@omnicajs/icons 0.2.0 → 0.3.1

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.
Files changed (70) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +113 -0
  3. package/assets/icons/filled/actions/badge-recommendation.svg +3 -0
  4. package/assets/icons/filled/actions/clear-circle-small.svg +3 -0
  5. package/assets/icons/filled/actions/clear-circle.svg +1 -1
  6. package/assets/icons/filled/commerce/shopping-cart-sale.svg +3 -0
  7. package/assets/icons/filled/layout/browser-window-close.svg +3 -0
  8. package/assets/icons/filled/layout/browser-window-in.svg +3 -0
  9. package/assets/icons/filled/navigation/exit.svg +4 -0
  10. package/assets/icons/filled/navigation/menu-squares.svg +3 -0
  11. package/dist/_virtual/_rolldown/runtime.cjs +23 -0
  12. package/dist/build.js +1 -13
  13. package/dist/extracted/bundler/component-loader.cjs +26 -0
  14. package/dist/extracted/bundler/component-loader.d.ts +3 -0
  15. package/dist/extracted/bundler/plugin.cjs +125 -0
  16. package/dist/extracted/bundler/plugin.d.ts +21 -0
  17. package/dist/extracted/bundler/template-assets-loader.cjs +8 -0
  18. package/dist/extracted/bundler/template-assets-loader.d.ts +3 -0
  19. package/dist/extracted/core.d.ts +14 -0
  20. package/dist/extracted/core.js +64 -0
  21. package/dist/extracted/manifest.cjs +23 -0
  22. package/dist/extracted/manifest.d.ts +11 -0
  23. package/dist/extracted/manifest.js +20 -0
  24. package/dist/extracted/vite.d.ts +8 -0
  25. package/dist/extracted/vite.js +174 -0
  26. package/dist/filled/actions.cjs +1 -1
  27. package/dist/filled/actions.d.ts +1 -1
  28. package/dist/filled/actions.js +1 -1
  29. package/dist/filled/commerce.cjs +1 -1
  30. package/dist/filled/commerce.d.ts +1 -1
  31. package/dist/filled/commerce.js +1 -1
  32. package/dist/filled/index.cjs +4 -4
  33. package/dist/filled/index.d.ts +4 -4
  34. package/dist/filled/index.js +4 -4
  35. package/dist/filled/layout.cjs +1 -1
  36. package/dist/filled/layout.d.ts +1 -1
  37. package/dist/filled/layout.js +1 -1
  38. package/dist/filled/navigation.cjs +1 -1
  39. package/dist/filled/navigation.d.ts +1 -1
  40. package/dist/filled/navigation.js +1 -1
  41. package/dist/manifest.cjs +1 -1
  42. package/dist/manifest.js +1 -1
  43. package/dist/manifest.json +55 -11
  44. package/dist/rspack.cjs +14 -0
  45. package/dist/rspack.d.ts +16 -0
  46. package/dist/shared/sprite.d.ts +2 -0
  47. package/dist/shared/sprite.js +16 -0
  48. package/dist/sprites/filled/actions.svg +7 -1
  49. package/dist/sprites/filled/commerce.svg +3 -0
  50. package/dist/sprites/filled/layout.svg +6 -0
  51. package/dist/sprites/filled/navigation.svg +6 -0
  52. package/dist/sprites/filled.svg +22 -1
  53. package/dist/{adapter-output.d.ts → subset/adapter-output.d.ts} +1 -1
  54. package/dist/{adapter-output.js → subset/adapter-output.js} +1 -1
  55. package/dist/subset/vite.d.ts +7 -0
  56. package/dist/subset/vite.js +61 -0
  57. package/dist/{webpack-loader.cjs → subset/webpack-loader.cjs} +5 -9
  58. package/dist/{webpack-loader.d.ts → subset/webpack-loader.d.ts} +1 -1
  59. package/dist/{webpack-runtime.cjs → subset/webpack-runtime.cjs} +1 -1
  60. package/dist/subset/webpack.cjs +27 -0
  61. package/dist/subset/webpack.d.ts +14 -0
  62. package/dist/vite.d.ts +4 -7
  63. package/dist/vite.js +3 -61
  64. package/dist/webpack.cjs +9 -21
  65. package/dist/webpack.d.ts +12 -7
  66. package/metadata/icon-keywords.json +9 -0
  67. package/metadata/migrations/groups-v1.json +2 -2
  68. package/package.json +14 -2
  69. package/vue.d.ts +36 -0
  70. /package/dist/{webpack-runtime.d.ts → subset/webpack-runtime.d.ts} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.1
4
+
5
+ ### Features
6
+
7
+ * Added import-driven Vue icon components ([5fed0d0](https://github.com/omnicajs/icons/commit/5fed0d0724bafc5d60ba43ab4510c3f1856e944c))
8
+
9
+ ## 0.3.0
10
+
11
+ ### ⚠ BREAKING CHANGE* **icons:** Added missing icons and standardized clear circle
12
+ * **icons:** filled/actions/clear-circle now uses the standard 20x20 circle. The previous 16x16 glyph is available as filled/actions/clear-circle-small.
13
+
14
+
15
+ ### Features
16
+
17
+ * **docs:** Expanded package showcase ([5e849a9](https://github.com/omnicajs/icons/commit/5e849a931ca2409e1dfd5d0662a29cd15477cbe0))
18
+ * **icons:** Added missing icons and standardized clear circle ([c7ac32d](https://github.com/omnicajs/icons/commit/c7ac32d3bc26a40bf9f6d6c0b14f1d4a25def89e))
19
+
3
20
  ## 0.2.0
4
21
 
5
22
  ### ⚠ BREAKING CHANGE* **icons:** Reorganized icon delivery layers
package/README.md CHANGED
@@ -119,6 +119,119 @@ const brainKeywords = manifest.variants.filled.groups.ai.icons['brain-circuit'].
119
119
  // ['ai/brain-ai']
120
120
  ```
121
121
 
122
+ ## Import-driven Vue icons
123
+
124
+ The opt-in Vue adapter complements the existing full, group, and configured subset APIs. It supports Vue 3 and transforms only unqualified `filled` and `outlined` package assets.
125
+
126
+ ### Vite
127
+
128
+ Add the adapter before the regular Vue plugin:
129
+
130
+ ```ts
131
+ import vue from '@vitejs/plugin-vue'
132
+ import { defineConfig } from 'vite'
133
+ import { omnicaIconComponents } from '@omnicajs/icons/vite'
134
+
135
+ export default defineConfig({
136
+ plugins: [
137
+ omnicaIconComponents(),
138
+ vue(),
139
+ ],
140
+ })
141
+ ```
142
+
143
+ ### Webpack
144
+
145
+ Add the icon plugin before `VueLoaderPlugin`. The adapter injects its package-scoped SVG rule and reuses the application's `vue-loader`:
146
+
147
+ ```js
148
+ const { VueLoaderPlugin } = require('vue-loader')
149
+ const { OmnicaIconComponentsPlugin } = require('@omnicajs/icons/webpack')
150
+
151
+ module.exports = {
152
+ output: {
153
+ publicPath: '/',
154
+ },
155
+ module: {
156
+ rules: [
157
+ { test: /\.vue$/, loader: 'vue-loader' },
158
+ { test: /\.svg$/, type: 'asset/resource' },
159
+ ],
160
+ },
161
+ plugins: [
162
+ new OmnicaIconComponentsPlugin(),
163
+ new VueLoaderPlugin(),
164
+ ],
165
+ }
166
+ ```
167
+
168
+ ### Rspack
169
+
170
+ Rspack uses the same contract and its own typed entrypoint:
171
+
172
+ ```js
173
+ const { VueLoaderPlugin } = require('vue-loader')
174
+ const { OmnicaIconComponentsPlugin } = require('@omnicajs/icons/rspack')
175
+
176
+ module.exports = {
177
+ output: {
178
+ publicPath: '/',
179
+ },
180
+ module: {
181
+ rules: [
182
+ { test: /\.vue$/, loader: 'vue-loader' },
183
+ { test: /\.svg$/, type: 'asset/resource' },
184
+ ],
185
+ },
186
+ plugins: [
187
+ new OmnicaIconComponentsPlugin(),
188
+ new VueLoaderPlugin(),
189
+ ],
190
+ }
191
+ ```
192
+
193
+ Both configurations require the normal Vue 3 SFC toolchain (`vue`, `vue-loader`, and `@vue/compiler-sfc`) in the application. The package does not declare a root Vue peer because the adapter is opt-in and the sprite/URL APIs remain compatible with non-Vue and Vue 2 consumers. If an application already has another SVG loader, constrain that rule with a query or exclude `@omnicajs/icons/assets/icons` so one unqualified import is not processed by two component loaders.
194
+
195
+ An unqualified monochrome SVG import then resolves to a Vue component:
196
+
197
+ ```vue
198
+ <script setup lang="ts">
199
+ import IconClearCircle from '@omnicajs/icons/assets/icons/filled/actions/clear-circle.svg'
200
+ </script>
201
+
202
+ <template>
203
+ <IconClearCircle width="24" height="24" aria-hidden="true" />
204
+ </template>
205
+ ```
206
+
207
+ Load the opt-in declarations from a project declaration file included by the consumer `tsconfig`, for example `src/omnica-icons.d.ts`:
208
+
209
+ ```ts
210
+ import '@omnicajs/icons/vue'
211
+ ```
212
+
213
+ The `/vue` entrypoint exports `OmnicaIconProps` as Vue's `SVGAttributes` plus typed `data-*` attributes, and `OmnicaIconComponent` as `DefineComponent<OmnicaIconProps>`. Every transformed asset uses that component type, so TypeScript checks standard SVG presentation, sizing, accessibility, data, and event attributes instead of exposing an unqualified generic Vue component.
214
+
215
+ Production builds emit one content-hashed sprite containing the imported `filled` and `outlined` symbols. Generated components preserve the source `viewBox`, forward attributes to their root `svg`, and inherit `currentColor`. The symbol fragment includes the variant, for example `#filled/actions/clear-circle`, so filled and outlined names cannot collide. Vite honours its configured root-relative `base`; Webpack and Rspack use their root-relative `output.publicPath`.
216
+
217
+ For SSR, run the client build first. It emits `.omnica/omnica-icons-imported.json`; the Vite, Webpack, and Rspack SSR adapters read that manifest and reference the exact client sprite instead of hashing the server graph independently. Server-rendered icons must be a subset of the client graph, otherwise the SSR build fails with the missing symbol names instead of producing a URL that would return 404.
218
+
219
+ The default client output is `<root>/dist` for Vite and `<context>/dist` for Webpack/Rspack. When the client uses another output directory, pass it to both configurations:
220
+
221
+ ```ts
222
+ omnicaIconComponents({ clientOutputDirectory: 'dist/client' })
223
+ ```
224
+
225
+ ```js
226
+ new OmnicaIconComponentsPlugin({ clientOutputDirectory: 'dist/client' })
227
+ ```
228
+
229
+ All production builds require a root-relative public path such as `/app/`: configure it through Vite `base` or Webpack/Rspack `output.publicPath`. Absolute HTTP(S), protocol-relative, automatic, empty, and relative paths are rejected. The generated components use external SVG `<use>` references, which browsers restrict to the page origin, so CDN sprite URLs are not supported. SSR builds reuse the public sprite URL recorded by the client manifest even when the server bundler has another root-relative public path.
230
+
231
+ Vite development serves content-addressed one-symbol sprites so HMR can add or remove imports without stale combined-sprite state. Vite watch builds and Webpack/Rspack watch compilations recalculate the production sprite from the current module graph.
232
+
233
+ Imports with `?url` keep the bundler's standard string URL behavior. Static asset URLs in Vue templates, CSS `url()` references, and JavaScript `new URL(..., import.meta.url)` dependencies also remain in the normal asset pipeline; only module imports become components. Flags and logos are not transformed by this adapter and remain available through their existing URL and sprite APIs.
234
+
122
235
  ## Custom subsets with the CLI
123
236
 
124
237
  The package can generate one sprite per selected variant. Create `omnica-icons.config.mjs`:
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
2
+ <path d="M14.5623 2.43733L12 1L9.43769 2.43733L6.5 2.47372L4.99964 4.99964L2.47372 6.5L2.43733 9.43769L1 12L2.43733 14.5623L2.47372 17.5L4.99964 19.0004L6.5 21.5263L9.43769 21.5627L12 23L14.5623 21.5627L17.5 21.5263L19.0004 19.0004L21.5263 17.5L21.5627 14.5623L23 12L21.5627 9.43769L21.5263 6.5L19.0004 4.99964L17.5 2.47372L14.5623 2.43733ZM10.0168 4.59854L12 3.48605L13.9832 4.59854L16.257 4.62671L17.4182 6.58176L19.3733 7.74303L19.4015 10.0168L20.5139 12L19.4015 13.9832L19.3733 16.257L17.4182 17.4182L16.257 19.3733L13.9832 19.4015L12 20.5139L10.0168 19.4015L7.74303 19.3733L6.58176 17.4182L4.62671 16.257L4.59854 13.9832L3.48605 12L4.59854 10.0168L4.62671 7.74303L6.58176 6.58176L7.74303 4.62671L10.0168 4.59854ZM16.263 9.98931H13.5983L14.4244 8.33189C14.5922 8.00225 14.6747 7.63578 14.6642 7.26603V7.05819C14.6642 6.61669 14.3063 6.25879 13.8648 6.25879H13.7902C13.6766 6.25963 13.5761 6.33238 13.5397 6.43999L13.22 7.3886C13.1208 7.68463 12.8967 7.92228 12.6071 8.03878L12.3779 8.12938C11.9596 8.30084 11.6055 8.59904 11.3654 8.98207L10.7152 10.0479C10.52 10.3602 10.1775 10.5496 9.80919 10.5489H9.33488V14.8123H9.64931C10.1274 14.8056 10.5888 14.9875 10.9337 15.3186C11.2742 15.6595 11.7362 15.8512 12.218 15.8516H15.5435C15.9784 15.8498 16.3686 15.5841 16.5295 15.1801L17.0997 13.7571C17.2503 13.379 17.3281 12.9757 17.3289 12.5687V11.0552C17.3289 10.4665 16.8517 9.98931 16.263 9.98931ZM8.26909 15.0518C8.26909 15.199 8.14979 15.3183 8.00262 15.3183H6.93676C6.78959 15.3183 6.67029 15.199 6.67029 15.0518V10.2555C6.67029 10.1083 6.78959 9.98899 6.93676 9.98899H8.00262C8.14979 9.98899 8.26909 10.1083 8.26909 10.2555V15.0518Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" />
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
2
+ <path d="M4 12C4 7.58172 7.58172 4 12 4C14.1217 4 16.1566 4.84285 17.6569 6.34315C19.1571 7.84344 20 9.87827 20 12C20 16.4183 16.4183 20 12 20C7.58172 20 4 16.4183 4 12ZM15 14.0453C15 13.9226 14.9492 13.8054 14.8598 13.7214L13.1476 12L14.8598 10.2786C14.9492 10.1946 15 10.0774 15 9.95466C15 9.83196 14.9492 9.71471 14.8598 9.63074L14.3693 9.14023C14.2853 9.05076 14.168 9 14.0453 9C13.9226 9 13.8054 9.05076 13.7214 9.14023L12 10.8524L10.2786 9.14023C10.1946 9.05076 10.0774 9 9.95466 9C9.83196 9 9.71471 9.05076 9.63074 9.14023L9.14023 9.63074C9.05076 9.71471 9 9.83196 9 9.95466C9 10.0774 9.05076 10.1946 9.14023 10.2786L10.8524 12L9.14023 13.7214C9.05076 13.8054 9 13.9226 9 14.0453C9 14.168 9.05076 14.2853 9.14023 14.3693L9.63074 14.8598C9.71471 14.9492 9.83196 15 9.95466 15C10.0774 15 10.1946 14.9492 10.2786 14.8598L12 13.1476L13.7214 14.8598C13.8054 14.9492 13.9226 15 14.0453 15C14.168 15 14.2853 14.9492 14.3693 14.8598L14.8598 14.3693C14.9492 14.2853 15 14.168 15 14.0453Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" />
3
+ </svg>
@@ -1,3 +1,3 @@
1
1
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
2
- <path d="M4 12C4 7.58172 7.58172 4 12 4C14.1217 4 16.1566 4.84285 17.6569 6.34315C19.1571 7.84344 20 9.87827 20 12C20 16.4183 16.4183 20 12 20C7.58172 20 4 16.4183 4 12ZM15 14.0453C15 13.9226 14.9492 13.8054 14.8598 13.7214L13.1476 12L14.8598 10.2786C14.9492 10.1946 15 10.0774 15 9.95466C15 9.83196 14.9492 9.71471 14.8598 9.63074L14.3693 9.14023C14.2853 9.05076 14.168 9 14.0453 9C13.9226 9 13.8054 9.05076 13.7214 9.14023L12 10.8524L10.2786 9.14023C10.1946 9.05076 10.0774 9 9.95466 9C9.83196 9 9.71471 9.05076 9.63074 9.14023L9.14023 9.63074C9.05076 9.71471 9 9.83196 9 9.95466C9 10.0774 9.05076 10.1946 9.14023 10.2786L10.8524 12L9.14023 13.7214C9.05076 13.8054 9 13.9226 9 14.0453C9 14.168 9.05076 14.2853 9.14023 14.3693L9.63074 14.8598C9.71471 14.9492 9.83196 15 9.95466 15C10.0774 15 10.1946 14.9492 10.2786 14.8598L12 13.1476L13.7214 14.8598C13.8054 14.9492 13.9226 15 14.0453 15C14.168 15 14.2853 14.9492 14.3693 14.8598L14.8598 14.3693C14.9492 14.2853 15 14.168 15 14.0453Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" />
2
+ <path d="M12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12C22 9.34784 20.9464 6.8043 19.0711 4.92893C17.1957 3.05357 14.6522 2 12 2ZM14.4751 8.11137C14.6703 7.9161 14.9869 7.9161 15.1822 8.11137L15.8893 8.81847C16.0845 9.01373 16.0845 9.33032 15.8893 9.52558L13.4147 12.0002L15.8891 14.4746C16.0844 14.6698 16.0844 14.9864 15.8891 15.1817L15.182 15.8888C14.9868 16.084 14.6702 16.084 14.4749 15.8888L12.0005 13.4144L9.52531 15.8895C9.33005 16.0848 9.01347 16.0848 8.81821 15.8895L8.1111 15.1824C7.91584 14.9872 7.91584 14.6706 8.1111 14.4753L10.5863 12.0002L8.11095 9.52482C7.91569 9.32956 7.91569 9.01298 8.11095 8.81772L8.81806 8.11061C9.01332 7.91535 9.3299 7.91535 9.52516 8.11061L12.0005 10.5859L14.4751 8.11137Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" />
3
3
  </svg>
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
2
+ <path d="M8 19C9.10456 19 9.99999 19.8954 10 21C10 22.1046 9.10457 23 8 23C6.89543 23 6 22.1046 6 21C6.00001 19.8954 6.89544 19 8 19ZM18 19C19.1046 19 20 19.8954 20 21C20 22.1046 19.1046 23 18 23C16.8954 23 16 22.1046 16 21C16 19.8954 16.8954 19 18 19ZM3.41992 3C4.13729 2.99715 4.80147 3.37873 5.16016 4L9.44043 11.5C9.61797 11.8074 9.94484 11.9978 10.2998 12H16.5303C16.8454 11.9618 17.1239 11.7762 17.2803 11.5L19.6396 7.37012C19.8726 6.95086 19.9968 6.47963 20 6V5.5C20 5.22387 20.2239 5 20.5 5H21.5C21.7761 5 22 5.22387 22 5.5V6C21.9928 6.82988 21.7683 7.6438 21.3496 8.36035L19 12.4902C18.4915 13.404 17.5358 13.9789 16.4902 14H10.2598C10.0438 13.9953 9.82903 13.9653 9.62012 13.9102L8.62012 16H19.5C19.7761 16 20 16.2239 20 16.5V17.5C20 17.7761 19.7761 18 19.5 18H7C6.72633 18.0063 6.47048 17.8649 6.33008 17.6299L6.11035 17.25C5.99473 17.0275 5.99473 16.7626 6.11035 16.54L7.96973 12.8398C7.86831 12.7327 7.77807 12.6155 7.7002 12.4902L3.41992 5H2.5C2.22386 5 2 4.77614 2 4.5V3.5C2.00001 3.22387 2.22386 3 2.5 3H3.41992ZM15.6123 5.76172C16.899 5.76172 17.9424 6.8051 17.9424 8.0918C17.9424 9.37848 16.899 10.4219 15.6123 10.4219C14.3256 10.4218 13.2822 9.37844 13.2822 8.0918C13.2822 6.80515 14.3256 5.7618 15.6123 5.76172ZM17.0088 2.76172L10.0488 9.37988L9.30371 8.6709L16.2637 2.05176L17.0088 2.76172ZM15.6123 6.92676C14.9689 6.92676 14.4473 7.44845 14.4473 8.0918C14.4473 8.73515 14.9689 9.25684 15.6123 9.25684C16.2556 9.25678 16.7773 8.73511 16.7773 8.0918C16.7773 7.44849 16.2556 6.92681 15.6123 6.92676ZM10.6025 1.17676C11.8891 1.17689 12.9325 2.2203 12.9326 3.50684C12.9326 4.79345 11.8892 5.83679 10.6025 5.83691C9.3158 5.83691 8.27246 4.79353 8.27246 3.50684C8.27256 2.22022 9.31586 1.17676 10.6025 1.17676ZM10.6025 2.3418C9.95924 2.3418 9.43762 2.86359 9.4375 3.50684C9.4375 4.15018 9.95917 4.67188 10.6025 4.67188C11.2457 4.67161 11.7666 4.15002 11.7666 3.50684C11.7665 2.86375 11.2456 2.34206 10.6025 2.3418Z" fill="currentColor" />
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
2
+ <path d="M20 4H4C2.89543 4 2 4.89543 2 6V18C2 19.1046 2.89543 20 4 20H20C21.1046 20 22 19.1046 22 18V6C22 4.89543 21.1046 4 20 4ZM20 8V18H4V8H20ZM9.43982 15.8188L8.90982 15.2888C8.81314 15.1981 8.7583 15.0714 8.7583 14.9388C8.7583 14.8062 8.81314 14.6796 8.90982 14.5888L10.7598 12.7288L8.90982 10.8688C8.81314 10.7781 8.7583 10.6514 8.7583 10.5188C8.7583 10.3862 8.81314 10.2596 8.90982 10.1688L9.43982 9.63882C9.53055 9.54215 9.65723 9.4873 9.78982 9.4873C9.92241 9.4873 10.0491 9.54215 10.1398 9.63882L11.9998 11.4888L13.8598 9.63882C13.9506 9.54215 14.0772 9.4873 14.2098 9.4873C14.3424 9.4873 14.4691 9.54215 14.5598 9.63882L15.0898 10.1688C15.1865 10.2596 15.2413 10.3862 15.2413 10.5188C15.2413 10.6514 15.1865 10.7781 15.0898 10.8688L13.2398 12.7288L15.0898 14.5888C15.1865 14.6796 15.2413 14.8062 15.2413 14.9388C15.2413 15.0714 15.1865 15.1981 15.0898 15.2888L14.5598 15.8188C14.4691 15.9155 14.3424 15.9703 14.2098 15.9703C14.0772 15.9703 13.9506 15.9155 13.8598 15.8188L11.9998 13.9688L10.1398 15.8188C10.0491 15.9155 9.92241 15.9703 9.78982 15.9703C9.65723 15.9703 9.53055 15.9155 9.43982 15.8188Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" />
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
2
+ <path d="M20 4H4C2.89543 4 2 4.89543 2 6V18C2 19.1046 2.89543 20 4 20H20C21.1046 20 22 19.1046 22 18V6C22 4.89543 21.1046 4 20 4ZM20 8V18H4V8H20ZM12.4029 16.048L15.4029 13.048H15.3629C15.5456 12.8488 15.5412 12.5418 15.3529 12.348L12.3529 9.34799C12.2101 9.20793 11.9975 9.1665 11.8125 9.24267C11.6275 9.31884 11.5057 9.49795 11.5029 9.69799L11.5029 11.698L9.00293 11.698C8.72679 11.698 8.50293 11.9218 8.50293 12.198V13.198C8.50293 13.4741 8.72679 13.698 9.00293 13.698H11.5029V15.698C11.4785 15.9228 11.6081 16.136 11.8188 16.2179C12.0295 16.2999 12.269 16.2302 12.4029 16.048Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" />
3
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
2
+ <path d="M4.78626 8.53765C4.65386 8.81303 4.3818 9 4.07625 9H2.79862C2.62981 9 2.50962 8.83601 2.5657 8.67678C3.93563 4.78753 7.64241 2 12.0003 2C17.5231 2 22.0003 6.47715 22.0003 12C22.0003 17.5228 17.5231 22 12.0003 22C7.64241 22 3.93563 19.2125 2.56571 15.3232C2.50962 15.164 2.62981 15 2.79862 15H4.07625C4.3818 15 4.65386 15.187 4.78626 15.4623C6.07707 18.1469 8.82226 20 12.0003 20C16.4185 20 20.0003 16.4183 20.0003 12C20.0003 7.58172 16.4185 4 12.0003 4C8.82226 4 6.07707 5.85308 4.78626 8.53765Z" fill="currentColor" />
3
+ <path d="M11.6464 16.3536C11.4512 16.5488 11.1346 16.5488 10.9393 16.3536L7.29287 12.7071C6.90234 12.3166 6.90234 11.6834 7.29287 11.2929L10.9393 7.64645C11.1346 7.45118 11.4512 7.45118 11.6464 7.64645L12.3535 8.35355C12.5488 8.54882 12.5488 8.8654 12.3535 9.06066L10.4141 11.0001H15.5001C15.7762 11.0001 16.0001 11.2239 16.0001 11.5001V12.5001C16.0001 12.7762 15.7762 13.0001 15.5001 13.0001H10.4143L12.3535 14.9393C12.5488 15.1346 12.5488 15.4512 12.3535 15.6464L11.6464 16.3536Z" fill="currentColor" />
4
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
2
+ <path d="M6.375 9.5H2.625C2.27982 9.5 2 9.77982 2 10.125V13.875C2 14.2202 2.27982 14.5 2.625 14.5H6.375C6.72018 14.5 7 14.2202 7 13.875V10.125C7 9.77982 6.72018 9.5 6.375 9.5ZM13.875 9.5H10.125C9.77982 9.5 9.5 9.77982 9.5 10.125V13.875C9.5 14.2202 9.77982 14.5 10.125 14.5H13.875C14.2202 14.5 14.5 14.2202 14.5 13.875V10.125C14.5 9.77982 14.2202 9.5 13.875 9.5ZM17.625 9.5H21.375C21.7202 9.5 22 9.77982 22 10.125V13.875C22 14.2202 21.7202 14.5 21.375 14.5H17.625C17.2798 14.5 17 14.2202 17 13.875V10.125C17 9.77982 17.2798 9.5 17.625 9.5Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" />
3
+ </svg>
@@ -0,0 +1,23 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+ //#endregion
23
+ exports.__toESM = __toESM;
package/dist/build.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { extractSymbol, serializeSprite } from "./shared/sprite.js";
1
2
  import fs from "node:fs/promises";
2
3
  import path from "node:path";
3
4
  //#region tooling/build.ts
@@ -10,13 +11,6 @@ var hasOwn = (object, key) => Object.prototype.hasOwnProperty.call(object, key);
10
11
  var assertObject = (value, label) => {
11
12
  if (value === null || typeof value !== "object" || Array.isArray(value)) throw new TypeError(`${label} must be an object`);
12
13
  };
13
- var escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
14
- var serializeSprite = (symbols) => [
15
- "<svg xmlns=\"http://www.w3.org/2000/svg\">",
16
- symbols.join("\n"),
17
- "</svg>",
18
- ""
19
- ].join("\n");
20
14
  var selectionNames = (selection, group) => selection === "*" ? Object.keys(group.icons) : selection;
21
15
  var runtimeModule = ({ variant, groups }, spriteImport) => {
22
16
  return `const hasOwn = (object: object, key: PropertyKey): key is keyof typeof object => Object.prototype.hasOwnProperty.call(object, key)
@@ -92,12 +86,6 @@ var resolveSelection = (config, manifest) => {
92
86
  })
93
87
  }));
94
88
  };
95
- var extractSymbol = (sprite, symbolId, filename) => {
96
- const expression = new RegExp(`<symbol\\b[^>]*\\bid=(["'])${escapeRegExp(symbolId)}\\1[\\s\\S]*?<\\/symbol>`);
97
- const match = sprite.match(expression);
98
- if (!match) throw new Error(`Unable to find symbol ${symbolId} in ${filename}`);
99
- return match[0];
100
- };
101
89
  var loadIconSymbols = (resolvedVariants) => Promise.all(resolvedVariants.map(async (variant) => ({
102
90
  ...variant,
103
91
  groups: await Promise.all(variant.groups.map(async (group) => {
@@ -0,0 +1,26 @@
1
+ const require_extracted_bundler_plugin = require("./plugin.cjs");
2
+ let node_path = require("node:path");
3
+ let node_url = require("node:url");
4
+ //#region tooling/extracted/bundler/component-loader.ts
5
+ var omnicaIconComponentsLoader = function() {
6
+ const callback = this.async();
7
+ const { ssr = false } = this.getOptions();
8
+ const assetsPath = (0, node_path.resolve)(__dirname, "../../../assets/icons");
9
+ const assetPath = (0, node_path.relative)(assetsPath, this.resourcePath).split(node_path.sep).join("/");
10
+ this.cacheable(true);
11
+ if (assetPath.startsWith("../") || assetPath === "..") {
12
+ callback(/* @__PURE__ */ new Error(`Imported icon is outside ${assetsPath}: ${this.resourcePath}`));
13
+ return;
14
+ }
15
+ const source = `@omnicajs/icons/assets/icons/${assetPath}`;
16
+ import((0, node_url.pathToFileURL)((0, node_path.join)(__dirname, "../core.js")).href).then(async ({ createVueIconSfc, loadImportedIcon, loadManifest }) => {
17
+ const icon = await loadImportedIcon(source, await loadManifest());
18
+ if (!icon) throw new Error(`Unable to resolve imported icon ${source}`);
19
+ this.emitFile(require_extracted_bundler_plugin.importedSymbolAssetFilename(icon), require_extracted_bundler_plugin.createImportedSymbolAsset(icon));
20
+ callback(null, createVueIconSfc(icon, ssr ? JSON.stringify(require_extracted_bundler_plugin.importedSpriteMarker) : `__webpack_public_path__ + ${JSON.stringify(require_extracted_bundler_plugin.importedSpriteMarker)}`));
21
+ }).catch((error) => {
22
+ callback(error instanceof Error ? error : new Error(String(error)));
23
+ });
24
+ };
25
+ //#endregion
26
+ module.exports = omnicaIconComponentsLoader;
@@ -0,0 +1,3 @@
1
+ import type { LoaderDefinitionFunction } from 'webpack';
2
+ declare const omnicaIconComponentsLoader: LoaderDefinitionFunction;
3
+ export default omnicaIconComponentsLoader;
@@ -0,0 +1,125 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_runtime = require("../../_virtual/_rolldown/runtime.cjs");
3
+ const require_manifest = require("../manifest.cjs");
4
+ let node_path = require("node:path");
5
+ let node_url = require("node:url");
6
+ let node_crypto = require("node:crypto");
7
+ let node_fs_promises = require("node:fs/promises");
8
+ node_fs_promises = require_runtime.__toESM(node_fs_promises, 1);
9
+ //#region tooling/extracted/bundler/plugin.ts
10
+ var pluginName = "OmnicaIconComponentsPlugin";
11
+ var temporaryAssetPrefix = "__omnica_icons_imported__/";
12
+ var importedSpriteMarker = "__OMNICA_IMPORTED_SPRITE_URL__";
13
+ var targetsNode = (compiler) => {
14
+ const target = compiler.options.target;
15
+ return (Array.isArray(target) ? target : [target]).some((candidate) => typeof candidate === "string" && candidate.startsWith("node")) || compiler.options.externalsPresets?.node === true;
16
+ };
17
+ var assertRootRelativePublicPath = (publicPath) => {
18
+ if (typeof publicPath !== "string" || !publicPath.startsWith("/") || publicPath.startsWith("//") || !publicPath.endsWith("/")) throw new Error(`Import-driven icon builds require output.publicPath to be root-relative and end in "/". Absolute, protocol-relative, automatic, and relative public paths are not supported. Received ${typeof publicPath === "string" ? JSON.stringify(publicPath) : typeof publicPath}.`);
19
+ return publicPath;
20
+ };
21
+ var renderContentHashFilename = (template, source) => {
22
+ const hash = (0, node_crypto.createHash)("sha256").update(source).digest("hex");
23
+ return template.replace(/\[contenthash(?::(\d+))?\]/g, (_match, length) => length ? hash.slice(0, Number(length)) : hash);
24
+ };
25
+ var createImportedSymbolAsset = (symbol) => JSON.stringify({
26
+ schemaVersion: 1,
27
+ importedSymbol: symbol.importedSymbol,
28
+ symbolSource: symbol.symbolSource
29
+ });
30
+ var importedSymbolAssetFilename = (symbol) => {
31
+ return `${temporaryAssetPrefix}${(0, node_crypto.createHash)("sha256").update(symbol.importedSymbol).digest("hex")}.json`;
32
+ };
33
+ var parseImportedSymbolAsset = (source, filename) => {
34
+ const parsed = JSON.parse(source);
35
+ if (parsed.schemaVersion !== 1 || typeof parsed.importedSymbol !== "string" || typeof parsed.symbolSource !== "string") throw new Error(`Invalid imported icon metadata in ${filename}`);
36
+ return parsed;
37
+ };
38
+ var replaceSpriteMarker = (compiler, compilation, filename) => {
39
+ const { ReplaceSource } = compiler.webpack.sources;
40
+ for (const asset of compilation.getAssets()) {
41
+ const source = asset.source.source().toString();
42
+ if (!source.includes("__OMNICA_IMPORTED_SPRITE_URL__")) continue;
43
+ const replaced = new ReplaceSource(asset.source, asset.name);
44
+ let position = source.indexOf(importedSpriteMarker);
45
+ while (position !== -1) {
46
+ replaced.replace(position, position + 30 - 1, filename);
47
+ position = source.indexOf(importedSpriteMarker, position + 30);
48
+ }
49
+ compilation.updateAsset(asset.name, replaced);
50
+ }
51
+ };
52
+ var BundlerIconComponentsPlugin = class {
53
+ #options;
54
+ constructor(options = {}) {
55
+ this.#options = options;
56
+ }
57
+ apply(compiler) {
58
+ const loaderPath = (0, node_path.join)(__dirname, "component-loader.cjs");
59
+ const templateAssetsLoaderPath = (0, node_path.join)(__dirname, "template-assets-loader.cjs");
60
+ const assetsPath = (0, node_path.resolve)(__dirname, "../../../assets/icons");
61
+ const clientOutputDirectory = (0, node_path.resolve)(compiler.context, this.#options.clientOutputDirectory ?? "dist");
62
+ const ssr = this.#options.ssr ?? targetsNode(compiler);
63
+ const publicPath = assertRootRelativePublicPath(compiler.options.output.publicPath);
64
+ const vueLoader = {
65
+ loader: this.#options.vueLoader ?? "vue-loader",
66
+ options: { experimentalInlineMatchResource: true }
67
+ };
68
+ compiler.options.module.rules.push({
69
+ dependency: { not: ["url"] },
70
+ include: assetsPath,
71
+ issuer: /\.(?:[cm]?[jt]sx?|vue)$/,
72
+ resourceQuery: /^(?:$|\?vue&type=(?:script|template)\b)/,
73
+ test: /\.svg$/,
74
+ type: "javascript/auto",
75
+ use: [vueLoader, {
76
+ loader: loaderPath,
77
+ options: { ssr }
78
+ }]
79
+ });
80
+ compiler.options.module.rules.push({
81
+ enforce: "post",
82
+ resourceQuery: /\bvue&type=(?:script|template)\b/,
83
+ test: /\.vue$/,
84
+ use: [{ loader: templateAssetsLoaderPath }]
85
+ });
86
+ compiler.hooks.thisCompilation.tap(pluginName, (compilation) => {
87
+ compilation.hooks.processAssets.tapPromise({
88
+ name: pluginName,
89
+ stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_INLINE
90
+ }, async () => {
91
+ const temporaryAssets = compilation.getAssets().filter((asset) => asset.name.startsWith(temporaryAssetPrefix));
92
+ if (temporaryAssets.length === 0) return;
93
+ const symbols = temporaryAssets.map((asset) => parseImportedSymbolAsset(asset.source.source().toString(), asset.name));
94
+ for (const asset of temporaryAssets) compilation.deleteAsset(asset.name);
95
+ let filename;
96
+ if (ssr) {
97
+ const manifestPath = (0, node_path.join)(clientOutputDirectory, require_manifest.importedSpriteManifestFilename);
98
+ let clientManifest;
99
+ try {
100
+ clientManifest = require_manifest.parseImportedSpriteManifest(await node_fs_promises.default.readFile(manifestPath, "utf8"), manifestPath);
101
+ } catch (error) {
102
+ const detail = error instanceof Error ? ` ${error.message}` : "";
103
+ throw new Error(`Unable to load the import-driven icon client manifest at ${manifestPath}. Build the client before SSR or configure clientOutputDirectory.${detail}`);
104
+ }
105
+ require_manifest.assertImportedSymbolsAvailable(clientManifest, symbols);
106
+ filename = clientManifest.spriteUrl;
107
+ } else {
108
+ const { createImportedSprite } = await import((0, node_url.pathToFileURL)((0, node_path.join)(__dirname, "../core.js")).href);
109
+ const spriteSource = createImportedSprite(symbols);
110
+ const filenameTemplate = this.#options.filename ?? "assets/omnica-icons-imported.[contenthash:8].svg";
111
+ filename = renderContentHashFilename(filenameTemplate, spriteSource);
112
+ compilation.emitAsset(filename, new compiler.webpack.sources.RawSource(spriteSource), { immutable: /\[contenthash(?::\d+)?\]/.test(filenameTemplate) });
113
+ compilation.emitAsset(require_manifest.importedSpriteManifestFilename, new compiler.webpack.sources.RawSource(require_manifest.createImportedSpriteManifest(filename, `${publicPath}${filename}`, symbols)));
114
+ }
115
+ replaceSpriteMarker(compiler, compilation, filename);
116
+ });
117
+ });
118
+ }
119
+ };
120
+ //#endregion
121
+ exports.BundlerIconComponentsPlugin = BundlerIconComponentsPlugin;
122
+ exports.createImportedSymbolAsset = createImportedSymbolAsset;
123
+ exports.importedSpriteMarker = importedSpriteMarker;
124
+ exports.importedSymbolAssetFilename = importedSymbolAssetFilename;
125
+ exports.renderContentHashFilename = renderContentHashFilename;
@@ -0,0 +1,21 @@
1
+ import type { Compiler } from 'webpack';
2
+ import type { ImportedSymbol } from '../core.js';
3
+ export interface BundlerIconComponentsOptions {
4
+ /** Supports `[contenthash]` and `[contenthash:N]`. */
5
+ readonly filename?: string;
6
+ /** Overrides the loader used to compile the generated Vue SFC. */
7
+ readonly vueLoader?: string;
8
+ /** Client build output read by a later SSR build. Defaults to `<context>/dist`. */
9
+ readonly clientOutputDirectory?: string;
10
+ /** Overrides automatic Node-target SSR detection. */
11
+ readonly ssr?: boolean;
12
+ }
13
+ export declare const importedSpriteMarker = "__OMNICA_IMPORTED_SPRITE_URL__";
14
+ export declare const renderContentHashFilename: (template: string, source: string) => string;
15
+ export declare const createImportedSymbolAsset: (symbol: ImportedSymbol) => string;
16
+ export declare const importedSymbolAssetFilename: (symbol: ImportedSymbol) => string;
17
+ export declare class BundlerIconComponentsPlugin {
18
+ #private;
19
+ constructor(options?: BundlerIconComponentsOptions);
20
+ apply(compiler: Compiler): void;
21
+ }
@@ -0,0 +1,8 @@
1
+ //#region tooling/extracted/bundler/template-assets-loader.ts
2
+ var vueTemplateAssetImport = /(\bimport\s+_imports_\d+\s+from\s+)(["'])(@omnicajs\/icons\/assets\/icons\/(?:filled|outlined)\/[^"'?#]+\.svg)\2/g;
3
+ var bundlerTemplateAssetsLoader = function(source, sourceMap) {
4
+ const transformed = source.replace(vueTemplateAssetImport, (_match, prefix, quote, request) => `${prefix}${quote}${request}?url${quote}`);
5
+ this.callback(null, transformed, sourceMap);
6
+ };
7
+ //#endregion
8
+ module.exports = bundlerTemplateAssetsLoader;
@@ -0,0 +1,3 @@
1
+ import type { LoaderDefinitionFunction } from 'webpack';
2
+ declare const bundlerTemplateAssetsLoader: LoaderDefinitionFunction;
3
+ export default bundlerTemplateAssetsLoader;
@@ -0,0 +1,14 @@
1
+ import type { IconManifest, ManifestIcon } from '../build.js';
2
+ export { loadManifest } from '../build.js';
3
+ export interface ImportedIcon extends ManifestIcon {
4
+ readonly variant: 'filled' | 'outlined';
5
+ readonly group: string;
6
+ readonly name: string;
7
+ readonly importedSymbol: string;
8
+ readonly symbolSource: string;
9
+ }
10
+ export type ImportedSymbol = Pick<ImportedIcon, 'importedSymbol' | 'symbolSource'>;
11
+ export declare const resolveImportedIcon: (source: string, manifest: IconManifest) => Omit<ImportedIcon, "symbolSource"> | null;
12
+ export declare const loadImportedIcon: (source: string, manifest: IconManifest) => Promise<ImportedIcon | null>;
13
+ export declare const createImportedSprite: (icons: readonly ImportedSymbol[]) => string;
14
+ export declare const createVueIconSfc: (icon: ImportedIcon, spriteExpression: string) => string;
@@ -0,0 +1,64 @@
1
+ import { serializeSprite } from "../shared/sprite.js";
2
+ import { loadIconSymbols, loadManifest } from "../build.js";
3
+ //#region tooling/extracted/core.ts
4
+ var importedAssetExpression = /^@omnicajs\/icons\/(assets\/icons\/(filled|outlined)\/([^/]+)\/([^/]+)\.svg)$/;
5
+ var importedSymbolId = (variant, group, name) => `${variant}/${group}/${name}`;
6
+ var resolveImportedIcon = (source, manifest) => {
7
+ if (source.includes("?") || source.includes("#")) return null;
8
+ const match = source.match(importedAssetExpression);
9
+ if (!match) return null;
10
+ const [, assetPath, variant, group, name] = match;
11
+ const icon = manifest.variants[variant]?.groups[group]?.icons[name];
12
+ if (!icon || icon.source !== assetPath) throw new Error(`Unknown imported icon ${variant}/${group}/${name}`);
13
+ return {
14
+ ...icon,
15
+ variant,
16
+ group,
17
+ name,
18
+ importedSymbol: importedSymbolId(variant, group, name)
19
+ };
20
+ };
21
+ var loadImportedIcon = async (source, manifest) => {
22
+ const icon = resolveImportedIcon(source, manifest);
23
+ if (!icon) return null;
24
+ const symbolSource = (await loadIconSymbols([{
25
+ variant: icon.variant,
26
+ groups: [{
27
+ name: icon.group,
28
+ sprite: manifest.variants[icon.variant].groups[icon.group].sprite,
29
+ icons: [{
30
+ name: icon.name,
31
+ source: icon.source,
32
+ symbol: icon.symbol,
33
+ viewBox: icon.viewBox,
34
+ keywords: icon.keywords
35
+ }]
36
+ }]
37
+ }]))[0]?.groups[0]?.icons[0]?.symbolSource;
38
+ if (!symbolSource) throw new Error(`Missing symbol source for ${icon.importedSymbol}`);
39
+ return {
40
+ ...icon,
41
+ symbolSource
42
+ };
43
+ };
44
+ var createImportedSprite = (icons) => {
45
+ return serializeSprite([...new Map(icons.map((icon) => [icon.importedSymbol, icon])).values()].sort((left, right) => left.importedSymbol.localeCompare(right.importedSymbol)).map((icon) => icon.symbolSource.replace(/(<symbol\b[^>]*\bid=)(["'])([^"']+)\2/, (_match, prefix, quote) => `${prefix}${quote}${icon.importedSymbol}${quote}`)));
46
+ };
47
+ var componentName = (icon) => `Omnica-${icon.variant}-${icon.group}-${icon.name}-icon`.split(/[^A-Za-z0-9]+/).filter(Boolean).map((part) => `${part[0].toUpperCase()}${part.slice(1)}`).join("");
48
+ var createVueIconSfc = (icon, spriteExpression) => `<template>
49
+ <svg viewBox="${icon.viewBox}">
50
+ <use :href="href" />
51
+ </svg>
52
+ </template>
53
+
54
+ <script>
55
+ const href = ${spriteExpression} + ${JSON.stringify(`#${icon.importedSymbol}`)}
56
+
57
+ export default {
58
+ name: ${JSON.stringify(componentName(icon))},
59
+ data: () => ({ href }),
60
+ }
61
+ <\/script>
62
+ `;
63
+ //#endregion
64
+ export { createImportedSprite, createVueIconSfc, loadImportedIcon, loadManifest, resolveImportedIcon };
@@ -0,0 +1,23 @@
1
+ //#region tooling/extracted/manifest.ts
2
+ var importedSpriteManifestFilename = ".omnica/omnica-icons-imported.json";
3
+ var createImportedSpriteManifest = (spriteFilename, spriteUrl, icons) => `${JSON.stringify({
4
+ schemaVersion: 1,
5
+ spriteFilename,
6
+ spriteUrl,
7
+ symbols: [...new Set(icons.map((icon) => icon.importedSymbol))].sort()
8
+ }, null, 2)}\n`;
9
+ var parseImportedSpriteManifest = (source, filename) => {
10
+ const parsed = JSON.parse(source);
11
+ if (parsed.schemaVersion !== 1 || typeof parsed.spriteFilename !== "string" || parsed.spriteFilename.length === 0 || typeof parsed.spriteUrl !== "string" || !parsed.spriteUrl.startsWith("/") || parsed.spriteUrl.startsWith("//") || !Array.isArray(parsed.symbols) || parsed.symbols.some((symbol) => typeof symbol !== "string") || new Set(parsed.symbols).size !== parsed.symbols.length) throw new Error(`Invalid import-driven icon manifest in ${filename}`);
12
+ return parsed;
13
+ };
14
+ var assertImportedSymbolsAvailable = (manifest, icons) => {
15
+ const clientSymbols = new Set(manifest.symbols);
16
+ const missing = [...new Set(icons.map((icon) => icon.importedSymbol).filter((symbol) => !clientSymbols.has(symbol)))].sort();
17
+ if (missing.length > 0) throw new Error(`SSR imports icons missing from the client sprite: ${missing.join(", ")}. Build the client first and ensure its icon graph contains every server-rendered icon.`);
18
+ };
19
+ //#endregion
20
+ exports.assertImportedSymbolsAvailable = assertImportedSymbolsAvailable;
21
+ exports.createImportedSpriteManifest = createImportedSpriteManifest;
22
+ exports.importedSpriteManifestFilename = importedSpriteManifestFilename;
23
+ exports.parseImportedSpriteManifest = parseImportedSpriteManifest;
@@ -0,0 +1,11 @@
1
+ import type { ImportedSymbol } from './core.js';
2
+ export interface ImportedSpriteManifest {
3
+ readonly schemaVersion: 1;
4
+ readonly spriteFilename: string;
5
+ readonly spriteUrl: string;
6
+ readonly symbols: readonly string[];
7
+ }
8
+ export declare const importedSpriteManifestFilename = ".omnica/omnica-icons-imported.json";
9
+ export declare const createImportedSpriteManifest: (spriteFilename: string, spriteUrl: string, icons: readonly ImportedSymbol[]) => string;
10
+ export declare const parseImportedSpriteManifest: (source: string, filename: string) => ImportedSpriteManifest;
11
+ export declare const assertImportedSymbolsAvailable: (manifest: ImportedSpriteManifest, icons: readonly ImportedSymbol[]) => void;
@@ -0,0 +1,20 @@
1
+ //#region tooling/extracted/manifest.ts
2
+ var importedSpriteManifestFilename = ".omnica/omnica-icons-imported.json";
3
+ var createImportedSpriteManifest = (spriteFilename, spriteUrl, icons) => `${JSON.stringify({
4
+ schemaVersion: 1,
5
+ spriteFilename,
6
+ spriteUrl,
7
+ symbols: [...new Set(icons.map((icon) => icon.importedSymbol))].sort()
8
+ }, null, 2)}\n`;
9
+ var parseImportedSpriteManifest = (source, filename) => {
10
+ const parsed = JSON.parse(source);
11
+ if (parsed.schemaVersion !== 1 || typeof parsed.spriteFilename !== "string" || parsed.spriteFilename.length === 0 || typeof parsed.spriteUrl !== "string" || !parsed.spriteUrl.startsWith("/") || parsed.spriteUrl.startsWith("//") || !Array.isArray(parsed.symbols) || parsed.symbols.some((symbol) => typeof symbol !== "string") || new Set(parsed.symbols).size !== parsed.symbols.length) throw new Error(`Invalid import-driven icon manifest in ${filename}`);
12
+ return parsed;
13
+ };
14
+ var assertImportedSymbolsAvailable = (manifest, icons) => {
15
+ const clientSymbols = new Set(manifest.symbols);
16
+ const missing = [...new Set(icons.map((icon) => icon.importedSymbol).filter((symbol) => !clientSymbols.has(symbol)))].sort();
17
+ if (missing.length > 0) throw new Error(`SSR imports icons missing from the client sprite: ${missing.join(", ")}. Build the client first and ensure its icon graph contains every server-rendered icon.`);
18
+ };
19
+ //#endregion
20
+ export { assertImportedSymbolsAvailable, createImportedSpriteManifest, importedSpriteManifestFilename, parseImportedSpriteManifest };
@@ -0,0 +1,8 @@
1
+ import type { Plugin } from 'vite';
2
+ export interface OmnicaIconComponentsOptions {
3
+ /** Asset name before Vite adds its content hash. */
4
+ readonly spriteName?: string;
5
+ /** Client build output read by a later SSR build. Defaults to `<root>/dist`. */
6
+ readonly clientOutputDirectory?: string;
7
+ }
8
+ export declare const omnicaIconComponents: (options?: OmnicaIconComponentsOptions) => Plugin;