True SVG icon support
See original GitHub issueSynopsis
QIcons with SVG are already available but through images. This RFC is about true SVG icons, which will include svg Quasar icon sets and the ability to use true svg icons (so dynamically sizable and colorable) in devland too (through @quasar/extras package).
Advantages
- Better app footprint – only used icons will be included in the final build
- Better quality icons
- No need for including equivalent webfonts from
@quasar/extras
or CDN.
Devland usage
Notice in the example below that we want to avoid Vue observable wrapping, so we inject icons on the instance through created()
hook. It will work if declared in data()
too, but… overhead.
Also, the usage will extend to all icon-related props on Quasar components, which is why I’ve added a QBtn example too.
// some .vue file in devland
<template>
<div>
<q-icon :name="matMenu" />
<q-btn :icon="mdiAbTesting" />
</div>
</template>
<script>
import { matMenu } from '@quasar/extras/material-icons'
import { mdiAbTesting } from '@quasar/extras/mdi-v4'
export default {
// ...
created () {
this.matMenu = matMenu
this.mdiAbTesting = mdiAbTesting
}
}
Custom SVG icons (not supplied by “@quasar/extras”) will also be supported.
Quasar svg Icon Sets
Below is an example with Material Icons. It will also work with MDI, Fontawesome, …
// quasar.conf.js
framework: {
// ...
iconSet: 'svg-material-icons'
}
QIcon svg name format
Svg icons will be defined as String with the following syntax:
Syntax: "<path>|<viewBox>" or "<path>" (with implicit 0 0 24 24 viewBox)
Examples:
M9 3L5 6.99h3V14h2V6.99h3L9 3zm7 14.01V10h-2v7.01h-3L15 21l4-3.99h-3z|0 0 24 24
M9 3L5 6.99h3V14h2V6.99h3L9 3zm7 14.01V10h-2v7.01h-3L15 21l4-3.99h-3z
QIcon with inline svg
QIcon can contain one <svg>
tag (the content of the svg can be anything, not only a path). Reasoning on why to use an <svg>
in a QIcon: the svg will respect the size and color as any QIcon through its props.
<q-icon color="accent" size="5rem">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm0 4c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm6 12H6v-1.4c0-2 4-3.1 6-3.1s6 1.1 6 3.1V19z"/>
</svg>
</q-icon>
Some limitations:
- do not use “height”/“width” attributes on the
<svg>
tag (it will brake QIcon’s way of handling the size) - all
<path>
s will have “fill: currentColor” CSS applied by default; if you don’t want that, then addfill="none"
to the<path>
tag
Current work status
Overall:
- - QIcon support
- - QIcon with inline svg
- - Quasar SVG Icon Sets
- - “@quasar/extras” svg build system
- - “@quasar/app” support
- - UMD variant usage
Per icon library:
Icon library | Quasar Icon Set | “@quasar/extras” svg build system |
---|---|---|
Material Icons | 👍 | 👍 |
MDI v4 | 👍 | 👍 |
Fontawesome v5 | 👍 | 👍 |
Ionicons v5 | 👍 | 👍 |
Eva Icons | 👍 | 👍 |
Themify Icons | 👍 | 👍 |
Issue Analytics
- State:
- Created 4 years ago
- Reactions:13
- Comments:12 (11 by maintainers)
Yes, it opens up to XSS attacks if the dev uses it without caution. Now I see why a registry is used in Angular: it keeps track of “safe” URLs in some way. It’s also written on the overview page:
I find this feature really valuable nonetheless (if all possible precautions are taken to avoid misuse), but I understand if you decide it’s too time-consuming to implement it. In my experience, I needed this feature for literally all projects I did (either 3-weeks websites, 1-year enterprise projects or something in the middle) with any framework (Angular, Vue or Quasar), so I guess it could be a common use case.
There is no duplication no matter how many times you use an svg icon and on how many vue components. Also, svg icons are not defined through CSS.