@onedarnleyroad/vite-plugin-svg-sprite 2.0.0 → 2.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.
Files changed (3) hide show
  1. package/README.md +16 -12
  2. package/package.json +2 -2
  3. package/src/index.js +9 -5
package/README.md CHANGED
@@ -112,28 +112,32 @@ With Craft CMS + [nystudio107/craft-vite](https://nystudio107.com/docs/vite/):
112
112
 
113
113
  #### A reusable, accessible macro
114
114
 
115
- Rather than hand-writing the `<svg><use>` wrapper each time, wrap it in a Twig macro. Pass `folder:` for a subfolder spriteit maps to the `sprite-{folder}.svg` manifest key for you, so templates keep the folder mental model. Icons default to decorative (`aria-hidden="true"`), and switch to a labelled `role="img"` when the icon carries meaning on its own:
115
+ Rather than hand-writing the `<svg><use>` wrapper each time, wrap it in a Twig macro. The two things you set most often the icon **name** and its **classes** are positional; the rest (subfolder, accessible label, extra attributes) goes in an `options` hash. Icons default to decorative (`aria-hidden="true"`), and switch to a labelled `role="img"` when the icon carries meaning on its own:
116
116
 
117
117
  ```twig
118
- {% macro icon(name, folder = null, label = null, prefix = 'sprite', class = 'icon', extra = {}) %}
119
- {% set key = folder ? "#{prefix}-#{folder}.svg" : "#{prefix}.svg" %}
120
- {% set a11y = label
118
+ {% macro icon(name, classList = '', options = {}) %}
119
+ {% set folder = options.folder ?? null %}
120
+ {% set label = options.label ?? null %}
121
+ {% set file = folder ? "sprite-#{folder}.svg" : 'sprite.svg' %}
122
+ {% set a11y = label
121
123
  ? { role: 'img', 'aria-label': label }
122
124
  : { 'aria-hidden': 'true', focusable: 'false' } %}
123
- <svg{{ attr({ class: class }|merge(a11y)|merge(extra)) }}>
124
- <use href="{{ craft.vite.entry(key) }}#svg-{{ name }}"></use>
125
+ <svg{{ attr({ class: classList }|merge(a11y)|merge(options.attrs ?? {})) }}>
126
+ <use href="{{ craft.vite.entry(file) }}#svg-{{ name }}"></use>
125
127
  </svg>
126
128
  {% endmacro %}
127
129
  ```
128
130
 
129
131
  ```twig
130
- {{ icon('arrow') }} {# root sprite → entry('sprite.svg') #}
131
- {{ icon('sun', folder: 'light') }} {# subfolder → entry('sprite-light.svg') #}
132
- {{ icon('search', label: 'Search') }} {# meaningful → role="img" + aria-label #}
133
- <button aria-label="Close">{{ icon('x') }}</button> {# icon-only control: label the button #}
132
+ {{ icon('arrow', 'icon') }} {# root sprite → entry('sprite.svg') #}
133
+ {{ icon('sun', 'icon', { folder: 'light' }) }} {# subfolder → entry('sprite-light.svg') #}
134
+ {{ icon('search', 'icon', { label: 'Search' }) }} {# meaningful → role="img" + aria-label #}
135
+ <button aria-label="Close">{{ icon('x', 'icon') }}</button> {# icon-only control: label the button #}
134
136
  ```
135
137
 
136
- Reach for `aria-hidden="true"` only when the icon is decorative — i.e. sitting next to visible text. A standalone, meaning-bearing icon needs an accessible name (via `label`, or on the enclosing control such as a button), or it's invisible to assistive tech. (`attr()` is Craft's built-in attribute renderer.)
138
+ Reach for `aria-hidden="true"` only when the icon is decorative — i.e. sitting next to visible text. A standalone, meaning-bearing icon needs an accessible name (via `options.label`, or on the enclosing control such as a button), or it's invisible to assistive tech. (`'icon'` is a CSS class you define to size the `<svg>` — sprite symbols have no intrinsic dimensions; the walkthrough below covers sizing and colour. `attr()` is Craft's built-in attribute renderer.)
139
+
140
+ > **Full Craft CMS walkthrough:** [SVG icon sprites in Craft CMS with Vite](https://github.com/onedarnleyroad/craftcms/wiki/SVG-icon-sprites-in-Craft-CMS-with-Vite) — end-to-end setup, the macro, sizing & colour gotchas, and sprites vs. inlining.
137
141
 
138
142
  ## Development workflow
139
143
 
@@ -182,7 +186,7 @@ If you want runtime/HMR injection or a virtual import, one of the others will su
182
186
 
183
187
  ## FAQ
184
188
 
185
- **Does it work with Craft CMS?** Yes — it's the primary target. With [nystudio107's Craft Vite plugin](https://nystudio107.com/docs/vite/), reference a sprite with `craft.vite.entry('sprite.svg')` (see [Using the sprite](#using-the-sprite)).
189
+ **Does it work with Craft CMS?** Yes — it's the primary target. With [nystudio107's Craft Vite plugin](https://nystudio107.com/docs/vite/), reference a sprite with `craft.vite.entry('sprite.svg')` see [Using the sprite](#using-the-sprite), or the full [Craft + Vite walkthrough](https://github.com/onedarnleyroad/craftcms/wiki/SVG-icon-sprites-in-Craft-CMS-with-Vite).
186
190
 
187
191
  **How do I reference an icon in a Twig template?** Use `<use href="{{ craft.vite.entry('sprite.svg') }}#svg-{name}">`, or the reusable [`icon()` macro](#a-reusable-accessible-macro).
188
192
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onedarnleyroad/vite-plugin-svg-sprite",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Vite plugin that builds an SVG sprite sheet from a directory of SVG files",
5
5
  "type": "module",
6
6
  "exports": {
@@ -34,6 +34,6 @@
34
34
  "access": "public"
35
35
  },
36
36
  "peerDependencies": {
37
- "vite": ">=4.0.0"
37
+ "vite": ">=3.0.0"
38
38
  }
39
39
  }
package/src/index.js CHANGED
@@ -142,11 +142,15 @@ export default function svgSpritePlugin(options = {}) {
142
142
  writeBundle(outputOptions) {
143
143
  if (!viteConfig?.build?.manifest) return
144
144
 
145
- const manifestName = typeof viteConfig.build.manifest === 'string'
146
- ? viteConfig.build.manifest
147
- : '.vite/manifest.json'
148
- const manifestPath = resolve(outputOptions.dir, manifestName)
149
- if (!existsSync(manifestPath)) return
145
+ // Vite 5+ writes the default manifest to .vite/manifest.json; Vite 3/4 write
146
+ // manifest.json at the outDir root. Try both when no custom path is configured.
147
+ const manifestNames = typeof viteConfig.build.manifest === 'string'
148
+ ? [viteConfig.build.manifest]
149
+ : ['.vite/manifest.json', 'manifest.json']
150
+ const manifestPath = manifestNames
151
+ .map(name => resolve(outputOptions.dir, name))
152
+ .find(path => existsSync(path))
153
+ if (!manifestPath) return
150
154
 
151
155
  const manifest = JSON.parse(readFileSync(manifestPath, 'utf-8'))
152
156