@stephansama/vite-iconify-svgmap 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +226 -0
- package/client.d.ts +16 -0
- package/dist/astro/integration.d.mts +11 -0
- package/dist/astro/integration.mjs +22 -0
- package/dist/index.d.mts +24 -0
- package/dist/index.mjs +2 -0
- package/dist/src-CsllISxW.mjs +8060 -0
- package/dist/svelte/integration.d.mts +23 -0
- package/dist/svelte/integration.mjs +80 -0
- package/dist/type-S4YO472i.d.mts +18 -0
- package/frameworks/astro/astro.d.ts +5 -0
- package/frameworks/astro/component.ts +1 -0
- package/frameworks/astro/icon.astro +31 -0
- package/frameworks/astro/index.ts +3 -0
- package/frameworks/svelte/component.d.ts +19 -0
- package/frameworks/svelte/component.js +1 -0
- package/frameworks/svelte/icon.svelte +33 -0
- package/frameworks/svelte/index.d.ts +3 -0
- package/frameworks/svelte/index.js +3 -0
- package/package.json +114 -0
- package/skills/vite-iconify-svgmap/SKILL.md +161 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Stephan Randle
|
|
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# [`@stephansama`](https://github.com/stephansama) / vite-iconify-svgmap
|
|
4
|
+
|
|
5
|
+
<!-- BADGE start -->
|
|
6
|
+
|
|
7
|
+
[](https://github.com/stephansama/packages/tree/main/core/vite-iconify-svgmap)
|
|
8
|
+
[](https://packages.stephansama.info/api/@stephansama/vite-iconify-svgmap)
|
|
9
|
+
[](https://www.npmx.dev/package/@stephansama/vite-iconify-svgmap)
|
|
10
|
+
[](https://socket.dev/npm/package/@stephansama/vite-iconify-svgmap/overview)
|
|
11
|
+
[](https://jsr.io/@stephansama/vite-iconify-svgmap)
|
|
12
|
+
[](https://www.npmx.dev/package/@stephansama/vite-iconify-svgmap)
|
|
13
|
+
|
|
14
|
+
[](https://npmx.dev/package/@iconify/types)
|
|
15
|
+
[](https://npmx.dev/package/@tanstack/intent)
|
|
16
|
+
[](https://npmx.dev/package/astro)
|
|
17
|
+
[](https://npmx.dev/package/svelte)
|
|
18
|
+
[](https://npmx.dev/package/tsdown)
|
|
19
|
+
[](https://npmx.dev/package/vite)
|
|
20
|
+
|
|
21
|
+
<!-- BADGE end -->
|
|
22
|
+
|
|
23
|
+
Vite plugin for generating iconify svg sprite maps in memory
|
|
24
|
+
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
##### Table of contents
|
|
28
|
+
|
|
29
|
+
<details><summary>Open Table of contents</summary>
|
|
30
|
+
|
|
31
|
+
- [Installation](#installation)
|
|
32
|
+
- [Usage](#usage)
|
|
33
|
+
- [Astro](#astro)
|
|
34
|
+
- [SvelteKit](#sveltekit)
|
|
35
|
+
- [Vite](#vite)
|
|
36
|
+
- [Static imports](#static-imports)
|
|
37
|
+
- [Icons known while rendering](#icons-known-while-rendering)
|
|
38
|
+
- [Icon components](#icon-components)
|
|
39
|
+
- [Options](#options)
|
|
40
|
+
- [How it works](#how-it-works)
|
|
41
|
+
|
|
42
|
+
</details>
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
|
|
46
|
+
Install the plugin and at least one `@iconify-json/*` icon pack
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
pnpm install -D @stephansama/vite-iconify-svgmap @iconify-json/logos
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Add the virtual module types to your `tsconfig.json`
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"compilerOptions": {
|
|
57
|
+
"types": ["@stephansama/vite-iconify-svgmap/client"]
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Usage
|
|
63
|
+
|
|
64
|
+
### Astro
|
|
65
|
+
|
|
66
|
+
The astro integration adds the vite plugin and writes sprites for icons
|
|
67
|
+
registered with `getIcon` once every page has rendered.
|
|
68
|
+
|
|
69
|
+
```js
|
|
70
|
+
// astro.config.mjs
|
|
71
|
+
import iconifySvgmap from "@stephansama/vite-iconify-svgmap/astro/integration";
|
|
72
|
+
import { defineConfig } from "astro/config";
|
|
73
|
+
|
|
74
|
+
export default defineConfig({
|
|
75
|
+
integrations: [iconifySvgmap()],
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### SvelteKit
|
|
80
|
+
|
|
81
|
+
Add the sveltekit plugins **after** `sveltekit()`:
|
|
82
|
+
|
|
83
|
+
```js
|
|
84
|
+
// vite.config.js
|
|
85
|
+
import iconifySvgmap from "@stephansama/vite-iconify-svgmap/svelte/integration";
|
|
86
|
+
import { sveltekit } from "@sveltejs/kit/vite";
|
|
87
|
+
import { defineConfig } from "vite";
|
|
88
|
+
|
|
89
|
+
export default defineConfig({
|
|
90
|
+
plugins: [sveltekit(), iconifySvgmap()],
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
SvelteKit prerenders in a worker thread and has no hook after prerendering,
|
|
95
|
+
so this plugin:
|
|
96
|
+
|
|
97
|
+
- receives `getIcon` calls made inside the prerender worker over an in
|
|
98
|
+
memory `BroadcastChannel`
|
|
99
|
+
- writes empty placeholder sprites for every installed icon pack when the
|
|
100
|
+
client build finishes, so the prerender crawler does not fail on
|
|
101
|
+
`<use href>` links to sprites that do not exist yet
|
|
102
|
+
- writes the real sprites (and removes unused placeholders) after
|
|
103
|
+
prerendering, before the adapter copies the client output
|
|
104
|
+
|
|
105
|
+
### Vite
|
|
106
|
+
|
|
107
|
+
```js
|
|
108
|
+
// vite.config.js
|
|
109
|
+
import iconifySvgmap from "@stephansama/vite-iconify-svgmap";
|
|
110
|
+
import { defineConfig } from "vite";
|
|
111
|
+
|
|
112
|
+
export default defineConfig({
|
|
113
|
+
plugins: [iconifySvgmap()],
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Static imports need nothing else. If you use `getIcon` in a server rendered
|
|
118
|
+
or prerendered app, call `writeSprites` with your client output directory
|
|
119
|
+
once rendering has finished:
|
|
120
|
+
|
|
121
|
+
```js
|
|
122
|
+
import { writeSprites } from "@stephansama/vite-iconify-svgmap";
|
|
123
|
+
|
|
124
|
+
await writeSprites("dist");
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Static imports
|
|
128
|
+
|
|
129
|
+
Import an icon as `virtual:iconify-svgmap/<pack>/<icon>` to get its sprite
|
|
130
|
+
href. Unknown packs or icons fail the build.
|
|
131
|
+
|
|
132
|
+
```astro
|
|
133
|
+
---
|
|
134
|
+
import astro from "virtual:iconify-svgmap/logos/astro";
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
<svg width="24" height="24"><use href={astro}></use></svg>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Only the imported icons end up in a content hashed sprite per pack (for
|
|
141
|
+
example `/_astro/logos.BzUCTX55.svg`).
|
|
142
|
+
|
|
143
|
+
### Icons known while rendering
|
|
144
|
+
|
|
145
|
+
When the icon name is only known while rendering (cms data, frontmatter,
|
|
146
|
+
loops), use `getIcon`:
|
|
147
|
+
|
|
148
|
+
```astro
|
|
149
|
+
---
|
|
150
|
+
import { getIcon } from "virtual:iconify-svgmap";
|
|
151
|
+
|
|
152
|
+
const href = getIcon(entry.data.iconPack, entry.data.icon);
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
<svg width="24" height="24"><use href={href}></use></svg>
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
`getIcon` records the icon in memory and returns
|
|
159
|
+
`/_iconify/<pack>.svg?v=<build>#<icon>`. The sprite is written after all pages
|
|
160
|
+
have rendered.
|
|
161
|
+
|
|
162
|
+
> \[!NOTE]
|
|
163
|
+
> `getIcon` icons must be rendered during the build, in the same process or
|
|
164
|
+
> one of its worker threads (static astro sites and prerendered sveltekit
|
|
165
|
+
> pages). Icons first requested at runtime by an on demand rendered route, or
|
|
166
|
+
> only by client side code, are not included in the written sprites. During
|
|
167
|
+
> development every icon works, including client rendered ones.
|
|
168
|
+
|
|
169
|
+
### Icon components
|
|
170
|
+
|
|
171
|
+
Each framework subpath exports an `Icon` component that wraps `getIcon` in an
|
|
172
|
+
`<svg><use /></svg>`. They follow the same rules as `getIcon`: icons must be
|
|
173
|
+
rendered on the server during the build (for example astro pages or
|
|
174
|
+
server rendered svelte islands) and the sprites written afterwards (the astro
|
|
175
|
+
integration does this).
|
|
176
|
+
|
|
177
|
+
| Framework | Import |
|
|
178
|
+
| --------- | --------------------------------------------------------------------------- |
|
|
179
|
+
| astro | `import { Icon } from "@stephansama/vite-iconify-svgmap/astro/component";` |
|
|
180
|
+
| svelte 5 | `import { Icon } from "@stephansama/vite-iconify-svgmap/svelte/component";` |
|
|
181
|
+
|
|
182
|
+
```astro
|
|
183
|
+
---
|
|
184
|
+
import { Icon } from "@stephansama/vite-iconify-svgmap/astro/component";
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
<Icon pack="logos" name="github-icon" size={24} title="GitHub" />
|
|
188
|
+
<Icon pack="heroicons" name="heart-solid" class="text-red-500" />
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
```svelte
|
|
192
|
+
<script>
|
|
193
|
+
import { Icon } from "@stephansama/vite-iconify-svgmap/svelte/component";
|
|
194
|
+
</script>
|
|
195
|
+
|
|
196
|
+
<Icon pack="logos" name="svelte-icon" size={24} title="Svelte" />
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
| Prop | Default | Description |
|
|
200
|
+
| ------- | ------- | -------------------------------------------------------------------- |
|
|
201
|
+
| `pack` | | iconify pack, e.g. `logos` for `@iconify-json/logos` |
|
|
202
|
+
| `name` | | icon name inside the pack |
|
|
203
|
+
| `size` | `"1em"` | width and height |
|
|
204
|
+
| `title` | | accessible label; without it the icon gets `aria-hidden="true"` |
|
|
205
|
+
| ... | | any other svg attribute (`class`, `style`, ...) is passed to `<svg>` |
|
|
206
|
+
|
|
207
|
+
Icons that use `currentColor` follow the css `color` of the component.
|
|
208
|
+
|
|
209
|
+
## Options
|
|
210
|
+
|
|
211
|
+
| Option | Default | Description |
|
|
212
|
+
| ------ | ------------- | -------------------------------------------------------------------------------------- |
|
|
213
|
+
| `dir` | `"_iconify"` | folder, relative to the output directory, for sprites of icons registered by `getIcon` |
|
|
214
|
+
| `root` | vite's `root` | directory used to resolve `@iconify-json/*` packages |
|
|
215
|
+
|
|
216
|
+
## How it works
|
|
217
|
+
|
|
218
|
+
Nothing is written to the file system until the final output:
|
|
219
|
+
|
|
220
|
+
- icon packs are loaded lazily, only when an icon from the pack is requested
|
|
221
|
+
- during development sprites are generated in memory and served by the dev
|
|
222
|
+
server
|
|
223
|
+
- static imports are emitted as vite assets, so they are hashed and moved to
|
|
224
|
+
the output like any other asset
|
|
225
|
+
- `getIcon` usage is kept in an in memory registry and flushed once by
|
|
226
|
+
`writeSprites`
|
package/client.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
declare module "virtual:iconify-svgmap" {
|
|
2
|
+
/**
|
|
3
|
+
* Register an icon while rendering and return its sprite href, e.g.
|
|
4
|
+
* `/_iconify/<pack>.svg?v=<build>#<name>`
|
|
5
|
+
*/
|
|
6
|
+
export function getIcon(pack: string, name: string): string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
declare module "virtual:iconify-svgmap/*" {
|
|
10
|
+
/**
|
|
11
|
+
* Sprite href for the imported icon, e.g.
|
|
12
|
+
* `/_astro/<pack>-<hash>.svg#<icon>`
|
|
13
|
+
*/
|
|
14
|
+
const href: string;
|
|
15
|
+
export default href;
|
|
16
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { t as Options } from "../type-S4YO472i.mjs";
|
|
2
|
+
import { AstroIntegration } from "astro";
|
|
3
|
+
|
|
4
|
+
//#region src/astro.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Astro integration that adds the vite plugin and writes sprites for icons
|
|
7
|
+
* registered with `getIcon` once every page has been rendered
|
|
8
|
+
*/
|
|
9
|
+
declare function iconifySvgmapIntegration(options?: Options): AstroIntegration;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { iconifySvgmapIntegration as default };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { n as iconifySvgmap, o as name, r as writeSprites } from "../src-CsllISxW.mjs";
|
|
2
|
+
//#region src/astro.ts
|
|
3
|
+
/**
|
|
4
|
+
* Astro integration that adds the vite plugin and writes sprites for icons
|
|
5
|
+
* registered with `getIcon` once every page has been rendered
|
|
6
|
+
*/
|
|
7
|
+
function iconifySvgmapIntegration(options = {}) {
|
|
8
|
+
return {
|
|
9
|
+
name,
|
|
10
|
+
hooks: {
|
|
11
|
+
async "astro:build:done"({ dir, logger }) {
|
|
12
|
+
const written = await writeSprites(dir);
|
|
13
|
+
if (written.length > 0) logger.info(`wrote ${written.length} svg sprite(s)`);
|
|
14
|
+
},
|
|
15
|
+
"astro:config:setup"({ updateConfig }) {
|
|
16
|
+
updateConfig({ vite: { plugins: [iconifySvgmap(options)] } });
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
export { iconifySvgmapIntegration as default };
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { t as Options } from "./type-S4YO472i.mjs";
|
|
2
|
+
import { Plugin } from "vite";
|
|
3
|
+
|
|
4
|
+
//#region src/index.d.ts
|
|
5
|
+
declare const VIRTUAL_MODULE_ID = "virtual:iconify-svgmap";
|
|
6
|
+
/**
|
|
7
|
+
* Vite plugin that turns iconify icons into svg sprite maps
|
|
8
|
+
*
|
|
9
|
+
* - `import href from "virtual:iconify-svgmap/<pack>/<icon>"` resolves at build
|
|
10
|
+
* time and emits a content hashed `<pack>.svg` sprite through vite
|
|
11
|
+
* - `import { getIcon } from "virtual:iconify-svgmap"` registers icons while
|
|
12
|
+
* pages render; call {@link writeSprites} after rendering to write their
|
|
13
|
+
* sprites (the `/astro` integration does this for you)
|
|
14
|
+
*/
|
|
15
|
+
declare function iconifySvgmap(options?: Options): Plugin;
|
|
16
|
+
/**
|
|
17
|
+
* Write sprites for every icon registered with `getIcon` into
|
|
18
|
+
* `<outDirectory>/<dir>/<pack>.svg`. call this after all pages have rendered.
|
|
19
|
+
*
|
|
20
|
+
* @returns The paths of the written sprites
|
|
21
|
+
*/
|
|
22
|
+
declare function writeSprites(outDirectory: string | URL): Promise<string[]>;
|
|
23
|
+
//#endregion
|
|
24
|
+
export { type Options, VIRTUAL_MODULE_ID, iconifySvgmap as default, writeSprites };
|
package/dist/index.mjs
ADDED