|
|
1 år sedan | |
|---|---|---|
| .. | ||
| dist | 1 år sedan | |
| node_modules | 1 år sedan | |
| types | 1 år sedan | |
| LICENSE | 1 år sedan | |
| README.md | 1 år sedan | |
| package.json | 1 år sedan | |
Access thousands of icons as components on-demand universally.
💡 **Story behind this tool**: [Journey with Icons Continues](https://antfu.me/posts/journey-with-icons-continues) - a blog post by Anthony |
vite-plugin-iconshas been renamed tounplugin-icons, see the migration guide
Import icons names with the convention ~icons/{collection}/{icon} and use them directly as components. Auto importing is also possible.
import IconAccessibility from '~icons/carbon/accessibility'
import IconAccountBox from '~icons/mdi/account-box'
function App() {
return (
<div>
<IconAccessibility />
<IconAccountBox style={{ fontSize: '2em', color: 'red' }}/>
</div>
)
}
<script setup>
import IconAccessibility from '~icons/carbon/accessibility'
import IconAccountBox from '~icons/mdi/account-box'
</script>
<template>
<icon-accessibility/>
<icon-account-box style="font-size: 2em; color: red"/>
</template>
npm i -D unplugin-icons
We use Iconify as the icons data source (supports 100+ iconsets).
You have two ways to install them:
npm i -D @iconify/json
@iconify/json (~120MB) includes all the iconsets from Iconify so you can install once and use any of them as you want (only the icons you actually use will be bundle into the production build).
If you only want to use a few of the icon sets and don't want to download the entire collection, you can also install them individually with @iconify-json/[collection-id].
For example, to install Material Design Icons, you can do:
npm i -D @iconify-json/mdi
To boost your workflow, it's also possible to let unplugin-icons handle that installation by enabling the autoInstall option.
Icons({
// experimental
autoInstall: true,
})
It will install the icon set when you import them. The right package manager will be auto-detected (npm, yarn or pnpm).
From v0.13.2 you can also use raw compiler to access the svg icon and use it on your html templates, just add raw to the icon query param.
For example, using vue3:
<script setup lang='ts'>
import RawMdiAlarmOff from '~icons/mdi/alarm-off?raw&width=4em&height=4em'
import RawMdiAlarmOff2 from '~icons/mdi/alarm-off?raw&width=1em&height=1em'
</script>
<template>
<!-- raw example -->
<pre>
import RawMdiAlarmOff from '~icons/mdi/alarm-off?raw&width=4em&height=4em'
{{ RawMdiAlarmOff }}
import RawMdiAlarmOff2 from '~icons/mdi/alarm-off?raw&width=1em&height=1em'
{{ RawMdiAlarmOff2 }}
</pre>
<!-- svg example -->
<span v-html="RawMdiAlarmOff" />
<span v-html="RawMdiAlarmOff2" />
</template>
From v0.11, you can now load your own icons!
From v0.13 you can also provide a transform callback to FileSystemIconLoader.
import { promises as fs } from 'node:fs'
// loader helpers
import { FileSystemIconLoader } from 'unplugin-icons/loaders'
Icons({
customCollections: {
// key as the collection name
'my-icons': {
account: '<svg><!-- ... --></svg>',
// load your custom icon lazily
settings: () => fs.readFile('./path/to/my-icon.svg', 'utf-8'),
/* ... */
},
'my-other-icons': async (iconName) => {
// your custom loader here. Do whatever you want.
// for example, fetch from a remote server:
return await fetch(`https://example.com/icons/${iconName}.svg`).then(res => res.text())
},
// a helper to load icons from the file system
// files under `./assets/icons` with `.svg` extension will be loaded as it's file name
// you can also provide a transform callback to change each icon (optional)
'my-yet-other-icons': FileSystemIconLoader(
'./assets/icons',
svg => svg.replace(/^<svg /, '<svg fill="currentColor" '),
),
},
})
Then use as
import IconAccount from '~icons/my-icons/account'
import IconFoo from '~icons/my-other-icons/foo'
import IconBar from '~icons/my-yet-other-icons/bar'
💡 SVG Authoring Tips:
- To make your icons color adaptable, set
fill="currentColor"orstroke="currentColor"in your SVG.- Leave the
heightandwidthunspecified, we will set them for you.
When using with resolvers for auto-importing, you will need to tell it your custom collection names:
IconResolver({
customCollections: [
'my-icons',
'my-other-icons',
'my-yet-other-icons',
],
})
See the Vue 3 + Vite example.
From v0.13 you can also customize each icon using iconCustomizer configuration option or using query params when importing them.
The query param will take precedence over iconCustomizer and iconCustomizer over configuration.
The iconCustomizer and query params will be applied to any collection, that is, for each icon from custom loader, inlined on customCollections or from @iconify.
For example, you can configure iconCustomizer to change all icons for a collection or individual icons on a collection:
import { promises as fs } from 'node:fs'
// loader helpers
import { FileSystemIconLoader } from 'unplugin-icons/loaders'
Icons({
customCollections: {
// key as the collection name
'my-icons': {
account: '<svg><!-- ... --></svg>',
// load your custom icon lazily
settings: () => fs.readFile('./path/to/my-icon.svg', 'utf-8'),
/* ... */
},
'my-other-icons': async (iconName) => {
// your custom loader here. Do whatever you want.
// for example, fetch from a remote server:
return await fetch(`https://example.com/icons/${iconName}.svg`).then(res => res.text())
},
// a helper to load icons from the file system
// files under `./assets/icons` with `.svg` extension will be loaded as it's file name
// you can also provide a transform callback to change each icon (optional)
'my-yet-other-icons': FileSystemIconLoader(
'./assets/icons',
svg => svg.replace(/^<svg /, '<svg fill="currentColor" '),
),
},
iconCustomizer(collection, icon, props) {
// customize all icons in this collection
if (collection === 'my-other-icons') {
props.width = '4em'
props.height = '4em'
}
// customize this icon in this collection
if (collection === 'my-icons' && icon === 'account') {
props.width = '6em'
props.height = '6em'
}
// customize this @iconify icon in this collection
if (collection === 'mdi' && icon === 'account') {
props.width = '2em'
props.height = '2em'
}
},
})
or you can use query params to apply to individual icons:
<script setup lang='ts'>
import MdiAlarmOff from 'virtual:icons/mdi/alarm-off?width=4em&height=4em'
import MdiAlarmOff2 from 'virtual:icons/mdi/alarm-off?width=1em&height=1em'
</script>
<template>
<!-- width=4em and height=4em -->
<mdi-alarm-off />
<!-- width=4em and height=4em -->
<MdiAlarmOff />
<!-- width=1em and height=1em -->
<MdiAlarmOff2 />
</template>
See src/App.vue component and vite.config.ts configuration on vite-vue3 example project.
From version 0.14.2, when loading your custom icons, you can transform them, for example adding fill attribute with currentColor:
Icons({
customCollections: {
// key as the collection name
'my-icons': {
account: '<svg><!-- ... --></svg>',
/* ... */
},
},
transform(svg, collection, icon) {
// apply fill to this icon on this collection
if (collection === 'my-icons' && icon === 'account')
return svg.replace(/^<svg /, '<svg fill="currentColor" ')
return svg
},
})
When using this plugin with your custom icons, consider using a cleanup process similar to that done by Iconify for any icons sets. All the tools you need are available in Iconify Tools.
You can check this repo, using unplugin-icons on a SvelteKit project: https://github.com/iconify/tools/tree/main/%40iconify-demo/unplugin-svelte.
Read Cleaning up icons article from Iconify for more details.
vite-plugin-iconspackage.json
{
"devDependencies": {
- "vite-plugin-icons": "*",
+ "unplugin-icons": "^0.7.0",
}
}
vite.config.json
import Components from 'unplugin-vue-components/vite'
- import Icons, { ViteIconsResolver } from 'vite-plugin-icons'
+ import Icons from 'unplugin-icons/vite'
+ import IconsResolver from 'unplugin-icons/resolver'
export default {
plugins: [
Vue(),
Components({
resolvers: [
IconsResolver()
],
}),
Icons(),
],
}
* - imports usage
- import IconComponent from 'virtual:vite-icons/collection/name'
+ import IconComponent from '~icons/collection/name'
You can still use
virtual:iconsprefix in Vite if you prefer, but it's not yet supported in Webpack, we are unifying it as a workaround in the docs.
You can set default styling for all icons. The following config shows the default values of each option:
Icons({
scale: 1.2, // Scale of icons against 1em
defaultStyle: '', // Style apply to icons
defaultClass: '', // Class names apply to icons
compiler: null, // 'vue2', 'vue3', 'jsx'
jsx: 'react', // 'react' or 'preact'
})
When using component resolver, you have to follow the name conversion for icons to be properly inferred.
{prefix}-{collection}-{icon}
The collection field follows Iconify's collection IDs.
By default, the prefix is set to i while you can customize via config
IconsResolver({
prefix: 'icon', // <--
})
<template>
<icon-mdi-account />
</template>
Non-prefix mode is also supported
IconsResolver({
prefix: false, // <--
// this is optional, default enabling all the collections supported by Iconify
enabledCollections: ['mdi'],
})
<template>
<mdi-account />
</template>
When using component resolver, you have to use the name of the collection that can be long or redundant: for example,
when using icon-park collection you need to use it like this <icon-icon-park-abnormal />.
You can add an alias for any collection to the IconResolver plugin:
IconsResolver({
alias: {
park: 'icon-park',
fas: 'fa-solid',
// ...
}
})
You can use the alias or the collection name, the plugin will resolve both.
Following with the example and configuring the plugin with previous alias entry, you can now use
<icon-park-abnormal /> or <icon-icon-park-abnormal />.
This project is part of my Sponsor Program
MIT License © 2020-PRESENT Anthony Fu