Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto-inline SVGs #4763

Closed
iMakedonsky opened this issue Jul 30, 2019 · 13 comments
Closed

Auto-inline SVGs #4763

iMakedonsky opened this issue Jul 30, 2019 · 13 comments

Comments

@iMakedonsky
Copy link

Everything is described in this comment:
#2494 (comment)

@IlCallo
Copy link
Member

IlCallo commented Aug 14, 2019

Looking forward for this too, to be able to inherit color from CSS properties as we do with webfonts.

A good starting point could be to analyze Angular Material Icon SVG management and MatIconRegistry, which allow to create a sprite of SVGs and inline them where needed.

Talking about alternatives, #2894 won't do, because it doesn't manage dynamic bindings.

@rstoenescu
Copy link
Member

Hi guys, don't have time atm to read the exact request, but putting this here if it helps (extract from docs, currently not deployed yet):

It is also possible to inline the image (svg, png, jpeg, gif...) and dynamically change its style (svg):

<q-icon name="img:data:image/svg+xml;charset=utf8,<svg xmlns='http://www.w3.org/2000/svg' height='140' width='500'><ellipse cx='200' cy='80' rx='100' ry='50' style='fill:yellow;stroke:purple;stroke-width:2' /></svg>" />

<doc-example title="Dynamic SVG" file="QIcon/DynamicSvg" />

You can also base64 encode an image and supply it. The example below is with a QBtn, but the same principle is involved when dealing with any icon prop or with QIcon:

<q-btn icon="
img:data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" ... />

QIcon/DynamicSvg here: https://github.com/quasarframework/quasar/blob/dev/docs/src/examples/QIcon/DynamicSvg.vue

@IlCallo
Copy link
Member

IlCallo commented Aug 14, 2019

I think it's not exactly the same thing we are searching, but it's a nice step forward!
I'll wait for the release to check if can be used as I hope

@rstoenescu
Copy link
Member

Don't need to wait for the release. This already works in 1.0

@iMakedonsky
Copy link
Author

iMakedonsky commented Aug 14, 2019

@rstoenescu So something like

<q-icon :name="require(`!!${dynamicComputedPathToSvg}`)"/>

Should work, right?

@IlCallo
Copy link
Member

IlCallo commented Aug 16, 2019

What we mean by "inline SVG" we mean inlining it into HTML, not having to inline it into the name prop.
Your way only works if the SVG should be used in a single place, otherwise you must copy/paste the SVG every time (or programmatically import it as text and inject it, which is doable, but not really clean IMO).

Also it doesn't take into account CSS rules inherited from parents like color, I guess?

Ideal API, for me, should be

<q-icon svg-inline name="static/icon.svg"/>

Which renders to

<svg class="q-icon svg-icon">
  <!-- SVG icon content -->
</svg>

Does this make sense for you?
<use> tag here, if I'm not wrong, will create a shadow DOM, preventing CSS rules like color to pass-by.
You can automatically set fill CSS property to currentColor to automatically make it take the value of inherited color rule, as explained here

All in all, I keep suggesting to check Angular SVG Icons as its a very well designed system, with Icon Sets saved as an SVG of named SVGs

@mesqueeb
Copy link
Contributor

mesqueeb commented Sep 25, 2019

I use vue-svg-inline-loader but it will only work with native img tags like so:
<img svg-inline src="" />

+1 for a feature to inline SVGs in QIcon, QImg and others.

@IlCallo
Copy link
Member

IlCallo commented Oct 16, 2019

It actually works pretty well, except the fact that referencing them with ~assets/... won't work for some reason. Using relative paths will work.
If this problem gets resolved (and if there are no edge cases), using that library could be the reccomended go-to for this scenario.

@iMakedonsky
Copy link
Author

@IlCallo it works up until you start using dynamic urls like

`../my_folder/{myVariable}.svg`

Or trying to insert those inside q-icon, q-btn or anything else instead of img tag.

@IlCallo
Copy link
Member

IlCallo commented Oct 16, 2019

Well, of course, given that it's done at build time.
It doesn't cover all user cases, but it's a start

@IlCallo
Copy link
Member

IlCallo commented Oct 22, 2019

oliverfindl/vue-svg-inline-loader#2 (comment)

Here the maintainer of vue-svg-inline-loader said he's working on a Vue plugin to inline SVG at runtime, providing dynamic support.

This is pointed out to be a possible solution for now, even if it seems a bit verbose to me.

@mv-go
Copy link

mv-go commented Nov 4, 2020

Going to bring this up again.

So I have a fairly large number of custom icons in my project. And I really love the way QIcon handles working with icons. My current approach is to create a separate <template functional> .vue file for every custom icon holding just the <svg> inside. I would them import these files in components where I need them and wrap inside QIcon like so

import IconHashtag from '@/icons/IconHashtag.vue'
...
components: {
  IconHashtag
}
...
<q-icon color="primary" size="md">
  <icon-hashtag/>
</q-icon>

This works fine and as expected but looks a bit (a lot) cumbersome. Especially when I have to use a custom icon somewhere inside another Quasar component.

So I stumbled upon iconMapFn here docs. Implemented the approach as suggested (created .svg files, referenced them, and passed to iconMapFn), and now I'm able to use my custom icons inside the name prop of QIcon (and other Quasar components that expect an icon to be passed to them).

The issue is colours. This approach does not support propagating colours to my icons. All icons would just default to black. In discord channel @rstoenescu suggested I add fill: currentColor to my custom .svg files. But this does not seem to help. If I pass let's say fill: red to my .svg - it does indeed become red (no wonder). But once I change it to fill: currentColor, the icon (or rather <img> that's generated by QIcon) does not seem to care. It just remains black. My reasoning would be the scoping issue (img simply does not care to pass color to its src .svg file).

No matter the reason, this significantly limits my approach to using custom icon library (bare in mind, it's a number of svg files, not a web-font) in my project. As the number of custom icons grows (and the number of icons used from 3rd party vendors, that are already included in quasar-extras, shrinks) - this is becoming more and more of a concern to me.

What makes matters worse is the inability to use even my current approach (svgs inside separate functional vue components) in some Quasar components. Most of this can be (and is) bypassed through <slot>s, but imho it looks much more verbose than in could (should) be.

@IlCallo IlCallo mentioned this issue Nov 25, 2020
36 tasks
@hawkeye64
Copy link
Member

I am closing the issue for inactivity. If this is still a concern, please create a conversation in the Discussions area or feel free to reopen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants