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

[Proposal] SVG icon #2494

Closed
olegvakulenko opened this issue Aug 30, 2018 · 26 comments
Closed

[Proposal] SVG icon #2494

olegvakulenko opened this issue Aug 30, 2018 · 26 comments

Comments

@olegvakulenko
Copy link
Contributor

Hi!

Is it possible to support SVG icon (with svg tag) instead of icon font?
For example, FontAwesome offer svg files for each icon, so if I use only several item of collection it would be optimal to place only needed icon inline in page template.

Thanks!

@mesqueeb
Copy link
Contributor

mesqueeb commented Sep 7, 2018

I also require custom svg in many cases Quasar offers the icon slot.

Eg. QDropdownBtn has an "icon" slot, but I need to use a custom svg in that slot.

@HenriqueSPin
Copy link

Nowadays its pretty simple to create your own symbol font (like font awesome).

You can always use https://icomoon.io (for example) to create a symbol set that you can reference in your quasar just like any of the material icons.

@mesqueeb
Copy link
Contributor

mesqueeb commented Sep 9, 2018

Henrique if this is true i’d love to try it out and write some guide on this for the quasar docs.

For the time being can you point me in the direction to start doing this? Any blog post or guide you can recommend?

@mesqueeb
Copy link
Contributor

mesqueeb commented Sep 9, 2018

I beautiful solution would be to allow to pass a path to the svg icon in the assets folder.
Something like:

<q-btn icon="~/svg/myCustomIcon.svg" />

What do you think?

@olegvakulenko
Copy link
Contributor Author

I think solution to use SVG icon may be like this:

<q-btn>
  <svg slot='icon'>
    ...
  </svg>
</q-btn>

As I can see, this solution allow to use SVG inline or by link (xlink:href) or even as sprite:

https://fvsch.com/svg-icons/

@olegvakulenko
Copy link
Contributor Author

@HenriqueSPin
I agree with you that I can generate icon font with online tool and use it in my project, but in my case when I use only about 10 or so icons, I prefer to be able to inline this icon (as SVG) in template code and avoid to link extra network resource.

@HenriqueSPin
Copy link

Henrique if this is true i’d love to try it out and write some guide on this for the quasar docs.

For the time being can you point me in the direction to start doing this? Any blog post or guide you can recommend?

It's really a simple and straight forward process. All you have to do is start a new project in IcoMoon App (https://icomoon.io/app/), upload your own SVGs or use icons from the free IcoMoon catalog to compose your very own set.

After this, you only have to export by click in "generate font". In the next screen you can customize the name of your glyphs (CSS class names) and download it.

Now, in your project, unzip the folder into your fonts/assets folder and import the file into your stylus/css main (may be another css/styl file, like fonts.styl, as long as it is imported somewhere in your project).

Now you are able to use the names of your glyphs as a icon. Jus like this <q-icon name="fa custom_name" /> or in any other component. NOTE the fa "prefix". That is to tell quasar that this is not a material icon. It will be treated as a "FontAwesome" icon.

PLUS: The files exported by IconMoon contains a .json with all your glyphs and sets that you can import anytime in the IcoMoon App and add/remove/edit glyphs or sets to the font.

@amfine-soft-scheminel
Copy link
Contributor

I like using SVG because it so much featured than font. In SVG you can have mapping and gradient, css transformations...
So the font way is not a fair replacement to SVG.

I achieve using some SVG icons in quasar components by doing like that :

 /* CSS File */
  .icon-svg:before{
      content : url("path/to/file.svg");
  }
   <!-- in template.vue -->
  <q-btn @click="clikc" icon="icon-svg" />

But I can't influence currentColor in such case. I mean if I wan't to themify my app I have too supply all needed SVG coloured files and to do some tricky template tests.

With the slot solution describe above it will be possible to influence SVG icons with CSS so themification will become so easier.

@amfine-soft-scheminel
Copy link
Contributor

amfine-soft-scheminel commented Sep 18, 2018

I've found this tricky way :

        <q-btn @click="home" >
          <q-icon v-html="$options.filters.svg('home')" ></q-icon>
        </q-btn>
  Vue.filter("svg", function (code, options) {
    options=Object.assign({
      width : 20,
      height : 26,
      "class" : "svg-icon"
    }, options );
    return `<svg viewBox="0 0 65 65" height="${options.height}px" width="${options.height}px" class="${options.class}"><use xlink:href="#svg-icon-${code}" /></svg>`;
  });

With this method I can adapt my svg icon through CSS properties.
I especially use currentColor in my SVG icon.

@nothingismagick
Copy link
Contributor

@amfine-soft-scheminel - that is really freaking clever.

@drasill
Copy link

drasill commented Oct 22, 2018

I would love to use svg icons in all places (like <q-item-side icon="svg#icon-id"/>).

For this to work, QIcon must be modified.

Would you accept a PR on a working solution ?

@mesqueeb
Copy link
Contributor

mesqueeb commented Mar 21, 2019

I just wanted to bump this thread since it's 2019 and V1 is released.

Anywhere in Quasar I can use icon, I'd love to have a simple way to use custom SVG icons as well.

Eg. when the name passed in icon is not found in any of the icon-sets it could look in a specific place inside assets/statics where the dev should place all their own custom icons.

@drasill
Copy link

drasill commented Mar 21, 2019

I have a very ugly override on QIcon, for quasar 0.17.

It lets me use things as <q-icon name="svguse-./dist/icons.svg#star"/>, for exemple.

I had to update the webpack config also so an SVG file could be integrated (in quasar.conf.js) :

// ...
const SpriteLoaderPlugin = require('svg-sprite-loader/plugin');

module.exports = function (ctx) {
  return {
    //...
    build: {
      //...
      chainWebpack (chain) {

        // Remove icon path from Quasar's svg loader
        chain.module.rule('images')
          .exclude
          .add(/src\/icons\/.*\.svg$/)
          .end()

        chain.module.rule('svg-sprite')
          .test(/src\/icons\/.*\.svg$/)
          .use('svg-sprite')
          .loader('svg-sprite-loader')
          .options({
            extract: true,
            spriteFilename: './dist/icons.svg',
          })

        chain.module.rule('svg-sprite')
          .test(/src\/icons\/.*\.svg$/)
          .use('svgo')
          .loader('svgo-loader')
          .options({
            plugins: [
              {
                removeUselessStrokeAndFill: {
                  fill: true,
                  stroke: true,
                },
              },
            ],
          })

        chain.plugin('svg-sprite')
          .use(SpriteLoaderPlugin, [{plainSprite: true}])

        // Override QIcon
        chain.plugin('override-q-icon')
          .use(webpack.NormalModuleReplacementPlugin, [
            /QIcon\.js$/,
            (resource) => {
              resource.request = path.resolve(__dirname, './src/override/QIcon.js')
            }
          ])

      },
      //...

I'll have to make it work for v1, but without answer from the quasar team, I'll probably do another ugly workaround in my corner.

@nothingismagick
Copy link
Contributor

That is a bit ugly, I agree - there should be a way to do this natively without having to patch together an SVG loader.

@drasill
Copy link

drasill commented Mar 21, 2019

Actually having the SVG loader does seems normal to me.

IMO, what's ugly here is overriding QIcon.

@rstoenescu
Copy link
Member

Will be available in beta.12.

QIcon name prop will also support "img:" prefix, which can be used like this (just a few examples below, literally every "icon" prop of any component will work with this):

<q-icon name="img:https://cdn.quasar-framework.org/logo/svg/quasar-logo.svg" />
<q-btn icon="img:https://cdn.quasar-framework.org/logo/svg/quasar-logo.svg" ... />
<q-icon name="img:statics/my/path/to/some.svg" />

This is not restricted to SVG only. You can use whatever image type you want (png, jpg, ...):

<q-icon name="img:statics/bla/bla/my.png" />
<q-btn icon="img:statics/bla/bla/my.jpg" ... />
<q-input clearable clear-icon="img:statics/bla/bla/my.gif" ... />

@mesqueeb
Copy link
Contributor

mesqueeb commented Mar 21, 2019

Woooow this is soooo great. I have like three pre-v1 apps with hoops and loops to do this. Now it all works out of the box!!! 😍

Thank you so much for your time and effort.

@scwall
Copy link

scwall commented Mar 22, 2019

Is it possible to add it also for "q-expansion-item" and "q-tab" ? I'm just using it :) thanks you :D

@rstoenescu
Copy link
Member

@scwall It will be available for ALL components that have icon-related props. So this also includes QExpansionItem and QTab.

@scwall
Copy link

scwall commented Mar 23, 2019

Perfect!

@drasill
Copy link

drasill commented Mar 26, 2019

Nice, but I suppose it won't be possible to use SVG sprites, with a use tag, like :

<svg>
   <use xlink:href="..."></use>
</svg>

@rstoenescu
Copy link
Member

rstoenescu commented Mar 26, 2019

@drasill As per MDN docs, xlink:href is deprecated. Quote:

Deprecated since SVG 2
This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.

@iMakedonsky
Copy link

iMakedonsky commented Jul 29, 2019

@rstoenescu Could quasar add support for something like https://github.com/iconfu/svg-inject/ natively inside all components that utilize icons?

For example, there's a q-tab component, and we can select an icon for it. It supports img:assets/my.svg binding, though this way it's just embedding it <img> tag, thusway creating new separate document and preventing style propagation to svg.

Instead, would be cool to have svg icons be automatically processed by such library (or similar builtin directive), that would inline svg icons so that they can behave like font icons and inherit colors/styles/etc from css.

vue-svg-inline-loader is not the solution, since it doesn't process dynamic content and it doesn't work with any of components. It only supports plain <img>.

@mesqueeb
Copy link
Contributor

@iMakedonsky I'm using my own "MyIcon" wrapper in most projects that use vue-svg-inline-loader.
But as you say, it's not compatible with Quasar. It does work for using CSS to style the SVGs for me though.

If Quasar could natively support the possibility to inline SVGs any place it uses an icon now, that would be a dream come true. 🌷

However, maybe in this closed thread your suggestion might get lost. Maybe you could open a new feature request issue and link this thread?

@IlCallo
Copy link
Member

IlCallo commented Aug 14, 2019

As per MDN docs, xlink:href is deprecated

@rstoenescu
About xlink:href: https://css-tricks.com/on-xlinkhref-being-deprecated-in-svg/
Newer syntax is not supported by Safari yet, and old one is gonna stay for quite some time.
Could be a good idea to keep using deprecated one

@rstoenescu
Copy link
Member

RFC to watch: #6027

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

No branches or pull requests

10 participants