├── .gitattributes ├── .github ├── FUNDING.yml └── workflows │ └── release.yml ├── .gitignore ├── .npmrc ├── .tazerc.json ├── .vscode └── settings.json ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── eslint.config.js ├── examples ├── README.md ├── astro-vue │ ├── .stackblitz.js │ ├── astro.config.mjs │ ├── package.json │ ├── public │ │ └── favicon.svg │ ├── src │ │ ├── components │ │ │ └── HomeLink.vue │ │ ├── env.d.ts │ │ ├── layouts │ │ │ └── Layout.astro │ │ └── pages │ │ │ └── index.astro │ └── tsconfig.json ├── astro │ ├── .stackblitz.js │ ├── astro.config.mjs │ ├── package.json │ ├── public │ │ └── favicon.svg │ ├── src │ │ ├── env.d.ts │ │ ├── layouts │ │ │ └── Layout.astro │ │ └── pages │ │ │ └── index.astro │ └── tsconfig.json ├── next │ ├── .gitignore │ ├── .stackblitz.js │ ├── next-env.d.ts │ ├── next.config.js │ ├── package.json │ ├── pages │ │ ├── _app.tsx │ │ └── index.tsx │ ├── public │ │ └── favicon.ico │ ├── styles │ │ ├── Home.module.css │ │ └── globals.css │ └── tsconfig.json ├── nuxt3 │ ├── .gitignore │ ├── .npmrc │ ├── .stackblitz.js │ ├── README.md │ ├── app.vue │ ├── components.d.ts │ ├── components │ │ ├── Circle.vue │ │ └── LayoutHeader.vue │ ├── nuxt.config.ts │ ├── package.json │ ├── pnpm-workspace.yaml │ └── tsconfig.json ├── rspack-vue3 │ ├── .gitignore │ ├── .stackblitz.js │ ├── README.md │ ├── index.html │ ├── package.json │ ├── rspack.config.mjs │ └── src │ │ ├── App.vue │ │ ├── assets │ │ ├── rspack.svg │ │ └── vue.svg │ │ ├── components │ │ └── HelloWorld.vue │ │ ├── main.js │ │ └── style.css ├── sveltekit │ ├── .stackblitz.js │ ├── package.json │ ├── src │ │ ├── app.d.ts │ │ ├── app.html │ │ └── routes │ │ │ └── +page.svelte │ ├── static │ │ └── favicon.ico │ ├── svelte.config.js │ ├── tsconfig.json │ └── vite.config.ts ├── vite-preact │ ├── .gitignore │ ├── .stackblitz.js │ ├── index.html │ ├── package.json │ ├── src │ │ ├── app.tsx │ │ ├── index.css │ │ ├── main.tsx │ │ ├── preact.d.ts │ │ └── vite-env.d.ts │ ├── tsconfig.json │ └── vite.config.ts ├── vite-qwik │ ├── .gitignore │ ├── .stackblitz.js │ ├── package.json │ ├── src │ │ ├── app.tsx │ │ ├── entry.dev.tsx │ │ ├── entry.ssr.tsx │ │ └── root.tsx │ ├── tsconfig.json │ └── vite.config.ts ├── vite-react │ ├── .stackblitz.js │ ├── index.html │ ├── package.json │ ├── src │ │ ├── App.css │ │ ├── App.tsx │ │ ├── index.css │ │ ├── main.tsx │ │ └── vite-env.d.ts │ ├── tsconfig.json │ └── vite.config.ts ├── vite-solid │ ├── .gitignore │ ├── .stackblitz.js │ ├── index.html │ ├── package.json │ ├── src │ │ ├── App.module.css │ │ ├── App.tsx │ │ ├── index.css │ │ ├── index.tsx │ │ └── logo.svg │ ├── tsconfig.json │ └── vite.config.ts ├── vite-svelte │ ├── .stackblitz.js │ ├── index.html │ ├── package.json │ ├── src │ │ ├── App.svelte │ │ ├── CustomSvg.svelte │ │ ├── main.ts │ │ └── vite-env.d.ts │ ├── svelte.config.js │ ├── tsconfig.json │ └── vite.config.js ├── vite-vanilla │ ├── .stackblitz.js │ ├── index.html │ ├── main.ts │ ├── package.json │ └── vite.config.ts ├── vite-vue2 │ ├── .stackblitz.js │ ├── App.vue │ ├── components.d.ts │ ├── index.html │ ├── main.ts │ ├── package.json │ ├── vite.config.ts │ └── vue-shim.d.ts ├── vite-vue3-legacy │ ├── .stackblitz.js │ ├── App.vue │ ├── assets │ │ ├── custom-a │ │ │ ├── SteeringWheel.svg │ │ │ └── car-a.svg │ │ └── giftbox.svg │ ├── components.d.ts │ ├── index.html │ ├── main.ts │ ├── package.json │ └── vite.config.ts ├── vite-vue3 │ ├── .stackblitz.js │ ├── @test-scope │ │ └── test-color-icons │ │ │ ├── index.d.ts │ │ │ ├── index.js │ │ │ ├── index.mjs │ │ │ └── package.json │ ├── App.vue │ ├── assets │ │ ├── custom-a │ │ │ ├── SteeringWheel.svg │ │ │ └── car-a.svg │ │ └── giftbox.svg │ ├── components.d.ts │ ├── getConfig.ts │ ├── index.html │ ├── main.ts │ ├── package.json │ ├── plain-color-icons │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── index.mjs │ │ └── package.json │ └── vite.config.ts ├── vite-web-components │ ├── .stackblitz.js │ ├── index.html │ ├── package.json │ └── vite.config.ts ├── vue-cli-vue2 │ ├── .npmrc │ ├── .stackblitz.js │ ├── babel.config.js │ ├── package.json │ ├── public │ │ └── index.html │ ├── src │ │ ├── App.vue │ │ ├── main.ts │ │ └── shims-vue.d.ts │ ├── tsconfig.json │ └── vue.config.js └── webpack │ ├── package.json │ ├── src │ └── main.js │ └── webpack.config.js ├── package.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── scripts └── prebuild.ts ├── src ├── core │ ├── collections.ts │ ├── compilers │ │ ├── astro.ts │ │ ├── index.ts │ │ ├── jsx.ts │ │ ├── marko.ts │ │ ├── none.ts │ │ ├── qwik.ts │ │ ├── raw.ts │ │ ├── solid.ts │ │ ├── svelte.ts │ │ ├── types.ts │ │ ├── vue2.ts │ │ ├── vue3.ts │ │ └── web-components.ts │ ├── icon-sets.json │ ├── loader.ts │ ├── options.ts │ └── svgId.ts ├── esbuild.ts ├── index.ts ├── loaders.ts ├── nuxt.ts ├── resolver.ts ├── rollup.ts ├── rspack.ts ├── types.ts ├── vite.ts └── webpack.ts ├── test ├── __snapshots__ │ └── idSvg.test.ts.snap └── idSvg.test.ts ├── tsconfig.json ├── tsup.config.ts └── types ├── astro.d.ts ├── index.d.ts ├── preact.d.ts ├── qwik.d.ts ├── raw.d.ts ├── react.d.ts ├── solid.d.ts ├── svelte.d.ts ├── svelte3.d.ts ├── svelte4.d.ts ├── svelte5.d.ts ├── vue.d.ts ├── vue3.d.ts └── web-components.d.ts /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | open_collective: antfu 2 | github: [antfu] 3 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*' 7 | 8 | jobs: 9 | release: 10 | runs-on: ubuntu-latest 11 | permissions: 12 | contents: write 13 | steps: 14 | - uses: actions/checkout@v4 15 | with: 16 | fetch-depth: 0 17 | 18 | - uses: actions/setup-node@v4 19 | with: 20 | node-version: lts/* 21 | 22 | - run: npx changelogithub 23 | env: 24 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | example/README.md 5 | .nuxt 6 | .idea 7 | .svelte-kit/ 8 | examples/nuxt3/pnpm-lock.yaml 9 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | ignore-workspace-root-check=true 2 | strict-peer-dependencies=false 3 | shell-emulator=true 4 | -------------------------------------------------------------------------------- /.tazerc.json: -------------------------------------------------------------------------------- 1 | { 2 | "exclude": [ 3 | "vue" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | // Enable the ESlint flat config support 3 | "eslint.experimental.useFlatConfig": true, 4 | 5 | // Disable the default formatter, use eslint instead 6 | "prettier.enable": false, 7 | "editor.formatOnSave": false, 8 | 9 | // Auto fix 10 | "editor.codeActionsOnSave": { 11 | "source.fixAll": "explicit", 12 | "source.organizeImports": "never" 13 | }, 14 | 15 | // Silent the stylistic rules in you IDE, but still auto fix them 16 | "eslint.rules.customizations": [ 17 | { "rule": "style/*", "severity": "off" }, 18 | { "rule": "*-indent", "severity": "off" }, 19 | { "rule": "*-spacing", "severity": "off" }, 20 | { "rule": "*-spaces", "severity": "off" }, 21 | { "rule": "*-order", "severity": "off" }, 22 | { "rule": "*-dangle", "severity": "off" }, 23 | { "rule": "*-newline", "severity": "off" }, 24 | { "rule": "*quotes", "severity": "off" }, 25 | { "rule": "*semi", "severity": "off" } 26 | ], 27 | 28 | // Enable eslint for all supported languages 29 | "eslint.validate": [ 30 | "javascript", 31 | "javascriptreact", 32 | "typescript", 33 | "typescriptreact", 34 | "vue", 35 | "html", 36 | "markdown", 37 | "json", 38 | "jsonc", 39 | "yaml" 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Please refer to https://github.com/antfu/contribute 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020-PRESENT Anthony Fu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | import antfu from '@antfu/eslint-config' 3 | 4 | export default antfu() 5 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | **NOTE**: Qwik (Vite) example running on StackBlitz will switch to `compiler: 'jsx'` and `jsx: 'qwik'`, replacing `@svgx/core` with `@svgr/core` and `@svgr/plugin-jsx`) 4 | 5 | | Example | Source | Playground | 6 | |-------------------------|---------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 7 | | `Astro` | [GitHub](https://github.com/unplugin/unplugin-icons/tree/main/examples/astro) | [Play Online](https://stackblitz.com/fork/github/unplugin/unplugin-icons/tree/main/examples/astro) | 8 | | `Astro + Vue` | [GitHub](https://github.com/unplugin/unplugin-icons/tree/main/examples/astro-vue) | [Play Online](https://stackblitz.com/fork/github/unplugin/unplugin-icons/tree/main/examples/astro-vue) | 9 | | `Next` | [GitHub](https://github.com/unplugin/unplugin-icons/tree/main/examples/next) | [Play Online](https://stackblitz.com/fork/github/unplugin/unplugin-icons/tree/main/examples/next) | 10 | | `Nuxt 3` | [GitHub](https://github.com/unplugin/unplugin-icons/tree/main/examples/nuxt3) | [Play Online](https://stackblitz.com/fork/github/unplugin/unplugin-icons/tree/main/examples/nuxt3) | 11 | | `SvelteKit` | [GitHub](https://github.com/unplugin/unplugin-icons/tree/main/examples/sveltekit) | [Play Online](https://stackblitz.com/fork/github/unplugin/unplugin-icons/tree/main/examples/sveltekit) | 12 | | `Preact (Vite)` | [GitHub](https://github.com/unplugin/unplugin-icons/tree/main/examples/vite-preact) | [Play Online](https://stackblitz.com/fork/github/unplugin/unplugin-icons/tree/main/examples/vite-preact) | 13 | | `Qwik (Vite)` | [GitHub](https://github.com/unplugin/unplugin-icons/tree/main/examples/vite-qwik) | [Play Online](https://stackblitz.com/fork/github/unplugin/unplugin-icons/tree/main/examples/vite-qwik) | 14 | | `React (Vite)` | [GitHub](https://github.com/unplugin/unplugin-icons/tree/main/examples/vite-react) | [Play Online](https://stackblitz.com/fork/github/unplugin/unplugin-icons/tree/main/examples/vite-react) | 15 | | `Solid (Vite)` | [GitHub](https://github.com/unplugin/unplugin-icons/tree/main/examples/vite-solid) | [Play Online](https://stackblitz.com/fork/github/unplugin/unplugin-icons/tree/main/examples/vite-solid) | 16 | | `Svelte (Vite)` | [GitHub](https://github.com/unplugin/unplugin-icons/tree/main/examples/vite-svelte) | [Play Online](https://stackblitz.com/fork/github/unplugin/unplugin-icons/tree/main/examples/vite-svelte) | 17 | | `VanillaJS (Vite)` | [GitHub](https://github.com/unplugin/unplugin-icons/tree/main/examples/vite-vanilla) | [Play Online](https://stackblitz.com/fork/github/unplugin/unplugin-icons/tree/main/examples/vite-vanilla) | 18 | | `Vue2 (Vite)` | [GitHub](https://github.com/unplugin/unplugin-icons/tree/main/examples/vite-vue2) | [Play Online](https://stackblitz.com/fork/github/unplugin/unplugin-icons/tree/main/examples/vite-vue2) | 19 | | `Vue3 (Vite)` | [GitHub](https://github.com/unplugin/unplugin-icons/tree/main/examples/vite-vue3) | [Play Online](https://stackblitz.com/fork/github/unplugin/unplugin-icons/tree/main/examples/vite-vue3) | 20 | | `Vue3 legacy (Vite)` | [GitHub](https://github.com/unplugin/unplugin-icons/tree/main/examples/vite-vue3-legacy) | [Play Online](https://stackblitz.com/fork/github/unplugin/unplugin-icons/tree/main/examples/vite-vue3-legacy) | 21 | | `Web Components (Vite)` | [GitHub](https://github.com/unplugin/unplugin-icons/tree/main/examples/vite-web-components) | [Play Online](https://stackblitz.com/fork/github/unplugin/unplugin-icons/tree/main/examples/vite-web-components) | 22 | | `Vue2 (Vue CLI)` | [GitHub](https://github.com/unplugin/unplugin-icons/tree/main/examples/vue-cli-vue2) | [Play Online](https://stackblitz.com/fork/github/unplugin/unplugin-icons/tree/main/examples/vue-cli-vue2) | 23 | -------------------------------------------------------------------------------- /examples/astro-vue/.stackblitz.js: -------------------------------------------------------------------------------- 1 | import { promises as fsPromises } from 'node:fs' 2 | 3 | updatePackageJson() 4 | 5 | async function updatePackageJson() { 6 | const filename = './package.json' 7 | try { 8 | const contents = await fsPromises.readFile(filename, 'utf-8') 9 | const updatedContent = contents.replace('workspace:*', 'latest') 10 | await fsPromises.writeFile(filename, updatedContent) 11 | } 12 | catch (err) { 13 | console.error(err) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/astro-vue/astro.config.mjs: -------------------------------------------------------------------------------- 1 | import Vue from '@astrojs/vue' 2 | import { defineConfig } from 'astro/config' 3 | import Icons from 'unplugin-icons/vite' 4 | 5 | // https://astro.build/config 6 | export default defineConfig({ 7 | integrations: [ 8 | Vue(), 9 | ], 10 | vite: { 11 | plugins: [ 12 | Icons({ 13 | compiler: 'vue3', 14 | }), 15 | ], 16 | }, 17 | }) 18 | -------------------------------------------------------------------------------- /examples/astro-vue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "astro-example", 3 | "type": "module", 4 | "version": "0.0.1", 5 | "private": true, 6 | "description": "unplugin-icons + Astro", 7 | "scripts": { 8 | "astro": "astro", 9 | "build": "astro build", 10 | "dev": "astro dev", 11 | "preview": "astro preview", 12 | "start": "astro dev" 13 | }, 14 | "dependencies": { 15 | "@astrojs/vue": "^4.5.3", 16 | "astro": "^4.16.18" 17 | }, 18 | "devDependencies": { 19 | "@iconify/json": "^2.2.308", 20 | "unplugin-icons": "workspace:*" 21 | }, 22 | "stackblitz": { 23 | "installDependencies": false, 24 | "startCommand": "node .stackblitz.js && npm install && npm run dev" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /examples/astro-vue/public/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 19 | -------------------------------------------------------------------------------- /examples/astro-vue/src/components/HomeLink.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | 11 | 18 | -------------------------------------------------------------------------------- /examples/astro-vue/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /examples/astro-vue/src/layouts/Layout.astro: -------------------------------------------------------------------------------- 1 | --- 2 | export interface Props { 3 | title: string; 4 | } 5 | const { title } = Astro.props; 6 | --- 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | {title} 16 | 17 | 18 | 19 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /examples/astro-vue/src/pages/index.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Layout from "../layouts/Layout.astro"; 3 | import IconParkAbnormal from "~icons/icon-park/abnormal"; 4 | 5 | import HomeLink from "../components/HomeLink.vue"; 6 | --- 7 | 8 | 9 |
10 | 11 |
12 | 13 |
14 |
15 | -------------------------------------------------------------------------------- /examples/astro-vue/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/strict", 3 | "compilerOptions": { 4 | "types": ["unplugin-icons/types/vue"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/astro/.stackblitz.js: -------------------------------------------------------------------------------- 1 | import { promises as fsPromises } from 'node:fs' 2 | 3 | updatePackageJson() 4 | 5 | async function updatePackageJson() { 6 | const filename = './package.json' 7 | try { 8 | const contents = await fsPromises.readFile(filename, 'utf-8') 9 | const updatedContent = contents.replace('workspace:*', 'latest') 10 | await fsPromises.writeFile(filename, updatedContent) 11 | } 12 | catch (err) { 13 | console.error(err) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/astro/astro.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'astro/config' 2 | import Icons from 'unplugin-icons/vite' 3 | 4 | // https://astro.build/config 5 | export default defineConfig({ 6 | vite: { 7 | plugins: [ 8 | Icons({ 9 | compiler: 'astro', 10 | }), 11 | ], 12 | }, 13 | }) 14 | -------------------------------------------------------------------------------- /examples/astro/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "astro-example", 3 | "type": "module", 4 | "version": "0.0.1", 5 | "private": true, 6 | "description": "unplugin-icons + Astro", 7 | "scripts": { 8 | "dev": "astro dev", 9 | "start": "astro dev", 10 | "build": "astro build", 11 | "preview": "astro preview", 12 | "astro": "astro" 13 | }, 14 | "dependencies": { 15 | "astro": "^4.16.18" 16 | }, 17 | "devDependencies": { 18 | "@iconify/json": "^2.2.308", 19 | "unplugin-icons": "workspace:*" 20 | }, 21 | "stackblitz": { 22 | "installDependencies": false, 23 | "startCommand": "node .stackblitz.js && npm install && npm run dev" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/astro/public/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 19 | -------------------------------------------------------------------------------- /examples/astro/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /examples/astro/src/layouts/Layout.astro: -------------------------------------------------------------------------------- 1 | --- 2 | export interface Props { 3 | title: string; 4 | } 5 | const { title } = Astro.props; 6 | --- 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | {title} 16 | 17 | 18 | 19 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /examples/astro/src/pages/index.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Layout from "../layouts/Layout.astro"; 3 | import AstroLogo from "~icons/logos/astro"; 4 | import MdiStore24Hour from "~icons/mdi/store-24-hour"; 5 | import MdiAlarmOff from "~icons/mdi/alarm-off"; 6 | import IconParkAbnormal from "~icons/icon-park/abnormal"; 7 | import RawMdiAlarmOff from "~icons/mdi/alarm-off?raw&width=4em&height=4em"; 8 | import RawMdiAlarmOff2 from "~icons/mdi/alarm-off?raw&width=1em&height=1em"; 9 | --- 10 | 11 | 12 |
13 | 14 |
15 |
16 | 17 | 18 | 19 | 20 | 21 |
22 |
23 | 24 | 29 | -------------------------------------------------------------------------------- /examples/astro/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/strict", 3 | "compilerOptions": { 4 | "types": ["unplugin-icons/types/astro"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/next/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env.local 29 | .env.development.local 30 | .env.test.local 31 | .env.production.local 32 | 33 | # vercel 34 | .vercel 35 | -------------------------------------------------------------------------------- /examples/next/.stackblitz.js: -------------------------------------------------------------------------------- 1 | const { promises } = require('node:fs') 2 | 3 | updatePackageJson() 4 | 5 | async function updatePackageJson() { 6 | const filename = './package.json' 7 | try { 8 | const contents = await promises.readFile(filename, 'utf-8') 9 | const updatedContent = contents.replace('workspace:*', 'latest') 10 | await promises.writeFile(filename, updatedContent) 11 | } 12 | catch (err) { 13 | console.error(err) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/next/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /examples/next/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | module.exports = { 3 | reactStrictMode: true, 4 | webpack(config) { 5 | config.plugins.push( 6 | require('unplugin-icons/webpack').default({ 7 | compiler: 'jsx', 8 | jsx: 'react', 9 | }), 10 | ) 11 | 12 | return config 13 | }, 14 | } 15 | -------------------------------------------------------------------------------- /examples/next/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next-example", 3 | "private": true, 4 | "description": "unplugin-icons + Next", 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start" 9 | }, 10 | "dependencies": { 11 | "next": "13.4.19", 12 | "react": "18.2.0", 13 | "react-dom": "18.2.0" 14 | }, 15 | "devDependencies": { 16 | "@iconify/json": "2.2.110", 17 | "@svgr/core": "8.1.0", 18 | "@svgr/plugin-jsx": "^8.1.0", 19 | "@types/node": "20.5.9", 20 | "@types/react": "18.2.21", 21 | "typescript": "5.2.2", 22 | "unplugin-icons": "workspace:*" 23 | }, 24 | "stackblitz": { 25 | "installDependencies": false, 26 | "startCommand": "node .stackblitz.js && npm install && npm run dev" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/next/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import type { AppProps } from 'next/app' 2 | import '../styles/globals.css' 3 | 4 | function MyApp({ Component, pageProps }: AppProps) { 5 | return 6 | } 7 | 8 | export default MyApp 9 | -------------------------------------------------------------------------------- /examples/next/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import type { NextPage } from 'next' 2 | import Head from 'next/head' 3 | import IconArrowRight from '~icons/dashicons/arrow-right.jsx' 4 | import NextLogo from '~icons/logos/nextjs.jsx' 5 | import VercelLogo from '~icons/logos/vercel.jsx' 6 | import styles from '../styles/Home.module.css' 7 | 8 | const Home: NextPage = () => { 9 | return ( 10 | 83 | ) 84 | } 85 | 86 | export default Home 87 | -------------------------------------------------------------------------------- /examples/next/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unplugin/unplugin-icons/f018da55f270d37b3549ee4a44cd1425eafbf681/examples/next/public/favicon.ico -------------------------------------------------------------------------------- /examples/next/styles/Home.module.css: -------------------------------------------------------------------------------- 1 | .container { 2 | padding: 0 2rem; 3 | } 4 | 5 | .main { 6 | min-height: 100vh; 7 | padding: 4rem 0; 8 | flex: 1; 9 | display: flex; 10 | flex-direction: column; 11 | justify-content: center; 12 | align-items: center; 13 | } 14 | 15 | .footer { 16 | display: flex; 17 | flex: 1; 18 | padding: 2rem 0; 19 | border-top: 1px solid #eaeaea; 20 | justify-content: center; 21 | align-items: center; 22 | } 23 | 24 | .footer a { 25 | display: flex; 26 | justify-content: center; 27 | align-items: center; 28 | flex-grow: 1; 29 | } 30 | 31 | .title a { 32 | color: #0070f3; 33 | text-decoration: none; 34 | } 35 | 36 | .title a:hover, 37 | .title a:focus, 38 | .title a:active { 39 | text-decoration: underline; 40 | } 41 | 42 | .title { 43 | margin: 0; 44 | line-height: 1.15; 45 | font-size: 4rem; 46 | } 47 | 48 | .title, 49 | .description { 50 | text-align: center; 51 | } 52 | 53 | .description { 54 | margin: 4rem 0; 55 | line-height: 1.5; 56 | font-size: 1.5rem; 57 | } 58 | 59 | .code { 60 | background: #fafafa; 61 | border-radius: 5px; 62 | padding: 0.75rem; 63 | font-size: 1.1rem; 64 | font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, 65 | Bitstream Vera Sans Mono, Courier New, monospace; 66 | } 67 | 68 | .grid { 69 | display: flex; 70 | align-items: center; 71 | justify-content: center; 72 | flex-wrap: wrap; 73 | max-width: 800px; 74 | } 75 | 76 | .card { 77 | margin: 1rem; 78 | padding: 1.5rem; 79 | text-align: left; 80 | color: inherit; 81 | text-decoration: none; 82 | border: 1px solid #eaeaea; 83 | border-radius: 10px; 84 | transition: color 0.15s ease, border-color 0.15s ease; 85 | max-width: 300px; 86 | } 87 | 88 | .card:hover, 89 | .card:focus, 90 | .card:active { 91 | color: #0070f3; 92 | border-color: #0070f3; 93 | } 94 | 95 | .card h2 { 96 | margin: 0 0 1rem 0; 97 | font-size: 1.5rem; 98 | } 99 | 100 | .card p { 101 | margin: 0; 102 | font-size: 1.25rem; 103 | line-height: 1.5; 104 | } 105 | 106 | .logo { 107 | height: 1em; 108 | margin-left: 0.5rem; 109 | } 110 | 111 | @media (max-width: 600px) { 112 | .grid { 113 | width: 100%; 114 | flex-direction: column; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /examples/next/styles/globals.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | padding: 0; 4 | margin: 0; 5 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 6 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 7 | } 8 | 9 | a { 10 | color: inherit; 11 | text-decoration: none; 12 | } 13 | 14 | * { 15 | box-sizing: border-box; 16 | } 17 | -------------------------------------------------------------------------------- /examples/next/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "incremental": true, 4 | "target": "es5", 5 | "jsx": "preserve", 6 | "lib": ["dom", "dom.iterable", "esnext"], 7 | "module": "esnext", 8 | "moduleResolution": "node", 9 | "resolveJsonModule": true, 10 | "types": ["unplugin-icons/types/react"], 11 | "allowJs": true, 12 | "strict": true, 13 | "noEmit": true, 14 | "esModuleInterop": true, 15 | "forceConsistentCasingInFileNames": true, 16 | "isolatedModules": true, 17 | "skipLibCheck": true 18 | }, 19 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 20 | "exclude": ["node_modules"] 21 | } 22 | -------------------------------------------------------------------------------- /examples/nuxt3/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log* 3 | .nuxt 4 | .nitro 5 | .cache 6 | .output 7 | .env 8 | dist 9 | -------------------------------------------------------------------------------- /examples/nuxt3/.npmrc: -------------------------------------------------------------------------------- 1 | shamefully-hoist=true 2 | -------------------------------------------------------------------------------- /examples/nuxt3/.stackblitz.js: -------------------------------------------------------------------------------- 1 | import { promises as fsPromises } from 'node:fs' 2 | 3 | updatePackageJson() 4 | 5 | async function updatePackageJson() { 6 | const filename = './package.json' 7 | try { 8 | const contents = await fsPromises.readFile(filename, 'utf-8') 9 | const updatedContent = contents.replace('link:../..', 'latest') 10 | await fsPromises.writeFile(filename, updatedContent) 11 | } 12 | catch (err) { 13 | console.error(err) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/nuxt3/README.md: -------------------------------------------------------------------------------- 1 | # Nuxt 3 Minimal Starter 2 | 3 | Look at the [nuxt 3 documentation](https://v3.nuxtjs.org) to learn more. 4 | 5 | ## Setup 6 | 7 | Make sure to install the dependencies: 8 | 9 | ```bash 10 | # yarn 11 | yarn install 12 | 13 | # npm 14 | npm install 15 | 16 | # pnpm 17 | pnpm install --shamefully-hoist 18 | ``` 19 | 20 | ## Development Server 21 | 22 | Start the development server on http://localhost:3000 23 | 24 | ```bash 25 | npm run dev 26 | ``` 27 | 28 | ## Production 29 | 30 | Build the application for production: 31 | 32 | ```bash 33 | npm run build 34 | ``` 35 | 36 | Locally preview production build: 37 | 38 | ```bash 39 | npm run preview 40 | ``` 41 | 42 | Checkout the [deployment documentation](https://v3.nuxtjs.org/guide/deploy/presets) for more information. 43 | -------------------------------------------------------------------------------- /examples/nuxt3/app.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 22 | -------------------------------------------------------------------------------- /examples/nuxt3/components.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | /* prettier-ignore */ 3 | // @ts-nocheck 4 | // Generated by unplugin-vue-components 5 | // Read more: https://github.com/vuejs/core/pull/3399 6 | export {} 7 | 8 | declare module 'vue' { 9 | export interface GlobalComponents { 10 | RouterLink: typeof import('vue-router')['RouterLink'] 11 | RouterView: typeof import('vue-router')['RouterView'] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/nuxt3/components/Circle.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /examples/nuxt3/components/LayoutHeader.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /examples/nuxt3/nuxt.config.ts: -------------------------------------------------------------------------------- 1 | import IconsResolver from 'unplugin-icons/resolver' 2 | import ViteComponents from 'unplugin-vue-components/vite' 3 | 4 | // https://v3.nuxtjs.org/api/configuration/nuxt.config 5 | export default defineNuxtConfig({ 6 | modules: [ 7 | 'unplugin-icons/nuxt', 8 | ], 9 | vite: { 10 | plugins: [ 11 | ViteComponents({ 12 | resolvers: [ 13 | IconsResolver({ 14 | prefix: '', 15 | strict: true, 16 | }), 17 | ], 18 | dts: true, 19 | }), 20 | ], 21 | }, 22 | }) 23 | -------------------------------------------------------------------------------- /examples/nuxt3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt3-example", 3 | "type": "module", 4 | "private": true, 5 | "description": "unplugin-icons + Nuxt 3", 6 | "scripts": { 7 | "build": "nuxt build", 8 | "dev": "nuxt dev", 9 | "generate": "nuxt generate", 10 | "preview": "nuxt preview" 11 | }, 12 | "devDependencies": { 13 | "@iconify-json/logos": "^1.2.3", 14 | "@iconify-json/mdi": "^1.2.1", 15 | "nuxt": "^3.14.1592", 16 | "unplugin-icons": "link:../..", 17 | "unplugin-vue-components": "^0.27.5" 18 | }, 19 | "stackblitz": { 20 | "installDependencies": false, 21 | "startCommand": "node .stackblitz.js && npm install && npm run dev" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /examples/nuxt3/pnpm-workspace.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unplugin/unplugin-icons/f018da55f270d37b3549ee4a44cd1425eafbf681/examples/nuxt3/pnpm-workspace.yaml -------------------------------------------------------------------------------- /examples/nuxt3/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // https://v3.nuxtjs.org/concepts/typescript 3 | "extends": "./.nuxt/tsconfig.json" 4 | } 5 | -------------------------------------------------------------------------------- /examples/rspack-vue3/.gitignore: -------------------------------------------------------------------------------- 1 | # Local 2 | .DS_Store 3 | *.local 4 | *.log* 5 | 6 | # Dist 7 | node_modules 8 | dist/ 9 | 10 | # IDE 11 | .vscode/* 12 | !.vscode/extensions.json 13 | .idea 14 | -------------------------------------------------------------------------------- /examples/rspack-vue3/.stackblitz.js: -------------------------------------------------------------------------------- 1 | import { promises as fsPromises } from 'node:fs' 2 | 3 | updatePackageJson() 4 | 5 | async function updatePackageJson() { 6 | const filename = './package.json' 7 | try { 8 | const contents = await fsPromises.readFile(filename, 'utf-8') 9 | const updatedContent = contents.replace('workspace:*', 'latest') 10 | await fsPromises.writeFile(filename, updatedContent) 11 | } 12 | catch (err) { 13 | console.error(err) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/rspack-vue3/README.md: -------------------------------------------------------------------------------- 1 | # Rspack Project 2 | 3 | ## Setup 4 | 5 | Install the dependencies: 6 | 7 | ```bash 8 | npm install 9 | ``` 10 | 11 | ## Get Started 12 | 13 | Start the dev server: 14 | 15 | ```bash 16 | npm run dev 17 | ``` 18 | 19 | Build the app for production: 20 | 21 | ```bash 22 | npm run build 23 | ``` 24 | -------------------------------------------------------------------------------- /examples/rspack-vue3/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Vue 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/rspack-vue3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rspack", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "NODE_ENV=development rspack serve", 7 | "build": "NODE_ENV=production rspack build" 8 | }, 9 | "dependencies": { 10 | "vue": "^3.4.21" 11 | }, 12 | "devDependencies": { 13 | "@iconify/json": "^2.2.308", 14 | "@rspack/cli": "^1.2.3", 15 | "@rspack/core": "^1.2.3", 16 | "unplugin-icons": "workspace:*", 17 | "vue-loader": "^17.4.2" 18 | }, 19 | "stackblitz": { 20 | "installDependencies": false, 21 | "startCommand": "node .stackblitz.js && npm install && npm run dev" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /examples/rspack-vue3/rspack.config.mjs: -------------------------------------------------------------------------------- 1 | import { dirname } from 'node:path' 2 | import { fileURLToPath } from 'node:url' 3 | import { defineConfig } from '@rspack/cli' 4 | import { rspack } from '@rspack/core' 5 | import Icons from 'unplugin-icons/rspack' 6 | import { VueLoaderPlugin } from 'vue-loader' 7 | 8 | const __dirname = dirname(fileURLToPath(import.meta.url)) 9 | 10 | // Target browsers, see: https://github.com/browserslist/browserslist 11 | const targets = ['chrome >= 87', 'edge >= 88', 'firefox >= 78', 'safari >= 14'] 12 | 13 | export default defineConfig({ 14 | context: __dirname, 15 | entry: { 16 | main: './src/main.js', 17 | }, 18 | resolve: { 19 | extensions: ['...', '.ts', '.vue'], 20 | }, 21 | module: { 22 | rules: [ 23 | { 24 | test: /\.vue$/, 25 | loader: 'vue-loader', 26 | options: { 27 | experimentalInlineMatchResource: true, 28 | }, 29 | }, 30 | { 31 | test: /\.(js|ts)$/, 32 | use: [ 33 | { 34 | loader: 'builtin:swc-loader', 35 | options: { 36 | jsc: { 37 | parser: { 38 | syntax: 'typescript', 39 | }, 40 | }, 41 | env: { targets }, 42 | }, 43 | }, 44 | ], 45 | }, 46 | { 47 | test: /\.svg/, 48 | type: 'asset/resource', 49 | }, 50 | ], 51 | }, 52 | plugins: [ 53 | new rspack.HtmlRspackPlugin({ 54 | template: './index.html', 55 | }), 56 | new rspack.DefinePlugin({ 57 | __VUE_OPTIONS_API__: true, 58 | __VUE_PROD_DEVTOOLS__: false, 59 | }), 60 | new VueLoaderPlugin(), 61 | Icons(), 62 | ], 63 | optimization: { 64 | minimizer: [ 65 | new rspack.SwcJsMinimizerRspackPlugin(), 66 | new rspack.LightningCssMinimizerRspackPlugin({ 67 | minimizerOptions: { targets }, 68 | }), 69 | ], 70 | }, 71 | experiments: { 72 | css: true, 73 | }, 74 | }) 75 | -------------------------------------------------------------------------------- /examples/rspack-vue3/src/App.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 21 | 22 | 38 | -------------------------------------------------------------------------------- /examples/rspack-vue3/src/assets/vue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/rspack-vue3/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 31 | 32 | 37 | -------------------------------------------------------------------------------- /examples/rspack-vue3/src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import App from './App.vue' 3 | import './style.css' 4 | 5 | createApp(App).mount('#app') 6 | -------------------------------------------------------------------------------- /examples/rspack-vue3/src/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, Avenir, Helvetica, Arial, sans-serif; 3 | font-size: 16px; 4 | line-height: 24px; 5 | font-weight: 400; 6 | 7 | color-scheme: light dark; 8 | color: rgba(255, 255, 255, 0.87); 9 | background-color: #242424; 10 | 11 | font-synthesis: none; 12 | text-rendering: optimizeLegibility; 13 | -webkit-font-smoothing: antialiased; 14 | -moz-osx-font-smoothing: grayscale; 15 | -webkit-text-size-adjust: 100%; 16 | } 17 | 18 | a { 19 | font-weight: 500; 20 | color: #646cff; 21 | text-decoration: inherit; 22 | } 23 | a:hover { 24 | color: #535bf2; 25 | } 26 | 27 | a { 28 | font-weight: 500; 29 | color: #646cff; 30 | text-decoration: inherit; 31 | } 32 | a:hover { 33 | color: #535bf2; 34 | } 35 | 36 | body { 37 | margin: 0; 38 | display: flex; 39 | place-items: center; 40 | min-width: 320px; 41 | min-height: 100vh; 42 | } 43 | 44 | h1 { 45 | font-size: 3.2em; 46 | line-height: 1.1; 47 | } 48 | 49 | button { 50 | border-radius: 8px; 51 | border: 1px solid transparent; 52 | padding: 0.6em 1.2em; 53 | font-size: 1em; 54 | font-weight: 500; 55 | font-family: inherit; 56 | background-color: #1a1a1a; 57 | cursor: pointer; 58 | transition: border-color 0.25s; 59 | } 60 | button:hover { 61 | border-color: #646cff; 62 | } 63 | button:focus, 64 | button:focus-visible { 65 | outline: 4px auto -webkit-focus-ring-color; 66 | } 67 | 68 | .card { 69 | padding: 2em; 70 | } 71 | 72 | #app { 73 | max-width: 1280px; 74 | margin: 0 auto; 75 | padding: 2rem; 76 | text-align: center; 77 | } 78 | 79 | @media (prefers-color-scheme: light) { 80 | :root { 81 | color: #213547; 82 | background-color: #ffffff; 83 | } 84 | a:hover { 85 | color: #747bff; 86 | } 87 | button { 88 | background-color: #f9f9f9; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /examples/sveltekit/.stackblitz.js: -------------------------------------------------------------------------------- 1 | import { promises as fsPromises } from 'node:fs' 2 | 3 | updatePackageJson() 4 | 5 | async function updatePackageJson() { 6 | const filename = './package.json' 7 | try { 8 | const contents = await fsPromises.readFile(filename, 'utf-8') 9 | const updatedContent = contents.replace('workspace:*', 'latest') 10 | await fsPromises.writeFile(filename, updatedContent) 11 | } 12 | catch (err) { 13 | console.error(err) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/sveltekit/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sveltekit-example", 3 | "type": "module", 4 | "private": true, 5 | "description": "unplugin-icons + SvelteKit", 6 | "scripts": { 7 | "build": "vite build", 8 | "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", 9 | "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", 10 | "dev": "vite dev", 11 | "preview": "vite preview" 12 | }, 13 | "devDependencies": { 14 | "@iconify-json/icon-park": "^1.2.2", 15 | "@iconify-json/logos": "^1.2.4", 16 | "@iconify-json/mdi": "^1.2.3", 17 | "@sveltejs/kit": "^2.17.2", 18 | "@sveltejs/vite-plugin-svelte": "^5.0.3", 19 | "svelte": "^5.20.1", 20 | "svelte-check": "^4.1.4", 21 | "tslib": "^2.8.1", 22 | "typescript": "^5.7.3", 23 | "unplugin-icons": "workspace:*" 24 | }, 25 | "stackblitz": { 26 | "installDependencies": false, 27 | "startCommand": "node .stackblitz.js && npm install && npm run dev" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/sveltekit/src/app.d.ts: -------------------------------------------------------------------------------- 1 | import 'unplugin-icons/types/svelte' 2 | 3 | declare global { 4 | namespace App { 5 | // interface Error {} 6 | // interface Locals {} 7 | // interface PageData {} 8 | // interface Platform {} 9 | } 10 | } 11 | 12 | export {} 13 | -------------------------------------------------------------------------------- /examples/sveltekit/src/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | %sveltekit.head% 6 | 7 | 8 |
%sveltekit.body%
9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/sveltekit/src/routes/+page.svelte: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 | 12 |
13 |
14 | 15 | 16 | 17 | {@html RawMdiAlarmOff} 18 | {@html RawMdiAlarmOff2} 19 |
20 | 21 | 26 | 27 | -------------------------------------------------------------------------------- /examples/sveltekit/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unplugin/unplugin-icons/f018da55f270d37b3549ee4a44cd1425eafbf681/examples/sveltekit/static/favicon.ico -------------------------------------------------------------------------------- /examples/sveltekit/svelte.config.js: -------------------------------------------------------------------------------- 1 | import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' 2 | 3 | /** @type {import('@sveltejs/kit').Config} */ 4 | const config = { 5 | // Consult https://github.com/sveltejs/svelte-preprocess 6 | // for more information about preprocessors 7 | preprocess: vitePreprocess(), 8 | } 9 | 10 | export default config 11 | -------------------------------------------------------------------------------- /examples/sveltekit/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.svelte-kit/tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /examples/sveltekit/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { sveltekit } from '@sveltejs/kit/vite' 2 | import Icons from 'unplugin-icons/vite' 3 | import { defineConfig } from 'vite' 4 | 5 | export default defineConfig({ 6 | plugins: [ 7 | sveltekit(), 8 | Icons({ 9 | compiler: 'svelte', 10 | }), 11 | ], 12 | }) 13 | -------------------------------------------------------------------------------- /examples/vite-preact/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | dist-ssr 5 | *.local 6 | -------------------------------------------------------------------------------- /examples/vite-preact/.stackblitz.js: -------------------------------------------------------------------------------- 1 | import { promises as fsPromises } from 'node:fs' 2 | 3 | updatePackageJson() 4 | 5 | async function updatePackageJson() { 6 | const filename = './package.json' 7 | try { 8 | const contents = await fsPromises.readFile(filename, 'utf-8') 9 | const updatedContent = contents.replace('workspace:*', 'latest') 10 | await fsPromises.writeFile(filename, updatedContent) 11 | } 12 | catch (err) { 13 | console.error(err) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/vite-preact/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Vite App 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /examples/vite-preact/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite-preact-example", 3 | "type": "module", 4 | "version": "0.0.0", 5 | "private": true, 6 | "description": "unplugin-icons + Preact (Vite)", 7 | "scripts": { 8 | "dev": "vite", 9 | "build": "tsc && vite build", 10 | "serve": "vite preview" 11 | }, 12 | "dependencies": { 13 | "preact": "^10.26.1" 14 | }, 15 | "devDependencies": { 16 | "@iconify-json/logos": "^1.2.4", 17 | "@preact/preset-vite": "^2.10.1", 18 | "@svgr/core": "^8.1.0", 19 | "@svgr/plugin-jsx": "^8.1.0", 20 | "typescript": "^5.7.3", 21 | "unplugin-icons": "workspace:*", 22 | "vite": "^6.1.0", 23 | "vite-plugin-inspect": "^10.2.1" 24 | }, 25 | "stackblitz": { 26 | "installDependencies": false, 27 | "startCommand": "node .stackblitz.js && npm install && npm run dev" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/vite-preact/src/app.tsx: -------------------------------------------------------------------------------- 1 | import Logo from '~icons/logos/preact' 2 | import RawLogo from '~icons/logos/preact?raw' 3 | 4 | export function App() { 5 | return ( 6 | <> 7 | 8 | 9 |

Hello Vite + Preact!

10 |

11 | 17 | Learn Preact 18 | 19 |

20 | 21 | ) 22 | } 23 | -------------------------------------------------------------------------------- /examples/vite-preact/src/index.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | height: 100%; 4 | width: 100%; 5 | padding: 0; 6 | margin: 0; 7 | background: #fafafa; 8 | font-family: 'Helvetica Neue', arial, sans-serif; 9 | font-weight: 400; 10 | color: #444; 11 | -webkit-font-smoothing: antialiased; 12 | -moz-osx-font-smoothing: grayscale; 13 | } 14 | 15 | * { 16 | box-sizing: border-box; 17 | } 18 | 19 | #app { 20 | height: 100%; 21 | text-align: center; 22 | background-color: #673ab880; 23 | color: #fff; 24 | font-size: 1.5em; 25 | padding-top: 100px; 26 | } 27 | 28 | .link { 29 | color: #fff; 30 | } 31 | -------------------------------------------------------------------------------- /examples/vite-preact/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { render } from 'preact' 2 | import { App } from './app' 3 | import './index.css' 4 | 5 | render(, document.getElementById('app')!) 6 | -------------------------------------------------------------------------------- /examples/vite-preact/src/preact.d.ts: -------------------------------------------------------------------------------- 1 | import JSX = preact.JSX 2 | -------------------------------------------------------------------------------- /examples/vite-preact/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /examples/vite-preact/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "jsx": "preserve", 5 | "jsxFactory": "h", 6 | "jsxFragmentFactory": "Fragment", 7 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 8 | "module": "ESNext", 9 | "moduleResolution": "Node", 10 | "resolveJsonModule": true, 11 | "types": [ 12 | "unplugin-icons/types/preact" 13 | ], 14 | "allowJs": false, 15 | "strict": true, 16 | "noEmit": true, 17 | "allowSyntheticDefaultImports": true, 18 | "esModuleInterop": false, 19 | "forceConsistentCasingInFileNames": true, 20 | "isolatedModules": true, 21 | "skipLibCheck": false 22 | }, 23 | "include": ["src"] 24 | } 25 | -------------------------------------------------------------------------------- /examples/vite-preact/vite.config.ts: -------------------------------------------------------------------------------- 1 | import Preact from '@preact/preset-vite' 2 | import Icons from 'unplugin-icons/vite' 3 | import { defineConfig } from 'vite' 4 | import Inspect from 'vite-plugin-inspect' 5 | 6 | // https://vitejs.dev/config/ 7 | export default defineConfig({ 8 | plugins: [ 9 | Preact(), 10 | Inspect(), 11 | Icons({ 12 | compiler: 'jsx', 13 | jsx: 'preact', 14 | }), 15 | ], 16 | }) 17 | -------------------------------------------------------------------------------- /examples/vite-qwik/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | dist-ssr 5 | *.local 6 | .vscode 7 | .idea 8 | -------------------------------------------------------------------------------- /examples/vite-qwik/.stackblitz.js: -------------------------------------------------------------------------------- 1 | import { promises as fsPromises } from 'node:fs' 2 | 3 | updatePackageJson() 4 | 5 | async function updatePackageJson() { 6 | let filename = './package.json' 7 | try { 8 | const contents = await fsPromises.readFile(filename, 'utf-8') 9 | const updatedContent = contents 10 | .replace('workspace:*', 'latest') 11 | .replace('"eslint": "8.48.0",', '"eslint": "8.45.0",') 12 | .replace('"eslint-plugin-qwik": "1.2.10",', '"eslint-plugin-qwik": "1.2.11",') 13 | .replace('"@svgx/core": "^1.0.1",', '"@svgr/core": "^8.1.0", "@svgr/plugin-jsx": "^8.1.0",') 14 | await fsPromises.writeFile(filename, updatedContent) 15 | filename = './vite.config.ts' 16 | const viteConfigTs = await fsPromises.readFile(filename, 'utf-8') 17 | await fsPromises.writeFile(filename, viteConfigTs.replace('compiler: \'qwik\',', 'compiler: \'jsx\', jsx: \'qwik\',')) 18 | } 19 | catch (err) { 20 | console.error(err) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /examples/vite-qwik/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite-qwik-example", 3 | "type": "module", 4 | "private": true, 5 | "description": "unplugin-icons + Qwik (Vite)", 6 | "scripts": { 7 | "build": "qwik build", 8 | "build.client": "vite build", 9 | "build.preview": "vite build --ssr src/entry.preview.tsx", 10 | "build.types": "tsc --incremental --noEmit", 11 | "dev": "vite --mode ssr", 12 | "fmt": "prettier --write .", 13 | "fmt.check": "prettier --check .", 14 | "lint": "eslint \"src/**/*.ts*\"", 15 | "start": "vite --open --mode ssr", 16 | "qwik": "qwik" 17 | }, 18 | "devDependencies": { 19 | "@builder.io/qwik": "1.2.10", 20 | "@svgx/core": "^1.0.1", 21 | "@types/eslint": "8.44.2", 22 | "@types/node": "^22.13.4", 23 | "@types/node-fetch": "latest", 24 | "@typescript-eslint/eslint-plugin": "6.5.0", 25 | "@typescript-eslint/parser": "6.5.0", 26 | "eslint": "8.48.0", 27 | "eslint-plugin-qwik": "1.2.10", 28 | "node-fetch": "3.3.2", 29 | "prettier": "3.0.3", 30 | "typescript": "5.2.2", 31 | "undici": "5.23.0", 32 | "unplugin-icons": "workspace:*", 33 | "vite": "4.4.9", 34 | "vite-tsconfig-paths": "4.2.0" 35 | }, 36 | "stackblitz": { 37 | "installDependencies": false, 38 | "startCommand": "node .stackblitz.js && npm install && npm run dev" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /examples/vite-qwik/src/app.tsx: -------------------------------------------------------------------------------- 1 | import { component$ } from '@builder.io/qwik' 2 | import RiFlashlightLine from '~icons/ri/flashlight-line' 3 | 4 | export default component$(() => { 5 | return ( 6 |

7 | {' '} 8 | 9 | {' '} 10 | Welcome To Qwik With Icons 11 | {' '} 12 |

13 | ) 14 | }) 15 | -------------------------------------------------------------------------------- /examples/vite-qwik/src/entry.dev.tsx: -------------------------------------------------------------------------------- 1 | import type { RenderOptions } from '@builder.io/qwik/server' 2 | import { renderToString } from '@builder.io/qwik/server' 3 | import Root from './root' 4 | 5 | export default function (opts: RenderOptions) { 6 | return renderToString(, opts) 7 | } 8 | -------------------------------------------------------------------------------- /examples/vite-qwik/src/entry.ssr.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * WHAT IS THIS FILE? 3 | * 4 | * SSR entry point, in all cases the application is render outside the browser, this 5 | * entry point will be the common one. 6 | * 7 | * - Server (express, cloudflare...) 8 | * - npm run start 9 | * - npm run preview 10 | * - npm run build 11 | * 12 | */ 13 | import type { RenderToStreamOptions } from '@builder.io/qwik/server' 14 | import { renderToStream } from '@builder.io/qwik/server' 15 | import { manifest } from '@qwik-client-manifest' 16 | import Root from './root' 17 | 18 | export default function (opts: RenderToStreamOptions) { 19 | return renderToStream(, { 20 | manifest, 21 | ...opts, 22 | // Use container attributes to set attributes on the html tag. 23 | containerAttributes: { 24 | lang: 'en-us', 25 | ...opts.containerAttributes, 26 | }, 27 | }) 28 | } 29 | -------------------------------------------------------------------------------- /examples/vite-qwik/src/root.tsx: -------------------------------------------------------------------------------- 1 | import App from './app' 2 | 3 | export default () => { 4 | return ( 5 | <> 6 | 7 | Qwik With Icons 8 | 9 | 10 | 11 | 12 | 13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /examples/vite-qwik/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "incremental": true, 4 | "target": "ES2017", 5 | "jsx": "react-jsx", 6 | "jsxImportSource": "@builder.io/qwik", 7 | "lib": ["es2020", "DOM", "WebWorker", "DOM.Iterable"], 8 | "module": "ES2020", 9 | "moduleResolution": "node", 10 | "paths": { 11 | "~/*": ["./src/*"] 12 | }, 13 | "resolveJsonModule": true, 14 | "types": ["node", "vite/client", "unplugin-icons/types/qwik"], 15 | "allowJs": true, 16 | "strict": true, 17 | "noEmit": true, 18 | "outDir": "tmp", 19 | "esModuleInterop": true, 20 | "forceConsistentCasingInFileNames": true, 21 | "isolatedModules": true, 22 | "skipLibCheck": true 23 | }, 24 | "files": ["./.eslintrc.cjs"], 25 | "include": ["src"] 26 | } 27 | -------------------------------------------------------------------------------- /examples/vite-qwik/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { qwikVite } from '@builder.io/qwik/optimizer' 2 | import Icons from 'unplugin-icons/vite' 3 | import { defineConfig } from 'vite' 4 | import tsconfigPaths from 'vite-tsconfig-paths' 5 | 6 | export default defineConfig(() => { 7 | return { 8 | plugins: [ 9 | Icons({ 10 | autoInstall: true, 11 | compiler: 'qwik', 12 | }), 13 | qwikVite(), 14 | tsconfigPaths(), 15 | ], 16 | preview: { 17 | headers: { 18 | 'Cache-Control': 'public, max-age=600', 19 | }, 20 | }, 21 | } 22 | }) 23 | -------------------------------------------------------------------------------- /examples/vite-react/.stackblitz.js: -------------------------------------------------------------------------------- 1 | import { promises as fsPromises } from 'node:fs' 2 | 3 | updatePackageJson() 4 | 5 | async function updatePackageJson() { 6 | const filename = './package.json' 7 | try { 8 | const contents = await fsPromises.readFile(filename, 'utf-8') 9 | const updatedContent = contents.replace('workspace:*', 'latest') 10 | await fsPromises.writeFile(filename, updatedContent) 11 | } 12 | catch (err) { 13 | console.error(err) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/vite-react/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Vite App 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /examples/vite-react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite-react-example", 3 | "type": "module", 4 | "version": "0.0.0", 5 | "private": true, 6 | "description": "unplugin-icons + React (Vite)", 7 | "scripts": { 8 | "dev": "vite", 9 | "build": "vite build", 10 | "serve": "vite preview" 11 | }, 12 | "dependencies": { 13 | "react": "^18.3.1", 14 | "react-dom": "^18.3.1" 15 | }, 16 | "devDependencies": { 17 | "@iconify-json/logos": "^1.2.4", 18 | "@svgr/core": "^8.1.0", 19 | "@svgr/plugin-jsx": "^8.1.0", 20 | "@types/react": "^18.3.18", 21 | "@types/react-dom": "^18.3.5", 22 | "@vitejs/plugin-react-refresh": "^1.3.6", 23 | "typescript": "^5.7.3", 24 | "unplugin-icons": "workspace:*", 25 | "vite": "^6.1.0", 26 | "vite-plugin-inspect": "^10.2.1" 27 | }, 28 | "stackblitz": { 29 | "installDependencies": false, 30 | "startCommand": "node .stackblitz.js && npm install && npm run dev" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /examples/vite-react/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | 40 | button { 41 | font-size: calc(10px + 2vmin); 42 | } 43 | -------------------------------------------------------------------------------- /examples/vite-react/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react' 2 | import ReactLogo from '~icons/logos/react' 3 | import RawReactLogo from '~icons/logos/react?raw' 4 | import './App.css' 5 | 6 | function _a() { 7 | return 8 | } 9 | 10 | function App() { 11 | const [count, setCount] = useState(0) 12 | 13 | return ( 14 |
15 |
16 | 17 | 18 |

Hello Vite + React!

19 |

20 | 25 |

26 |

27 | Edit 28 | {' '} 29 | App.tsx 30 | {' '} 31 | and save to test HMR updates. 32 |

33 |

34 | 40 | Learn React 41 | 42 | {' | '} 43 | 49 | Vite Docs 50 | 51 |

52 |
53 |
54 | ) 55 | } 56 | 57 | export default App 58 | -------------------------------------------------------------------------------- /examples/vite-react/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /examples/vite-react/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import App from './App' 4 | import './index.css' 5 | 6 | ReactDOM.render( 7 | 8 | 9 | , 10 | document.getElementById('root'), 11 | ) 12 | -------------------------------------------------------------------------------- /examples/vite-react/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /examples/vite-react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "jsx": "react", 5 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 6 | "module": "ESNext", 7 | "moduleResolution": "Node", 8 | "resolveJsonModule": true, 9 | "types": [ 10 | "unplugin-icons/types/react" 11 | ], 12 | "allowJs": false, 13 | "strict": true, 14 | "noEmit": true, 15 | "allowSyntheticDefaultImports": true, 16 | "esModuleInterop": true, 17 | "forceConsistentCasingInFileNames": true, 18 | "isolatedModules": true, 19 | "skipLibCheck": false 20 | }, 21 | "include": ["./src"] 22 | } 23 | -------------------------------------------------------------------------------- /examples/vite-react/vite.config.ts: -------------------------------------------------------------------------------- 1 | import React from '@vitejs/plugin-react-refresh' 2 | import Icons from 'unplugin-icons/vite' 3 | import { defineConfig } from 'vite' 4 | import Inspect from 'vite-plugin-inspect' 5 | 6 | // https://vitejs.dev/config/ 7 | export default defineConfig({ 8 | plugins: [ 9 | React(), 10 | Icons({ 11 | compiler: 'jsx', 12 | jsx: 'react', 13 | }), 14 | Inspect(), 15 | ], 16 | }) 17 | -------------------------------------------------------------------------------- /examples/vite-solid/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist -------------------------------------------------------------------------------- /examples/vite-solid/.stackblitz.js: -------------------------------------------------------------------------------- 1 | import { promises as fsPromises } from 'node:fs' 2 | 3 | updatePackageJson() 4 | 5 | async function updatePackageJson() { 6 | const filename = './package.json' 7 | try { 8 | const contents = await fsPromises.readFile(filename, 'utf-8') 9 | const updatedContent = contents.replace('workspace:*', 'latest') 10 | await fsPromises.writeFile(filename, updatedContent) 11 | } 12 | catch (err) { 13 | console.error(err) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/vite-solid/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Solid App 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /examples/vite-solid/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite-solid-example", 3 | "type": "module", 4 | "private": true, 5 | "description": "unplugin-icons + Solid (Vite)", 6 | "license": "MIT", 7 | "scripts": { 8 | "start": "vite", 9 | "dev": "vite", 10 | "build": "vite build", 11 | "serve": "vite preview" 12 | }, 13 | "dependencies": { 14 | "solid-js": "^1.9.4" 15 | }, 16 | "devDependencies": { 17 | "@iconify-json/logos": "^1.2.4", 18 | "@svgr/core": "^8.1.0", 19 | "@svgr/plugin-jsx": "^8.1.0", 20 | "unplugin-icons": "workspace:*", 21 | "vite": "^6.1.0", 22 | "vite-plugin-solid": "^2.11.1" 23 | }, 24 | "stackblitz": { 25 | "installDependencies": false, 26 | "startCommand": "node .stackblitz.js && npm install && npm run dev" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/vite-solid/src/App.module.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .logo { 6 | animation: logo-spin infinite 20s linear; 7 | height: 20vmin; 8 | pointer-events: none; 9 | } 10 | 11 | .header { 12 | background-color: #282c34; 13 | min-height: 100vh; 14 | display: flex; 15 | flex-direction: column; 16 | align-items: center; 17 | justify-content: center; 18 | font-size: calc(10px + 2vmin); 19 | color: white; 20 | } 21 | 22 | .link { 23 | color: #b318f0; 24 | } 25 | -------------------------------------------------------------------------------- /examples/vite-solid/src/App.tsx: -------------------------------------------------------------------------------- 1 | import type { Component } from 'solid-js' 2 | 3 | import Icon from '~icons/logos/solidjs-icon' 4 | import styles from './App.module.css' 5 | import logo from './logo.svg' 6 | 7 | const App: Component = () => { 8 | return ( 9 |
10 |
11 | logo 12 |

13 | Vite + Solid 14 |

15 |

16 | 22 | Learn Solid 23 | 24 |
25 |
26 | ) 27 | } 28 | 29 | export default App 30 | -------------------------------------------------------------------------------- /examples/vite-solid/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", 4 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /examples/vite-solid/src/index.tsx: -------------------------------------------------------------------------------- 1 | import { render } from 'solid-js/web' 2 | 3 | import App from './App' 4 | import './index.css' 5 | 6 | render(() => , document.getElementById('root')) 7 | -------------------------------------------------------------------------------- /examples/vite-solid/src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/vite-solid/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "jsx": "preserve", 5 | "jsxImportSource": "solid-js", 6 | "module": "ESNext", 7 | "moduleResolution": "node", 8 | "types": ["vite/client", "unplugin-icons/types/solid"], 9 | "allowSyntheticDefaultImports": true, 10 | "esModuleInterop": true 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /examples/vite-solid/vite.config.ts: -------------------------------------------------------------------------------- 1 | import Icons from 'unplugin-icons/vite' 2 | import { defineConfig } from 'vite' 3 | import solidPlugin from 'vite-plugin-solid' 4 | 5 | export default defineConfig({ 6 | plugins: [ 7 | solidPlugin(), 8 | Icons({ 9 | compiler: 'jsx', 10 | jsx: 'preact', 11 | }), 12 | ], 13 | build: { 14 | target: 'esnext', 15 | polyfillDynamicImport: false, 16 | }, 17 | }) 18 | -------------------------------------------------------------------------------- /examples/vite-svelte/.stackblitz.js: -------------------------------------------------------------------------------- 1 | import { promises as fsPromises } from 'node:fs' 2 | 3 | updatePackageJson() 4 | 5 | async function updatePackageJson() { 6 | const filename = './package.json' 7 | try { 8 | const contents = await fsPromises.readFile(filename, 'utf-8') 9 | const updatedContent = contents.replace('workspace:*', 'latest') 10 | await fsPromises.writeFile(filename, updatedContent) 11 | } 12 | catch (err) { 13 | console.error(err) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/vite-svelte/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Vite App 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/vite-svelte/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite-svelte", 3 | "type": "module", 4 | "private": true, 5 | "description": "unplugin-icons + Svelte (Vite)", 6 | "scripts": { 7 | "build": "DEBUG='unplugin-icons:*' vite build", 8 | "dev": "DEBUG='unplugin-icons:*' vite", 9 | "serve": "npm run build && DEBUG='unplugin-icons:*' vite preview", 10 | "build-custom": "DEBUG='unplugin-icons:*' CUSTOM_COMPILER=true vite build", 11 | "dev-custom": "DEBUG='unplugin-icons:*' CUSTOM_COMPILER=true vite", 12 | "serve-custom": "npm run build-custom && DEBUG='unplugin-icons:*' CUSTOM_COMPILER=true vite preview" 13 | }, 14 | "devDependencies": { 15 | "@iconify-json/icon-park": "^1.2.2", 16 | "@iconify-json/logos": "^1.2.4", 17 | "@iconify-json/mdi": "^1.2.3", 18 | "@sveltejs/vite-plugin-svelte": "^5.0.3", 19 | "@tsconfig/svelte": "^5.0.4", 20 | "svelte": "^5.20.1", 21 | "svelte-check": "^4.1.4", 22 | "svelte-preprocess": "^6.0.3", 23 | "typescript": "^5.7.3", 24 | "unplugin-icons": "workspace:*", 25 | "vite": "^6.1.0" 26 | }, 27 | "stackblitz": { 28 | "installDependencies": false, 29 | "startCommand": "node .stackblitz.js && npm install && npm run dev" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /examples/vite-svelte/src/App.svelte: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 | 12 |
13 |
14 | 15 | 16 | 17 | {@html RawMdiAlarmOff} 18 | {@html RawMdiAlarmOff2} 19 |
20 | 21 | 26 | -------------------------------------------------------------------------------- /examples/vite-svelte/src/CustomSvg.svelte: -------------------------------------------------------------------------------- 1 | 4 | {@html content} 5 | -------------------------------------------------------------------------------- /examples/vite-svelte/src/main.ts: -------------------------------------------------------------------------------- 1 | import { mount } from 'svelte' 2 | import App from './App.svelte' 3 | 4 | const app = mount(App, { 5 | target: document.getElementById('app')!, 6 | }) 7 | 8 | export default app 9 | -------------------------------------------------------------------------------- /examples/vite-svelte/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | -------------------------------------------------------------------------------- /examples/vite-svelte/svelte.config.js: -------------------------------------------------------------------------------- 1 | import sveltePreprocess from 'svelte-preprocess' 2 | 3 | export default { 4 | // Consult https://github.com/sveltejs/svelte-preprocess 5 | // for more information about preprocessors 6 | preprocess: sveltePreprocess(), 7 | } 8 | -------------------------------------------------------------------------------- /examples/vite-svelte/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/svelte/tsconfig.json", 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "baseUrl": ".", 6 | "module": "esnext", 7 | "resolveJsonModule": true, 8 | /** 9 | * Typecheck JS in `.svelte` and `.js` files by default. 10 | * Disable checkJs if you'd like to use dynamic types in JS. 11 | * Note that setting allowJs false does not prevent the use 12 | * of JS in `.svelte` files. 13 | */ 14 | "allowJs": true, 15 | "checkJs": true 16 | }, 17 | "include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"] 18 | } 19 | -------------------------------------------------------------------------------- /examples/vite-svelte/vite.config.js: -------------------------------------------------------------------------------- 1 | import process from 'node:process' 2 | import { svelte } from '@sveltejs/vite-plugin-svelte' 3 | import Icons from 'unplugin-icons/vite' 4 | import { defineConfig } from 'vite' 5 | 6 | const options = process.env.CUSTOM_COMPILER === 'true' 7 | ? { 8 | compiler: { 9 | extension: 'svelte', 10 | compiler: compilerFactory(), 11 | }, 12 | } 13 | : { compiler: 'svelte' } 14 | 15 | export default defineConfig({ 16 | plugins: [ 17 | svelte(), 18 | Icons(options), 19 | ], 20 | }) 21 | 22 | function customSvelteCompiler(svg) { 23 | const openTagStart = svg.indexOf('', openTagStart) 25 | const closeTagStart = svg.lastIndexOf(' 29 | import CustomSvg from "/src/CustomSvg.svelte"; 30 | const content=\`${content.replace(/`/g, '`')}\`; 31 | 32 | 33 | ` 34 | } 35 | 36 | // to show how to use async 37 | async function compilerFactory() { 38 | return Promise.resolve(customSvelteCompiler) 39 | } 40 | -------------------------------------------------------------------------------- /examples/vite-vanilla/.stackblitz.js: -------------------------------------------------------------------------------- 1 | import { promises as fsPromises } from 'node:fs' 2 | 3 | updatePackageJson() 4 | 5 | async function updatePackageJson() { 6 | const filename = './package.json' 7 | try { 8 | const contents = await fsPromises.readFile(filename, 'utf-8') 9 | const updatedContent = contents.replace('workspace:*', 'latest') 10 | await fsPromises.writeFile(filename, updatedContent) 11 | } 12 | catch (err) { 13 | console.error(err) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/vite-vanilla/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /examples/vite-vanilla/main.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unplugin/unplugin-icons/f018da55f270d37b3549ee4a44cd1425eafbf681/examples/vite-vanilla/main.ts -------------------------------------------------------------------------------- /examples/vite-vanilla/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite-vanilla-example", 3 | "type": "module", 4 | "private": true, 5 | "description": "unplugin-icons + VanillaJS (Vite)", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build" 9 | }, 10 | "devDependencies": { 11 | "@iconify-json/mono-icons": "^1.2.0", 12 | "unplugin-icons": "workspace:*", 13 | "vite": "^6.1.0" 14 | }, 15 | "stackblitz": { 16 | "installDependencies": false, 17 | "startCommand": "node .stackblitz.js && npm install && npm run dev" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /examples/vite-vanilla/vite.config.ts: -------------------------------------------------------------------------------- 1 | import type { UserConfig } from 'vite' 2 | import Icons from 'unplugin-icons/vite' 3 | 4 | const config: UserConfig = { 5 | plugins: [ 6 | Icons({ 7 | compiler: 'raw', 8 | }), 9 | ], 10 | } 11 | 12 | export default config 13 | -------------------------------------------------------------------------------- /examples/vite-vue2/.stackblitz.js: -------------------------------------------------------------------------------- 1 | import { promises as fsPromises } from 'node:fs' 2 | 3 | updatePackageJson() 4 | 5 | async function updatePackageJson() { 6 | const filename = './package.json' 7 | try { 8 | const contents = await fsPromises.readFile(filename, 'utf-8') 9 | const updatedContent = contents.replace('workspace:*', 'latest') 10 | await fsPromises.writeFile(filename, updatedContent) 11 | } 12 | catch (err) { 13 | console.error(err) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/vite-vue2/App.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 39 | -------------------------------------------------------------------------------- /examples/vite-vue2/components.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | // @ts-nocheck 3 | // Generated by unplugin-vue-components 4 | // Read more: https://github.com/vuejs/core/pull/3399 5 | export {} 6 | 7 | /* prettier-ignore */ 8 | declare module 'vue' { 9 | export interface GlobalComponents { 10 | ICarbonAppConnectivity: typeof import('~icons/carbon/app-connectivity')['default'] 11 | IFaSolidDiceFive: typeof import('~icons/fa-solid/dice-five')['default'] 12 | IHeroiconsOutlineMenuAlt2: typeof import('~icons/heroicons-outline/menu-alt2')['default'] 13 | IIcTwotone23mp: typeof import('~icons/ic/twotone23mp')['default'] 14 | IIcTwotone24mp: typeof import('~icons/ic/twotone24mp')['default'] 15 | ILogosVue: typeof import('~icons/logos/vue')['default'] 16 | 'IMdi:cactus': typeof import('~icons/mdi/cactus')['default'] 17 | IMdiAccount: typeof import('~icons/mdi/account')['default'] 18 | IMdiDiceD12: typeof import('~icons/mdi/dice-d12')['default'] 19 | IMdiLightAlarm: typeof import('~icons/mdi-light/alarm')['default'] 20 | INotoV1FlagForFlagJapan: typeof import('~icons/noto-v1/flag-for-flag-japan')['default'] 21 | IRiApps2Line: typeof import('~icons/ri/apps2-line')['default'] 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /examples/vite-vue2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/vite-vue2/main.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | 4 | new Vue(App).$mount('#app') 5 | -------------------------------------------------------------------------------- /examples/vite-vue2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite-vue2-example", 3 | "type": "module", 4 | "private": true, 5 | "description": "unplugin-icons + Vue2 (Vite)", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build" 9 | }, 10 | "dependencies": { 11 | "vue": "^2.7.8" 12 | }, 13 | "devDependencies": { 14 | "@iconify-json/carbon": "^1.2.7", 15 | "@iconify-json/fa-solid": "^1.2.1", 16 | "@iconify-json/heroicons-outline": "^1.2.1", 17 | "@iconify-json/ic": "^1.2.2", 18 | "@iconify-json/logos": "^1.2.4", 19 | "@iconify-json/mdi": "^1.2.3", 20 | "@iconify-json/mdi-light": "^1.2.2", 21 | "@iconify-json/noto-v1": "^1.2.1", 22 | "@iconify-json/ri": "^1.2.5", 23 | "@iconify-json/vscode-icons": "^1.2.14", 24 | "@vitejs/plugin-vue2": "^2.3.3", 25 | "typescript": "^5.7.3", 26 | "unplugin-icons": "workspace:*", 27 | "unplugin-vue-components": "^28.2.0", 28 | "vite": "^6.1.0", 29 | "vue-template-compiler": "^2.7.16", 30 | "vue-template-es2015-compiler": "^1.9.1" 31 | }, 32 | "stackblitz": { 33 | "installDependencies": false, 34 | "startCommand": "node .stackblitz.js && npm install && npm run dev" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /examples/vite-vue2/vite.config.ts: -------------------------------------------------------------------------------- 1 | import type { UserConfig } from 'vite' 2 | import Vue from '@vitejs/plugin-vue2' 3 | import IconsResolver from 'unplugin-icons/resolver' 4 | import Icons from 'unplugin-icons/vite' 5 | import Components from 'unplugin-vue-components/vite' 6 | 7 | const config: UserConfig = { 8 | plugins: [ 9 | Vue(), 10 | Components({ 11 | resolvers: [ 12 | IconsResolver(), 13 | ], 14 | }), 15 | Icons({ 16 | defaultClass: 'text-red-100', 17 | defaultStyle: 'color: green', 18 | compiler: 'vue2', 19 | }), 20 | ], 21 | } 22 | 23 | export default config 24 | -------------------------------------------------------------------------------- /examples/vite-vue2/vue-shim.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.vue' { 2 | import type { defineComponent } from 'vue' 3 | 4 | const Component: ReturnType 5 | export default Component 6 | } 7 | 8 | declare module '*.md' { 9 | import type { defineComponent } from 'vue' 10 | 11 | const Component: ReturnType 12 | export default Component 13 | } 14 | -------------------------------------------------------------------------------- /examples/vite-vue3-legacy/.stackblitz.js: -------------------------------------------------------------------------------- 1 | import { promises as fsPromises } from 'node:fs' 2 | 3 | updatePackageJson() 4 | 5 | async function updatePackageJson() { 6 | const filename = './package.json' 7 | try { 8 | const contents = await fsPromises.readFile(filename, 'utf-8') 9 | const updatedContent = contents.replace('workspace:*', 'latest') 10 | await fsPromises.writeFile(filename, updatedContent) 11 | } 12 | catch (err) { 13 | console.error(err) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/vite-vue3-legacy/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 46 | -------------------------------------------------------------------------------- /examples/vite-vue3-legacy/assets/custom-a/SteeringWheel.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /examples/vite-vue3-legacy/assets/custom-a/car-a.svg: -------------------------------------------------------------------------------- 1 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /examples/vite-vue3-legacy/assets/giftbox.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /examples/vite-vue3-legacy/components.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | // @ts-nocheck 3 | // Generated by unplugin-vue-components 4 | // Read more: https://github.com/vuejs/core/pull/3399 5 | export {} 6 | 7 | /* prettier-ignore */ 8 | declare module 'vue' { 9 | export interface GlobalComponents { 10 | ICarbonAppConnectivity: typeof import('~icons/carbon/app-connectivity')['default'] 11 | 'ICodicon:diffIgnored': typeof import('~icons/codicon/diff-ignored')['default'] 12 | ICustomCarA: typeof import('~icons/custom/car-a')['default'] 13 | ICustomSteeringWheel: typeof import('~icons/custom/steering-wheel')['default'] 14 | IFaSolidDiceFive: typeof import('~icons/fa-solid/dice-five')['default'] 15 | IHeroiconsOutlineMenuAlt2: typeof import('~icons/heroicons-outline/menu-alt2')['default'] 16 | IIconParkAbnormal: typeof import('~icons/icon-park/abnormal')['default'] 17 | IIcTwotone23mp: typeof import('~icons/ic/twotone23mp')['default'] 18 | IIcTwotone24mp: typeof import('~icons/ic/twotone24mp')['default'] 19 | IInlineAsync: typeof import('~icons/inline/async')['default'] 20 | IInlineFoo: typeof import('~icons/inline/foo')['default'] 21 | ILogosVue: typeof import('~icons/logos/vue')['default'] 22 | IMdiAccount: typeof import('~icons/mdi/account')['default'] 23 | IMdiDiceD12: typeof import('~icons/mdi/dice-d12')['default'] 24 | IMdiLightAlarm: typeof import('~icons/mdi-light/alarm')['default'] 25 | INotoV1FlagForFlagJapan: typeof import('~icons/noto-v1/flag-for-flag-japan')['default'] 26 | IParkAbnormal: typeof import('~icons/icon-park/abnormal')['default'] 27 | IRiApps2Line: typeof import('~icons/ri/apps2-line')['default'] 28 | ITwemoji1stPlaceMedal: typeof import('~icons/twemoji/1st-place-medal')['default'] 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /examples/vite-vue3-legacy/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/vite-vue3-legacy/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import App from './App.vue' 3 | 4 | createApp(App).mount('#app') 5 | -------------------------------------------------------------------------------- /examples/vite-vue3-legacy/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite-vue3-legacy-example", 3 | "private": true, 4 | "description": "unplugin-icons + Vue3 legacy (Vite)", 5 | "scripts": { 6 | "dev": "DEBUG='unplugin-icons:*' vite", 7 | "build": "vite build" 8 | }, 9 | "dependencies": { 10 | "vue": "^3.2.37" 11 | }, 12 | "devDependencies": { 13 | "@iconify/json": "^2.2.308", 14 | "@vitejs/plugin-vue": "^5.2.1", 15 | "typescript": "^5.7.3", 16 | "unplugin-icons": "workspace:*", 17 | "unplugin-vue-components": "^28.2.0", 18 | "vite": "^6.1.0" 19 | }, 20 | "stackblitz": { 21 | "installDependencies": false, 22 | "startCommand": "node .stackblitz.js && npm install && npm run dev" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /examples/vite-vue3-legacy/vite.config.ts: -------------------------------------------------------------------------------- 1 | import type { UserConfig } from 'vite' 2 | import { promises as fs } from 'node:fs' 3 | import Vue from '@vitejs/plugin-vue' 4 | import { FileSystemIconLoader } from 'unplugin-icons/loaders' 5 | import IconsResolver from 'unplugin-icons/resolver' 6 | import Icons from 'unplugin-icons/vite' 7 | import Components from 'unplugin-vue-components/vite' 8 | 9 | const config: UserConfig = { 10 | plugins: [ 11 | Vue(), 12 | Icons({ 13 | compiler: 'vue3', 14 | iconSource: 'legacy', 15 | customCollections: { 16 | custom: FileSystemIconLoader('assets/custom-a'), 17 | inline: { 18 | foo: '', 19 | async: () => fs.readFile('assets/giftbox.svg', 'utf-8'), 20 | }, 21 | }, 22 | }), 23 | Components({ 24 | dts: true, 25 | resolvers: [ 26 | IconsResolver({ 27 | alias: { 28 | park: 'icon-park', 29 | }, 30 | customCollections: ['custom', 'inline'], 31 | }), 32 | ], 33 | }), 34 | ], 35 | } 36 | 37 | export default config 38 | -------------------------------------------------------------------------------- /examples/vite-vue3/.stackblitz.js: -------------------------------------------------------------------------------- 1 | import { promises as fsPromises } from 'node:fs' 2 | 3 | updatePackageJson() 4 | 5 | async function updatePackageJson() { 6 | const filename = './package.json' 7 | try { 8 | const contents = await fsPromises.readFile(filename, 'utf-8') 9 | const updatedContent = contents.replace('workspace:*', 'latest') 10 | await fsPromises.writeFile(filename, updatedContent) 11 | } 12 | catch (err) { 13 | console.error(err) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/vite-vue3/@test-scope/test-color-icons/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | IconifyChars, 3 | IconifyInfo, 4 | IconifyJSON, 5 | IconifyMetaData, 6 | } from '@iconify/types' 7 | 8 | export { IconifyChars, IconifyInfo, IconifyJSON, IconifyMetaData } 9 | 10 | export declare const icons: IconifyJSON 11 | export declare const info: IconifyInfo 12 | export declare const metadata: IconifyMetaData 13 | export declare const chars: IconifyChars 14 | -------------------------------------------------------------------------------- /examples/vite-vue3/@test-scope/test-color-icons/index.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable style/comma-dangle */ 2 | exports.icons = { 3 | prefix: 'test-color-icons', 4 | icons: { 5 | about: { 6 | body: '', 7 | } 8 | }, 9 | lastModified: 1672652184, 10 | width: 48, 11 | height: 48 12 | } 13 | exports.info = { 14 | prefix: 'test-color-icons', 15 | name: 'Test Color Icons', 16 | total: 1, 17 | author: { 18 | name: 'test' 19 | }, 20 | license: { 21 | title: 'MIT' 22 | }, 23 | samples: ['about'], 24 | height: 32, 25 | displayHeight: 16 26 | } 27 | exports.metadata = {} 28 | exports.chars = {} 29 | -------------------------------------------------------------------------------- /examples/vite-vue3/@test-scope/test-color-icons/index.mjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable style/comma-dangle */ 2 | const icons = { 3 | prefix: 'test-color-icons', 4 | icons: { 5 | about: { 6 | body: '' 7 | } 8 | }, 9 | lastModified: 1672652184, 10 | width: 48, 11 | height: 48 12 | } 13 | 14 | const info = { 15 | prefix: 'test-color-icons', 16 | name: 'Test Color Icons', 17 | total: 1, 18 | author: { 19 | name: 'test' 20 | }, 21 | license: { 22 | title: 'MIT' 23 | }, 24 | samples: ['about'], 25 | height: 32, 26 | displayHeight: 16 27 | } 28 | 29 | const metadata = {} 30 | const chars = {} 31 | export { chars, icons, info, metadata } 32 | -------------------------------------------------------------------------------- /examples/vite-vue3/@test-scope/test-color-icons/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@test-scope/test-color-icons", 3 | "exports": { 4 | "./*": "./*", 5 | ".": { 6 | "import": "./index.mjs", 7 | "require": "./index.js" 8 | } 9 | }, 10 | "main": "index.js", 11 | "module": "index.mjs", 12 | "types": "index.d.ts" 13 | } 14 | -------------------------------------------------------------------------------- /examples/vite-vue3/App.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 107 | 108 | 113 | -------------------------------------------------------------------------------- /examples/vite-vue3/assets/custom-a/SteeringWheel.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /examples/vite-vue3/assets/custom-a/car-a.svg: -------------------------------------------------------------------------------- 1 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /examples/vite-vue3/assets/giftbox.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /examples/vite-vue3/components.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | // @ts-nocheck 3 | // Generated by unplugin-vue-components 4 | // Read more: https://github.com/vuejs/core/pull/3399 5 | export {} 6 | 7 | /* prettier-ignore */ 8 | declare module 'vue' { 9 | export interface GlobalComponents { 10 | ICarbonAppConnectivity: typeof import('~icons/carbon/app-connectivity')['default'] 11 | ICustomCarA: typeof import('~icons/custom/car-a')['default'] 12 | ICustomSteeringWheel: typeof import('~icons/custom/steering-wheel')['default'] 13 | IFaSolidDiceFive: typeof import('~icons/fa-solid/dice-five')['default'] 14 | 'IHeroiconsOutline:menuAlt2': typeof import('~icons/heroicons-outline/menu-alt2')['default'] 15 | IHeroiconsOutlineMenuAlt2: typeof import('~icons/heroicons-outline/menu-alt2')['default'] 16 | IIconParkAbnormal: typeof import('~icons/icon-park/abnormal')['default'] 17 | IIcTwotone23mp: typeof import('~icons/ic/twotone23mp')['default'] 18 | IIcTwotone24mp: typeof import('~icons/ic/twotone24mp')['default'] 19 | IInlineAsync: typeof import('~icons/inline/async')['default'] 20 | IInlineFoo: typeof import('~icons/inline/foo')['default'] 21 | ILogosVue: typeof import('~icons/logos/vue')['default'] 22 | 'IMdi:cactus': typeof import('~icons/mdi/cactus')['default'] 23 | 'IMdi:lightFloodDown': typeof import('~icons/mdi/light-flood-down')['default'] 24 | IMdiAccount: typeof import('~icons/mdi/account')['default'] 25 | IMdiDiceD12: typeof import('~icons/mdi/dice-d12')['default'] 26 | IMdiLightAlarm: typeof import('~icons/mdi-light/alarm')['default'] 27 | INotoV1FlagForFlagJapan: typeof import('~icons/noto-v1/flag-for-flag-japan')['default'] 28 | IParkAbnormal: typeof import('~icons/icon-park/abnormal')['default'] 29 | 'IPlainColorIcons:about': typeof import('~icons/plain-color-icons/about')['default'] 30 | IRiApps2Line: typeof import('~icons/ri/apps2-line')['default'] 31 | 'ITestColorIcons:about': typeof import('~icons/test-color-icons/about')['default'] 32 | ITwemoji1stPlaceMedal: typeof import('~icons/twemoji/1st-place-medal')['default'] 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /examples/vite-vue3/getConfig.ts: -------------------------------------------------------------------------------- 1 | import { loadConfig, loadVitePluginConfig } from 'unconfig' 2 | 3 | loadConfig({ 4 | sources: [ 5 | loadVitePluginConfig({ 6 | pluginNames: ['unplugin-icons'], 7 | }), 8 | ], 9 | }) 10 | // eslint-disable-next-line no-console 11 | .then(i => console.log(i)) 12 | -------------------------------------------------------------------------------- /examples/vite-vue3/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/vite-vue3/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import App from './App.vue' 3 | 4 | createApp(App).mount('#app') 5 | -------------------------------------------------------------------------------- /examples/vite-vue3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite-vue3-example", 3 | "type": "module", 4 | "private": true, 5 | "description": "unplugin-icons + Vue3 (Vite)", 6 | "scripts": { 7 | "dev": "DEBUG='unplugin-icons:*' vite", 8 | "build": "vite build" 9 | }, 10 | "dependencies": { 11 | "vue": "^3.2.37" 12 | }, 13 | "devDependencies": { 14 | "@iconify-json/carbon": "^1.2.7", 15 | "@iconify-json/fa-solid": "^1.2.1", 16 | "@iconify-json/heroicons-outline": "^1.2.1", 17 | "@iconify-json/ic": "^1.2.2", 18 | "@iconify-json/icon-park": "^1.2.2", 19 | "@iconify-json/logos": "^1.2.4", 20 | "@iconify-json/mdi": "^1.2.3", 21 | "@iconify-json/mdi-light": "^1.2.2", 22 | "@iconify-json/noto-v1": "^1.2.1", 23 | "@iconify-json/ri": "^1.2.5", 24 | "@iconify-json/twemoji": "^1.2.2", 25 | "@iconify-json/vscode-icons": "^1.2.14", 26 | "@vitejs/plugin-vue": "^5.2.1", 27 | "typescript": "^5.7.3", 28 | "unconfig": "^7.0.0", 29 | "unplugin-icons": "workspace:*", 30 | "unplugin-vue-components": "^28.2.0", 31 | "vite": "^6.1.0" 32 | }, 33 | "stackblitz": { 34 | "installDependencies": false, 35 | "startCommand": "node .stackblitz.js && npm install && npm run dev" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /examples/vite-vue3/plain-color-icons/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | IconifyChars, 3 | IconifyInfo, 4 | IconifyJSON, 5 | IconifyMetaData, 6 | } from '@iconify/types' 7 | 8 | export { IconifyChars, IconifyInfo, IconifyJSON, IconifyMetaData } 9 | 10 | export declare const icons: IconifyJSON 11 | export declare const info: IconifyInfo 12 | export declare const metadata: IconifyMetaData 13 | export declare const chars: IconifyChars 14 | -------------------------------------------------------------------------------- /examples/vite-vue3/plain-color-icons/index.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable style/comma-dangle */ 2 | exports.icons = { 3 | prefix: 'plain-color-icons', 4 | icons: { 5 | about: { 6 | body: '' 7 | } 8 | }, 9 | lastModified: 1672652184, 10 | width: 48, 11 | height: 48 12 | } 13 | exports.info = { 14 | prefix: 'test-color-icons', 15 | name: 'Test Color Icons', 16 | total: 1, 17 | author: { 18 | name: 'test' 19 | }, 20 | license: { 21 | title: 'MIT' 22 | }, 23 | samples: ['about'], 24 | height: 32, 25 | displayHeight: 16 26 | } 27 | exports.metadata = {} 28 | exports.chars = {} 29 | -------------------------------------------------------------------------------- /examples/vite-vue3/plain-color-icons/index.mjs: -------------------------------------------------------------------------------- 1 | const icons = { 2 | prefix: 'plain-color-icons', 3 | icons: { 4 | about: { 5 | body: '', 6 | }, 7 | }, 8 | lastModified: 1672652184, 9 | width: 48, 10 | height: 48, 11 | } 12 | 13 | const info = { 14 | prefix: 'test-color-icons', 15 | name: 'Test Color Icons', 16 | total: 1, 17 | author: { 18 | name: 'test', 19 | }, 20 | license: { 21 | title: 'MIT', 22 | }, 23 | samples: ['about'], 24 | height: 32, 25 | displayHeight: 16, 26 | } 27 | 28 | const metadata = {} 29 | const chars = {} 30 | export { chars, icons, info, metadata } 31 | -------------------------------------------------------------------------------- /examples/vite-vue3/plain-color-icons/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "plain-color-icons", 3 | "exports": { 4 | "./*": "./*", 5 | ".": { 6 | "import": "./index.mjs", 7 | "require": "./index.js" 8 | } 9 | }, 10 | "main": "index.js", 11 | "module": "index.mjs", 12 | "types": "index.d.ts" 13 | } 14 | -------------------------------------------------------------------------------- /examples/vite-vue3/vite.config.ts: -------------------------------------------------------------------------------- 1 | import type { UserConfig } from 'vite' 2 | import { cpSync, promises as fs } from 'node:fs' 3 | import Vue from '@vitejs/plugin-vue' 4 | import { ExternalPackageIconLoader, FileSystemIconLoader } from 'unplugin-icons/loaders' 5 | import IconsResolver from 'unplugin-icons/resolver' 6 | import Icons from 'unplugin-icons/vite' 7 | import Components from 'unplugin-vue-components/vite' 8 | 9 | /************************************************************/ 10 | // DON'T DO THIS IN YOUR CODE: IT IS FOR TESTING PURPOSES ONLY 11 | cpSync( 12 | './plain-color-icons', 13 | './node_modules/plain-color-icons', 14 | { recursive: true }, 15 | ) 16 | cpSync( 17 | './@test-scope', 18 | './node_modules/@test-scope', 19 | { recursive: true }, 20 | ) 21 | /************************************************************/ 22 | 23 | const config: UserConfig = { 24 | plugins: [ 25 | Vue(), 26 | Icons({ 27 | compiler: 'vue3', 28 | customCollections: { 29 | ...ExternalPackageIconLoader('@test-scope/test-color-icons'), 30 | ...ExternalPackageIconLoader('plain-color-icons'), 31 | custom: FileSystemIconLoader('assets/custom-a'), 32 | inline: { 33 | foo: ` 34 | 35 | 36 | `, 37 | async: () => fs.readFile('assets/giftbox.svg', 'utf-8'), 38 | }, 39 | }, 40 | iconCustomizer(collection, icon, props) { 41 | const name = `${collection}:${icon}` 42 | if (name === 'inline:async' || name === 'carbon:app-connectivity' || name === 'custom:car-a') { 43 | props.width = '3em' 44 | props.height = '3em' 45 | props.color = 'skyblue' 46 | } 47 | }, 48 | }), 49 | Components({ 50 | dts: true, 51 | resolvers: [ 52 | IconsResolver({ 53 | alias: { 54 | park: 'icon-park', 55 | }, 56 | customCollections: [ 57 | 'custom', 58 | 'inline', 59 | // custom external packages 60 | 'plain-color-icons', 61 | 'test-color-icons', 62 | ], 63 | }), 64 | ], 65 | }), 66 | ], 67 | } 68 | 69 | export default config 70 | -------------------------------------------------------------------------------- /examples/vite-web-components/.stackblitz.js: -------------------------------------------------------------------------------- 1 | import { promises as fsPromises } from 'node:fs' 2 | 3 | updatePackageJson() 4 | 5 | async function updatePackageJson() { 6 | const filename = './package.json' 7 | try { 8 | const contents = await fsPromises.readFile(filename, 'utf-8') 9 | const updatedContent = contents.replace('workspace:*', 'latest') 10 | await fsPromises.writeFile(filename, updatedContent) 11 | } 12 | catch (err) { 13 | console.error(err) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/vite-web-components/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/vite-web-components/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite-web-components-example", 3 | "type": "module", 4 | "private": true, 5 | "description": "unplugin-icons + Web Components (Vite)", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build" 9 | }, 10 | "devDependencies": { 11 | "@iconify-json/ion": "^1.2.2", 12 | "@iconify-json/mono-icons": "^1.2.0", 13 | "unplugin-icons": "workspace:*", 14 | "vite": "^6.1.0" 15 | }, 16 | "stackblitz": { 17 | "installDependencies": false, 18 | "startCommand": "node .stackblitz.js && npm install && npm run dev" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/vite-web-components/vite.config.ts: -------------------------------------------------------------------------------- 1 | import type { UserConfig } from 'vite' 2 | import Icons from 'unplugin-icons/vite' 3 | 4 | const config: UserConfig = { 5 | plugins: [ 6 | Icons({ 7 | compiler: 'web-components', 8 | webComponents: { 9 | autoDefine: true, 10 | }, 11 | }), 12 | ], 13 | } 14 | 15 | export default config 16 | -------------------------------------------------------------------------------- /examples/vue-cli-vue2/.npmrc: -------------------------------------------------------------------------------- 1 | shamefully-hoist=true 2 | -------------------------------------------------------------------------------- /examples/vue-cli-vue2/.stackblitz.js: -------------------------------------------------------------------------------- 1 | const { promises } = require('node:fs') 2 | 3 | updatePackageJson() 4 | 5 | async function updatePackageJson() { 6 | const filename = './package.json' 7 | try { 8 | const contents = await promises.readFile(filename, 'utf-8') 9 | const updatedContent = contents.replace('workspace:*', 'latest') 10 | await promises.writeFile(filename, updatedContent) 11 | } 12 | catch (err) { 13 | console.error(err) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/vue-cli-vue2/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset', 4 | ], 5 | } 6 | -------------------------------------------------------------------------------- /examples/vue-cli-vue2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-cli-example", 3 | "private": true, 4 | "description": "unplugin-icons + Vue2 (Vue CLI)", 5 | "scripts": { 6 | "dev": "vue-cli-service serve", 7 | "build": "vue-tsc --noEmit && vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "core-js": "^3.40.0", 12 | "vue": "^2.7.8" 13 | }, 14 | "devDependencies": { 15 | "@iconify/json": "^2.2.308", 16 | "@vue/cli-plugin-babel": "^5.0.8", 17 | "@vue/cli-plugin-typescript": "^5.0.8", 18 | "@vue/cli-service": "^5.0.8", 19 | "typescript": "^5.7.3", 20 | "unplugin-icons": "workspace:*", 21 | "vue-tsc": "^2.2.2" 22 | }, 23 | "stackblitz": { 24 | "installDependencies": false, 25 | "startCommand": "node .stackblitz.js && npm install && npm add -D vue-template-compiler && npm run dev" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /examples/vue-cli-vue2/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <%= htmlWebpackPlugin.options.title %> 8 | 9 | 10 | 13 |
14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /examples/vue-cli-vue2/src/App.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 30 | -------------------------------------------------------------------------------- /examples/vue-cli-vue2/src/main.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | 4 | Vue.config.productionTip = false 5 | 6 | const app = new Vue({ render: h => h(App as any) }) 7 | 8 | app.$mount('#app') 9 | -------------------------------------------------------------------------------- /examples/vue-cli-vue2/src/shims-vue.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.vue' { 2 | import Vue from 'vue' 3 | 4 | export default Vue 5 | } 6 | -------------------------------------------------------------------------------- /examples/vue-cli-vue2/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "jsx": "preserve", 5 | "lib": [ 6 | "esnext", 7 | "dom", 8 | "dom.iterable", 9 | "scripthost" 10 | ], 11 | "baseUrl": ".", 12 | "module": "esnext", 13 | "moduleResolution": "node", 14 | "paths": { 15 | "@/*": [ 16 | "src/*" 17 | ] 18 | }, 19 | "types": [ 20 | "webpack-env" 21 | ], 22 | "strict": true, 23 | "importHelpers": true, 24 | "sourceMap": true, 25 | "allowSyntheticDefaultImports": true, 26 | "esModuleInterop": true, 27 | "skipLibCheck": true 28 | }, 29 | "include": [ 30 | "src/**/*.ts", 31 | "src/**/*.tsx", 32 | "src/**/*.vue", 33 | "tests/**/*.ts", 34 | "tests/**/*.tsx" 35 | ], 36 | "exclude": [ 37 | "node_modules" 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /examples/vue-cli-vue2/vue.config.js: -------------------------------------------------------------------------------- 1 | const Icons = require('unplugin-icons/webpack') 2 | 3 | /** 4 | * @type {import('@vue/cli-service').ProjectOptions} 5 | */ 6 | module.exports = { 7 | configureWebpack: { 8 | plugins: [ 9 | Icons.default({ 10 | compiler: 'vue2', 11 | }), 12 | ], 13 | }, 14 | chainWebpack(config) { 15 | // disable type check and let `vue-tsc` handles it 16 | config.plugins.delete('fork-ts-checker') 17 | 18 | // disable cache for testing, you should remove this in production 19 | config.module.rule('vue').uses.delete('cache-loader') 20 | config.module.rule('js').uses.delete('cache-loader') 21 | config.module.rule('ts').uses.delete('cache-loader') 22 | config.module.rule('tsx').uses.delete('cache-loader') 23 | }, 24 | } 25 | -------------------------------------------------------------------------------- /examples/webpack/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-example", 3 | "private": true, 4 | "scripts": { 5 | "build": "webpack" 6 | }, 7 | "devDependencies": { 8 | "@iconify/json": "^2.2.308", 9 | "unplugin-icons": "workspace:*", 10 | "webpack": "^5.98.0", 11 | "webpack-cli": "^5.1.4" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/webpack/src/main.js: -------------------------------------------------------------------------------- 1 | import VueLogo from '~icons/logos/vue' 2 | 3 | // eslint-disable-next-line no-console 4 | console.log(VueLogo) 5 | -------------------------------------------------------------------------------- /examples/webpack/webpack.config.js: -------------------------------------------------------------------------------- 1 | const { resolve } = require('node:path') 2 | const Icons = require('unplugin-icons/webpack') 3 | 4 | module.exports = { 5 | mode: 'development', 6 | entry: resolve(__dirname, 'src/main.js'), 7 | output: { 8 | path: resolve(__dirname, 'dist/webpack'), 9 | filename: 'main.js', 10 | }, 11 | plugins: [ 12 | Icons(), 13 | ], 14 | } 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "unplugin-icons", 3 | "type": "module", 4 | "version": "22.1.0", 5 | "packageManager": "pnpm@10.4.1", 6 | "description": "Access thousands of icons as components on-demand universally", 7 | "author": "Anthony Fu ", 8 | "license": "MIT", 9 | "funding": "https://github.com/sponsors/antfu", 10 | "homepage": "https://github.com/unplugin/unplugin-icons#readme", 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/unplugin/unplugin-icons.git" 14 | }, 15 | "bugs": "https://github.com/unplugin/unplugin-icons/issues", 16 | "exports": { 17 | ".": { 18 | "import": { 19 | "types": "./dist/index.d.ts", 20 | "default": "./dist/index.js" 21 | }, 22 | "require": { 23 | "types": "./dist/index.d.cts", 24 | "default": "./dist/index.cjs" 25 | } 26 | }, 27 | "./*": "./*", 28 | "./esbuild": { 29 | "import": { 30 | "types": "./dist/esbuild.d.ts", 31 | "default": "./dist/esbuild.js" 32 | }, 33 | "require": { 34 | "types": "./dist/esbuild.d.cts", 35 | "default": "./dist/esbuild.cjs" 36 | } 37 | }, 38 | "./loaders": { 39 | "import": { 40 | "types": "./dist/loaders.d.ts", 41 | "default": "./dist/loaders.js" 42 | }, 43 | "require": { 44 | "types": "./dist/loaders.d.cts", 45 | "default": "./dist/loaders.cjs" 46 | } 47 | }, 48 | "./nuxt": { 49 | "import": { 50 | "types": "./dist/nuxt.d.ts", 51 | "default": "./dist/nuxt.js" 52 | }, 53 | "require": { 54 | "types": "./dist/nuxt.d.cts", 55 | "default": "./dist/nuxt.cjs" 56 | } 57 | }, 58 | "./resolver": { 59 | "import": { 60 | "types": "./dist/resolver.d.ts", 61 | "default": "./dist/resolver.js" 62 | }, 63 | "require": { 64 | "types": "./dist/resolver.d.cts", 65 | "default": "./dist/resolver.cjs" 66 | } 67 | }, 68 | "./rollup": { 69 | "import": { 70 | "types": "./dist/rollup.d.ts", 71 | "default": "./dist/rollup.js" 72 | }, 73 | "require": { 74 | "types": "./dist/rollup.d.cts", 75 | "default": "./dist/rollup.cjs" 76 | } 77 | }, 78 | "./types": { 79 | "import": { 80 | "types": "./dist/types.d.ts", 81 | "default": "./dist/types.js" 82 | }, 83 | "require": { 84 | "types": "./dist/types.d.cts", 85 | "default": "./dist/types.cjs" 86 | } 87 | }, 88 | "./types/astro": { 89 | "types": "./types/astro.d.ts" 90 | }, 91 | "./types/preact": { 92 | "types": "./types/preact.d.ts" 93 | }, 94 | "./types/qwik": { 95 | "types": "./types/qwik.d.ts" 96 | }, 97 | "./types/raw": { 98 | "types": "./types/raw.d.ts" 99 | }, 100 | "./types/react": { 101 | "types": "./types/react.d.ts" 102 | }, 103 | "./types/solid": { 104 | "types": "./types/solid.d.ts" 105 | }, 106 | "./types/svelte": { 107 | "types": "./types/svelte.d.ts" 108 | }, 109 | "./types/svelte3": { 110 | "types": "./types/svelte3.d.ts" 111 | }, 112 | "./types/svelte4": { 113 | "types": "./types/svelte4.d.ts" 114 | }, 115 | "./types/svelte5": { 116 | "types": "./types/svelte5.d.ts" 117 | }, 118 | "./types/vue": { 119 | "types": "./types/vue.d.ts" 120 | }, 121 | "./types/vue3": { 122 | "types": "./types/vue3.d.ts" 123 | }, 124 | "./types/web-components": { 125 | "types": "./types/web-components.d.ts" 126 | }, 127 | "./vite": { 128 | "import": { 129 | "types": "./dist/vite.d.ts", 130 | "default": "./dist/vite.js" 131 | }, 132 | "require": { 133 | "types": "./dist/vite.d.cts", 134 | "default": "./dist/vite.cjs" 135 | } 136 | }, 137 | "./webpack": { 138 | "import": { 139 | "types": "./dist/webpack.d.ts", 140 | "default": "./dist/webpack.js" 141 | }, 142 | "require": { 143 | "types": "./dist/webpack.d.cts", 144 | "default": "./dist/webpack.cjs" 145 | } 146 | }, 147 | "./rspack": { 148 | "import": { 149 | "types": "./dist/rspack.d.ts", 150 | "default": "./dist/rspack.js" 151 | }, 152 | "require": { 153 | "types": "./dist/rspack.d.cts", 154 | "default": "./dist/rspack.cjs" 155 | } 156 | } 157 | }, 158 | "main": "dist/index.cjs", 159 | "module": "dist/index.js", 160 | "types": "dist/index.d.ts", 161 | "typesVersions": { 162 | "*": { 163 | "*": [ 164 | "./dist/*", 165 | "./*" 166 | ] 167 | } 168 | }, 169 | "files": [ 170 | "*.d.ts", 171 | "dist", 172 | "types" 173 | ], 174 | "scripts": { 175 | "build": "tsx scripts/prebuild.ts && tsup", 176 | "dev": "tsx scripts/prebuild.ts && tsup --watch src", 177 | "example:build": "npm -C examples/vite-vue3 run build", 178 | "example:dev": "npm -C examples/vite-vue3 run dev", 179 | "lint": "eslint .", 180 | "lint-fix": "eslint . --fix", 181 | "prepublishOnly": "npm run build", 182 | "release": "bumpp && npm publish", 183 | "test": "vitest", 184 | "typecheck": "tsc --noEmit" 185 | }, 186 | "peerDependencies": { 187 | "@svgr/core": ">=7.0.0", 188 | "@svgx/core": "^1.0.1", 189 | "@vue/compiler-sfc": "^3.0.2 || ^2.7.0", 190 | "svelte": "^3.0.0 || ^4.0.0 || ^5.0.0", 191 | "vue-template-compiler": "^2.6.12", 192 | "vue-template-es2015-compiler": "^1.9.0" 193 | }, 194 | "peerDependenciesMeta": { 195 | "@svgr/core": { 196 | "optional": true 197 | }, 198 | "@svgx/core": { 199 | "optional": true 200 | }, 201 | "@vue/compiler-sfc": { 202 | "optional": true 203 | }, 204 | "svelte": { 205 | "optional": true 206 | }, 207 | "vue-template-compiler": { 208 | "optional": true 209 | }, 210 | "vue-template-es2015-compiler": { 211 | "optional": true 212 | } 213 | }, 214 | "dependencies": { 215 | "@antfu/install-pkg": "^1.0.0", 216 | "@iconify/utils": "^2.3.0", 217 | "debug": "^4.4.0", 218 | "local-pkg": "^1.0.0", 219 | "unplugin": "^2.2.0" 220 | }, 221 | "devDependencies": { 222 | "@antfu/eslint-config": "^4.3.0", 223 | "@antfu/utils": "^9.1.0", 224 | "@iconify/json": "^2.2.308", 225 | "@iconify/types": "^2.0.0", 226 | "@svgr/core": "^8.1.0", 227 | "@svgr/plugin-jsx": "^8.1.0", 228 | "@svgx/core": "^1.0.1", 229 | "@types/debug": "^4.1.12", 230 | "@types/node": "^22.13.4", 231 | "@vue/compiler-sfc": "^3.5.13", 232 | "bumpp": "^10.0.3", 233 | "eslint": "^9.20.1", 234 | "publint": "^0.3.5", 235 | "rollup": "^4.34.8", 236 | "tsup": "^8.3.6", 237 | "tsx": "^4.19.2", 238 | "typescript": "^5.7.3", 239 | "vite": "^6.1.0", 240 | "vitest": "^3.0.5" 241 | } 242 | } 243 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'examples/*' 3 | - '!examples/nuxt3' 4 | -------------------------------------------------------------------------------- /scripts/prebuild.ts: -------------------------------------------------------------------------------- 1 | import { promises as fs } from 'node:fs' 2 | import { basename, resolve } from 'node:path' 3 | import { fileURLToPath } from 'node:url' 4 | import jc from '@iconify/json/collections.json' 5 | 6 | (async () => { 7 | const __dirname = fileURLToPath(new URL('.', import.meta.url)) 8 | const file = resolve(__dirname, '../src/core/icon-sets.json') 9 | console.log('[prebuild]', basename(file)) 10 | await fs.writeFile(file, `${JSON.stringify(Object.keys(jc).sort(), null, 2)}\n`) 11 | })() 12 | -------------------------------------------------------------------------------- /src/core/collections.ts: -------------------------------------------------------------------------------- 1 | import collections from './icon-sets.json' 2 | 3 | export { collections } 4 | 5 | export function hasCollection(collection: string) { 6 | return collections.includes(collection) 7 | } 8 | -------------------------------------------------------------------------------- /src/core/compilers/astro.ts: -------------------------------------------------------------------------------- 1 | import type { Compiler } from './types' 2 | 3 | export const AstroCompiler = ((svg: string) => { 4 | const svgWithProps = svg.replace(', Compiler> = { 16 | 'astro': AstroCompiler, 17 | 'jsx': JSXCompiler, 18 | 'marko': MarkoCompiler, 19 | 'none': NoneCompiler, 20 | 'raw': RawCompiler, 21 | 'solid': SolidCompiler, 22 | 'svelte': SvelteCompiler, 23 | 'vue2': Vue2Compiler, 24 | 'vue3': Vue3Compiler, 25 | 'web-components': WebComponentsCompiler, 26 | 'qwik': QwikCompiler, 27 | } 28 | -------------------------------------------------------------------------------- /src/core/compilers/jsx.ts: -------------------------------------------------------------------------------- 1 | import type { Compiler } from './types' 2 | import { camelize } from '@iconify/utils/lib/misc/strings' 3 | import { importModule } from 'local-pkg' 4 | 5 | export const JSXCompiler = (async ( 6 | svg, 7 | collection, 8 | icon, 9 | options, 10 | ) => { 11 | const svgrCore = await importModule('@svgr/core') 12 | // check for v6/v7 transform (v7 on CJS it is in default), v5 default and previous versions 13 | const svgr = svgrCore.transform // v6 or v7 ESM 14 | || (svgrCore.default ? (svgrCore.default.transform /* v7 CJS */ ?? svgrCore.default) : svgrCore.default) 15 | || svgrCore 16 | let res = await svgr( 17 | svg, 18 | { 19 | plugins: ['@svgr/plugin-jsx'], 20 | ref: options.jsx === 'react', 21 | }, 22 | { componentName: camelize(`${collection}-${icon}`) }, 23 | ) 24 | // svgr does not provide an option to support preact (WHY?), 25 | // we manually remove the react import for preact 26 | if (options.jsx !== 'react') 27 | res = res.replace('import * as React from "react";', '') 28 | return res 29 | }) as Compiler 30 | -------------------------------------------------------------------------------- /src/core/compilers/marko.ts: -------------------------------------------------------------------------------- 1 | import type { Compiler } from './types' 2 | 3 | export const MarkoCompiler = ((svg: string) => { 4 | const openTagEnd = svg.indexOf('>', svg.indexOf('` 7 | const content = `$!{\`${escapeTemplateLiteral(svg.slice(openTagEnd + 1, closeTagStart))}\`}` 8 | const closeTag = svg.slice(closeTagStart) 9 | return `${openTag}${content}${closeTag}` 10 | }) as Compiler 11 | 12 | export function escapeTemplateLiteral(str: string): string { 13 | return str.replace(/\\.|[$`]/g, (m) => { 14 | switch (m) { 15 | case '$': return '$' 16 | case '`': return '`' 17 | default: return m 18 | } 19 | }) 20 | } 21 | -------------------------------------------------------------------------------- /src/core/compilers/none.ts: -------------------------------------------------------------------------------- 1 | import type { Compiler } from './types' 2 | 3 | export const NoneCompiler = ((svg: string) => { 4 | return svg 5 | }) as Compiler 6 | -------------------------------------------------------------------------------- /src/core/compilers/qwik.ts: -------------------------------------------------------------------------------- 1 | import type { ToJsComponentOptions } from '@svgx/core' 2 | import type { Compiler } from './types' 3 | import { camelize } from '@iconify/utils/lib/misc/strings' 4 | import { importModule } from 'local-pkg' 5 | 6 | export const QwikCompiler = (async ( 7 | svg, 8 | collection, 9 | icon, 10 | options, 11 | ) => { 12 | const defaultOptions: ToJsComponentOptions = { 13 | importSource: '@builder.io/qwik', 14 | runtime: 'automatic', 15 | componentName: camelize(`${collection}-${icon}`), 16 | } 17 | const mergedOptions = Object.assign({}, defaultOptions, options) 18 | const svgx = await importModule('@svgx/core') 19 | const toJsxComponent = svgx.toJsxComponent 20 | const res = toJsxComponent(svg, { 21 | ...mergedOptions, 22 | defaultExport: true, 23 | }) 24 | return res 25 | }) as Compiler 26 | -------------------------------------------------------------------------------- /src/core/compilers/raw.ts: -------------------------------------------------------------------------------- 1 | import type { Compiler } from './types' 2 | 3 | export const RawCompiler = ((svg: string) => { 4 | return `export default ${JSON.stringify(svg)}` 5 | }) as Compiler 6 | -------------------------------------------------------------------------------- /src/core/compilers/solid.ts: -------------------------------------------------------------------------------- 1 | import type { Compiler } from './types' 2 | 3 | export const SolidCompiler = ((svg: string) => { 4 | const svgWithProps = svg.replace(/([{}])/g, '{\'$1\'}').replace(/(?<=)/i, '{...props}>') 5 | return `export default (props = {}) => ${svgWithProps}` 6 | }) as Compiler 7 | -------------------------------------------------------------------------------- /src/core/compilers/svelte.ts: -------------------------------------------------------------------------------- 1 | import type { Compiler } from './types' 2 | 3 | let svelteRunes: boolean | null 4 | 5 | export const SvelteCompiler = (async (svg: string) => { 6 | if (svelteRunes == null) { 7 | try { 8 | const { VERSION } = await import('svelte/compiler') 9 | svelteRunes = Number(VERSION.split('.')[0]) >= 5 10 | } 11 | catch { 12 | svelteRunes = false 13 | } 14 | } 15 | const openTagEnd = svg.indexOf('>', svg.indexOf('` 18 | if (svelteRunes) 19 | sfc += svg.slice(openTagEnd + 1, closeTagStart) 20 | else 21 | sfc += `{@html \`${escapeSvelte(svg.slice(openTagEnd + 1, closeTagStart))}\`}` 22 | 23 | sfc += svg.slice(closeTagStart) 24 | return svelteRunes ? `${sfc}` : sfc 25 | }) as Compiler 26 | 27 | // escape curlies, backtick, \t, \r, \n to avoid breaking output of {@html `here`} in .svelte 28 | export function escapeSvelte(str: string): string { 29 | return str 30 | .replace(/\{/g, '{') 31 | .replace(/\}/g, '}') 32 | .replace(/`/g, '`') 33 | .replace(/\\([trn])/g, ' ') 34 | } 35 | -------------------------------------------------------------------------------- /src/core/compilers/types.ts: -------------------------------------------------------------------------------- 1 | import type { Awaitable } from '@antfu/utils' 2 | import type { ResolvedOptions } from '../../types' 3 | 4 | export type Compiler = ( 5 | svg: string, 6 | collection: string, 7 | icon: string, 8 | options: ResolvedOptions 9 | ) => string | Promise 10 | 11 | export interface CustomCompiler { 12 | compiler: Awaitable 13 | extension?: string 14 | } 15 | -------------------------------------------------------------------------------- /src/core/compilers/vue2.ts: -------------------------------------------------------------------------------- 1 | import type { Compiler } from './types' 2 | import { importModule } from 'local-pkg' 3 | import { handleSVGId } from '../svgId' 4 | 5 | // refer to: https://github.com/underfin/vite-plugin-vue2/blob/master/src/template/compileTemplate.ts 6 | export const Vue2Compiler = (async ( 7 | svg: string, 8 | collection: string, 9 | icon: string, 10 | ) => { 11 | const { compile } = await importModule('vue-template-compiler') 12 | const transpileMod = (await importModule('vue-template-es2015-compiler')) 13 | const transpile = transpileMod.default || transpileMod 14 | 15 | const { injectScripts, svg: handled } = handleSVGId(svg) 16 | 17 | const { render } = compile(handled) 18 | const toFunction = (code: string): string => { 19 | return `function () {${code}}` 20 | } 21 | 22 | // transpile code with vue-template-es2015-compiler, which is a forked 23 | // version of Buble that applies ES2015 transforms + stripping `with` usage 24 | let code = transpile(`var __render__ = ${toFunction(render as any)}\n`, {}) 25 | 26 | // we use __render__ to avoid `render` not being prefixed by the 27 | // transpiler when stripping with, but revert it back to `render` to 28 | // maintain backwards compat 29 | code = code.replace(/\s__(render|staticRenderFns)__\s/g, ' $1 ') 30 | 31 | code += ` 32 | /* vite-plugin-components disabled */ 33 | export default { 34 | render: render, 35 | ${injectScripts ? `data() {${injectScripts};return { idMap }},` : ''} 36 | name: '${collection}-${icon}', 37 | } 38 | ` 39 | 40 | return code 41 | }) as Compiler 42 | -------------------------------------------------------------------------------- /src/core/compilers/vue3.ts: -------------------------------------------------------------------------------- 1 | import type { Compiler } from './types' 2 | import { importModule } from 'local-pkg' 3 | import { handleSVGId } from '../svgId' 4 | 5 | export const Vue3Compiler = (async (svg: string, collection: string, icon: string) => { 6 | const { compileTemplate } = await importModule('@vue/compiler-sfc') 7 | 8 | const { injectScripts, svg: handled } = handleSVGId(svg) 9 | 10 | let { code } = compileTemplate({ 11 | source: handled, 12 | id: `${collection}:${icon}`, 13 | filename: `${collection}-${icon}.vue`, 14 | }) 15 | 16 | code = `import { markRaw } from 'vue'\n${code}` 17 | code = code.replace(/^export /gm, '') 18 | code += `\n\nexport default markRaw({ name: '${collection}-${icon}', render${ 19 | injectScripts ? `, setup() {${injectScripts};return { idMap }}` : '' 20 | } })` 21 | code += '\n/* vite-plugin-components disabled */' 22 | 23 | return code 24 | }) as Compiler 25 | -------------------------------------------------------------------------------- /src/core/compilers/web-components.ts: -------------------------------------------------------------------------------- 1 | import type { Compiler } from './types' 2 | import { camelize } from '@iconify/utils/lib/misc/strings' 3 | 4 | export const WebComponentsCompiler = ((svg, collection, icon, { webComponents: options }) => { 5 | let id = `${collection}-${icon}` 6 | if (options.iconPrefix) 7 | id = `${options.iconPrefix}-${id}` 8 | 9 | const name = camelize(id) 10 | let code = `export default class ${name} extends HTMLElement {` 11 | if (options.shadow) { 12 | code += `constructor() { 13 | super() 14 | this.attachShadow({ mode: 'open' }).innerHTML = ${JSON.stringify(svg)} 15 | }` 16 | } 17 | else { 18 | // use connectedCallback because children can't be appended in the constructor of a CE: 19 | code += `connectedCallback() { this.innerHTML = ${JSON.stringify(svg)} }` 20 | } 21 | code += '}' 22 | 23 | if (options.autoDefine) 24 | code += `\ncustomElements.define('${id}', ${name})` 25 | 26 | return code 27 | }) as Compiler 28 | -------------------------------------------------------------------------------- /src/core/icon-sets.json: -------------------------------------------------------------------------------- 1 | [ 2 | "academicons", 3 | "akar-icons", 4 | "ant-design", 5 | "arcticons", 6 | "basil", 7 | "bi", 8 | "bitcoin-icons", 9 | "bpmn", 10 | "brandico", 11 | "bx", 12 | "bxl", 13 | "bxs", 14 | "bytesize", 15 | "carbon", 16 | "catppuccin", 17 | "cbi", 18 | "charm", 19 | "ci", 20 | "cib", 21 | "cif", 22 | "cil", 23 | "circle-flags", 24 | "circum", 25 | "clarity", 26 | "codex", 27 | "codicon", 28 | "covid", 29 | "cryptocurrency", 30 | "cryptocurrency-color", 31 | "cuida", 32 | "dashicons", 33 | "devicon", 34 | "devicon-plain", 35 | "duo-icons", 36 | "ei", 37 | "el", 38 | "emojione", 39 | "emojione-monotone", 40 | "emojione-v1", 41 | "entypo", 42 | "entypo-social", 43 | "eos-icons", 44 | "ep", 45 | "et", 46 | "eva", 47 | "f7", 48 | "fa", 49 | "fa-brands", 50 | "fa-regular", 51 | "fa-solid", 52 | "fa6-brands", 53 | "fa6-regular", 54 | "fa6-solid", 55 | "fad", 56 | "famicons", 57 | "fe", 58 | "feather", 59 | "file-icons", 60 | "flag", 61 | "flagpack", 62 | "flat-color-icons", 63 | "flat-ui", 64 | "flowbite", 65 | "fluent", 66 | "fluent-color", 67 | "fluent-emoji", 68 | "fluent-emoji-flat", 69 | "fluent-emoji-high-contrast", 70 | "fluent-mdl2", 71 | "fontelico", 72 | "fontisto", 73 | "formkit", 74 | "foundation", 75 | "fxemoji", 76 | "gala", 77 | "game-icons", 78 | "garden", 79 | "geo", 80 | "gg", 81 | "gis", 82 | "gravity-ui", 83 | "gridicons", 84 | "grommet-icons", 85 | "guidance", 86 | "healthicons", 87 | "heroicons", 88 | "heroicons-outline", 89 | "heroicons-solid", 90 | "hugeicons", 91 | "humbleicons", 92 | "ic", 93 | "icomoon-free", 94 | "icon-park", 95 | "icon-park-outline", 96 | "icon-park-solid", 97 | "icon-park-twotone", 98 | "iconamoon", 99 | "iconoir", 100 | "icons8", 101 | "il", 102 | "ion", 103 | "iwwa", 104 | "ix", 105 | "jam", 106 | "la", 107 | "lets-icons", 108 | "line-md", 109 | "lineicons", 110 | "logos", 111 | "ls", 112 | "lsicon", 113 | "lucide", 114 | "lucide-lab", 115 | "mage", 116 | "majesticons", 117 | "maki", 118 | "map", 119 | "marketeq", 120 | "material-symbols", 121 | "material-symbols-light", 122 | "mdi", 123 | "mdi-light", 124 | "medical-icon", 125 | "memory", 126 | "meteocons", 127 | "meteor-icons", 128 | "mi", 129 | "mingcute", 130 | "mono-icons", 131 | "mynaui", 132 | "nimbus", 133 | "nonicons", 134 | "noto", 135 | "noto-v1", 136 | "nrk", 137 | "octicon", 138 | "oi", 139 | "ooui", 140 | "openmoji", 141 | "oui", 142 | "pajamas", 143 | "pepicons", 144 | "pepicons-pencil", 145 | "pepicons-pop", 146 | "pepicons-print", 147 | "ph", 148 | "pixelarticons", 149 | "prime", 150 | "proicons", 151 | "ps", 152 | "qlementine-icons", 153 | "quill", 154 | "radix-icons", 155 | "raphael", 156 | "ri", 157 | "rivet-icons", 158 | "si", 159 | "si-glyph", 160 | "simple-icons", 161 | "simple-line-icons", 162 | "skill-icons", 163 | "solar", 164 | "stash", 165 | "streamline", 166 | "streamline-emojis", 167 | "subway", 168 | "svg-spinners", 169 | "system-uicons", 170 | "tabler", 171 | "tdesign", 172 | "teenyicons", 173 | "token", 174 | "token-branded", 175 | "topcoat", 176 | "twemoji", 177 | "typcn", 178 | "uil", 179 | "uim", 180 | "uis", 181 | "uit", 182 | "uiw", 183 | "unjs", 184 | "vaadin", 185 | "vs", 186 | "vscode-icons", 187 | "websymbol", 188 | "weui", 189 | "whh", 190 | "wi", 191 | "wpf", 192 | "zmdi", 193 | "zondicons" 194 | ] 195 | -------------------------------------------------------------------------------- /src/core/loader.ts: -------------------------------------------------------------------------------- 1 | import type { IconifyLoaderOptions } from '@iconify/utils' 2 | import type { ResolvedOptions } from '../types' 3 | import type { Compiler } from './compilers/types' 4 | import { loadNodeIcon } from '@iconify/utils/lib/loader/node-loader' 5 | import { compilers } from './compilers' 6 | 7 | const URL_PREFIXES = ['/~icons/', '~icons/', 'virtual:icons/', 'virtual/icons/'] 8 | const iconPathRE = new RegExp(`${URL_PREFIXES.map(v => `^${v}`).join('|')}`) 9 | 10 | export interface ResolvedIconPath { 11 | collection: string 12 | icon: string 13 | query: Record 14 | } 15 | 16 | export function isIconPath(path: string) { 17 | return iconPathRE.test(path) 18 | } 19 | 20 | export function normalizeIconPath(path: string) { 21 | return path.replace(iconPathRE, URL_PREFIXES[0]) 22 | } 23 | 24 | export function resolveIconsPath(path: string): ResolvedIconPath | null { 25 | if (!isIconPath(path)) 26 | return null 27 | 28 | path = path.replace(iconPathRE, '') 29 | 30 | const query: ResolvedIconPath['query'] = {} 31 | const queryIndex = path.indexOf('?') 32 | if (queryIndex !== -1) { 33 | const queryRaw = path.slice(queryIndex + 1) 34 | path = path.slice(0, queryIndex) 35 | new URLSearchParams(queryRaw).forEach((value, key) => { 36 | // configure raw compiler for empty and true values only 37 | if (key === 'raw') 38 | query.raw = (value === '' || value === 'true') ? 'true' : 'false' 39 | else 40 | query[key] = value 41 | }) 42 | } 43 | 44 | // remove extension 45 | path = path.replace(/\.\w+$/, '') 46 | 47 | const [collection, icon] = path.split('/') 48 | 49 | return { 50 | collection, 51 | icon, 52 | query, 53 | } 54 | } 55 | 56 | export async function generateComponent({ collection, icon, query }: ResolvedIconPath, options: ResolvedOptions) { 57 | const warn = `${collection}/${icon}` 58 | const { 59 | scale, 60 | defaultStyle, 61 | defaultClass, 62 | customCollections, 63 | iconCustomizer: providedIconCustomizer, 64 | transform, 65 | autoInstall = false, 66 | collectionsNodeResolvePath, 67 | } = options 68 | 69 | const iconifyLoaderOptions: IconifyLoaderOptions = { 70 | addXmlNs: false, 71 | scale, 72 | customCollections, 73 | autoInstall, 74 | defaultClass, 75 | defaultStyle, 76 | cwd: collectionsNodeResolvePath, 77 | // there is no need to warn since we throw an error below 78 | warn: undefined, 79 | customizations: { 80 | transform, 81 | async iconCustomizer(collection, icon, props) { 82 | await providedIconCustomizer?.(collection, icon, props) 83 | Object.keys(query).forEach((p) => { 84 | const v = query[p] 85 | // exclude raw compiler entry to be serialized as svg attr 86 | if (p !== 'raw' && v !== undefined && v !== null) 87 | props[p] = v 88 | }) 89 | }, 90 | }, 91 | } 92 | const svg = await loadNodeIcon(collection, icon, iconifyLoaderOptions) 93 | if (!svg) 94 | throw new Error(`Icon \`${warn}\` not found`) 95 | 96 | // accept raw compiler from query params 97 | const _compiler = query.raw === 'true' ? 'raw' : options.compiler 98 | 99 | if (_compiler) { 100 | const compiler = typeof _compiler === 'string' 101 | ? compilers[_compiler] 102 | : (await _compiler.compiler) as Compiler 103 | 104 | if (compiler) 105 | return compiler(svg, collection, icon, options) 106 | } 107 | 108 | throw new Error(`Unknown compiler: ${_compiler}`) 109 | } 110 | 111 | export async function generateComponentFromPath(path: string, options: ResolvedOptions) { 112 | const resolved = resolveIconsPath(path) 113 | if (!resolved) 114 | return null 115 | return generateComponent(resolved, options) 116 | } 117 | -------------------------------------------------------------------------------- /src/core/options.ts: -------------------------------------------------------------------------------- 1 | import type { Options, ResolvedOptions } from '../types' 2 | import process from 'node:process' 3 | import createDebugger from 'debug' 4 | import { getPackageInfo, isPackageExists } from 'local-pkg' 5 | 6 | const debug = createDebugger('unplugin-icons:options') 7 | 8 | export async function resolveOptions(options: Options): Promise { 9 | const { 10 | scale = 1.2, 11 | defaultStyle = '', 12 | defaultClass = '', 13 | compiler = await guessCompiler(), 14 | jsx = guessJSX(), 15 | customCollections = {}, 16 | iconCustomizer = () => {}, 17 | transform, 18 | autoInstall = false, 19 | collectionsNodeResolvePath = process.cwd(), 20 | } = options 21 | 22 | const webComponents = Object.assign({ 23 | autoDefine: false, 24 | iconPrefix: 'icon', 25 | }, options.webComponents) 26 | 27 | debug('compiler', compiler) 28 | 29 | return { 30 | scale, 31 | defaultStyle, 32 | defaultClass, 33 | customCollections, 34 | iconCustomizer, 35 | compiler, 36 | jsx, 37 | webComponents, 38 | transform, 39 | autoInstall, 40 | collectionsNodeResolvePath, 41 | } 42 | } 43 | 44 | async function guessCompiler(): Promise { 45 | return await getVueVersion() || (isPackageExists('@svgr/core') ? 'jsx' : 'vue3') 46 | } 47 | 48 | function guessJSX(): ResolvedOptions['jsx'] { 49 | if (isPackageExists('preact')) 50 | return 'preact' 51 | return 'react' 52 | } 53 | 54 | async function getVueVersion() { 55 | try { 56 | const result = await getPackageInfo('vue') 57 | if (!result || !result.version) 58 | return null 59 | return result.version?.startsWith('2.') ? 'vue2' : 'vue3' 60 | } 61 | catch { 62 | return null 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/core/svgId.ts: -------------------------------------------------------------------------------- 1 | const randIdFn = 'const __randId = () => Math.random().toString(36).substr(2, 10);' 2 | 3 | export function handleSVGId(svg: string) { 4 | const hasID = /="url\(#/.test(svg) 5 | const idMap: Record = {} 6 | let injectScripts = '' 7 | 8 | if (hasID) { 9 | svg = svg 10 | .replace(/\b([\w-]+)="url\(#(.+?)\)"/g, (_, s, id) => { 11 | idMap[id] = `'${id}':'uicons-'+__randId()` 12 | return `:${s}="'url(#'+idMap['${id}']+')'"` 13 | }) 14 | .replace(/\bid="(.+?)"/g, (full, id) => { 15 | if (idMap[id]) 16 | return `:id="idMap['${id}']"` 17 | return full 18 | }) 19 | injectScripts = `${randIdFn}const idMap = {${Object.values(idMap).join(',')}};` 20 | } 21 | 22 | return { 23 | hasID, 24 | svg, 25 | injectScripts, 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/esbuild.ts: -------------------------------------------------------------------------------- 1 | import unplugin from '.' 2 | 3 | export default unplugin.esbuild 4 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import type { Options } from './types' 2 | import { createUnplugin } from 'unplugin' 3 | import { generateComponentFromPath, isIconPath, normalizeIconPath, resolveIconsPath } from './core/loader' 4 | import { resolveOptions } from './core/options' 5 | 6 | const unplugin = createUnplugin((options = {}) => { 7 | const resolved = resolveOptions(options) 8 | 9 | return { 10 | name: 'unplugin-icons', 11 | enforce: 'pre', 12 | resolveId(id) { 13 | if (isIconPath(id)) { 14 | const normalizedId = normalizeIconPath(id) 15 | // fix issue 322 16 | const queryIndex = normalizedId.indexOf('?') 17 | const res = `${(queryIndex > -1 ? normalizedId.slice(0, queryIndex) : normalizedId) 18 | .replace(/\.\w+$/, '') 19 | .replace(/^\//, '')}${queryIndex > -1 ? `?${normalizedId.slice(queryIndex + 1)}` : ''}` 20 | const resolved = resolveIconsPath(res) 21 | // accept raw compiler from query params 22 | const compiler = resolved?.query?.raw === 'true' ? 'raw' : options.compiler 23 | if (compiler && typeof compiler !== 'string') { 24 | const ext = compiler.extension 25 | if (ext) 26 | return `${res}.${ext.startsWith('.') ? ext.slice(1) : ext}` 27 | } 28 | else { 29 | switch (compiler) { 30 | case 'astro': 31 | return `${res}.astro` 32 | case 'jsx': 33 | return `${res}.jsx` 34 | case 'qwik': 35 | return `${res}.jsx` 36 | case 'marko': 37 | return `${res}.marko` 38 | case 'svelte': 39 | return `${res}.svelte` 40 | case 'solid': 41 | return `${res}.tsx` 42 | } 43 | } 44 | return res 45 | } 46 | return null 47 | }, 48 | loadInclude(id) { 49 | return isIconPath(id) 50 | }, 51 | async load(id) { 52 | const config = await resolved 53 | const code = await generateComponentFromPath(id, config) || null 54 | if (code) { 55 | return { 56 | code, 57 | map: { version: 3, mappings: '', sources: [] } as any, 58 | } 59 | } 60 | }, 61 | rollup: { 62 | api: { 63 | config: options, 64 | }, 65 | }, 66 | } 67 | }) 68 | 69 | export * from './types' 70 | 71 | export default unplugin 72 | -------------------------------------------------------------------------------- /src/loaders.ts: -------------------------------------------------------------------------------- 1 | import type { Awaitable } from '@antfu/utils' 2 | import type { AutoInstall, ExternalPkgName } from '@iconify/utils/lib/loader/types' 3 | import type { CustomIconLoader } from '.' 4 | import { createExternalPackageIconLoader } from '@iconify/utils/lib/loader/external-pkg' 5 | import { FileSystemIconLoader as IconifyFileSystemIconLoader } from '@iconify/utils/lib/loader/node-loaders' 6 | 7 | export function FileSystemIconLoader(dir: string, transform?: (svg: string) => Awaitable): CustomIconLoader { 8 | return IconifyFileSystemIconLoader(dir, transform) 9 | } 10 | 11 | export function ExternalPackageIconLoader(packageName: ExternalPkgName, autoInstall?: AutoInstall): Record { 12 | return createExternalPackageIconLoader(packageName, autoInstall) 13 | } 14 | -------------------------------------------------------------------------------- /src/nuxt.ts: -------------------------------------------------------------------------------- 1 | import type { Options } from './types' 2 | import unplugin from '.' 3 | 4 | export default function (this: any, options: Options = {}, nuxt: any) { 5 | const nuxtApp = this?.nuxt || nuxt 6 | 7 | if (nuxtApp?._version?.startsWith('3.')) { 8 | options.compiler = 'vue3' 9 | 10 | // injecting types 11 | nuxtApp.options.typescript ||= {} 12 | nuxtApp.options.typescript.tsConfig ||= {} 13 | nuxtApp.options.typescript.tsConfig.compilerOptions ||= {} 14 | nuxtApp.options.typescript.tsConfig.compilerOptions.types ||= [] 15 | nuxtApp.options.typescript.tsConfig.compilerOptions.types.push('unplugin-icons/types/vue') 16 | } 17 | 18 | // install webpack plugin 19 | nuxtApp.hook('webpack:config', (configs: any[]) => { 20 | configs.forEach((config) => { 21 | config.plugins = config.plugins || [] 22 | config.plugins.unshift(unplugin.webpack(options)) 23 | }) 24 | }) 25 | 26 | // install vite plugin 27 | nuxtApp.hook('vite:extend', async (vite: any) => { 28 | vite.config.plugins = vite.config.plugins || [] 29 | vite.config.plugins.push(unplugin.vite(options)) 30 | }) 31 | } 32 | -------------------------------------------------------------------------------- /src/resolver.ts: -------------------------------------------------------------------------------- 1 | import { toArray, uniq } from '@antfu/utils' 2 | import { camelToKebab } from '@iconify/utils/lib/misc/strings' 3 | import { collections as allCollections } from './core/collections' 4 | 5 | export interface ComponentResolverOption { 6 | /** 7 | * Prefix for resolving components name. 8 | * Set '' to disable prefix. 9 | * 10 | * @default 'i' 11 | */ 12 | prefix?: string | false 13 | 14 | /** 15 | * Iconify collection names to that enable for resolving. 16 | * 17 | * @default [all collections] 18 | */ 19 | enabledCollections?: string | string[] 20 | 21 | /** 22 | * Icon collections aliases. 23 | * 24 | * The `aliases` keys are the `alias` and the values are the `name` for the collection. 25 | * 26 | * Instead using `` we can use `` configuring: 27 | * `alias: { park: 'icon-park' }` 28 | */ 29 | alias?: Record 30 | 31 | /** 32 | * Name for custom collections provide by loaders. 33 | */ 34 | customCollections?: string | string[] 35 | 36 | /** 37 | * Extension for the resolved id 38 | * Set `jsx` for JSX components 39 | * 40 | * @default '' 41 | */ 42 | extension?: string 43 | 44 | /** 45 | * @deprecated renamed to `prefix` 46 | */ 47 | componentPrefix?: string 48 | 49 | /** 50 | * For collections strict matching. 51 | * Default is `false`, not side effect. 52 | * Set `true` to enable strict matching with `-` suffix for all collections. 53 | */ 54 | strict?: boolean 55 | } 56 | 57 | /** 58 | * Resolver for unplugin-vue-components and unplugin-auto-import 59 | * 60 | * @param options 61 | */ 62 | export default function ComponentsResolver(options: ComponentResolverOption = {}) { 63 | const { 64 | prefix: rawPrefix = options.componentPrefix ?? 'i', 65 | enabledCollections = allCollections, 66 | alias = {}, 67 | customCollections = [], 68 | extension, 69 | strict = false, 70 | } = options 71 | 72 | const prefix = rawPrefix ? `${camelToKebab(rawPrefix)}-` : '' 73 | const ext = extension 74 | ? extension.startsWith('.') 75 | ? extension 76 | : `.${extension}` 77 | : '' 78 | const collections = uniq([ 79 | ...toArray(enabledCollections), 80 | ...toArray(customCollections), 81 | ...toArray(Object.keys(alias)), 82 | ]) 83 | 84 | // match longer name first 85 | collections.sort((a, b) => b.length - a.length) 86 | 87 | return (name: string) => { 88 | let collection: string 89 | let icon: string 90 | if (name.includes(':')) { 91 | const [iconPrefix, iconSuffix] = name.split(':') 92 | collection = camelToKebab(iconPrefix) 93 | if (!collection.startsWith(prefix)) 94 | return 95 | 96 | const slice = collection.slice(prefix.length) 97 | // find the collection 98 | const resolvedCollection = collections.find(i => slice === i) 99 | if (!resolvedCollection) 100 | return 101 | 102 | collection = resolvedCollection 103 | 104 | icon = camelToKebab(iconSuffix) 105 | } 106 | else { 107 | const kebab = camelToKebab(name) 108 | if (!kebab.startsWith(prefix)) 109 | return 110 | 111 | const slice = kebab.slice(prefix.length) 112 | const resolvedCollection = collections.find(i => slice.startsWith(`${i}-`)) || (!strict && collections.find(i => slice.startsWith(i))) 113 | if (!resolvedCollection) 114 | return 115 | 116 | collection = resolvedCollection 117 | icon = slice.slice(resolvedCollection.length) 118 | } 119 | 120 | if (icon[0] === '-') 121 | icon = icon.slice(1) 122 | 123 | if (!icon) 124 | return 125 | 126 | const resolvedCollection = alias[collection] || collection 127 | 128 | if (collections.includes(resolvedCollection)) 129 | return `~icons/${resolvedCollection}/${icon}${ext}` 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/rollup.ts: -------------------------------------------------------------------------------- 1 | import unplugin from '.' 2 | 3 | export default unplugin.rollup 4 | -------------------------------------------------------------------------------- /src/rspack.ts: -------------------------------------------------------------------------------- 1 | import type { Options } from './types' 2 | import unplugin from '.' 3 | 4 | export default unplugin.rspack as (options?: Options) => any 5 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | import type { Awaitable } from '@antfu/utils' 2 | import type { CustomCompiler } from './core/compilers/types' 3 | 4 | export type CustomIconLoader = (name: string) => Awaitable 5 | export type IconCustomizer = (collection: string, icon: string, props: Record) => Awaitable 6 | export type InlineCollection = Record Awaitable)> 7 | export type { CustomCompiler } 8 | 9 | export interface Options { 10 | /** 11 | * Scale of icons against 1em 12 | * 13 | * @default 1.2 14 | */ 15 | scale?: number 16 | 17 | /** 18 | * Style apply to icons by default 19 | * 20 | * @default '' 21 | */ 22 | defaultStyle?: string 23 | 24 | /** 25 | * Class names apply to icons by default 26 | * 27 | * @default '' 28 | */ 29 | defaultClass?: string 30 | 31 | /** 32 | * Loader for custom loaders 33 | */ 34 | customCollections?: Record 35 | 36 | /** 37 | * Icon customizer 38 | */ 39 | iconCustomizer?: IconCustomizer 40 | 41 | /** 42 | * Current working directory for resolving collections from node_modules 43 | */ 44 | collectionsNodeResolvePath?: string | string[] 45 | 46 | /** 47 | * Transform raw `svg`. 48 | * 49 | * **WARNING**: `transform` will be only applied when using `custom` icon collection. 50 | * 51 | * @param svg The loaded `svg` 52 | * @param collection The name of the collection 53 | * @param icon The name of the icon 54 | * @return The transformed `svg`. 55 | */ 56 | transform?: (svg: string, collection: string, icon: string) => Awaitable 57 | 58 | /** 59 | * Auto install icon sources package when the usages is detected 60 | * 61 | * @default false 62 | */ 63 | autoInstall?: boolean 64 | 65 | /** 66 | * Compiler 67 | * 68 | * - none: plain SVG content 69 | * - raw: an ESM module with a default exported string of the SVG HTML 70 | * 71 | * @default (detect automatically, fallback to 'vue3') 72 | */ 73 | compiler?: 'astro' | 'jsx' | 'marko' | 'none' | 'solid' | 'svelte' | 'raw' | 'vue2' | 'vue3' | 'web-components' | 'qwik' | CustomCompiler 74 | 75 | /** 76 | * JSX style, works only when compiler set to `jsx` 77 | * 78 | * @default (detect automatically, fallback to 'react') 79 | */ 80 | jsx?: 'react' | 'preact' | 'qwik' 81 | 82 | /** 83 | * Config for Web Components compiler 84 | */ 85 | webComponents?: { 86 | /** 87 | * Call `customElements.define` automatically on module importing 88 | */ 89 | autoDefine?: boolean 90 | 91 | /** 92 | * Prefix for auto defining 93 | * 94 | * @default 'icon' 95 | */ 96 | iconPrefix?: string 97 | 98 | /** 99 | * Use shadow DOM 100 | * @default false 101 | */ 102 | shadow?: boolean 103 | } 104 | 105 | /** 106 | * @deprecated no longer needed 107 | */ 108 | iconSource?: 'legacy' | 'modern' | 'auto' 109 | } 110 | 111 | export type ResolvedOptions = Omit, 'iconSource' | 'transform'> & Pick 112 | -------------------------------------------------------------------------------- /src/vite.ts: -------------------------------------------------------------------------------- 1 | import unplugin from '.' 2 | 3 | export default unplugin.vite 4 | -------------------------------------------------------------------------------- /src/webpack.ts: -------------------------------------------------------------------------------- 1 | import type { Options } from './types' 2 | import unplugin from '.' 3 | 4 | export default unplugin.webpack as (options?: Options) => any 5 | -------------------------------------------------------------------------------- /test/__snapshots__/idSvg.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`handleSVGId 1`] = ` 4 | { 5 | "hasID": true, 6 | "injectScripts": "const __randId = () => Math.random().toString(36).substr(2, 10);const idMap = {'ssvg-id-vitejsa':'uicons-'+__randId(),'ssvg-id-vitejsb':'uicons-'+__randId()};", 7 | "svg": " 8 | 14 | 15 | 22 | 23 | 24 | 25 | 32 | 33 | 34 | 35 | 36 | 37 | 41 | 45 | 46 | ", 47 | } 48 | `; 49 | -------------------------------------------------------------------------------- /test/idSvg.test.ts: -------------------------------------------------------------------------------- 1 | import { expect, it } from 'vitest' 2 | import { handleSVGId } from '../src/core/svgId' 3 | 4 | const fixture = ` 5 | 11 | 12 | 19 | 20 | 21 | 22 | 29 | 30 | 31 | 32 | 33 | 34 | 38 | 42 | 43 | ` 44 | 45 | it('handleSVGId', () => { 46 | expect(handleSVGId(fixture)).toMatchSnapshot() 47 | }) 48 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "jsx": "preserve", 5 | "lib": ["ESNext", "DOM"], 6 | "module": "ESNext", 7 | "moduleResolution": "Node", 8 | "resolveJsonModule": true, 9 | "strict": true, 10 | "strictNullChecks": true, 11 | "esModuleInterop": true, 12 | "skipLibCheck": true 13 | }, 14 | "exclude": [ 15 | "**/dist", 16 | "**/node_modules", 17 | "**/test", 18 | "**/examples", 19 | "dist" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /tsup.config.ts: -------------------------------------------------------------------------------- 1 | import type { Options } from 'tsup' 2 | 3 | export const tsup: Options = { 4 | splitting: true, 5 | clean: true, 6 | dts: true, 7 | entry: [ 8 | 'src/*.ts', 9 | ], 10 | format: [ 11 | 'esm', 12 | 'cjs', 13 | ], 14 | external: [ 15 | 'vue', 16 | '@iconify/json/package.json', 17 | ], 18 | } 19 | -------------------------------------------------------------------------------- /types/astro.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '~icons/*' { 4 | const component: (props: astroHTML.JSX.SVGAttributes) => astroHTML.JSX.Element 5 | export default component 6 | } 7 | declare module 'virtual:icons/*' { 8 | const component: (props: astroHTML.JSX.SVGAttributes) => astroHTML.JSX.Element 9 | export default component 10 | } 11 | -------------------------------------------------------------------------------- /types/index.d.ts: -------------------------------------------------------------------------------- 1 | export { default } from '../dist/types' 2 | -------------------------------------------------------------------------------- /types/preact.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'virtual:icons/*' { 2 | import type { JSX } from 'preact' 3 | 4 | const component: (props: JSX.SVGAttributes) => JSX.Element 5 | export default component 6 | } 7 | declare module '~icons/*' { 8 | import type { JSX } from 'preact' 9 | 10 | const component: (props: JSX.SVGAttributes) => JSX.Element 11 | export default component 12 | } 13 | -------------------------------------------------------------------------------- /types/qwik.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'virtual:icons/*' { 2 | import type { FunctionComponent, QwikIntrinsicElements } from '@builder.io/qwik' 3 | 4 | const Component: FunctionComponent 5 | export default Component 6 | } 7 | declare module '~icons/*' { 8 | import type { FunctionComponent, QwikIntrinsicElements } from '@builder.io/qwik' 9 | 10 | const Component: FunctionComponent 11 | export default Component 12 | } 13 | -------------------------------------------------------------------------------- /types/raw.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'virtual:icons/*' { 2 | const component: string 3 | export default string 4 | } 5 | declare module '~icons/*' { 6 | const component: string 7 | export default component 8 | } 9 | -------------------------------------------------------------------------------- /types/react.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'virtual:icons/*' { 2 | import type { ForwardRefExoticComponent, SVGProps } from 'react' 3 | 4 | const component: ForwardRefExoticComponent> 5 | export default component 6 | } 7 | declare module '~icons/*' { 8 | import type { ForwardRefExoticComponent, SVGProps } from 'react' 9 | 10 | const component: ForwardRefExoticComponent> 11 | export default component 12 | } 13 | -------------------------------------------------------------------------------- /types/solid.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'virtual:icons/*' { 2 | import type { ComponentProps, JSX } from 'solid-js' 3 | 4 | const component: (props: ComponentProps<'svg'>) => JSX.Element 5 | export default component 6 | } 7 | declare module '~icons/*' { 8 | import type { ComponentProps, JSX } from 'solid-js' 9 | 10 | const component: (props: ComponentProps<'svg'>) => JSX.Element 11 | export default component 12 | } 13 | -------------------------------------------------------------------------------- /types/svelte.d.ts: -------------------------------------------------------------------------------- 1 | import './svelte5.d.ts' 2 | -------------------------------------------------------------------------------- /types/svelte3.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'virtual:icons/*' { 2 | export { SvelteComponentDev as default } from 'svelte/internal' 3 | } 4 | 5 | declare module '~icons/*' { 6 | import { SvelteComponentTyped } from 'svelte' 7 | 8 | export default class extends SvelteComponentTyped {} 9 | } 10 | -------------------------------------------------------------------------------- /types/svelte4.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'virtual:icons/*' { 2 | import type { SvelteHTMLElements } from 'svelte/elements' 3 | import { SvelteComponent } from 'svelte' 4 | 5 | export default class extends SvelteComponent {} 6 | } 7 | 8 | declare module '~icons/*' { 9 | import type { SvelteHTMLElements } from 'svelte/elements' 10 | import { SvelteComponent } from 'svelte' 11 | 12 | export default class extends SvelteComponent {} 13 | } 14 | -------------------------------------------------------------------------------- /types/svelte5.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'virtual:icons/*' { 2 | import type { Component } from 'svelte' 3 | import type { SvelteHTMLElements } from 'svelte/elements' 4 | 5 | const component: Component 6 | 7 | export default component 8 | } 9 | 10 | declare module '~icons/*' { 11 | import type { Component } from 'svelte' 12 | import type { SvelteHTMLElements } from 'svelte/elements' 13 | 14 | const component: Component 15 | 16 | export default component 17 | } 18 | -------------------------------------------------------------------------------- /types/vue.d.ts: -------------------------------------------------------------------------------- 1 | import './vue3.d.ts' 2 | -------------------------------------------------------------------------------- /types/vue3.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'virtual:icons/*' { 2 | import type { FunctionalComponent, SVGAttributes } from 'vue' 3 | 4 | const component: FunctionalComponent 5 | export default component 6 | } 7 | declare module '~icons/*' { 8 | import type { FunctionalComponent, SVGAttributes } from 'vue' 9 | 10 | const component: FunctionalComponent 11 | export default component 12 | } 13 | -------------------------------------------------------------------------------- /types/web-components.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'virtual:icons/*' { 2 | const component: HTMLElement 3 | export default component 4 | } 5 | declare module '~icons/*' { 6 | const component: HTMLElement 7 | export default component 8 | } 9 | --------------------------------------------------------------------------------