mirror of
https://github.com/gromlab-ru/svg-sprites.git
synced 2026-07-22 12:40:21 +03:00
Compare commits
38 Commits
fix/releas
...
v2.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e9ae91815a | ||
| 92a3cce7f1 | |||
|
|
f289e7c4b8 | ||
| b43814e57b | |||
| 8b3365f957 | |||
| e54ab4991c | |||
| 44afec7cdb | |||
| ab7042001a | |||
| 1280eb6fcd | |||
| c596f9f1c3 | |||
| 3dd385bfda | |||
| 632b450c8b | |||
| 7992adc9d3 | |||
| f4f464a568 | |||
|
|
bc4bece3c5 | ||
| c47fbdad8c | |||
|
|
06fef6bd96 | ||
| 00fa6cea28 | |||
|
|
b9451c8ff3 | ||
| 1b6a5cb90c | |||
|
|
cb40d4eb04 | ||
| 873704abd6 | |||
| 3f6b186a5b | |||
|
|
c7e6a27236 | ||
| b4869deb97 | |||
|
|
07d57e3838 | ||
| 1b5b446d8f | |||
|
|
b3a3a8347a | ||
| b72a113955 | |||
|
|
838cb7cfff | ||
| 4833b31516 | |||
|
|
38068d7c9f | ||
| 82bc9e7d77 | |||
|
|
b6c4561c28 | ||
| 03858aa1f4 | |||
|
|
9439682235 | ||
| df096126a7 | |||
|
|
4b47df9898 |
33
.github/workflows/ci.yml
vendored
33
.github/workflows/ci.yml
vendored
@@ -40,3 +40,36 @@ jobs:
|
|||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: npm run build
|
run: npm run build
|
||||||
|
|
||||||
|
integration:
|
||||||
|
name: Integration playground
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 60
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 24
|
||||||
|
cache: npm
|
||||||
|
cache-dependency-path: |
|
||||||
|
package-lock.json
|
||||||
|
integration/package-lock.json
|
||||||
|
|
||||||
|
- name: Install package dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Build package
|
||||||
|
run: npm run build:package
|
||||||
|
|
||||||
|
- name: Install playground dependencies
|
||||||
|
run: npm ci --prefix integration
|
||||||
|
|
||||||
|
- name: Install Chromium
|
||||||
|
run: npm exec --prefix integration -- playwright install --with-deps chromium
|
||||||
|
|
||||||
|
- name: Verify playground
|
||||||
|
run: npm run verify --prefix integration
|
||||||
|
|||||||
9
.github/workflows/release.yml
vendored
9
.github/workflows/release.yml
vendored
@@ -28,15 +28,16 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout release tag
|
- name: Checkout release tag
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v6
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.release.tag_name || inputs.tag }}
|
ref: ${{ github.event.release.tag_name || inputs.tag }}
|
||||||
|
|
||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v6
|
||||||
with:
|
with:
|
||||||
node-version: 24
|
node-version: 24
|
||||||
cache: npm
|
registry-url: https://registry.npmjs.org
|
||||||
|
package-manager-cache: false
|
||||||
|
|
||||||
- name: Update npm
|
- name: Update npm
|
||||||
run: npm install --global npm@latest
|
run: npm install --global npm@latest
|
||||||
@@ -111,4 +112,4 @@ jobs:
|
|||||||
DIST_TAG=next
|
DIST_TAG=next
|
||||||
fi
|
fi
|
||||||
|
|
||||||
npm publish ./release/*.tgz --access public --provenance --tag "$DIST_TAG"
|
npm publish --ignore-scripts --access public --tag "$DIST_TAG"
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -2,7 +2,10 @@ node_modules/
|
|||||||
dist/
|
dist/
|
||||||
public/
|
public/
|
||||||
test/public/
|
test/public/
|
||||||
|
test/.next-fixture-*/
|
||||||
|
test-results/
|
||||||
.tmp/
|
.tmp/
|
||||||
|
skills/artifacts/
|
||||||
*.generated.ts
|
*.generated.ts
|
||||||
*.tgz
|
*.tgz
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|||||||
121
AGENTS.md
Normal file
121
AGENTS.md
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
# Архитектурные правила
|
||||||
|
|
||||||
|
## Изоляция modes
|
||||||
|
|
||||||
|
Каждый полный mode key является независимым adapter со своим generated-контрактом:
|
||||||
|
|
||||||
|
- `react@vite`;
|
||||||
|
- `react@webpack`;
|
||||||
|
- `next@app/turbopack`;
|
||||||
|
- `next@app/webpack`;
|
||||||
|
- `next@pages/turbopack`;
|
||||||
|
- `next@pages/webpack`;
|
||||||
|
- `standalone`;
|
||||||
|
- `standalone@vite`;
|
||||||
|
- `standalone@webpack`;
|
||||||
|
- `vue@vite`;
|
||||||
|
- `vue@webpack`;
|
||||||
|
- `nuxt@vite`;
|
||||||
|
- `nuxt@webpack`;
|
||||||
|
- `svelte@vite`;
|
||||||
|
- `svelte@webpack`;
|
||||||
|
- `sveltekit@vite`;
|
||||||
|
- `angular@application`;
|
||||||
|
- `angular@webpack`;
|
||||||
|
- `astro@vite`;
|
||||||
|
- `solid@vite`;
|
||||||
|
- `solid@webpack`;
|
||||||
|
- `solid-start@vite`;
|
||||||
|
- `preact@vite`;
|
||||||
|
- `preact@webpack`;
|
||||||
|
- `qwik@vite`;
|
||||||
|
- `lit@vite`;
|
||||||
|
- `lit@webpack`;
|
||||||
|
- `alpine@vite`;
|
||||||
|
- `alpine@webpack`;
|
||||||
|
- будущие exact modes.
|
||||||
|
|
||||||
|
Для каждого exact mode используется отдельный каталог `src/modes/<mode-slug>/`. Adapter самостоятельно определяет:
|
||||||
|
|
||||||
|
- compile options;
|
||||||
|
- список и имена generated-файлов;
|
||||||
|
- runtime JavaScript;
|
||||||
|
- TypeScript declarations;
|
||||||
|
- manifest source;
|
||||||
|
- CSS;
|
||||||
|
- способ получения asset URL;
|
||||||
|
- mode-specific result metadata.
|
||||||
|
|
||||||
|
Изменение output одного mode не должно менять output другого mode. Дублирование component, manifest, declaration и CSS codegen между adapters является сознательной ценой изоляции.
|
||||||
|
|
||||||
|
Запрещено:
|
||||||
|
|
||||||
|
- импортировать один `src/modes/<exact>/` из другого mode;
|
||||||
|
- создавать общий framework/component/manifest/CSS codegen для нескольких modes;
|
||||||
|
- создавать общий runtime asset URL generator для нескольких modes;
|
||||||
|
- ветвиться по generic target внутри adapter;
|
||||||
|
- писать generated-файлы непосредственно из adapter через `fs`;
|
||||||
|
- импортировать exact-mode adapters из core.
|
||||||
|
|
||||||
|
Единственное место, которое импортирует все adapters, — `src/mode-registry.ts`.
|
||||||
|
|
||||||
|
## Общий core
|
||||||
|
|
||||||
|
Общими могут быть только mode-neutral данные и инфраструктура:
|
||||||
|
|
||||||
|
- загрузка, merge и валидация config;
|
||||||
|
- scanner исходных SVG;
|
||||||
|
- shape IDs и проверка конфликтов;
|
||||||
|
- низкоуровневый SVG compiler и transformations;
|
||||||
|
- подготовка нейтрального compiled artifact;
|
||||||
|
- protocol `ModeAdapter`/`OutputPlan`;
|
||||||
|
- проверка output paths;
|
||||||
|
- staged directory writer и symlink protection;
|
||||||
|
- logger и базовые result types.
|
||||||
|
|
||||||
|
Core не генерирует JavaScript, declarations, manifest source, CSS или framework-specific exports. Изменение общего compiler может ожидаемо изменить SVG всех modes; изменение generated source должно быть локально одному adapter.
|
||||||
|
|
||||||
|
## Generated-контракт
|
||||||
|
|
||||||
|
Один config разрешается ровно в один mode и один output. Множественные modes не генерируются в один root; orchestration выполняется независимыми config/API/CLI вызовами.
|
||||||
|
|
||||||
|
Каждый adapter генерирует один нативный для фреймворка runtime-контракт, совместимый со стандартными JavaScript- и TypeScript-конфигурациями этого фреймворка. Предпочтительный output — ESM JavaScript; если framework compiler требует собственный формат, допускаются framework-native контейнеры с JavaScript-синтаксисом (`.jsx`, `.svelte`, `.astro` и аналогичные). `.tsx` и TypeScript runtime запрещены, кроме frameworks вроде Angular, чей штатный production toolchain требует TypeScript. Типизация всегда добавляется отдельными `.d.ts`; отдельные JS- и TS-реализации одного компонента не создаются.
|
||||||
|
|
||||||
|
Integration-стенд должен собирать runtime как JavaScript-потребитель без дополнительной TypeScript-настройки, когда framework это допускает. TypeScript-совместимость того же generated API проверяется отдельным type probe внутри стенда. Framework-native adapter нельзя подменять consumer-примером другого mode или Web Component facade.
|
||||||
|
|
||||||
|
Core writer полностью владеет каталогом `.svg-sprite` и при каждой генерации заменяет его через временный каталог с rollback при ошибке. Корневым `.gitignore` writer владеет, когда exact-mode adapter запрашивает его через `OutputPlan`. Bare `standalone` не создаёт `.gitignore`; остальные modes создают.
|
||||||
|
|
||||||
|
Sprite-level asset, icon data, manifest и facade лежат непосредственно в `.svg-sprite/`. `standalone@vite` и `standalone@webpack` генерируют нативный icon Web Component внутри своего facade; bare `standalone` остаётся без JavaScript runtime. Framework runtime группируется отдельно: React adapters используют `.svg-sprite/react/`, будущие framework adapters получают собственный framework-каталог.
|
||||||
|
|
||||||
|
Adapter возвращает файлы в памяти. Только core writer проверяет paths, полностью заменяет `.svg-sprite` и обновляет управляемый `.gitignore`.
|
||||||
|
|
||||||
|
## Зависимости
|
||||||
|
|
||||||
|
Допустимое направление импортов:
|
||||||
|
|
||||||
|
```text
|
||||||
|
public API / CLI
|
||||||
|
-> generate
|
||||||
|
-> mode-registry
|
||||||
|
-> один exact-mode adapter
|
||||||
|
-> core protocols and services
|
||||||
|
```
|
||||||
|
|
||||||
|
Обратные и горизонтальные зависимости запрещены:
|
||||||
|
|
||||||
|
```text
|
||||||
|
core -X-> modes
|
||||||
|
mode A -X-> mode B
|
||||||
|
mode A -X-> shared output codegen
|
||||||
|
```
|
||||||
|
|
||||||
|
`src/viewer/` с Web Component является framework-neutral browser runtime пакета, а не mode adapter. `src/react/` содержит только React bridge к этому runtime.
|
||||||
|
|
||||||
|
## Изменение mode
|
||||||
|
|
||||||
|
При работе с adapter:
|
||||||
|
|
||||||
|
1. Изменяйте только его каталог и mode-neutral protocol, если это действительно необходимо.
|
||||||
|
2. Не переносите output-логику в core ради устранения дублирования.
|
||||||
|
3. Не меняйте generated-контракты других adapters автоматически.
|
||||||
|
4. Проверяйте отсутствие cross-mode imports.
|
||||||
55
FEATURES.md
Normal file
55
FEATURES.md
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
# Иконки без лишней цены для приложения
|
||||||
|
|
||||||
|
`@gromlab/svg-sprites` превращает SVG проекта в кешируемую, типизированную систему иконок для современных web frameworks. В коде остаются нативные компоненты выбранного стека, а приложение получает преимущества спрайтов без сложной инфраструктуры.
|
||||||
|
|
||||||
|
1. **AI-friendly из коробки**
|
||||||
|
|
||||||
|
`@gromlab/svg-sprites` сразу рассчитан на работу с AI-агентами. Подключите готовый skill и поручите агенту настройку, миграцию или диагностику без длинных инструкций и ручного изучения документации.
|
||||||
|
|
||||||
|
2. **Типизированный нативный компонент с автокомплитом**
|
||||||
|
|
||||||
|
Каждый спрайт получает собственный готовый компонент. Prop `icon` формируется из реальных имён SVG, поэтому редактор показывает точный список доступных иконок, а TypeScript сразу обнаруживает опечатки. Не нужно вручную поддерживать компоненты, union-типы или реестр имён.
|
||||||
|
|
||||||
|
3. **Next.js App Router и SSR из коробки**
|
||||||
|
|
||||||
|
Generated-компоненты работают в Server Components, SSR и SSG без `'use client'`. Подключение иконки не переносит страницу на клиент и не требует provider или дополнительной гидратации.
|
||||||
|
|
||||||
|
4. **Множественные спрайты вместо одного глобального**
|
||||||
|
|
||||||
|
Проект не ограничен одним набором иконок. Создавайте независимые спрайты для общих элементов, отдельных страниц и крупных UI-модулей. Каждый набор получает собственный типизированный компонент и SVG asset, поэтому разделы приложения не несут иконки, которые им не нужны.
|
||||||
|
|
||||||
|
5. **Каждая иконка хранится в одном экземпляре**
|
||||||
|
|
||||||
|
Одна SVG-иконка может входить в любое количество спрайтов. Общие иконки не приходится копировать между страницами и модулями: они хранятся в одном месте и обновляются сразу для всех наборов.
|
||||||
|
|
||||||
|
6. **Браузерное кэширование**
|
||||||
|
|
||||||
|
Каждый спрайт выпускается отдельным версионированным SVG-файлом. Пока его набор иконок не меняется, браузер может использовать сохранённую копию независимо от обновлений JavaScript приложения.
|
||||||
|
|
||||||
|
7. **JavaScript без SVG-балласта**
|
||||||
|
|
||||||
|
Контуры иконок остаются во внешних SVG assets и не увеличивают chunks приложения. JavaScript отвечает за интерфейс и поведение, а графика загружается и кешируется отдельно.
|
||||||
|
|
||||||
|
8. **Трансформации SVG из коробки**
|
||||||
|
|
||||||
|
Во время генерации пакет автоматически подготавливает исходные SVG для интерфейса: удаляет фиксированные `width` и `height` с сохранением `viewBox`, преобразует `fill` и `stroke` в CSS-переменные и добавляет плавные transitions непосредственно в цветные элементы иконки. Каждую трансформацию можно настроить или отключить независимо.
|
||||||
|
|
||||||
|
9. **Каждый цвет под контролем CSS**
|
||||||
|
|
||||||
|
При генерации цвета `fill` и `stroke` автоматически преобразуются в CSS-переменные `--icon-color-N`. Монохромная иконка наследует `currentColor`, а в многоцветной каждый цвет можно менять отдельно. Темы, состояния и hover-эффекты создаются без редактирования SVG и дополнительных копий иконки.
|
||||||
|
|
||||||
|
10. **SpriteViewer: все спрайты на одной debug-странице**
|
||||||
|
|
||||||
|
`SpriteViewer` рендерит все спрайты проекта в одном месте и показывает, какие иконки вошли в каждый набор и как они выглядят. Для каждой иконки видны созданные CSS-переменные и их fallback-цвета. Значения можно менять прямо в Viewer и сразу наблюдать результат. Здесь же доступны готовые примеры для framework из manifest, `<svg><use>`, `<img>` и CSS.
|
||||||
|
|
||||||
|
11. **29 exact modes**
|
||||||
|
|
||||||
|
Изолированные adapters создают нативные компоненты для standalone, React, Next.js, Vue, Nuxt, Svelte, SvelteKit, Angular, Astro, Solid, SolidStart, Preact, Qwik, Lit и Alpine.js. Каждый exact mode учитывает свой Vite, Webpack, Turbopack или application-builder контракт.
|
||||||
|
|
||||||
|
12. **Чистый Git**
|
||||||
|
|
||||||
|
Generated-файлы автоматически исключаются из Git и не засоряют историю, pull requests и код проекта. В репозитории остаются только исходные SVG и конфигурация, а локально и в CI спрайты, компоненты и типы заново создаются через `prebuild`.
|
||||||
|
|
||||||
|
13. **В production только иконки**
|
||||||
|
|
||||||
|
Генератор можно запускать через `npx`, не добавляя package в проект. Локальная установка нужна только для необязательного Viewer, типизации config через package или программного API. Compiler и CLI не попадают в клиентское приложение: после сборки остаются только локальный типизированный компонент и внешний SVG-файл.
|
||||||
78
MODES_CHECKLIST.md
Normal file
78
MODES_CHECKLIST.md
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
# Exact Mode Checklist
|
||||||
|
|
||||||
|
Mode отмечается поддержанным только после завершения полного вертикального среза:
|
||||||
|
|
||||||
|
- реализован независимый adapter в `src/modes/<mode-slug>/`;
|
||||||
|
- добавлен один integration-стенд для exact mode;
|
||||||
|
- production build стенда успешно рендерит иконку из внешнего SVG-спрайта;
|
||||||
|
- Viewer на стенде загружает тот же спрайт и проходит адресный E2E;
|
||||||
|
- добавлены быстрые старты на русском и английском языках;
|
||||||
|
- ссылки на быстрые старты добавлены в `README_RU.md` и `README.md`.
|
||||||
|
|
||||||
|
## Standalone
|
||||||
|
|
||||||
|
- [x] `standalone`
|
||||||
|
- [x] `standalone@vite`
|
||||||
|
- [x] `standalone@webpack`
|
||||||
|
|
||||||
|
## React
|
||||||
|
|
||||||
|
- [x] `react@vite`
|
||||||
|
- [x] `react@webpack`
|
||||||
|
|
||||||
|
## Next.js
|
||||||
|
|
||||||
|
- [x] `next@app/turbopack`
|
||||||
|
- [x] `next@app/webpack`
|
||||||
|
- [x] `next@pages/turbopack`
|
||||||
|
- [x] `next@pages/webpack`
|
||||||
|
|
||||||
|
## Vue
|
||||||
|
|
||||||
|
- [x] `vue@vite`
|
||||||
|
- [x] `vue@webpack`
|
||||||
|
|
||||||
|
## Nuxt
|
||||||
|
|
||||||
|
- [x] `nuxt@vite`
|
||||||
|
- [x] `nuxt@webpack`
|
||||||
|
|
||||||
|
## Svelte
|
||||||
|
|
||||||
|
- [x] `svelte@vite`
|
||||||
|
- [x] `svelte@webpack`
|
||||||
|
- [x] `sveltekit@vite`
|
||||||
|
|
||||||
|
## Angular
|
||||||
|
|
||||||
|
- [x] `angular@application`
|
||||||
|
- [x] `angular@webpack`
|
||||||
|
|
||||||
|
## Astro
|
||||||
|
|
||||||
|
- [x] `astro@vite`
|
||||||
|
|
||||||
|
## Solid
|
||||||
|
|
||||||
|
- [x] `solid@vite`
|
||||||
|
- [x] `solid@webpack`
|
||||||
|
- [x] `solid-start@vite`
|
||||||
|
|
||||||
|
## Preact
|
||||||
|
|
||||||
|
- [x] `preact@vite`
|
||||||
|
- [x] `preact@webpack`
|
||||||
|
|
||||||
|
## Qwik
|
||||||
|
|
||||||
|
- [x] `qwik@vite`
|
||||||
|
|
||||||
|
## Lit
|
||||||
|
|
||||||
|
- [x] `lit@vite`
|
||||||
|
- [x] `lit@webpack`
|
||||||
|
|
||||||
|
## Alpine.js
|
||||||
|
|
||||||
|
- [x] `alpine@vite`
|
||||||
|
- [x] `alpine@webpack`
|
||||||
543
README.md
543
README.md
@@ -1,397 +1,280 @@
|
|||||||
# @gromlab/svg-sprites
|
# @gromlab/svg-sprites
|
||||||
|
|
||||||
🇬🇧 English | [🇷🇺 Русский](README_RU.md)
|
🇬🇧 English | [🇷🇺 Русский](https://github.com/gromlab-ru/svg-sprites/blob/master/README_RU.md)
|
||||||
|
|
||||||
 
|
 
|
||||||
|
|
||||||
A CLI for generating SVG sprites and typed icon components for React and Next.js.
|
`@gromlab/svg-sprites` is an SVG sprite generator for modern web applications. It combines selected SVG icons into one or more external, cacheable sprites and prepares them for use in the UI.
|
||||||
|
|
||||||

|
Each exact mode generates a native typed component for its framework and bundler: Web Component, React, Vue, Svelte, Angular, Astro, Solid, Preact, Qwik, Lit, or Alpine.js. In every case, the SVG remains a separate cacheable asset.
|
||||||
|
|
||||||
## Navigation
|
## An SVG sprite as simple as a regular SVG icon
|
||||||
|
|
||||||
- [Features](#features)
|
One typed React component is generated for the entire sprite. Choose an icon with the `icon` prop, and your editor will autocomplete every available name.
|
||||||
- [Support matrix](#support-matrix)
|
|
||||||
- [Requirements](#requirements)
|
|
||||||
- [Quick start](#quick-start)
|
|
||||||
- [React + Vite](docs/en/react-vite.md)
|
|
||||||
- [React + Webpack 5](docs/en/react-webpack.md)
|
|
||||||
- [Next.js App Router](docs/en/next-app.md)
|
|
||||||
- [Next.js Pages Router](docs/en/next-pages.md)
|
|
||||||
- [Configuration](#configuration)
|
|
||||||
- [React](#react)
|
|
||||||
- [Next.js](#nextjs)
|
|
||||||
- [Multiple sprites](#multiple-sprites)
|
|
||||||
- [TypeScript](#typescript)
|
|
||||||
- [Sprite formats](#sprite-formats)
|
|
||||||
- [Rendering methods](#rendering-methods)
|
|
||||||
- [Transformations](#transformations)
|
|
||||||
- [Icon color management](#icon-color-management)
|
|
||||||
- [Caching](#caching)
|
|
||||||
- [SpriteViewer](#spriteviewer)
|
|
||||||
- [Migrating from 0.1.x](docs/en/migration-1.md)
|
|
||||||
- [Documentation](#documentation)
|
|
||||||
|
|
||||||
## Features
|
```tsx
|
||||||
|
<AppIcon icon="search" width={24} height={24} />
|
||||||
- **AI-agent friendly** - the repository includes a ready-to-use skill with up-to-date documentation for configuring, migrating, and troubleshooting `@gromlab/svg-sprites`.
|
|
||||||
- **TypeScript-friendly** - typed React components, union types, and runtime lists of available icons.
|
|
||||||
- **Clean generation** - generated files are automatically excluded from Git, the sprite does not need to be placed in `public` manually, and the generator updates only files it owns.
|
|
||||||
- **Shared icons without copying** - SVGs from the local folder and `inputFiles` are merged into a single sprite; one file can be used in multiple sprites.
|
|
||||||
- **Built-in interactive preview** - `<SpriteViewer>` is integrated as an application page and displays the provided React and Next.js sprites with search, color controls, and usage examples.
|
|
||||||
- **Configurable SVG transformations** - remove `width` and `height` while preserving `viewBox`, replace source colors with CSS variables, and add transitions for `fill` and `stroke`.
|
|
||||||
- **Separate cacheable SVG asset** - SVG path data does not end up in JavaScript chunks, and the bundler emits a file with a content hash.
|
|
||||||
- **Multiple sprites** - independent React and Next.js modules with their own components, types, and SVG assets.
|
|
||||||
- **Server-first Next.js** - generated components work in Server Components, SSR, and SSG without the `'use client'` directive.
|
|
||||||
- **Formats for different use cases** - React and Next.js use `stack`; legacy mode also supports `symbol` for existing integrations.
|
|
||||||
|
|
||||||
## Support matrix
|
|
||||||
|
|
||||||
| Environment | API mode key | Status |
|
|
||||||
|---|---|---|
|
|
||||||
| React + Vite | `react@vite` | Ready |
|
|
||||||
| React + Webpack 5 | `react@webpack` | Ready |
|
|
||||||
| Next.js 16.2+ App Router + Turbopack | `next@app/turbopack` | Ready |
|
|
||||||
| Next.js 13.4+ App Router + Webpack 5 | `next@app/webpack` | Ready |
|
|
||||||
| Next.js 16.2+ Pages Router + Turbopack | `next@pages/turbopack` | Ready |
|
|
||||||
| Next.js 12.2+ Pages Router + Webpack 5 | `next@pages/webpack` | Ready |
|
|
||||||
| Vue | - | Coming soon |
|
|
||||||
| Standalone | - | Coming soon |
|
|
||||||
|
|
||||||
## Requirements
|
|
||||||
|
|
||||||
- Node.js 18 or newer;
|
|
||||||
- the package is distributed as ESM only and is loaded via `import`;
|
|
||||||
- React 18 or 19 is required only for generated components and the `@gromlab/svg-sprites/react` entry point;
|
|
||||||
- for subpath export typings, use TypeScript 5+ with `moduleResolution: "bundler"`, `"node16"`, or `"nodenext"`.
|
|
||||||
|
|
||||||
## Quick start
|
|
||||||
|
|
||||||
For a quick start, follow the guide for your stack:
|
|
||||||
|
|
||||||
- [React + Vite](docs/en/react-vite.md)
|
|
||||||
- [React + Webpack 5](docs/en/react-webpack.md)
|
|
||||||
- [Next.js App Router](docs/en/next-app.md)
|
|
||||||
- [Next.js Pages Router](docs/en/next-pages.md)
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
### React
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineReactSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineReactSpriteConfig({
|
|
||||||
name: 'file-manager',
|
|
||||||
description: 'File manager icons',
|
|
||||||
inputFolder: './icons',
|
|
||||||
inputFiles: [
|
|
||||||
'../../shared/icons/check.svg',
|
|
||||||
],
|
|
||||||
transform: {
|
|
||||||
removeSize: true,
|
|
||||||
replaceColors: true,
|
|
||||||
addTransition: true,
|
|
||||||
},
|
|
||||||
generatedNotice: true,
|
|
||||||
})
|
|
||||||
```
|
```
|
||||||
|
|
||||||
| Option | Type | Default | Purpose |
|
The component accepts familiar SVG attributes: dimensions, `color`, `className`, `style`, `aria-*`, and event handlers. If you need an outer container, add `wrapped`.
|
||||||
|---|---|---|---|
|
|
||||||
| `name` | `string` | Folder name | Name of the sprite, component, and public types |
|
|
||||||
| `description` | `string` | None | Description for types and the debug manifest |
|
|
||||||
| `inputFolder` | `string` | `./icons` | Folder containing source SVGs, relative to the config |
|
|
||||||
| `inputFiles` | `string[]` | `[]` | Additional SVG files, relative to the config |
|
|
||||||
| `transform` | `TransformOptions` | All enabled | [Transformation settings](#transformations) for source SVGs |
|
|
||||||
| `generatedNotice` | `boolean` | `true` | Full or short warning in generated files |
|
|
||||||
|
|
||||||
`inputFolder` and `inputFiles` are merged into a single sprite, so one SVG file can be used in multiple sprites without copying. If the implicit `./icons` folder does not exist but `inputFiles` is populated, generation continues using only the list. An explicitly specified missing folder is an error. Duplicate paths are deduplicated, while different files with the same icon name are treated as an error.
|
```tsx
|
||||||
|
<AppIcon icon="search" wrapped className="iconWrapper" />
|
||||||
`name` is stored in kebab-case and must start with a Latin letter. The React and Next.js presets produce the `stack` format.
|
|
||||||
|
|
||||||
### Next.js
|
|
||||||
|
|
||||||
Next.js uses the same `svg-sprite.config.ts` and set of options. For type checking, you can use a dedicated helper:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineNextSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineNextSpriteConfig({
|
|
||||||
name: 'file-manager',
|
|
||||||
description: 'File manager icons',
|
|
||||||
inputFolder: './icons',
|
|
||||||
})
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The router and bundler are selected through the mode key, so switching between Turbopack and Webpack is always explicitly reflected in the generation command.
|
You do not have to work with the sprite directly in your application. Use it like a regular SVG icon while benefiting from a single component, autocomplete, and TypeScript validation for every name.
|
||||||
|
|
||||||
## Multiple sprites
|
## AI-friendly out of the box
|
||||||
|
|
||||||
An application can contain several independent sprites for different scopes:
|
`@gromlab/svg-sprites` is designed to work with AI agents from the start. Add the ready-made skill and ask an agent to configure, migrate, or troubleshoot the package without lengthy instructions or manual documentation research.
|
||||||
|
|
||||||
**Problem:** one global sprite loads icons that the current screen does not need.
|
[🇬🇧 Download AI skill (English)](https://github.com/gromlab-ru/svg-sprites/releases/latest/download/svg-sprites.zip)
|
||||||
|
|
||||||
**Solution:** keep shared icons globally, and place icon sets for pages and large components in separate sprites that load alongside them.
|
[🇷🇺 Download AI skill (Russian)](https://github.com/gromlab-ru/svg-sprites/releases/latest/download/svg-sprites-ru.zip)
|
||||||
|
|
||||||
|
## From SVG to component in three steps
|
||||||
|
|
||||||
|
The main example uses the Next.js App Router and Turbopack.
|
||||||
|
|
||||||
|
### 1. Specify the icons you need
|
||||||
|
|
||||||
|
Create directories for the source icons and the sprite:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
global -> GlobalIcon -> shared application icons
|
assets/
|
||||||
analytics-page -> AnalyticsPageIcon -> icons for a specific page
|
├── app-icons/
|
||||||
file-manager -> FileManagerIcon -> icons for a large component
|
│ └── svg-sprite.config.json
|
||||||
|
└── svg-icons/
|
||||||
|
├── search.svg
|
||||||
|
└── settings.svg
|
||||||
```
|
```
|
||||||
|
|
||||||
- **Global sprite** contains a small set of shared icons used in different parts of the application: navigation, states, and basic actions.
|
Create the sprite configuration:
|
||||||
- **Page sprite** loads with a specific section and does not increase the shared sprite with icons that are not needed anywhere else.
|
|
||||||
- **Large component sprite** encapsulates the icon set of a complex UI module, such as a file manager or editor.
|
|
||||||
|
|
||||||
Each group gets:
|
```json
|
||||||
|
{
|
||||||
- its own SVG asset;
|
"mode": "next@app/turbopack",
|
||||||
- its own typed component;
|
"name": "app",
|
||||||
- a separate list of icon names;
|
"input": "../svg-icons/**/*.svg"
|
||||||
- a separate debug manifest;
|
|
||||||
- an independent cache lifecycle.
|
|
||||||
|
|
||||||
|
|
||||||
## TypeScript
|
|
||||||
|
|
||||||
The main feature of the TypeScript API is icon name autocomplete directly in the `icon` prop:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
<FileManagerIcon icon="folder" />
|
|
||||||
// ^ the editor suggests every icon in the sprite
|
|
||||||
```
|
|
||||||
|
|
||||||
SVG file names become valid `icon` values. A typo or unknown name immediately becomes a TypeScript error:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
<FileManagerIcon icon="unknown" /> // TypeScript error
|
|
||||||
```
|
|
||||||
|
|
||||||
For programmatic access, the generated module exports a readonly array of all icons available in a specific sprite:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { fileManagerIconNames } from './svg-sprite'
|
|
||||||
|
|
||||||
// readonly ['check', 'folder', ...]
|
|
||||||
```
|
|
||||||
|
|
||||||
You can use this list in custom catalogs, select components, tests, and other runtime scenarios. The `FileManagerIconName` union type is also derived from it.
|
|
||||||
|
|
||||||
File names containing spaces and other characters unsafe for SVG IDs remain part of the public TypeScript API. For the internal `<symbol id>`, the generator creates a stable hash ID.
|
|
||||||
|
|
||||||
```text
|
|
||||||
folder open.svg -> icon="folder open" -> id="icon-<stable-hash>"
|
|
||||||
```
|
|
||||||
|
|
||||||
For such names, use the generated component or the `id` from the debug manifest. The manual examples below using `#<name>` are suitable only for names that are already safe SVG IDs.
|
|
||||||
|
|
||||||
## Sprite formats
|
|
||||||
|
|
||||||
`stack` is the more modern format, so it is used by default. Icons can be rendered through `<svg><use>`, `<img>`, and CSS `background-image`.
|
|
||||||
|
|
||||||
`symbol` is retained for compatibility with existing integrations and supports rendering only through `<svg><use>`.
|
|
||||||
|
|
||||||
## Rendering methods
|
|
||||||
|
|
||||||
### React component - recommended
|
|
||||||
|
|
||||||
The generated component provides type safety and icon name autocomplete, and constructs the SVG asset URL itself.
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
<FileManagerIcon icon="check" width={24} height={24} />
|
|
||||||
```
|
|
||||||
|
|
||||||
Monochrome and multicolor icons are supported through `color` and `--icon-color-N`.
|
|
||||||
|
|
||||||
### Manually with `<svg><use>`
|
|
||||||
|
|
||||||
A good low-level method that provides full control over dimensions and colors. This is exactly what the React component uses under the hood.
|
|
||||||
|
|
||||||
How you obtain `spriteUrl` depends on the bundler.
|
|
||||||
|
|
||||||
**Vite:**
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
import spriteUrl from './svg-sprite/generated/sprite.svg?no-inline'
|
|
||||||
```
|
|
||||||
|
|
||||||
**Webpack 5:**
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
const spriteUrl = new URL(
|
|
||||||
'./svg-sprite/generated/sprite.svg',
|
|
||||||
import.meta.url,
|
|
||||||
).href
|
|
||||||
```
|
|
||||||
|
|
||||||
**Next.js with Webpack 5 or Turbopack:**
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
const spriteUrl = new URL(
|
|
||||||
'./svg-sprite/generated/sprite.svg',
|
|
||||||
import.meta.url,
|
|
||||||
).href
|
|
||||||
```
|
|
||||||
|
|
||||||
After obtaining the URL, the icon is rendered the same way:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
<svg width={24} height={24}>
|
|
||||||
<use href={`${spriteUrl}#check`} />
|
|
||||||
</svg>
|
|
||||||
```
|
|
||||||
|
|
||||||
Vite, Webpack 5, and Next.js replace the source path with the final hashed asset URL automatically.
|
|
||||||
|
|
||||||
### With `<img>` - less efficient
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
<img src={`${spriteUrl}#check`} width={24} height={24} alt="Done" />
|
|
||||||
```
|
|
||||||
|
|
||||||
The SVG loads as an isolated image: its colors cannot be changed through `color` or `--icon-color-N`.
|
|
||||||
|
|
||||||
### With CSS `background-image` - less efficient
|
|
||||||
|
|
||||||
```css
|
|
||||||
.icon {
|
|
||||||
background: url('./svg-sprite/generated/sprite.svg#check') center / contain no-repeat;
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Like `<img>`, this method does not allow you to control internal SVG colors. The path is specified relative to the CSS file, and Vite/Webpack replaces it with the final hashed URL during the build.
|
`input` supports directory paths, individual SVG files, and glob patterns.
|
||||||
|
|
||||||
### With CSS mask - less efficient
|
### 2. Add a generation script
|
||||||
|
|
||||||
```css
|
```json
|
||||||
.icon {
|
{
|
||||||
background-color: currentColor;
|
"scripts": {
|
||||||
mask: url('./svg-sprite/generated/sprite.svg#check') center / contain no-repeat;
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"prebuild": "npm run sprites"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
A mask retains only the silhouette and colors it with a single color. The original colors, gradients, and distinctions between `fill` and `stroke` are lost.
|
Create an entry point for the generated API:
|
||||||
|
|
||||||
## Transformations
|
```ts
|
||||||
|
// assets/app-icons/index.ts
|
||||||
All transformations are enabled by default and configured independently through `transform`.
|
export * from './.svg-sprite/index.js'
|
||||||
|
|
||||||
| Option | Default | What it does |
|
|
||||||
|---|---|---|
|
|
||||||
| `removeSize` | `true` | Removes `width` and `height` from the root `<svg>` while preserving the existing `viewBox`. The icon size is then set externally. |
|
|
||||||
| `replaceColors` | `true` | Replaces `fill` and `stroke` colors with `--icon-color-N`. For a monochrome icon, the fallback becomes `currentColor`; for a multicolor icon, the original colors are preserved. |
|
|
||||||
| `addTransition` | `true` | Adds `style="transition:fill 0.3s,stroke 0.3s;"` directly to colored SVG elements. An existing `transition` is not overwritten. |
|
|
||||||
|
|
||||||
To disable a transformation, pass `false` for the corresponding option. For more details about the result of `replaceColors`, see [Icon color management](#icon-color-management).
|
|
||||||
|
|
||||||
## Icon color management
|
|
||||||
|
|
||||||
When color replacement is enabled, the generator analyzes `fill` and `stroke` and converts them to CSS custom properties.
|
|
||||||
|
|
||||||
### Monochrome icons
|
|
||||||
|
|
||||||
If one color is found, the fallback is replaced with `currentColor`:
|
|
||||||
|
|
||||||
```svg
|
|
||||||
stroke="var(--icon-color-1, currentColor)"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The color is controlled by the CSS `color` property of the outer `<svg>` or its parent.
|
First run:
|
||||||
|
|
||||||
### Multicolor icons
|
```bash
|
||||||
|
npm run sprites
|
||||||
Each unique color gets a separate variable with the original fallback:
|
|
||||||
|
|
||||||
```svg
|
|
||||||
fill="var(--icon-color-1, #798198)"
|
|
||||||
fill="var(--icon-color-2, #ffffff)"
|
|
||||||
fill="var(--icon-color-3, #129d9d)"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The page can override only the required colors:
|
The package will generate `AppIcon`, TypeScript types, and a separate SVG sprite.
|
||||||
|
|
||||||
```css
|
### 3. Use it like a regular icon
|
||||||
.icon {
|
|
||||||
--icon-color-1: #4b5563;
|
```tsx
|
||||||
--icon-color-3: #14b8a6;
|
// app/page.tsx
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
|
export default function SearchButton() {
|
||||||
|
return (
|
||||||
|
<button type="button">
|
||||||
|
<AppIcon icon="search" width={20} height={20} />
|
||||||
|
Search
|
||||||
|
</button>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Color limitations
|
This is a Server Component. The icon does not require a provider, `'use client'`, or manual URL construction.
|
||||||
|
|
||||||
- `none`, `transparent`, `inherit`, `unset`, and `initial` are not replaced;
|
## Typed React component with autocomplete
|
||||||
- colors in `fill`, `stroke`, and inline `style` attributes are handled most reliably;
|
|
||||||
- CSS classes and external stylesheets inside the source SVG are not the primary transformation use case;
|
|
||||||
- gradients, patterns, filters, and `url(#...)` values require separate verification and may be incompatible with automatic color replacement;
|
|
||||||
- page CSS variables are available with `<svg><use>`, but are not available inside `<img>` and `background-image`.
|
|
||||||
|
|
||||||
## Caching
|
Each sprite gets its own ready-to-use component. The `icon` prop is derived from the actual SVG names, so your editor shows the exact list of available icons and TypeScript catches typos immediately.
|
||||||
|
|
||||||
The Vite, Webpack, and Next.js targets emit the sprite as a separate asset with a content hash:
|
```tsx
|
||||||
|
<AppIcon icon="search" /> // available icon
|
||||||
|
<AppIcon icon="serach" /> // TypeScript error
|
||||||
|
```
|
||||||
|
|
||||||
|
After you add a new SVG icon and run generation again, its name automatically appears in the types and autocomplete. There is no need to maintain components, union types, or a name registry manually.
|
||||||
|
|
||||||
|
## Next.js App Router and SSR out of the box
|
||||||
|
|
||||||
|
Generated components work in Server Components, SSR, and SSG without `'use client'`.
|
||||||
|
|
||||||
|
Using an icon does not turn the page into a Client Component, require a provider, or create an additional hydration boundary.
|
||||||
|
|
||||||
|
The same component can be used in `page.tsx`, `layout.tsx`, and both server and client components.
|
||||||
|
|
||||||
|
## Multiple sprites instead of one global sprite
|
||||||
|
|
||||||
|
Your project is not limited to a single icon set. Create independent sprites for shared elements, individual pages, and large UI modules.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<AppIcon icon="search" />
|
||||||
|
<AnalyticsIcon icon="chart" />
|
||||||
|
<EditorIcon icon="bold" />
|
||||||
|
```
|
||||||
|
|
||||||
|
Each set gets its own typed component and SVG asset, so application sections do not load icons they do not need.
|
||||||
|
|
||||||
|
## Store each icon only once
|
||||||
|
|
||||||
|
Each SVG icon is stored once in the source library and can be included in any number of sprites. Shared icons do not need to be copied between pages and modules: a single source updates every set.
|
||||||
|
|
||||||
```text
|
```text
|
||||||
/assets/sprite-<hash>.svg
|
search.svg ─┬─→ AppIcon
|
||||||
|
├─→ AnalyticsIcon
|
||||||
|
└─→ EditorIcon
|
||||||
```
|
```
|
||||||
|
|
||||||
This provides the following properties:
|
Sprites are split for performance, while the source icon library remains unified.
|
||||||
|
|
||||||
- the SVG is cached independently of JavaScript;
|
## Browser caching
|
||||||
- changes to React code do not alter the sprite contents;
|
|
||||||
- icon changes produce a new hashed asset;
|
|
||||||
- one file is used by every instance of the generated component;
|
|
||||||
- SVG path data is absent from JavaScript chunks.
|
|
||||||
|
|
||||||
The Vite target prevents inlining through `?no-inline`. The Webpack 5 target uses Asset Modules through `new URL(..., import.meta.url)`.
|
With a standard Vite, Webpack, or Next.js configuration, each sprite is emitted as a separate versioned SVG file.
|
||||||
|
|
||||||
## SpriteViewer
|
As long as the icon set does not change, the browser can reuse its cached copy independently of JavaScript application updates.
|
||||||
|
|
||||||
`SpriteViewer` is a React component for viewing generated sprites inside an application's debug route.
|
Changes to React components do not require downloading the geometry of every icon again.
|
||||||
|
|
||||||
It uses separate manifests and displays:
|
## JavaScript without SVG bloat
|
||||||
|
|
||||||
- sprite groups;
|
Icon paths remain in external SVG assets and do not add to application chunks.
|
||||||
- the icon list and count;
|
|
||||||
- search and the system light/dark theme;
|
|
||||||
- a preview modal with the `viewBox` and color variable controls;
|
|
||||||
- React, SVG, IMG, and CSS examples with code copying.
|
|
||||||
|
|
||||||
Production components do not import debug manifests. How you integrate the Viewer depends on the bundler:
|
```text
|
||||||
|
React code → JavaScript chunks
|
||||||
- [React + Vite: automatic `import.meta.glob`](docs/en/react-vite.md#6-add-a-debug-page);
|
SVG icons → separate SVG assets
|
||||||
- [React + Webpack 5: static `import()`](docs/en/react-webpack.md#6-add-a-debug-page);
|
|
||||||
- [Next.js App Router](docs/en/next-app.md#5-add-spriteviewer);
|
|
||||||
- [Next.js Pages Router](docs/en/next-pages.md#5-add-spriteviewer).
|
|
||||||
|
|
||||||
The Viewer is imported from the separate `@gromlab/svg-sprites/react` client entry point and is not included in production icon components.
|
|
||||||
|
|
||||||
### Viewer theme
|
|
||||||
|
|
||||||
By default, `colorTheme="auto"`: the Viewer follows `prefers-color-scheme` and responds to system theme changes. The application theme can be passed explicitly:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
<SpriteViewer sources={sources} colorTheme="dark" />
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Valid `colorTheme` values are `auto`, `light`, and `dark`. When the theme is controlled externally, the built-in switch is hidden. To keep it and update the application theme through the Viewer, pass a callback:
|
JavaScript handles the interface and behavior, while graphics are loaded and cached separately.
|
||||||
|
|
||||||
|
## Built-in SVG transformations
|
||||||
|
|
||||||
|
During generation, the package automatically prepares source SVG files for use in the UI:
|
||||||
|
|
||||||
|
- removes fixed `width` and `height` attributes;
|
||||||
|
- preserves the existing `viewBox`;
|
||||||
|
- converts `fill` and `stroke` values to CSS variables;
|
||||||
|
- adds smooth transitions directly to colored icon elements.
|
||||||
|
|
||||||
|
Each transformation can be configured or disabled independently.
|
||||||
|
|
||||||
|
## Control every color with CSS
|
||||||
|
|
||||||
|
During generation, `fill` and `stroke` colors are automatically converted to `--icon-color-N` CSS variables.
|
||||||
|
|
||||||
|
A monochrome icon inherits `currentColor`:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
<SpriteViewer
|
<AppIcon icon="search" color="rebeccapurple" />
|
||||||
sources={sources}
|
```
|
||||||
colorTheme={appTheme}
|
|
||||||
onColorThemeChange={setAppTheme}
|
For a multicolor icon, each color can be changed independently:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<AppIcon
|
||||||
|
icon="user"
|
||||||
|
style={{
|
||||||
|
'--icon-color-1': '#2563eb',
|
||||||
|
'--icon-color-2': '#dbeafe',
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Create themes, states, and hover effects without editing the SVG or making additional copies of the icon.
|
||||||
|
|
||||||
|
## SpriteViewer: every sprite on one debug page
|
||||||
|
|
||||||
|
`SpriteViewer` renders sprites from every supported exact mode in one place. One Web Component owns the visuals, while React also provides a thin bridge to it.
|
||||||
|
|
||||||
|
For each icon, you can see the generated CSS variables and their fallback colors. Change the values directly in the Viewer and see the result immediately.
|
||||||
|
|
||||||
|
It also provides ready-to-use examples for the manifest's framework, `<svg><use>`, `<img>`, and CSS.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
The Viewer is added only to an internal debug page and does not become part of the generated icon components.
|
||||||
|
|
||||||
|
With bare standalone, the application loads the Viewer as a browser script and HTML element. Bundler and framework modes use the npm Web Component entry; React and Next.js may instead import the bridge from `@gromlab/svg-sprites/react`.
|
||||||
|
|
||||||
|
## 29 exact modes
|
||||||
|
|
||||||
|
The package provides isolated contracts for standalone, React, Next.js, Vue, Nuxt, Svelte, SvelteKit, Angular, Astro, Solid, SolidStart, Preact, Qwik, Lit, and Alpine.js across their supported Vite, Webpack, Turbopack, and application-builder variants.
|
||||||
|
|
||||||
|
## Clean Git history
|
||||||
|
|
||||||
|
Bundler and framework modes create a local `.gitignore` that excludes generated files and keeps them from cluttering project history, pull requests, and the codebase. Bare `standalone` leaves the repository policy to the application.
|
||||||
|
|
||||||
|
In bundler and framework modes, the repository contains the source SVG files, configuration, and `.gitignore` rule, while sprites, components, and types are regenerated locally and in CI through `prebuild`.
|
||||||
|
|
||||||
|
## Only icons in production
|
||||||
|
|
||||||
|
Generation can run entirely through `npx`, without adding the package to the project. Install it as a development dependency only when you need the Viewer, config types, or the programmatic API.
|
||||||
|
|
||||||
|
Production components use only local generated code, styles, and the external SVG file. The compiler and CLI are not bundled into the client application, while `SpriteViewer` is imported separately only where a debug page is needed.
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
- [React + Vite](docs/en/react-vite.md)
|
This README introduces the project's capabilities and demonstrates the primary use case. For setup, choose the guide for your stack.
|
||||||
- [React + Webpack 5](docs/en/react-webpack.md)
|
|
||||||
- [Next.js App Router](docs/en/next-app.md)
|
### Quick start
|
||||||
- [Next.js Pages Router](docs/en/next-pages.md)
|
|
||||||
- [Legacy mode](docs/en/legacy.md)
|
- [Bare standalone](docs/en/guides/standalone.md)
|
||||||
- [Migrating from 0.1.x](docs/en/migration-1.md)
|
- [Standalone + Vite](docs/en/guides/standalone-vite.md)
|
||||||
- [Programmatic API](docs/en/programmatic-api.md)
|
- [Standalone + Webpack 5](docs/en/guides/standalone-webpack.md)
|
||||||
|
- [React + Vite](docs/en/guides/react-vite.md)
|
||||||
|
- [React + Webpack 5](docs/en/guides/react-webpack.md)
|
||||||
|
- [Vue + Vite](docs/en/guides/vue-vite.md)
|
||||||
|
- [Vue + Webpack](docs/en/guides/vue-webpack.md)
|
||||||
|
- [Nuxt + Vite](docs/en/guides/nuxt-vite.md)
|
||||||
|
- [Nuxt + Webpack](docs/en/guides/nuxt-webpack.md)
|
||||||
|
- [Svelte + Vite](docs/en/guides/svelte-vite.md)
|
||||||
|
- [Svelte + Webpack](docs/en/guides/svelte-webpack.md)
|
||||||
|
- [SvelteKit + Vite](docs/en/guides/sveltekit-vite.md)
|
||||||
|
- [Angular application builder](docs/en/guides/angular-application.md)
|
||||||
|
- [Angular + Webpack](docs/en/guides/angular-webpack.md)
|
||||||
|
- [Astro + Vite](docs/en/guides/astro-vite.md)
|
||||||
|
- [Solid + Vite](docs/en/guides/solid-vite.md)
|
||||||
|
- [Solid + Webpack](docs/en/guides/solid-webpack.md)
|
||||||
|
- [SolidStart + Vite](docs/en/guides/solid-start-vite.md)
|
||||||
|
- [Preact + Vite](docs/en/guides/preact-vite.md)
|
||||||
|
- [Preact + Webpack](docs/en/guides/preact-webpack.md)
|
||||||
|
- [Qwik + Vite](docs/en/guides/qwik-vite.md)
|
||||||
|
- [Lit + Vite](docs/en/guides/lit-vite.md)
|
||||||
|
- [Lit + Webpack](docs/en/guides/lit-webpack.md)
|
||||||
|
- [Alpine.js + Vite](docs/en/guides/alpine-vite.md)
|
||||||
|
- [Alpine.js + Webpack](docs/en/guides/alpine-webpack.md)
|
||||||
|
- [Next.js App Router + Turbopack](docs/en/guides/next-app-turbopack.md)
|
||||||
|
- [Next.js App Router + Webpack](docs/en/guides/next-app-webpack.md)
|
||||||
|
- [Next.js Pages Router + Turbopack](docs/en/guides/next-pages-turbopack.md)
|
||||||
|
- [Next.js Pages Router + Webpack](docs/en/guides/next-pages-webpack.md)
|
||||||
|
|
||||||
|
### Technical resources
|
||||||
|
|
||||||
|
- [Documentation index](docs/en/README.md)
|
||||||
|
- [Configuration](docs/en/configuration.md)
|
||||||
|
- [Technical reference](docs/en/reference/technical.md)
|
||||||
|
- [Programmatic API](docs/en/reference/programmatic-api.md)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
543
README_RU.md
543
README_RU.md
@@ -1,397 +1,280 @@
|
|||||||
# @gromlab/svg-sprites
|
# @gromlab/svg-sprites
|
||||||
|
|
||||||
[🇬🇧 English](README.md) | 🇷🇺 Русский
|
[🇬🇧 English](https://github.com/gromlab-ru/svg-sprites/blob/master/README.md) | 🇷🇺 Русский
|
||||||
|
|
||||||
 
|
 
|
||||||
|
|
||||||
CLI для генерации SVG-спрайтов и типизированных компонентов иконок для React и Next.js.
|
`@gromlab/svg-sprites` — генератор SVG-спрайтов для современных веб-приложений. Он собирает выбранные SVG-иконки в один или несколько внешних кешируемых спрайтов и подготавливает их для использования в интерфейсе.
|
||||||
|
|
||||||

|
Каждый exact mode создаёт нативный типизированный компонент для своего framework и bundler: Web Component, React, Vue, Svelte, Angular, Astro, Solid, Preact, Qwik, Lit или Alpine.js. SVG во всех случаях остаётся отдельным кешируемым asset.
|
||||||
|
|
||||||
## Навигация
|
## SVG-спрайт так же прост, как обычная SVG-иконка
|
||||||
|
|
||||||
- [Возможности](#возможности)
|
Для всего спрайта генерируется один типизированный React-компонент. Выберите иконку через `icon`, а редактор покажет автокомплит всех доступных имён.
|
||||||
- [Таблица поддержки](#таблица-поддержки)
|
|
||||||
- [Требования](#требования)
|
|
||||||
- [Быстрый старт](#быстрый-старт)
|
|
||||||
- [React + Vite](docs/ru/react-vite.md)
|
|
||||||
- [React + Webpack 5](docs/ru/react-webpack.md)
|
|
||||||
- [Next.js App Router](docs/ru/next-app.md)
|
|
||||||
- [Next.js Pages Router](docs/ru/next-pages.md)
|
|
||||||
- [Конфигурация](#конфигурация)
|
|
||||||
- [React](#react)
|
|
||||||
- [Next.js](#nextjs)
|
|
||||||
- [Множественные спрайты](#множественные-спрайты)
|
|
||||||
- [TypeScript](#typescript)
|
|
||||||
- [Форматы спрайтов](#форматы-спрайтов)
|
|
||||||
- [Способы отображения](#способы-отображения)
|
|
||||||
- [Трансформации](#трансформации)
|
|
||||||
- [Управление цветом иконок](#управление-цветом-иконок)
|
|
||||||
- [Кеширование](#кеширование)
|
|
||||||
- [SpriteViewer](#spriteviewer)
|
|
||||||
- [Миграция с 0.1.x](docs/ru/migration-1.md)
|
|
||||||
- [Документация](#документация)
|
|
||||||
|
|
||||||
## Возможности
|
```tsx
|
||||||
|
<AppIcon icon="search" width={24} height={24} />
|
||||||
- **AI-agent friendly** — репозиторий содержит готовый skill с актуальной документацией для настройки, миграции и диагностики `@gromlab/svg-sprites`.
|
|
||||||
- **TypeScript-friendly** — типизированные React-компоненты, union-типы и runtime-списки доступных иконок.
|
|
||||||
- **Чистая генерация** — generated-файлы автоматически исключаются из Git, спрайт не нужно вручную размещать в `public`, а генератор обновляет только принадлежащие ему файлы.
|
|
||||||
- **Общие иконки без копирования** — SVG из локальной папки и `inputFiles` объединяются в один спрайт; один файл можно использовать в нескольких спрайтах.
|
|
||||||
- **Встроенное интерактивное превью** — `<SpriteViewer>` подключается как страница приложения и показывает переданные React- и Next.js-спрайты с поиском, настройкой цветов и примерами использования.
|
|
||||||
- **Настраиваемые трансформации SVG** — удаление `width` и `height` с сохранением `viewBox`, замена исходных цветов на CSS-переменные и transitions для `fill` и `stroke`.
|
|
||||||
- **Отдельный кешируемый SVG asset** — SVG path-данные не попадают в JavaScript chunks, а сборщик выпускает файл с content hash.
|
|
||||||
- **Множественные спрайты** — независимые React- и Next.js-модули со своими компонентами, типами и SVG assets.
|
|
||||||
- **Server-first Next.js** — generated-компоненты работают в Server Components, SSR и SSG без директивы `'use client'`.
|
|
||||||
- **Форматы под разные сценарии** — React и Next.js используют `stack`, legacy-режим также поддерживает `symbol` для существующих интеграций.
|
|
||||||
|
|
||||||
## Таблица поддержки
|
|
||||||
|
|
||||||
| Среда | Ключ мода API | Статус |
|
|
||||||
|---|---|---|
|
|
||||||
| React + Vite | `react@vite` | Готово |
|
|
||||||
| React + Webpack 5 | `react@webpack` | Готово |
|
|
||||||
| Next.js 16.2+ App Router + Turbopack | `next@app/turbopack` | Готово |
|
|
||||||
| Next.js 13.4+ App Router + Webpack 5 | `next@app/webpack` | Готово |
|
|
||||||
| Next.js 16.2+ Pages Router + Turbopack | `next@pages/turbopack` | Готово |
|
|
||||||
| Next.js 12.2+ Pages Router + Webpack 5 | `next@pages/webpack` | Готово |
|
|
||||||
| Vue | — | Скоро |
|
|
||||||
| Standalone | — | Скоро |
|
|
||||||
|
|
||||||
## Требования
|
|
||||||
|
|
||||||
- Node.js 18 или новее;
|
|
||||||
- пакет распространяется только как ESM и подключается через `import`;
|
|
||||||
- React 18 или 19 требуется только для generated-компонентов и точки входа `@gromlab/svg-sprites/react`;
|
|
||||||
- для типизации subpath exports используйте TypeScript 5+ с `moduleResolution: "bundler"`, `"node16"` или `"nodenext"`.
|
|
||||||
|
|
||||||
## Быстрый старт
|
|
||||||
|
|
||||||
Для быстрого старта воспользуйтесь инструкцией для вашего стека:
|
|
||||||
|
|
||||||
- [React + Vite](docs/ru/react-vite.md)
|
|
||||||
- [React + Webpack 5](docs/ru/react-webpack.md)
|
|
||||||
- [Next.js App Router](docs/ru/next-app.md)
|
|
||||||
- [Next.js Pages Router](docs/ru/next-pages.md)
|
|
||||||
|
|
||||||
## Конфигурация
|
|
||||||
|
|
||||||
### React
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineReactSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineReactSpriteConfig({
|
|
||||||
name: 'file-manager',
|
|
||||||
description: 'Иконки файлового менеджера',
|
|
||||||
inputFolder: './icons',
|
|
||||||
inputFiles: [
|
|
||||||
'../../shared/icons/check.svg',
|
|
||||||
],
|
|
||||||
transform: {
|
|
||||||
removeSize: true,
|
|
||||||
replaceColors: true,
|
|
||||||
addTransition: true,
|
|
||||||
},
|
|
||||||
generatedNotice: true,
|
|
||||||
})
|
|
||||||
```
|
```
|
||||||
|
|
||||||
| Опция | Тип | По умолчанию | Назначение |
|
Компонент принимает привычные SVG-атрибуты: размеры, `color`, `className`, `style`, `aria-*` и обработчики событий. Если нужен внешний контейнер, добавьте `wrapped`.
|
||||||
|---|---|---|---|
|
|
||||||
| `name` | `string` | Имя папки | Имя спрайта, компонента и публичных типов |
|
|
||||||
| `description` | `string` | Нет | Описание для типов и debug-манифеста |
|
|
||||||
| `inputFolder` | `string` | `./icons` | Папка с исходными SVG относительно конфига |
|
|
||||||
| `inputFiles` | `string[]` | `[]` | Дополнительные SVG-файлы относительно конфига |
|
|
||||||
| `transform` | `TransformOptions` | Все включены | [Настройки трансформации](#трансформации) исходных SVG |
|
|
||||||
| `generatedNotice` | `boolean` | `true` | Полное либо короткое предупреждение в generated-файлах |
|
|
||||||
|
|
||||||
`inputFolder` и `inputFiles` объединяются в один спрайт, поэтому один SVG-файл можно использовать в нескольких спрайтах без копирования. Если неявной папки `./icons` нет, но `inputFiles` заполнен, генерация продолжается только по списку. Явно указанная отсутствующая папка считается ошибкой. Одинаковые пути дедуплицируются, а разные файлы с одинаковым именем иконки считаются ошибкой.
|
```tsx
|
||||||
|
<AppIcon icon="search" wrapped className="iconWrapper" />
|
||||||
`name` записывается в kebab-case и должно начинаться с латинской буквы. React и Next.js presets создают формат `stack`.
|
|
||||||
|
|
||||||
### Next.js
|
|
||||||
|
|
||||||
Next.js использует тот же `svg-sprite.config.ts` и набор опций. Для типизации можно использовать отдельный хелпер:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineNextSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineNextSpriteConfig({
|
|
||||||
name: 'file-manager',
|
|
||||||
description: 'Иконки файлового менеджера',
|
|
||||||
inputFolder: './icons',
|
|
||||||
})
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Роутер и сборщик выбираются через mode key, поэтому переключение между Turbopack и Webpack всегда явно отражено в команде генерации.
|
В приложении не приходится работать со спрайтом напрямую. Вы используете его так же, как обычную SVG-иконку, но получаете один компонент, автокомплит и TypeScript-проверку всех имён.
|
||||||
|
|
||||||
## Множественные спрайты
|
## AI-friendly из коробки
|
||||||
|
|
||||||
Приложение может содержать несколько независимых спрайтов с разной областью использования:
|
`@gromlab/svg-sprites` сразу рассчитан на работу с AI-агентами. Подключите готовый skill и поручите агенту настройку, миграцию или диагностику без длинных инструкций и ручного изучения документации.
|
||||||
|
|
||||||
**Проблема:** один глобальный спрайт загружает иконки, которые текущему экрану не нужны.
|
[🇷🇺 Скачать AI skill (на русском)](https://github.com/gromlab-ru/svg-sprites/releases/latest/download/svg-sprites-ru.zip)
|
||||||
|
|
||||||
**Решение:** общие иконки хранить глобально, а наборы страниц и крупных компонентов — в отдельных спрайтах, загружаемых вместе с ними.
|
[🇬🇧 Скачать AI skill (на английском)](https://github.com/gromlab-ru/svg-sprites/releases/latest/download/svg-sprites.zip)
|
||||||
|
|
||||||
|
## От SVG до компонента за три шага
|
||||||
|
|
||||||
|
Основной пример использует Next.js App Router и Turbopack.
|
||||||
|
|
||||||
|
### 1. Укажите нужные иконки
|
||||||
|
|
||||||
|
Создайте папки для исходных иконок и спрайта:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
global → GlobalIcon → общие иконки приложения
|
assets/
|
||||||
analytics-page → AnalyticsPageIcon → иконки отдельной страницы
|
├── app-icons/
|
||||||
file-manager → FileManagerIcon → иконки крупного компонента
|
│ └── svg-sprite.config.json
|
||||||
|
└── svg-icons/
|
||||||
|
├── search.svg
|
||||||
|
└── settings.svg
|
||||||
```
|
```
|
||||||
|
|
||||||
- **Глобальный спрайт** содержит небольшие общие иконки, используемые в разных частях приложения: навигацию, состояния и базовые действия.
|
Создайте конфигурацию спрайта:
|
||||||
- **Спрайт страницы** загружается вместе с конкретным разделом и не увеличивает общий спрайт иконками, которые больше нигде не нужны.
|
|
||||||
- **Спрайт крупного компонента** инкапсулирует собственный набор иконок сложного UI-модуля, например файлового менеджера или редактора.
|
|
||||||
|
|
||||||
Каждая группа получает:
|
```json
|
||||||
|
{
|
||||||
- собственный SVG asset;
|
"mode": "next@app/turbopack",
|
||||||
- собственный типизированный компонент;
|
"name": "app",
|
||||||
- отдельный список имён иконок;
|
"input": "../svg-icons/**/*.svg"
|
||||||
- отдельный debug-манифест;
|
|
||||||
- независимый cache lifecycle.
|
|
||||||
|
|
||||||
|
|
||||||
## TypeScript
|
|
||||||
|
|
||||||
Главная возможность TypeScript API — автодополнение имён иконок непосредственно в prop `icon`:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
<FileManagerIcon icon="folder" />
|
|
||||||
// ↑ редактор предлагает все иконки спрайта
|
|
||||||
```
|
|
||||||
|
|
||||||
Имена SVG-файлов становятся допустимыми значениями `icon`. Опечатка или неизвестное имя сразу становятся ошибкой TypeScript:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
<FileManagerIcon icon="unknown" /> // ошибка TypeScript
|
|
||||||
```
|
|
||||||
|
|
||||||
Для программного доступа generated-модуль экспортирует readonly-массив всех доступных иконок конкретного спрайта:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { fileManagerIconNames } from './svg-sprite'
|
|
||||||
|
|
||||||
// readonly ['check', 'folder', ...]
|
|
||||||
```
|
|
||||||
|
|
||||||
Этот список можно использовать в собственных каталогах, select-компонентах, тестах и других runtime-сценариях. Из него также выводится union-тип `FileManagerIconName`.
|
|
||||||
|
|
||||||
Имена файлов с пробелами и другими небезопасными для SVG ID символами остаются частью публичного TypeScript API. Для внутреннего `<symbol id>` генератор создаёт стабильный hash ID.
|
|
||||||
|
|
||||||
```text
|
|
||||||
folder open.svg → icon="folder open" → id="icon-<stable-hash>"
|
|
||||||
```
|
|
||||||
|
|
||||||
Для таких имён используйте generated-компонент или `id` из debug-манифеста. Ручные примеры ниже с `#<имя>` подходят только для имён, которые уже являются безопасными SVG ID.
|
|
||||||
|
|
||||||
## Форматы спрайтов
|
|
||||||
|
|
||||||
`stack` — более современный формат, поэтому он используется по умолчанию. Иконки можно отображать через `<svg><use>`, `<img>` и CSS `background-image`.
|
|
||||||
|
|
||||||
`symbol` сохраняется для совместимости с существующими интеграциями и поддерживает отображение только через `<svg><use>`.
|
|
||||||
|
|
||||||
## Способы отображения
|
|
||||||
|
|
||||||
### React-компонент — рекомендуется
|
|
||||||
|
|
||||||
Generated-компонент предоставляет типизацию, автодополнение имён иконок и сам формирует URL SVG asset.
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
<FileManagerIcon icon="check" width={24} height={24} />
|
|
||||||
```
|
|
||||||
|
|
||||||
Через `color` и `--icon-color-N` доступны одноцветные и многоцветные иконки.
|
|
||||||
|
|
||||||
### Самостоятельно через `<svg><use>`
|
|
||||||
|
|
||||||
Хороший низкоуровневый способ с полным управлением размерами и цветами. React-компонент под капотом использует именно его.
|
|
||||||
|
|
||||||
Способ получения `spriteUrl` зависит от сборщика.
|
|
||||||
|
|
||||||
**Vite:**
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
import spriteUrl from './svg-sprite/generated/sprite.svg?no-inline'
|
|
||||||
```
|
|
||||||
|
|
||||||
**Webpack 5:**
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
const spriteUrl = new URL(
|
|
||||||
'./svg-sprite/generated/sprite.svg',
|
|
||||||
import.meta.url,
|
|
||||||
).href
|
|
||||||
```
|
|
||||||
|
|
||||||
**Next.js с Webpack 5 или Turbopack:**
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
const spriteUrl = new URL(
|
|
||||||
'./svg-sprite/generated/sprite.svg',
|
|
||||||
import.meta.url,
|
|
||||||
).href
|
|
||||||
```
|
|
||||||
|
|
||||||
После получения URL иконка отображается одинаково:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
<svg width={24} height={24}>
|
|
||||||
<use href={`${spriteUrl}#check`} />
|
|
||||||
</svg>
|
|
||||||
```
|
|
||||||
|
|
||||||
Vite, Webpack 5 и Next.js сами заменяют исходный путь на итоговый URL asset с hash.
|
|
||||||
|
|
||||||
### Через `<img>` — менее эффективно
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
<img src={`${spriteUrl}#check`} width={24} height={24} alt="Готово" />
|
|
||||||
```
|
|
||||||
|
|
||||||
SVG загружается как изолированное изображение: изменить его цвета через `color` или `--icon-color-N` нельзя.
|
|
||||||
|
|
||||||
### Через CSS `background-image` — менее эффективно
|
|
||||||
|
|
||||||
```css
|
|
||||||
.icon {
|
|
||||||
background: url('./svg-sprite/generated/sprite.svg#check') center / contain no-repeat;
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Как и `<img>`, этот способ не позволяет управлять внутренними цветами SVG. Путь указывается относительно CSS-файла, а Vite/Webpack заменяет его на итоговый URL с hash при сборке.
|
`input` поддерживает пути к папкам, отдельным SVG и glob-шаблоны.
|
||||||
|
|
||||||
### Через CSS mask — менее эффективно
|
### 2. Добавьте генерацию
|
||||||
|
|
||||||
```css
|
```json
|
||||||
.icon {
|
{
|
||||||
background-color: currentColor;
|
"scripts": {
|
||||||
mask: url('./svg-sprite/generated/sprite.svg#check') center / contain no-repeat;
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"prebuild": "npm run sprites"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Mask оставляет только силуэт и окрашивает его одним цветом. Исходные цвета, gradients и различия между `fill` и `stroke` теряются.
|
Создайте точку входа для сгенерированного API:
|
||||||
|
|
||||||
## Трансформации
|
```ts
|
||||||
|
// assets/app-icons/index.ts
|
||||||
Все трансформации включены по умолчанию и настраиваются независимо через `transform`.
|
export * from './.svg-sprite/index.js'
|
||||||
|
|
||||||
| Опция | По умолчанию | Что делает |
|
|
||||||
|---|---|---|
|
|
||||||
| `removeSize` | `true` | Удаляет `width` и `height` с корневого `<svg>`, сохраняя существующий `viewBox`. Размер иконки после этого задаётся снаружи. |
|
|
||||||
| `replaceColors` | `true` | Заменяет цвета `fill` и `stroke` на `--icon-color-N`. Для одноцветной иконки fallback становится `currentColor`, для многоцветной сохраняются исходные цвета. |
|
|
||||||
| `addTransition` | `true` | Добавляет `style="transition:fill 0.3s,stroke 0.3s;"` непосредственно цветным элементам SVG. Существующий `transition` не перезаписывается. |
|
|
||||||
|
|
||||||
Чтобы отключить преобразование, передайте для соответствующей опции `false`. Подробнее о результате `replaceColors` — в разделе [«Управление цветом иконок»](#управление-цветом-иконок).
|
|
||||||
|
|
||||||
## Управление цветом иконок
|
|
||||||
|
|
||||||
При включённой замене цветов генератор анализирует `fill` и `stroke` и преобразует их в CSS custom properties.
|
|
||||||
|
|
||||||
### Монохромные иконки
|
|
||||||
|
|
||||||
Если найден один цвет, fallback заменяется на `currentColor`:
|
|
||||||
|
|
||||||
```svg
|
|
||||||
stroke="var(--icon-color-1, currentColor)"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Цветом управляет CSS-свойство `color` внешнего `<svg>` или его родителя.
|
Первый запуск:
|
||||||
|
|
||||||
### Многоцветные иконки
|
```bash
|
||||||
|
npm run sprites
|
||||||
Каждый уникальный цвет получает отдельную переменную с исходным fallback:
|
|
||||||
|
|
||||||
```svg
|
|
||||||
fill="var(--icon-color-1, #798198)"
|
|
||||||
fill="var(--icon-color-2, #ffffff)"
|
|
||||||
fill="var(--icon-color-3, #129d9d)"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Страница может заменить только необходимые цвета:
|
Пакет создаст `AppIcon`, TypeScript-типы и отдельный SVG-спрайт.
|
||||||
|
|
||||||
```css
|
### 3. Используйте как обычную иконку
|
||||||
.icon {
|
|
||||||
--icon-color-1: #4b5563;
|
```tsx
|
||||||
--icon-color-3: #14b8a6;
|
// app/page.tsx
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
|
export default function SearchButton() {
|
||||||
|
return (
|
||||||
|
<button type="button">
|
||||||
|
<AppIcon icon="search" width={20} height={20} />
|
||||||
|
Найти
|
||||||
|
</button>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Ограничения цветов
|
Это Server Component. Для иконки не нужны provider, `'use client'` или ручная сборка URL.
|
||||||
|
|
||||||
- `none`, `transparent`, `inherit`, `unset` и `initial` не заменяются;
|
## Типизированный React-компонент с автокомплитом
|
||||||
- цвета в атрибутах `fill`, `stroke` и inline `style` обрабатываются надёжнее всего;
|
|
||||||
- CSS-классы и внешние stylesheets внутри исходного SVG не являются основным сценарием трансформации;
|
|
||||||
- gradients, patterns, filters и значения `url(#...)` требуют отдельной проверки и могут быть несовместимы с автоматической заменой цветов;
|
|
||||||
- CSS-переменные страницы доступны при `<svg><use>`, но недоступны внутри `<img>` и `background-image`.
|
|
||||||
|
|
||||||
## Кеширование
|
Каждый спрайт получает собственный готовый компонент. Свойство `icon` формируется из реальных имён SVG, поэтому редактор показывает точный список доступных иконок, а TypeScript сразу обнаруживает опечатки.
|
||||||
|
|
||||||
Vite, Webpack и Next.js target выпускают спрайт отдельным asset с content hash:
|
```tsx
|
||||||
|
<AppIcon icon="search" /> // доступная иконка
|
||||||
|
<AppIcon icon="serach" /> // ошибка TypeScript
|
||||||
|
```
|
||||||
|
|
||||||
|
После добавления новой SVG-иконки и повторной генерации её имя автоматически появляется в типах и автокомплите. Не нужно вручную поддерживать компоненты, union-типы или реестр имён.
|
||||||
|
|
||||||
|
## Next.js App Router и SSR из коробки
|
||||||
|
|
||||||
|
Generated-компоненты работают в Server Components, SSR и SSG без `'use client'`.
|
||||||
|
|
||||||
|
Подключение иконки не переносит страницу на клиент, не требует provider и не создаёт дополнительную границу гидратации.
|
||||||
|
|
||||||
|
Один и тот же компонент можно использовать в `page.tsx`, `layout.tsx`, серверных и клиентских компонентах.
|
||||||
|
|
||||||
|
## Множественные спрайты вместо одного глобального
|
||||||
|
|
||||||
|
Проект не ограничен одним набором иконок. Создавайте независимые спрайты для общих элементов, отдельных страниц и крупных UI-модулей.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<AppIcon icon="search" />
|
||||||
|
<AnalyticsIcon icon="chart" />
|
||||||
|
<EditorIcon icon="bold" />
|
||||||
|
```
|
||||||
|
|
||||||
|
Каждый набор получает собственный типизированный компонент и SVG asset, поэтому разделы приложения не несут иконки, которые им не нужны.
|
||||||
|
|
||||||
|
## Каждая иконка хранится в одном экземпляре
|
||||||
|
|
||||||
|
В библиотеке исходников каждая SVG-иконка хранится в одном экземпляре и может входить в любое количество спрайтов. Общие иконки не приходится копировать между страницами и модулями: они обновляются для всех наборов из одного места.
|
||||||
|
|
||||||
```text
|
```text
|
||||||
/assets/sprite-<hash>.svg
|
search.svg ─┬─→ AppIcon
|
||||||
|
├─→ AnalyticsIcon
|
||||||
|
└─→ EditorIcon
|
||||||
```
|
```
|
||||||
|
|
||||||
Это даёт следующие свойства:
|
Спрайты разделяются ради производительности, но библиотека исходных иконок остаётся единой.
|
||||||
|
|
||||||
- SVG кешируется независимо от JavaScript;
|
## Браузерное кеширование
|
||||||
- изменение React-кода не меняет содержимое спрайта;
|
|
||||||
- изменение иконок создаёт новый hash asset;
|
|
||||||
- один файл используется всеми экземплярами generated-компонента;
|
|
||||||
- SVG path-данные отсутствуют в JavaScript chunks.
|
|
||||||
|
|
||||||
Vite target запрещает inline через `?no-inline`. Webpack 5 target использует Asset Modules через `new URL(..., import.meta.url)`.
|
При стандартной конфигурации Vite, Webpack или Next.js каждый спрайт выпускается отдельным версионированным SVG-файлом.
|
||||||
|
|
||||||
## SpriteViewer
|
Пока набор иконок не меняется, браузер может использовать сохранённую копию независимо от обновлений JavaScript приложения.
|
||||||
|
|
||||||
`SpriteViewer` — React-компонент для просмотра generated-спрайтов внутри debug-маршрута приложения.
|
Изменение React-компонентов не требует повторно загружать геометрию всех иконок.
|
||||||
|
|
||||||
Он использует отдельные манифесты и показывает:
|
## JavaScript без SVG-балласта
|
||||||
|
|
||||||
- группы спрайтов;
|
Контуры иконок остаются во внешних SVG assets и не увеличивают chunks приложения.
|
||||||
- список и количество иконок;
|
|
||||||
- поиск и системную светлую/тёмную тему;
|
|
||||||
- модальное превью с `viewBox` и настройкой цветовых переменных;
|
|
||||||
- примеры React, SVG, IMG и CSS с копированием кода.
|
|
||||||
|
|
||||||
Production-компоненты не импортируют debug-манифесты. Способ подключения Viewer зависит от сборщика:
|
```text
|
||||||
|
React-код → JavaScript chunks
|
||||||
- [React + Vite: автоматический `import.meta.glob`](docs/ru/react-vite.md#6-добавьте-debug-страницу);
|
SVG-иконки → отдельные SVG assets
|
||||||
- [React + Webpack 5: статические `import()`](docs/ru/react-webpack.md#6-добавьте-debug-страницу);
|
|
||||||
- [Next.js App Router](docs/ru/next-app.md#5-добавьте-spriteviewer);
|
|
||||||
- [Next.js Pages Router](docs/ru/next-pages.md#5-добавьте-spriteviewer).
|
|
||||||
|
|
||||||
Viewer подключается из отдельной клиентской точки входа `@gromlab/svg-sprites/react` и не попадает в production-компоненты иконок.
|
|
||||||
|
|
||||||
### Тема Viewer
|
|
||||||
|
|
||||||
По умолчанию `colorTheme="auto"`: Viewer следует `prefers-color-scheme` и реагирует на смену системной темы. Тему приложения можно передать явно:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
<SpriteViewer sources={sources} colorTheme="dark" />
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Допустимые значения `colorTheme`: `auto`, `light`, `dark`. При управлении темой извне встроенный переключатель скрывается. Чтобы оставить его и обновлять тему приложения через Viewer, передайте callback:
|
JavaScript отвечает за интерфейс и поведение, а графика загружается и кешируется отдельно.
|
||||||
|
|
||||||
|
## Трансформации SVG из коробки
|
||||||
|
|
||||||
|
Во время генерации пакет автоматически подготавливает исходные SVG для интерфейса:
|
||||||
|
|
||||||
|
- удаляет фиксированные `width` и `height`;
|
||||||
|
- сохраняет существующий `viewBox`;
|
||||||
|
- преобразует `fill` и `stroke` в CSS-переменные;
|
||||||
|
- добавляет плавные transitions непосредственно в цветные элементы иконки.
|
||||||
|
|
||||||
|
Каждую трансформацию можно настроить или отключить независимо.
|
||||||
|
|
||||||
|
## Каждый цвет под контролем CSS
|
||||||
|
|
||||||
|
При генерации цвета `fill` и `stroke` автоматически преобразуются в CSS-переменные `--icon-color-N`.
|
||||||
|
|
||||||
|
Монохромная иконка наследует `currentColor`:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
<SpriteViewer
|
<AppIcon icon="search" color="rebeccapurple" />
|
||||||
sources={sources}
|
```
|
||||||
colorTheme={appTheme}
|
|
||||||
onColorThemeChange={setAppTheme}
|
В многоцветной иконке каждый цвет можно менять отдельно:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<AppIcon
|
||||||
|
icon="user"
|
||||||
|
style={{
|
||||||
|
'--icon-color-1': '#2563eb',
|
||||||
|
'--icon-color-2': '#dbeafe',
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Темы, состояния и hover-эффекты создаются без редактирования SVG и дополнительных копий иконки.
|
||||||
|
|
||||||
|
## SpriteViewer: все спрайты на одной debug-странице
|
||||||
|
|
||||||
|
`SpriteViewer` рендерит спрайты всех поддерживаемых exact modes в одном месте. Один Web Component отвечает за визуал, а для React также доступен тонкий bridge к нему.
|
||||||
|
|
||||||
|
Для каждой иконки видны созданные CSS-переменные и их fallback-цвета. Значения можно менять прямо в Viewer и сразу наблюдать результат.
|
||||||
|
|
||||||
|
Здесь же доступны готовые примеры для framework из manifest, `<svg><use>`, `<img>` и CSS.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Viewer подключается только к внутренней debug-странице и не становится частью generated-компонентов иконок.
|
||||||
|
|
||||||
|
Bare standalone подключает Viewer через browser script и HTML element. Bundler и framework modes используют npm entry Web Component; React и Next.js также могут импортировать bridge из `@gromlab/svg-sprites/react`.
|
||||||
|
|
||||||
|
## 29 exact modes
|
||||||
|
|
||||||
|
Пакет предоставляет изолированные контракты для standalone, React, Next.js, Vue, Nuxt, Svelte, SvelteKit, Angular, Astro, Solid, SolidStart, Preact, Qwik, Lit и Alpine.js в поддерживаемых вариантах Vite, Webpack, Turbopack и application builder.
|
||||||
|
|
||||||
|
## Чистый Git
|
||||||
|
|
||||||
|
Bundler и framework modes создают локальный `.gitignore`, который исключает generated-файлы и не позволяет им засорять историю, pull requests и код проекта. Bare `standalone` оставляет политику репозитория приложению.
|
||||||
|
|
||||||
|
В bundler и framework modes в репозитории остаются исходные SVG, конфигурация и правило `.gitignore`, а локально и в CI спрайты, компоненты и типы заново создаются через `prebuild`.
|
||||||
|
|
||||||
|
## В production только иконки
|
||||||
|
|
||||||
|
Генерация полностью работает через `npx`, без добавления package в проект. Устанавливайте его как development dependency, только если нужны Viewer, типы конфига или программный API.
|
||||||
|
|
||||||
|
Production-компоненты используют только локальный generated-код, стили и внешний SVG-файл. Compiler и CLI не попадают в клиентское приложение, а `SpriteViewer` подключается отдельно только там, где нужна debug-страница.
|
||||||
|
|
||||||
## Документация
|
## Документация
|
||||||
|
|
||||||
- [React + Vite](docs/ru/react-vite.md)
|
README знакомит с возможностями проекта и показывает основной сценарий использования. Для настройки выберите руководство под свой стек.
|
||||||
- [React + Webpack 5](docs/ru/react-webpack.md)
|
|
||||||
- [Next.js App Router](docs/ru/next-app.md)
|
### Быстрый старт
|
||||||
- [Next.js Pages Router](docs/ru/next-pages.md)
|
|
||||||
- [Legacy mode](docs/ru/legacy.md)
|
- [Bare standalone](docs/ru/guides/standalone.md)
|
||||||
- [Миграция с 0.1.x](docs/ru/migration-1.md)
|
- [Standalone + Vite](docs/ru/guides/standalone-vite.md)
|
||||||
- [Программный API](docs/ru/programmatic-api.md)
|
- [Standalone + Webpack 5](docs/ru/guides/standalone-webpack.md)
|
||||||
|
- [React + Vite](docs/ru/guides/react-vite.md)
|
||||||
|
- [React + Webpack 5](docs/ru/guides/react-webpack.md)
|
||||||
|
- [Vue + Vite](docs/ru/guides/vue-vite.md)
|
||||||
|
- [Vue + Webpack](docs/ru/guides/vue-webpack.md)
|
||||||
|
- [Nuxt + Vite](docs/ru/guides/nuxt-vite.md)
|
||||||
|
- [Nuxt + Webpack](docs/ru/guides/nuxt-webpack.md)
|
||||||
|
- [Svelte + Vite](docs/ru/guides/svelte-vite.md)
|
||||||
|
- [Svelte + Webpack](docs/ru/guides/svelte-webpack.md)
|
||||||
|
- [SvelteKit + Vite](docs/ru/guides/sveltekit-vite.md)
|
||||||
|
- [Angular application builder](docs/ru/guides/angular-application.md)
|
||||||
|
- [Angular + Webpack](docs/ru/guides/angular-webpack.md)
|
||||||
|
- [Astro + Vite](docs/ru/guides/astro-vite.md)
|
||||||
|
- [Solid + Vite](docs/ru/guides/solid-vite.md)
|
||||||
|
- [Solid + Webpack](docs/ru/guides/solid-webpack.md)
|
||||||
|
- [SolidStart + Vite](docs/ru/guides/solid-start-vite.md)
|
||||||
|
- [Preact + Vite](docs/ru/guides/preact-vite.md)
|
||||||
|
- [Preact + Webpack](docs/ru/guides/preact-webpack.md)
|
||||||
|
- [Qwik + Vite](docs/ru/guides/qwik-vite.md)
|
||||||
|
- [Lit + Vite](docs/ru/guides/lit-vite.md)
|
||||||
|
- [Lit + Webpack](docs/ru/guides/lit-webpack.md)
|
||||||
|
- [Alpine.js + Vite](docs/ru/guides/alpine-vite.md)
|
||||||
|
- [Alpine.js + Webpack](docs/ru/guides/alpine-webpack.md)
|
||||||
|
- [Next.js App Router + Turbopack](docs/ru/guides/next-app-turbopack.md)
|
||||||
|
- [Next.js App Router + Webpack](docs/ru/guides/next-app-webpack.md)
|
||||||
|
- [Next.js Pages Router + Turbopack](docs/ru/guides/next-pages-turbopack.md)
|
||||||
|
- [Next.js Pages Router + Webpack](docs/ru/guides/next-pages-webpack.md)
|
||||||
|
|
||||||
|
### Технические материалы
|
||||||
|
|
||||||
|
- [Индекс документации](docs/ru/README.md)
|
||||||
|
- [Конфигурация](docs/ru/configuration.md)
|
||||||
|
- [Технический справочник](docs/ru/reference/technical.md)
|
||||||
|
- [Программный API](docs/ru/reference/programmatic-api.md)
|
||||||
|
|
||||||
## Лицензия
|
## Лицензия
|
||||||
|
|
||||||
|
|||||||
@@ -1,58 +1,41 @@
|
|||||||
# Third-Party Notices
|
# Third-Party Notices
|
||||||
|
|
||||||
The distributed React entry and preview template include code from the projects listed below.
|
The distributed Viewer browser bundle includes code from the projects listed below.
|
||||||
|
|
||||||
## React, React DOM and Scheduler
|
## Lit
|
||||||
|
|
||||||
Copyright (c) Meta Platforms, Inc. and affiliates.
|
Copyright (c) 2017 Google LLC. All rights reserved.
|
||||||
|
|
||||||
MIT License
|
BSD 3-Clause License
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Redistribution and use in source and binary forms, with or without
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
modification, are permitted provided that the following conditions are met:
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
1. Redistributions of source code must retain the above copyright notice, this
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
list of conditions and the following disclaimer.
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
The above copyright notice and this permission notice shall be included in all
|
this list of conditions and the following disclaimer in the documentation
|
||||||
copies or substantial portions of the Software.
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
3. Neither the name of the copyright holder nor the names of its
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
contributors may be used to endorse or promote products derived from
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
this software without specific prior written permission.
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
SOFTWARE.
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
## react-colorful
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
Copyright (c) 2020 Vlad Shilov <omgovich@ya.ru>
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
MIT License
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
## vanilla-colorful
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
Copyright (c) 2020 Serhii Kulykov <iamkulykov@gmail.com>
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
|
|
||||||
## clsx
|
|
||||||
|
|
||||||
Copyright (c) Luke Edwards <luke.edwards05@gmail.com> (lukeed.com)
|
|
||||||
|
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
|
|||||||
52
docs/en/README.md
Normal file
52
docs/en/README.md
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
# Documentation
|
||||||
|
|
||||||
|
Choose one exact mode guide for setup. The guides are standalone documents and
|
||||||
|
can also be used unchanged by AI skills.
|
||||||
|
|
||||||
|
The common format for JSON, JavaScript, and TypeScript config files is described in the [configuration guide](configuration.md).
|
||||||
|
|
||||||
|
## Quick Start Guides
|
||||||
|
|
||||||
|
| Project | Exact mode | Guide |
|
||||||
|
|---|---|---|
|
||||||
|
| Static HTML or custom publishing | `standalone` | [Bare standalone](guides/standalone.md) |
|
||||||
|
| Vanilla + Vite | `standalone@vite` | [Standalone + Vite](guides/standalone-vite.md) |
|
||||||
|
| Vanilla + Webpack 5 | `standalone@webpack` | [Standalone + Webpack](guides/standalone-webpack.md) |
|
||||||
|
| React + Vite | `react@vite` | [React + Vite](guides/react-vite.md) |
|
||||||
|
| React + Webpack 5 | `react@webpack` | [React + Webpack](guides/react-webpack.md) |
|
||||||
|
| Vue + Vite | `vue@vite` | [Vue + Vite](guides/vue-vite.md) |
|
||||||
|
| Vue + Webpack | `vue@webpack` | [Vue + Webpack](guides/vue-webpack.md) |
|
||||||
|
| Nuxt + Vite | `nuxt@vite` | [Nuxt + Vite](guides/nuxt-vite.md) |
|
||||||
|
| Nuxt + Webpack | `nuxt@webpack` | [Nuxt + Webpack](guides/nuxt-webpack.md) |
|
||||||
|
| Svelte + Vite | `svelte@vite` | [Svelte + Vite](guides/svelte-vite.md) |
|
||||||
|
| Svelte + Webpack | `svelte@webpack` | [Svelte + Webpack](guides/svelte-webpack.md) |
|
||||||
|
| SvelteKit + Vite | `sveltekit@vite` | [SvelteKit + Vite](guides/sveltekit-vite.md) |
|
||||||
|
| Angular application builder | `angular@application` | [Angular application builder](guides/angular-application.md) |
|
||||||
|
| Angular + Webpack | `angular@webpack` | [Angular + Webpack](guides/angular-webpack.md) |
|
||||||
|
| Astro + Vite | `astro@vite` | [Astro + Vite](guides/astro-vite.md) |
|
||||||
|
| Solid + Vite | `solid@vite` | [Solid + Vite](guides/solid-vite.md) |
|
||||||
|
| Solid + Webpack | `solid@webpack` | [Solid + Webpack](guides/solid-webpack.md) |
|
||||||
|
| SolidStart + Vite | `solid-start@vite` | [SolidStart + Vite](guides/solid-start-vite.md) |
|
||||||
|
| Preact + Vite | `preact@vite` | [Preact + Vite](guides/preact-vite.md) |
|
||||||
|
| Preact + Webpack | `preact@webpack` | [Preact + Webpack](guides/preact-webpack.md) |
|
||||||
|
| Qwik + Vite | `qwik@vite` | [Qwik + Vite](guides/qwik-vite.md) |
|
||||||
|
| Lit + Vite | `lit@vite` | [Lit + Vite](guides/lit-vite.md) |
|
||||||
|
| Lit + Webpack | `lit@webpack` | [Lit + Webpack](guides/lit-webpack.md) |
|
||||||
|
| Alpine.js + Vite | `alpine@vite` | [Alpine.js + Vite](guides/alpine-vite.md) |
|
||||||
|
| Alpine.js + Webpack | `alpine@webpack` | [Alpine.js + Webpack](guides/alpine-webpack.md) |
|
||||||
|
| Next.js App Router + Turbopack | `next@app/turbopack` | [App Router + Turbopack](guides/next-app-turbopack.md) |
|
||||||
|
| Next.js App Router + Webpack | `next@app/webpack` | [App Router + Webpack](guides/next-app-webpack.md) |
|
||||||
|
| Next.js Pages Router + Turbopack | `next@pages/turbopack` | [Pages Router + Turbopack](guides/next-pages-turbopack.md) |
|
||||||
|
| Next.js Pages Router + Webpack | `next@pages/webpack` | [Pages Router + Webpack](guides/next-pages-webpack.md) |
|
||||||
|
|
||||||
|
Every guide follows the same order:
|
||||||
|
|
||||||
|
1. Generate the sprite through `npx` without adding the package to the project.
|
||||||
|
2. Use the sprite in the application.
|
||||||
|
3. Optionally add the Viewer for debugging and previews.
|
||||||
|
|
||||||
|
## Reference
|
||||||
|
|
||||||
|
- [Configuration](configuration.md)
|
||||||
|
- [Technical reference](reference/technical.md)
|
||||||
|
- [Programmatic API](reference/programmatic-api.md)
|
||||||
99
docs/en/configuration.md
Normal file
99
docs/en/configuration.md
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
# Configuration
|
||||||
|
|
||||||
|
Each config file describes one independent sprite. The CLI does not discover config files automatically, so always pass the path explicitly:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx --yes @gromlab/svg-sprites path/to/svg-sprite.config.json
|
||||||
|
```
|
||||||
|
|
||||||
|
## JSON
|
||||||
|
|
||||||
|
JSON works for most projects and does not require installing the package locally:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "next@app/turbopack",
|
||||||
|
"name": "app",
|
||||||
|
"description": "Shared application icons",
|
||||||
|
"input": [
|
||||||
|
"./icons",
|
||||||
|
"../../assets/icons/**/*.svg",
|
||||||
|
"!../../assets/icons/deprecated-*.svg"
|
||||||
|
],
|
||||||
|
"transform": {
|
||||||
|
"removeSize": true,
|
||||||
|
"replaceColors": true,
|
||||||
|
"addTransition": true
|
||||||
|
},
|
||||||
|
"generatedNotice": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| Field | Default | Purpose |
|
||||||
|
|---|---|---|
|
||||||
|
| `mode` | None | Exact mode matching the framework and bundler |
|
||||||
|
| `name` | Kebab-case module directory name; for `svg-sprite` and `svg-sprites`, the parent directory name | Sprite name; in modes with a component, it also determines the component and type names |
|
||||||
|
| `description` | None | Description used in types and the Viewer |
|
||||||
|
| `input` | `./icons` | Directory, SVG file, glob pattern, or array of sources |
|
||||||
|
| `transform` | All enabled | SVG preparation options |
|
||||||
|
| `generatedNotice` | `true` | Full or compact warning in generated files |
|
||||||
|
|
||||||
|
Paths and glob patterns in `input` are resolved relative to the config file's directory. A pattern prefixed with `!` excludes matches.
|
||||||
|
|
||||||
|
## JavaScript
|
||||||
|
|
||||||
|
A JavaScript config default-exports a plain object:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default {
|
||||||
|
mode: 'react@vite',
|
||||||
|
name: 'icons',
|
||||||
|
input: './icons',
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Pass the path to the `.js` file to the CLI just like a JSON file:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx --yes @gromlab/svg-sprites path/to/svg-sprite.config.js
|
||||||
|
```
|
||||||
|
|
||||||
|
## TypeScript
|
||||||
|
|
||||||
|
To type-check a TypeScript config, install the package as a development dependency:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Use `defineSpriteConfig`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { defineSpriteConfig } from '@gromlab/svg-sprites'
|
||||||
|
|
||||||
|
export default defineSpriteConfig({
|
||||||
|
mode: 'react@vite',
|
||||||
|
name: 'icons',
|
||||||
|
input: './icons',
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternatively, use `satisfies` with a type-only import:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import type { SpriteConfig } from '@gromlab/svg-sprites'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mode: 'react@vite',
|
||||||
|
name: 'icons',
|
||||||
|
input: './icons',
|
||||||
|
} satisfies SpriteConfig
|
||||||
|
```
|
||||||
|
|
||||||
|
The CLI loads `.ts` config files directly:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx --yes @gromlab/svg-sprites path/to/svg-sprite.config.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
For the complete list of modes, CLI flags, naming rules, and transform options, see the [technical reference](reference/technical.md).
|
||||||
31
docs/en/guides/README.md
Normal file
31
docs/en/guides/README.md
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# Quick Start Guides
|
||||||
|
|
||||||
|
- `standalone`: [bare standalone](standalone.md)
|
||||||
|
- `standalone@vite`: [standalone with Vite](standalone-vite.md)
|
||||||
|
- `standalone@webpack`: [standalone with Webpack](standalone-webpack.md)
|
||||||
|
- `react@vite`: [React with Vite](react-vite.md)
|
||||||
|
- `react@webpack`: [React with Webpack](react-webpack.md)
|
||||||
|
- `vue@vite`: [Vue with Vite](vue-vite.md)
|
||||||
|
- `vue@webpack`: [Vue with Webpack](vue-webpack.md)
|
||||||
|
- `nuxt@vite`: [Nuxt with Vite](nuxt-vite.md)
|
||||||
|
- `nuxt@webpack`: [Nuxt with Webpack](nuxt-webpack.md)
|
||||||
|
- `svelte@vite`: [Svelte with Vite](svelte-vite.md)
|
||||||
|
- `svelte@webpack`: [Svelte with Webpack](svelte-webpack.md)
|
||||||
|
- `sveltekit@vite`: [SvelteKit with Vite](sveltekit-vite.md)
|
||||||
|
- `angular@application`: [Angular application builder](angular-application.md)
|
||||||
|
- `angular@webpack`: [Angular with Webpack](angular-webpack.md)
|
||||||
|
- `astro@vite`: [Astro with Vite](astro-vite.md)
|
||||||
|
- `solid@vite`: [Solid with Vite](solid-vite.md)
|
||||||
|
- `solid@webpack`: [Solid with Webpack](solid-webpack.md)
|
||||||
|
- `solid-start@vite`: [SolidStart with Vite](solid-start-vite.md)
|
||||||
|
- `preact@vite`: [Preact with Vite](preact-vite.md)
|
||||||
|
- `preact@webpack`: [Preact with Webpack](preact-webpack.md)
|
||||||
|
- `qwik@vite`: [Qwik with Vite](qwik-vite.md)
|
||||||
|
- `lit@vite`: [Lit with Vite](lit-vite.md)
|
||||||
|
- `lit@webpack`: [Lit with Webpack](lit-webpack.md)
|
||||||
|
- `alpine@vite`: [Alpine.js with Vite](alpine-vite.md)
|
||||||
|
- `alpine@webpack`: [Alpine.js with Webpack](alpine-webpack.md)
|
||||||
|
- `next@app/turbopack`: [App Router with Turbopack](next-app-turbopack.md)
|
||||||
|
- `next@app/webpack`: [App Router with Webpack](next-app-webpack.md)
|
||||||
|
- `next@pages/turbopack`: [Pages Router with Turbopack](next-pages-turbopack.md)
|
||||||
|
- `next@pages/webpack`: [Pages Router with Webpack](next-pages-webpack.md)
|
||||||
91
docs/en/guides/alpine-vite.md
Normal file
91
docs/en/guides/alpine-vite.md
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
# SVG Sprite for Alpine.js with Vite
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in an Alpine.js application built with Vite.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "alpine@vite",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The generator does not need to be added to the application dependencies: run it through `npx`.
|
||||||
|
|
||||||
|
Add generation before development and production builds:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "vite",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "vite build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
The value `name: "app"` creates the Alpine plugin `appAlpinePlugin`, the `x-app-icon` directive, and the `$appIconHref` magic.
|
||||||
|
|
||||||
|
Create `assets/app-icons/index.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Register the generated plugin before starting Alpine:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import Alpine from 'alpinejs'
|
||||||
|
import { appAlpinePlugin } from '../assets/app-icons/index.js'
|
||||||
|
|
||||||
|
Alpine.plugin(appAlpinePlugin)
|
||||||
|
Alpine.start()
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the reactive directive on an SVG element:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<svg
|
||||||
|
x-data="{ iconName: 'icon-name' }"
|
||||||
|
x-app-icon="iconName"
|
||||||
|
role="img"
|
||||||
|
aria-label="Done"
|
||||||
|
style="width:24px;height:24px;color:#334155;--icon-color-2:#f59e0b"
|
||||||
|
></svg>
|
||||||
|
```
|
||||||
|
|
||||||
|
The directive expression resolves to a source SVG file name without the extension. A monochrome icon inherits `color`; override multicolor icon layers with `--icon-color-N`. Vite loads the generated CSS and emits `sprite.svg` as a separate production asset.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Viewer displays all icons on one page and is only needed during development. Install it separately:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Add Viewer to a development page:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<gromlab-sprite-viewer viewer-title="Project icons"></gromlab-sprite-viewer>
|
||||||
|
<script type="module" src="/src/svg-sprite-debug.js"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
Create `src/svg-sprite-debug.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
import spriteManifest from '../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
|
||||||
|
document.querySelector('gromlab-sprite-viewer').sources = [spriteManifest]
|
||||||
|
```
|
||||||
|
|
||||||
|
Run `npm run dev` and open the development page. Viewer is independent from the Alpine plugin.
|
||||||
103
docs/en/guides/alpine-webpack.md
Normal file
103
docs/en/guides/alpine-webpack.md
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
# SVG Sprite for Alpine.js with Webpack 5
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in an Alpine.js application built with Webpack 5.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "alpine@webpack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The generator does not need to be added to the application dependencies: run it through `npx`.
|
||||||
|
|
||||||
|
Add generation before development and production builds:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "webpack serve --mode development",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "webpack --mode production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
The value `name: "app"` creates the Alpine plugin `appAlpinePlugin`, the `x-app-icon` directive, and the `$appIconHref` magic.
|
||||||
|
|
||||||
|
Generated Alpine CSS is imported with the `?inline` query. Add an Asset Module rule to `webpack.config.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default {
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.css$/,
|
||||||
|
resourceQuery: /inline/,
|
||||||
|
type: 'asset/source',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Create `assets/app-icons/index.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Register the generated plugin before starting Alpine:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import Alpine from 'alpinejs'
|
||||||
|
import { appAlpinePlugin } from '../assets/app-icons/index.js'
|
||||||
|
|
||||||
|
Alpine.plugin(appAlpinePlugin)
|
||||||
|
Alpine.start()
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the reactive directive on an SVG element:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<svg
|
||||||
|
x-data="{ iconName: 'icon-name' }"
|
||||||
|
x-app-icon="iconName"
|
||||||
|
role="img"
|
||||||
|
aria-label="Done"
|
||||||
|
style="width:24px;height:24px;color:#334155;--icon-color-2:#f59e0b"
|
||||||
|
></svg>
|
||||||
|
```
|
||||||
|
|
||||||
|
The directive expression resolves to a source SVG file name without the extension. A monochrome icon inherits `color`; override multicolor icon layers with `--icon-color-N`. Webpack 5 emits `sprite.svg` as a separate production asset.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Viewer displays all icons on one page and is only needed during development. Install it separately:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Add Viewer to a development entry:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
import spriteManifest from '../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
|
||||||
|
const viewer = document.createElement('gromlab-sprite-viewer')
|
||||||
|
viewer.viewerTitle = 'Project icons'
|
||||||
|
viewer.sources = [spriteManifest]
|
||||||
|
document.body.append(viewer)
|
||||||
|
```
|
||||||
|
|
||||||
|
Include this entry only in development. Viewer is independent from the Alpine plugin.
|
||||||
94
docs/en/guides/angular-application.md
Normal file
94
docs/en/guides/angular-application.md
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
# SVG Sprite for Angular with the Application Builder
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in an Angular application built with `@angular/build:application`.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "angular@application",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The package does not need to be a project dependency. Run generation through `npx` before development and production builds:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"prestart": "npm run sprites",
|
||||||
|
"start": "ng serve",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "ng build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The application builder emits imported SVG files when its file loader is enabled. Add this option to the build target in `angular.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"builder": "@angular/build:application",
|
||||||
|
"options": {
|
||||||
|
"loader": { ".svg": "file" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
Create `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index'
|
||||||
|
```
|
||||||
|
|
||||||
|
Import the generated standalone component. The value `name: "app"` creates `AppIcon` and the selector `app-icon`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { Component } from '@angular/core'
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-root',
|
||||||
|
standalone: true,
|
||||||
|
imports: [AppIcon],
|
||||||
|
template: `
|
||||||
|
<app-icon
|
||||||
|
icon="icon-name"
|
||||||
|
role="img"
|
||||||
|
aria-label="Done"
|
||||||
|
style="width: 24px; height: 24px; color: #334155; --icon-color-2: #f59e0b"
|
||||||
|
/>
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
export class AppComponent {}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `icon` input is typed from source file names. Monochrome icons inherit `color`; use `--icon-color-N` for individual colors.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Viewer is optional and only needed during development:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Import `@gromlab/svg-sprites/viewer/element`, add `CUSTOM_ELEMENTS_SCHEMA`, and place `<gromlab-sprite-viewer [sources]="viewerSources" />` in the template. Load the generated manifest while omitting framework-only usage metadata:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
readonly viewerSources = [async () => {
|
||||||
|
const { default: manifest } = await import(
|
||||||
|
'../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
)
|
||||||
|
const { usage: _usage, ...viewerManifest } = manifest
|
||||||
|
return viewerManifest
|
||||||
|
}]
|
||||||
|
```
|
||||||
|
|
||||||
|
The Viewer uses the same production sprite URL as `AppIcon`.
|
||||||
93
docs/en/guides/angular-webpack.md
Normal file
93
docs/en/guides/angular-webpack.md
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
# SVG Sprite for Angular with Webpack
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in an Angular application built by the Webpack-based Angular CLI browser builder.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "angular@webpack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This mode is for a workspace whose build target uses the official Webpack builder:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"builder": "@angular-devkit/build-angular:browser"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The package does not need to be a project dependency. Generate the sprite through `npx` before each start and build:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"prestart": "npm run sprites",
|
||||||
|
"start": "ng serve",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "ng build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Webpack resolves the generated `new URL(..., import.meta.url)` expression and emits `sprite.svg` as a production asset.
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
Create `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index'
|
||||||
|
```
|
||||||
|
|
||||||
|
Import the generated standalone component. The value `name: "app"` creates `AppIcon` and the selector `app-icon`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { Component } from '@angular/core'
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-root',
|
||||||
|
standalone: true,
|
||||||
|
imports: [AppIcon],
|
||||||
|
template: `
|
||||||
|
<app-icon
|
||||||
|
icon="icon-name"
|
||||||
|
role="img"
|
||||||
|
aria-label="Done"
|
||||||
|
style="width: 24px; height: 24px; color: #334155; --icon-color-2: #f59e0b"
|
||||||
|
/>
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
export class AppComponent {}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `icon` input is typed from source file names. Monochrome icons inherit `color`; use `--icon-color-N` for individual colors.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Viewer is optional and only needed during development:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Import `@gromlab/svg-sprites/viewer/element`, add `CUSTOM_ELEMENTS_SCHEMA`, and place `<gromlab-sprite-viewer [sources]="viewerSources" />` in the template:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
readonly viewerSources = [async () => {
|
||||||
|
const { default: manifest } = await import(
|
||||||
|
'../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
)
|
||||||
|
const { usage: _usage, ...viewerManifest } = manifest
|
||||||
|
return viewerManifest
|
||||||
|
}]
|
||||||
|
```
|
||||||
|
|
||||||
|
The Viewer and `AppIcon` share the Webpack-emitted sprite URL.
|
||||||
92
docs/en/guides/astro-vite.md
Normal file
92
docs/en/guides/astro-vite.md
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
# SVG Sprite for Astro with Vite
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in an Astro application built with Vite.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "astro@vite",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The package does not need to be a project dependency. Generate the sprite through `npx` before development and production builds:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "astro dev",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "astro check && astro build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
Create `assets/app-icons/index.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Create `assets/app-icons/index.d.ts` for the same typed API:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
The value `name: "app"` creates the native Astro component `AppIcon`. Use it in a page:
|
||||||
|
|
||||||
|
```astro
|
||||||
|
---
|
||||||
|
import { AppIcon } from '../../assets/app-icons/index.js'
|
||||||
|
---
|
||||||
|
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
role="img"
|
||||||
|
aria-label="Done"
|
||||||
|
style="color: #334155; --icon-color-2: #f59e0b"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
The `icon` prop is typed from source file names. Vite emits `sprite.svg` from the component's static asset import.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Viewer is optional and only needed during development:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Add the Viewer to the page and connect the generated manifest in a client script:
|
||||||
|
|
||||||
|
```astro
|
||||||
|
<gromlab-sprite-viewer id="sprite-viewer"></gromlab-sprite-viewer>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
||||||
|
|
||||||
|
const viewer = document.querySelector<SpriteViewerElement>('#sprite-viewer')!
|
||||||
|
viewer.sources = [async () => {
|
||||||
|
const { default: manifest } = await import(
|
||||||
|
'../../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
)
|
||||||
|
const { usage: _usage, ...viewerManifest } = manifest
|
||||||
|
return viewerManifest
|
||||||
|
}]
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
The manifest retains Astro usage metadata while Viewer renders the same production sprite.
|
||||||
86
docs/en/guides/lit-vite.md
Normal file
86
docs/en/guides/lit-vite.md
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
# SVG Sprite for Lit with Vite
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in a Lit application built with Vite.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "lit@vite",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The generator does not need to be added to the application dependencies: run it through `npx`.
|
||||||
|
|
||||||
|
Add generation before development and production builds:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "vite",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "vite build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
The value `name: "app"` creates the Lit class `AppIcon`, the `<app-icon>` tag, and the `defineAppIcon` registration function.
|
||||||
|
|
||||||
|
Create `assets/app-icons/index.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Register the component before rendering it:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { defineAppIcon } from '../assets/app-icons/index.js'
|
||||||
|
|
||||||
|
defineAppIcon()
|
||||||
|
|
||||||
|
document.querySelector('#app').innerHTML = `
|
||||||
|
<app-icon
|
||||||
|
icon="icon-name"
|
||||||
|
role="img"
|
||||||
|
aria-label="Done"
|
||||||
|
style="width:24px;height:24px;color:#334155;--icon-color-2:#f59e0b"
|
||||||
|
></app-icon>
|
||||||
|
`
|
||||||
|
```
|
||||||
|
|
||||||
|
The `icon` property accepts source SVG file names without the extension. A monochrome icon inherits `color`; override multicolor icon layers with `--icon-color-N`. Vite loads the component CSS and emits `sprite.svg` as a separate production asset.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Viewer displays all icons on one page and is only needed during development. Install it separately:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Add Viewer to a development page:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<gromlab-sprite-viewer viewer-title="Project icons"></gromlab-sprite-viewer>
|
||||||
|
<script type="module" src="/src/svg-sprite-debug.js"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
Create `src/svg-sprite-debug.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
import spriteManifest from '../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
|
||||||
|
document.querySelector('gromlab-sprite-viewer').sources = [spriteManifest]
|
||||||
|
```
|
||||||
|
|
||||||
|
Run `npm run dev` and open the development page. Viewer is not required by `AppIcon`.
|
||||||
98
docs/en/guides/lit-webpack.md
Normal file
98
docs/en/guides/lit-webpack.md
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
# SVG Sprite for Lit with Webpack 5
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in a Lit application built with Webpack 5.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "lit@webpack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The generator does not need to be added to the application dependencies: run it through `npx`.
|
||||||
|
|
||||||
|
Add generation before development and production builds:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "webpack serve --mode development",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "webpack --mode production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
The value `name: "app"` creates the Lit class `AppIcon`, the `<app-icon>` tag, and the `defineAppIcon` registration function.
|
||||||
|
|
||||||
|
Generated Lit CSS is imported with the `?inline` query. Add an Asset Module rule to `webpack.config.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default {
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.css$/,
|
||||||
|
resourceQuery: /inline/,
|
||||||
|
type: 'asset/source',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Create `assets/app-icons/index.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Register the component before rendering it:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { defineAppIcon } from '../assets/app-icons/index.js'
|
||||||
|
|
||||||
|
defineAppIcon()
|
||||||
|
|
||||||
|
document.querySelector('#app').innerHTML = `
|
||||||
|
<app-icon
|
||||||
|
icon="icon-name"
|
||||||
|
role="img"
|
||||||
|
aria-label="Done"
|
||||||
|
style="width:24px;height:24px;color:#334155;--icon-color-2:#f59e0b"
|
||||||
|
></app-icon>
|
||||||
|
`
|
||||||
|
```
|
||||||
|
|
||||||
|
The `icon` property accepts source SVG file names without the extension. A monochrome icon inherits `color`; override multicolor icon layers with `--icon-color-N`. Webpack 5 emits `sprite.svg` as a separate production asset.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Viewer displays all icons on one page and is only needed during development. Install it separately:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Add Viewer to a development entry:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
import spriteManifest from '../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
|
||||||
|
const viewer = document.createElement('gromlab-sprite-viewer')
|
||||||
|
viewer.viewerTitle = 'Project icons'
|
||||||
|
viewer.sources = [spriteManifest]
|
||||||
|
document.body.append(viewer)
|
||||||
|
```
|
||||||
|
|
||||||
|
Include this entry only in development. Viewer is not required by `AppIcon`.
|
||||||
108
docs/en/guides/next-app-turbopack.md
Normal file
108
docs/en/guides/next-app-turbopack.md
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
# SVG Sprite for Next.js App Router with Turbopack
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in a Next.js application using App Router and Turbopack.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
Example configuration:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "next@app/turbopack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The package does not need to be a project dependency: generation runs through `npx`.
|
||||||
|
|
||||||
|
Add generation commands to `package.json`. Generated files are excluded from Git by default, so `predev` and `prebuild` rebuild the sprite before every start and build:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "next dev --turbopack",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "next build --turbopack"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
The value `name: "app"` creates the React component `AppIcon`.
|
||||||
|
|
||||||
|
Create the entry point `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the component in a Server Component:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
// app/page.tsx
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
role="img"
|
||||||
|
aria-label="Done"
|
||||||
|
style={{
|
||||||
|
color: '#334155',
|
||||||
|
'--icon-color-2': '#f59e0b',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`AppIcon` does not need `'use client'`. Turbopack automatically adds `sprite.svg` to the production build, so you do not need to move it to `public`.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Viewer displays all icons on one page so you can check their rendering, change colors, and inspect the related CSS variables. It is only needed for development and is installed separately:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Create the Client Component `app/svg-sprite/SvgSpriteViewer.tsx`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
'use client'
|
||||||
|
|
||||||
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
|
||||||
|
const sources = [
|
||||||
|
() => import('../../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
] as const
|
||||||
|
|
||||||
|
export function SvgSpriteViewer() {
|
||||||
|
return <SpriteViewer sources={sources} title="Project icons" />
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Create the route `app/svg-sprite/page.tsx`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { notFound } from 'next/navigation'
|
||||||
|
|
||||||
|
import { SvgSpriteViewer } from './SvgSpriteViewer'
|
||||||
|
|
||||||
|
export default function SvgSpritePage() {
|
||||||
|
if (process.env.NODE_ENV !== 'development') notFound()
|
||||||
|
|
||||||
|
return <SvgSpriteViewer />
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Run `npm run dev` and open `/svg-sprite`. In production, the route returns 404.
|
||||||
108
docs/en/guides/next-app-webpack.md
Normal file
108
docs/en/guides/next-app-webpack.md
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
# SVG Sprite for Next.js App Router with Webpack
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in a Next.js application using App Router and Webpack.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
Example configuration:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "next@app/webpack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The package does not need to be a project dependency: generation runs through `npx`.
|
||||||
|
|
||||||
|
Add generation commands to `package.json`. Generated files are excluded from Git by default, so `predev` and `prebuild` rebuild the sprite before every start and build:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "next dev --webpack",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "next build --webpack"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
The value `name: "app"` creates the React component `AppIcon`.
|
||||||
|
|
||||||
|
Create the entry point `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the component in a Server Component:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
// app/page.tsx
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
role="img"
|
||||||
|
aria-label="Done"
|
||||||
|
style={{
|
||||||
|
color: '#334155',
|
||||||
|
'--icon-color-2': '#f59e0b',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`AppIcon` does not need `'use client'`. Next.js automatically adds `sprite.svg` to the production build, so you do not need to move it to `public`.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Viewer displays all icons on one page so you can check their rendering, change colors, and inspect the related CSS variables. It is only needed for development and is installed separately:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Create the Client Component `app/svg-sprite/SvgSpriteViewer.tsx`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
'use client'
|
||||||
|
|
||||||
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
|
||||||
|
const sources = [
|
||||||
|
() => import('../../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
] as const
|
||||||
|
|
||||||
|
export function SvgSpriteViewer() {
|
||||||
|
return <SpriteViewer sources={sources} title="Project icons" />
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Create the route `app/svg-sprite/page.tsx`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { notFound } from 'next/navigation'
|
||||||
|
|
||||||
|
import { SvgSpriteViewer } from './SvgSpriteViewer'
|
||||||
|
|
||||||
|
export default function SvgSpritePage() {
|
||||||
|
if (process.env.NODE_ENV !== 'development') notFound()
|
||||||
|
|
||||||
|
return <SvgSpriteViewer />
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Run `npm run dev` and open `/svg-sprite`. In production, the route returns 404.
|
||||||
98
docs/en/guides/next-pages-turbopack.md
Normal file
98
docs/en/guides/next-pages-turbopack.md
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
# SVG Sprite for Next.js Pages Router with Turbopack
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in a Next.js application using Pages Router and Turbopack.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
Example configuration:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "next@pages/turbopack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The package does not need to be a project dependency: generation runs through `npx`.
|
||||||
|
|
||||||
|
Add generation commands to `package.json`. Generated files are excluded from Git by default, so `predev` and `prebuild` rebuild the sprite before every start and build:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "next dev --turbopack",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "next build --turbopack"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
The value `name: "app"` creates the React component `AppIcon`.
|
||||||
|
|
||||||
|
Create the entry point `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the component on a page:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
// pages/index.tsx
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
role="img"
|
||||||
|
aria-label="Done"
|
||||||
|
style={{
|
||||||
|
color: '#334155',
|
||||||
|
'--icon-color-2': '#f59e0b',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The component works with SSR, SSG, and client-side navigation. Turbopack automatically adds `sprite.svg` to the production build, so you do not need to move it to `public`.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Viewer displays all icons on one page so you can check their rendering, change colors, and inspect the related CSS variables. It is only needed for development and is installed separately:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Create the page `pages/svg-sprite.tsx`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import type { GetStaticProps } from 'next'
|
||||||
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
|
||||||
|
const sources = [
|
||||||
|
() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
] as const
|
||||||
|
|
||||||
|
export default function SvgSpritePage() {
|
||||||
|
return <SpriteViewer sources={sources} title="Project icons" />
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getStaticProps: GetStaticProps = () =>
|
||||||
|
process.env.NODE_ENV === 'development'
|
||||||
|
? { props: {} }
|
||||||
|
: { notFound: true }
|
||||||
|
```
|
||||||
|
|
||||||
|
Run `npm run dev` and open `/svg-sprite`. In production, the route returns 404.
|
||||||
98
docs/en/guides/next-pages-webpack.md
Normal file
98
docs/en/guides/next-pages-webpack.md
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
# SVG Sprite for Next.js Pages Router with Webpack
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in a Next.js application using Pages Router and Webpack.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
Example configuration:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "next@pages/webpack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The package does not need to be a project dependency: generation runs through `npx`.
|
||||||
|
|
||||||
|
Add generation commands to `package.json`. Generated files are excluded from Git by default, so `predev` and `prebuild` rebuild the sprite before every start and build:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "next dev --webpack",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "next build --webpack"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
The value `name: "app"` creates the React component `AppIcon`.
|
||||||
|
|
||||||
|
Create the entry point `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the component on a page:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
// pages/index.tsx
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
role="img"
|
||||||
|
aria-label="Done"
|
||||||
|
style={{
|
||||||
|
color: '#334155',
|
||||||
|
'--icon-color-2': '#f59e0b',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The component works with SSR, SSG, and client-side navigation. Next.js automatically adds `sprite.svg` to the production build, so you do not need to move it to `public`.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Viewer displays all icons on one page so you can check their rendering, change colors, and inspect the related CSS variables. It is only needed for development and is installed separately:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Create the page `pages/svg-sprite.tsx`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import type { GetStaticProps } from 'next'
|
||||||
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
|
||||||
|
const sources = [
|
||||||
|
() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
] as const
|
||||||
|
|
||||||
|
export default function SvgSpritePage() {
|
||||||
|
return <SpriteViewer sources={sources} title="Project icons" />
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getStaticProps: GetStaticProps = () =>
|
||||||
|
process.env.NODE_ENV === 'development'
|
||||||
|
? { props: {} }
|
||||||
|
: { notFound: true }
|
||||||
|
```
|
||||||
|
|
||||||
|
Run `npm run dev` and open `/svg-sprite`. In production, the route returns 404.
|
||||||
100
docs/en/guides/nuxt-vite.md
Normal file
100
docs/en/guides/nuxt-vite.md
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
# SVG Sprite for Nuxt with Vite
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in a Nuxt application built with Vite.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
Example configuration:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "nuxt@vite",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The package does not need to be a project dependency: generation runs through `npx`.
|
||||||
|
|
||||||
|
Add generation commands to `package.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "nuxt dev",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "nuxt build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
The value `name: "app"` creates the Vue component `AppIcon`. Create `assets/app-icons/index.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the component in a Nuxt page or layout:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
import { AppIcon } from '../assets/app-icons/index.js'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
role="img"
|
||||||
|
aria-label="Done"
|
||||||
|
style="color: #334155; --icon-color-2: #f59e0b"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
`AppIcon` is SSR-safe and does not need a client-only wrapper. Vite emits `sprite.svg` as a separate production asset.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Viewer displays all icons on one page so you can check their rendering, change colors, and inspect the related CSS variables. It is only needed for development and is installed separately:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Create `app/components/SvgSpriteViewer.client.vue` so the browser-only Viewer is not evaluated during SSR:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
|
||||||
|
const sources = [
|
||||||
|
() => import('../../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
]
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<gromlab-sprite-viewer :sources="sources" viewer-title="Project icons" />
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
Mark `gromlab-sprite-viewer` as a custom element in `nuxt.config.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
vue: {
|
||||||
|
compilerOptions: {
|
||||||
|
isCustomElement: (tag) => tag === 'gromlab-sprite-viewer',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Render `<SvgSpriteViewer />` on your development page. Viewer is isolated from the generated `AppIcon` runtime.
|
||||||
113
docs/en/guides/nuxt-webpack.md
Normal file
113
docs/en/guides/nuxt-webpack.md
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
# SVG Sprite for Nuxt with Webpack
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in a Nuxt application built with Webpack.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
Example configuration:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "nuxt@webpack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The package does not need to be a project dependency: generation runs through `npx`.
|
||||||
|
|
||||||
|
Use the Nuxt Webpack builder in `nuxt.config.ts`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @nuxt/webpack-builder
|
||||||
|
```
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
builder: '@nuxt/webpack-builder',
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Add generation commands to `package.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "nuxt dev",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "nuxt build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
The value `name: "app"` creates the Vue component `AppIcon`. Create `assets/app-icons/index.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the component in a Nuxt page or layout:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
import { AppIcon } from '../assets/app-icons/index.js'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
role="img"
|
||||||
|
aria-label="Done"
|
||||||
|
style="color: #334155; --icon-color-2: #f59e0b"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
`AppIcon` is SSR-safe and does not need a client-only wrapper. Webpack emits `sprite.svg` as a separate production asset.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Viewer displays all icons on one page so you can check their rendering, change colors, and inspect the related CSS variables. It is only needed for development and is installed separately:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Create `app/components/SvgSpriteViewer.client.vue` so the browser-only Viewer is not evaluated during SSR:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
|
||||||
|
const sources = [
|
||||||
|
() => import('../../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
]
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<gromlab-sprite-viewer :sources="sources" viewer-title="Project icons" />
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
Extend the existing `nuxt.config.ts` settings so Vue treats the Viewer as a custom element:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
builder: '@nuxt/webpack-builder',
|
||||||
|
vue: {
|
||||||
|
compilerOptions: {
|
||||||
|
isCustomElement: (tag) => tag === 'gromlab-sprite-viewer',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Render `<SvgSpriteViewer />` on your development page. Viewer is isolated from the generated `AppIcon` runtime.
|
||||||
75
docs/en/guides/preact-vite.md
Normal file
75
docs/en/guides/preact-vite.md
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
# SVG Sprite for Preact with Vite
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in a Preact application built with Vite.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "preact@vite",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The package does not need to be a project dependency. Run it through `npx` before development and production builds:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "vite",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "tsc --noEmit && vite build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
Create `assets/app-icons/index.js` and `assets/app-icons/index.d.ts` with the same export:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the generated plain-JavaScript Preact component:
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
import { AppIcon } from '../assets/app-icons/index.js'
|
||||||
|
|
||||||
|
export function SaveIcon() {
|
||||||
|
return (
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
aria-label="Done"
|
||||||
|
style={{ color: '#334155', '--icon-color-2': '#f59e0b' }}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Vite automatically emits the imported `sprite.svg` as a production asset.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Install Viewer only for development:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Mount it from a debug entry:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
|
||||||
|
const viewer = document.createElement('gromlab-sprite-viewer')
|
||||||
|
viewer.sources = [() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js')]
|
||||||
|
document.body.append(viewer)
|
||||||
|
```
|
||||||
75
docs/en/guides/preact-webpack.md
Normal file
75
docs/en/guides/preact-webpack.md
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
# SVG Sprite for Preact with Webpack
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in a Preact application built with Webpack 5.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "preact@webpack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The package does not need to be a project dependency. Run it through `npx` before Webpack starts or builds:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "webpack serve --mode development",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "tsc --noEmit && webpack --mode production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
Create `assets/app-icons/index.js` and `assets/app-icons/index.d.ts` with the same export:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the generated Preact component:
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
import { AppIcon } from '../assets/app-icons/index.js'
|
||||||
|
|
||||||
|
export function SaveIcon() {
|
||||||
|
return (
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
aria-label="Done"
|
||||||
|
style={{ color: '#334155', '--icon-color-2': '#f59e0b' }}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Webpack Asset Modules emit `sprite.svg` from the generated `new URL(...)` expression.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Install Viewer only for development:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Mount it from a development-only entry:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
|
||||||
|
const viewer = document.createElement('gromlab-sprite-viewer')
|
||||||
|
viewer.sources = [() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js')]
|
||||||
|
document.body.append(viewer)
|
||||||
|
```
|
||||||
82
docs/en/guides/qwik-vite.md
Normal file
82
docs/en/guides/qwik-vite.md
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
# SVG Sprite for Qwik with Vite
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in an SSR Qwik application built with Vite.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "qwik@vite",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The package does not need to be a project dependency. Regenerate through `npx` before Vite starts or builds:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "vite --mode ssr",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "tsc --noEmit && vite build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
Create `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
The generated component is a Qwik `component$` and is safe during SSR:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { component$ } from '@builder.io/qwik'
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
|
export default component$(() => (
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
aria-label="Done"
|
||||||
|
style={{ color: '#334155', '--icon-color-2': '#f59e0b' }}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
```
|
||||||
|
|
||||||
|
The component uses a static Vite asset import and does not access browser globals during SSR.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Viewer is browser-only, optional development tooling:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Load it from a visible task:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { component$, useSignal, useVisibleTask$ } from '@builder.io/qwik'
|
||||||
|
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
||||||
|
|
||||||
|
export const IconViewer = component$(() => {
|
||||||
|
const host = useSignal<HTMLElement>()
|
||||||
|
useVisibleTask$(async () => {
|
||||||
|
await import('@gromlab/svg-sprites/viewer/element')
|
||||||
|
const viewer = document.createElement('gromlab-sprite-viewer') as SpriteViewerElement
|
||||||
|
viewer.sources = [() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js')]
|
||||||
|
host.value?.append(viewer)
|
||||||
|
})
|
||||||
|
return <div ref={host} />
|
||||||
|
})
|
||||||
|
```
|
||||||
115
docs/en/guides/react-vite.md
Normal file
115
docs/en/guides/react-vite.md
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
# SVG Sprite for React with Vite
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in a React application built with Vite.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
Example configuration:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "react@vite",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The package does not need to be a project dependency: generation runs through `npx`.
|
||||||
|
|
||||||
|
Add generation commands to `package.json`. Generated files are excluded from Git by default, so `predev` and `prebuild` rebuild the sprite before every start and build:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "vite",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "tsc --noEmit && vite build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
The value `name: "app"` creates the React component `AppIcon`.
|
||||||
|
|
||||||
|
Create the entry point `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the component in your application:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
|
export function SaveIcon() {
|
||||||
|
return (
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
role="img"
|
||||||
|
aria-label="Done"
|
||||||
|
style={{
|
||||||
|
color: '#334155',
|
||||||
|
'--icon-color-2': '#f59e0b',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `icon` prop accepts source SVG file names without the extension. A monochrome icon inherits `color`, while colors in a multicolor icon are overridden with `--icon-color-N`.
|
||||||
|
|
||||||
|
Vite automatically includes the component styles and adds `sprite.svg` to the production build.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Viewer displays all icons on one page so you can check their rendering, change colors, and inspect the related CSS variables. It is only needed for development and is installed separately:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Create `svg-sprite.html` in the project root:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Project icons</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- React root for debugging and previewing the SVG sprite in Viewer -->
|
||||||
|
<div id="svg-sprite-viewer"></div>
|
||||||
|
|
||||||
|
<!-- Load the debug script created below -->
|
||||||
|
<script type="module" src="/src/svg-sprite-debug.tsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
Create `src/svg-sprite-debug.tsx`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { createRoot } from 'react-dom/client'
|
||||||
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
|
||||||
|
const sources = [
|
||||||
|
() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
] as const
|
||||||
|
|
||||||
|
createRoot(document.getElementById('svg-sprite-viewer')!).render(
|
||||||
|
<SpriteViewer sources={sources} title="Project icons" />,
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Run `npm run dev` and open `/svg-sprite.html`.
|
||||||
|
|
||||||
|
The standard Vite production build uses only `index.html` and does not include the Viewer page.
|
||||||
132
docs/en/guides/react-webpack.md
Normal file
132
docs/en/guides/react-webpack.md
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
# SVG Sprite for React with Webpack 5
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in a React application built with Webpack 5.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
Example configuration:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "react@webpack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The package does not need to be a project dependency: generation runs through `npx`.
|
||||||
|
|
||||||
|
Add generation commands to `package.json`. Generated files are excluded from Git by default, so `predev` and `prebuild` rebuild the sprite before every start and build:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "webpack serve --mode development",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "webpack --mode production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
The value `name: "app"` creates the React component `AppIcon`.
|
||||||
|
|
||||||
|
Create the entry point `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the component in your application:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
|
export function SaveIcon() {
|
||||||
|
return (
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
role="img"
|
||||||
|
aria-label="Done"
|
||||||
|
style={{
|
||||||
|
color: '#334155',
|
||||||
|
'--icon-color-2': '#f59e0b',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `icon` prop accepts source SVG file names without the extension. A monochrome icon inherits `color`, while colors in a multicolor icon are overridden with `--icon-color-N`.
|
||||||
|
|
||||||
|
The component uses CSS Modules. If the project does not process them yet, install the loaders:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev style-loader css-loader
|
||||||
|
```
|
||||||
|
|
||||||
|
Then add a rule with a default export to `webpack.config.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
test: /\.module\.css$/i,
|
||||||
|
use: [
|
||||||
|
'style-loader',
|
||||||
|
{
|
||||||
|
loader: 'css-loader',
|
||||||
|
options: { modules: { namedExport: false } },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Webpack 5 automatically adds `sprite.svg` to the production build.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Viewer displays all icons on one page so you can check their rendering, change colors, and inspect the related CSS variables. It is only needed for development.
|
||||||
|
|
||||||
|
Install Viewer:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Create the entry `src/svg-sprite-debug.tsx`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { createRoot } from 'react-dom/client'
|
||||||
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
|
||||||
|
const sources = [
|
||||||
|
() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
] as const
|
||||||
|
|
||||||
|
const container = document.createElement('div')
|
||||||
|
document.body.append(container)
|
||||||
|
|
||||||
|
createRoot(container).render(
|
||||||
|
<SpriteViewer sources={sources} title="Project icons" />,
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Add the script to the main entry only in development mode. Keep the rest of your `webpack.config.js` settings:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default (_env, argv) => ({
|
||||||
|
// Other Webpack settings.
|
||||||
|
entry: [
|
||||||
|
'./src/main.tsx',
|
||||||
|
...(argv.mode === 'development' ? ['./src/svg-sprite-debug.tsx'] : []),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Run `npm run dev`. Viewer appears on the application's main page and is not included in the production build.
|
||||||
83
docs/en/guides/solid-start-vite.md
Normal file
83
docs/en/guides/solid-start-vite.md
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
# SVG Sprite for SolidStart with Vite
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in an SSR SolidStart application built with Vite.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "solid-start@vite",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The package does not need to be a project dependency. Regenerate through `npx` before Vinxi starts or builds:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "vinxi dev",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "vinxi build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
Create `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
The generated component is safe to render on the server:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
|
export default function Home() {
|
||||||
|
return (
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
aria-label="Done"
|
||||||
|
style={{ color: '#334155', '--icon-color-2': '#f59e0b' }}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The component uses a static Vite asset import and does not access browser globals during SSR.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Viewer is browser-only, optional development tooling:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Load it from `onMount` so it is excluded from server rendering:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { onMount } from 'solid-js'
|
||||||
|
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
||||||
|
|
||||||
|
export function IconViewer() {
|
||||||
|
let host!: HTMLDivElement
|
||||||
|
onMount(async () => {
|
||||||
|
await import('@gromlab/svg-sprites/viewer/element')
|
||||||
|
const viewer = document.createElement('gromlab-sprite-viewer') as SpriteViewerElement
|
||||||
|
viewer.sources = [() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js')]
|
||||||
|
host.append(viewer)
|
||||||
|
})
|
||||||
|
return <div ref={host} />
|
||||||
|
}
|
||||||
|
```
|
||||||
83
docs/en/guides/solid-vite.md
Normal file
83
docs/en/guides/solid-vite.md
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
# SVG Sprite for Solid with Vite
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in a Solid application built with Vite.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "solid@vite",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The package does not need to be a project dependency. Run it through `npx` and regenerate before development and production builds:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "vite",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "tsc --noEmit && vite build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
Create `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
The name `app` creates the Solid component `AppIcon`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
|
export function SaveIcon() {
|
||||||
|
return (
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
aria-label="Done"
|
||||||
|
style={{ color: '#334155', '--icon-color-2': '#f59e0b' }}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Vite emits `sprite.svg` as a production asset. Monochrome icons inherit `color`; multicolor icons use `--icon-color-N`.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Viewer is optional and only needed during development:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Mount it from a debug component after the browser is ready:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { onMount } from 'solid-js'
|
||||||
|
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
||||||
|
|
||||||
|
export function IconViewer() {
|
||||||
|
let host!: HTMLDivElement
|
||||||
|
onMount(async () => {
|
||||||
|
await import('@gromlab/svg-sprites/viewer/element')
|
||||||
|
const viewer = document.createElement('gromlab-sprite-viewer') as SpriteViewerElement
|
||||||
|
viewer.sources = [() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js')]
|
||||||
|
host.append(viewer)
|
||||||
|
})
|
||||||
|
return <div ref={host} />
|
||||||
|
}
|
||||||
|
```
|
||||||
75
docs/en/guides/solid-webpack.md
Normal file
75
docs/en/guides/solid-webpack.md
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
# SVG Sprite for Solid with Webpack
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in a Solid application built with Webpack 5.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "solid@webpack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The package does not need to be a project dependency. Run it through `npx` before Webpack starts or builds:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "webpack serve --mode development",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "tsc --noEmit && webpack --mode production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
Create `assets/app-icons/index.js` and `assets/app-icons/index.d.ts` with the same export:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the generated Solid component:
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
import { AppIcon } from '../assets/app-icons/index.js'
|
||||||
|
|
||||||
|
export function SaveIcon() {
|
||||||
|
return (
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
aria-label="Done"
|
||||||
|
style={{ color: '#334155', '--icon-color-2': '#f59e0b' }}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Webpack Asset Modules emit `sprite.svg` from the generated `new URL(...)`. Keep `.jsx` processing enabled for the generated Solid component.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Install Viewer only for development:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Add it to a development-only entry:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
|
||||||
|
const viewer = document.createElement('gromlab-sprite-viewer')
|
||||||
|
viewer.sources = [() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js')]
|
||||||
|
document.body.append(viewer)
|
||||||
|
```
|
||||||
114
docs/en/guides/standalone-vite.md
Normal file
114
docs/en/guides/standalone-vite.md
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
# SVG Sprite for Vite Without a Framework
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in a Vite application without a framework.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
Example configuration:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "standalone@vite",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The package does not need to be a project dependency: generation runs through `npx`.
|
||||||
|
|
||||||
|
Add generation commands to `package.json`. Generated files are excluded from Git by default, so `predev` and `prebuild` rebuild the sprite before every start and build:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "vite",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "vite build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
The value `name: "app"` creates the `<app-icon>` element.
|
||||||
|
|
||||||
|
Create the entry point `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Register the element in `src/main.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { defineAppIconElement } from '../assets/app-icons'
|
||||||
|
import './style.css'
|
||||||
|
|
||||||
|
defineAppIconElement()
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the icon in HTML:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<app-icon icon="icon-name" role="img" aria-label="Done"></app-icon>
|
||||||
|
```
|
||||||
|
|
||||||
|
The `icon` value is the source SVG filename without the extension. Set its size and colors with CSS:
|
||||||
|
|
||||||
|
```css
|
||||||
|
app-icon {
|
||||||
|
font-size: 24px;
|
||||||
|
color: #334155;
|
||||||
|
--icon-color-2: #f59e0b;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
A monochrome icon inherits `color`, while colors in a multicolor icon are overridden with `--icon-color-N`. Viewer shows the variables you need.
|
||||||
|
|
||||||
|
Vite automatically adds `sprite.svg` to the production build. You do not need to copy it to `public`.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Viewer displays all icons on one page so you can check their rendering, change colors, and inspect the related CSS variables. It is only needed for development and is installed separately:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Create `svg-sprite.html` in the project root:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Project icons</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- Viewer component for debugging and previewing the SVG sprite -->
|
||||||
|
<gromlab-sprite-viewer viewer-title="Project icons"></gromlab-sprite-viewer>
|
||||||
|
|
||||||
|
<!-- Load the debug script created below -->
|
||||||
|
<script type="module" src="/src/svg-sprite-debug.ts"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
Create `src/svg-sprite-debug.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
||||||
|
import spriteManifest from '../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
|
||||||
|
const viewer = document.querySelector<SpriteViewerElement>('gromlab-sprite-viewer')!
|
||||||
|
viewer.sources = [spriteManifest]
|
||||||
|
```
|
||||||
|
|
||||||
|
Run `npm run dev` and open `/svg-sprite.html`.
|
||||||
|
|
||||||
|
Viewer is not required for `<app-icon>` and is not imported by the application's main code.
|
||||||
111
docs/en/guides/standalone-webpack.md
Normal file
111
docs/en/guides/standalone-webpack.md
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
# SVG Sprite for Webpack 5 Without a Framework
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in a Webpack 5 application without a framework.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
Example configuration:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "standalone@webpack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The package does not need to be a project dependency: generation runs through `npx`.
|
||||||
|
|
||||||
|
Add generation commands to `package.json`. Generated files are excluded from Git by default, so `predev` and `prebuild` rebuild the sprite before every start and build:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "webpack serve --mode development",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "webpack --mode production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
The value `name: "app"` creates the `<app-icon>` element.
|
||||||
|
|
||||||
|
Create the entry point `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Register the element in the application's main entry:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { defineAppIconElement } from '../assets/app-icons'
|
||||||
|
import './style.css'
|
||||||
|
|
||||||
|
defineAppIconElement()
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the icon in HTML:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<app-icon icon="icon-name" role="img" aria-label="Done"></app-icon>
|
||||||
|
```
|
||||||
|
|
||||||
|
The `icon` value is the source SVG filename without the extension. Set its size and colors with CSS:
|
||||||
|
|
||||||
|
```css
|
||||||
|
app-icon {
|
||||||
|
font-size: 24px;
|
||||||
|
color: #334155;
|
||||||
|
--icon-color-2: #f59e0b;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
A monochrome icon inherits `color`, while colors in a multicolor icon are overridden with `--icon-color-N`. Viewer shows the variables you need.
|
||||||
|
|
||||||
|
Webpack 5 automatically adds `sprite.svg` to the production build.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Viewer displays all icons on one page so you can check their rendering, change colors, and inspect the related CSS variables. It is only needed for development.
|
||||||
|
|
||||||
|
Install Viewer:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Create the entry `src/svg-sprite-debug.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
||||||
|
import spriteManifest from '../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
|
||||||
|
const viewer = document.createElement('gromlab-sprite-viewer') as SpriteViewerElement
|
||||||
|
viewer.viewerTitle = 'Project icons'
|
||||||
|
viewer.sources = [spriteManifest]
|
||||||
|
document.body.append(viewer)
|
||||||
|
```
|
||||||
|
|
||||||
|
Add the script to the main entry only in development mode. Keep the rest of your `webpack.config.js` settings:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default (_env, argv) => ({
|
||||||
|
// Other Webpack settings.
|
||||||
|
entry: [
|
||||||
|
'./src/main.ts',
|
||||||
|
...(argv.mode === 'development' ? ['./src/svg-sprite-debug.ts'] : []),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Run `npm run dev`. Viewer appears on the application's main page.
|
||||||
|
|
||||||
|
Viewer is only added to the development build and is not included in production.
|
||||||
83
docs/en/guides/standalone.md
Normal file
83
docs/en/guides/standalone.md
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
# SVG Sprite for a Site Without a Bundler
|
||||||
|
|
||||||
|
Combine SVG icons into one file and use them on an HTML page.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
You do not need to install the package in your project.
|
||||||
|
|
||||||
|
### 1. Create the sprite config
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "standalone",
|
||||||
|
"name": "icons",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Generate the sprite
|
||||||
|
|
||||||
|
Pass the config path to the command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json
|
||||||
|
```
|
||||||
|
|
||||||
|
The package collects the icons in a `.svg-sprite` directory next to the config:
|
||||||
|
|
||||||
|
```text
|
||||||
|
assets/app-icons/.svg-sprite/
|
||||||
|
├── sprite.svg
|
||||||
|
└── svg-sprite.manifest.json
|
||||||
|
```
|
||||||
|
|
||||||
|
- `sprite.svg` is the finished sprite for use on the site.
|
||||||
|
- `svg-sprite.manifest.json` contains icon data for Viewer.
|
||||||
|
|
||||||
|
The `.svg-sprite` directory is created automatically and fully replaced on every generation. Do not edit its contents manually.
|
||||||
|
|
||||||
|
### 3. Use an icon
|
||||||
|
|
||||||
|
In `index.html`, point to the generated `sprite.svg`. After `#`, add the icon file name without the `.svg` extension:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<svg
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
aria-label="Done"
|
||||||
|
>
|
||||||
|
<use href="./assets/app-icons/.svg-sprite/sprite.svg#icon-name"></use>
|
||||||
|
</svg>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
`sprite.svg` is a technical file, not an icon gallery. Opening it does not provide a convenient view of the whole set. Gradients, masks, filters, and references to internal `id` values may also render with artifacts.
|
||||||
|
|
||||||
|
Use the official Viewer for visual checks. It displays every icon in the sprite and helps you verify its colors and rendering.
|
||||||
|
|
||||||
|
Viewer is optional and intended only for development. You do not need to install the package through npm.
|
||||||
|
|
||||||
|
Viewer works directly with files from `.svg-sprite`. Nothing needs to be copied.
|
||||||
|
|
||||||
|
### Add Viewer to the page
|
||||||
|
|
||||||
|
Add a module script to `index.html` and provide paths to the generated manifest and sprite:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script
|
||||||
|
type="module"
|
||||||
|
src="https://cdn.jsdelivr.net/npm/@gromlab/svg-sprites/dist/viewer-element.js"
|
||||||
|
></script>
|
||||||
|
|
||||||
|
<gromlab-sprite-viewer
|
||||||
|
viewer-title="Project icons"
|
||||||
|
manifest-url="./assets/app-icons/.svg-sprite/svg-sprite.manifest.json"
|
||||||
|
sprite-url="./assets/app-icons/.svg-sprite/sprite.svg"
|
||||||
|
></gromlab-sprite-viewer>
|
||||||
|
```
|
||||||
|
|
||||||
|
You can move Viewer to a separate HTML file in the site root used only for development and icon checks.
|
||||||
95
docs/en/guides/svelte-vite.md
Normal file
95
docs/en/guides/svelte-vite.md
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
# SVG Sprite for Svelte with Vite
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in a Svelte application built with Vite.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
Example configuration:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "svelte@vite",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The package does not need to be a project dependency: generation runs through `npx`.
|
||||||
|
|
||||||
|
Add generation commands to `package.json`. Generated files are excluded from Git by default, so `predev` and `prebuild` rebuild the sprite before every start and build:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "vite",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "vite build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
The value `name: "app"` creates the Svelte component `AppIcon`.
|
||||||
|
|
||||||
|
Create `assets/app-icons/index.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the component in your application:
|
||||||
|
|
||||||
|
```svelte
|
||||||
|
<script>
|
||||||
|
import { AppIcon } from '../assets/app-icons/index.js'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
role="img"
|
||||||
|
aria-label="Done"
|
||||||
|
style="color: #334155; --icon-color-2: #f59e0b"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
The `icon` prop accepts source SVG file names without the extension. A monochrome icon inherits `color`, while colors in a multicolor icon are overridden with `--icon-color-N`.
|
||||||
|
|
||||||
|
Vite automatically includes the component styles and emits `sprite.svg` as a separate production asset.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Viewer displays all icons on one page so you can check their rendering, change colors, and inspect the related CSS variables. It is only needed for development and is installed separately:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Add Viewer to a development-only Svelte page or component:
|
||||||
|
|
||||||
|
```svelte
|
||||||
|
<script>
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
|
||||||
|
const sources = [
|
||||||
|
() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
]
|
||||||
|
|
||||||
|
function connectViewer(node) {
|
||||||
|
node.sources = sources
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<gromlab-sprite-viewer
|
||||||
|
use:connectViewer
|
||||||
|
viewer-title="Project icons"
|
||||||
|
></gromlab-sprite-viewer>
|
||||||
|
```
|
||||||
|
|
||||||
|
Run `npm run dev` and open the page containing Viewer. Do not import this development component from the production entry.
|
||||||
105
docs/en/guides/svelte-webpack.md
Normal file
105
docs/en/guides/svelte-webpack.md
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
# SVG Sprite for Svelte with Webpack 5
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in a Svelte application built with Webpack 5.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
Example configuration:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "svelte@webpack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The package does not need to be a project dependency: generation runs through `npx`.
|
||||||
|
|
||||||
|
Add generation commands to `package.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "webpack serve --mode development",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "webpack --mode production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
The value `name: "app"` creates the Svelte component `AppIcon`.
|
||||||
|
|
||||||
|
Create `assets/app-icons/index.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the component in your application:
|
||||||
|
|
||||||
|
```svelte
|
||||||
|
<script>
|
||||||
|
import { AppIcon } from '../assets/app-icons/index.js'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
role="img"
|
||||||
|
aria-label="Done"
|
||||||
|
style="color: #334155; --icon-color-2: #f59e0b"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
The generated component is a native `.svelte` file. The normal `svelte-loader` rule must include `.svelte` files under `assets`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
test: /\.svelte$/,
|
||||||
|
use: {
|
||||||
|
loader: 'svelte-loader',
|
||||||
|
options: { emitCss: false },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Webpack 5 processes the component's asset URL and emits `sprite.svg` as a separate production asset.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Viewer displays all icons on one page so you can check their rendering, change colors, and inspect the related CSS variables. It is only needed for development and is installed separately:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Add Viewer to a development-only Svelte component:
|
||||||
|
|
||||||
|
```svelte
|
||||||
|
<script>
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
|
||||||
|
const sources = [
|
||||||
|
() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
]
|
||||||
|
|
||||||
|
function connectViewer(node) {
|
||||||
|
node.sources = sources
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<gromlab-sprite-viewer
|
||||||
|
use:connectViewer
|
||||||
|
viewer-title="Project icons"
|
||||||
|
></gromlab-sprite-viewer>
|
||||||
|
```
|
||||||
|
|
||||||
|
Run `npm run dev` and open the page containing Viewer. Do not import this development component from the production entry.
|
||||||
91
docs/en/guides/sveltekit-vite.md
Normal file
91
docs/en/guides/sveltekit-vite.md
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
# SVG Sprite for SvelteKit with Vite
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in a SvelteKit application built with Vite.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
Example configuration:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "sveltekit@vite",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The package does not need to be a project dependency: generation runs through `npx`.
|
||||||
|
|
||||||
|
Add generation commands to `package.json`. Generated files are excluded from Git by default, so `predev` and `prebuild` rebuild the sprite before every start and build:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "vite dev",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "vite build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
The value `name: "app"` creates the SSR-safe Svelte component `AppIcon`.
|
||||||
|
|
||||||
|
Create `assets/app-icons/index.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the component in `src/routes/+page.svelte`:
|
||||||
|
|
||||||
|
```svelte
|
||||||
|
<script>
|
||||||
|
import { AppIcon } from '../../assets/app-icons/index.js'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
role="img"
|
||||||
|
aria-label="Done"
|
||||||
|
style="color: #334155; --icon-color-2: #f59e0b"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
The `icon` prop accepts source SVG file names without the extension. The component has no browser-only initialization, so the page can be rendered on the server. Vite emits `sprite.svg` as a separate production asset.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Viewer displays all icons on one page so you can check their rendering, change colors, and inspect the related CSS variables. It is only needed for development and is installed separately:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Create a development route such as `src/routes/svg-sprite/+page.svelte`. Load the custom element from an action so it is only registered in the browser:
|
||||||
|
|
||||||
|
```svelte
|
||||||
|
<script>
|
||||||
|
const sources = [
|
||||||
|
() => import('../../../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
]
|
||||||
|
|
||||||
|
function connectViewer(node) {
|
||||||
|
void import('@gromlab/svg-sprites/viewer/element').then(() => {
|
||||||
|
node.sources = sources
|
||||||
|
node.viewerTitle = 'Project icons'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<gromlab-sprite-viewer use:connectViewer></gromlab-sprite-viewer>
|
||||||
|
```
|
||||||
|
|
||||||
|
Run `npm run dev` and open `/svg-sprite`. The action does not run during SSR.
|
||||||
105
docs/en/guides/vue-vite.md
Normal file
105
docs/en/guides/vue-vite.md
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
# SVG Sprite for Vue with Vite
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in a Vue application built with Vite.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
Example configuration:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "vue@vite",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The package does not need to be a project dependency: generation runs through `npx`.
|
||||||
|
|
||||||
|
Add generation commands to `package.json`. Generated files are excluded from Git by default, so `predev` and `prebuild` rebuild the sprite before every start and build:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "vite",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "vue-tsc --noEmit && vite build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
The value `name: "app"` creates the Vue component `AppIcon`.
|
||||||
|
|
||||||
|
Create the entry point `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the component in your application:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
role="img"
|
||||||
|
aria-label="Done"
|
||||||
|
style="color: #334155; --icon-color-2: #f59e0b"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
The `icon` prop accepts source SVG file names without the extension. A monochrome icon inherits `color`, while colors in a multicolor icon are overridden with `--icon-color-N`.
|
||||||
|
|
||||||
|
Vite automatically includes the component styles and adds `sprite.svg` to the production build.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Viewer displays all icons on one page so you can check their rendering, change colors, and inspect the related CSS variables. It is only needed for development and is installed separately:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Create `svg-sprite.html` in the project root:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Project icons</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<gromlab-sprite-viewer viewer-title="Project icons"></gromlab-sprite-viewer>
|
||||||
|
<script type="module" src="/src/svg-sprite-debug.ts"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
Create `src/svg-sprite-debug.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
||||||
|
import spriteManifest from '../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
|
||||||
|
const viewer = document.querySelector<SpriteViewerElement>('gromlab-sprite-viewer')!
|
||||||
|
viewer.sources = [spriteManifest]
|
||||||
|
```
|
||||||
|
|
||||||
|
Run `npm run dev` and open `/svg-sprite.html`.
|
||||||
|
|
||||||
|
Viewer is not required by `AppIcon` and is not loaded by the main application code.
|
||||||
126
docs/en/guides/vue-webpack.md
Normal file
126
docs/en/guides/vue-webpack.md
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
# SVG Sprite for Vue with Webpack 5
|
||||||
|
|
||||||
|
A quick guide to creating an SVG sprite in a Vue application built with Webpack 5.
|
||||||
|
|
||||||
|
## Generate the sprite
|
||||||
|
|
||||||
|
Choose a directory for the future SVG sprite, for example `assets/app-icons`, and create `svg-sprite.config.json` inside it. In `input`, specify the path to existing SVG files relative to the configuration file. There is no need to move or copy the icons.
|
||||||
|
|
||||||
|
Example configuration:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "vue@webpack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The package does not need to be a project dependency: generation runs through `npx`.
|
||||||
|
|
||||||
|
Add generation commands to `package.json`. Generated files are excluded from Git by default, so `predev` and `prebuild` rebuild the sprite before every start and build:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "webpack serve --mode development",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "webpack --mode production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the sprite
|
||||||
|
|
||||||
|
The value `name: "app"` creates the Vue component `AppIcon`. Create `assets/app-icons/index.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the component in your application:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
import { AppIcon } from '../assets/app-icons/index.js'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
role="img"
|
||||||
|
aria-label="Done"
|
||||||
|
style="color: #334155; --icon-color-2: #f59e0b"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
The `icon` prop accepts source SVG file names without the extension. A monochrome icon inherits `color`, while colors in a multicolor icon are overridden with `--icon-color-N`.
|
||||||
|
|
||||||
|
The component uses CSS Modules. If the project does not process them yet, install `style-loader` and `css-loader`, then add a rule with a default export:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev style-loader css-loader
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
test: /\.module\.css$/i,
|
||||||
|
use: [
|
||||||
|
'style-loader',
|
||||||
|
{
|
||||||
|
loader: 'css-loader',
|
||||||
|
options: { modules: { namedExport: false } },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Webpack 5 automatically adds `sprite.svg` to the production build.
|
||||||
|
|
||||||
|
## Debug and preview
|
||||||
|
|
||||||
|
Viewer displays all icons on one page so you can check their rendering, change colors, and inspect the related CSS variables. It is only needed for development and is installed separately:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Add Viewer to a development-only Vue component:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
|
||||||
|
const sources = [
|
||||||
|
() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
]
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<gromlab-sprite-viewer
|
||||||
|
:sources="sources"
|
||||||
|
viewer-title="Project icons"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
Configure Vue Loader to treat `gromlab-sprite-viewer` as a custom element:
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
test: /\.vue$/,
|
||||||
|
loader: 'vue-loader',
|
||||||
|
options: {
|
||||||
|
compilerOptions: {
|
||||||
|
isCustomElement: (tag) => tag === 'gromlab-sprite-viewer',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Render the Viewer component on your development page. Viewer is not required by `AppIcon`.
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
# Legacy mode
|
|
||||||
|
|
||||||
[← Back to home](../../README.md)
|
|
||||||
|
|
||||||
A quick guide to generating centralized SVG sprites in `symbol` and `stack` formats, with an optional HTML preview.
|
|
||||||
|
|
||||||
## 1. Install the package
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install @gromlab/svg-sprites
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2. Prepare the icons and config
|
|
||||||
|
|
||||||
```text
|
|
||||||
project/
|
|
||||||
├── src/assets/icons/
|
|
||||||
│ ├── check.svg
|
|
||||||
│ └── folder.svg
|
|
||||||
└── svg-sprites.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// svg-sprites.config.ts
|
|
||||||
import { defineLegacyConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineLegacyConfig({
|
|
||||||
output: 'public/sprites',
|
|
||||||
preview: true,
|
|
||||||
sprites: [
|
|
||||||
{
|
|
||||||
name: 'icons',
|
|
||||||
input: 'src/assets/icons',
|
|
||||||
format: 'symbol',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
## 3. Run generation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx svg-sprites --mode legacy .
|
|
||||||
```
|
|
||||||
|
|
||||||
Result:
|
|
||||||
|
|
||||||
```text
|
|
||||||
public/sprites/
|
|
||||||
├── icons.sprite.svg
|
|
||||||
└── preview.html
|
|
||||||
```
|
|
||||||
|
|
||||||
With `preview: false`, the HTML file is not created. For the `stack` format, specify `format: 'stack'`.
|
|
||||||
|
|
||||||
## 4. Use the symbol sprite
|
|
||||||
|
|
||||||
```html
|
|
||||||
<svg width="24" height="24" aria-label="Done">
|
|
||||||
<use href="/sprites/icons.sprite.svg#check"></use>
|
|
||||||
</svg>
|
|
||||||
```
|
|
||||||
|
|
||||||
## 5. Add a package script
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"scripts": {
|
|
||||||
"sprites": "svg-sprites --mode legacy .",
|
|
||||||
"prebuild": "npm run sprites"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Multiple sprites
|
|
||||||
|
|
||||||
Add multiple entries to `sprites`:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
sprites: [
|
|
||||||
{
|
|
||||||
name: 'icons',
|
|
||||||
input: 'src/assets/icons',
|
|
||||||
format: 'symbol',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'logos',
|
|
||||||
input: 'src/assets/logos',
|
|
||||||
format: 'stack',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
All output files and the shared `preview.html` will be written to `output`.
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
- Config not found: make sure `svg-sprites.config.ts` is located in the specified root directory.
|
|
||||||
- No icons: check `sprites[].input` and the `.svg` extension.
|
|
||||||
- Preview not needed: set `preview: false`.
|
|
||||||
|
|
||||||
For programmatic use, see [`generateLegacy`](programmatic-api.md#generatelegacy).
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
# Migrating from 0.1.x to 1.0
|
|
||||||
|
|
||||||
[← Back to home](../../README.md)
|
|
||||||
|
|
||||||
Version 1.0 separates local generation for React and Next.js from the centralized legacy mode. The old config cannot be mixed with the new API in a single CLI invocation.
|
|
||||||
|
|
||||||
## CLI
|
|
||||||
|
|
||||||
The CLI now always requires an explicit `--mode` and a path to the configuration directory:
|
|
||||||
|
|
||||||
```text
|
|
||||||
svg-sprites
|
|
||||||
→ svg-sprites --mode <mode> <path>
|
|
||||||
```
|
|
||||||
|
|
||||||
Choose a mode based on your environment:
|
|
||||||
|
|
||||||
| Environment | Mode |
|
|
||||||
|---|---|
|
|
||||||
| React + Vite | `react@vite` |
|
|
||||||
| React + Webpack 5 | `react@webpack` |
|
|
||||||
| Next.js App Router + Turbopack | `next@app/turbopack` |
|
|
||||||
| Next.js App Router + Webpack 5 | `next@app/webpack` |
|
|
||||||
| Next.js Pages Router + Turbopack | `next@pages/turbopack` |
|
|
||||||
| Next.js Pages Router + Webpack 5 | `next@pages/webpack` |
|
|
||||||
| Centralized legacy setup | `legacy` |
|
|
||||||
|
|
||||||
## React and Next.js
|
|
||||||
|
|
||||||
Instead of a root-level `svg-sprites.config.ts`, create a local `svg-sprite.config.ts` next to the icon set:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineNextSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineNextSpriteConfig({
|
|
||||||
name: 'global',
|
|
||||||
inputFolder: './icons',
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
For regular React, use `defineReactSpriteConfig`. A folder and an explicit list of shared SVG files can be combined using `inputFolder` and `inputFiles`.
|
|
||||||
|
|
||||||
The old `publicPath` and `react` options are no longer needed. The generated module is created next to the config and adds its own `.gitignore`, while Vite, Webpack, or Next.js emits the SVG as a separate asset with a content hash.
|
|
||||||
|
|
||||||
The `<SvgSprite icon="..." />` component is replaced by a component whose name is derived from `name`:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
<GlobalIcon icon="check" />
|
|
||||||
```
|
|
||||||
|
|
||||||
To browse the icons, add `<SpriteViewer>` as a debug page in the application. A separate `preview.html` is available only in legacy mode.
|
|
||||||
|
|
||||||
## Legacy mode
|
|
||||||
|
|
||||||
If you need to preserve the centralized structure, rename the helper and the format fields:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineLegacyConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineLegacyConfig({
|
|
||||||
output: 'public/sprites',
|
|
||||||
preview: true,
|
|
||||||
sprites: [
|
|
||||||
{
|
|
||||||
name: 'icons',
|
|
||||||
input: 'src/assets/icons',
|
|
||||||
format: 'stack',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
- `defineConfig` has been replaced with `defineLegacyConfig`;
|
|
||||||
- `sprites[].mode` has been renamed to `sprites[].format`;
|
|
||||||
- `generate` has been replaced with `generateLegacy`;
|
|
||||||
- `loadConfig` has been replaced with `loadLegacyConfig`;
|
|
||||||
- `publicPath` and generation of the old shared React component have been removed.
|
|
||||||
|
|
||||||
Run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
svg-sprites --mode legacy .
|
|
||||||
```
|
|
||||||
|
|
||||||
## Programmatic API
|
|
||||||
|
|
||||||
The package is distributed as ESM only. Replace `require()` with `import`.
|
|
||||||
|
|
||||||
`compileSpriteContent` now returns `Promise<Uint8Array>` so that the public declarations do not require `@types/node` to be installed. In Node.js, the actual result is compatible with APIs that accept `Uint8Array`.
|
|
||||||
|
|
||||||
## After migration
|
|
||||||
|
|
||||||
1. Remove the old generated files and rules that ignored the entire directory containing the source icons.
|
|
||||||
2. Add an explicit generation command before `dev`, `build`, and `typecheck`.
|
|
||||||
3. Run generation and type checking.
|
|
||||||
4. Check all icons and color variables using `SpriteViewer` or the legacy `preview.html`.
|
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
# Next.js App Router
|
|
||||||
|
|
||||||
[← Back to home](../../README.md)
|
|
||||||
|
|
||||||
Two explicit modes are supported:
|
|
||||||
|
|
||||||
| Bundler | Mode key | Next.js version |
|
|
||||||
|---|---|---|
|
|
||||||
| Turbopack | `next@app/turbopack` | 16.2+ |
|
|
||||||
| Webpack 5 | `next@app/webpack` | 13.4+ |
|
|
||||||
|
|
||||||
## 1. Install the package
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install @gromlab/svg-sprites
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2. Create a sprite module
|
|
||||||
|
|
||||||
```text
|
|
||||||
src/ui/file-manager/svg-sprite/
|
|
||||||
├── icons/
|
|
||||||
│ ├── check.svg
|
|
||||||
│ └── folder.svg
|
|
||||||
└── svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// src/ui/file-manager/svg-sprite/svg-sprite.config.ts
|
|
||||||
import { defineNextSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineNextSpriteConfig({
|
|
||||||
name: 'file-manager',
|
|
||||||
description: 'File manager icons',
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
## 3. Add generation
|
|
||||||
|
|
||||||
For Turbopack:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"scripts": {
|
|
||||||
"sprite:file-manager": "svg-sprites --mode next@app/turbopack src/ui/file-manager/svg-sprite",
|
|
||||||
"predev": "npm run sprite:file-manager",
|
|
||||||
"prebuild": "npm run sprite:file-manager"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
For Webpack, replace the mode key with `next@app/webpack`. In Next 13–15, Webpack is used with the regular `next build` command; in Next 16, use `next build --webpack`.
|
|
||||||
|
|
||||||
## 4. Use it in a Server Component
|
|
||||||
|
|
||||||
The generated component does not contain `'use client'`, so it can be imported directly into `page.tsx` or `layout.tsx`:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
import { FileManagerIcon } from '@/ui/file-manager/svg-sprite'
|
|
||||||
|
|
||||||
export default function Page() {
|
|
||||||
return (
|
|
||||||
<main>
|
|
||||||
<FileManagerIcon icon="folder" width={24} height={24} />
|
|
||||||
</main>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Next.js emits a separate SVG asset with a content hash. The same generated code is used during SSR and in the browser, with no URL mismatch.
|
|
||||||
|
|
||||||
## 5. Add SpriteViewer
|
|
||||||
|
|
||||||
The viewer is interactive, so it requires a separate Client Component boundary:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
'use client'
|
|
||||||
|
|
||||||
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
|
||||||
|
|
||||||
const sources = [
|
|
||||||
() => import('@/ui/file-manager/svg-sprite/manifest'),
|
|
||||||
]
|
|
||||||
|
|
||||||
export default function SpritesPage() {
|
|
||||||
return <SpriteViewer sources={sources} />
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Verify the bundler
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Turbopack
|
|
||||||
npx next build --turbopack
|
|
||||||
|
|
||||||
# Webpack 5
|
|
||||||
npx next build --webpack
|
|
||||||
```
|
|
||||||
|
|
||||||
For Next 13–15 with Webpack, use `npx next build` without the flag.
|
|
||||||
|
|
||||||
The Next.js command and the generator mode key must target the same bundler.
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
# Next.js Pages Router
|
|
||||||
|
|
||||||
[← Back to home](../../README.md)
|
|
||||||
|
|
||||||
Two explicit modes are supported:
|
|
||||||
|
|
||||||
| Bundler | Mode key | Next.js version |
|
|
||||||
|---|---|---|
|
|
||||||
| Turbopack | `next@pages/turbopack` | 16.2+ |
|
|
||||||
| Webpack 5 | `next@pages/webpack` | 12.2+ |
|
|
||||||
|
|
||||||
Next.js 12.2 requires React 18.
|
|
||||||
|
|
||||||
## 1. Install the package
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install @gromlab/svg-sprites
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2. Create a sprite module
|
|
||||||
|
|
||||||
```text
|
|
||||||
src/ui/file-manager/svg-sprite/
|
|
||||||
├── icons/
|
|
||||||
│ ├── check.svg
|
|
||||||
│ └── folder.svg
|
|
||||||
└── svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// src/ui/file-manager/svg-sprite/svg-sprite.config.ts
|
|
||||||
import { defineNextSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineNextSpriteConfig({
|
|
||||||
name: 'file-manager',
|
|
||||||
description: 'File manager icons',
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
## 3. Add generation
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"scripts": {
|
|
||||||
"sprite:file-manager": "svg-sprites --mode next@pages/webpack src/ui/file-manager/svg-sprite",
|
|
||||||
"predev": "npm run sprite:file-manager",
|
|
||||||
"prebuild": "npm run sprite:file-manager"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
For Next.js 16.2 with Turbopack, replace the mode key with `next@pages/turbopack`.
|
|
||||||
|
|
||||||
## 4. Use it on a page
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
import { FileManagerIcon } from '@/ui/file-manager/svg-sprite'
|
|
||||||
|
|
||||||
export default function FilesPage() {
|
|
||||||
return <FileManagerIcon icon="folder" width={24} height={24} />
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getServerSideProps() {
|
|
||||||
return { props: {} }
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The component works the same way with SSR, SSG, and client-side navigation. Next.js emits a separate SVG asset with a content hash.
|
|
||||||
|
|
||||||
## 5. Add SpriteViewer
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
|
||||||
|
|
||||||
const sources = [
|
|
||||||
() => import('@/ui/file-manager/svg-sprite/manifest'),
|
|
||||||
]
|
|
||||||
|
|
||||||
export default function SpritesPage() {
|
|
||||||
return <SpriteViewer sources={sources} />
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Verify the bundler
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Turbopack
|
|
||||||
npx next build --turbopack
|
|
||||||
|
|
||||||
# Webpack 5
|
|
||||||
npx next build --webpack
|
|
||||||
```
|
|
||||||
|
|
||||||
For Next 12–15 with Webpack, use `npx next build` without the flag.
|
|
||||||
|
|
||||||
The Next.js command and the generator mode key must target the same bundler.
|
|
||||||
@@ -1,203 +0,0 @@
|
|||||||
# Programmatic API
|
|
||||||
|
|
||||||
[← Back to home](../../README.md)
|
|
||||||
|
|
||||||
The package provides a main Node.js entry point and a separate React runtime entry point. Both are distributed as ESM only and must be loaded with `import`.
|
|
||||||
|
|
||||||
To resolve `@gromlab/svg-sprites/react` in TypeScript, use `moduleResolution: "bundler"`, `"node16"`, or `"nodenext"`.
|
|
||||||
|
|
||||||
## Main entry point
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import {
|
|
||||||
defineNextSpriteConfig,
|
|
||||||
defineReactSpriteConfig,
|
|
||||||
generateNextSprite,
|
|
||||||
generateReactSprite,
|
|
||||||
} from '@gromlab/svg-sprites'
|
|
||||||
```
|
|
||||||
|
|
||||||
The main entry point does not import React and can be used in CLIs, build scripts, and Node.js tools.
|
|
||||||
|
|
||||||
## `generateReactSprite`
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { generateReactSprite } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
const result = await generateReactSprite(
|
|
||||||
'src/ui/file-manager/svg-sprite',
|
|
||||||
'vite',
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
The second argument is required:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type ReactAssetTarget = 'vite' | 'webpack'
|
|
||||||
```
|
|
||||||
|
|
||||||
Result:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type ReactSpriteGenerationResult = {
|
|
||||||
name: string
|
|
||||||
rootDir: string
|
|
||||||
generatedDir: string
|
|
||||||
spritePath: string
|
|
||||||
manifestPath: string
|
|
||||||
iconCount: number
|
|
||||||
target: 'vite' | 'webpack'
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
```ts
|
|
||||||
console.log(result.name)
|
|
||||||
console.log(result.iconCount)
|
|
||||||
console.log(result.spritePath)
|
|
||||||
console.log(result.manifestPath)
|
|
||||||
```
|
|
||||||
|
|
||||||
The function loads `svg-sprite.config.ts` from the specified root, compiles the SVG files, and safely updates managed files.
|
|
||||||
|
|
||||||
## `generateNextSprite`
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { generateNextSprite } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
const result = await generateNextSprite(
|
|
||||||
'src/ui/file-manager/svg-sprite',
|
|
||||||
{
|
|
||||||
router: 'app',
|
|
||||||
bundler: 'turbopack',
|
|
||||||
},
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
Available values:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type NextSpriteGenerationOptions = {
|
|
||||||
router: 'app' | 'pages'
|
|
||||||
bundler: 'turbopack' | 'webpack'
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The result also contains the selected `router`, `bundler`, and the full target in the form `next@app/turbopack`.
|
|
||||||
|
|
||||||
## `defineReactSpriteConfig`
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineReactSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineReactSpriteConfig({
|
|
||||||
name: 'file-manager',
|
|
||||||
description: 'File manager icons',
|
|
||||||
inputFolder: './icons',
|
|
||||||
inputFiles: [
|
|
||||||
'../../shared/icons/check.svg',
|
|
||||||
],
|
|
||||||
transform: {
|
|
||||||
removeSize: true,
|
|
||||||
replaceColors: true,
|
|
||||||
addTransition: true,
|
|
||||||
},
|
|
||||||
generatedNotice: true,
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
`inputFolder` and `inputFiles` are combined. The helper returns the configuration without runtime transformations and provides TypeScript autocomplete.
|
|
||||||
|
|
||||||
## `defineNextSpriteConfig`
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineNextSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineNextSpriteConfig({
|
|
||||||
name: 'file-manager',
|
|
||||||
description: 'File manager icons',
|
|
||||||
inputFolder: './icons',
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
Next.js uses the same configuration contract as the React presets.
|
|
||||||
|
|
||||||
## `generateLegacy`
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { generateLegacy } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
const results = await generateLegacy({
|
|
||||||
output: 'public/sprites',
|
|
||||||
preview: false,
|
|
||||||
sprites: [
|
|
||||||
{
|
|
||||||
name: 'icons',
|
|
||||||
input: 'src/assets/icons',
|
|
||||||
format: 'symbol',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
Returns an array:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type SpriteResult = {
|
|
||||||
name: string
|
|
||||||
format: 'symbol' | 'stack'
|
|
||||||
spritePath: string
|
|
||||||
iconCount: number
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
For details, see [Legacy mode](legacy.md).
|
|
||||||
|
|
||||||
## Low-level functions
|
|
||||||
|
|
||||||
The main entry point also exports:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import {
|
|
||||||
compileSprite,
|
|
||||||
compileSpriteContent,
|
|
||||||
createShapeTransform,
|
|
||||||
generatePreview,
|
|
||||||
loadLegacyConfig,
|
|
||||||
loadReactSpriteConfig,
|
|
||||||
resolveSpriteEntry,
|
|
||||||
resolveSprites,
|
|
||||||
} from '@gromlab/svg-sprites'
|
|
||||||
```
|
|
||||||
|
|
||||||
These functions are intended for custom orchestration built on top of the existing compiler and writer. For standard usage, prefer `generateReactSprite` and `generateLegacy`.
|
|
||||||
|
|
||||||
## React runtime entry point
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
|
||||||
```
|
|
||||||
|
|
||||||
Types:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import type {
|
|
||||||
SpriteManifest,
|
|
||||||
SpriteManifestColor,
|
|
||||||
SpriteManifestIcon,
|
|
||||||
SpriteManifestLoader,
|
|
||||||
SpriteManifestModule,
|
|
||||||
SpriteViewerColorTheme,
|
|
||||||
SpriteViewerProps,
|
|
||||||
SpriteViewerSource,
|
|
||||||
SpriteViewerSources,
|
|
||||||
} from '@gromlab/svg-sprites/react'
|
|
||||||
```
|
|
||||||
|
|
||||||
The React entry point contains `'use client'` and is intended for debug tools. Generated production components are imported from the application's local sprite modules, not from the package's React entry point.
|
|
||||||
|
|
||||||
`SpriteViewerProps.colorTheme` accepts `auto | light | dark`. The default is `auto`, which follows `prefers-color-scheme`; to synchronize it with the application theme, pass the computed `light` or `dark` value.
|
|
||||||
|
|
||||||
## Related guides
|
|
||||||
|
|
||||||
- [React + Vite](react-vite.md)
|
|
||||||
- [React + Webpack 5](react-webpack.md)
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
# React + Vite
|
|
||||||
|
|
||||||
[← Back to home](../../README.md)
|
|
||||||
|
|
||||||
A quick guide to installing and using SVG sprites in a React and Vite project.
|
|
||||||
|
|
||||||
The result is a typed React component and a separate cacheable SVG asset.
|
|
||||||
|
|
||||||
## 1. Install the package
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install @gromlab/svg-sprites
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2. Create the sprite directory
|
|
||||||
|
|
||||||
```text
|
|
||||||
src/ui/file-manager/svg-sprite/
|
|
||||||
├── icons/
|
|
||||||
│ ├── check.svg
|
|
||||||
│ └── folder.svg
|
|
||||||
└── svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Place the source SVG files in `icons/`.
|
|
||||||
|
|
||||||
## 3. Add the configuration
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// src/ui/file-manager/svg-sprite/svg-sprite.config.ts
|
|
||||||
import { defineReactSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineReactSpriteConfig({
|
|
||||||
name: 'file-manager',
|
|
||||||
description: 'File manager icons',
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
By default, SVG files are loaded from `./icons`. You can add shared icons from other directories through `inputFiles`: the directory and file list are combined into a single sprite.
|
|
||||||
|
|
||||||
The complete list of options is available under [Configuration → React](../../README.md#react).
|
|
||||||
|
|
||||||
## 4. Add generation to package.json
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"scripts": {
|
|
||||||
"sprite:file-manager": "svg-sprites --mode react@vite src/ui/file-manager/svg-sprite",
|
|
||||||
"predev": "npm run sprite:file-manager",
|
|
||||||
"prebuild": "npm run sprite:file-manager",
|
|
||||||
"pretypecheck": "npm run sprite:file-manager"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Generated files are excluded from Git, so generation must run before `dev`, `build`, and `typecheck`.
|
|
||||||
|
|
||||||
First run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run sprite:file-manager
|
|
||||||
```
|
|
||||||
|
|
||||||
## 5. Use the component
|
|
||||||
|
|
||||||
The name `file-manager` is converted to `FileManagerIcon`:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
import { FileManagerIcon } from './svg-sprite'
|
|
||||||
|
|
||||||
export const OpenFolderButton = () => (
|
|
||||||
<button type="button">
|
|
||||||
<FileManagerIcon icon="folder" width={24} height={24} />
|
|
||||||
Open
|
|
||||||
</button>
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
TypeScript checks the `icon` value against the file names:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
<FileManagerIcon icon="check" /> // valid
|
|
||||||
<FileManagerIcon icon="unknown" /> // TypeScript error
|
|
||||||
```
|
|
||||||
|
|
||||||
Types, display methods, and color controls are described in the [main documentation](../../README.md#display-methods).
|
|
||||||
|
|
||||||
Vite emits the sprite as a separate file named like `assets/sprite-<hash>.svg`. SVG path data is not included in JavaScript.
|
|
||||||
|
|
||||||
## 6. Add a debug page
|
|
||||||
|
|
||||||
After integrating the icons, you can display all React sprites with `SpriteViewer`:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
|
||||||
import type { SpriteManifestModule } from '@gromlab/svg-sprites/react'
|
|
||||||
|
|
||||||
const sources = import.meta.glob<SpriteManifestModule>(
|
|
||||||
'/src/**/svg-sprite/manifest.ts',
|
|
||||||
)
|
|
||||||
|
|
||||||
export const IconsDebugPage = () => (
|
|
||||||
<SpriteViewer sources={sources} title="Project icons" />
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
Vite automatically finds the generated `manifest.ts` for each React sprite. The `import.meta.glob` pattern must be a string literal, and generation must run before Vite starts.
|
|
||||||
|
|
||||||
Only include the Viewer on a debug route or in an internal tool.
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
- Missing `index.ts`: run `npm run sprite:file-manager`.
|
|
||||||
- The Viewer cannot find the sprite: check the glob path and make sure `manifest.ts` exists.
|
|
||||||
- `Refusing to overwrite a user file` error: there is a user file at a generated path.
|
|
||||||
- The icon does not change color: use `color` or `--icon-color-N`.
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
# React + Webpack 5
|
|
||||||
|
|
||||||
[← Back to home](../../README.md)
|
|
||||||
|
|
||||||
A quick guide to installing and using SVG sprites in a React and Webpack 5 project.
|
|
||||||
|
|
||||||
The result is a typed React component and a separate SVG asset emitted through Webpack Asset Modules.
|
|
||||||
|
|
||||||
## 1. Install the package
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install @gromlab/svg-sprites
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2. Create the sprite directory
|
|
||||||
|
|
||||||
```text
|
|
||||||
src/ui/file-manager/svg-sprite/
|
|
||||||
├── icons/
|
|
||||||
│ ├── check.svg
|
|
||||||
│ └── folder.svg
|
|
||||||
└── svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Place the source SVG files in `icons/`.
|
|
||||||
|
|
||||||
## 3. Add the configuration
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// src/ui/file-manager/svg-sprite/svg-sprite.config.ts
|
|
||||||
import { defineReactSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineReactSpriteConfig({
|
|
||||||
name: 'file-manager',
|
|
||||||
description: 'File manager icons',
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
By default, SVG files are loaded from `./icons`. You can add shared icons from other directories through `inputFiles`: the directory and file list are combined into a single sprite.
|
|
||||||
|
|
||||||
The complete list of options is available under [Configuration → React](../../README.md#react).
|
|
||||||
|
|
||||||
## 4. Add generation to package.json
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"scripts": {
|
|
||||||
"sprite:file-manager": "svg-sprites --mode react@webpack src/ui/file-manager/svg-sprite",
|
|
||||||
"predev": "npm run sprite:file-manager",
|
|
||||||
"prebuild": "npm run sprite:file-manager",
|
|
||||||
"pretypecheck": "npm run sprite:file-manager"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Generated files are excluded from Git, so generation must run before `dev`, `build`, and `typecheck`.
|
|
||||||
|
|
||||||
First run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run sprite:file-manager
|
|
||||||
```
|
|
||||||
|
|
||||||
## 5. Use the component
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
import { FileManagerIcon } from './svg-sprite'
|
|
||||||
|
|
||||||
export const OpenFolderButton = () => (
|
|
||||||
<button type="button">
|
|
||||||
<FileManagerIcon icon="folder" width={24} height={24} />
|
|
||||||
Open
|
|
||||||
</button>
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
TypeScript checks the `icon` value against the file names:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
<FileManagerIcon icon="folder" /> // valid
|
|
||||||
<FileManagerIcon icon="missing" /> // TypeScript error
|
|
||||||
```
|
|
||||||
|
|
||||||
Types, display methods, and color controls are described in the [main documentation](../../README.md#display-methods).
|
|
||||||
|
|
||||||
Webpack processes the generated `new URL('./sprite.svg', import.meta.url)` through Asset Modules and emits a separate SVG asset.
|
|
||||||
|
|
||||||
If the project already uses a custom SVG loader, make sure it does not intercept the generated `sprite.svg` instead of Asset Modules.
|
|
||||||
|
|
||||||
## 6. Add a debug page
|
|
||||||
|
|
||||||
Webpack does not support Vite's `import.meta.glob` API, so provide static loaders:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
|
||||||
|
|
||||||
const sources = [
|
|
||||||
() => import('./ui/file-manager/svg-sprite/manifest'),
|
|
||||||
() => import('./ui/navigation/svg-sprite/manifest'),
|
|
||||||
]
|
|
||||||
|
|
||||||
export const IconsDebugPage = () => (
|
|
||||||
<SpriteViewer sources={sources} title="Project icons" />
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
The paths in `import()` must be string literals. Webpack creates chunks for the manifests and associates them with the SVG assets.
|
|
||||||
|
|
||||||
Only include the Viewer on a debug route or in an internal tool.
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
- Missing `index.ts`: run `npm run sprite:file-manager`.
|
|
||||||
- The Viewer does not load the sprite: check the path in `import()` and make sure `manifest.ts` exists.
|
|
||||||
- Incorrect asset URL: check `output.publicPath`.
|
|
||||||
- Another loader intercepts the SVG: exclude the generated sprite from the incompatible rule.
|
|
||||||
|
|
||||||
For Next.js, use the separate mode keys described in the [App Router](next-app.md) and [Pages Router](next-pages.md) guides.
|
|
||||||
4
docs/en/reference/README.md
Normal file
4
docs/en/reference/README.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# Reference
|
||||||
|
|
||||||
|
- [Technical reference](technical.md)
|
||||||
|
- [Programmatic API](programmatic-api.md)
|
||||||
185
docs/en/reference/programmatic-api.md
Normal file
185
docs/en/reference/programmatic-api.md
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
# Programmatic API
|
||||||
|
|
||||||
|
[Documentation index](../README.md)
|
||||||
|
|
||||||
|
The package is ESM-only and provides one Node.js generation API. The framework-neutral Viewer is available from `@gromlab/svg-sprites/viewer`, its auto-register entry from `@gromlab/svg-sprites/viewer/element`, and the React bridge from `@gromlab/svg-sprites/react`.
|
||||||
|
|
||||||
|
## `generateSprite`
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { generateSprite } from '@gromlab/svg-sprites'
|
||||||
|
|
||||||
|
const result = await generateSprite(
|
||||||
|
'src/ui/file-manager/svg-sprite/svg-sprite.config.ts',
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
The result contains the sprite name, exact mode, mode-specific asset target, icon count, and absolute filesystem paths:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
result.name
|
||||||
|
result.mode
|
||||||
|
result.target
|
||||||
|
result.iconCount
|
||||||
|
result.rootDir
|
||||||
|
result.generatedDir
|
||||||
|
result.spritePath
|
||||||
|
result.manifestPath
|
||||||
|
```
|
||||||
|
|
||||||
|
Next.js modes additionally return `router` and `bundler`.
|
||||||
|
For bare `standalone`, `target` is `static`; standalone bundler and React modes
|
||||||
|
return `vite` or `webpack`; Next.js modes return their full exact mode as the
|
||||||
|
target.
|
||||||
|
|
||||||
|
For static standalone mode, use `result.spritePath` in a build script to publish the
|
||||||
|
SVG under an application URL:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { copyFile } from 'node:fs/promises'
|
||||||
|
|
||||||
|
const result = await generateSprite('src/sprite/svg-sprite.config.ts', {
|
||||||
|
mode: 'standalone',
|
||||||
|
})
|
||||||
|
await copyFile(result.spritePath, 'dist/app-icons/sprite.svg')
|
||||||
|
```
|
||||||
|
|
||||||
|
`spritePath` is a filesystem path, not a browser URL. A deployment-neutral JSON
|
||||||
|
manifest is available through `result.manifestPath` and is copied independently.
|
||||||
|
|
||||||
|
The first argument accepts an absolute or relative path to an explicitly selected `.ts`, `.js`, or `.json` config file with any name. Passing a directory enables config-less mode and uses that directory as the sprite module root.
|
||||||
|
|
||||||
|
The second argument contains optional overrides and always takes precedence over the config:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
await generateSprite('src/ui/file-manager/svg-sprite/custom-config.json', {
|
||||||
|
mode: 'react@webpack',
|
||||||
|
name: 'documents',
|
||||||
|
input: ['./assets', '../../shared/search.svg'],
|
||||||
|
transform: {
|
||||||
|
addTransition: false,
|
||||||
|
},
|
||||||
|
generatedNotice: false,
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Configuration is resolved in this order:
|
||||||
|
|
||||||
|
```text
|
||||||
|
defaults → config → API overrides
|
||||||
|
```
|
||||||
|
|
||||||
|
For fully programmatic generation, pass a directory and provide the required `mode` and any other settings as overrides. `name` is optional: when omitted, it is inferred in kebab-case from the directory name, or from the parent directory when the module directory is named `svg-sprite` or `svg-sprites`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
await generateSprite('src/ui/file-manager/svg-sprite', {
|
||||||
|
mode: 'react@vite',
|
||||||
|
name: 'file-manager',
|
||||||
|
input: [
|
||||||
|
'../../shared/search.svg',
|
||||||
|
'../../shared/settings.svg',
|
||||||
|
],
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { defineSpriteConfig } from '@gromlab/svg-sprites'
|
||||||
|
|
||||||
|
export default defineSpriteConfig({
|
||||||
|
mode: 'react@vite',
|
||||||
|
name: 'file-manager',
|
||||||
|
description: 'File manager icons',
|
||||||
|
input: ['./icons', '../../shared/check.svg'],
|
||||||
|
transform: {
|
||||||
|
removeSize: true,
|
||||||
|
replaceColors: true,
|
||||||
|
addTransition: true,
|
||||||
|
},
|
||||||
|
generatedNotice: true,
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
`input` accepts one folder, SVG file, or glob pattern, or an array that combines them. When omitted, it defaults to `./icons`; relative paths start at the config directory.
|
||||||
|
|
||||||
|
`defineSpriteConfig` is an identity helper for TypeScript autocomplete. JavaScript can export the same object with `export default`, while JSON contains the object directly.
|
||||||
|
|
||||||
|
## Specialized wrappers
|
||||||
|
|
||||||
|
The specialized functions are available as wrappers around `generateSprite`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { generateNextSprite, generateReactSprite } from '@gromlab/svg-sprites'
|
||||||
|
|
||||||
|
await generateReactSprite('path/to/config.ts', 'vite')
|
||||||
|
await generateNextSprite('path/to/config.ts', {
|
||||||
|
router: 'app',
|
||||||
|
bundler: 'turbopack',
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
An explicitly supplied target overrides `mode` from the file. Prefer `generateSprite` in new code.
|
||||||
|
|
||||||
|
## Config API
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import {
|
||||||
|
isSpriteMode,
|
||||||
|
loadSpriteConfig,
|
||||||
|
resolveSpriteConfig,
|
||||||
|
resolveSpriteConfigSource,
|
||||||
|
validateSpriteConfig,
|
||||||
|
} from '@gromlab/svg-sprites'
|
||||||
|
```
|
||||||
|
|
||||||
|
- `isSpriteMode(value)` checks whether a value is a supported exact mode.
|
||||||
|
- `loadSpriteConfig(file)` loads an explicitly selected `.ts`, `.js`, or `.json` file.
|
||||||
|
- `resolveSpriteConfigSource(source)` resolves a path as either a config file or a config-less directory.
|
||||||
|
- `validateSpriteConfig(value)` performs runtime validation.
|
||||||
|
- `resolveSpriteConfig(root, config, overrides)` merges values, applies defaults, and resolves paths relative to `root`.
|
||||||
|
|
||||||
|
## Low-level compiler
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import {
|
||||||
|
compileSprite,
|
||||||
|
compileSpriteContent,
|
||||||
|
createShapeTransform,
|
||||||
|
} from '@gromlab/svg-sprites'
|
||||||
|
```
|
||||||
|
|
||||||
|
These functions are intended for custom orchestration. Standard generation should use `generateSprite`.
|
||||||
|
|
||||||
|
## Viewer runtime
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
||||||
|
```
|
||||||
|
|
||||||
|
The browser entry registers `<gromlab-sprite-viewer>`. Bare standalone can also load the self-contained `dist/viewer-element.js` without a bundler.
|
||||||
|
|
||||||
|
For manual registration, import the runtime without the auto-register entry:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { defineSpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
||||||
|
|
||||||
|
defineSpriteViewerElement()
|
||||||
|
```
|
||||||
|
|
||||||
|
Both Viewer entries export the registration function and the same public types:
|
||||||
|
`SpriteViewerColorTheme`, `SpriteViewerElement`, `SpriteViewerManifest`,
|
||||||
|
`SpriteViewerManifestColor`, `SpriteViewerManifestIcon`,
|
||||||
|
`SpriteViewerManifestLoader`, `SpriteViewerManifestModule`,
|
||||||
|
`SpriteViewerManifestUsage`, `SpriteViewerRemoteSource`, `SpriteViewerSource`,
|
||||||
|
and `SpriteViewerSources`. Only `@gromlab/svg-sprites/viewer/element` registers the
|
||||||
|
element as an import side effect.
|
||||||
|
|
||||||
|
The React bridge keeps the component API:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
```
|
||||||
|
|
||||||
|
`SpriteViewer` accepts generated manifests, remote standalone sources, lazy loaders, or an `import.meta.glob` result. The React entry contains `'use client'` and is intended for debug tools; production components are imported from local sprite modules.
|
||||||
674
docs/en/reference/technical.md
Normal file
674
docs/en/reference/technical.md
Normal file
@@ -0,0 +1,674 @@
|
|||||||
|
# Technical reference
|
||||||
|
|
||||||
|
[Documentation index](../README.md)
|
||||||
|
|
||||||
|
[JSON, JavaScript, and TypeScript configuration](../configuration.md)
|
||||||
|
|
||||||
|
Reference for the configuration, generated API, and behavior of `@gromlab/svg-sprites`. For step-by-step setup instructions, see the guide for your stack:
|
||||||
|
|
||||||
|
- [Bare standalone](../guides/standalone.md)
|
||||||
|
- [Standalone + Vite](../guides/standalone-vite.md)
|
||||||
|
- [Standalone + Webpack 5](../guides/standalone-webpack.md)
|
||||||
|
- [React + Vite](../guides/react-vite.md)
|
||||||
|
- [React + Webpack 5](../guides/react-webpack.md)
|
||||||
|
- [Next.js App Router + Turbopack](../guides/next-app-turbopack.md)
|
||||||
|
- [Next.js App Router + Webpack](../guides/next-app-webpack.md)
|
||||||
|
- [Next.js Pages Router + Turbopack](../guides/next-pages-turbopack.md)
|
||||||
|
- [Next.js Pages Router + Webpack](../guides/next-pages-webpack.md)
|
||||||
|
- [Vue + Vite](../guides/vue-vite.md)
|
||||||
|
- [Vue + Webpack](../guides/vue-webpack.md)
|
||||||
|
- [Nuxt + Vite](../guides/nuxt-vite.md)
|
||||||
|
- [Nuxt + Webpack](../guides/nuxt-webpack.md)
|
||||||
|
- [Svelte + Vite](../guides/svelte-vite.md)
|
||||||
|
- [Svelte + Webpack](../guides/svelte-webpack.md)
|
||||||
|
- [SvelteKit + Vite](../guides/sveltekit-vite.md)
|
||||||
|
- [Angular application builder](../guides/angular-application.md)
|
||||||
|
- [Angular + Webpack](../guides/angular-webpack.md)
|
||||||
|
- [Astro + Vite](../guides/astro-vite.md)
|
||||||
|
- [Solid + Vite](../guides/solid-vite.md)
|
||||||
|
- [Solid + Webpack](../guides/solid-webpack.md)
|
||||||
|
- [SolidStart + Vite](../guides/solid-start-vite.md)
|
||||||
|
- [Preact + Vite](../guides/preact-vite.md)
|
||||||
|
- [Preact + Webpack](../guides/preact-webpack.md)
|
||||||
|
- [Qwik + Vite](../guides/qwik-vite.md)
|
||||||
|
- [Lit + Vite](../guides/lit-vite.md)
|
||||||
|
- [Lit + Webpack](../guides/lit-webpack.md)
|
||||||
|
- [Alpine.js + Vite](../guides/alpine-vite.md)
|
||||||
|
- [Alpine.js + Webpack](../guides/alpine-webpack.md)
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- Node.js 18 or newer;
|
||||||
|
- the package is distributed as ESM and is loaded with `import`;
|
||||||
|
- React 18 or 19 is required only for React/Next generated components and `@gromlab/svg-sprites/react`;
|
||||||
|
- for typed package exports, use TypeScript 5+ with `moduleResolution: "bundler"`, `"node16"`, or `"nodenext"`.
|
||||||
|
|
||||||
|
Generation does not require a project dependency. Run the CLI through `npx`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx --yes @gromlab/svg-sprites path/to/svg-sprite.config.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Install the package as a development dependency only when the project needs the
|
||||||
|
Viewer, config types, or the programmatic API:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
## CLI and generation modes
|
||||||
|
|
||||||
|
The CLI accepts exactly one path: an explicitly selected config file or a directory for config-less generation:
|
||||||
|
|
||||||
|
```text
|
||||||
|
svg-sprites [options] <config-file-or-directory>
|
||||||
|
```
|
||||||
|
|
||||||
|
| Environment | Mode |
|
||||||
|
|---|---|
|
||||||
|
| Static HTML / custom publishing | `standalone` |
|
||||||
|
| Standalone + Vite | `standalone@vite` |
|
||||||
|
| Standalone + Webpack 5 | `standalone@webpack` |
|
||||||
|
| React + Vite | `react@vite` |
|
||||||
|
| React + Webpack 5 | `react@webpack` |
|
||||||
|
| Vue + Vite | `vue@vite` |
|
||||||
|
| Vue + Webpack | `vue@webpack` |
|
||||||
|
| Nuxt + Vite | `nuxt@vite` |
|
||||||
|
| Nuxt + Webpack | `nuxt@webpack` |
|
||||||
|
| Svelte + Vite | `svelte@vite` |
|
||||||
|
| Svelte + Webpack | `svelte@webpack` |
|
||||||
|
| SvelteKit + Vite | `sveltekit@vite` |
|
||||||
|
| Angular application builder | `angular@application` |
|
||||||
|
| Angular + Webpack | `angular@webpack` |
|
||||||
|
| Astro + Vite | `astro@vite` |
|
||||||
|
| Solid + Vite | `solid@vite` |
|
||||||
|
| Solid + Webpack | `solid@webpack` |
|
||||||
|
| SolidStart + Vite | `solid-start@vite` |
|
||||||
|
| Preact + Vite | `preact@vite` |
|
||||||
|
| Preact + Webpack | `preact@webpack` |
|
||||||
|
| Qwik + Vite | `qwik@vite` |
|
||||||
|
| Lit + Vite | `lit@vite` |
|
||||||
|
| Lit + Webpack | `lit@webpack` |
|
||||||
|
| Alpine.js + Vite | `alpine@vite` |
|
||||||
|
| Alpine.js + Webpack | `alpine@webpack` |
|
||||||
|
| Next.js App Router + Turbopack | `next@app/turbopack` |
|
||||||
|
| Next.js App Router + Webpack 5 | `next@app/webpack` |
|
||||||
|
| Next.js Pages Router + Turbopack | `next@pages/turbopack` |
|
||||||
|
| Next.js Pages Router + Webpack 5 | `next@pages/webpack` |
|
||||||
|
|
||||||
|
The config file may have any name and use the `.ts`, `.js`, or `.json` extension. The CLI does not discover it by convention: pass the file explicitly. The recommended name is `svg-sprite.config.json`.
|
||||||
|
|
||||||
|
When a directory is passed, all settings come from CLI options. When a config file is passed, CLI options override the file. The full order is `defaults → config → CLI`.
|
||||||
|
|
||||||
|
`--help` and `-h` print usage information without requiring a path. Generation options are `--mode`, `--name`, `--description`, repeatable `--input <path-or-glob>`, plus the `--remove-size`/`--no-remove-size`, `--replace-colors`/`--no-replace-colors`, `--add-transition`/`--no-add-transition`, and `--generated-notice`/`--no-generated-notice` pairs. Transform flags override individual fields, while supplying at least one `--input` replaces the complete config `input` value.
|
||||||
|
|
||||||
|
Quote CLI glob patterns with single quotes so the shell does not expand them before the generator receives them:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
svg-sprites --input './icons/**/*.svg' --input '!./icons/legacy/**' svg-sprite.config.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
The mode must match the application's publishing strategy. Bare `standalone` leaves the public URL to the application; Vite and Webpack modes generate bundler-specific SVG asset integration.
|
||||||
|
|
||||||
|
## Unified configuration
|
||||||
|
|
||||||
|
Each config file defines one independent sprite.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { defineSpriteConfig } from '@gromlab/svg-sprites'
|
||||||
|
|
||||||
|
export default defineSpriteConfig({
|
||||||
|
mode: 'next@app/turbopack',
|
||||||
|
name: 'app',
|
||||||
|
description: 'Shared application icons',
|
||||||
|
input: [
|
||||||
|
'./local-icons',
|
||||||
|
'../../assets/icons/*.svg',
|
||||||
|
'!../../assets/icons/deprecated-*.svg',
|
||||||
|
],
|
||||||
|
transform: {
|
||||||
|
removeSize: true,
|
||||||
|
replaceColors: true,
|
||||||
|
addTransition: true,
|
||||||
|
},
|
||||||
|
generatedNotice: true,
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
| Option | Type | Default | Purpose |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `mode` | `SpriteMode` | None | Generation mode; may be supplied by CLI/API |
|
||||||
|
| `name` | `string` | Derived from the directory | Sprite name; in modes with a component, it also determines the component and public type names |
|
||||||
|
| `description` | `string` | None | Description for types and the debug manifest |
|
||||||
|
| `input` | `string \| string[]` | `./icons` | SVG folders, files, and glob patterns relative to the config directory |
|
||||||
|
| `transform` | `TransformOptions` | All enabled | SVG preparation settings |
|
||||||
|
| `generatedNotice` | `boolean` | `true` | Full or abbreviated warning in generated files |
|
||||||
|
|
||||||
|
### Sprite name
|
||||||
|
|
||||||
|
`name` is written in kebab-case and must start with an ASCII letter:
|
||||||
|
|
||||||
|
```text
|
||||||
|
app → AppIcon
|
||||||
|
file-manager → FileManagerIcon
|
||||||
|
```
|
||||||
|
|
||||||
|
If `name` is omitted, the generator converts the directory name to kebab-case. For a directory named `svg-sprite` or `svg-sprites`, the parent directory's name is used.
|
||||||
|
|
||||||
|
### Icon sources
|
||||||
|
|
||||||
|
`SpriteConfig.input` is optional and has the type `string | string[]`. When it is omitted, the source is the literal `./icons` folder relative to the config directory. In config-less mode, relative paths start at the directory passed to the CLI or API.
|
||||||
|
|
||||||
|
Each positive string may be a literal folder, a literal `.svg` file, or a glob pattern. A literal folder includes only its immediate `*.svg` children. Use an explicit pattern such as `icons/**/*.svg` to traverse nested directories.
|
||||||
|
|
||||||
|
An array combines all positive sources. A pattern prefixed with `!` excludes its matches from the combined result globally, regardless of which positive source included them.
|
||||||
|
|
||||||
|
Supported glob syntax includes:
|
||||||
|
|
||||||
|
| Syntax | Meaning |
|
||||||
|
|---|---|
|
||||||
|
| `*` | Any characters within one path segment |
|
||||||
|
| `**` | Any number of nested directories |
|
||||||
|
| `?` | One character within a path segment |
|
||||||
|
| `{a,b}` | Either alternative |
|
||||||
|
| `[abc]` | One character from the set or range |
|
||||||
|
| `!pattern` | Exclude matches from the full combined input |
|
||||||
|
|
||||||
|
Every positive source or pattern must find at least one SVG, otherwise generation fails. Duplicate paths are removed and the final file list is sorted deterministically. Different SVG files with the same basename remain a conflict because the basename defines the public icon name.
|
||||||
|
|
||||||
|
## Generated module
|
||||||
|
|
||||||
|
After generation, a React or Next.js sprite directory looks like this:
|
||||||
|
|
||||||
|
```text
|
||||||
|
app-icons/
|
||||||
|
├── .gitignore
|
||||||
|
├── svg-sprite.config.json
|
||||||
|
├── index.ts # optional user-owned barrel
|
||||||
|
└── .svg-sprite/
|
||||||
|
├── index.js
|
||||||
|
├── index.d.ts
|
||||||
|
├── icon-data.js
|
||||||
|
├── icon-data.d.ts
|
||||||
|
├── sprite.svg
|
||||||
|
├── svg-sprite.manifest.js
|
||||||
|
├── svg-sprite.manifest.d.ts
|
||||||
|
└── react/
|
||||||
|
├── react-component.js
|
||||||
|
├── react-component.d.ts
|
||||||
|
└── react-component.module.css
|
||||||
|
```
|
||||||
|
|
||||||
|
| File | Purpose |
|
||||||
|
|---|---|
|
||||||
|
| `.svg-sprite/index.js` | Mode-specific production facade and runtime icon-name list |
|
||||||
|
| `.svg-sprite/index.d.ts` | Public declarations for the facade, component, and icon-name union |
|
||||||
|
| `.svg-sprite/svg-sprite.manifest.js` | Debug metadata and the asset URL for `SpriteViewer` |
|
||||||
|
| `.svg-sprite/sprite.svg` | Compiled SVG sprite |
|
||||||
|
| `.svg-sprite/react/react-component.js` | React component runtime without TypeScript or JSX |
|
||||||
|
| `.svg-sprite/react/react-component.d.ts` | React component props, style, and declaration |
|
||||||
|
| `.svg-sprite/react/react-component.module.css` | Styles for the React implementation |
|
||||||
|
| `.svg-sprite/icon-data.js` | Runtime icon-name list and internal IDs |
|
||||||
|
| `.svg-sprite/*.d.ts` | TypeScript declarations for the corresponding JavaScript modules |
|
||||||
|
|
||||||
|
Standalone contracts do not create `react/`. Bare `standalone` contains only the
|
||||||
|
runtime asset and deployment-neutral manifest data:
|
||||||
|
|
||||||
|
```text
|
||||||
|
.svg-sprite/
|
||||||
|
├── sprite.svg
|
||||||
|
└── svg-sprite.manifest.json
|
||||||
|
```
|
||||||
|
|
||||||
|
`standalone@vite` and `standalone@webpack` additionally create `index.*`,
|
||||||
|
`icon-data.*`, and a resolved `svg-sprite.manifest.*`. Their facade contains a
|
||||||
|
native generated Web Component with no external runtime dependencies. Bare
|
||||||
|
`standalone` intentionally does not generate a JavaScript component.
|
||||||
|
|
||||||
|
The generator fully manages `.svg-sprite` and replaces the whole directory on every generation through a staged write with rollback on replacement failure. Any files added inside it are deleted during the next generation. Keep user-owned files alongside it, for example in a root `index.ts` barrel:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Standalone Web Component and TypeScript
|
||||||
|
|
||||||
|
In `standalone@vite` and `standalone@webpack`, a sprite with `name: 'app'`
|
||||||
|
exports the `defineAppIconElement()` registration function and the `<app-icon>`
|
||||||
|
tag:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { defineAppIconElement } from '@/ui/app-icons'
|
||||||
|
|
||||||
|
defineAppIconElement()
|
||||||
|
```
|
||||||
|
|
||||||
|
After registration, use the element in HTML:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<app-icon icon="search" aria-hidden="true"></app-icon>
|
||||||
|
|
||||||
|
<app-icon
|
||||||
|
icon="settings"
|
||||||
|
role="img"
|
||||||
|
aria-label="Settings"
|
||||||
|
></app-icon>
|
||||||
|
```
|
||||||
|
|
||||||
|
The component renders `<svg><use>` in an open Shadow DOM, selects the internal
|
||||||
|
ID and `viewBox`, and obtains the asset URL through the corresponding Vite or
|
||||||
|
Webpack mechanism. The host defaults to `1em × 1em`; set `class`, `style`,
|
||||||
|
`color`, and `--icon-color-N` with ordinary CSS.
|
||||||
|
|
||||||
|
The generated `HTMLElementTagNameMap` types the property API:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const icon = document.createElement('app-icon')
|
||||||
|
|
||||||
|
icon.icon = 'search'
|
||||||
|
icon.icon = 'unknown' // TypeScript error
|
||||||
|
```
|
||||||
|
|
||||||
|
TypeScript does not validate attribute values in plain HTML. Therefore an
|
||||||
|
unknown `icon="unknown"` is also validated at runtime: the component hides its
|
||||||
|
inner SVG and reports an error instead of creating a `#undefined` fragment.
|
||||||
|
Calling `defineAppIconElement()` repeatedly is safe for the same sprite; a
|
||||||
|
different element already registered as `<app-icon>` causes an error.
|
||||||
|
|
||||||
|
## React component and TypeScript
|
||||||
|
|
||||||
|
A sprite with `name: 'app'` exports:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export { AppIcon, appIconNames }
|
||||||
|
export type { AppIconName, AppIconProps, AppIconStyle }
|
||||||
|
```
|
||||||
|
|
||||||
|
### Icon names
|
||||||
|
|
||||||
|
SVG file names become valid `icon` values:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<AppIcon icon="search" />
|
||||||
|
<AppIcon icon="unknown" /> // TypeScript error
|
||||||
|
```
|
||||||
|
|
||||||
|
The runtime list contains the same values:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { appIconNames } from '@/ui/app-icons'
|
||||||
|
|
||||||
|
// readonly ['search', 'settings', 'user']
|
||||||
|
```
|
||||||
|
|
||||||
|
Names containing spaces or other characters that are unsafe in SVG IDs remain part of the public API. For the internal fragment ID, the generator creates a stable, safe hash:
|
||||||
|
|
||||||
|
```text
|
||||||
|
folder open.svg → icon="folder open" → id="icon-<stable-hash>"
|
||||||
|
```
|
||||||
|
|
||||||
|
For these names, use the generated component or the `id` from the debug manifest instead of constructing the fragment ID manually.
|
||||||
|
|
||||||
|
### SVG attributes
|
||||||
|
|
||||||
|
By default, the component renders an `<svg>` and accepts standard SVG attributes:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<AppIcon
|
||||||
|
icon="search"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
color="rebeccapurple"
|
||||||
|
className="searchIcon"
|
||||||
|
aria-label="Search"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
The component does not add accessibility semantics automatically. Pass appropriate `aria-*` attributes, a `role`, or a label based on the icon's purpose.
|
||||||
|
|
||||||
|
### Wrapper
|
||||||
|
|
||||||
|
`wrapped` renders a `<span>` containing the SVG. In this mode, the remaining props apply to the `<span>`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<AppIcon icon="search" wrapped className="iconWrapper" />
|
||||||
|
```
|
||||||
|
|
||||||
|
### Typed CSS custom properties
|
||||||
|
|
||||||
|
`AppIconStyle` extends `CSSProperties` and supports properties in the form `--icon-color-N`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<AppIcon
|
||||||
|
icon="user"
|
||||||
|
style={{
|
||||||
|
'--icon-color-1': '#2563eb',
|
||||||
|
'--icon-color-2': '#dbeafe',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Multiple sprites
|
||||||
|
|
||||||
|
Each directory with a configuration creates an independent mode-specific contract. Framework modes generate their native component and declarations, standalone bundler modes generate a Web Component and declarations, and bare `standalone` generates an SVG and JSON manifest:
|
||||||
|
|
||||||
|
```text
|
||||||
|
app-icons → AppIcon → shared icons
|
||||||
|
analytics-icons → AnalyticsIcon → analytics page icons
|
||||||
|
editor-icons → EditorIcon → editor icons
|
||||||
|
```
|
||||||
|
|
||||||
|
The same source SVG can be added to multiple configurations through `input`. You do not need to copy the file into each sprite directory.
|
||||||
|
|
||||||
|
For multiple sprites, add a separate CLI command for each directory or combine the commands in a shared npm script.
|
||||||
|
|
||||||
|
## Formats and rendering methods
|
||||||
|
|
||||||
|
All current modes generate the `stack` format.
|
||||||
|
|
||||||
|
| Format | `<svg><use>` | `<img>` | CSS background |
|
||||||
|
|---|---:|---:|---:|
|
||||||
|
| `stack` | Yes | Yes | Yes |
|
||||||
|
|
||||||
|
### Generated component
|
||||||
|
|
||||||
|
Use the generated native component documented by the selected exact-mode guide. It knows the internal IDs, constructs the URL, and provides a TypeScript API. React and Next.js use it like this:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<AppIcon icon="search" width={24} height={24} />
|
||||||
|
```
|
||||||
|
|
||||||
|
For `standalone@vite` and `standalone@webpack`, use the generated Web Component:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<app-icon icon="search" style="font-size: 24px"></app-icon>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Manually with `<svg><use>`
|
||||||
|
|
||||||
|
How you obtain `spriteUrl` depends on the bundler.
|
||||||
|
|
||||||
|
Static HTML after the application publishes `.svg-sprite/sprite.svg`:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<svg aria-hidden="true">
|
||||||
|
<use href="/assets/icons.svg#search"></use>
|
||||||
|
</svg>
|
||||||
|
```
|
||||||
|
|
||||||
|
Standalone Vite/Webpack provides generated `getAppIconHref()` and an internal ID
|
||||||
|
map. Do not construct fragments from unsafe file names manually.
|
||||||
|
|
||||||
|
Vite:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import spriteUrl from './.svg-sprite/sprite.svg?no-inline'
|
||||||
|
```
|
||||||
|
|
||||||
|
Webpack 5, Turbopack, and Next.js:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const spriteUrl = new URL('./.svg-sprite/sprite.svg', import.meta.url).href
|
||||||
|
```
|
||||||
|
|
||||||
|
After obtaining the URL, use it in JSX:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<svg width="24" height="24" aria-label="Search">
|
||||||
|
<use href={`${spriteUrl}#search`} />
|
||||||
|
</svg>
|
||||||
|
```
|
||||||
|
|
||||||
|
For names that are unsafe as SVG IDs, use the internal `id` from the manifest.
|
||||||
|
|
||||||
|
### With `<img>`
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<img src={`${spriteUrl}#search`} width={24} height={24} alt="Search" />
|
||||||
|
```
|
||||||
|
|
||||||
|
An SVG inside `<img>` is isolated from the page's CSS. Setting `color` or `--icon-color-N` on the outer element does not change its internal colors.
|
||||||
|
|
||||||
|
### With CSS
|
||||||
|
|
||||||
|
```css
|
||||||
|
.icon {
|
||||||
|
background: url('./.svg-sprite/sprite.svg#search') center / contain no-repeat;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
For a single-color silhouette, you can use a mask:
|
||||||
|
|
||||||
|
```css
|
||||||
|
.icon {
|
||||||
|
background-color: currentColor;
|
||||||
|
mask: url('./.svg-sprite/sprite.svg#search') center / contain no-repeat;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
A mask does not preserve original colors, gradients, or differences between `fill` and `stroke`.
|
||||||
|
|
||||||
|
The path in CSS is resolved relative to the CSS file itself. In these examples, the CSS file is next to `svg-sprite.config.ts`.
|
||||||
|
|
||||||
|
## Assets and caching
|
||||||
|
|
||||||
|
The generated component or standalone facade passes the SVG to the bundler as a separate asset:
|
||||||
|
|
||||||
|
- Vite uses a static import with `?no-inline`;
|
||||||
|
- Webpack 5, Turbopack, and Next.js use `new URL(..., import.meta.url)`;
|
||||||
|
- SVG path data is not serialized into generated JavaScript.
|
||||||
|
|
||||||
|
Bare `standalone` does not participate in an asset pipeline: the application copies
|
||||||
|
or publishes `sprite.svg` and owns its URL, versioning, and cache policy.
|
||||||
|
|
||||||
|
With standard asset naming, the bundler adds a content hash:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/assets/sprite-<hash>.svg
|
||||||
|
```
|
||||||
|
|
||||||
|
This allows the SVG to be cached separately from JavaScript. Changing React code does not change the sprite contents, while changing icons creates a new asset version.
|
||||||
|
|
||||||
|
HTTP cache headers, CDN behavior, and `Cache-Control` are configured by the application or hosting platform. With Webpack, the final file name depends on the project's `assetModuleFilename`.
|
||||||
|
|
||||||
|
## SVG transformations
|
||||||
|
|
||||||
|
All transformations are enabled by default and can be configured independently:
|
||||||
|
|
||||||
|
| Option | Behavior |
|
||||||
|
|---|---|
|
||||||
|
| `removeSize` | Removes `width` and `height` from the root `<svg>` while preserving an existing `viewBox` |
|
||||||
|
| `replaceColors` | Replaces detected `fill` and `stroke` values with `--icon-color-N` |
|
||||||
|
| `addTransition` | Adds transitions for `fill` and `stroke` to colored elements and generated styles |
|
||||||
|
|
||||||
|
To disable an individual operation:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export default defineSpriteConfig({
|
||||||
|
mode: 'next@app/turbopack',
|
||||||
|
transform: {
|
||||||
|
removeSize: false,
|
||||||
|
replaceColors: false,
|
||||||
|
addTransition: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Source SVG files are not modified. Transformations apply only to the generated sprite contents.
|
||||||
|
|
||||||
|
## Color management
|
||||||
|
|
||||||
|
### Monochrome icons
|
||||||
|
|
||||||
|
If one color is detected, its fallback becomes `currentColor`:
|
||||||
|
|
||||||
|
```svg
|
||||||
|
stroke="var(--icon-color-1, currentColor)"
|
||||||
|
```
|
||||||
|
|
||||||
|
Set the color through a prop or CSS:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<AppIcon icon="search" color="rebeccapurple" />
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multicolor icons
|
||||||
|
|
||||||
|
Each unique color gets its own custom property with the original color as its fallback:
|
||||||
|
|
||||||
|
```svg
|
||||||
|
fill="var(--icon-color-1, #798198)"
|
||||||
|
fill="var(--icon-color-2, #ffffff)"
|
||||||
|
fill="var(--icon-color-3, #129d9d)"
|
||||||
|
```
|
||||||
|
|
||||||
|
You can override only the values you need:
|
||||||
|
|
||||||
|
```css
|
||||||
|
.icon {
|
||||||
|
--icon-color-1: #4b5563;
|
||||||
|
--icon-color-3: #14b8a6;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Limitations
|
||||||
|
|
||||||
|
- `none`, `transparent`, `inherit`, `unset`, and `initial` are not replaced;
|
||||||
|
- colors in `fill`, `stroke`, and inline `style` attributes are handled most reliably;
|
||||||
|
- CSS classes and external stylesheets inside the SVG are not the primary transformation use case;
|
||||||
|
- `url(#...)` values may be replaced along with colors, so gradients and patterns require a separate sprite with `replaceColors: false`;
|
||||||
|
- masks, filters, and complex internal CSS rules require visual verification;
|
||||||
|
- page CSS custom properties are available through `<svg><use>`, but not inside `<img>` or a CSS background.
|
||||||
|
|
||||||
|
For a complex icon, you can disable `replaceColors` in a separate sprite configuration.
|
||||||
|
|
||||||
|
## SpriteViewer
|
||||||
|
|
||||||
|
The Viewer uses one Shadow DOM Web Component for every mode. React and future framework components are bridges to that same element, so the visuals and behavior are not duplicated.
|
||||||
|
|
||||||
|
Bare `standalone` loads the self-contained browser bundle and supplies the JSON manifest URL and the published SVG URL:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script
|
||||||
|
type="module"
|
||||||
|
src="https://unpkg.com/@gromlab/svg-sprites@<version>/dist/viewer-element.js"
|
||||||
|
></script>
|
||||||
|
|
||||||
|
<gromlab-sprite-viewer
|
||||||
|
viewer-title="Project icons"
|
||||||
|
manifest-url="/app-icons/manifest.json"
|
||||||
|
sprite-url="/app-icons/sprite.svg"
|
||||||
|
></gromlab-sprite-viewer>
|
||||||
|
```
|
||||||
|
|
||||||
|
`viewer-element.js` has no additional runtime files and can be copied with the other static assets for self-hosting.
|
||||||
|
|
||||||
|
`standalone@vite` and `standalone@webpack` register the same element through an npm entry and pass the generated JS manifest through the `sources` property:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
||||||
|
import spriteManifest from './svg-sprite/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
|
||||||
|
const viewer = document.querySelector<SpriteViewerElement>('gromlab-sprite-viewer')!
|
||||||
|
viewer.sources = [spriteManifest]
|
||||||
|
```
|
||||||
|
|
||||||
|
React and Next.js keep the component API:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
```
|
||||||
|
|
||||||
|
It accepts ready-made manifests, remote standalone sources, an array of lazy loaders, or a record in the format returned by `import.meta.glob`.
|
||||||
|
|
||||||
|
Vite:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
import type { SpriteManifestModule } from '@gromlab/svg-sprites/react'
|
||||||
|
|
||||||
|
const sources = import.meta.glob<SpriteManifestModule>(
|
||||||
|
'/src/**/svg-sprite/.svg-sprite/svg-sprite.manifest.js',
|
||||||
|
)
|
||||||
|
|
||||||
|
export const IconsDebugPage = () => (
|
||||||
|
<SpriteViewer sources={sources} title="Project icons" />
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Webpack and Next.js:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
const sources = [
|
||||||
|
() => import('@/ui/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
() => import('@/features/analytics/icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
]
|
||||||
|
|
||||||
|
export const IconsDebugPage = () => (
|
||||||
|
<SpriteViewer sources={sources} />
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
The Viewer displays groups, search, `viewBox`, CSS custom properties, and fallback colors. Framework manifests get their framework-specific tab plus SVG, IMG, and CSS; standalone manifests get SVG, IMG, and CSS. You can change color values in the interface and immediately inspect the result.
|
||||||
|
|
||||||
|
### Viewer theme
|
||||||
|
|
||||||
|
By default, `colorTheme="auto"` follows `prefers-color-scheme`. You can explicitly pass `light` or `dark`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<SpriteViewer sources={sources} colorTheme="dark" />
|
||||||
|
```
|
||||||
|
|
||||||
|
To synchronize it with the application theme:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<SpriteViewer
|
||||||
|
sources={sources}
|
||||||
|
colorTheme={appTheme}
|
||||||
|
onColorThemeChange={setAppTheme}
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
`@gromlab/svg-sprites/react` contains `'use client'` and renders the Web Component host; its internal Shadow DOM is created after the browser runtime loads. In the Next.js App Router, place the Viewer inside a separate Client Component boundary and use it only on a debug route or in an internal tool.
|
||||||
|
|
||||||
|
## Generated files, Git, and CI
|
||||||
|
|
||||||
|
Every mode except bare `standalone` creates a local `.gitignore` for:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/.svg-sprite/
|
||||||
|
```
|
||||||
|
|
||||||
|
Commit the local `.gitignore` to the repository once. It excludes the other generated files, so generation must run before commands that import the sprite module:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites src/ui/app-icons/svg-sprite.config.ts",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"pretypecheck": "npm run sprites"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
CI must run generation before building or type-checking. Pin `@gromlab/svg-sprites` to an exact version when the CI toolchain must be reproducible. A local package installation is not required unless CI also uses the Viewer, package config types, or the programmatic API.
|
||||||
|
|
||||||
|
Bare `standalone` does not create a `.gitignore` and preserves a user-owned file. If a managed `.gitignore` remains after another mode, bare mode removes it. In every other mode, the generator refuses to overwrite a user-owned `.gitignore` without a generated marker. The root `index.ts` remains user-owned and may re-export the generated API.
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
- In every mode except bare `standalone`, missing `.svg-sprite/index.js`: run the generation script before importing the generated module.
|
||||||
|
- Source not found: pass an existing config file or sprite module directory.
|
||||||
|
- Mode missing: add `mode` to the config or pass `--mode`.
|
||||||
|
- Icon missing from the type: check `input`, the `.svg` extension, glob exclusions, and whether nested folders require `**/*.svg`.
|
||||||
|
- Name conflict: two different SVG files have the same basename; rename one of them.
|
||||||
|
- `Refusing to overwrite a user file`: the sprite module root contains a user-owned `.gitignore` that the generator cannot replace.
|
||||||
|
- The icon does not change color: use `<svg><use>` or the generated component and check `replaceColors`.
|
||||||
|
- Webpack emits an incorrect URL: check Asset Modules, `output.publicPath`, and SVG loaders.
|
||||||
|
- Static sprite returns 404: check the post-generation copy or server alias, and do not put a filesystem `spritePath` into HTML.
|
||||||
|
- The Viewer cannot find the sprite: in bundler modes, check the path to `.svg-sprite/svg-sprite.manifest.js`; for bare `standalone`, check the published `svg-sprite.manifest.json` and `sprite.svg` URLs. Run generation before starting the application.
|
||||||
|
- Build and mode do not match: use the target that corresponds to the actual bundler.
|
||||||
|
|
||||||
|
For custom orchestration and low-level compilation, see the [Programmatic API](programmatic-api.md).
|
||||||
52
docs/ru/README.md
Normal file
52
docs/ru/README.md
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
# Документация
|
||||||
|
|
||||||
|
Для настройки выберите guide одного exact mode. Каждый guide является
|
||||||
|
самостоятельным документом и без изменений используется в AI skills.
|
||||||
|
|
||||||
|
Общий формат JSON, JavaScript и TypeScript config-файлов описан в [руководстве по конфигурации](configuration.md).
|
||||||
|
|
||||||
|
## Гайды быстрого старта
|
||||||
|
|
||||||
|
| Проект | Exact mode | Guide |
|
||||||
|
|---|---|---|
|
||||||
|
| Static HTML или собственная публикация | `standalone` | [Bare standalone](guides/standalone.md) |
|
||||||
|
| Vanilla + Vite | `standalone@vite` | [Standalone + Vite](guides/standalone-vite.md) |
|
||||||
|
| Vanilla + Webpack 5 | `standalone@webpack` | [Standalone + Webpack](guides/standalone-webpack.md) |
|
||||||
|
| React + Vite | `react@vite` | [React + Vite](guides/react-vite.md) |
|
||||||
|
| React + Webpack 5 | `react@webpack` | [React + Webpack](guides/react-webpack.md) |
|
||||||
|
| Vue + Vite | `vue@vite` | [Vue + Vite](guides/vue-vite.md) |
|
||||||
|
| Vue + Webpack | `vue@webpack` | [Vue + Webpack](guides/vue-webpack.md) |
|
||||||
|
| Nuxt + Vite | `nuxt@vite` | [Nuxt + Vite](guides/nuxt-vite.md) |
|
||||||
|
| Nuxt + Webpack | `nuxt@webpack` | [Nuxt + Webpack](guides/nuxt-webpack.md) |
|
||||||
|
| Svelte + Vite | `svelte@vite` | [Svelte + Vite](guides/svelte-vite.md) |
|
||||||
|
| Svelte + Webpack | `svelte@webpack` | [Svelte + Webpack](guides/svelte-webpack.md) |
|
||||||
|
| SvelteKit + Vite | `sveltekit@vite` | [SvelteKit + Vite](guides/sveltekit-vite.md) |
|
||||||
|
| Angular application builder | `angular@application` | [Angular application builder](guides/angular-application.md) |
|
||||||
|
| Angular + Webpack | `angular@webpack` | [Angular + Webpack](guides/angular-webpack.md) |
|
||||||
|
| Astro + Vite | `astro@vite` | [Astro + Vite](guides/astro-vite.md) |
|
||||||
|
| Solid + Vite | `solid@vite` | [Solid + Vite](guides/solid-vite.md) |
|
||||||
|
| Solid + Webpack | `solid@webpack` | [Solid + Webpack](guides/solid-webpack.md) |
|
||||||
|
| SolidStart + Vite | `solid-start@vite` | [SolidStart + Vite](guides/solid-start-vite.md) |
|
||||||
|
| Preact + Vite | `preact@vite` | [Preact + Vite](guides/preact-vite.md) |
|
||||||
|
| Preact + Webpack | `preact@webpack` | [Preact + Webpack](guides/preact-webpack.md) |
|
||||||
|
| Qwik + Vite | `qwik@vite` | [Qwik + Vite](guides/qwik-vite.md) |
|
||||||
|
| Lit + Vite | `lit@vite` | [Lit + Vite](guides/lit-vite.md) |
|
||||||
|
| Lit + Webpack | `lit@webpack` | [Lit + Webpack](guides/lit-webpack.md) |
|
||||||
|
| Alpine.js + Vite | `alpine@vite` | [Alpine.js + Vite](guides/alpine-vite.md) |
|
||||||
|
| Alpine.js + Webpack | `alpine@webpack` | [Alpine.js + Webpack](guides/alpine-webpack.md) |
|
||||||
|
| Next.js App Router + Turbopack | `next@app/turbopack` | [App Router + Turbopack](guides/next-app-turbopack.md) |
|
||||||
|
| Next.js App Router + Webpack | `next@app/webpack` | [App Router + Webpack](guides/next-app-webpack.md) |
|
||||||
|
| Next.js Pages Router + Turbopack | `next@pages/turbopack` | [Pages Router + Turbopack](guides/next-pages-turbopack.md) |
|
||||||
|
| Next.js Pages Router + Webpack | `next@pages/webpack` | [Pages Router + Webpack](guides/next-pages-webpack.md) |
|
||||||
|
|
||||||
|
Все guides используют один порядок:
|
||||||
|
|
||||||
|
1. Генерация спрайта через `npx` без добавления package в проект.
|
||||||
|
2. Использование спрайта в приложении.
|
||||||
|
3. Необязательное подключение Viewer для дебага и превью.
|
||||||
|
|
||||||
|
## Справочники
|
||||||
|
|
||||||
|
- [Конфигурация](configuration.md)
|
||||||
|
- [Технический справочник](reference/technical.md)
|
||||||
|
- [Программный API](reference/programmatic-api.md)
|
||||||
99
docs/ru/configuration.md
Normal file
99
docs/ru/configuration.md
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
# Конфигурация
|
||||||
|
|
||||||
|
Каждый config-файл описывает один независимый спрайт. CLI не ищет конфиг автоматически, поэтому всегда передавайте путь явно:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx --yes @gromlab/svg-sprites path/to/svg-sprite.config.json
|
||||||
|
```
|
||||||
|
|
||||||
|
## JSON
|
||||||
|
|
||||||
|
JSON подходит для большинства проектов и не требует локальной установки пакета:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "next@app/turbopack",
|
||||||
|
"name": "app",
|
||||||
|
"description": "Общие иконки приложения",
|
||||||
|
"input": [
|
||||||
|
"./icons",
|
||||||
|
"../../assets/icons/**/*.svg",
|
||||||
|
"!../../assets/icons/deprecated-*.svg"
|
||||||
|
],
|
||||||
|
"transform": {
|
||||||
|
"removeSize": true,
|
||||||
|
"replaceColors": true,
|
||||||
|
"addTransition": true
|
||||||
|
},
|
||||||
|
"generatedNotice": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| Поле | По умолчанию | Назначение |
|
||||||
|
|---|---|---|
|
||||||
|
| `mode` | Нет | Exact mode, соответствующий framework и сборщику |
|
||||||
|
| `name` | Kebab-case имени каталога модуля; для `svg-sprite` и `svg-sprites` — имени родительского каталога | Имя спрайта; в modes с компонентом также задаёт имя компонента и типов |
|
||||||
|
| `description` | Нет | Описание для типов и Viewer |
|
||||||
|
| `input` | `./icons` | Каталог, SVG-файл, glob-шаблон или массив источников |
|
||||||
|
| `transform` | Все включены | Настройки подготовки SVG |
|
||||||
|
| `generatedNotice` | `true` | Вид предупреждения в generated-файлах |
|
||||||
|
|
||||||
|
Пути и glob-шаблоны в `input` считаются от каталога config-файла. Паттерн с префиксом `!` исключает совпадения.
|
||||||
|
|
||||||
|
## JavaScript
|
||||||
|
|
||||||
|
JavaScript-конфиг экспортирует обычный объект по умолчанию:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default {
|
||||||
|
mode: 'react@vite',
|
||||||
|
name: 'icons',
|
||||||
|
input: './icons',
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Передайте CLI путь к `.js`-файлу так же, как к JSON:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx --yes @gromlab/svg-sprites path/to/svg-sprite.config.js
|
||||||
|
```
|
||||||
|
|
||||||
|
## TypeScript
|
||||||
|
|
||||||
|
Для проверки конфига TypeScript установите пакет как dev dependency:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Используйте `defineSpriteConfig`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { defineSpriteConfig } from '@gromlab/svg-sprites'
|
||||||
|
|
||||||
|
export default defineSpriteConfig({
|
||||||
|
mode: 'react@vite',
|
||||||
|
name: 'icons',
|
||||||
|
input: './icons',
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Или примените `satisfies` с type-only импортом:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import type { SpriteConfig } from '@gromlab/svg-sprites'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mode: 'react@vite',
|
||||||
|
name: 'icons',
|
||||||
|
input: './icons',
|
||||||
|
} satisfies SpriteConfig
|
||||||
|
```
|
||||||
|
|
||||||
|
CLI загружает `.ts`-конфиг напрямую:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx --yes @gromlab/svg-sprites path/to/svg-sprite.config.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
Полный список modes, CLI-флагов, правил именования и transform-опций находится в [техническом справочнике](reference/technical.md).
|
||||||
78
docs/ru/guides/AGENTS.md
Normal file
78
docs/ru/guides/AGENTS.md
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
# Правила гайдов быстрого старта
|
||||||
|
|
||||||
|
## Цель
|
||||||
|
|
||||||
|
Гайд должен помочь читателю как можно быстрее создать SVG-спрайт и использовать его в своём приложении.
|
||||||
|
|
||||||
|
Спрайт является главным результатом. Компоненты и другие сгенерированные файлы описываются только как средства его использования.
|
||||||
|
|
||||||
|
## Область гайда
|
||||||
|
|
||||||
|
Каждый гайд посвящён одному exact mode.
|
||||||
|
|
||||||
|
В гайд включаются только действия и особенности, относящиеся к этому mode. Нельзя переносить в него поведение других сборщиков, фреймворков или modes.
|
||||||
|
|
||||||
|
Все технические утверждения необходимо проверять по реализации соответствующего adapter.
|
||||||
|
|
||||||
|
## Структура
|
||||||
|
|
||||||
|
Гайд состоит из трёх основных частей:
|
||||||
|
|
||||||
|
1. Генерация спрайта.
|
||||||
|
2. Использование спрайта.
|
||||||
|
3. Дебаг и превью через Viewer.
|
||||||
|
|
||||||
|
Первая строка после заголовка должна объяснять, что это инструкция по быстрому созданию SVG-спрайта и для какого приложения она предназначена.
|
||||||
|
|
||||||
|
## Примеры
|
||||||
|
|
||||||
|
Все примеры внутри гайда должны составлять один последовательный сценарий.
|
||||||
|
|
||||||
|
Пути, имена, команды, импорты и названия сгенерированных API должны соответствовать друг другу и фактическому результату генерации.
|
||||||
|
|
||||||
|
Во всех гайдах используются согласованные примеры:
|
||||||
|
|
||||||
|
- исходные SVG находятся в `assets/svg-icons`;
|
||||||
|
- спрайт создаётся в `assets/app-icons`;
|
||||||
|
- конфиг записывается в JSON;
|
||||||
|
- имя спрайта в конфиге — `app`.
|
||||||
|
|
||||||
|
## Зависимости
|
||||||
|
|
||||||
|
В разделе генерации нужно явно показать ключевое преимущество: для создания и использования спрайта пакет не требуется добавлять в зависимости проекта.
|
||||||
|
|
||||||
|
Viewer описывается отдельно как необязательный инструмент разработки. Установка или подключение пакета допускается только в разделе Viewer и только способом, подходящим текущему mode.
|
||||||
|
|
||||||
|
## Содержание
|
||||||
|
|
||||||
|
Гайд должен содержать только минимальный рабочий путь:
|
||||||
|
|
||||||
|
- структуру проекта;
|
||||||
|
- конфиг;
|
||||||
|
- команду генерации;
|
||||||
|
- автоматическую генерацию перед запуском и сборкой, если она необходима;
|
||||||
|
- подключение иконки;
|
||||||
|
- базовую настройку размера и цветов;
|
||||||
|
- подключение Viewer.
|
||||||
|
|
||||||
|
Особенности mode добавляются только тогда, когда без них пример не работает или работает неправильно.
|
||||||
|
|
||||||
|
## Технический шум
|
||||||
|
|
||||||
|
Не нужно описывать внутреннее устройство генератора, сгенерированных файлов и сборщика.
|
||||||
|
|
||||||
|
Не нужно перечислять альтернативные конфигурации, дополнительные API, редкие сценарии и ограничения, не относящиеся к быстрому старту.
|
||||||
|
|
||||||
|
Подробности должны оставаться в reference-документации.
|
||||||
|
|
||||||
|
## Стиль
|
||||||
|
|
||||||
|
Писать для пользователя, а не для разработчика библиотеки.
|
||||||
|
|
||||||
|
Использовать короткие, прямые и практические формулировки.
|
||||||
|
|
||||||
|
Сначала объяснять пользу или цель шага, затем показывать действие.
|
||||||
|
|
||||||
|
Не использовать воду, рекламные формулировки и технические термины, которые не помогают выполнить инструкцию.
|
||||||
|
|
||||||
|
Не начинать документ с перечисления сгенерированных компонентов или особенностей реализации.
|
||||||
31
docs/ru/guides/README.md
Normal file
31
docs/ru/guides/README.md
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# Гайды быстрого старта
|
||||||
|
|
||||||
|
- `standalone`: [bare standalone](standalone.md)
|
||||||
|
- `standalone@vite`: [standalone с Vite](standalone-vite.md)
|
||||||
|
- `standalone@webpack`: [standalone с Webpack](standalone-webpack.md)
|
||||||
|
- `react@vite`: [React с Vite](react-vite.md)
|
||||||
|
- `react@webpack`: [React с Webpack](react-webpack.md)
|
||||||
|
- `vue@vite`: [Vue с Vite](vue-vite.md)
|
||||||
|
- `vue@webpack`: [Vue с Webpack](vue-webpack.md)
|
||||||
|
- `nuxt@vite`: [Nuxt с Vite](nuxt-vite.md)
|
||||||
|
- `nuxt@webpack`: [Nuxt с Webpack](nuxt-webpack.md)
|
||||||
|
- `svelte@vite`: [Svelte с Vite](svelte-vite.md)
|
||||||
|
- `svelte@webpack`: [Svelte с Webpack](svelte-webpack.md)
|
||||||
|
- `sveltekit@vite`: [SvelteKit с Vite](sveltekit-vite.md)
|
||||||
|
- `angular@application`: [Angular application builder](angular-application.md)
|
||||||
|
- `angular@webpack`: [Angular с Webpack](angular-webpack.md)
|
||||||
|
- `astro@vite`: [Astro с Vite](astro-vite.md)
|
||||||
|
- `solid@vite`: [Solid с Vite](solid-vite.md)
|
||||||
|
- `solid@webpack`: [Solid с Webpack](solid-webpack.md)
|
||||||
|
- `solid-start@vite`: [SolidStart с Vite](solid-start-vite.md)
|
||||||
|
- `preact@vite`: [Preact с Vite](preact-vite.md)
|
||||||
|
- `preact@webpack`: [Preact с Webpack](preact-webpack.md)
|
||||||
|
- `qwik@vite`: [Qwik с Vite](qwik-vite.md)
|
||||||
|
- `lit@vite`: [Lit с Vite](lit-vite.md)
|
||||||
|
- `lit@webpack`: [Lit с Webpack](lit-webpack.md)
|
||||||
|
- `alpine@vite`: [Alpine.js с Vite](alpine-vite.md)
|
||||||
|
- `alpine@webpack`: [Alpine.js с Webpack](alpine-webpack.md)
|
||||||
|
- `next@app/turbopack`: [App Router с Turbopack](next-app-turbopack.md)
|
||||||
|
- `next@app/webpack`: [App Router с Webpack](next-app-webpack.md)
|
||||||
|
- `next@pages/turbopack`: [Pages Router с Turbopack](next-pages-turbopack.md)
|
||||||
|
- `next@pages/webpack`: [Pages Router с Webpack](next-pages-webpack.md)
|
||||||
91
docs/ru/guides/alpine-vite.md
Normal file
91
docs/ru/guides/alpine-vite.md
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
# SVG-спрайт для Alpine.js на Vite
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в Alpine.js-приложении на Vite.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "alpine@vite",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Генератор не нужно добавлять в зависимости приложения: запускайте его через `npx`.
|
||||||
|
|
||||||
|
Добавьте генерацию перед запуском разработки и production-сборкой:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "vite",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "vite build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Значение `name: "app"` создаёт Alpine plugin `appAlpinePlugin`, директиву `x-app-icon` и magic `$appIconHref`.
|
||||||
|
|
||||||
|
Создайте `assets/app-icons/index.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Зарегистрируйте generated plugin до запуска Alpine:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import Alpine from 'alpinejs'
|
||||||
|
import { appAlpinePlugin } from '../assets/app-icons/index.js'
|
||||||
|
|
||||||
|
Alpine.plugin(appAlpinePlugin)
|
||||||
|
Alpine.start()
|
||||||
|
```
|
||||||
|
|
||||||
|
Используйте реактивную директиву на SVG-элементе:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<svg
|
||||||
|
x-data="{ iconName: 'icon-name' }"
|
||||||
|
x-app-icon="iconName"
|
||||||
|
role="img"
|
||||||
|
aria-label="Готово"
|
||||||
|
style="width:24px;height:24px;color:#334155;--icon-color-2:#f59e0b"
|
||||||
|
></svg>
|
||||||
|
```
|
||||||
|
|
||||||
|
Выражение директивы возвращает имя исходного SVG без расширения. Монохромная иконка наследует `color`, а слои многоцветной иконки переопределяются через `--icon-color-N`. Vite подключает generated CSS и выпускает `sprite.svg` отдельным production asset.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer показывает все иконки на одной странице и нужен только при разработке. Установите его отдельно:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Добавьте Viewer на development-страницу:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<gromlab-sprite-viewer viewer-title="Иконки проекта"></gromlab-sprite-viewer>
|
||||||
|
<script type="module" src="/src/svg-sprite-debug.js"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
Создайте `src/svg-sprite-debug.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
import spriteManifest from '../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
|
||||||
|
document.querySelector('gromlab-sprite-viewer').sources = [spriteManifest]
|
||||||
|
```
|
||||||
|
|
||||||
|
Запустите `npm run dev` и откройте development-страницу. Viewer не зависит от Alpine plugin.
|
||||||
103
docs/ru/guides/alpine-webpack.md
Normal file
103
docs/ru/guides/alpine-webpack.md
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
# SVG-спрайт для Alpine.js на Webpack 5
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в Alpine.js-приложении на Webpack 5.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "alpine@webpack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Генератор не нужно добавлять в зависимости приложения: запускайте его через `npx`.
|
||||||
|
|
||||||
|
Добавьте генерацию перед запуском разработки и production-сборкой:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "webpack serve --mode development",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "webpack --mode production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Значение `name: "app"` создаёт Alpine plugin `appAlpinePlugin`, директиву `x-app-icon` и magic `$appIconHref`.
|
||||||
|
|
||||||
|
Generated CSS Alpine импортируется с query `?inline`. Добавьте правило Asset Modules в `webpack.config.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default {
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.css$/,
|
||||||
|
resourceQuery: /inline/,
|
||||||
|
type: 'asset/source',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Создайте `assets/app-icons/index.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Зарегистрируйте generated plugin до запуска Alpine:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import Alpine from 'alpinejs'
|
||||||
|
import { appAlpinePlugin } from '../assets/app-icons/index.js'
|
||||||
|
|
||||||
|
Alpine.plugin(appAlpinePlugin)
|
||||||
|
Alpine.start()
|
||||||
|
```
|
||||||
|
|
||||||
|
Используйте реактивную директиву на SVG-элементе:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<svg
|
||||||
|
x-data="{ iconName: 'icon-name' }"
|
||||||
|
x-app-icon="iconName"
|
||||||
|
role="img"
|
||||||
|
aria-label="Готово"
|
||||||
|
style="width:24px;height:24px;color:#334155;--icon-color-2:#f59e0b"
|
||||||
|
></svg>
|
||||||
|
```
|
||||||
|
|
||||||
|
Выражение директивы возвращает имя исходного SVG без расширения. Монохромная иконка наследует `color`, а слои многоцветной иконки переопределяются через `--icon-color-N`. Webpack 5 выпускает `sprite.svg` отдельным production asset.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer показывает все иконки на одной странице и нужен только при разработке. Установите его отдельно:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Добавьте Viewer в development entry:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
import spriteManifest from '../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
|
||||||
|
const viewer = document.createElement('gromlab-sprite-viewer')
|
||||||
|
viewer.viewerTitle = 'Иконки проекта'
|
||||||
|
viewer.sources = [spriteManifest]
|
||||||
|
document.body.append(viewer)
|
||||||
|
```
|
||||||
|
|
||||||
|
Подключайте этот entry только при разработке. Viewer не зависит от Alpine plugin.
|
||||||
94
docs/ru/guides/angular-application.md
Normal file
94
docs/ru/guides/angular-application.md
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
# SVG-спрайт для Angular с Application Builder
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в Angular-приложении на `@angular/build:application`.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "angular@application",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Пакет не нужно добавлять в зависимости проекта. Запускайте генерацию через `npx` перед разработкой и production-сборкой:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"prestart": "npm run sprites",
|
||||||
|
"start": "ng serve",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "ng build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Application Builder выпускает импортированный SVG отдельным файлом при включённом file loader. Добавьте опцию в build target файла `angular.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"builder": "@angular/build:application",
|
||||||
|
"options": {
|
||||||
|
"loader": { ".svg": "file" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Создайте `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index'
|
||||||
|
```
|
||||||
|
|
||||||
|
Импортируйте сгенерированный standalone-компонент. Значение `name: "app"` создаёт `AppIcon` с селектором `app-icon`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { Component } from '@angular/core'
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-root',
|
||||||
|
standalone: true,
|
||||||
|
imports: [AppIcon],
|
||||||
|
template: `
|
||||||
|
<app-icon
|
||||||
|
icon="icon-name"
|
||||||
|
role="img"
|
||||||
|
aria-label="Готово"
|
||||||
|
style="width: 24px; height: 24px; color: #334155; --icon-color-2: #f59e0b"
|
||||||
|
/>
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
export class AppComponent {}
|
||||||
|
```
|
||||||
|
|
||||||
|
Input `icon` типизирован именами исходных файлов. Монохромные иконки наследуют `color`, отдельные цвета задаются через `--icon-color-N`.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer необязателен и нужен только при разработке:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Импортируйте `@gromlab/svg-sprites/viewer/element`, добавьте `CUSTOM_ELEMENTS_SCHEMA` и поместите `<gromlab-sprite-viewer [sources]="viewerSources" />` в шаблон. Загрузите generated manifest без framework-specific metadata:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
readonly viewerSources = [async () => {
|
||||||
|
const { default: manifest } = await import(
|
||||||
|
'../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
)
|
||||||
|
const { usage: _usage, ...viewerManifest } = manifest
|
||||||
|
return viewerManifest
|
||||||
|
}]
|
||||||
|
```
|
||||||
|
|
||||||
|
Viewer использует тот же production URL спрайта, что и `AppIcon`.
|
||||||
93
docs/ru/guides/angular-webpack.md
Normal file
93
docs/ru/guides/angular-webpack.md
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
# SVG-спрайт для Angular на Webpack
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в Angular-приложении со штатным Webpack browser builder из Angular CLI.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "angular@webpack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Mode предназначен для workspace, где build target использует официальный Webpack builder:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"builder": "@angular-devkit/build-angular:browser"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Пакет не нужно добавлять в зависимости проекта. Генерируйте спрайт через `npx` перед каждым запуском и сборкой:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"prestart": "npm run sprites",
|
||||||
|
"start": "ng serve",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "ng build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Webpack разрешает generated-выражение `new URL(..., import.meta.url)` и выпускает `sprite.svg` как production asset.
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Создайте `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index'
|
||||||
|
```
|
||||||
|
|
||||||
|
Импортируйте сгенерированный standalone-компонент. Значение `name: "app"` создаёт `AppIcon` с селектором `app-icon`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { Component } from '@angular/core'
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-root',
|
||||||
|
standalone: true,
|
||||||
|
imports: [AppIcon],
|
||||||
|
template: `
|
||||||
|
<app-icon
|
||||||
|
icon="icon-name"
|
||||||
|
role="img"
|
||||||
|
aria-label="Готово"
|
||||||
|
style="width: 24px; height: 24px; color: #334155; --icon-color-2: #f59e0b"
|
||||||
|
/>
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
export class AppComponent {}
|
||||||
|
```
|
||||||
|
|
||||||
|
Input `icon` типизирован именами исходных файлов. Монохромные иконки наследуют `color`, отдельные цвета задаются через `--icon-color-N`.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer необязателен и нужен только при разработке:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Импортируйте `@gromlab/svg-sprites/viewer/element`, добавьте `CUSTOM_ELEMENTS_SCHEMA` и поместите `<gromlab-sprite-viewer [sources]="viewerSources" />` в шаблон:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
readonly viewerSources = [async () => {
|
||||||
|
const { default: manifest } = await import(
|
||||||
|
'../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
)
|
||||||
|
const { usage: _usage, ...viewerManifest } = manifest
|
||||||
|
return viewerManifest
|
||||||
|
}]
|
||||||
|
```
|
||||||
|
|
||||||
|
Viewer и `AppIcon` используют один выпущенный Webpack URL спрайта.
|
||||||
92
docs/ru/guides/astro-vite.md
Normal file
92
docs/ru/guides/astro-vite.md
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
# SVG-спрайт для Astro на Vite
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в Astro-приложении на Vite.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "astro@vite",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Пакет не нужно добавлять в зависимости проекта. Генерируйте спрайт через `npx` перед разработкой и production-сборкой:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "astro dev",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "astro check && astro build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Создайте `assets/app-icons/index.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Создайте `assets/app-icons/index.d.ts` для того же типизированного API:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Значение `name: "app"` создаёт нативный Astro-компонент `AppIcon`. Используйте его на странице:
|
||||||
|
|
||||||
|
```astro
|
||||||
|
---
|
||||||
|
import { AppIcon } from '../../assets/app-icons/index.js'
|
||||||
|
---
|
||||||
|
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
role="img"
|
||||||
|
aria-label="Готово"
|
||||||
|
style="color: #334155; --icon-color-2: #f59e0b"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
Prop `icon` типизирован именами исходных файлов. Vite выпускает `sprite.svg` из статического asset import компонента.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer необязателен и нужен только при разработке:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Добавьте Viewer на страницу и подключите generated manifest в клиентском скрипте:
|
||||||
|
|
||||||
|
```astro
|
||||||
|
<gromlab-sprite-viewer id="sprite-viewer"></gromlab-sprite-viewer>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
||||||
|
|
||||||
|
const viewer = document.querySelector<SpriteViewerElement>('#sprite-viewer')!
|
||||||
|
viewer.sources = [async () => {
|
||||||
|
const { default: manifest } = await import(
|
||||||
|
'../../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
)
|
||||||
|
const { usage: _usage, ...viewerManifest } = manifest
|
||||||
|
return viewerManifest
|
||||||
|
}]
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
Manifest сохраняет Astro usage metadata, а Viewer отображает тот же production-спрайт.
|
||||||
86
docs/ru/guides/lit-vite.md
Normal file
86
docs/ru/guides/lit-vite.md
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
# SVG-спрайт для Lit на Vite
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в Lit-приложении на Vite.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "lit@vite",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Генератор не нужно добавлять в зависимости приложения: запускайте его через `npx`.
|
||||||
|
|
||||||
|
Добавьте генерацию перед запуском разработки и production-сборкой:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "vite",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "vite build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Значение `name: "app"` создаёт Lit-класс `AppIcon`, тег `<app-icon>` и функцию регистрации `defineAppIcon`.
|
||||||
|
|
||||||
|
Создайте `assets/app-icons/index.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Зарегистрируйте компонент перед его отображением:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { defineAppIcon } from '../assets/app-icons/index.js'
|
||||||
|
|
||||||
|
defineAppIcon()
|
||||||
|
|
||||||
|
document.querySelector('#app').innerHTML = `
|
||||||
|
<app-icon
|
||||||
|
icon="icon-name"
|
||||||
|
role="img"
|
||||||
|
aria-label="Готово"
|
||||||
|
style="width:24px;height:24px;color:#334155;--icon-color-2:#f59e0b"
|
||||||
|
></app-icon>
|
||||||
|
`
|
||||||
|
```
|
||||||
|
|
||||||
|
Свойство `icon` принимает имя исходного SVG без расширения. Монохромная иконка наследует `color`, а слои многоцветной иконки переопределяются через `--icon-color-N`. Vite подключает CSS компонента и выпускает `sprite.svg` отдельным production asset.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer показывает все иконки на одной странице и нужен только при разработке. Установите его отдельно:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Добавьте Viewer на development-страницу:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<gromlab-sprite-viewer viewer-title="Иконки проекта"></gromlab-sprite-viewer>
|
||||||
|
<script type="module" src="/src/svg-sprite-debug.js"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
Создайте `src/svg-sprite-debug.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
import spriteManifest from '../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
|
||||||
|
document.querySelector('gromlab-sprite-viewer').sources = [spriteManifest]
|
||||||
|
```
|
||||||
|
|
||||||
|
Запустите `npm run dev` и откройте development-страницу. Viewer не требуется для работы `AppIcon`.
|
||||||
98
docs/ru/guides/lit-webpack.md
Normal file
98
docs/ru/guides/lit-webpack.md
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
# SVG-спрайт для Lit на Webpack 5
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в Lit-приложении на Webpack 5.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "lit@webpack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Генератор не нужно добавлять в зависимости приложения: запускайте его через `npx`.
|
||||||
|
|
||||||
|
Добавьте генерацию перед запуском разработки и production-сборкой:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "webpack serve --mode development",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "webpack --mode production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Значение `name: "app"` создаёт Lit-класс `AppIcon`, тег `<app-icon>` и функцию регистрации `defineAppIcon`.
|
||||||
|
|
||||||
|
Generated CSS Lit импортируется с query `?inline`. Добавьте правило Asset Modules в `webpack.config.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default {
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.css$/,
|
||||||
|
resourceQuery: /inline/,
|
||||||
|
type: 'asset/source',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Создайте `assets/app-icons/index.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Зарегистрируйте компонент перед его отображением:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { defineAppIcon } from '../assets/app-icons/index.js'
|
||||||
|
|
||||||
|
defineAppIcon()
|
||||||
|
|
||||||
|
document.querySelector('#app').innerHTML = `
|
||||||
|
<app-icon
|
||||||
|
icon="icon-name"
|
||||||
|
role="img"
|
||||||
|
aria-label="Готово"
|
||||||
|
style="width:24px;height:24px;color:#334155;--icon-color-2:#f59e0b"
|
||||||
|
></app-icon>
|
||||||
|
`
|
||||||
|
```
|
||||||
|
|
||||||
|
Свойство `icon` принимает имя исходного SVG без расширения. Монохромная иконка наследует `color`, а слои многоцветной иконки переопределяются через `--icon-color-N`. Webpack 5 выпускает `sprite.svg` отдельным production asset.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer показывает все иконки на одной странице и нужен только при разработке. Установите его отдельно:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Добавьте Viewer в development entry:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
import spriteManifest from '../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
|
||||||
|
const viewer = document.createElement('gromlab-sprite-viewer')
|
||||||
|
viewer.viewerTitle = 'Иконки проекта'
|
||||||
|
viewer.sources = [spriteManifest]
|
||||||
|
document.body.append(viewer)
|
||||||
|
```
|
||||||
|
|
||||||
|
Подключайте этот entry только при разработке. Viewer не требуется для работы `AppIcon`.
|
||||||
108
docs/ru/guides/next-app-turbopack.md
Normal file
108
docs/ru/guides/next-app-turbopack.md
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
# SVG-спрайт для Next.js App Router с Turbopack
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в приложении Next.js с App Router и Turbopack.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
Пример конфига:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "next@app/turbopack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Пакет не нужно добавлять в зависимости проекта: генерация запускается через `npx`.
|
||||||
|
|
||||||
|
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "next dev --turbopack",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "next build --turbopack"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Значение `name: "app"` создаёт React-компонент `AppIcon`.
|
||||||
|
|
||||||
|
Создайте точку входа `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Используйте компонент в Server Component:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
// app/page.tsx
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
role="img"
|
||||||
|
aria-label="Готово"
|
||||||
|
style={{
|
||||||
|
color: '#334155',
|
||||||
|
'--icon-color-2': '#f59e0b',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Для `AppIcon` не нужен `'use client'`. Turbopack сам добавляет `sprite.svg` в итоговую сборку, поэтому переносить его в `public` не нужно.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки и устанавливается отдельно:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Создайте Client Component `app/svg-sprite/SvgSpriteViewer.tsx`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
'use client'
|
||||||
|
|
||||||
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
|
||||||
|
const sources = [
|
||||||
|
() => import('../../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
] as const
|
||||||
|
|
||||||
|
export function SvgSpriteViewer() {
|
||||||
|
return <SpriteViewer sources={sources} title="Иконки проекта" />
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Создайте маршрут `app/svg-sprite/page.tsx`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { notFound } from 'next/navigation'
|
||||||
|
|
||||||
|
import { SvgSpriteViewer } from './SvgSpriteViewer'
|
||||||
|
|
||||||
|
export default function SvgSpritePage() {
|
||||||
|
if (process.env.NODE_ENV !== 'development') notFound()
|
||||||
|
|
||||||
|
return <SvgSpriteViewer />
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Запустите `npm run dev` и откройте `/svg-sprite`. В production маршрут вернёт 404.
|
||||||
108
docs/ru/guides/next-app-webpack.md
Normal file
108
docs/ru/guides/next-app-webpack.md
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
# SVG-спрайт для Next.js App Router с Webpack
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в приложении Next.js с App Router и Webpack.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
Пример конфига:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "next@app/webpack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Пакет не нужно добавлять в зависимости проекта: генерация запускается через `npx`.
|
||||||
|
|
||||||
|
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "next dev --webpack",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "next build --webpack"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Значение `name: "app"` создаёт React-компонент `AppIcon`.
|
||||||
|
|
||||||
|
Создайте точку входа `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Используйте компонент в Server Component:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
// app/page.tsx
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
role="img"
|
||||||
|
aria-label="Готово"
|
||||||
|
style={{
|
||||||
|
color: '#334155',
|
||||||
|
'--icon-color-2': '#f59e0b',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Для `AppIcon` не нужен `'use client'`. Next.js сам добавляет `sprite.svg` в итоговую сборку, поэтому переносить его в `public` не нужно.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки и устанавливается отдельно:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Создайте Client Component `app/svg-sprite/SvgSpriteViewer.tsx`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
'use client'
|
||||||
|
|
||||||
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
|
||||||
|
const sources = [
|
||||||
|
() => import('../../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
] as const
|
||||||
|
|
||||||
|
export function SvgSpriteViewer() {
|
||||||
|
return <SpriteViewer sources={sources} title="Иконки проекта" />
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Создайте маршрут `app/svg-sprite/page.tsx`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { notFound } from 'next/navigation'
|
||||||
|
|
||||||
|
import { SvgSpriteViewer } from './SvgSpriteViewer'
|
||||||
|
|
||||||
|
export default function SvgSpritePage() {
|
||||||
|
if (process.env.NODE_ENV !== 'development') notFound()
|
||||||
|
|
||||||
|
return <SvgSpriteViewer />
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Запустите `npm run dev` и откройте `/svg-sprite`. В production маршрут вернёт 404.
|
||||||
98
docs/ru/guides/next-pages-turbopack.md
Normal file
98
docs/ru/guides/next-pages-turbopack.md
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
# SVG-спрайт для Next.js Pages Router с Turbopack
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в приложении Next.js с Pages Router и Turbopack.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
Пример конфига:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "next@pages/turbopack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Пакет не нужно добавлять в зависимости проекта: генерация запускается через `npx`.
|
||||||
|
|
||||||
|
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "next dev --turbopack",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "next build --turbopack"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Значение `name: "app"` создаёт React-компонент `AppIcon`.
|
||||||
|
|
||||||
|
Создайте точку входа `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Используйте компонент на странице:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
// pages/index.tsx
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
role="img"
|
||||||
|
aria-label="Готово"
|
||||||
|
style={{
|
||||||
|
color: '#334155',
|
||||||
|
'--icon-color-2': '#f59e0b',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Компонент работает с SSR, SSG и клиентскими переходами. Turbopack сам добавляет `sprite.svg` в итоговую сборку, поэтому переносить его в `public` не нужно.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки и устанавливается отдельно:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Создайте страницу `pages/svg-sprite.tsx`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import type { GetStaticProps } from 'next'
|
||||||
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
|
||||||
|
const sources = [
|
||||||
|
() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
] as const
|
||||||
|
|
||||||
|
export default function SvgSpritePage() {
|
||||||
|
return <SpriteViewer sources={sources} title="Иконки проекта" />
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getStaticProps: GetStaticProps = () =>
|
||||||
|
process.env.NODE_ENV === 'development'
|
||||||
|
? { props: {} }
|
||||||
|
: { notFound: true }
|
||||||
|
```
|
||||||
|
|
||||||
|
Запустите `npm run dev` и откройте `/svg-sprite`. В production маршрут вернёт 404.
|
||||||
98
docs/ru/guides/next-pages-webpack.md
Normal file
98
docs/ru/guides/next-pages-webpack.md
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
# SVG-спрайт для Next.js Pages Router с Webpack
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в приложении Next.js с Pages Router и Webpack.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
Пример конфига:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "next@pages/webpack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Пакет не нужно добавлять в зависимости проекта: генерация запускается через `npx`.
|
||||||
|
|
||||||
|
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "next dev --webpack",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "next build --webpack"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Значение `name: "app"` создаёт React-компонент `AppIcon`.
|
||||||
|
|
||||||
|
Создайте точку входа `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Используйте компонент на странице:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
// pages/index.tsx
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
role="img"
|
||||||
|
aria-label="Готово"
|
||||||
|
style={{
|
||||||
|
color: '#334155',
|
||||||
|
'--icon-color-2': '#f59e0b',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Компонент работает с SSR, SSG и клиентскими переходами. Next.js сам добавляет `sprite.svg` в итоговую сборку, поэтому переносить его в `public` не нужно.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки и устанавливается отдельно:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Создайте страницу `pages/svg-sprite.tsx`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import type { GetStaticProps } from 'next'
|
||||||
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
|
||||||
|
const sources = [
|
||||||
|
() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
] as const
|
||||||
|
|
||||||
|
export default function SvgSpritePage() {
|
||||||
|
return <SpriteViewer sources={sources} title="Иконки проекта" />
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getStaticProps: GetStaticProps = () =>
|
||||||
|
process.env.NODE_ENV === 'development'
|
||||||
|
? { props: {} }
|
||||||
|
: { notFound: true }
|
||||||
|
```
|
||||||
|
|
||||||
|
Запустите `npm run dev` и откройте `/svg-sprite`. В production маршрут вернёт 404.
|
||||||
100
docs/ru/guides/nuxt-vite.md
Normal file
100
docs/ru/guides/nuxt-vite.md
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
# SVG-спрайт для Nuxt на Vite
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в Nuxt-приложении на Vite.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
Пример конфига:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "nuxt@vite",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Пакет не нужно добавлять в зависимости проекта: генерация запускается через `npx`.
|
||||||
|
|
||||||
|
Добавьте команды генерации в `package.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "nuxt dev",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "nuxt build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Значение `name: "app"` создаёт Vue-компонент `AppIcon`. Создайте `assets/app-icons/index.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Используйте компонент на странице или в layout Nuxt:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
import { AppIcon } from '../assets/app-icons/index.js'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
role="img"
|
||||||
|
aria-label="Готово"
|
||||||
|
style="color: #334155; --icon-color-2: #f59e0b"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
`AppIcon` безопасен для SSR и не требует client-only обёртки. Vite выпускает `sprite.svg` отдельным production asset.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки и устанавливается отдельно:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Создайте `app/components/SvgSpriteViewer.client.vue`, чтобы browser-only Viewer не выполнялся во время SSR:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
|
||||||
|
const sources = [
|
||||||
|
() => import('../../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
]
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<gromlab-sprite-viewer :sources="sources" viewer-title="Иконки проекта" />
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
Отметьте `gromlab-sprite-viewer` как custom element в `nuxt.config.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
vue: {
|
||||||
|
compilerOptions: {
|
||||||
|
isCustomElement: (tag) => tag === 'gromlab-sprite-viewer',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Покажите `<SvgSpriteViewer />` на странице разработки. Viewer изолирован от generated runtime компонента `AppIcon`.
|
||||||
113
docs/ru/guides/nuxt-webpack.md
Normal file
113
docs/ru/guides/nuxt-webpack.md
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
# SVG-спрайт для Nuxt на Webpack
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в Nuxt-приложении на Webpack.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
Пример конфига:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "nuxt@webpack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Пакет не нужно добавлять в зависимости проекта: генерация запускается через `npx`.
|
||||||
|
|
||||||
|
Подключите Webpack builder Nuxt в `nuxt.config.ts`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @nuxt/webpack-builder
|
||||||
|
```
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
builder: '@nuxt/webpack-builder',
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Добавьте команды генерации в `package.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "nuxt dev",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "nuxt build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Значение `name: "app"` создаёт Vue-компонент `AppIcon`. Создайте `assets/app-icons/index.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Используйте компонент на странице или в layout Nuxt:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
import { AppIcon } from '../assets/app-icons/index.js'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
role="img"
|
||||||
|
aria-label="Готово"
|
||||||
|
style="color: #334155; --icon-color-2: #f59e0b"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
`AppIcon` безопасен для SSR и не требует client-only обёртки. Webpack выпускает `sprite.svg` отдельным production asset.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки и устанавливается отдельно:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Создайте `app/components/SvgSpriteViewer.client.vue`, чтобы browser-only Viewer не выполнялся во время SSR:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
|
||||||
|
const sources = [
|
||||||
|
() => import('../../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
]
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<gromlab-sprite-viewer :sources="sources" viewer-title="Иконки проекта" />
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
Дополните существующие настройки `nuxt.config.ts`, чтобы Vue считал Viewer custom element:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
builder: '@nuxt/webpack-builder',
|
||||||
|
vue: {
|
||||||
|
compilerOptions: {
|
||||||
|
isCustomElement: (tag) => tag === 'gromlab-sprite-viewer',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Покажите `<SvgSpriteViewer />` на странице разработки. Viewer изолирован от generated runtime компонента `AppIcon`.
|
||||||
75
docs/ru/guides/preact-vite.md
Normal file
75
docs/ru/guides/preact-vite.md
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
# SVG-спрайт для Preact на Vite
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в Preact-приложении на Vite.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "preact@vite",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Пакет не нужно добавлять в зависимости проекта. Запускайте его через `npx` перед разработкой и production-сборкой:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "vite",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "tsc --noEmit && vite build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Создайте `assets/app-icons/index.js` и `assets/app-icons/index.d.ts` с одинаковым экспортом:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Используйте сгенерированный Preact-компонент на plain JavaScript:
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
import { AppIcon } from '../assets/app-icons/index.js'
|
||||||
|
|
||||||
|
export function SaveIcon() {
|
||||||
|
return (
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
aria-label="Готово"
|
||||||
|
style={{ color: '#334155', '--icon-color-2': '#f59e0b' }}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Vite автоматически выпускает импортированный `sprite.svg` как production asset.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Установите Viewer только для разработки:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Подключите его в отладочной entry:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
|
||||||
|
const viewer = document.createElement('gromlab-sprite-viewer')
|
||||||
|
viewer.sources = [() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js')]
|
||||||
|
document.body.append(viewer)
|
||||||
|
```
|
||||||
75
docs/ru/guides/preact-webpack.md
Normal file
75
docs/ru/guides/preact-webpack.md
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
# SVG-спрайт для Preact на Webpack
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в Preact-приложении на Webpack 5.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "preact@webpack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Пакет не нужно добавлять в зависимости проекта. Запускайте его через `npx` перед запуском и сборкой Webpack:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "webpack serve --mode development",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "tsc --noEmit && webpack --mode production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Создайте `assets/app-icons/index.js` и `assets/app-icons/index.d.ts` с одинаковым экспортом:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Используйте сгенерированный Preact-компонент:
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
import { AppIcon } from '../assets/app-icons/index.js'
|
||||||
|
|
||||||
|
export function SaveIcon() {
|
||||||
|
return (
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
aria-label="Готово"
|
||||||
|
style={{ color: '#334155', '--icon-color-2': '#f59e0b' }}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Webpack Asset Modules выпускают `sprite.svg` из сгенерированного выражения `new URL(...)`.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Установите Viewer только для разработки:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Подключите его в отдельной development entry:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
|
||||||
|
const viewer = document.createElement('gromlab-sprite-viewer')
|
||||||
|
viewer.sources = [() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js')]
|
||||||
|
document.body.append(viewer)
|
||||||
|
```
|
||||||
82
docs/ru/guides/qwik-vite.md
Normal file
82
docs/ru/guides/qwik-vite.md
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
# SVG-спрайт для Qwik на Vite
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в SSR-приложении Qwik на Vite.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "qwik@vite",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Пакет не нужно добавлять в зависимости проекта. Перегенерируйте спрайт через `npx` перед запуском и сборкой Vite:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "vite --mode ssr",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "tsc --noEmit && vite build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Создайте `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Сгенерированный компонент является Qwik `component$` и безопасен во время SSR:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { component$ } from '@builder.io/qwik'
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
|
export default component$(() => (
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
aria-label="Готово"
|
||||||
|
style={{ color: '#334155', '--icon-color-2': '#f59e0b' }}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
```
|
||||||
|
|
||||||
|
Компонент использует статический Vite asset import и не обращается к browser globals во время SSR.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer работает только в браузере и нужен лишь для разработки:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Загрузите его из visible task:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { component$, useSignal, useVisibleTask$ } from '@builder.io/qwik'
|
||||||
|
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
||||||
|
|
||||||
|
export const IconViewer = component$(() => {
|
||||||
|
const host = useSignal<HTMLElement>()
|
||||||
|
useVisibleTask$(async () => {
|
||||||
|
await import('@gromlab/svg-sprites/viewer/element')
|
||||||
|
const viewer = document.createElement('gromlab-sprite-viewer') as SpriteViewerElement
|
||||||
|
viewer.sources = [() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js')]
|
||||||
|
host.value?.append(viewer)
|
||||||
|
})
|
||||||
|
return <div ref={host} />
|
||||||
|
})
|
||||||
|
```
|
||||||
115
docs/ru/guides/react-vite.md
Normal file
115
docs/ru/guides/react-vite.md
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
# SVG-спрайт для React на Vite
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в React-приложении на Vite.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
Пример конфига:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "react@vite",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Пакет не нужно добавлять в зависимости проекта: генерация запускается через `npx`.
|
||||||
|
|
||||||
|
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "vite",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "tsc --noEmit && vite build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Значение `name: "app"` создаёт React-компонент `AppIcon`.
|
||||||
|
|
||||||
|
Создайте точку входа `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Используйте компонент в приложении:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
|
export function SaveIcon() {
|
||||||
|
return (
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
role="img"
|
||||||
|
aria-label="Готово"
|
||||||
|
style={{
|
||||||
|
color: '#334155',
|
||||||
|
'--icon-color-2': '#f59e0b',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Свойство `icon` принимает имена исходных SVG без расширения. Монохромная иконка наследует `color`, а цвета многоцветной переопределяются через `--icon-color-N`.
|
||||||
|
|
||||||
|
Vite сам подключает стили компонента и добавляет `sprite.svg` в итоговую сборку.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки и устанавливается отдельно:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Создайте `svg-sprite.html` в корне проекта:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="ru">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Иконки проекта</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- React-корень Viewer для дебага и превью SVG-спрайта -->
|
||||||
|
<div id="svg-sprite-viewer"></div>
|
||||||
|
|
||||||
|
<!-- Подключение создаваемого ниже скрипта дебаггера -->
|
||||||
|
<script type="module" src="/src/svg-sprite-debug.tsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
Создайте `src/svg-sprite-debug.tsx`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { createRoot } from 'react-dom/client'
|
||||||
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
|
||||||
|
const sources = [
|
||||||
|
() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
] as const
|
||||||
|
|
||||||
|
createRoot(document.getElementById('svg-sprite-viewer')!).render(
|
||||||
|
<SpriteViewer sources={sources} title="Иконки проекта" />,
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Запустите `npm run dev` и откройте `/svg-sprite.html`.
|
||||||
|
|
||||||
|
Стандартная production-сборка Vite использует только `index.html` и не включает страницу Viewer.
|
||||||
132
docs/ru/guides/react-webpack.md
Normal file
132
docs/ru/guides/react-webpack.md
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
# SVG-спрайт для React на Webpack 5
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в React-приложении на Webpack 5.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
Пример конфига:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "react@webpack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Пакет не нужно добавлять в зависимости проекта: генерация запускается через `npx`.
|
||||||
|
|
||||||
|
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "webpack serve --mode development",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "webpack --mode production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Значение `name: "app"` создаёт React-компонент `AppIcon`.
|
||||||
|
|
||||||
|
Создайте точку входа `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Используйте компонент в приложении:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
|
export function SaveIcon() {
|
||||||
|
return (
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
role="img"
|
||||||
|
aria-label="Готово"
|
||||||
|
style={{
|
||||||
|
color: '#334155',
|
||||||
|
'--icon-color-2': '#f59e0b',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Свойство `icon` принимает имена исходных SVG без расширения. Монохромная иконка наследует `color`, а цвета многоцветной переопределяются через `--icon-color-N`.
|
||||||
|
|
||||||
|
Компонент использует CSS Modules. Если проект ещё не обрабатывает их, установите loaders:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev style-loader css-loader
|
||||||
|
```
|
||||||
|
|
||||||
|
Затем добавьте правило с default export в `webpack.config.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
test: /\.module\.css$/i,
|
||||||
|
use: [
|
||||||
|
'style-loader',
|
||||||
|
{
|
||||||
|
loader: 'css-loader',
|
||||||
|
options: { modules: { namedExport: false } },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Webpack 5 сам добавляет `sprite.svg` в итоговую сборку.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки.
|
||||||
|
|
||||||
|
Установите Viewer:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Создайте entry `src/svg-sprite-debug.tsx`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { createRoot } from 'react-dom/client'
|
||||||
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
|
||||||
|
const sources = [
|
||||||
|
() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
] as const
|
||||||
|
|
||||||
|
const container = document.createElement('div')
|
||||||
|
document.body.append(container)
|
||||||
|
|
||||||
|
createRoot(container).render(
|
||||||
|
<SpriteViewer sources={sources} title="Иконки проекта" />,
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Добавьте скрипт к основному entry только в development-режиме. Сохраните остальные настройки `webpack.config.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default (_env, argv) => ({
|
||||||
|
// Остальные настройки Webpack.
|
||||||
|
entry: [
|
||||||
|
'./src/main.tsx',
|
||||||
|
...(argv.mode === 'development' ? ['./src/svg-sprite-debug.tsx'] : []),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Запустите `npm run dev`. Viewer появится на основной странице приложения и не попадёт в production-сборку.
|
||||||
83
docs/ru/guides/solid-start-vite.md
Normal file
83
docs/ru/guides/solid-start-vite.md
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
# SVG-спрайт для SolidStart на Vite
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в SSR-приложении SolidStart на Vite.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "solid-start@vite",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Пакет не нужно добавлять в зависимости проекта. Перегенерируйте спрайт через `npx` перед запуском и сборкой Vinxi:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "vinxi dev",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "vinxi build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Создайте `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Сгенерированный компонент безопасно рендерится на сервере:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
|
export default function Home() {
|
||||||
|
return (
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
aria-label="Готово"
|
||||||
|
style={{ color: '#334155', '--icon-color-2': '#f59e0b' }}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Компонент использует статический Vite asset import и не обращается к browser globals во время SSR.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer работает только в браузере и нужен лишь для разработки:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Загрузите его из `onMount`, чтобы исключить из серверного рендера:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { onMount } from 'solid-js'
|
||||||
|
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
||||||
|
|
||||||
|
export function IconViewer() {
|
||||||
|
let host!: HTMLDivElement
|
||||||
|
onMount(async () => {
|
||||||
|
await import('@gromlab/svg-sprites/viewer/element')
|
||||||
|
const viewer = document.createElement('gromlab-sprite-viewer') as SpriteViewerElement
|
||||||
|
viewer.sources = [() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js')]
|
||||||
|
host.append(viewer)
|
||||||
|
})
|
||||||
|
return <div ref={host} />
|
||||||
|
}
|
||||||
|
```
|
||||||
83
docs/ru/guides/solid-vite.md
Normal file
83
docs/ru/guides/solid-vite.md
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
# SVG-спрайт для Solid на Vite
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в Solid-приложении на Vite.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "solid@vite",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Пакет не нужно добавлять в зависимости проекта. Запускайте его через `npx` перед разработкой и production-сборкой:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "vite",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "tsc --noEmit && vite build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Создайте `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Имя `app` создаёт Solid-компонент `AppIcon`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
|
export function SaveIcon() {
|
||||||
|
return (
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
aria-label="Готово"
|
||||||
|
style={{ color: '#334155', '--icon-color-2': '#f59e0b' }}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Vite выпускает `sprite.svg` как production asset. Монохромные иконки наследуют `color`, многоцветные используют `--icon-color-N`.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer нужен только во время разработки и устанавливается отдельно:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Подключите его в отладочном компоненте после запуска браузерного кода:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { onMount } from 'solid-js'
|
||||||
|
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
||||||
|
|
||||||
|
export function IconViewer() {
|
||||||
|
let host!: HTMLDivElement
|
||||||
|
onMount(async () => {
|
||||||
|
await import('@gromlab/svg-sprites/viewer/element')
|
||||||
|
const viewer = document.createElement('gromlab-sprite-viewer') as SpriteViewerElement
|
||||||
|
viewer.sources = [() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js')]
|
||||||
|
host.append(viewer)
|
||||||
|
})
|
||||||
|
return <div ref={host} />
|
||||||
|
}
|
||||||
|
```
|
||||||
75
docs/ru/guides/solid-webpack.md
Normal file
75
docs/ru/guides/solid-webpack.md
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
# SVG-спрайт для Solid на Webpack
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в Solid-приложении на Webpack 5.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "solid@webpack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Пакет не нужно добавлять в зависимости проекта. Запускайте его через `npx` перед запуском и сборкой Webpack:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "webpack serve --mode development",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "tsc --noEmit && webpack --mode production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Создайте `assets/app-icons/index.js` и `assets/app-icons/index.d.ts` с одинаковым экспортом:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Используйте сгенерированный Solid-компонент:
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
import { AppIcon } from '../assets/app-icons/index.js'
|
||||||
|
|
||||||
|
export function SaveIcon() {
|
||||||
|
return (
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
aria-label="Готово"
|
||||||
|
style={{ color: '#334155', '--icon-color-2': '#f59e0b' }}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Webpack Asset Modules выпускают `sprite.svg` из сгенерированного `new URL(...)`. Обработка `.jsx` должна охватывать сгенерированный Solid-компонент.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Установите Viewer только для разработки:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Подключите его в отдельной development entry:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
|
||||||
|
const viewer = document.createElement('gromlab-sprite-viewer')
|
||||||
|
viewer.sources = [() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js')]
|
||||||
|
document.body.append(viewer)
|
||||||
|
```
|
||||||
114
docs/ru/guides/standalone-vite.md
Normal file
114
docs/ru/guides/standalone-vite.md
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
# SVG-спрайт для Vite без фреймворка
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в приложении на Vite без фреймворка.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
Пример конфига:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "standalone@vite",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Пакет не нужно добавлять в зависимости проекта: генерация запускается через `npx`.
|
||||||
|
|
||||||
|
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "vite",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "vite build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Значение `name: "app"` создаёт элемент `<app-icon>`.
|
||||||
|
|
||||||
|
Создайте точку входа `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Зарегистрируйте элемент в `src/main.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { defineAppIconElement } from '../assets/app-icons'
|
||||||
|
import './style.css'
|
||||||
|
|
||||||
|
defineAppIconElement()
|
||||||
|
```
|
||||||
|
|
||||||
|
Используйте иконку в HTML:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<app-icon icon="icon-name" role="img" aria-label="Готово"></app-icon>
|
||||||
|
```
|
||||||
|
|
||||||
|
Значение `icon` — имя исходного SVG без расширения. Размер и цвета настраиваются через CSS:
|
||||||
|
|
||||||
|
```css
|
||||||
|
app-icon {
|
||||||
|
font-size: 24px;
|
||||||
|
color: #334155;
|
||||||
|
--icon-color-2: #f59e0b;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Монохромная иконка наследует `color`, а цвета многоцветной иконки переопределяются через `--icon-color-N`. Нужные переменные показывает Viewer.
|
||||||
|
|
||||||
|
Vite сам добавит `sprite.svg` в итоговую сборку. Копировать его в `public` не нужно.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки и устанавливается отдельно:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Создайте `svg-sprite.html` в корне проекта:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="ru">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Иконки проекта</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- Компонент Viewer для дебага и превью SVG-спрайта -->
|
||||||
|
<gromlab-sprite-viewer viewer-title="Иконки проекта"></gromlab-sprite-viewer>
|
||||||
|
|
||||||
|
<!-- Подключение создаваемого ниже скрипта дебаггера -->
|
||||||
|
<script type="module" src="/src/svg-sprite-debug.ts"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
Создайте `src/svg-sprite-debug.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
||||||
|
import spriteManifest from '../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
|
||||||
|
const viewer = document.querySelector<SpriteViewerElement>('gromlab-sprite-viewer')!
|
||||||
|
viewer.sources = [spriteManifest]
|
||||||
|
```
|
||||||
|
|
||||||
|
Запустите `npm run dev` и откройте `/svg-sprite.html`.
|
||||||
|
|
||||||
|
Viewer не требуется для работы `<app-icon>` и не подключается к основному коду приложения.
|
||||||
111
docs/ru/guides/standalone-webpack.md
Normal file
111
docs/ru/guides/standalone-webpack.md
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
# SVG-спрайт для Webpack 5 без фреймворка
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в приложении на Webpack 5 без фреймворка.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
Пример конфига:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "standalone@webpack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Пакет не нужно добавлять в зависимости проекта: генерация запускается через `npx`.
|
||||||
|
|
||||||
|
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "webpack serve --mode development",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "webpack --mode production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Значение `name: "app"` создаёт элемент `<app-icon>`.
|
||||||
|
|
||||||
|
Создайте точку входа `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Зарегистрируйте элемент в основном entry приложения:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { defineAppIconElement } from '../assets/app-icons'
|
||||||
|
import './style.css'
|
||||||
|
|
||||||
|
defineAppIconElement()
|
||||||
|
```
|
||||||
|
|
||||||
|
Используйте иконку в HTML:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<app-icon icon="icon-name" role="img" aria-label="Готово"></app-icon>
|
||||||
|
```
|
||||||
|
|
||||||
|
Значение `icon` — имя исходного SVG без расширения. Размер и цвета настраиваются через CSS:
|
||||||
|
|
||||||
|
```css
|
||||||
|
app-icon {
|
||||||
|
font-size: 24px;
|
||||||
|
color: #334155;
|
||||||
|
--icon-color-2: #f59e0b;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Монохромная иконка наследует `color`, а цвета многоцветной иконки переопределяются через `--icon-color-N`. Нужные переменные показывает Viewer.
|
||||||
|
|
||||||
|
Webpack 5 сам добавит `sprite.svg` в итоговую сборку.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки.
|
||||||
|
|
||||||
|
Установите Viewer:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Создайте entry `src/svg-sprite-debug.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
||||||
|
import spriteManifest from '../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
|
||||||
|
const viewer = document.createElement('gromlab-sprite-viewer') as SpriteViewerElement
|
||||||
|
viewer.viewerTitle = 'Иконки проекта'
|
||||||
|
viewer.sources = [spriteManifest]
|
||||||
|
document.body.append(viewer)
|
||||||
|
```
|
||||||
|
|
||||||
|
Добавьте скрипт к основному entry только в development-режиме. Сохраните остальные настройки `webpack.config.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default (_env, argv) => ({
|
||||||
|
// Остальные настройки Webpack.
|
||||||
|
entry: [
|
||||||
|
'./src/main.ts',
|
||||||
|
...(argv.mode === 'development' ? ['./src/svg-sprite-debug.ts'] : []),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Запустите `npm run dev`. Viewer появится на основной странице приложения.
|
||||||
|
|
||||||
|
Viewer добавляется только в development-сборку и не попадает в production.
|
||||||
83
docs/ru/guides/standalone.md
Normal file
83
docs/ru/guides/standalone.md
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
# SVG-спрайт для сайта без сборщика
|
||||||
|
|
||||||
|
Соберите SVG-иконки в один файл и используйте их на HTML-странице.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Устанавливать пакет в проект не нужно.
|
||||||
|
|
||||||
|
### 1. Создайте конфиг спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "standalone",
|
||||||
|
"name": "icons",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Сгенерируйте спрайт
|
||||||
|
|
||||||
|
Передайте команде путь к конфигу:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Пакет соберёт иконки в каталог `.svg-sprite` рядом с конфигом:
|
||||||
|
|
||||||
|
```text
|
||||||
|
assets/app-icons/.svg-sprite/
|
||||||
|
├── sprite.svg
|
||||||
|
└── svg-sprite.manifest.json
|
||||||
|
```
|
||||||
|
|
||||||
|
- `sprite.svg` — готовый спрайт для использования на сайте.
|
||||||
|
- `svg-sprite.manifest.json` — данные об иконках для Viewer.
|
||||||
|
|
||||||
|
Каталог `.svg-sprite` создаётся автоматически и полностью заменяется при каждой генерации. Не редактируйте его содержимое вручную.
|
||||||
|
|
||||||
|
### 3. Используйте иконку
|
||||||
|
|
||||||
|
В `index.html` укажите путь к созданному `sprite.svg`. После `#` добавьте имя нужной иконки без расширения `.svg`:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<svg
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
aria-label="Готово"
|
||||||
|
>
|
||||||
|
<use href="./assets/app-icons/.svg-sprite/sprite.svg#icon-name"></use>
|
||||||
|
</svg>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
`sprite.svg` — технический файл, а не галерея иконок. При его открытии нельзя удобно просмотреть весь набор. Кроме того, градиенты, маски, фильтры и ссылки на внутренние `id` могут отображаться с артефактами.
|
||||||
|
|
||||||
|
Для визуальной проверки используйте официальный Viewer. Он показывает все иконки спрайта и помогает проверить их цвета и отображение.
|
||||||
|
|
||||||
|
Viewer необязателен и предназначен только для разработки. Устанавливать пакет через npm не нужно.
|
||||||
|
|
||||||
|
Viewer работает напрямую с файлами из `.svg-sprite`. Ничего копировать не нужно.
|
||||||
|
|
||||||
|
### Добавьте Viewer на страницу
|
||||||
|
|
||||||
|
Добавьте в `index.html` module script и укажите пути к generated manifest и спрайту:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script
|
||||||
|
type="module"
|
||||||
|
src="https://cdn.jsdelivr.net/npm/@gromlab/svg-sprites/dist/viewer-element.js"
|
||||||
|
></script>
|
||||||
|
|
||||||
|
<gromlab-sprite-viewer
|
||||||
|
viewer-title="Иконки проекта"
|
||||||
|
manifest-url="./assets/app-icons/.svg-sprite/svg-sprite.manifest.json"
|
||||||
|
sprite-url="./assets/app-icons/.svg-sprite/sprite.svg"
|
||||||
|
></gromlab-sprite-viewer>
|
||||||
|
```
|
||||||
|
|
||||||
|
Viewer можно вынести в отдельный HTML-файл в корне сайта, предназначенный только для разработки и проверки иконок.
|
||||||
95
docs/ru/guides/svelte-vite.md
Normal file
95
docs/ru/guides/svelte-vite.md
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
# SVG-спрайт для Svelte на Vite
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в Svelte-приложении на Vite.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
Пример конфига:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "svelte@vite",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Пакет не нужно добавлять в зависимости проекта: генерация запускается через `npx`.
|
||||||
|
|
||||||
|
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "vite",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "vite build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Значение `name: "app"` создаёт Svelte-компонент `AppIcon`.
|
||||||
|
|
||||||
|
Создайте `assets/app-icons/index.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Используйте компонент в приложении:
|
||||||
|
|
||||||
|
```svelte
|
||||||
|
<script>
|
||||||
|
import { AppIcon } from '../assets/app-icons/index.js'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
role="img"
|
||||||
|
aria-label="Готово"
|
||||||
|
style="color: #334155; --icon-color-2: #f59e0b"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
Свойство `icon` принимает имена исходных SVG без расширения. Монохромная иконка наследует `color`, а цвета многоцветной переопределяются через `--icon-color-N`.
|
||||||
|
|
||||||
|
Vite сам подключает стили компонента и выпускает `sprite.svg` отдельным production asset.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки и устанавливается отдельно:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Добавьте Viewer на страницу или в компонент, используемый только при разработке:
|
||||||
|
|
||||||
|
```svelte
|
||||||
|
<script>
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
|
||||||
|
const sources = [
|
||||||
|
() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
]
|
||||||
|
|
||||||
|
function connectViewer(node) {
|
||||||
|
node.sources = sources
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<gromlab-sprite-viewer
|
||||||
|
use:connectViewer
|
||||||
|
viewer-title="Иконки проекта"
|
||||||
|
></gromlab-sprite-viewer>
|
||||||
|
```
|
||||||
|
|
||||||
|
Запустите `npm run dev` и откройте страницу с Viewer. Не импортируйте этот отладочный компонент из production entry.
|
||||||
105
docs/ru/guides/svelte-webpack.md
Normal file
105
docs/ru/guides/svelte-webpack.md
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
# SVG-спрайт для Svelte на Webpack 5
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в Svelte-приложении на Webpack 5.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
Пример конфига:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "svelte@webpack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Пакет не нужно добавлять в зависимости проекта: генерация запускается через `npx`.
|
||||||
|
|
||||||
|
Добавьте команды генерации в `package.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "webpack serve --mode development",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "webpack --mode production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Значение `name: "app"` создаёт Svelte-компонент `AppIcon`.
|
||||||
|
|
||||||
|
Создайте `assets/app-icons/index.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Используйте компонент в приложении:
|
||||||
|
|
||||||
|
```svelte
|
||||||
|
<script>
|
||||||
|
import { AppIcon } from '../assets/app-icons/index.js'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
role="img"
|
||||||
|
aria-label="Готово"
|
||||||
|
style="color: #334155; --icon-color-2: #f59e0b"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
Generated-компонент является нативным `.svelte`-файлом. Обычное правило `svelte-loader` должно обрабатывать `.svelte`-файлы в `assets`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
test: /\.svelte$/,
|
||||||
|
use: {
|
||||||
|
loader: 'svelte-loader',
|
||||||
|
options: { emitCss: false },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Webpack 5 обрабатывает asset URL из компонента и выпускает `sprite.svg` отдельным production asset.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки и устанавливается отдельно:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Добавьте Viewer в Svelte-компонент, используемый только при разработке:
|
||||||
|
|
||||||
|
```svelte
|
||||||
|
<script>
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
|
||||||
|
const sources = [
|
||||||
|
() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
]
|
||||||
|
|
||||||
|
function connectViewer(node) {
|
||||||
|
node.sources = sources
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<gromlab-sprite-viewer
|
||||||
|
use:connectViewer
|
||||||
|
viewer-title="Иконки проекта"
|
||||||
|
></gromlab-sprite-viewer>
|
||||||
|
```
|
||||||
|
|
||||||
|
Запустите `npm run dev` и откройте страницу с Viewer. Не импортируйте этот отладочный компонент из production entry.
|
||||||
91
docs/ru/guides/sveltekit-vite.md
Normal file
91
docs/ru/guides/sveltekit-vite.md
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
# SVG-спрайт для SvelteKit на Vite
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в SvelteKit-приложении на Vite.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
Пример конфига:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "sveltekit@vite",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Пакет не нужно добавлять в зависимости проекта: генерация запускается через `npx`.
|
||||||
|
|
||||||
|
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "vite dev",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "vite build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Значение `name: "app"` создаёт SSR-safe Svelte-компонент `AppIcon`.
|
||||||
|
|
||||||
|
Создайте `assets/app-icons/index.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Используйте компонент в `src/routes/+page.svelte`:
|
||||||
|
|
||||||
|
```svelte
|
||||||
|
<script>
|
||||||
|
import { AppIcon } from '../../assets/app-icons/index.js'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
role="img"
|
||||||
|
aria-label="Готово"
|
||||||
|
style="color: #334155; --icon-color-2: #f59e0b"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
Свойство `icon` принимает имена исходных SVG без расширения. В компоненте нет browser-only инициализации, поэтому страница может рендериться на сервере. Vite выпускает `sprite.svg` отдельным production asset.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки и устанавливается отдельно:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Создайте отладочный route, например `src/routes/svg-sprite/+page.svelte`. Загружайте custom element из action, чтобы регистрация выполнялась только в браузере:
|
||||||
|
|
||||||
|
```svelte
|
||||||
|
<script>
|
||||||
|
const sources = [
|
||||||
|
() => import('../../../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
]
|
||||||
|
|
||||||
|
function connectViewer(node) {
|
||||||
|
void import('@gromlab/svg-sprites/viewer/element').then(() => {
|
||||||
|
node.sources = sources
|
||||||
|
node.viewerTitle = 'Иконки проекта'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<gromlab-sprite-viewer use:connectViewer></gromlab-sprite-viewer>
|
||||||
|
```
|
||||||
|
|
||||||
|
Запустите `npm run dev` и откройте `/svg-sprite`. Action не выполняется во время SSR.
|
||||||
105
docs/ru/guides/vue-vite.md
Normal file
105
docs/ru/guides/vue-vite.md
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
# SVG-спрайт для Vue на Vite
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в Vue-приложении на Vite.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
Пример конфига:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "vue@vite",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Пакет не нужно добавлять в зависимости проекта: генерация запускается через `npx`.
|
||||||
|
|
||||||
|
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "vite",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "vue-tsc --noEmit && vite build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Значение `name: "app"` создаёт Vue-компонент `AppIcon`.
|
||||||
|
|
||||||
|
Создайте точку входа `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Используйте компонент в приложении:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
role="img"
|
||||||
|
aria-label="Готово"
|
||||||
|
style="color: #334155; --icon-color-2: #f59e0b"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
Свойство `icon` принимает имена исходных SVG без расширения. Монохромная иконка наследует `color`, а цвета многоцветной переопределяются через `--icon-color-N`.
|
||||||
|
|
||||||
|
Vite сам подключает стили компонента и добавляет `sprite.svg` в итоговую сборку.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки и устанавливается отдельно:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Создайте `svg-sprite.html` в корне проекта:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="ru">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Иконки проекта</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<gromlab-sprite-viewer viewer-title="Иконки проекта"></gromlab-sprite-viewer>
|
||||||
|
<script type="module" src="/src/svg-sprite-debug.ts"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
Создайте `src/svg-sprite-debug.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
||||||
|
import spriteManifest from '../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
|
||||||
|
const viewer = document.querySelector<SpriteViewerElement>('gromlab-sprite-viewer')!
|
||||||
|
viewer.sources = [spriteManifest]
|
||||||
|
```
|
||||||
|
|
||||||
|
Запустите `npm run dev` и откройте `/svg-sprite.html`.
|
||||||
|
|
||||||
|
Viewer не требуется для работы `AppIcon` и не подключается к основному коду приложения.
|
||||||
126
docs/ru/guides/vue-webpack.md
Normal file
126
docs/ru/guides/vue-webpack.md
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
# SVG-спрайт для Vue на Webpack 5
|
||||||
|
|
||||||
|
Инструкция по быстрому созданию SVG-спрайта в Vue-приложении на Webpack 5.
|
||||||
|
|
||||||
|
## Генерация спрайта
|
||||||
|
|
||||||
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
|
Пример конфига:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mode": "vue@webpack",
|
||||||
|
"name": "app",
|
||||||
|
"input": "../svg-icons/**/*.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Пакет не нужно добавлять в зависимости проекта: генерация запускается через `npx`.
|
||||||
|
|
||||||
|
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"dev": "webpack serve --mode development",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "webpack --mode production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование спрайта
|
||||||
|
|
||||||
|
Значение `name: "app"` создаёт Vue-компонент `AppIcon`. Создайте `assets/app-icons/index.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Используйте компонент в приложении:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
import { AppIcon } from '../assets/app-icons/index.js'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<AppIcon
|
||||||
|
icon="icon-name"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
role="img"
|
||||||
|
aria-label="Готово"
|
||||||
|
style="color: #334155; --icon-color-2: #f59e0b"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
Свойство `icon` принимает имена исходных SVG без расширения. Монохромная иконка наследует `color`, а цвета многоцветной переопределяются через `--icon-color-N`.
|
||||||
|
|
||||||
|
Компонент использует CSS Modules. Если проект ещё не обрабатывает их, установите `style-loader` и `css-loader`, затем добавьте правило с default export:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev style-loader css-loader
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
test: /\.module\.css$/i,
|
||||||
|
use: [
|
||||||
|
'style-loader',
|
||||||
|
{
|
||||||
|
loader: 'css-loader',
|
||||||
|
options: { modules: { namedExport: false } },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Webpack 5 сам добавляет `sprite.svg` в итоговую сборку.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки и устанавливается отдельно:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
Добавьте Viewer в Vue-компонент, подключаемый только при разработке:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
|
||||||
|
const sources = [
|
||||||
|
() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
]
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<gromlab-sprite-viewer
|
||||||
|
:sources="sources"
|
||||||
|
viewer-title="Иконки проекта"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
Настройте Vue Loader так, чтобы `gromlab-sprite-viewer` считался custom element:
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
test: /\.vue$/,
|
||||||
|
loader: 'vue-loader',
|
||||||
|
options: {
|
||||||
|
compilerOptions: {
|
||||||
|
isCustomElement: (tag) => tag === 'gromlab-sprite-viewer',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Покажите компонент Viewer на странице разработки. Viewer не требуется для работы `AppIcon`.
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
# Legacy mode
|
|
||||||
|
|
||||||
[← Главная](../../README_RU.md)
|
|
||||||
|
|
||||||
Краткая инструкция по генерации централизованных SVG-спрайтов форматов `symbol` и `stack` с optional HTML preview.
|
|
||||||
|
|
||||||
## 1. Установите пакет
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install @gromlab/svg-sprites
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2. Подготовьте иконки и конфиг
|
|
||||||
|
|
||||||
```text
|
|
||||||
project/
|
|
||||||
├── src/assets/icons/
|
|
||||||
│ ├── check.svg
|
|
||||||
│ └── folder.svg
|
|
||||||
└── svg-sprites.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// svg-sprites.config.ts
|
|
||||||
import { defineLegacyConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineLegacyConfig({
|
|
||||||
output: 'public/sprites',
|
|
||||||
preview: true,
|
|
||||||
sprites: [
|
|
||||||
{
|
|
||||||
name: 'icons',
|
|
||||||
input: 'src/assets/icons',
|
|
||||||
format: 'symbol',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
## 3. Запустите генерацию
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx svg-sprites --mode legacy .
|
|
||||||
```
|
|
||||||
|
|
||||||
Результат:
|
|
||||||
|
|
||||||
```text
|
|
||||||
public/sprites/
|
|
||||||
├── icons.sprite.svg
|
|
||||||
└── preview.html
|
|
||||||
```
|
|
||||||
|
|
||||||
При `preview: false` HTML-файл не создаётся. Для формата `stack` укажите `format: 'stack'`.
|
|
||||||
|
|
||||||
## 4. Используйте symbol-спрайт
|
|
||||||
|
|
||||||
```html
|
|
||||||
<svg width="24" height="24" aria-label="Готово">
|
|
||||||
<use href="/sprites/icons.sprite.svg#check"></use>
|
|
||||||
</svg>
|
|
||||||
```
|
|
||||||
|
|
||||||
## 5. Добавьте package script
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"scripts": {
|
|
||||||
"sprites": "svg-sprites --mode legacy .",
|
|
||||||
"prebuild": "npm run sprites"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Несколько спрайтов
|
|
||||||
|
|
||||||
Добавьте несколько записей в `sprites`:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
sprites: [
|
|
||||||
{
|
|
||||||
name: 'icons',
|
|
||||||
input: 'src/assets/icons',
|
|
||||||
format: 'symbol',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'logos',
|
|
||||||
input: 'src/assets/logos',
|
|
||||||
format: 'stack',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
Все результаты и общий `preview.html` будут записаны в `output`.
|
|
||||||
|
|
||||||
## Если что-то не работает
|
|
||||||
|
|
||||||
- Не найден конфиг: убедитесь, что `svg-sprites.config.ts` находится в переданном корне.
|
|
||||||
- Нет иконок: проверьте `sprites[].input` и расширение `.svg`.
|
|
||||||
- Не нужен preview: установите `preview: false`.
|
|
||||||
|
|
||||||
Для программного запуска используйте [`generateLegacy`](programmatic-api.md#generatelegacy).
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
# Миграция с 0.1.x на 1.0
|
|
||||||
|
|
||||||
[← Главная](../../README_RU.md)
|
|
||||||
|
|
||||||
Версия 1.0 разделяет локальную генерацию для React и Next.js и централизованный legacy-режим. Старый config нельзя смешивать с новым API в одном вызове CLI.
|
|
||||||
|
|
||||||
## CLI
|
|
||||||
|
|
||||||
CLI теперь всегда требует явный `--mode` и путь к каталогу конфигурации:
|
|
||||||
|
|
||||||
```text
|
|
||||||
svg-sprites
|
|
||||||
→ svg-sprites --mode <mode> <path>
|
|
||||||
```
|
|
||||||
|
|
||||||
Выберите mode по окружению:
|
|
||||||
|
|
||||||
| Окружение | Mode |
|
|
||||||
|---|---|
|
|
||||||
| React + Vite | `react@vite` |
|
|
||||||
| React + Webpack 5 | `react@webpack` |
|
|
||||||
| Next.js App Router + Turbopack | `next@app/turbopack` |
|
|
||||||
| Next.js App Router + Webpack 5 | `next@app/webpack` |
|
|
||||||
| Next.js Pages Router + Turbopack | `next@pages/turbopack` |
|
|
||||||
| Next.js Pages Router + Webpack 5 | `next@pages/webpack` |
|
|
||||||
| Централизованная старая схема | `legacy` |
|
|
||||||
|
|
||||||
## React и Next.js
|
|
||||||
|
|
||||||
Вместо корневого `svg-sprites.config.ts` создайте локальный `svg-sprite.config.ts` рядом с набором иконок:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineNextSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineNextSpriteConfig({
|
|
||||||
name: 'global',
|
|
||||||
inputFolder: './icons',
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
Для обычного React используйте `defineReactSpriteConfig`. Папку и явный список общих SVG можно объединить через `inputFolder` и `inputFiles`.
|
|
||||||
|
|
||||||
Старые `publicPath` и `react` больше не нужны. Generated-модуль создаётся рядом с конфигом, сам добавляет `.gitignore`, а Vite, Webpack или Next.js выпускает SVG как отдельный asset с content hash.
|
|
||||||
|
|
||||||
Компонент `<SvgSprite icon="..." />` заменяется компонентом, имя которого выводится из `name`:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
<GlobalIcon icon="check" />
|
|
||||||
```
|
|
||||||
|
|
||||||
Для просмотра иконок добавьте `<SpriteViewer>` как debug-страницу приложения. Отдельный `preview.html` остаётся только в legacy-режиме.
|
|
||||||
|
|
||||||
## Legacy-режим
|
|
||||||
|
|
||||||
Если централизованную структуру нужно сохранить, переименуйте helper и поля формата:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineLegacyConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineLegacyConfig({
|
|
||||||
output: 'public/sprites',
|
|
||||||
preview: true,
|
|
||||||
sprites: [
|
|
||||||
{
|
|
||||||
name: 'icons',
|
|
||||||
input: 'src/assets/icons',
|
|
||||||
format: 'stack',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
- `defineConfig` заменён на `defineLegacyConfig`;
|
|
||||||
- `sprites[].mode` переименован в `sprites[].format`;
|
|
||||||
- `generate` заменён на `generateLegacy`;
|
|
||||||
- `loadConfig` заменён на `loadLegacyConfig`;
|
|
||||||
- `publicPath` и генерация старого общего React-компонента удалены.
|
|
||||||
|
|
||||||
Запуск:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
svg-sprites --mode legacy .
|
|
||||||
```
|
|
||||||
|
|
||||||
## Программный API
|
|
||||||
|
|
||||||
Пакет распространяется только как ESM. Замените `require()` на `import`.
|
|
||||||
|
|
||||||
`compileSpriteContent` теперь возвращает `Promise<Uint8Array>`, чтобы публичные декларации не требовали установки `@types/node`. В Node.js фактический результат совместим с API, принимающими `Uint8Array`.
|
|
||||||
|
|
||||||
## После миграции
|
|
||||||
|
|
||||||
1. Удалите старые generated-файлы и правила, которые игнорировали целиком каталог с исходными иконками.
|
|
||||||
2. Добавьте явную команду генерации перед `dev`, `build` и `typecheck`.
|
|
||||||
3. Запустите генерацию и проверку типов.
|
|
||||||
4. Проверьте все иконки и цветовые переменные через `SpriteViewer` или legacy `preview.html`.
|
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
# Next.js App Router
|
|
||||||
|
|
||||||
[← Главная](../../README_RU.md)
|
|
||||||
|
|
||||||
Поддерживаются два явных режима:
|
|
||||||
|
|
||||||
| Сборщик | Mode key | Версия Next.js |
|
|
||||||
|---|---|---|
|
|
||||||
| Turbopack | `next@app/turbopack` | 16.2+ |
|
|
||||||
| Webpack 5 | `next@app/webpack` | 13.4+ |
|
|
||||||
|
|
||||||
## 1. Установите пакет
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install @gromlab/svg-sprites
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2. Создайте sprite-модуль
|
|
||||||
|
|
||||||
```text
|
|
||||||
src/ui/file-manager/svg-sprite/
|
|
||||||
├── icons/
|
|
||||||
│ ├── check.svg
|
|
||||||
│ └── folder.svg
|
|
||||||
└── svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// src/ui/file-manager/svg-sprite/svg-sprite.config.ts
|
|
||||||
import { defineNextSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineNextSpriteConfig({
|
|
||||||
name: 'file-manager',
|
|
||||||
description: 'Иконки файлового менеджера',
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
## 3. Добавьте генерацию
|
|
||||||
|
|
||||||
Для Turbopack:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"scripts": {
|
|
||||||
"sprite:file-manager": "svg-sprites --mode next@app/turbopack src/ui/file-manager/svg-sprite",
|
|
||||||
"predev": "npm run sprite:file-manager",
|
|
||||||
"prebuild": "npm run sprite:file-manager"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Для Webpack замените mode key на `next@app/webpack`. В Next 13–15 Webpack используется обычной командой `next build`, в Next 16 — командой `next build --webpack`.
|
|
||||||
|
|
||||||
## 4. Используйте в Server Component
|
|
||||||
|
|
||||||
Generated-компонент не содержит `'use client'`, поэтому его можно импортировать непосредственно в `page.tsx` или `layout.tsx`:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
import { FileManagerIcon } from '@/ui/file-manager/svg-sprite'
|
|
||||||
|
|
||||||
export default function Page() {
|
|
||||||
return (
|
|
||||||
<main>
|
|
||||||
<FileManagerIcon icon="folder" width={24} height={24} />
|
|
||||||
</main>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Next.js выпустит отдельный SVG asset с content hash. Один generated-код используется при SSR и в браузере без расхождения URL.
|
|
||||||
|
|
||||||
## 5. Добавьте SpriteViewer
|
|
||||||
|
|
||||||
Viewer интерактивен, поэтому для него нужна отдельная Client Component граница:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
'use client'
|
|
||||||
|
|
||||||
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
|
||||||
|
|
||||||
const sources = [
|
|
||||||
() => import('@/ui/file-manager/svg-sprite/manifest'),
|
|
||||||
]
|
|
||||||
|
|
||||||
export default function SpritesPage() {
|
|
||||||
return <SpriteViewer sources={sources} />
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Проверка сборщика
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Turbopack
|
|
||||||
npx next build --turbopack
|
|
||||||
|
|
||||||
# Webpack 5
|
|
||||||
npx next build --webpack
|
|
||||||
```
|
|
||||||
|
|
||||||
Для Next 13–15 с Webpack используйте `npx next build` без флага.
|
|
||||||
|
|
||||||
Команда Next.js и mode key генератора должны указывать один и тот же сборщик.
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
# Next.js Pages Router
|
|
||||||
|
|
||||||
[← Главная](../../README_RU.md)
|
|
||||||
|
|
||||||
Поддерживаются два явных режима:
|
|
||||||
|
|
||||||
| Сборщик | Mode key | Версия Next.js |
|
|
||||||
|---|---|---|
|
|
||||||
| Turbopack | `next@pages/turbopack` | 16.2+ |
|
|
||||||
| Webpack 5 | `next@pages/webpack` | 12.2+ |
|
|
||||||
|
|
||||||
Для Next.js 12.2 требуется React 18.
|
|
||||||
|
|
||||||
## 1. Установите пакет
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install @gromlab/svg-sprites
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2. Создайте sprite-модуль
|
|
||||||
|
|
||||||
```text
|
|
||||||
src/ui/file-manager/svg-sprite/
|
|
||||||
├── icons/
|
|
||||||
│ ├── check.svg
|
|
||||||
│ └── folder.svg
|
|
||||||
└── svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// src/ui/file-manager/svg-sprite/svg-sprite.config.ts
|
|
||||||
import { defineNextSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineNextSpriteConfig({
|
|
||||||
name: 'file-manager',
|
|
||||||
description: 'Иконки файлового менеджера',
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
## 3. Добавьте генерацию
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"scripts": {
|
|
||||||
"sprite:file-manager": "svg-sprites --mode next@pages/webpack src/ui/file-manager/svg-sprite",
|
|
||||||
"predev": "npm run sprite:file-manager",
|
|
||||||
"prebuild": "npm run sprite:file-manager"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Для Next.js 16.2 с Turbopack замените mode key на `next@pages/turbopack`.
|
|
||||||
|
|
||||||
## 4. Используйте на странице
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
import { FileManagerIcon } from '@/ui/file-manager/svg-sprite'
|
|
||||||
|
|
||||||
export default function FilesPage() {
|
|
||||||
return <FileManagerIcon icon="folder" width={24} height={24} />
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getServerSideProps() {
|
|
||||||
return { props: {} }
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Компонент одинаково работает при SSR, SSG и клиентских переходах. Next.js выпускает отдельный SVG asset с content hash.
|
|
||||||
|
|
||||||
## 5. Добавьте SpriteViewer
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
|
||||||
|
|
||||||
const sources = [
|
|
||||||
() => import('@/ui/file-manager/svg-sprite/manifest'),
|
|
||||||
]
|
|
||||||
|
|
||||||
export default function SpritesPage() {
|
|
||||||
return <SpriteViewer sources={sources} />
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Проверка сборщика
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Turbopack
|
|
||||||
npx next build --turbopack
|
|
||||||
|
|
||||||
# Webpack 5
|
|
||||||
npx next build --webpack
|
|
||||||
```
|
|
||||||
|
|
||||||
Для Next 12–15 с Webpack используйте `npx next build` без флага.
|
|
||||||
|
|
||||||
Команда Next.js и mode key генератора должны указывать один и тот же сборщик.
|
|
||||||
@@ -1,203 +0,0 @@
|
|||||||
# Программный API
|
|
||||||
|
|
||||||
[← Главная](../../README_RU.md)
|
|
||||||
|
|
||||||
Пакет предоставляет основную Node.js точку входа и отдельный React runtime entry. Обе точки распространяются только как ESM и подключаются через `import`.
|
|
||||||
|
|
||||||
Для разрешения `@gromlab/svg-sprites/react` в TypeScript используйте `moduleResolution: "bundler"`, `"node16"` или `"nodenext"`.
|
|
||||||
|
|
||||||
## Основной entry
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import {
|
|
||||||
defineNextSpriteConfig,
|
|
||||||
defineReactSpriteConfig,
|
|
||||||
generateNextSprite,
|
|
||||||
generateReactSprite,
|
|
||||||
} from '@gromlab/svg-sprites'
|
|
||||||
```
|
|
||||||
|
|
||||||
Основной entry не импортирует React и может использоваться в CLI, build scripts и Node.js инструментах.
|
|
||||||
|
|
||||||
## `generateReactSprite`
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { generateReactSprite } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
const result = await generateReactSprite(
|
|
||||||
'src/ui/file-manager/svg-sprite',
|
|
||||||
'vite',
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
Второй аргумент обязателен:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type ReactAssetTarget = 'vite' | 'webpack'
|
|
||||||
```
|
|
||||||
|
|
||||||
Результат:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type ReactSpriteGenerationResult = {
|
|
||||||
name: string
|
|
||||||
rootDir: string
|
|
||||||
generatedDir: string
|
|
||||||
spritePath: string
|
|
||||||
manifestPath: string
|
|
||||||
iconCount: number
|
|
||||||
target: 'vite' | 'webpack'
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
```ts
|
|
||||||
console.log(result.name)
|
|
||||||
console.log(result.iconCount)
|
|
||||||
console.log(result.spritePath)
|
|
||||||
console.log(result.manifestPath)
|
|
||||||
```
|
|
||||||
|
|
||||||
Функция загружает `svg-sprite.config.ts` из указанного корня, компилирует SVG и безопасно обновляет managed-файлы.
|
|
||||||
|
|
||||||
## `generateNextSprite`
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { generateNextSprite } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
const result = await generateNextSprite(
|
|
||||||
'src/ui/file-manager/svg-sprite',
|
|
||||||
{
|
|
||||||
router: 'app',
|
|
||||||
bundler: 'turbopack',
|
|
||||||
},
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
Доступные значения:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type NextSpriteGenerationOptions = {
|
|
||||||
router: 'app' | 'pages'
|
|
||||||
bundler: 'turbopack' | 'webpack'
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Результат дополнительно содержит выбранные `router`, `bundler` и полный target вида `next@app/turbopack`.
|
|
||||||
|
|
||||||
## `defineReactSpriteConfig`
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineReactSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineReactSpriteConfig({
|
|
||||||
name: 'file-manager',
|
|
||||||
description: 'Иконки файлового менеджера',
|
|
||||||
inputFolder: './icons',
|
|
||||||
inputFiles: [
|
|
||||||
'../../shared/icons/check.svg',
|
|
||||||
],
|
|
||||||
transform: {
|
|
||||||
removeSize: true,
|
|
||||||
replaceColors: true,
|
|
||||||
addTransition: true,
|
|
||||||
},
|
|
||||||
generatedNotice: true,
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
`inputFolder` и `inputFiles` объединяются. Хелпер возвращает конфиг без runtime-преобразований и предоставляет TypeScript autocomplete.
|
|
||||||
|
|
||||||
## `defineNextSpriteConfig`
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineNextSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineNextSpriteConfig({
|
|
||||||
name: 'file-manager',
|
|
||||||
description: 'Иконки файлового менеджера',
|
|
||||||
inputFolder: './icons',
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
Next.js использует тот же контракт конфигурации, что и React presets.
|
|
||||||
|
|
||||||
## `generateLegacy`
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { generateLegacy } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
const results = await generateLegacy({
|
|
||||||
output: 'public/sprites',
|
|
||||||
preview: false,
|
|
||||||
sprites: [
|
|
||||||
{
|
|
||||||
name: 'icons',
|
|
||||||
input: 'src/assets/icons',
|
|
||||||
format: 'symbol',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
Возвращается массив:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type SpriteResult = {
|
|
||||||
name: string
|
|
||||||
format: 'symbol' | 'stack'
|
|
||||||
spritePath: string
|
|
||||||
iconCount: number
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Подробнее: [Legacy mode](legacy.md).
|
|
||||||
|
|
||||||
## Низкоуровневые функции
|
|
||||||
|
|
||||||
Основная точка входа также экспортирует:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import {
|
|
||||||
compileSprite,
|
|
||||||
compileSpriteContent,
|
|
||||||
createShapeTransform,
|
|
||||||
generatePreview,
|
|
||||||
loadLegacyConfig,
|
|
||||||
loadReactSpriteConfig,
|
|
||||||
resolveSpriteEntry,
|
|
||||||
resolveSprites,
|
|
||||||
} from '@gromlab/svg-sprites'
|
|
||||||
```
|
|
||||||
|
|
||||||
Эти функции предназначены для собственного orchestration поверх существующего compiler и writer. Для стандартного использования предпочтительны `generateReactSprite` и `generateLegacy`.
|
|
||||||
|
|
||||||
## React runtime entry
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
|
||||||
```
|
|
||||||
|
|
||||||
Типы:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import type {
|
|
||||||
SpriteManifest,
|
|
||||||
SpriteManifestColor,
|
|
||||||
SpriteManifestIcon,
|
|
||||||
SpriteManifestLoader,
|
|
||||||
SpriteManifestModule,
|
|
||||||
SpriteViewerColorTheme,
|
|
||||||
SpriteViewerProps,
|
|
||||||
SpriteViewerSource,
|
|
||||||
SpriteViewerSources,
|
|
||||||
} from '@gromlab/svg-sprites/react'
|
|
||||||
```
|
|
||||||
|
|
||||||
React entry содержит `'use client'` и предназначен для debug-инструментов. Generated production-компоненты импортируются из локальных sprite-модулей приложения, а не из React entry пакета.
|
|
||||||
|
|
||||||
`SpriteViewerProps.colorTheme` принимает `auto | light | dark`. Значение `auto` используется по умолчанию и следует `prefers-color-scheme`; для синхронизации с темой приложения передавайте вычисленное `light` или `dark`.
|
|
||||||
|
|
||||||
## Связанные руководства
|
|
||||||
|
|
||||||
- [React + Vite](react-vite.md)
|
|
||||||
- [React + Webpack 5](react-webpack.md)
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
# React + Vite
|
|
||||||
|
|
||||||
[← Главная](../../README_RU.md)
|
|
||||||
|
|
||||||
Краткая инструкция по установке и использованию SVG-спрайтов в проекте на React и Vite.
|
|
||||||
|
|
||||||
В результате вы получите типизированный React-компонент и отдельный кешируемый SVG asset.
|
|
||||||
|
|
||||||
## 1. Установите пакет
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install @gromlab/svg-sprites
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2. Создайте папку спрайта
|
|
||||||
|
|
||||||
```text
|
|
||||||
src/ui/file-manager/svg-sprite/
|
|
||||||
├── icons/
|
|
||||||
│ ├── check.svg
|
|
||||||
│ └── folder.svg
|
|
||||||
└── svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Поместите исходные SVG-файлы в `icons/`.
|
|
||||||
|
|
||||||
## 3. Добавьте конфиг
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// src/ui/file-manager/svg-sprite/svg-sprite.config.ts
|
|
||||||
import { defineReactSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineReactSpriteConfig({
|
|
||||||
name: 'file-manager',
|
|
||||||
description: 'Иконки файлового менеджера',
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
По умолчанию SVG берутся из `./icons`. Общие иконки из других папок можно добавить через `inputFiles`: папка и список объединяются в один спрайт.
|
|
||||||
|
|
||||||
Полный список опций находится в разделе [Конфигурация → React](../../README_RU.md#react).
|
|
||||||
|
|
||||||
## 4. Добавьте генерацию в package.json
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"scripts": {
|
|
||||||
"sprite:file-manager": "svg-sprites --mode react@vite src/ui/file-manager/svg-sprite",
|
|
||||||
"predev": "npm run sprite:file-manager",
|
|
||||||
"prebuild": "npm run sprite:file-manager",
|
|
||||||
"pretypecheck": "npm run sprite:file-manager"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Generated-файлы исключаются из Git, поэтому генерация должна выполняться перед `dev`, `build` и `typecheck`.
|
|
||||||
|
|
||||||
Первый запуск:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run sprite:file-manager
|
|
||||||
```
|
|
||||||
|
|
||||||
## 5. Используйте компонент
|
|
||||||
|
|
||||||
Имя `file-manager` преобразуется в `FileManagerIcon`:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
import { FileManagerIcon } from './svg-sprite'
|
|
||||||
|
|
||||||
export const OpenFolderButton = () => (
|
|
||||||
<button type="button">
|
|
||||||
<FileManagerIcon icon="folder" width={24} height={24} />
|
|
||||||
Открыть
|
|
||||||
</button>
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
Значение `icon` проверяется TypeScript по именам файлов:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
<FileManagerIcon icon="check" /> // допустимо
|
|
||||||
<FileManagerIcon icon="unknown" /> // ошибка TypeScript
|
|
||||||
```
|
|
||||||
|
|
||||||
Типы, способы отображения и управление цветами описаны в [основной документации](../../README_RU.md#способы-отображения).
|
|
||||||
|
|
||||||
Vite выпустит спрайт отдельным файлом вида `assets/sprite-<hash>.svg`. SVG path-данные не попадут в JavaScript.
|
|
||||||
|
|
||||||
## 6. Добавьте debug-страницу
|
|
||||||
|
|
||||||
После подключения иконок можно вывести все React-спрайты через `SpriteViewer`:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
|
||||||
import type { SpriteManifestModule } from '@gromlab/svg-sprites/react'
|
|
||||||
|
|
||||||
const sources = import.meta.glob<SpriteManifestModule>(
|
|
||||||
'/src/**/svg-sprite/manifest.ts',
|
|
||||||
)
|
|
||||||
|
|
||||||
export const IconsDebugPage = () => (
|
|
||||||
<SpriteViewer sources={sources} title="Иконки проекта" />
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
Vite автоматически найдёт generated `manifest.ts` каждого React-спрайта. Шаблон `import.meta.glob` должен быть строковым литералом, а генерация должна выполниться до запуска Vite.
|
|
||||||
|
|
||||||
Размещайте Viewer только на debug-маршруте или во внутреннем инструменте.
|
|
||||||
|
|
||||||
## Если что-то не работает
|
|
||||||
|
|
||||||
- Нет `index.ts`: запустите `npm run sprite:file-manager`.
|
|
||||||
- Viewer не видит спрайт: проверьте путь glob и наличие `manifest.ts`.
|
|
||||||
- Ошибка `Refusing to overwrite a user file`: в generated-пути находится пользовательский файл.
|
|
||||||
- Иконка не меняет цвет: используйте `color` или `--icon-color-N`.
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
# React + Webpack 5
|
|
||||||
|
|
||||||
[← Главная](../../README_RU.md)
|
|
||||||
|
|
||||||
Краткая инструкция по установке и использованию SVG-спрайтов в проекте на React и Webpack 5.
|
|
||||||
|
|
||||||
В результате вы получите типизированный React-компонент и отдельный SVG asset через Webpack Asset Modules.
|
|
||||||
|
|
||||||
## 1. Установите пакет
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install @gromlab/svg-sprites
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2. Создайте папку спрайта
|
|
||||||
|
|
||||||
```text
|
|
||||||
src/ui/file-manager/svg-sprite/
|
|
||||||
├── icons/
|
|
||||||
│ ├── check.svg
|
|
||||||
│ └── folder.svg
|
|
||||||
└── svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Поместите исходные SVG-файлы в `icons/`.
|
|
||||||
|
|
||||||
## 3. Добавьте конфиг
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// src/ui/file-manager/svg-sprite/svg-sprite.config.ts
|
|
||||||
import { defineReactSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineReactSpriteConfig({
|
|
||||||
name: 'file-manager',
|
|
||||||
description: 'Иконки файлового менеджера',
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
По умолчанию SVG берутся из `./icons`. Общие иконки из других папок можно добавить через `inputFiles`: папка и список объединяются в один спрайт.
|
|
||||||
|
|
||||||
Полный список опций находится в разделе [Конфигурация → React](../../README_RU.md#react).
|
|
||||||
|
|
||||||
## 4. Добавьте генерацию в package.json
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"scripts": {
|
|
||||||
"sprite:file-manager": "svg-sprites --mode react@webpack src/ui/file-manager/svg-sprite",
|
|
||||||
"predev": "npm run sprite:file-manager",
|
|
||||||
"prebuild": "npm run sprite:file-manager",
|
|
||||||
"pretypecheck": "npm run sprite:file-manager"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Generated-файлы исключаются из Git, поэтому генерация должна выполняться перед `dev`, `build` и `typecheck`.
|
|
||||||
|
|
||||||
Первый запуск:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run sprite:file-manager
|
|
||||||
```
|
|
||||||
|
|
||||||
## 5. Используйте компонент
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
import { FileManagerIcon } from './svg-sprite'
|
|
||||||
|
|
||||||
export const OpenFolderButton = () => (
|
|
||||||
<button type="button">
|
|
||||||
<FileManagerIcon icon="folder" width={24} height={24} />
|
|
||||||
Открыть
|
|
||||||
</button>
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
Значение `icon` проверяется TypeScript по именам файлов:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
<FileManagerIcon icon="folder" /> // допустимо
|
|
||||||
<FileManagerIcon icon="missing" /> // ошибка TypeScript
|
|
||||||
```
|
|
||||||
|
|
||||||
Типы, способы отображения и управление цветами описаны в [основной документации](../../README_RU.md#способы-отображения).
|
|
||||||
|
|
||||||
Webpack обработает generated `new URL('./sprite.svg', import.meta.url)` через Asset Modules и выпустит отдельный SVG asset.
|
|
||||||
|
|
||||||
Если проект уже использует собственный SVG loader, убедитесь, что он не перехватывает generated `sprite.svg` вместо Asset Modules.
|
|
||||||
|
|
||||||
## 6. Добавьте debug-страницу
|
|
||||||
|
|
||||||
Webpack не поддерживает Vite API `import.meta.glob`, поэтому передайте статические loaders:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
|
||||||
|
|
||||||
const sources = [
|
|
||||||
() => import('./ui/file-manager/svg-sprite/manifest'),
|
|
||||||
() => import('./ui/navigation/svg-sprite/manifest'),
|
|
||||||
]
|
|
||||||
|
|
||||||
export const IconsDebugPage = () => (
|
|
||||||
<SpriteViewer sources={sources} title="Иконки проекта" />
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
Пути в `import()` должны быть строковыми литералами. Webpack создаст chunks для манифестов и свяжет их с SVG assets.
|
|
||||||
|
|
||||||
Размещайте Viewer только на debug-маршруте или во внутреннем инструменте.
|
|
||||||
|
|
||||||
## Если что-то не работает
|
|
||||||
|
|
||||||
- Нет `index.ts`: запустите `npm run sprite:file-manager`.
|
|
||||||
- Viewer не загружает спрайт: проверьте путь в `import()` и наличие `manifest.ts`.
|
|
||||||
- Неверный URL asset: проверьте `output.publicPath`.
|
|
||||||
- SVG перехватывает другой loader: исключите generated sprite из несовместимого правила.
|
|
||||||
|
|
||||||
Для Next.js используйте отдельные mode key из руководств [App Router](next-app.md) и [Pages Router](next-pages.md).
|
|
||||||
4
docs/ru/reference/README.md
Normal file
4
docs/ru/reference/README.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# Справочники
|
||||||
|
|
||||||
|
- [Технический справочник](technical.md)
|
||||||
|
- [Программный API](programmatic-api.md)
|
||||||
176
docs/ru/reference/programmatic-api.md
Normal file
176
docs/ru/reference/programmatic-api.md
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
# Программный API
|
||||||
|
|
||||||
|
[Индекс документации](../README.md)
|
||||||
|
|
||||||
|
Пакет распространяется как ESM и предоставляет единый Node.js API генерации. Framework-neutral Viewer находится в `@gromlab/svg-sprites/viewer`, auto-register entry — в `@gromlab/svg-sprites/viewer/element`, React bridge — в `@gromlab/svg-sprites/react`.
|
||||||
|
|
||||||
|
## `generateSprite`
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { generateSprite } from '@gromlab/svg-sprites'
|
||||||
|
|
||||||
|
const result = await generateSprite(
|
||||||
|
'src/ui/file-manager/svg-sprite/svg-sprite.config.ts',
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Результат содержит имя и mode спрайта, количество иконок и абсолютные filesystem paths:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
result.name
|
||||||
|
result.mode
|
||||||
|
result.target
|
||||||
|
result.iconCount
|
||||||
|
result.rootDir
|
||||||
|
result.generatedDir
|
||||||
|
result.spritePath
|
||||||
|
result.manifestPath
|
||||||
|
```
|
||||||
|
|
||||||
|
Next.js modes дополнительно возвращают `router` и `bundler`.
|
||||||
|
|
||||||
|
Для static standalone mode `result.spritePath` можно использовать в build-скрипте,
|
||||||
|
чтобы опубликовать SVG по URL приложения:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { copyFile } from 'node:fs/promises'
|
||||||
|
|
||||||
|
const result = await generateSprite('src/sprite/svg-sprite.config.ts', {
|
||||||
|
mode: 'standalone',
|
||||||
|
})
|
||||||
|
await copyFile(result.spritePath, 'dist/app-icons/sprite.svg')
|
||||||
|
```
|
||||||
|
|
||||||
|
`spritePath` является filesystem path, а не browser URL. Deployment-neutral JSON
|
||||||
|
manifest доступен через `result.manifestPath` и копируется независимо от SVG.
|
||||||
|
|
||||||
|
Первый аргумент принимает абсолютный или относительный путь к config-файлу с любым именем и расширением `.ts`, `.js` или `.json`. Каталог вместо файла включает config-less режим: корнем sprite-модуля становится этот каталог.
|
||||||
|
|
||||||
|
Второй аргумент содержит необязательные overrides и всегда имеет приоритет над конфигом:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
await generateSprite('src/ui/file-manager/svg-sprite/custom-config.json', {
|
||||||
|
mode: 'react@webpack',
|
||||||
|
name: 'documents',
|
||||||
|
input: ['./assets', '../../shared/search.svg'],
|
||||||
|
transform: {
|
||||||
|
addTransition: false,
|
||||||
|
},
|
||||||
|
generatedNotice: false,
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Порядок разрешения настроек:
|
||||||
|
|
||||||
|
```text
|
||||||
|
defaults → config → API overrides
|
||||||
|
```
|
||||||
|
|
||||||
|
Для полностью программной генерации передайте каталог и все обязательные настройки через overrides:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
await generateSprite('src/ui/file-manager/svg-sprite', {
|
||||||
|
mode: 'react@vite',
|
||||||
|
name: 'file-manager',
|
||||||
|
input: [
|
||||||
|
'../../shared/search.svg',
|
||||||
|
'../../shared/settings.svg',
|
||||||
|
],
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Конфигурация
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { defineSpriteConfig } from '@gromlab/svg-sprites'
|
||||||
|
|
||||||
|
export default defineSpriteConfig({
|
||||||
|
mode: 'react@vite',
|
||||||
|
name: 'file-manager',
|
||||||
|
description: 'Иконки файлового менеджера',
|
||||||
|
input: ['./icons', '../../shared/check.svg'],
|
||||||
|
transform: {
|
||||||
|
removeSize: true,
|
||||||
|
replaceColors: true,
|
||||||
|
addTransition: true,
|
||||||
|
},
|
||||||
|
generatedNotice: true,
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
`input` принимает одну папку, SVG-файл или glob-паттерн либо массив, объединяющий такие источники. Если поле не задано, используется `./icons`; относительные пути считаются от папки с конфигом.
|
||||||
|
|
||||||
|
`defineSpriteConfig` является identity helper для TypeScript autocomplete. JS может экспортировать тот же объект через `export default`, а JSON содержит объект непосредственно.
|
||||||
|
|
||||||
|
## Специализированные обёртки
|
||||||
|
|
||||||
|
Специализированные функции доступны как обёртки над `generateSprite`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { generateNextSprite, generateReactSprite } from '@gromlab/svg-sprites'
|
||||||
|
|
||||||
|
await generateReactSprite('path/to/config.ts', 'vite')
|
||||||
|
await generateNextSprite('path/to/config.ts', {
|
||||||
|
router: 'app',
|
||||||
|
bundler: 'turbopack',
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Явно переданный target перекрывает `mode` из файла. Для нового кода используйте `generateSprite`.
|
||||||
|
|
||||||
|
## Config API
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import {
|
||||||
|
isSpriteMode,
|
||||||
|
loadSpriteConfig,
|
||||||
|
resolveSpriteConfig,
|
||||||
|
resolveSpriteConfigSource,
|
||||||
|
validateSpriteConfig,
|
||||||
|
} from '@gromlab/svg-sprites'
|
||||||
|
```
|
||||||
|
|
||||||
|
- `isSpriteMode(value)` проверяет, является ли значение поддерживаемым exact mode.
|
||||||
|
- `loadSpriteConfig(file)` загружает явно указанный `.ts`, `.js` или `.json` файл.
|
||||||
|
- `resolveSpriteConfigSource(source)` разрешает путь как config-файл или config-less каталог.
|
||||||
|
- `validateSpriteConfig(value)` выполняет runtime-валидацию объекта.
|
||||||
|
- `resolveSpriteConfig(root, config, overrides)` объединяет значения, добавляет defaults и разрешает пути относительно `root`.
|
||||||
|
|
||||||
|
## Низкоуровневый compiler
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import {
|
||||||
|
compileSprite,
|
||||||
|
compileSpriteContent,
|
||||||
|
createShapeTransform,
|
||||||
|
} from '@gromlab/svg-sprites'
|
||||||
|
```
|
||||||
|
|
||||||
|
Эти функции предназначены для собственного orchestration. Стандартная генерация должна выполняться через `generateSprite`.
|
||||||
|
|
||||||
|
## Viewer runtime
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
||||||
|
```
|
||||||
|
|
||||||
|
Browser entry регистрирует `<gromlab-sprite-viewer>`. Bare standalone также может загрузить самостоятельный `dist/viewer-element.js` без bundler.
|
||||||
|
|
||||||
|
Для ручной регистрации импортируйте runtime без auto-register entry:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { defineSpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
||||||
|
|
||||||
|
defineSpriteViewerElement()
|
||||||
|
```
|
||||||
|
|
||||||
|
Этот entry также экспортирует типы `SpriteViewerElement`, `SpriteViewerManifest`, `SpriteViewerSource`, `SpriteViewerSources` и связанные типы manifest и loaders.
|
||||||
|
|
||||||
|
React bridge сохраняет компонентный API:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
```
|
||||||
|
|
||||||
|
`SpriteViewer` принимает generated manifests, remote standalone sources, lazy loaders или результат `import.meta.glob`. React entry содержит `'use client'` и предназначен для debug-инструментов; production-компоненты импортируются из локальных sprite-модулей приложения.
|
||||||
673
docs/ru/reference/technical.md
Normal file
673
docs/ru/reference/technical.md
Normal file
@@ -0,0 +1,673 @@
|
|||||||
|
# Технический справочник
|
||||||
|
|
||||||
|
[Индекс документации](../README.md)
|
||||||
|
|
||||||
|
[Конфигурация JSON, JavaScript и TypeScript](../configuration.md)
|
||||||
|
|
||||||
|
Справочник по конфигурации, generated API и поведению `@gromlab/svg-sprites`. Пошаговую установку смотрите в руководстве для вашего стека:
|
||||||
|
|
||||||
|
- [Bare standalone](../guides/standalone.md)
|
||||||
|
- [Standalone + Vite](../guides/standalone-vite.md)
|
||||||
|
- [Standalone + Webpack 5](../guides/standalone-webpack.md)
|
||||||
|
- [React + Vite](../guides/react-vite.md)
|
||||||
|
- [React + Webpack 5](../guides/react-webpack.md)
|
||||||
|
- [Next.js App Router + Turbopack](../guides/next-app-turbopack.md)
|
||||||
|
- [Next.js App Router + Webpack](../guides/next-app-webpack.md)
|
||||||
|
- [Next.js Pages Router + Turbopack](../guides/next-pages-turbopack.md)
|
||||||
|
- [Next.js Pages Router + Webpack](../guides/next-pages-webpack.md)
|
||||||
|
- [Vue + Vite](../guides/vue-vite.md)
|
||||||
|
- [Vue + Webpack](../guides/vue-webpack.md)
|
||||||
|
- [Nuxt + Vite](../guides/nuxt-vite.md)
|
||||||
|
- [Nuxt + Webpack](../guides/nuxt-webpack.md)
|
||||||
|
- [Svelte + Vite](../guides/svelte-vite.md)
|
||||||
|
- [Svelte + Webpack](../guides/svelte-webpack.md)
|
||||||
|
- [SvelteKit + Vite](../guides/sveltekit-vite.md)
|
||||||
|
- [Angular application builder](../guides/angular-application.md)
|
||||||
|
- [Angular + Webpack](../guides/angular-webpack.md)
|
||||||
|
- [Astro + Vite](../guides/astro-vite.md)
|
||||||
|
- [Solid + Vite](../guides/solid-vite.md)
|
||||||
|
- [Solid + Webpack](../guides/solid-webpack.md)
|
||||||
|
- [SolidStart + Vite](../guides/solid-start-vite.md)
|
||||||
|
- [Preact + Vite](../guides/preact-vite.md)
|
||||||
|
- [Preact + Webpack](../guides/preact-webpack.md)
|
||||||
|
- [Qwik + Vite](../guides/qwik-vite.md)
|
||||||
|
- [Lit + Vite](../guides/lit-vite.md)
|
||||||
|
- [Lit + Webpack](../guides/lit-webpack.md)
|
||||||
|
- [Alpine.js + Vite](../guides/alpine-vite.md)
|
||||||
|
- [Alpine.js + Webpack](../guides/alpine-webpack.md)
|
||||||
|
|
||||||
|
## Требования
|
||||||
|
|
||||||
|
- Node.js 18 или новее;
|
||||||
|
- пакет распространяется как ESM и подключается через `import`;
|
||||||
|
- React 18 или 19 требуется только для React/Next generated-компонентов и `@gromlab/svg-sprites/react`;
|
||||||
|
- для типизации package exports используйте TypeScript 5+ с `moduleResolution: "bundler"`, `"node16"` или `"nodenext"`.
|
||||||
|
|
||||||
|
Для генерации не нужна dependency проекта. Запускайте CLI через `npx`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx --yes @gromlab/svg-sprites path/to/svg-sprite.config.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Устанавливайте пакет как development dependency, только если проекту нужны
|
||||||
|
Viewer, типы конфига или программный API:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
|
```
|
||||||
|
|
||||||
|
## CLI и режимы генерации
|
||||||
|
|
||||||
|
Для генерации CLI принимает ровно один путь: явно выбранный config-файл либо каталог для config-less генерации:
|
||||||
|
|
||||||
|
```text
|
||||||
|
svg-sprites [options] <config-file-or-directory>
|
||||||
|
```
|
||||||
|
|
||||||
|
| Среда | Mode |
|
||||||
|
|---|---|
|
||||||
|
| Static HTML / собственная публикация | `standalone` |
|
||||||
|
| Standalone + Vite | `standalone@vite` |
|
||||||
|
| Standalone + Webpack 5 | `standalone@webpack` |
|
||||||
|
| React + Vite | `react@vite` |
|
||||||
|
| React + Webpack 5 | `react@webpack` |
|
||||||
|
| Vue + Vite | `vue@vite` |
|
||||||
|
| Vue + Webpack | `vue@webpack` |
|
||||||
|
| Nuxt + Vite | `nuxt@vite` |
|
||||||
|
| Nuxt + Webpack | `nuxt@webpack` |
|
||||||
|
| Svelte + Vite | `svelte@vite` |
|
||||||
|
| Svelte + Webpack | `svelte@webpack` |
|
||||||
|
| SvelteKit + Vite | `sveltekit@vite` |
|
||||||
|
| Angular application builder | `angular@application` |
|
||||||
|
| Angular + Webpack | `angular@webpack` |
|
||||||
|
| Astro + Vite | `astro@vite` |
|
||||||
|
| Solid + Vite | `solid@vite` |
|
||||||
|
| Solid + Webpack | `solid@webpack` |
|
||||||
|
| SolidStart + Vite | `solid-start@vite` |
|
||||||
|
| Preact + Vite | `preact@vite` |
|
||||||
|
| Preact + Webpack | `preact@webpack` |
|
||||||
|
| Qwik + Vite | `qwik@vite` |
|
||||||
|
| Lit + Vite | `lit@vite` |
|
||||||
|
| Lit + Webpack | `lit@webpack` |
|
||||||
|
| Alpine.js + Vite | `alpine@vite` |
|
||||||
|
| Alpine.js + Webpack | `alpine@webpack` |
|
||||||
|
| Next.js App Router + Turbopack | `next@app/turbopack` |
|
||||||
|
| Next.js App Router + Webpack 5 | `next@app/webpack` |
|
||||||
|
| Next.js Pages Router + Turbopack | `next@pages/turbopack` |
|
||||||
|
| Next.js Pages Router + Webpack 5 | `next@pages/webpack` |
|
||||||
|
|
||||||
|
Config-файл может иметь любое имя и расширение `.ts`, `.js` или `.json`. CLI не ищет конфиг по соглашению: файл нужно передать явно. В руководствах используется рекомендуемое имя `svg-sprite.config.json`.
|
||||||
|
|
||||||
|
Если передан каталог, все настройки берутся из CLI. Если передан config-файл, CLI-параметры перекрывают значения файла. Общий порядок: `defaults → config → CLI`.
|
||||||
|
|
||||||
|
`--help` и `-h` выводят справку без обязательного пути. Для генерации доступны `--mode`, `--name`, `--description`, повторяемый `--input <path-or-glob>`, а также пары `--remove-size`/`--no-remove-size`, `--replace-colors`/`--no-replace-colors`, `--add-transition`/`--no-add-transition` и `--generated-notice`/`--no-generated-notice`. Переданные transform-флаги перекрывают отдельные поля, а хотя бы один `--input` полностью заменяет значение `input` из config.
|
||||||
|
|
||||||
|
В CLI заключайте glob-паттерны в одинарные кавычки, чтобы shell не раскрыл их до запуска генератора:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
svg-sprites --input './icons/**/*.svg' --input '!./icons/legacy/**' svg-sprite.config.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
Mode должен соответствовать способу публикации приложения. Bare `standalone` оставляет публичный URL приложению; Vite и Webpack modes генерируют bundler-specific подключение SVG asset.
|
||||||
|
|
||||||
|
## Единая конфигурация
|
||||||
|
|
||||||
|
Каждый config-файл описывает один независимый спрайт.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { defineSpriteConfig } from '@gromlab/svg-sprites'
|
||||||
|
|
||||||
|
export default defineSpriteConfig({
|
||||||
|
mode: 'next@app/turbopack',
|
||||||
|
name: 'app',
|
||||||
|
description: 'Общие иконки приложения',
|
||||||
|
input: [
|
||||||
|
'./local-icons',
|
||||||
|
'../../assets/icons/*.svg',
|
||||||
|
'!../../assets/icons/deprecated-*.svg',
|
||||||
|
],
|
||||||
|
transform: {
|
||||||
|
removeSize: true,
|
||||||
|
replaceColors: true,
|
||||||
|
addTransition: true,
|
||||||
|
},
|
||||||
|
generatedNotice: true,
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
| Опция | Тип | По умолчанию | Назначение |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `mode` | `SpriteMode` | Нет | Режим генерации; можно передать через CLI/API |
|
||||||
|
| `name` | `string` | Выводится из каталога | Имя спрайта; в modes с компонентом также задаёт имя компонента и публичных типов |
|
||||||
|
| `description` | `string` | Нет | Описание для типов и debug manifest |
|
||||||
|
| `input` | `string \| string[]` | `./icons` | Папки, SVG-файлы и glob-паттерны относительно папки конфига |
|
||||||
|
| `transform` | `TransformOptions` | Все включены | Настройки подготовки SVG |
|
||||||
|
| `generatedNotice` | `boolean` | `true` | Полное или короткое предупреждение в generated-файлах |
|
||||||
|
|
||||||
|
### Имя спрайта
|
||||||
|
|
||||||
|
`name` записывается в kebab-case и должно начинаться с латинской буквы:
|
||||||
|
|
||||||
|
```text
|
||||||
|
app → AppIcon
|
||||||
|
file-manager → FileManagerIcon
|
||||||
|
```
|
||||||
|
|
||||||
|
Если `name` не задано, генератор преобразует имя каталога в kebab-case. Для каталога с именем `svg-sprite` или `svg-sprites` используется имя родительского каталога.
|
||||||
|
|
||||||
|
### Источники иконок
|
||||||
|
|
||||||
|
`SpriteConfig.input` является необязательным и имеет тип `string | string[]`. Если поле отсутствует, источником служит папка `./icons` относительно папки конфига. В config-less режиме относительные пути считаются от каталога, переданного CLI или API.
|
||||||
|
|
||||||
|
Каждая строка без префикса `!` может быть путём к конкретной папке, конкретному файлу `.svg` или glob-паттерном. Папка включает только непосредственные дочерние `*.svg`. Для рекурсивного обхода вложенных каталогов укажите явный паттерн, например `icons/**/*.svg`.
|
||||||
|
|
||||||
|
Массив объединяет все включающие источники. Паттерн с префиксом `!` глобально исключает совпадения из общего результата независимо от того, какой источник их добавил.
|
||||||
|
|
||||||
|
Поддерживается следующий glob-синтаксис:
|
||||||
|
|
||||||
|
| Синтаксис | Значение |
|
||||||
|
|---|---|
|
||||||
|
| `*` | Любые символы внутри одного сегмента пути |
|
||||||
|
| `**` | Любое число вложенных каталогов |
|
||||||
|
| `?` | Один символ внутри сегмента пути |
|
||||||
|
| `{a,b}` | Одна из альтернатив |
|
||||||
|
| `[abc]` | Один символ из набора или диапазона |
|
||||||
|
| `!pattern` | Исключение совпадений из всего объединённого input |
|
||||||
|
|
||||||
|
Каждый включающий источник или паттерн должен найти хотя бы один SVG, иначе генерация завершается ошибкой. Повторяющиеся пути удаляются, а итоговый список файлов детерминированно сортируется. Разные SVG с одинаковым basename по-прежнему считаются конфликтом, потому что basename задаёт публичное имя иконки.
|
||||||
|
|
||||||
|
## Generated-модуль
|
||||||
|
|
||||||
|
После генерации React- или Next.js-каталог спрайта выглядит так:
|
||||||
|
|
||||||
|
```text
|
||||||
|
app-icons/
|
||||||
|
├── .gitignore
|
||||||
|
├── svg-sprite.config.json
|
||||||
|
├── index.ts # необязательный пользовательский barrel
|
||||||
|
└── .svg-sprite/
|
||||||
|
├── index.js
|
||||||
|
├── index.d.ts
|
||||||
|
├── icon-data.js
|
||||||
|
├── icon-data.d.ts
|
||||||
|
├── sprite.svg
|
||||||
|
├── svg-sprite.manifest.js
|
||||||
|
├── svg-sprite.manifest.d.ts
|
||||||
|
└── react/
|
||||||
|
├── react-component.js
|
||||||
|
├── react-component.d.ts
|
||||||
|
└── react-component.module.css
|
||||||
|
```
|
||||||
|
|
||||||
|
| Файл | Назначение |
|
||||||
|
|---|---|
|
||||||
|
| `.svg-sprite/index.js` | Mode-specific production facade и runtime-список имён |
|
||||||
|
| `.svg-sprite/index.d.ts` | Публичные декларации facade, компонента и union-типа имён |
|
||||||
|
| `.svg-sprite/svg-sprite.manifest.js` | Debug metadata и URL asset для `SpriteViewer` |
|
||||||
|
| `.svg-sprite/sprite.svg` | Собранный SVG-спрайт |
|
||||||
|
| `.svg-sprite/react/react-component.js` | Runtime React-компонента без TypeScript и JSX |
|
||||||
|
| `.svg-sprite/react/react-component.d.ts` | Props, style и declaration React-компонента |
|
||||||
|
| `.svg-sprite/react/react-component.module.css` | Стили конкретной React-реализации |
|
||||||
|
| `.svg-sprite/icon-data.js` | Runtime-список имён и внутренние IDs |
|
||||||
|
| `.svg-sprite/*.d.ts` | TypeScript-декларации соответствующих JS-модулей |
|
||||||
|
|
||||||
|
Standalone-контракты не создают каталог `react/`. Bare `standalone` содержит только
|
||||||
|
runtime asset и deployment-neutral manifest data:
|
||||||
|
|
||||||
|
```text
|
||||||
|
.svg-sprite/
|
||||||
|
├── sprite.svg
|
||||||
|
└── svg-sprite.manifest.json
|
||||||
|
```
|
||||||
|
|
||||||
|
`standalone@vite` и `standalone@webpack` дополнительно создают `index.*`,
|
||||||
|
`icon-data.*` и resolved `svg-sprite.manifest.*`. Их facade содержит нативный
|
||||||
|
generated Web Component без внешних runtime-зависимостей. Bare `standalone`
|
||||||
|
намеренно не создаёт JavaScript-компонент.
|
||||||
|
|
||||||
|
`.svg-sprite` полностью управляется генератором и при каждой генерации заменяется целиком. Любые добавленные в него файлы будут удалены. Пользовательские файлы размещайте рядом, например в корневом `index.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Standalone Web Component и TypeScript
|
||||||
|
|
||||||
|
В modes `standalone@vite` и `standalone@webpack` спрайт с `name: 'app'`
|
||||||
|
экспортирует функцию регистрации `defineAppIconElement()` и tag `<app-icon>`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { defineAppIconElement } from '@/ui/app-icons'
|
||||||
|
|
||||||
|
defineAppIconElement()
|
||||||
|
```
|
||||||
|
|
||||||
|
После регистрации элемент можно использовать в HTML:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<app-icon icon="search" aria-hidden="true"></app-icon>
|
||||||
|
|
||||||
|
<app-icon
|
||||||
|
icon="settings"
|
||||||
|
role="img"
|
||||||
|
aria-label="Настройки"
|
||||||
|
></app-icon>
|
||||||
|
```
|
||||||
|
|
||||||
|
Компонент рендерит `<svg><use>` в открытом Shadow DOM, сам выбирает внутренний
|
||||||
|
ID и `viewBox`, а URL asset получает через соответствующий Vite или Webpack
|
||||||
|
механизм. Размер host по умолчанию равен `1em × 1em`; `class`, `style`, `color`
|
||||||
|
и `--icon-color-N` задаются обычным CSS.
|
||||||
|
|
||||||
|
Generated `HTMLElementTagNameMap` типизирует property API:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const icon = document.createElement('app-icon')
|
||||||
|
|
||||||
|
icon.icon = 'search'
|
||||||
|
icon.icon = 'unknown' // ошибка TypeScript
|
||||||
|
```
|
||||||
|
|
||||||
|
Значения атрибутов в обычной HTML-разметке TypeScript не проверяет. Поэтому
|
||||||
|
неизвестный `icon="unknown"` дополнительно проверяется в runtime: компонент
|
||||||
|
скрывает внутренний SVG и сообщает об ошибке, не создавая fragment
|
||||||
|
`#undefined`. Повторный вызов `defineAppIconElement()` безопасен для того же
|
||||||
|
спрайта; конфликт с другим элементом под tag `<app-icon>` завершается ошибкой.
|
||||||
|
|
||||||
|
## React-компонент и TypeScript
|
||||||
|
|
||||||
|
Спрайт с `name: 'app'` экспортирует:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export { AppIcon, appIconNames }
|
||||||
|
export type { AppIconName, AppIconProps, AppIconStyle }
|
||||||
|
```
|
||||||
|
|
||||||
|
### Имена иконок
|
||||||
|
|
||||||
|
Имена SVG-файлов становятся допустимыми значениями `icon`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<AppIcon icon="search" />
|
||||||
|
<AppIcon icon="unknown" /> // ошибка TypeScript
|
||||||
|
```
|
||||||
|
|
||||||
|
Runtime-список содержит те же значения:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { appIconNames } from '@/ui/app-icons'
|
||||||
|
|
||||||
|
// readonly ['search', 'settings', 'user']
|
||||||
|
```
|
||||||
|
|
||||||
|
Имена с пробелами и другими небезопасными для SVG ID символами остаются частью публичного API. Для внутреннего fragment ID генератор создаёт стабильный безопасный hash:
|
||||||
|
|
||||||
|
```text
|
||||||
|
folder open.svg → icon="folder open" → id="icon-<stable-hash>"
|
||||||
|
```
|
||||||
|
|
||||||
|
Для таких имён используйте generated-компонент или `id` из debug manifest, а не формируйте fragment ID вручную.
|
||||||
|
|
||||||
|
### SVG-атрибуты
|
||||||
|
|
||||||
|
По умолчанию компонент рендерит `<svg>` и принимает стандартные SVG-атрибуты:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<AppIcon
|
||||||
|
icon="search"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
color="rebeccapurple"
|
||||||
|
className="searchIcon"
|
||||||
|
aria-label="Поиск"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
Компонент не добавляет accessibility-семантику автоматически. Передавайте подходящие `aria-*`, `role` или подпись в зависимости от назначения иконки.
|
||||||
|
|
||||||
|
### Обёртка
|
||||||
|
|
||||||
|
`wrapped` рендерит `<span>` с внутренним SVG. Остальные props в этом режиме относятся к `<span>`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<AppIcon icon="search" wrapped className="iconWrapper" />
|
||||||
|
```
|
||||||
|
|
||||||
|
### Типизированные CSS-переменные
|
||||||
|
|
||||||
|
`AppIconStyle` расширяет `CSSProperties` и поддерживает свойства вида `--icon-color-N`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<AppIcon
|
||||||
|
icon="user"
|
||||||
|
style={{
|
||||||
|
'--icon-color-1': '#2563eb',
|
||||||
|
'--icon-color-2': '#dbeafe',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Множественные спрайты
|
||||||
|
|
||||||
|
Каждый каталог с конфигом создаёт независимый mode-specific контракт. Framework modes создают нативный компонент и declarations, standalone bundler modes — Web Component и declarations, а bare `standalone` — SVG и JSON manifest:
|
||||||
|
|
||||||
|
```text
|
||||||
|
app-icons → AppIcon → общие иконки
|
||||||
|
analytics-icons → AnalyticsIcon → иконки страницы аналитики
|
||||||
|
editor-icons → EditorIcon → иконки редактора
|
||||||
|
```
|
||||||
|
|
||||||
|
Один исходный SVG можно добавить через `input` в несколько конфигураций. Копировать файл в каталоги каждого спрайта не требуется.
|
||||||
|
|
||||||
|
Для нескольких спрайтов добавьте отдельную CLI-команду для каждого каталога или объедините команды в общем npm script.
|
||||||
|
|
||||||
|
## Форматы и способы отображения
|
||||||
|
|
||||||
|
Все текущие modes создают формат `stack`.
|
||||||
|
|
||||||
|
| Формат | `<svg><use>` | `<img>` | CSS background |
|
||||||
|
|---|---:|---:|---:|
|
||||||
|
| `stack` | Да | Да | Да |
|
||||||
|
|
||||||
|
### Generated-компонент
|
||||||
|
|
||||||
|
Используйте generated native-компонент из guide выбранного exact mode. Он знает внутренние ID, формирует URL и предоставляет TypeScript API. Для React и Next.js это выглядит так:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<AppIcon icon="search" width={24} height={24} />
|
||||||
|
```
|
||||||
|
|
||||||
|
Для `standalone@vite` и `standalone@webpack` используйте generated Web Component:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<app-icon icon="search" style="font-size: 24px"></app-icon>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Вручную через `<svg><use>`
|
||||||
|
|
||||||
|
Способ получения `spriteUrl` зависит от сборщика.
|
||||||
|
|
||||||
|
Static HTML после публикации `.svg-sprite/sprite.svg` приложением:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<svg aria-hidden="true">
|
||||||
|
<use href="/assets/icons.svg#search"></use>
|
||||||
|
</svg>
|
||||||
|
```
|
||||||
|
|
||||||
|
Standalone Vite/Webpack предоставляет generated `getAppIconHref()` и mapping
|
||||||
|
внутренних IDs. Не конструируйте fragment из небезопасного имени файла вручную.
|
||||||
|
|
||||||
|
Vite:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import spriteUrl from './.svg-sprite/sprite.svg?no-inline'
|
||||||
|
```
|
||||||
|
|
||||||
|
Webpack 5, Turbopack и Next.js:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const spriteUrl = new URL('./.svg-sprite/sprite.svg', import.meta.url).href
|
||||||
|
```
|
||||||
|
|
||||||
|
После получения URL используйте его в JSX:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<svg width="24" height="24" aria-label="Поиск">
|
||||||
|
<use href={`${spriteUrl}#search`} />
|
||||||
|
</svg>
|
||||||
|
```
|
||||||
|
|
||||||
|
Для имён, небезопасных как SVG ID, используйте внутренний `id` из manifest.
|
||||||
|
|
||||||
|
### Через `<img>`
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<img src={`${spriteUrl}#search`} width={24} height={24} alt="Поиск" />
|
||||||
|
```
|
||||||
|
|
||||||
|
SVG внутри `<img>` изолирован от CSS страницы. `color` и `--icon-color-N` на внешнем элементе не изменяют его внутренние цвета.
|
||||||
|
|
||||||
|
### Через CSS
|
||||||
|
|
||||||
|
```css
|
||||||
|
.icon {
|
||||||
|
background: url('./.svg-sprite/sprite.svg#search') center / contain no-repeat;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Для одноцветного силуэта можно использовать mask:
|
||||||
|
|
||||||
|
```css
|
||||||
|
.icon {
|
||||||
|
background-color: currentColor;
|
||||||
|
mask: url('./.svg-sprite/sprite.svg#search') center / contain no-repeat;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Mask не сохраняет исходные цвета, gradients и различия между `fill` и `stroke`.
|
||||||
|
|
||||||
|
Путь в CSS разрешается относительно самого CSS-файла. В примерах CSS-файл находится рядом с `svg-sprite.config.ts`.
|
||||||
|
|
||||||
|
## Assets и кеширование
|
||||||
|
|
||||||
|
Generated component или standalone facade передаёт SVG сборщику как отдельный asset:
|
||||||
|
|
||||||
|
- Vite использует статический импорт с `?no-inline`;
|
||||||
|
- Webpack 5, Turbopack и Next.js используют `new URL(..., import.meta.url)`;
|
||||||
|
- SVG path-данные не сериализуются в generated JavaScript.
|
||||||
|
|
||||||
|
Bare `standalone` не участвует в asset pipeline: приложение само копирует или
|
||||||
|
публикует `sprite.svg` и отвечает за URL, версионирование и cache policy.
|
||||||
|
|
||||||
|
При стандартном именовании assets сборщик добавляет content hash:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/assets/sprite-<hash>.svg
|
||||||
|
```
|
||||||
|
|
||||||
|
Это позволяет кешировать SVG отдельно от JavaScript. Изменение React-кода не меняет содержимое спрайта, а изменение иконок создаёт новую версию asset.
|
||||||
|
|
||||||
|
HTTP cache headers, CDN и `Cache-Control` настраиваются приложением или платформой размещения. Для Webpack имя итогового файла зависит от `assetModuleFilename` проекта.
|
||||||
|
|
||||||
|
## Трансформации SVG
|
||||||
|
|
||||||
|
Все трансформации включены по умолчанию и настраиваются независимо:
|
||||||
|
|
||||||
|
| Опция | Что делает |
|
||||||
|
|---|---|
|
||||||
|
| `removeSize` | Удаляет `width` и `height` с корневого `<svg>`, сохраняя существующий `viewBox` |
|
||||||
|
| `replaceColors` | Заменяет найденные `fill` и `stroke` на `--icon-color-N` |
|
||||||
|
| `addTransition` | Добавляет transitions для `fill` и `stroke` в цветные элементы и generated styles |
|
||||||
|
|
||||||
|
Чтобы отключить отдельную операцию:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export default defineSpriteConfig({
|
||||||
|
mode: 'next@app/turbopack',
|
||||||
|
transform: {
|
||||||
|
removeSize: false,
|
||||||
|
replaceColors: false,
|
||||||
|
addTransition: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Исходные SVG не изменяются. Трансформации применяются только к содержимому generated-спрайта.
|
||||||
|
|
||||||
|
## Управление цветами
|
||||||
|
|
||||||
|
### Монохромные иконки
|
||||||
|
|
||||||
|
Если найден один цвет, fallback становится `currentColor`:
|
||||||
|
|
||||||
|
```svg
|
||||||
|
stroke="var(--icon-color-1, currentColor)"
|
||||||
|
```
|
||||||
|
|
||||||
|
Цвет задаётся через prop или CSS:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<AppIcon icon="search" color="rebeccapurple" />
|
||||||
|
```
|
||||||
|
|
||||||
|
### Многоцветные иконки
|
||||||
|
|
||||||
|
Каждый уникальный цвет получает отдельную переменную с исходным fallback:
|
||||||
|
|
||||||
|
```svg
|
||||||
|
fill="var(--icon-color-1, #798198)"
|
||||||
|
fill="var(--icon-color-2, #ffffff)"
|
||||||
|
fill="var(--icon-color-3, #129d9d)"
|
||||||
|
```
|
||||||
|
|
||||||
|
Можно заменить только необходимые значения:
|
||||||
|
|
||||||
|
```css
|
||||||
|
.icon {
|
||||||
|
--icon-color-1: #4b5563;
|
||||||
|
--icon-color-3: #14b8a6;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ограничения
|
||||||
|
|
||||||
|
- `none`, `transparent`, `inherit`, `unset` и `initial` не заменяются;
|
||||||
|
- надёжнее всего обрабатываются цвета в атрибутах `fill`, `stroke` и inline `style`;
|
||||||
|
- CSS-классы и внешние stylesheets внутри SVG не являются основным сценарием трансформации;
|
||||||
|
- значения `url(#...)` могут быть заменены вместе с цветами, поэтому gradients и patterns требуют отдельного спрайта с `replaceColors: false`;
|
||||||
|
- masks, filters и сложные внутренние CSS-правила требуют визуальной проверки;
|
||||||
|
- CSS-переменные страницы доступны через `<svg><use>`, но не внутри `<img>` и CSS background.
|
||||||
|
|
||||||
|
Для сложной иконки можно отключить `replaceColors` в конфигурации отдельного спрайта.
|
||||||
|
|
||||||
|
## SpriteViewer
|
||||||
|
|
||||||
|
Viewer использует один Web Component с Shadow DOM для всех modes. React и будущие framework-компоненты являются bridge к этому же элементу, поэтому визуал и поведение не дублируются.
|
||||||
|
|
||||||
|
Bare `standalone` подключает самостоятельный browser bundle и передаёт URL JSON manifest и опубликованного SVG:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script
|
||||||
|
type="module"
|
||||||
|
src="https://unpkg.com/@gromlab/svg-sprites@<version>/dist/viewer-element.js"
|
||||||
|
></script>
|
||||||
|
|
||||||
|
<gromlab-sprite-viewer
|
||||||
|
viewer-title="Иконки проекта"
|
||||||
|
manifest-url="/app-icons/manifest.json"
|
||||||
|
sprite-url="/app-icons/sprite.svg"
|
||||||
|
></gromlab-sprite-viewer>
|
||||||
|
```
|
||||||
|
|
||||||
|
`viewer-element.js` не имеет дополнительных runtime-файлов и может быть скопирован с остальными static assets для self-hosting.
|
||||||
|
|
||||||
|
`standalone@vite` и `standalone@webpack` регистрируют тот же элемент через npm entry и передают generated JS manifest через свойство `sources`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
||||||
|
import spriteManifest from './svg-sprite/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
|
||||||
|
const viewer = document.querySelector<SpriteViewerElement>('gromlab-sprite-viewer')!
|
||||||
|
viewer.sources = [spriteManifest]
|
||||||
|
```
|
||||||
|
|
||||||
|
React и Next.js сохраняют компонентный API:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
```
|
||||||
|
|
||||||
|
Он принимает готовые manifests, remote standalone sources, массив lazy loaders или record формата `import.meta.glob`.
|
||||||
|
|
||||||
|
Vite:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
import type { SpriteManifestModule } from '@gromlab/svg-sprites/react'
|
||||||
|
|
||||||
|
const sources = import.meta.glob<SpriteManifestModule>(
|
||||||
|
'/src/**/svg-sprite/.svg-sprite/svg-sprite.manifest.js',
|
||||||
|
)
|
||||||
|
|
||||||
|
export const IconsDebugPage = () => (
|
||||||
|
<SpriteViewer sources={sources} title="Иконки проекта" />
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Webpack и Next.js:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
const sources = [
|
||||||
|
() => import('@/ui/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
() => import('@/features/analytics/icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
|
]
|
||||||
|
|
||||||
|
export const IconsDebugPage = () => (
|
||||||
|
<SpriteViewer sources={sources} />
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Viewer показывает группы, поиск, `viewBox`, CSS-переменные и fallback-цвета. Framework manifests получают вкладку своего framework, а также SVG, IMG и CSS; standalone manifests получают SVG, IMG и CSS. Цветовые значения можно менять в интерфейсе и сразу проверять результат.
|
||||||
|
|
||||||
|
### Тема Viewer
|
||||||
|
|
||||||
|
По умолчанию `colorTheme="auto"` следует `prefers-color-scheme`. Можно передать `light` или `dark` явно:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<SpriteViewer sources={sources} colorTheme="dark" />
|
||||||
|
```
|
||||||
|
|
||||||
|
Для синхронизации с темой приложения:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<SpriteViewer
|
||||||
|
sources={sources}
|
||||||
|
colorTheme={appTheme}
|
||||||
|
onColorThemeChange={setAppTheme}
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
`@gromlab/svg-sprites/react` содержит `'use client'` и рендерит Web Component host; внутренний Shadow DOM создаётся после загрузки browser runtime. В Next.js App Router размещайте Viewer внутри отдельной Client Component boundary и используйте только на debug-маршруте или во внутреннем инструменте.
|
||||||
|
|
||||||
|
## Generated-файлы, Git и CI
|
||||||
|
|
||||||
|
Все modes, кроме bare `standalone`, создают локальный `.gitignore` для:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/.svg-sprite/
|
||||||
|
```
|
||||||
|
|
||||||
|
Локальный `.gitignore` следует один раз добавить в репозиторий. Он исключает остальные generated-файлы, поэтому генерацию нужно запускать перед командами, которые импортируют sprite-модуль:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "npx --yes @gromlab/svg-sprites src/ui/app-icons/svg-sprite.config.ts",
|
||||||
|
"predev": "npm run sprites",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"pretypecheck": "npm run sprites"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
CI должен выполнять generation script до сборки или проверки типов. Локальная установка package не нужна, если CI не использует Viewer, package-типы config или программный API.
|
||||||
|
|
||||||
|
Bare `standalone` не создаёт `.gitignore` и сохраняет пользовательский файл. Если после другого mode остался управляемый `.gitignore`, bare mode удалит его. В остальных modes генератор откажется перезаписать пользовательский `.gitignore` без generated marker. Корневой `index.ts` остаётся пользовательским и может переэкспортировать generated API.
|
||||||
|
|
||||||
|
## Диагностика
|
||||||
|
|
||||||
|
- Для всех modes, кроме bare `standalone`: если нет `.svg-sprite/index.js`, запустите generation script до импорта generated-модуля.
|
||||||
|
- Не найден источник: передайте существующий config-файл или каталог sprite-модуля.
|
||||||
|
- Не указан mode: добавьте `mode` в config либо передайте `--mode`.
|
||||||
|
- Иконка отсутствует в типе: проверьте `input`, расширение `.svg`, glob-исключения и необходимость `**/*.svg` для вложенных папок.
|
||||||
|
- Конфликт имени: два разных SVG имеют одинаковый basename; переименуйте один файл.
|
||||||
|
- `Refusing to overwrite a user file`: в корне sprite-модуля находится пользовательский `.gitignore`, который генератор не может заменить.
|
||||||
|
- Иконка не меняет цвет: используйте `<svg><use>` или generated-компонент и проверьте `replaceColors`.
|
||||||
|
- Webpack выдаёт неверный URL: проверьте Asset Modules, `output.publicPath` и SVG loaders.
|
||||||
|
- Static sprite возвращает 404: проверьте post-generation copy или server alias и не передавайте filesystem `spritePath` в HTML.
|
||||||
|
- Viewer не видит спрайт: для bundler modes проверьте путь к `.svg-sprite/svg-sprite.manifest.js`; для bare `standalone` — URL опубликованных `svg-sprite.manifest.json` и `sprite.svg`. Выполните генерацию до запуска приложения.
|
||||||
|
- Build и mode не совпадают: используйте target, соответствующий фактическому сборщику.
|
||||||
|
|
||||||
|
Для собственного orchestration и низкоуровневой компиляции смотрите [Программный API](programmatic-api.md).
|
||||||
17
integration/.gitignore
vendored
Normal file
17
integration/.gitignore
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
node_modules/
|
||||||
|
playwright-report/
|
||||||
|
test-results/
|
||||||
|
apps/*/dist/
|
||||||
|
apps/*/.angular/
|
||||||
|
apps/*/.astro/
|
||||||
|
apps/*/.next/
|
||||||
|
apps/*/.nuxt/
|
||||||
|
apps/*/.output/
|
||||||
|
apps/*/.svelte-kit/
|
||||||
|
apps/*/.vinxi/
|
||||||
|
apps/*/build/
|
||||||
|
apps/*/out-tsc/
|
||||||
|
apps/*/public/sprites/
|
||||||
|
apps/*/static/sprites/
|
||||||
|
apps/*/*.tsbuildinfo
|
||||||
|
apps/*/src/sprite/.svg-sprite/
|
||||||
98
integration/README.md
Normal file
98
integration/README.md
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
# Integration playground
|
||||||
|
|
||||||
|
Постоянные минимальные consumer-приложения для проверки генерации, typecheck,
|
||||||
|
production build и отображения внешнего SVG-спрайта в настоящем Chromium.
|
||||||
|
|
||||||
|
## Матрица
|
||||||
|
|
||||||
|
| Fixture | Генератор | Runtime |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `standalone` | `standalone` | Static HTML + явный copy SVG |
|
||||||
|
| `standalone-vite` | `standalone@vite` | Vanilla TypeScript + Vite |
|
||||||
|
| `standalone-webpack` | `standalone@webpack` | Vanilla TypeScript + Webpack 5 |
|
||||||
|
| `react-vite` | `react@vite` | React + Vite |
|
||||||
|
| `react-webpack` | `react@webpack` | React + Webpack 5 |
|
||||||
|
| `vue-vite` | `vue@vite` | Vue + Vite |
|
||||||
|
| `vue-webpack` | `vue@webpack` | Vue + Webpack 5 |
|
||||||
|
| `nuxt-vite` | `nuxt@vite` | Nuxt + Vite |
|
||||||
|
| `nuxt-webpack` | `nuxt@webpack` | Nuxt + Webpack |
|
||||||
|
| `svelte-vite` | `svelte@vite` | Svelte + Vite |
|
||||||
|
| `svelte-webpack` | `svelte@webpack` | Svelte + Webpack |
|
||||||
|
| `sveltekit` | `sveltekit@vite` | SvelteKit + Vite |
|
||||||
|
| `angular` | `angular@application` | Angular application builder |
|
||||||
|
| `angular-webpack` | `angular@webpack` | Angular + Webpack |
|
||||||
|
| `astro` | `astro@vite` | Astro + Vite |
|
||||||
|
| `solid-vite` | `solid@vite` | Solid + Vite |
|
||||||
|
| `solid-webpack` | `solid@webpack` | Solid + Webpack |
|
||||||
|
| `solid-start-vite` | `solid-start@vite` | SolidStart + Vite |
|
||||||
|
| `preact-vite` | `preact@vite` | Preact + Vite |
|
||||||
|
| `preact-webpack` | `preact@webpack` | Preact + Webpack |
|
||||||
|
| `qwik-vite` | `qwik@vite` | Qwik + Vite |
|
||||||
|
| `lit-vite` | `lit@vite` | Lit + Vite |
|
||||||
|
| `lit-webpack` | `lit@webpack` | Lit + Webpack |
|
||||||
|
| `alpine-vite` | `alpine@vite` | Alpine.js + Vite |
|
||||||
|
| `alpine-webpack` | `alpine@webpack` | Alpine.js + Webpack |
|
||||||
|
| `next-app-turbopack` | `next@app/turbopack` | App Router + Turbopack |
|
||||||
|
| `next-app-webpack` | `next@app/webpack` | App Router + Webpack |
|
||||||
|
| `next-pages-turbopack` | `next@pages/turbopack` | Pages Router + Turbopack |
|
||||||
|
| `next-pages-webpack` | `next@pages/webpack` | Pages Router + Webpack |
|
||||||
|
|
||||||
|
В verify-матрицу входят все exact modes из корневого `MODES_CHECKLIST.md`.
|
||||||
|
|
||||||
|
## Первый запуск
|
||||||
|
|
||||||
|
Из корня репозитория:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm ci
|
||||||
|
npm run build:package
|
||||||
|
npm run integration:install
|
||||||
|
npm exec --prefix integration -- playwright install chromium
|
||||||
|
npm run integration:verify
|
||||||
|
```
|
||||||
|
|
||||||
|
`integration:verify` последовательно выполняет генерацию, typecheck, production build
|
||||||
|
активных fixtures и Playwright smoke-тесты.
|
||||||
|
|
||||||
|
## Отдельные этапы
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run integration:generate
|
||||||
|
npm run integration:build
|
||||||
|
npm run integration:test
|
||||||
|
```
|
||||||
|
|
||||||
|
Для запуска команды только в одном fixture:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
node scripts/run-workspaces.mjs build react-vite
|
||||||
|
npm run dev --workspace @svg-sprites-fixtures/react-vite --prefix integration
|
||||||
|
```
|
||||||
|
|
||||||
|
Первую команду запускайте из каталога `integration`.
|
||||||
|
|
||||||
|
Перед E2E production builds должны существовать. Тест запускает каждый server
|
||||||
|
последовательно, проверяет внешний `href`, HTTP status и Content-Type спрайта,
|
||||||
|
наличие symbol ID, отсутствие browser errors и зелёные пиксели отрисованной иконки.
|
||||||
|
Для каждого active mode тест также открывает единый Viewer, проверяет его Shadow DOM,
|
||||||
|
совпадение sprite URL, карточку `check`, dialog и mode-specific вкладки кода.
|
||||||
|
|
||||||
|
Static fixture копирует managed SVG и JSON manifest в `dist/app-icons/` и использует
|
||||||
|
literal `<use href="/app-icons/sprite.svg#check">`.
|
||||||
|
Vite и Webpack fixtures получают URL только из generated facade и сверяют его с
|
||||||
|
resolved manifest.
|
||||||
|
|
||||||
|
## Структура
|
||||||
|
|
||||||
|
```text
|
||||||
|
integration/
|
||||||
|
├── apps/ # реальные consumer package boundaries
|
||||||
|
├── fixtures/icons/ # общие исходные SVG
|
||||||
|
├── scripts/ # workspace runner и static production server
|
||||||
|
├── tests/ # Playwright runtime smoke
|
||||||
|
├── package.json # отдельный npm workspace
|
||||||
|
└── package-lock.json # зафиксированная framework matrix
|
||||||
|
```
|
||||||
|
|
||||||
|
Generated-файлы, framework build outputs и Playwright artifacts исключены через
|
||||||
|
`integration/.gitignore`.
|
||||||
17
integration/apps/alpine-vite/index.html
Normal file
17
integration/apps/alpine-vite/index.html
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Alpine Vite sprite fixture</title>
|
||||||
|
<style>
|
||||||
|
:root { font-family: system-ui, sans-serif; color: #172033; background: #fff; }
|
||||||
|
body { margin: 0; padding: 40px; }
|
||||||
|
gromlab-sprite-viewer { display: block; margin-top: 32px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main id="app"></main>
|
||||||
|
<script type="module" src="/src/main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
20
integration/apps/alpine-vite/package.json
Normal file
20
integration/apps/alpine-vite/package.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"name": "@svg-sprites-fixtures/alpine-vite",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"sprites": "svg-sprites src/sprite/svg-sprite.config.json",
|
||||||
|
"typecheck": "tsc --noEmit",
|
||||||
|
"build": "npm run sprites && npm run typecheck && vite build",
|
||||||
|
"dev": "npm run sprites && vite"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"alpinejs": "3.15.12"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@gromlab/svg-sprites": "file:../../..",
|
||||||
|
"typescript": "6.0.2",
|
||||||
|
"vite": "8.1.4"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import {
|
||||||
|
iconsAlpinePlugin,
|
||||||
|
iconsIconDirective,
|
||||||
|
iconsIconMagic,
|
||||||
|
iconsIconNames,
|
||||||
|
type IconsIconName,
|
||||||
|
} from './sprite/index.js'
|
||||||
|
|
||||||
|
declare const Alpine: { plugin(plugin: typeof iconsAlpinePlugin): void }
|
||||||
|
|
||||||
|
const iconName: IconsIconName = iconsIconNames[0]
|
||||||
|
const directive: 'icons-icon' = iconsIconDirective
|
||||||
|
const magic: 'iconsIconHref' = iconsIconMagic
|
||||||
|
|
||||||
|
Alpine.plugin(iconsAlpinePlugin)
|
||||||
|
void iconName
|
||||||
|
void directive
|
||||||
|
void magic
|
||||||
|
|
||||||
|
// @ts-expect-error Generated icon names form a literal union.
|
||||||
|
const missingIcon: IconsIconName = 'missing'
|
||||||
|
void missingIcon
|
||||||
25
integration/apps/alpine-vite/src/main.js
Normal file
25
integration/apps/alpine-vite/src/main.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
|
import Alpine from 'alpinejs'
|
||||||
|
import spriteManifest from './sprite/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
import { iconsAlpinePlugin } from './sprite/index.js'
|
||||||
|
|
||||||
|
Alpine.plugin(iconsAlpinePlugin)
|
||||||
|
window.Alpine = Alpine
|
||||||
|
|
||||||
|
document.querySelector('#app').innerHTML = `
|
||||||
|
<main x-data>
|
||||||
|
<h1>Alpine + Vite</h1>
|
||||||
|
<svg
|
||||||
|
data-testid="icon"
|
||||||
|
data-app="alpine-vite"
|
||||||
|
x-icons-icon="'check'"
|
||||||
|
role="img"
|
||||||
|
aria-label="Check icon"
|
||||||
|
style="width:64px;height:64px;color:#16a34a;--icon-color-1:#16a34a"
|
||||||
|
></svg>
|
||||||
|
<gromlab-sprite-viewer viewer-title="Alpine Vite Viewer"></gromlab-sprite-viewer>
|
||||||
|
</main>
|
||||||
|
`
|
||||||
|
|
||||||
|
document.querySelector('gromlab-sprite-viewer').sources = [spriteManifest]
|
||||||
|
Alpine.start()
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user