kiwilan / nuxt-svg-transformer

Nuxt 3 module. Transform SVG to inject dynamically into Vue component, type included. Powered by unplugin.
https://github.com/kiwilan/unplugin-svg-transformer
MIT License
27 stars 6 forks source link

Cannot apply class to SVG icons #1

Closed FarhanShares closed 1 year ago

FarhanShares commented 1 year ago

The component now renders the icon like this:

<Suspense>
    <span v-bind="attrs" v-html="svg" />
</Suspense>

For that reason, no class can be passed to the SVG itself though it's important because if we would like to resize, change colors by applying classes, we can't do it now. Is there a way?

However, the module has improved functionalities in some cases over other existing modules. Thanks for the awesome work.

ewilan-riviere commented 1 year ago

Thanks for your feedback, it's a very useful feature.

Component supported only global style and not scoped style, I use Tailwind, so it wasn't a problem for myself but isn't a good reason to not add this feature.

Like you propose, I remove Suspense from component, it works perfectly. You can try now the new version, tell me if it's OK for you.

https://github.com/kiwilan/nuxt-svg-transformer/releases/tag/0.0.44

FarhanShares commented 1 year ago

Great. I just tried with Tailwind CSS (via Windi CSS). In my case, Span being an inline element, it is not counting the height & width set by the classes. For i.e. the following works for the color but cannot affect the sizes.

 <SvgIcon name="github" class="w-10 h-10 text-blue-500" />

However, if I change it to block element, it just works as expected

 <SvgIcon name="github" class="block w-10 h-10 text-blue-400" />
ewilan-riviere commented 1 year ago

It's a good suggestion, do you think that it's better if component is by default div? To be in display:block directly?

ewilan-riviere commented 1 year ago

Or another solution, with global option, just add display:block by default to all SVG?

FarhanShares commented 1 year ago

I think we better not force others to use

svg {
    display: block;
}

Because they might not be interested to do it & affect their existing SVGs.

We can have a few options, i.e.

But, in all of the above cases, the element will probably get converted into a block level element. So it needs to be documented as well, because by default SVGs are inline element and we are altering it.

Therefore, I think we need to come up with a solution which is the same or at least close to the default behaviour. In that case, We can set it to inline-block instead. Which will still allow us to set height & width and behave almost like an inline element.

ewilan-riviere commented 1 year ago

Excellent analyse!

So we add a new global config option inlineBlock to set display:inline-block; to all SVG, but default is true or false for this option? Do you have some examples where inline-block could be a problem?

FarhanShares commented 1 year ago

I was thinking, we can just do this instead,

<span style="display: inline-block;" v-bind="attrs" v-html="svg" />

This way, it will not affect SVGs globally & we don't have to think about others. And since we have attrs already bound, it can be overridden as well on each components / icons.

ewilan-riviere commented 1 year ago

I add a new option inlineBlock (default true) to add display: inline-block to SvgIcon like you propose. Thanks ;)

I publish 0.0.5 version, tell if it's okay with this version!

ewilan-riviere commented 1 year ago

With new release 0.1.1, inlineBlock option is now display with CSS options for display (default is inline-block).