mirror of
https://github.com/gromlab-ru/svg-sprites.git
synced 2026-08-02 18:00:16 +03:00
Compare commits
4 Commits
ab7042001a
...
b43814e57b
| Author | SHA1 | Date | |
|---|---|---|---|
| b43814e57b | |||
| 8b3365f957 | |||
| e54ab4991c | |||
| 44afec7cdb |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,6 +3,7 @@ dist/
|
|||||||
public/
|
public/
|
||||||
test/public/
|
test/public/
|
||||||
test/.next-fixture-*/
|
test/.next-fixture-*/
|
||||||
|
test-results/
|
||||||
.tmp/
|
.tmp/
|
||||||
skills/artifacts/
|
skills/artifacts/
|
||||||
*.generated.ts
|
*.generated.ts
|
||||||
|
|||||||
26
AGENTS.md
26
AGENTS.md
@@ -13,7 +13,27 @@
|
|||||||
- `standalone`;
|
- `standalone`;
|
||||||
- `standalone@vite`;
|
- `standalone@vite`;
|
||||||
- `standalone@webpack`;
|
- `standalone@webpack`;
|
||||||
- будущие `vue@*` и другие modes.
|
- `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 самостоятельно определяет:
|
Для каждого exact mode используется отдельный каталог `src/modes/<mode-slug>/`. Adapter самостоятельно определяет:
|
||||||
|
|
||||||
@@ -59,7 +79,9 @@ Core не генерирует JavaScript, declarations, manifest source, CSS и
|
|||||||
|
|
||||||
Один config разрешается ровно в один mode и один output. Множественные modes не генерируются в один root; orchestration выполняется независимыми config/API/CLI вызовами.
|
Один config разрешается ровно в один mode и один output. Множественные modes не генерируются в один root; orchestration выполняется независимыми config/API/CLI вызовами.
|
||||||
|
|
||||||
Runtime генерируется как ESM JavaScript. Типизация добавляется отдельными `.d.ts`; TypeScript/TSX не используется как runtime output.
|
Каждый 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 создают.
|
Core writer полностью владеет каталогом `.svg-sprite` и при каждой генерации заменяет его через временный каталог с rollback при ошибке. Корневым `.gitignore` writer владеет, когда exact-mode adapter запрашивает его через `OutputPlan`. Bare `standalone` не создаёт `.gitignore`; остальные modes создают.
|
||||||
|
|
||||||
|
|||||||
10
FEATURES.md
10
FEATURES.md
@@ -1,12 +1,12 @@
|
|||||||
# Иконки без лишней цены для приложения
|
# Иконки без лишней цены для приложения
|
||||||
|
|
||||||
`@gromlab/svg-sprites` превращает SVG проекта в кешируемую, типизированную систему иконок для vanilla-приложений, React и Next.js. В коде остаются простые компоненты, а приложение получает преимущества спрайтов без сложной инфраструктуры.
|
`@gromlab/svg-sprites` превращает SVG проекта в кешируемую, типизированную систему иконок для современных web frameworks. В коде остаются нативные компоненты выбранного стека, а приложение получает преимущества спрайтов без сложной инфраструктуры.
|
||||||
|
|
||||||
1. **AI-friendly из коробки**
|
1. **AI-friendly из коробки**
|
||||||
|
|
||||||
`@gromlab/svg-sprites` сразу рассчитан на работу с AI-агентами. Подключите готовый skill и поручите агенту настройку, миграцию или диагностику без длинных инструкций и ручного изучения документации.
|
`@gromlab/svg-sprites` сразу рассчитан на работу с AI-агентами. Подключите готовый skill и поручите агенту настройку, миграцию или диагностику без длинных инструкций и ручного изучения документации.
|
||||||
|
|
||||||
2. **Типизированный React-компонент с автокомплитом**
|
2. **Типизированный нативный компонент с автокомплитом**
|
||||||
|
|
||||||
Каждый спрайт получает собственный готовый компонент. Prop `icon` формируется из реальных имён SVG, поэтому редактор показывает точный список доступных иконок, а TypeScript сразу обнаруживает опечатки. Не нужно вручную поддерживать компоненты, union-типы или реестр имён.
|
Каждый спрайт получает собственный готовый компонент. Prop `icon` формируется из реальных имён SVG, поэтому редактор показывает точный список доступных иконок, а TypeScript сразу обнаруживает опечатки. Не нужно вручную поддерживать компоненты, union-типы или реестр имён.
|
||||||
|
|
||||||
@@ -40,11 +40,11 @@
|
|||||||
|
|
||||||
10. **SpriteViewer: все спрайты на одной debug-странице**
|
10. **SpriteViewer: все спрайты на одной debug-странице**
|
||||||
|
|
||||||
`SpriteViewer` рендерит все спрайты проекта в одном месте и показывает, какие иконки вошли в каждый набор и как они выглядят. Для каждой иконки видны созданные CSS-переменные и их fallback-цвета. Значения можно менять прямо в Viewer и сразу наблюдать результат. Здесь же доступны готовые примеры подключения через React, `<svg><use>`, `<img>` и CSS.
|
`SpriteViewer` рендерит все спрайты проекта в одном месте и показывает, какие иконки вошли в каждый набор и как они выглядят. Для каждой иконки видны созданные CSS-переменные и их fallback-цвета. Значения можно менять прямо в Viewer и сразу наблюдать результат. Здесь же доступны готовые примеры для framework из manifest, `<svg><use>`, `<img>` и CSS.
|
||||||
|
|
||||||
11. **Standalone, React и Next.js**
|
11. **29 exact modes**
|
||||||
|
|
||||||
Для vanilla-приложений с Vite или Webpack пакет генерирует нативный типизированный Web Component без runtime-зависимостей. Для React и Next.js создаётся React-компонент с поддержкой Vite, Webpack 5, App Router, Pages Router и Turbopack.
|
Изолированные 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**
|
12. **Чистый Git**
|
||||||
|
|
||||||
|
|||||||
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`
|
||||||
118
README.md
118
README.md
@@ -1,12 +1,12 @@
|
|||||||
# @gromlab/svg-sprites
|
# @gromlab/svg-sprites
|
||||||
|
|
||||||
🇬🇧 English | [🇷🇺 Русский](README_RU.md)
|
🇬🇧 English | [🇷🇺 Русский](https://github.com/gromlab-ru/svg-sprites/blob/master/README_RU.md)
|
||||||
|
|
||||||
 
|
 
|
||||||
|
|
||||||
`@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.
|
`@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.
|
||||||
|
|
||||||
For vanilla applications using Vite/Webpack, the package generates a native typed Web Component; for React and Next.js, it generates a React component. In every case, the SVG remains a separate cacheable asset.
|
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.
|
||||||
|
|
||||||
## An SVG sprite as simple as a regular SVG icon
|
## An SVG sprite as simple as a regular SVG icon
|
||||||
|
|
||||||
@@ -24,20 +24,6 @@ The component accepts familiar SVG attributes: dimensions, `color`, `className`,
|
|||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
In `standalone@vite` and `standalone@webpack`, the same approach works without React:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineAppIconElement } from './app-icons'
|
|
||||||
|
|
||||||
defineAppIconElement()
|
|
||||||
```
|
|
||||||
|
|
||||||
```html
|
|
||||||
<app-icon icon="search" style="font-size: 24px"></app-icon>
|
|
||||||
```
|
|
||||||
|
|
||||||
Bare `standalone` remains minimal and generates only an SVG asset and JSON manifest, with no JavaScript runtime.
|
|
||||||
|
|
||||||
## AI-friendly out of the box
|
## AI-friendly out of the box
|
||||||
|
|
||||||
`@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.
|
`@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.
|
||||||
@@ -46,62 +32,55 @@ Bare `standalone` remains minimal and generates only an SVG asset and JSON manif
|
|||||||
|
|
||||||
[🇷🇺 Download AI skill (Russian)](https://github.com/gromlab-ru/svg-sprites/releases/latest/download/svg-sprites-ru.zip)
|
[🇷🇺 Download AI skill (Russian)](https://github.com/gromlab-ru/svg-sprites/releases/latest/download/svg-sprites-ru.zip)
|
||||||
|
|
||||||
## From SVG to component in four steps
|
## From SVG to component in three steps
|
||||||
|
|
||||||
The main example uses the Next.js App Router and Turbopack.
|
The main example uses the Next.js App Router and Turbopack.
|
||||||
|
|
||||||
### 1. Generate without installing the package
|
### 1. Specify the icons you need
|
||||||
|
|
||||||
```bash
|
Create directories for the source icons and the sprite:
|
||||||
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites --help
|
|
||||||
```
|
|
||||||
|
|
||||||
`npx` downloads the CLI temporarily. It does not add `@gromlab/svg-sprites` to
|
|
||||||
`package.json`, and the generated production runtime does not import the package.
|
|
||||||
|
|
||||||
### 2. Specify the icons you need
|
|
||||||
|
|
||||||
SVG files can remain in your project's existing structure:
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
src/
|
assets/
|
||||||
├── assets/icons/
|
├── app-icons/
|
||||||
│ ├── search.svg
|
│ └── svg-sprite.config.json
|
||||||
│ └── settings.svg
|
└── svg-icons/
|
||||||
├── features/profile/
|
├── search.svg
|
||||||
│ └── user.svg
|
└── settings.svg
|
||||||
└── ui/app-icons/
|
|
||||||
└── svg-sprite.config.ts
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Create the sprite configuration:
|
Create the sprite configuration:
|
||||||
|
|
||||||
```ts
|
```json
|
||||||
// src/ui/app-icons/svg-sprite.config.ts
|
{
|
||||||
export default {
|
"mode": "next@app/turbopack",
|
||||||
mode: 'next@app/turbopack',
|
"name": "app",
|
||||||
name: 'app',
|
"input": "../svg-icons/**/*.svg"
|
||||||
input: [
|
|
||||||
'../../assets/icons/search.svg',
|
|
||||||
'../../assets/icons/settings.svg',
|
|
||||||
'../../features/profile/user.svg',
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. Add generation
|
`input` supports directory paths, individual SVG files, and glob patterns.
|
||||||
|
|
||||||
|
### 2. Add a generation script
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/ui/app-icons/svg-sprite.config.ts",
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
"predev": "npm run sprites",
|
"predev": "npm run sprites",
|
||||||
"prebuild": "npm run sprites"
|
"prebuild": "npm run sprites"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Run it for the first time:
|
Create an entry point for the generated API:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// assets/app-icons/index.ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
First run:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run sprites
|
npm run sprites
|
||||||
@@ -109,10 +88,11 @@ npm run sprites
|
|||||||
|
|
||||||
The package will generate `AppIcon`, TypeScript types, and a separate SVG sprite.
|
The package will generate `AppIcon`, TypeScript types, and a separate SVG sprite.
|
||||||
|
|
||||||
### 4. Use it like a regular icon
|
### 3. Use it like a regular icon
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
import { AppIcon } from '@/ui/app-icons'
|
// app/page.tsx
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
export default function SearchButton() {
|
export default function SearchButton() {
|
||||||
return (
|
return (
|
||||||
@@ -225,26 +205,21 @@ Create themes, states, and hover effects without editing the SVG or making addit
|
|||||||
|
|
||||||
## SpriteViewer: every sprite on one debug page
|
## SpriteViewer: every sprite on one debug page
|
||||||
|
|
||||||
`SpriteViewer` renders all standalone, React, and Next.js project sprites in one place. One Web Component owns the visuals, while React uses a thin bridge to it.
|
`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.
|
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 integration examples for:
|
It also provides ready-to-use examples for the manifest's framework, `<svg><use>`, `<img>`, and CSS.
|
||||||
|
|
||||||
- React;
|
|
||||||
- `<svg><use>`;
|
|
||||||
- `<img>`;
|
|
||||||
- CSS.
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
The Viewer is added only to an internal debug page and does not become part of the generated icon components.
|
The Viewer is added only to an internal debug page and does not become part of the generated icon components.
|
||||||
|
|
||||||
Bare standalone loads the Viewer as a browser script and HTML element; bundler modes use the npm entry, while React and Next.js import `SpriteViewer` from `@gromlab/svg-sprites/react`.
|
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`.
|
||||||
|
|
||||||
## Standalone, React, and Next.js
|
## 29 exact modes
|
||||||
|
|
||||||
The package generates low-level standalone sprites for static HTML, Vite, and Webpack 5, plus typed React components for React and Next.js.
|
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
|
## Clean Git history
|
||||||
|
|
||||||
@@ -269,6 +244,26 @@ This README introduces the project's capabilities and demonstrates the primary u
|
|||||||
- [Standalone + Webpack 5](docs/en/guides/standalone-webpack.md)
|
- [Standalone + Webpack 5](docs/en/guides/standalone-webpack.md)
|
||||||
- [React + Vite](docs/en/guides/react-vite.md)
|
- [React + Vite](docs/en/guides/react-vite.md)
|
||||||
- [React + Webpack 5](docs/en/guides/react-webpack.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 + Turbopack](docs/en/guides/next-app-turbopack.md)
|
||||||
- [Next.js App Router + Webpack](docs/en/guides/next-app-webpack.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 + Turbopack](docs/en/guides/next-pages-turbopack.md)
|
||||||
@@ -277,6 +272,7 @@ This README introduces the project's capabilities and demonstrates the primary u
|
|||||||
### Technical resources
|
### Technical resources
|
||||||
|
|
||||||
- [Documentation index](docs/en/README.md)
|
- [Documentation index](docs/en/README.md)
|
||||||
|
- [Configuration](docs/en/configuration.md)
|
||||||
- [Technical reference](docs/en/reference/technical.md)
|
- [Technical reference](docs/en/reference/technical.md)
|
||||||
- [Programmatic API](docs/en/reference/programmatic-api.md)
|
- [Programmatic API](docs/en/reference/programmatic-api.md)
|
||||||
|
|
||||||
|
|||||||
116
README_RU.md
116
README_RU.md
@@ -1,12 +1,12 @@
|
|||||||
# @gromlab/svg-sprites
|
# @gromlab/svg-sprites
|
||||||
|
|
||||||
[🇬🇧 English](README.md) | 🇷🇺 Русский
|
[🇬🇧 English](https://github.com/gromlab-ru/svg-sprites/blob/master/README.md) | 🇷🇺 Русский
|
||||||
|
|
||||||
 
|
 
|
||||||
|
|
||||||
`@gromlab/svg-sprites` — генератор SVG-спрайтов для современных веб-приложений. Он собирает выбранные SVG-иконки в один или несколько внешних кешируемых спрайтов и подготавливает их для использования в интерфейсе.
|
`@gromlab/svg-sprites` — генератор SVG-спрайтов для современных веб-приложений. Он собирает выбранные SVG-иконки в один или несколько внешних кешируемых спрайтов и подготавливает их для использования в интерфейсе.
|
||||||
|
|
||||||
Для vanilla-приложений с Vite/Webpack пакет создаёт нативный типизированный Web Component, а для React и Next.js — React-компонент. SVG во всех случаях остаётся отдельным кешируемым asset.
|
Каждый exact mode создаёт нативный типизированный компонент для своего framework и bundler: Web Component, React, Vue, Svelte, Angular, Astro, Solid, Preact, Qwik, Lit или Alpine.js. SVG во всех случаях остаётся отдельным кешируемым asset.
|
||||||
|
|
||||||
## SVG-спрайт так же прост, как обычная SVG-иконка
|
## SVG-спрайт так же прост, как обычная SVG-иконка
|
||||||
|
|
||||||
@@ -24,20 +24,6 @@
|
|||||||
|
|
||||||
В приложении не приходится работать со спрайтом напрямую. Вы используете его так же, как обычную SVG-иконку, но получаете один компонент, автокомплит и TypeScript-проверку всех имён.
|
В приложении не приходится работать со спрайтом напрямую. Вы используете его так же, как обычную SVG-иконку, но получаете один компонент, автокомплит и TypeScript-проверку всех имён.
|
||||||
|
|
||||||
В `standalone@vite` и `standalone@webpack` тот же подход доступен без React:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineAppIconElement } from './app-icons'
|
|
||||||
|
|
||||||
defineAppIconElement()
|
|
||||||
```
|
|
||||||
|
|
||||||
```html
|
|
||||||
<app-icon icon="search" style="font-size: 24px"></app-icon>
|
|
||||||
```
|
|
||||||
|
|
||||||
Bare `standalone` остаётся минимальным и генерирует только SVG asset и JSON manifest без JavaScript runtime.
|
|
||||||
|
|
||||||
## AI-friendly из коробки
|
## AI-friendly из коробки
|
||||||
|
|
||||||
`@gromlab/svg-sprites` сразу рассчитан на работу с AI-агентами. Подключите готовый skill и поручите агенту настройку, миграцию или диагностику без длинных инструкций и ручного изучения документации.
|
`@gromlab/svg-sprites` сразу рассчитан на работу с AI-агентами. Подключите готовый skill и поручите агенту настройку, миграцию или диагностику без длинных инструкций и ручного изучения документации.
|
||||||
@@ -46,61 +32,54 @@ Bare `standalone` остаётся минимальным и генерируе
|
|||||||
|
|
||||||
[🇬🇧 Скачать AI skill (на английском)](https://github.com/gromlab-ru/svg-sprites/releases/latest/download/svg-sprites.zip)
|
[🇬🇧 Скачать AI skill (на английском)](https://github.com/gromlab-ru/svg-sprites/releases/latest/download/svg-sprites.zip)
|
||||||
|
|
||||||
## От SVG до компонента за четыре шага
|
## От SVG до компонента за три шага
|
||||||
|
|
||||||
Основной пример использует Next.js App Router и Turbopack.
|
Основной пример использует Next.js App Router и Turbopack.
|
||||||
|
|
||||||
### 1. Генерируйте без установки пакета
|
### 1. Укажите нужные иконки
|
||||||
|
|
||||||
```bash
|
Создайте папки для исходных иконок и спрайта:
|
||||||
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites --help
|
|
||||||
```
|
|
||||||
|
|
||||||
`npx` временно скачивает CLI, не добавляет `@gromlab/svg-sprites` в
|
|
||||||
`package.json`, а generated production runtime не импортирует package.
|
|
||||||
|
|
||||||
### 2. Укажите нужные иконки
|
|
||||||
|
|
||||||
SVG могут оставаться в существующей структуре проекта:
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
src/
|
assets/
|
||||||
├── assets/icons/
|
├── app-icons/
|
||||||
│ ├── search.svg
|
│ └── svg-sprite.config.json
|
||||||
│ └── settings.svg
|
└── svg-icons/
|
||||||
├── features/profile/
|
├── search.svg
|
||||||
│ └── user.svg
|
└── settings.svg
|
||||||
└── ui/app-icons/
|
|
||||||
└── svg-sprite.config.ts
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Создайте конфигурацию спрайта:
|
Создайте конфигурацию спрайта:
|
||||||
|
|
||||||
```ts
|
```json
|
||||||
// src/ui/app-icons/svg-sprite.config.ts
|
{
|
||||||
export default {
|
"mode": "next@app/turbopack",
|
||||||
mode: 'next@app/turbopack',
|
"name": "app",
|
||||||
name: 'app',
|
"input": "../svg-icons/**/*.svg"
|
||||||
input: [
|
|
||||||
'../../assets/icons/search.svg',
|
|
||||||
'../../assets/icons/settings.svg',
|
|
||||||
'../../features/profile/user.svg',
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. Добавьте генерацию
|
`input` поддерживает пути к папкам, отдельным SVG и glob-шаблоны.
|
||||||
|
|
||||||
|
### 2. Добавьте генерацию
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/ui/app-icons/svg-sprite.config.ts",
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
"predev": "npm run sprites",
|
"predev": "npm run sprites",
|
||||||
"prebuild": "npm run sprites"
|
"prebuild": "npm run sprites"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Создайте точку входа для сгенерированного API:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// assets/app-icons/index.ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
Первый запуск:
|
Первый запуск:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -109,10 +88,11 @@ npm run sprites
|
|||||||
|
|
||||||
Пакет создаст `AppIcon`, TypeScript-типы и отдельный SVG-спрайт.
|
Пакет создаст `AppIcon`, TypeScript-типы и отдельный SVG-спрайт.
|
||||||
|
|
||||||
### 4. Используйте как обычную иконку
|
### 3. Используйте как обычную иконку
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
import { AppIcon } from '@/ui/app-icons'
|
// app/page.tsx
|
||||||
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
export default function SearchButton() {
|
export default function SearchButton() {
|
||||||
return (
|
return (
|
||||||
@@ -225,26 +205,21 @@ JavaScript отвечает за интерфейс и поведение, а г
|
|||||||
|
|
||||||
## SpriteViewer: все спрайты на одной debug-странице
|
## SpriteViewer: все спрайты на одной debug-странице
|
||||||
|
|
||||||
`SpriteViewer` рендерит все standalone, React и Next.js спрайты проекта в одном месте. Один Web Component отвечает за визуал, а React использует тонкий bridge к нему.
|
`SpriteViewer` рендерит спрайты всех поддерживаемых exact modes в одном месте. Один Web Component отвечает за визуал, а для React также доступен тонкий bridge к нему.
|
||||||
|
|
||||||
Для каждой иконки видны созданные CSS-переменные и их fallback-цвета. Значения можно менять прямо в Viewer и сразу наблюдать результат.
|
Для каждой иконки видны созданные CSS-переменные и их fallback-цвета. Значения можно менять прямо в Viewer и сразу наблюдать результат.
|
||||||
|
|
||||||
Здесь же доступны готовые примеры подключения через:
|
Здесь же доступны готовые примеры для framework из manifest, `<svg><use>`, `<img>` и CSS.
|
||||||
|
|
||||||
- React;
|
|
||||||
- `<svg><use>`;
|
|
||||||
- `<img>`;
|
|
||||||
- CSS.
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Viewer подключается только к внутренней debug-странице и не становится частью generated-компонентов иконок.
|
Viewer подключается только к внутренней debug-странице и не становится частью generated-компонентов иконок.
|
||||||
|
|
||||||
Bare standalone подключает Viewer через browser script и HTML element; bundler modes используют npm entry, а React и Next.js импортируют `SpriteViewer` из `@gromlab/svg-sprites/react`.
|
Bare standalone подключает Viewer через browser script и HTML element. Bundler и framework modes используют npm entry Web Component; React и Next.js также могут импортировать bridge из `@gromlab/svg-sprites/react`.
|
||||||
|
|
||||||
## Standalone, React и Next.js
|
## 29 exact modes
|
||||||
|
|
||||||
Пакет генерирует низкоуровневые standalone-спрайты для static HTML, Vite и Webpack 5, а также типизированные React-компоненты для React и Next.js.
|
Пакет предоставляет изолированные контракты для standalone, React, Next.js, Vue, Nuxt, Svelte, SvelteKit, Angular, Astro, Solid, SolidStart, Preact, Qwik, Lit и Alpine.js в поддерживаемых вариантах Vite, Webpack, Turbopack и application builder.
|
||||||
|
|
||||||
## Чистый Git
|
## Чистый Git
|
||||||
|
|
||||||
@@ -269,6 +244,26 @@ README знакомит с возможностями проекта и пока
|
|||||||
- [Standalone + Webpack 5](docs/ru/guides/standalone-webpack.md)
|
- [Standalone + Webpack 5](docs/ru/guides/standalone-webpack.md)
|
||||||
- [React + Vite](docs/ru/guides/react-vite.md)
|
- [React + Vite](docs/ru/guides/react-vite.md)
|
||||||
- [React + Webpack 5](docs/ru/guides/react-webpack.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 + Turbopack](docs/ru/guides/next-app-turbopack.md)
|
||||||
- [Next.js App Router + Webpack](docs/ru/guides/next-app-webpack.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 + Turbopack](docs/ru/guides/next-pages-turbopack.md)
|
||||||
@@ -277,6 +272,7 @@ README знакомит с возможностями проекта и пока
|
|||||||
### Технические материалы
|
### Технические материалы
|
||||||
|
|
||||||
- [Индекс документации](docs/ru/README.md)
|
- [Индекс документации](docs/ru/README.md)
|
||||||
|
- [Конфигурация](docs/ru/configuration.md)
|
||||||
- [Технический справочник](docs/ru/reference/technical.md)
|
- [Технический справочник](docs/ru/reference/technical.md)
|
||||||
- [Программный API](docs/ru/reference/programmatic-api.md)
|
- [Программный API](docs/ru/reference/programmatic-api.md)
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
Choose one exact mode guide for setup. The guides are standalone documents and
|
Choose one exact mode guide for setup. The guides are standalone documents and
|
||||||
can also be used unchanged by AI skills.
|
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
|
## Quick Start Guides
|
||||||
|
|
||||||
| Project | Exact mode | Guide |
|
| Project | Exact mode | Guide |
|
||||||
@@ -12,6 +14,26 @@ can also be used unchanged by AI skills.
|
|||||||
| Vanilla + Webpack 5 | `standalone@webpack` | [Standalone + Webpack](guides/standalone-webpack.md) |
|
| Vanilla + Webpack 5 | `standalone@webpack` | [Standalone + Webpack](guides/standalone-webpack.md) |
|
||||||
| React + Vite | `react@vite` | [React + Vite](guides/react-vite.md) |
|
| React + Vite | `react@vite` | [React + Vite](guides/react-vite.md) |
|
||||||
| React + Webpack 5 | `react@webpack` | [React + Webpack](guides/react-webpack.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 + 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 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 + Turbopack | `next@pages/turbopack` | [Pages Router + Turbopack](guides/next-pages-turbopack.md) |
|
||||||
@@ -20,10 +42,11 @@ can also be used unchanged by AI skills.
|
|||||||
Every guide follows the same order:
|
Every guide follows the same order:
|
||||||
|
|
||||||
1. Generate the sprite through `npx` without adding the package to the project.
|
1. Generate the sprite through `npx` without adding the package to the project.
|
||||||
2. Optionally install and connect the debug Viewer.
|
2. Use the sprite in the application.
|
||||||
3. Optionally type the config through the package or a local copy-paste type.
|
3. Optionally add the Viewer for debugging and previews.
|
||||||
|
|
||||||
## Reference
|
## Reference
|
||||||
|
|
||||||
|
- [Configuration](configuration.md)
|
||||||
- [Technical reference](reference/technical.md)
|
- [Technical reference](reference/technical.md)
|
||||||
- [Programmatic API](reference/programmatic-api.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).
|
||||||
@@ -5,6 +5,26 @@
|
|||||||
- `standalone@webpack`: [standalone with Webpack](standalone-webpack.md)
|
- `standalone@webpack`: [standalone with Webpack](standalone-webpack.md)
|
||||||
- `react@vite`: [React with Vite](react-vite.md)
|
- `react@vite`: [React with Vite](react-vite.md)
|
||||||
- `react@webpack`: [React with Webpack](react-webpack.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/turbopack`: [App Router with Turbopack](next-app-turbopack.md)
|
||||||
- `next@app/webpack`: [App Router with Webpack](next-app-webpack.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/turbopack`: [Pages Router with Turbopack](next-pages-turbopack.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`.
|
||||||
@@ -1,153 +1,108 @@
|
|||||||
# Next.js App Router Turbopack SVG Sprite Quick Start
|
# SVG Sprite for Next.js App Router with Turbopack
|
||||||
|
|
||||||
This guide targets the exact mode key `next@app/turbopack`: a generated typed React icon for the Next.js App Router and Turbopack.
|
A quick guide to creating an SVG sprite in a Next.js application using App Router and Turbopack.
|
||||||
|
|
||||||
## 1. Generate the sprite
|
## Generate the sprite
|
||||||
|
|
||||||
No package installation and no `package.json` dependency are needed. `npx` downloads the CLI temporarily, and generated runtime does not import `@gromlab/svg-sprites`.
|
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.
|
||||||
|
|
||||||
Keep the config and source icons together:
|
Example configuration:
|
||||||
|
|
||||||
```text
|
```json
|
||||||
src/ui/icons/
|
{
|
||||||
├── icons/
|
"mode": "next@app/turbopack",
|
||||||
│ ├── check.svg
|
"name": "app",
|
||||||
│ └── folder.svg
|
"input": "../svg-icons/**/*.svg"
|
||||||
└── svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Use a plain default object export with no package import:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// src/ui/icons/svg-sprite.config.ts
|
|
||||||
export default {
|
|
||||||
mode: 'next@app/turbopack',
|
|
||||||
name: 'icons',
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
When `input` is omitted, SVG files are read from `./icons` relative to the config. A `.js` config with a default export and a `.json` config are also supported. Generate directly with:
|
The package does not need to be a project dependency: generation runs through `npx`.
|
||||||
|
|
||||||
```bash
|
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:
|
||||||
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/ui/icons/svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Generate once per invocation and keep the exact Turbopack flags on both commands:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/ui/icons/svg-sprite.config.ts",
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
"dev": "npm run sprites && next dev --turbopack",
|
"predev": "npm run sprites",
|
||||||
"build": "npm run sprites && next build --turbopack"
|
"dev": "next dev --turbopack",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "next build --turbopack"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Do not add `predev` or `prebuild` hooks to these scripts; that would run generation twice. In CI, replace `latest` with an exact package version.
|
## Use the sprite
|
||||||
|
|
||||||
Generation creates a local `.gitignore`; commit that file once, but do not commit `.svg-sprite/`. Generated declarations are self-contained and do not require the package.
|
The value `name: "app"` creates the React component `AppIcon`.
|
||||||
|
|
||||||
### Production usage
|
Create the entry point `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
The generated icon has no `'use client'` directive and is Server Component-compatible. Import it directly in an App Router page or layout:
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the component in a Server Component:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// src/app/page.tsx
|
// app/page.tsx
|
||||||
import {
|
import { AppIcon } from '../assets/app-icons'
|
||||||
IconsIcon,
|
|
||||||
iconsIconNames,
|
|
||||||
} from '../ui/icons/.svg-sprite/index.js'
|
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return (
|
return (
|
||||||
<main>
|
<AppIcon
|
||||||
<IconsIcon icon="folder" width={24} height={24} aria-label="Files" />
|
icon="icon-name"
|
||||||
<p>{iconsIconNames.length} icons available</p>
|
width={24}
|
||||||
</main>
|
height={24}
|
||||||
|
role="img"
|
||||||
|
aria-label="Done"
|
||||||
|
style={{
|
||||||
|
color: '#334155',
|
||||||
|
'--icon-color-2': '#f59e0b',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Turbopack resolves the generated `new URL('../sprite.svg', import.meta.url)` and CSS Module, emitting a separate SVG asset. Keep the mode and the `--turbopack` dev/build flags aligned.
|
`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`.
|
||||||
|
|
||||||
## 2. Debug and preview
|
## Debug and preview
|
||||||
|
|
||||||
This section is optional. Only users who need the Viewer or icon previews should install:
|
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
|
```bash
|
||||||
npm install --save-dev @gromlab/svg-sprites
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
```
|
```
|
||||||
|
|
||||||
Viewer is interactive, so place the React bridge in a separate Client Component:
|
Create the Client Component `app/svg-sprite/SvgSpriteViewer.tsx`:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// src/app/icon-debug/IconsViewer.tsx
|
|
||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
|
||||||
const sources = [
|
const sources = [
|
||||||
() => import('../../ui/icons/.svg-sprite/svg-sprite.manifest.js'),
|
() => import('../../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
]
|
] as const
|
||||||
|
|
||||||
export function IconsViewer() {
|
export function SvgSpriteViewer() {
|
||||||
return <SpriteViewer sources={sources} title="Project icons" />
|
return <SpriteViewer sources={sources} title="Project icons" />
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Render it from the route's Server Component:
|
Create the route `app/svg-sprite/page.tsx`:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// src/app/icon-debug/page.tsx
|
import { notFound } from 'next/navigation'
|
||||||
import { IconsViewer } from './IconsViewer'
|
|
||||||
|
|
||||||
export default function IconDebugPage() {
|
import { SvgSpriteViewer } from './SvgSpriteViewer'
|
||||||
return <IconsViewer />
|
|
||||||
|
export default function SvgSpritePage() {
|
||||||
|
if (process.env.NODE_ENV !== 'development') notFound()
|
||||||
|
|
||||||
|
return <SvgSpriteViewer />
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Keep the route internal or development-only. Viewer is not part of the production icon runtime.
|
Run `npm run dev` and open `/svg-sprite`. In production, the route returns 404.
|
||||||
|
|
||||||
## 3. Type the config
|
|
||||||
|
|
||||||
Choose one of these two paths.
|
|
||||||
|
|
||||||
### With a local package installation
|
|
||||||
|
|
||||||
After installing the package locally, use the helper:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineSpriteConfig({
|
|
||||||
mode: 'next@app/turbopack',
|
|
||||||
name: 'icons',
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
You can alternatively import `type SpriteConfig` and apply `satisfies SpriteConfig`.
|
|
||||||
|
|
||||||
### Without the package
|
|
||||||
|
|
||||||
Copy a mode-specific type directly into the config:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type LocalSpriteConfig = {
|
|
||||||
mode: 'next@app/turbopack'
|
|
||||||
name?: string
|
|
||||||
description?: string
|
|
||||||
input?: string | string[]
|
|
||||||
transform?: {
|
|
||||||
removeSize?: boolean
|
|
||||||
replaceColors?: boolean
|
|
||||||
addTransition?: boolean
|
|
||||||
}
|
|
||||||
generatedNotice?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mode: 'next@app/turbopack',
|
|
||||||
name: 'icons',
|
|
||||||
} satisfies LocalSpriteConfig
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -1,153 +1,108 @@
|
|||||||
# Next.js App Router Webpack SVG Sprite Quick Start
|
# SVG Sprite for Next.js App Router with Webpack
|
||||||
|
|
||||||
This guide targets the exact mode key `next@app/webpack`: a generated typed React icon for the Next.js App Router and Webpack 5.
|
A quick guide to creating an SVG sprite in a Next.js application using App Router and Webpack.
|
||||||
|
|
||||||
## 1. Generate the sprite
|
## Generate the sprite
|
||||||
|
|
||||||
No package installation and no `package.json` dependency are needed. `npx` downloads the CLI temporarily, and generated runtime does not import `@gromlab/svg-sprites`.
|
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.
|
||||||
|
|
||||||
Keep the config adjacent to its source icons:
|
Example configuration:
|
||||||
|
|
||||||
```text
|
```json
|
||||||
src/ui/icons/
|
{
|
||||||
├── icons/
|
"mode": "next@app/webpack",
|
||||||
│ ├── check.svg
|
"name": "app",
|
||||||
│ └── folder.svg
|
"input": "../svg-icons/**/*.svg"
|
||||||
└── svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Use a plain default object export with no package import:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// src/ui/icons/svg-sprite.config.ts
|
|
||||||
export default {
|
|
||||||
mode: 'next@app/webpack',
|
|
||||||
name: 'icons',
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
When `input` is omitted, SVG files are read from `./icons` relative to the config. A `.js` config with a default export and a `.json` config are also supported. Generate directly with:
|
The package does not need to be a project dependency: generation runs through `npx`.
|
||||||
|
|
||||||
```bash
|
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:
|
||||||
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/ui/icons/svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Generate once per invocation and keep the exact Webpack flags on both commands:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/ui/icons/svg-sprite.config.ts",
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
"dev": "npm run sprites && next dev --webpack",
|
"predev": "npm run sprites",
|
||||||
"build": "npm run sprites && next build --webpack"
|
"dev": "next dev --webpack",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "next build --webpack"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Do not add `predev` or `prebuild` hooks to these scripts; that would run generation twice. In CI, replace `latest` with an exact package version.
|
## Use the sprite
|
||||||
|
|
||||||
Generation creates a local `.gitignore`; commit that file once, but do not commit `.svg-sprite/`. Generated declarations are self-contained and do not require the package.
|
The value `name: "app"` creates the React component `AppIcon`.
|
||||||
|
|
||||||
### Production usage
|
Create the entry point `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
The generated icon has no `'use client'` directive and is Server Component-compatible. Import it directly in an App Router page or layout:
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the component in a Server Component:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// src/app/page.tsx
|
// app/page.tsx
|
||||||
import {
|
import { AppIcon } from '../assets/app-icons'
|
||||||
IconsIcon,
|
|
||||||
iconsIconNames,
|
|
||||||
} from '../ui/icons/.svg-sprite/index.js'
|
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return (
|
return (
|
||||||
<main>
|
<AppIcon
|
||||||
<IconsIcon icon="folder" width={24} height={24} aria-label="Files" />
|
icon="icon-name"
|
||||||
<p>{iconsIconNames.length} icons available</p>
|
width={24}
|
||||||
</main>
|
height={24}
|
||||||
|
role="img"
|
||||||
|
aria-label="Done"
|
||||||
|
style={{
|
||||||
|
color: '#334155',
|
||||||
|
'--icon-color-2': '#f59e0b',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Webpack resolves the generated `new URL('../sprite.svg', import.meta.url)` and CSS Module, emitting a separate SVG asset. Keep the mode and the `--webpack` dev/build flags aligned. If custom Next.js webpack rules process SVG through SVGR, exclude `.svg-sprite/sprite.svg` from those rules.
|
`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`.
|
||||||
|
|
||||||
## 2. Debug and preview
|
## Debug and preview
|
||||||
|
|
||||||
This section is optional. Only users who need the Viewer or icon previews should install:
|
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
|
```bash
|
||||||
npm install --save-dev @gromlab/svg-sprites
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
```
|
```
|
||||||
|
|
||||||
Viewer is interactive, so place the React bridge in a separate Client Component:
|
Create the Client Component `app/svg-sprite/SvgSpriteViewer.tsx`:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// src/app/icon-debug/IconsViewer.tsx
|
|
||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
|
||||||
const sources = [
|
const sources = [
|
||||||
() => import('../../ui/icons/.svg-sprite/svg-sprite.manifest.js'),
|
() => import('../../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
]
|
] as const
|
||||||
|
|
||||||
export function IconsViewer() {
|
export function SvgSpriteViewer() {
|
||||||
return <SpriteViewer sources={sources} title="Project icons" />
|
return <SpriteViewer sources={sources} title="Project icons" />
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Render it from the route's Server Component:
|
Create the route `app/svg-sprite/page.tsx`:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// src/app/icon-debug/page.tsx
|
import { notFound } from 'next/navigation'
|
||||||
import { IconsViewer } from './IconsViewer'
|
|
||||||
|
|
||||||
export default function IconDebugPage() {
|
import { SvgSpriteViewer } from './SvgSpriteViewer'
|
||||||
return <IconsViewer />
|
|
||||||
|
export default function SvgSpritePage() {
|
||||||
|
if (process.env.NODE_ENV !== 'development') notFound()
|
||||||
|
|
||||||
|
return <SvgSpriteViewer />
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Keep the route internal or development-only. Viewer is not part of the production icon runtime.
|
Run `npm run dev` and open `/svg-sprite`. In production, the route returns 404.
|
||||||
|
|
||||||
## 3. Type the config
|
|
||||||
|
|
||||||
Choose one of these two paths.
|
|
||||||
|
|
||||||
### With a local package installation
|
|
||||||
|
|
||||||
After installing the package locally, use the helper:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineSpriteConfig({
|
|
||||||
mode: 'next@app/webpack',
|
|
||||||
name: 'icons',
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
You can alternatively import `type SpriteConfig` and apply `satisfies SpriteConfig`.
|
|
||||||
|
|
||||||
### Without the package
|
|
||||||
|
|
||||||
Copy a mode-specific type directly into the config:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type LocalSpriteConfig = {
|
|
||||||
mode: 'next@app/webpack'
|
|
||||||
name?: string
|
|
||||||
description?: string
|
|
||||||
input?: string | string[]
|
|
||||||
transform?: {
|
|
||||||
removeSize?: boolean
|
|
||||||
replaceColors?: boolean
|
|
||||||
addTransition?: boolean
|
|
||||||
}
|
|
||||||
generatedNotice?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mode: 'next@app/webpack',
|
|
||||||
name: 'icons',
|
|
||||||
} satisfies LocalSpriteConfig
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -1,140 +1,98 @@
|
|||||||
# Next.js Pages Router Turbopack SVG Sprite Quick Start
|
# SVG Sprite for Next.js Pages Router with Turbopack
|
||||||
|
|
||||||
This guide targets the exact mode key `next@pages/turbopack`: a generated typed React icon for the Next.js Pages Router and Turbopack.
|
A quick guide to creating an SVG sprite in a Next.js application using Pages Router and Turbopack.
|
||||||
|
|
||||||
## 1. Generate the sprite
|
## Generate the sprite
|
||||||
|
|
||||||
No package installation and no `package.json` dependency are needed. `npx` downloads the CLI temporarily, and generated runtime does not import `@gromlab/svg-sprites`.
|
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.
|
||||||
|
|
||||||
Keep the config and source icons together:
|
Example configuration:
|
||||||
|
|
||||||
```text
|
```json
|
||||||
src/ui/icons/
|
{
|
||||||
├── icons/
|
"mode": "next@pages/turbopack",
|
||||||
│ ├── check.svg
|
"name": "app",
|
||||||
│ └── folder.svg
|
"input": "../svg-icons/**/*.svg"
|
||||||
└── svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Use a plain default object export with no package import:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// src/ui/icons/svg-sprite.config.ts
|
|
||||||
export default {
|
|
||||||
mode: 'next@pages/turbopack',
|
|
||||||
name: 'icons',
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
When `input` is omitted, SVG files are read from `./icons` relative to the config. A `.js` config with a default export and a `.json` config are also supported. Generate directly with:
|
The package does not need to be a project dependency: generation runs through `npx`.
|
||||||
|
|
||||||
```bash
|
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:
|
||||||
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/ui/icons/svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Generate once per invocation and keep the exact Turbopack flags on both commands:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/ui/icons/svg-sprite.config.ts",
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
"dev": "npm run sprites && next dev --turbopack",
|
"predev": "npm run sprites",
|
||||||
"build": "npm run sprites && next build --turbopack"
|
"dev": "next dev --turbopack",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "next build --turbopack"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Do not add `predev` or `prebuild` hooks to these scripts; that would run generation twice. In CI, replace `latest` with an exact package version.
|
## Use the sprite
|
||||||
|
|
||||||
Generation creates a local `.gitignore`; commit that file once, but do not commit `.svg-sprite/`. Generated declarations are self-contained and do not require the package.
|
The value `name: "app"` creates the React component `AppIcon`.
|
||||||
|
|
||||||
### Production usage
|
Create the entry point `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
Import the generated component and icon-name list into a Pages Router page:
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the component on a page:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// src/pages/index.tsx
|
// pages/index.tsx
|
||||||
import {
|
import { AppIcon } from '../assets/app-icons'
|
||||||
IconsIcon,
|
|
||||||
iconsIconNames,
|
|
||||||
} from '../ui/icons/.svg-sprite/index.js'
|
|
||||||
|
|
||||||
export default function HomePage() {
|
export default function Page() {
|
||||||
return (
|
return (
|
||||||
<main>
|
<AppIcon
|
||||||
<IconsIcon icon="folder" width={24} height={24} aria-label="Files" />
|
icon="icon-name"
|
||||||
<p>{iconsIconNames.length} icons available</p>
|
width={24}
|
||||||
</main>
|
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 resolves the generated SVG URL and CSS Module and emits a separate asset. Keep the mode and the `--turbopack` dev/build flags aligned.
|
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`.
|
||||||
|
|
||||||
## 2. Debug and preview
|
## Debug and preview
|
||||||
|
|
||||||
This section is optional. Only users who need the Viewer or icon previews should install:
|
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
|
```bash
|
||||||
npm install --save-dev @gromlab/svg-sprites
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
```
|
```
|
||||||
|
|
||||||
Pages Router does not require an App Router Client Component boundary. Use the React bridge directly in a page with a static loader array:
|
Create the page `pages/svg-sprite.tsx`:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// src/pages/icon-debug.tsx
|
import type { GetStaticProps } from 'next'
|
||||||
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
|
||||||
const sources = [
|
const sources = [
|
||||||
() => import('../ui/icons/.svg-sprite/svg-sprite.manifest.js'),
|
() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
]
|
] as const
|
||||||
|
|
||||||
export default function IconDebugPage() {
|
export default function SvgSpritePage() {
|
||||||
return <SpriteViewer sources={sources} title="Project icons" />
|
return <SpriteViewer sources={sources} title="Project icons" />
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getStaticProps: GetStaticProps = () =>
|
||||||
|
process.env.NODE_ENV === 'development'
|
||||||
|
? { props: {} }
|
||||||
|
: { notFound: true }
|
||||||
```
|
```
|
||||||
|
|
||||||
Keep the page internal or development-only. Viewer is not part of the production icon runtime.
|
Run `npm run dev` and open `/svg-sprite`. In production, the route returns 404.
|
||||||
|
|
||||||
## 3. Type the config
|
|
||||||
|
|
||||||
Choose one of these two paths.
|
|
||||||
|
|
||||||
### With a local package installation
|
|
||||||
|
|
||||||
After installing the package locally, use the helper:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineSpriteConfig({
|
|
||||||
mode: 'next@pages/turbopack',
|
|
||||||
name: 'icons',
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
You can alternatively import `type SpriteConfig` and apply `satisfies SpriteConfig`.
|
|
||||||
|
|
||||||
### Without the package
|
|
||||||
|
|
||||||
Copy a mode-specific type directly into the config:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type LocalSpriteConfig = {
|
|
||||||
mode: 'next@pages/turbopack'
|
|
||||||
name?: string
|
|
||||||
description?: string
|
|
||||||
input?: string | string[]
|
|
||||||
transform?: {
|
|
||||||
removeSize?: boolean
|
|
||||||
replaceColors?: boolean
|
|
||||||
addTransition?: boolean
|
|
||||||
}
|
|
||||||
generatedNotice?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mode: 'next@pages/turbopack',
|
|
||||||
name: 'icons',
|
|
||||||
} satisfies LocalSpriteConfig
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -1,140 +1,98 @@
|
|||||||
# Next.js Pages Router Webpack SVG Sprite Quick Start
|
# SVG Sprite for Next.js Pages Router with Webpack
|
||||||
|
|
||||||
This guide targets the exact mode key `next@pages/webpack`: a generated typed React icon for the Next.js Pages Router and Webpack 5.
|
A quick guide to creating an SVG sprite in a Next.js application using Pages Router and Webpack.
|
||||||
|
|
||||||
## 1. Generate the sprite
|
## Generate the sprite
|
||||||
|
|
||||||
No package installation and no `package.json` dependency are needed. `npx` downloads the CLI temporarily, and generated runtime does not import `@gromlab/svg-sprites`.
|
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.
|
||||||
|
|
||||||
Keep the config adjacent to its source icons:
|
Example configuration:
|
||||||
|
|
||||||
```text
|
```json
|
||||||
src/ui/icons/
|
{
|
||||||
├── icons/
|
"mode": "next@pages/webpack",
|
||||||
│ ├── check.svg
|
"name": "app",
|
||||||
│ └── folder.svg
|
"input": "../svg-icons/**/*.svg"
|
||||||
└── svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Use a plain default object export with no package import:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// src/ui/icons/svg-sprite.config.ts
|
|
||||||
export default {
|
|
||||||
mode: 'next@pages/webpack',
|
|
||||||
name: 'icons',
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
When `input` is omitted, SVG files are read from `./icons` relative to the config. A `.js` config with a default export and a `.json` config are also supported. Generate directly with:
|
The package does not need to be a project dependency: generation runs through `npx`.
|
||||||
|
|
||||||
```bash
|
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:
|
||||||
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/ui/icons/svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Generate once per invocation and keep the exact Webpack flags on both commands:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/ui/icons/svg-sprite.config.ts",
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
"dev": "npm run sprites && next dev --webpack",
|
"predev": "npm run sprites",
|
||||||
"build": "npm run sprites && next build --webpack"
|
"dev": "next dev --webpack",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "next build --webpack"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Do not add `predev` or `prebuild` hooks to these scripts; that would run generation twice. In CI, replace `latest` with an exact package version.
|
## Use the sprite
|
||||||
|
|
||||||
Generation creates a local `.gitignore`; commit that file once, but do not commit `.svg-sprite/`. Generated declarations are self-contained and do not require the package.
|
The value `name: "app"` creates the React component `AppIcon`.
|
||||||
|
|
||||||
### Production usage
|
Create the entry point `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
Import the generated component and icon-name list into a Pages Router page:
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the component on a page:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// src/pages/index.tsx
|
// pages/index.tsx
|
||||||
import {
|
import { AppIcon } from '../assets/app-icons'
|
||||||
IconsIcon,
|
|
||||||
iconsIconNames,
|
|
||||||
} from '../ui/icons/.svg-sprite/index.js'
|
|
||||||
|
|
||||||
export default function HomePage() {
|
export default function Page() {
|
||||||
return (
|
return (
|
||||||
<main>
|
<AppIcon
|
||||||
<IconsIcon icon="folder" width={24} height={24} aria-label="Files" />
|
icon="icon-name"
|
||||||
<p>{iconsIconNames.length} icons available</p>
|
width={24}
|
||||||
</main>
|
height={24}
|
||||||
|
role="img"
|
||||||
|
aria-label="Done"
|
||||||
|
style={{
|
||||||
|
color: '#334155',
|
||||||
|
'--icon-color-2': '#f59e0b',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The component works with SSR, SSG, and client-side navigation. Webpack resolves the generated SVG URL and CSS Module and emits a separate asset. Keep the mode and the `--webpack` dev/build flags aligned. If custom Next.js webpack rules process SVG through SVGR, exclude `.svg-sprite/sprite.svg` from those rules.
|
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`.
|
||||||
|
|
||||||
## 2. Debug and preview
|
## Debug and preview
|
||||||
|
|
||||||
This section is optional. Only users who need the Viewer or icon previews should install:
|
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
|
```bash
|
||||||
npm install --save-dev @gromlab/svg-sprites
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
```
|
```
|
||||||
|
|
||||||
Pages Router does not require an App Router Client Component boundary. Use the React bridge directly in a page with a static loader array:
|
Create the page `pages/svg-sprite.tsx`:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// src/pages/icon-debug.tsx
|
import type { GetStaticProps } from 'next'
|
||||||
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
|
||||||
const sources = [
|
const sources = [
|
||||||
() => import('../ui/icons/.svg-sprite/svg-sprite.manifest.js'),
|
() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
]
|
] as const
|
||||||
|
|
||||||
export default function IconDebugPage() {
|
export default function SvgSpritePage() {
|
||||||
return <SpriteViewer sources={sources} title="Project icons" />
|
return <SpriteViewer sources={sources} title="Project icons" />
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getStaticProps: GetStaticProps = () =>
|
||||||
|
process.env.NODE_ENV === 'development'
|
||||||
|
? { props: {} }
|
||||||
|
: { notFound: true }
|
||||||
```
|
```
|
||||||
|
|
||||||
Keep the page internal or development-only. Viewer is not part of the production icon runtime.
|
Run `npm run dev` and open `/svg-sprite`. In production, the route returns 404.
|
||||||
|
|
||||||
## 3. Type the config
|
|
||||||
|
|
||||||
Choose one of these two paths.
|
|
||||||
|
|
||||||
### With a local package installation
|
|
||||||
|
|
||||||
After installing the package locally, use the helper:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineSpriteConfig({
|
|
||||||
mode: 'next@pages/webpack',
|
|
||||||
name: 'icons',
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
You can alternatively import `type SpriteConfig` and apply `satisfies SpriteConfig`.
|
|
||||||
|
|
||||||
### Without the package
|
|
||||||
|
|
||||||
Copy a mode-specific type directly into the config:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type LocalSpriteConfig = {
|
|
||||||
mode: 'next@pages/webpack'
|
|
||||||
name?: string
|
|
||||||
description?: string
|
|
||||||
input?: string | string[]
|
|
||||||
transform?: {
|
|
||||||
removeSize?: boolean
|
|
||||||
replaceColors?: boolean
|
|
||||||
addTransition?: boolean
|
|
||||||
}
|
|
||||||
generatedNotice?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mode: 'next@pages/webpack',
|
|
||||||
name: 'icons',
|
|
||||||
} satisfies LocalSpriteConfig
|
|
||||||
```
|
|
||||||
|
|||||||
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} />
|
||||||
|
})
|
||||||
|
```
|
||||||
@@ -1,148 +1,115 @@
|
|||||||
# React Vite SVG Sprite Quick Start
|
# SVG Sprite for React with Vite
|
||||||
|
|
||||||
This guide targets the exact mode key `react@vite`: a generated typed React component with a Vite-managed SVG asset.
|
A quick guide to creating an SVG sprite in a React application built with Vite.
|
||||||
|
|
||||||
## 1. Generate the sprite
|
## Generate the sprite
|
||||||
|
|
||||||
No package installation and no `package.json` dependency are needed. `npx` downloads the CLI temporarily, and generated runtime does not import `@gromlab/svg-sprites`.
|
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.
|
||||||
|
|
||||||
Keep the config and source icons together:
|
Example configuration:
|
||||||
|
|
||||||
```text
|
```json
|
||||||
src/ui/icons/
|
{
|
||||||
├── icons/
|
"mode": "react@vite",
|
||||||
│ ├── check.svg
|
"name": "app",
|
||||||
│ └── folder.svg
|
"input": "../svg-icons/**/*.svg"
|
||||||
└── svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Use a plain default object export with no package import:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// src/ui/icons/svg-sprite.config.ts
|
|
||||||
export default {
|
|
||||||
mode: 'react@vite',
|
|
||||||
name: 'icons',
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
When `input` is omitted, SVG files are read from `./icons` relative to the config. A `.js` config with a default export and a `.json` config are also supported. Generate directly with:
|
The package does not need to be a project dependency: generation runs through `npx`.
|
||||||
|
|
||||||
```bash
|
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:
|
||||||
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/ui/icons/svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Use the exact Vite dev/build commands and generate once per invocation:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/ui/icons/svg-sprite.config.ts",
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
"dev": "npm run sprites && vite",
|
"predev": "npm run sprites",
|
||||||
"build": "npm run sprites && tsc --noEmit && vite build"
|
"dev": "vite",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "tsc --noEmit && vite build"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Do not add `predev` or `prebuild` hooks to these scripts; that would run generation twice. In CI, replace `latest` with an exact package version.
|
## Use the sprite
|
||||||
|
|
||||||
Generation creates a local `.gitignore`; commit that file once, but do not commit `.svg-sprite/`. Generated declarations are self-contained and do not require the package.
|
The value `name: "app"` creates the React component `AppIcon`.
|
||||||
|
|
||||||
### Production usage
|
Create the entry point `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
Import the generated component and icon-name list directly:
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the component in your application:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// src/App.tsx
|
import { AppIcon } from '../assets/app-icons'
|
||||||
import {
|
|
||||||
IconsIcon,
|
|
||||||
iconsIconNames,
|
|
||||||
} from './ui/icons/.svg-sprite/index.js'
|
|
||||||
|
|
||||||
export function App() {
|
export function SaveIcon() {
|
||||||
return (
|
return (
|
||||||
<main>
|
<AppIcon
|
||||||
<IconsIcon icon="check" width={24} height={24} aria-label="Complete" />
|
icon="icon-name"
|
||||||
<small>{iconsIconNames.length} icons available</small>
|
width={24}
|
||||||
</main>
|
height={24}
|
||||||
|
role="img"
|
||||||
|
aria-label="Done"
|
||||||
|
style={{
|
||||||
|
color: '#334155',
|
||||||
|
'--icon-color-2': '#f59e0b',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
`icon` is a generated union of SVG file names. Vite automatically handles the generated CSS Module and the `sprite.svg?no-inline` import, emitting the sprite as a separate asset. If your own TypeScript source imports Vite query assets, include Vite's ambient types:
|
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`.
|
||||||
|
|
||||||
```json
|
Vite automatically includes the component styles and adds `sprite.svg` to the production build.
|
||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"types": ["vite/client"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2. Debug and preview
|
## Debug and preview
|
||||||
|
|
||||||
This section is optional. Only users who need the Viewer or icon previews should install:
|
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
|
```bash
|
||||||
npm install --save-dev @gromlab/svg-sprites
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
```
|
```
|
||||||
|
|
||||||
Use the React `SpriteViewer` bridge with a static loader array. Keep every `import()` path a string literal:
|
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
|
```tsx
|
||||||
// src/IconsDebugPage.tsx
|
import { createRoot } from 'react-dom/client'
|
||||||
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
|
||||||
const sources = [
|
const sources = [
|
||||||
() => import('./ui/icons/.svg-sprite/svg-sprite.manifest.js'),
|
() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
]
|
] as const
|
||||||
|
|
||||||
export function IconsDebugPage() {
|
createRoot(document.getElementById('svg-sprite-viewer')!).render(
|
||||||
return <SpriteViewer sources={sources} title="Project icons" />
|
<SpriteViewer sources={sources} title="Project icons" />,
|
||||||
}
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
Keep this component on a debug route or in an internal tool. Viewer is not part of the production icon runtime.
|
Run `npm run dev` and open `/svg-sprite.html`.
|
||||||
|
|
||||||
## 3. Type the config
|
The standard Vite production build uses only `index.html` and does not include the Viewer page.
|
||||||
|
|
||||||
Choose one of these two paths.
|
|
||||||
|
|
||||||
### With a local package installation
|
|
||||||
|
|
||||||
After installing the package locally, use the helper:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineSpriteConfig({
|
|
||||||
mode: 'react@vite',
|
|
||||||
name: 'icons',
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
You can alternatively import `type SpriteConfig` and apply `satisfies SpriteConfig`.
|
|
||||||
|
|
||||||
### Without the package
|
|
||||||
|
|
||||||
Copy a mode-specific type directly into the config:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type LocalSpriteConfig = {
|
|
||||||
mode: 'react@vite'
|
|
||||||
name?: string
|
|
||||||
description?: string
|
|
||||||
input?: string | string[]
|
|
||||||
transform?: {
|
|
||||||
removeSize?: boolean
|
|
||||||
replaceColors?: boolean
|
|
||||||
addTransition?: boolean
|
|
||||||
}
|
|
||||||
generatedNotice?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mode: 'react@vite',
|
|
||||||
name: 'icons',
|
|
||||||
} satisfies LocalSpriteConfig
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -1,156 +1,132 @@
|
|||||||
# React Webpack SVG Sprite Quick Start
|
# SVG Sprite for React with Webpack 5
|
||||||
|
|
||||||
This guide targets the exact mode key `react@webpack`: a generated typed React component using Webpack 5 Asset Modules and CSS Modules.
|
A quick guide to creating an SVG sprite in a React application built with Webpack 5.
|
||||||
|
|
||||||
## 1. Generate the sprite
|
## Generate the sprite
|
||||||
|
|
||||||
No package installation and no `package.json` dependency are needed. `npx` downloads the CLI temporarily, and generated runtime does not import `@gromlab/svg-sprites`.
|
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.
|
||||||
|
|
||||||
Keep the config adjacent to its source icons:
|
Example configuration:
|
||||||
|
|
||||||
```text
|
```json
|
||||||
src/ui/icons/
|
{
|
||||||
├── icons/
|
"mode": "react@webpack",
|
||||||
│ ├── check.svg
|
"name": "app",
|
||||||
│ └── folder.svg
|
"input": "../svg-icons/**/*.svg"
|
||||||
└── svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Use a plain default object export with no package import:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// src/ui/icons/svg-sprite.config.ts
|
|
||||||
export default {
|
|
||||||
mode: 'react@webpack',
|
|
||||||
name: 'icons',
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
When `input` is omitted, SVG files are read from `./icons` relative to the config. A `.js` config with a default export and a `.json` config are also supported. Generate directly with:
|
The package does not need to be a project dependency: generation runs through `npx`.
|
||||||
|
|
||||||
```bash
|
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:
|
||||||
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/ui/icons/svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Use the exact Webpack 5 flags and generate once per invocation:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/ui/icons/svg-sprite.config.ts",
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
"dev": "npm run sprites && webpack serve --mode development",
|
"predev": "npm run sprites",
|
||||||
"build": "npm run sprites && webpack --mode production"
|
"dev": "webpack serve --mode development",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "webpack --mode production"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Do not add `predev` or `prebuild` hooks to these scripts; that would run generation twice. In CI, replace `latest` with an exact package version.
|
## Use the sprite
|
||||||
|
|
||||||
Generation creates a local `.gitignore`; commit that file once, but do not commit `.svg-sprite/`. Generated declarations are self-contained and do not require the package.
|
The value `name: "app"` creates the React component `AppIcon`.
|
||||||
|
|
||||||
### Production usage
|
Create the entry point `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
Import the generated component and icon-name list directly:
|
```ts
|
||||||
|
export * from './.svg-sprite/index.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the component in your application:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// src/App.tsx
|
import { AppIcon } from '../assets/app-icons'
|
||||||
import {
|
|
||||||
IconsIcon,
|
|
||||||
iconsIconNames,
|
|
||||||
} from './ui/icons/.svg-sprite/index.js'
|
|
||||||
|
|
||||||
export function App() {
|
export function SaveIcon() {
|
||||||
return (
|
return (
|
||||||
<main>
|
<AppIcon
|
||||||
<IconsIcon icon="folder" width={24} height={24} aria-label="Files" />
|
icon="icon-name"
|
||||||
<small>{iconsIconNames.length} icons available</small>
|
width={24}
|
||||||
</main>
|
height={24}
|
||||||
|
role="img"
|
||||||
|
aria-label="Done"
|
||||||
|
style={{
|
||||||
|
color: '#334155',
|
||||||
|
'--icon-color-2': '#f59e0b',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The generated component uses `new URL('../sprite.svg', import.meta.url)`, which Webpack 5 processes through Asset Modules and emits as a separate SVG asset. Exclude `.svg-sprite/sprite.svg` from SVG component or SVGR rules so they do not intercept that URL dependency.
|
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 generated component also imports `react-component.module.css`. Configure `.module.css` through `css-loader` with modules enabled, plus `style-loader` or `MiniCssExtractPlugin`:
|
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
|
```js
|
||||||
// webpack.config.js (relevant rule)
|
{
|
||||||
export default {
|
test: /\.module\.css$/i,
|
||||||
module: {
|
use: [
|
||||||
rules: [
|
'style-loader',
|
||||||
{
|
{
|
||||||
test: /\.module\.css$/i,
|
loader: 'css-loader',
|
||||||
use: ['style-loader', { loader: 'css-loader', options: { modules: true } }],
|
options: { modules: { namedExport: false } },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## 2. Debug and preview
|
Webpack 5 automatically adds `sprite.svg` to the production build.
|
||||||
|
|
||||||
This section is optional. Only users who need the Viewer or icon previews should install:
|
## 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
|
```bash
|
||||||
npm install --save-dev @gromlab/svg-sprites
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
```
|
```
|
||||||
|
|
||||||
Use the React `SpriteViewer` bridge with a static loader array. Keep every `import()` path a string literal so Webpack can create the chunk:
|
Create the entry `src/svg-sprite-debug.tsx`:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// src/IconsDebugPage.tsx
|
import { createRoot } from 'react-dom/client'
|
||||||
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
|
||||||
const sources = [
|
const sources = [
|
||||||
() => import('./ui/icons/.svg-sprite/svg-sprite.manifest.js'),
|
() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
]
|
] as const
|
||||||
|
|
||||||
export function IconsDebugPage() {
|
const container = document.createElement('div')
|
||||||
return <SpriteViewer sources={sources} title="Project icons" />
|
document.body.append(container)
|
||||||
}
|
|
||||||
|
createRoot(container).render(
|
||||||
|
<SpriteViewer sources={sources} title="Project icons" />,
|
||||||
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
Keep this component on a debug route or in an internal tool. Viewer is not part of the production icon runtime.
|
Add the script to the main entry only in development mode. Keep the rest of your `webpack.config.js` settings:
|
||||||
|
|
||||||
## 3. Type the config
|
```js
|
||||||
|
export default (_env, argv) => ({
|
||||||
Choose one of these two paths.
|
// Other Webpack settings.
|
||||||
|
entry: [
|
||||||
### With a local package installation
|
'./src/main.tsx',
|
||||||
|
...(argv.mode === 'development' ? ['./src/svg-sprite-debug.tsx'] : []),
|
||||||
After installing the package locally, use the helper:
|
],
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineSpriteConfig({
|
|
||||||
mode: 'react@webpack',
|
|
||||||
name: 'icons',
|
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
You can alternatively import `type SpriteConfig` and apply `satisfies SpriteConfig`.
|
Run `npm run dev`. Viewer appears on the application's main page and is not included in the production build.
|
||||||
|
|
||||||
### Without the package
|
|
||||||
|
|
||||||
Copy a mode-specific type directly into the config:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type LocalSpriteConfig = {
|
|
||||||
mode: 'react@webpack'
|
|
||||||
name?: string
|
|
||||||
description?: string
|
|
||||||
input?: string | string[]
|
|
||||||
transform?: {
|
|
||||||
removeSize?: boolean
|
|
||||||
replaceColors?: boolean
|
|
||||||
addTransition?: boolean
|
|
||||||
}
|
|
||||||
generatedNotice?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mode: 'react@webpack',
|
|
||||||
name: 'icons',
|
|
||||||
} satisfies LocalSpriteConfig
|
|
||||||
```
|
|
||||||
|
|||||||
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)
|
||||||
|
```
|
||||||
@@ -1,156 +1,114 @@
|
|||||||
# Standalone Vite SVG Sprite Quick Start
|
# SVG Sprite for Vite Without a Framework
|
||||||
|
|
||||||
This guide targets the exact mode key `standalone@vite`: a native generated Web Component with Vite-managed SVG assets.
|
A quick guide to creating an SVG sprite in a Vite application without a framework.
|
||||||
|
|
||||||
## 1. Generate the sprite
|
## Generate the sprite
|
||||||
|
|
||||||
No package installation and no `package.json` dependency are needed. `npx` downloads the CLI temporarily, and generated runtime does not import `@gromlab/svg-sprites`.
|
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.
|
||||||
|
|
||||||
Keep the config and source icons together:
|
Example configuration:
|
||||||
|
|
||||||
```text
|
```json
|
||||||
src/ui/icons/
|
{
|
||||||
├── icons/
|
"mode": "standalone@vite",
|
||||||
│ ├── check.svg
|
"name": "app",
|
||||||
│ └── folder.svg
|
"input": "../svg-icons/**/*.svg"
|
||||||
└── svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Use a plain default object export with no package import:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// src/ui/icons/svg-sprite.config.ts
|
|
||||||
export default {
|
|
||||||
mode: 'standalone@vite',
|
|
||||||
name: 'icons',
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
When `input` is omitted, SVG files are read from `./icons` relative to the config. A `.js` config with a default export and a `.json` config are also supported. Generate once directly with:
|
The package does not need to be a project dependency: generation runs through `npx`.
|
||||||
|
|
||||||
```bash
|
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:
|
||||||
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/ui/icons/svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Use the exact Vite dev/build commands and generate once per invocation:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/ui/icons/svg-sprite.config.ts",
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
"dev": "npm run sprites && vite",
|
"predev": "npm run sprites",
|
||||||
"build": "npm run sprites && vite build"
|
"dev": "vite",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "vite build"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Do not add `predev` or `prebuild` hooks to these scripts; that would run generation twice. In CI, replace `latest` with an exact package version.
|
## Use the sprite
|
||||||
|
|
||||||
Generation creates a local `.gitignore`; commit that file once, but do not commit `.svg-sprite/`. The generated JavaScript and declarations live together, and the declarations are self-contained: they do not require `@gromlab/svg-sprites`.
|
The value `name: "app"` creates the `<app-icon>` element.
|
||||||
|
|
||||||
### Production usage
|
Create the entry point `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
Register the generated element once, then use `<icons-icon>`:
|
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
// src/main.ts
|
export * from './.svg-sprite/index.js'
|
||||||
import {
|
|
||||||
defineIconsIconElement,
|
|
||||||
iconsIconNames,
|
|
||||||
} from './ui/icons/.svg-sprite/index.js'
|
|
||||||
|
|
||||||
defineIconsIconElement()
|
|
||||||
console.log('Available icons:', iconsIconNames)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Register the element in `src/main.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { defineAppIconElement } from '../assets/app-icons'
|
||||||
|
import './style.css'
|
||||||
|
|
||||||
|
defineAppIconElement()
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the icon in HTML:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<icons-icon icon="check" role="img" aria-label="Complete"></icons-icon>
|
<app-icon icon="icon-name" role="img" aria-label="Done"></app-icon>
|
||||||
```
|
```
|
||||||
|
|
||||||
The host is `1em` by `1em`, so `font-size` controls its default size. Transformed colors use `currentColor` and custom properties such as `--icon-color-1`:
|
The `icon` value is the source SVG filename without the extension. Set its size and colors with CSS:
|
||||||
|
|
||||||
```css
|
```css
|
||||||
icons-icon {
|
app-icon {
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
color: #2563eb;
|
color: #334155;
|
||||||
--icon-color-2: #dbeafe;
|
--icon-color-2: #f59e0b;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Vite handles the generated `sprite.svg?no-inline` import automatically and emits a separate asset. If your own TypeScript source imports Vite query assets, include Vite's ambient types:
|
A monochrome icon inherits `color`, while colors in a multicolor icon are overridden with `--icon-color-N`. Viewer shows the variables you need.
|
||||||
|
|
||||||
```json
|
Vite automatically adds `sprite.svg` to the production build. You do not need to copy it to `public`.
|
||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"types": ["vite/client"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2. Debug and preview
|
## Debug and preview
|
||||||
|
|
||||||
This section is optional. Only users who need the Viewer or icon previews should install:
|
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
|
```bash
|
||||||
npm install --save-dev @gromlab/svg-sprites
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
```
|
```
|
||||||
|
|
||||||
Register the Viewer element, import its type, and assign the generated JavaScript manifest to `sources`:
|
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
|
```ts
|
||||||
import '@gromlab/svg-sprites/viewer/element'
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
||||||
import spriteManifest from './ui/icons/.svg-sprite/svg-sprite.manifest.js'
|
import spriteManifest from '../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
|
||||||
document.querySelector<HTMLDivElement>('#debug')!.innerHTML = `
|
|
||||||
<gromlab-sprite-viewer viewer-title="Project icons"></gromlab-sprite-viewer>
|
|
||||||
`
|
|
||||||
|
|
||||||
const viewer = document.querySelector<SpriteViewerElement>('gromlab-sprite-viewer')!
|
const viewer = document.querySelector<SpriteViewerElement>('gromlab-sprite-viewer')!
|
||||||
viewer.sources = [spriteManifest]
|
viewer.sources = [spriteManifest]
|
||||||
```
|
```
|
||||||
|
|
||||||
Keep this code on a debug route or in an internal tool. Viewer is not part of the production icon runtime.
|
Run `npm run dev` and open `/svg-sprite.html`.
|
||||||
|
|
||||||
## 3. Type the config
|
Viewer is not required for `<app-icon>` and is not imported by the application's main code.
|
||||||
|
|
||||||
Choose one of these two paths.
|
|
||||||
|
|
||||||
### With a local package installation
|
|
||||||
|
|
||||||
After installing the package locally, use the helper:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineSpriteConfig({
|
|
||||||
mode: 'standalone@vite',
|
|
||||||
name: 'icons',
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
You can alternatively import `type SpriteConfig` and apply `satisfies SpriteConfig`.
|
|
||||||
|
|
||||||
### Without the package
|
|
||||||
|
|
||||||
Copy a mode-specific type directly into the config:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type LocalSpriteConfig = {
|
|
||||||
mode: 'standalone@vite'
|
|
||||||
name?: string
|
|
||||||
description?: string
|
|
||||||
input?: string | string[]
|
|
||||||
transform?: {
|
|
||||||
removeSize?: boolean
|
|
||||||
replaceColors?: boolean
|
|
||||||
addTransition?: boolean
|
|
||||||
}
|
|
||||||
generatedNotice?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mode: 'standalone@vite',
|
|
||||||
name: 'icons',
|
|
||||||
} satisfies LocalSpriteConfig
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -1,143 +1,111 @@
|
|||||||
# Standalone Webpack SVG Sprite Quick Start
|
# SVG Sprite for Webpack 5 Without a Framework
|
||||||
|
|
||||||
This guide targets the exact mode key `standalone@webpack`: a native generated Web Component using Webpack 5 Asset Modules.
|
A quick guide to creating an SVG sprite in a Webpack 5 application without a framework.
|
||||||
|
|
||||||
## 1. Generate the sprite
|
## Generate the sprite
|
||||||
|
|
||||||
No package installation and no `package.json` dependency are needed. `npx` downloads the CLI temporarily, and generated runtime does not import `@gromlab/svg-sprites`.
|
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.
|
||||||
|
|
||||||
Keep the config adjacent to its source icons:
|
Example configuration:
|
||||||
|
|
||||||
```text
|
```json
|
||||||
src/ui/icons/
|
{
|
||||||
├── icons/
|
"mode": "standalone@webpack",
|
||||||
│ ├── check.svg
|
"name": "app",
|
||||||
│ └── folder.svg
|
"input": "../svg-icons/**/*.svg"
|
||||||
└── svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Use a plain default object export with no package import:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// src/ui/icons/svg-sprite.config.ts
|
|
||||||
export default {
|
|
||||||
mode: 'standalone@webpack',
|
|
||||||
name: 'icons',
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
When `input` is omitted, SVG files are read from `./icons` relative to the config. A `.js` config with a default export and a `.json` config are also supported. Generate directly with:
|
The package does not need to be a project dependency: generation runs through `npx`.
|
||||||
|
|
||||||
```bash
|
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:
|
||||||
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/ui/icons/svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Use the exact Webpack 5 flags and generate once per invocation:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/ui/icons/svg-sprite.config.ts",
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
"dev": "npm run sprites && webpack serve --mode development",
|
"predev": "npm run sprites",
|
||||||
"build": "npm run sprites && webpack --mode production"
|
"dev": "webpack serve --mode development",
|
||||||
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "webpack --mode production"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Do not add `predev` or `prebuild` hooks to these scripts; that would run generation twice. In CI, replace `latest` with an exact package version.
|
## Use the sprite
|
||||||
|
|
||||||
Generation creates a local `.gitignore`; commit that file once, but do not commit `.svg-sprite/`. Generated declarations are self-contained and do not require the package.
|
The value `name: "app"` creates the `<app-icon>` element.
|
||||||
|
|
||||||
### Production usage
|
Create the entry point `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
Register the generated element once, then use `<icons-icon>`:
|
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
// src/main.ts
|
export * from './.svg-sprite/index.js'
|
||||||
import {
|
|
||||||
defineIconsIconElement,
|
|
||||||
iconsIconNames,
|
|
||||||
} from './ui/icons/.svg-sprite/index.js'
|
|
||||||
|
|
||||||
defineIconsIconElement()
|
|
||||||
console.log('Available icons:', iconsIconNames)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
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
|
```html
|
||||||
<icons-icon
|
<app-icon icon="icon-name" role="img" aria-label="Done"></app-icon>
|
||||||
icon="check"
|
|
||||||
role="img"
|
|
||||||
aria-label="Complete"
|
|
||||||
style="font-size:24px;color:#16a34a;--icon-color-1:#16a34a"
|
|
||||||
></icons-icon>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The generated facade uses `new URL('./sprite.svg', import.meta.url)`, which Webpack 5 processes through Asset Modules and emits as a separate asset. If the project has SVG-to-component or SVGR rules, exclude `.svg-sprite/sprite.svg` from them so they do not intercept this URL dependency. Check `output.publicPath` if the emitted URL is wrong.
|
The `icon` value is the source SVG filename without the extension. Set its size and colors with CSS:
|
||||||
|
|
||||||
## 2. Debug and preview
|
```css
|
||||||
|
app-icon {
|
||||||
|
font-size: 24px;
|
||||||
|
color: #334155;
|
||||||
|
--icon-color-2: #f59e0b;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
This section is optional. Only users who need the Viewer or icon previews should install:
|
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
|
```bash
|
||||||
npm install --save-dev @gromlab/svg-sprites
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
```
|
```
|
||||||
|
|
||||||
Register the Viewer element, import its type, and assign the generated JavaScript manifest to `sources`:
|
Create the entry `src/svg-sprite-debug.ts`:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import '@gromlab/svg-sprites/viewer/element'
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
||||||
import spriteManifest from './ui/icons/.svg-sprite/svg-sprite.manifest.js'
|
import spriteManifest from '../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
|
||||||
document.querySelector<HTMLDivElement>('#debug')!.innerHTML = `
|
const viewer = document.createElement('gromlab-sprite-viewer') as SpriteViewerElement
|
||||||
<gromlab-sprite-viewer viewer-title="Project icons"></gromlab-sprite-viewer>
|
viewer.viewerTitle = 'Project icons'
|
||||||
`
|
|
||||||
|
|
||||||
const viewer = document.querySelector<SpriteViewerElement>('gromlab-sprite-viewer')!
|
|
||||||
viewer.sources = [spriteManifest]
|
viewer.sources = [spriteManifest]
|
||||||
|
document.body.append(viewer)
|
||||||
```
|
```
|
||||||
|
|
||||||
Keep this code on a debug route or in an internal tool. Viewer is not part of the production icon runtime.
|
Add the script to the main entry only in development mode. Keep the rest of your `webpack.config.js` settings:
|
||||||
|
|
||||||
## 3. Type the config
|
```js
|
||||||
|
export default (_env, argv) => ({
|
||||||
Choose one of these two paths.
|
// Other Webpack settings.
|
||||||
|
entry: [
|
||||||
### With a local package installation
|
'./src/main.ts',
|
||||||
|
...(argv.mode === 'development' ? ['./src/svg-sprite-debug.ts'] : []),
|
||||||
After installing the package locally, use the helper:
|
],
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineSpriteConfig({
|
|
||||||
mode: 'standalone@webpack',
|
|
||||||
name: 'icons',
|
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
You can alternatively import `type SpriteConfig` and apply `satisfies SpriteConfig`.
|
Run `npm run dev`. Viewer appears on the application's main page.
|
||||||
|
|
||||||
### Without the package
|
Viewer is only added to the development build and is not included in production.
|
||||||
|
|
||||||
Copy a mode-specific type directly into the config:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type LocalSpriteConfig = {
|
|
||||||
mode: 'standalone@webpack'
|
|
||||||
name?: string
|
|
||||||
description?: string
|
|
||||||
input?: string | string[]
|
|
||||||
transform?: {
|
|
||||||
removeSize?: boolean
|
|
||||||
replaceColors?: boolean
|
|
||||||
addTransition?: boolean
|
|
||||||
}
|
|
||||||
generatedNotice?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mode: 'standalone@webpack',
|
|
||||||
name: 'icons',
|
|
||||||
} satisfies LocalSpriteConfig
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -1,171 +1,83 @@
|
|||||||
# Standalone SVG Sprite Quick Start
|
# SVG Sprite for a Site Without a Bundler
|
||||||
|
|
||||||
This guide targets the exact mode key `standalone`: static HTML or a custom asset pipeline with no generated JavaScript facade.
|
Combine SVG icons into one file and use them on an HTML page.
|
||||||
|
|
||||||
## 1. Generate the sprite
|
## Generate the sprite
|
||||||
|
|
||||||
No package installation and no `package.json` dependency are needed. `npx` downloads the CLI temporarily, and generated runtime does not import `@gromlab/svg-sprites`; bare `standalone` does not generate a JavaScript runtime at all.
|
You do not need to install the package in your project.
|
||||||
|
|
||||||
Keep the config next to its source icons:
|
### 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
|
```text
|
||||||
src/ui/icons/
|
assets/app-icons/.svg-sprite/
|
||||||
├── icons/
|
├── sprite.svg
|
||||||
│ ├── check.svg
|
└── svg-sprite.manifest.json
|
||||||
│ └── folder.svg
|
|
||||||
└── svg-sprite.config.json
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Create a JSON config:
|
- `sprite.svg` is the finished sprite for use on the site.
|
||||||
|
- `svg-sprite.manifest.json` contains icon data for Viewer.
|
||||||
|
|
||||||
```json
|
The `.svg-sprite` directory is created automatically and fully replaced on every generation. Do not edit its contents manually.
|
||||||
{
|
|
||||||
"mode": "standalone",
|
|
||||||
"name": "icons"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
When `input` is omitted, the generator reads `./icons` next to the config.
|
### 3. Use an icon
|
||||||
|
|
||||||
To include SVG files from nested directories, set one glob pattern:
|
In `index.html`, point to the generated `sprite.svg`. After `#`, add the icon file name without the `.svg` extension:
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"mode": "standalone",
|
|
||||||
"name": "icons",
|
|
||||||
"input": "../assets/icons/**/*.svg"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
An array can mix folders, individual SVG files, and glob patterns:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"mode": "standalone",
|
|
||||||
"name": "icons",
|
|
||||||
"input": [
|
|
||||||
"../assets/icons",
|
|
||||||
"../features/profile/user.svg",
|
|
||||||
"../features/admin/*.svg"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
All relative paths start at the config directory. Pass the config path explicitly:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/ui/icons/svg-sprite.config.json
|
|
||||||
```
|
|
||||||
|
|
||||||
For repeatable local commands, the same temporary CLI can be used from a script:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"scripts": {
|
|
||||||
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/ui/icons/svg-sprite.config.json"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Run that script once from your existing dev/build pipeline. If you use a `predev` or `prebuild` hook instead, do not also call `npm run sprites` inside the corresponding script. Bare `standalone` has no bundler-specific dev or build flag. In CI, replace `latest` with an exact package version.
|
|
||||||
|
|
||||||
Bare `standalone` does not create or modify `.gitignore`; the application decides whether `.svg-sprite/` is committed or ignored. It emits no declarations, facade, or component. Generated declarations in typed modes are self-contained and do not require the package.
|
|
||||||
|
|
||||||
### Production usage
|
|
||||||
|
|
||||||
The application owns the public URL, versioning, and cache policy. Copy both generated assets into the deploy output:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cp src/ui/icons/.svg-sprite/sprite.svg public/assets/icons.svg
|
|
||||||
cp src/ui/icons/.svg-sprite/svg-sprite.manifest.json public/assets/icons.manifest.json
|
|
||||||
```
|
|
||||||
|
|
||||||
Use the published URL manually:
|
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<svg width="24" height="24" role="img" aria-label="Complete">
|
<svg
|
||||||
<use href="/assets/icons.svg#check"></use>
|
width="24"
|
||||||
|
height="24"
|
||||||
|
aria-label="Done"
|
||||||
|
>
|
||||||
|
<use href="./assets/app-icons/.svg-sprite/sprite.svg#icon-name"></use>
|
||||||
</svg>
|
</svg>
|
||||||
```
|
```
|
||||||
|
|
||||||
Safe icon names normally match their fragment IDs. Names containing spaces or other SVG-ID-unsafe characters receive a generated ID; read that icon's `id` from `icons.manifest.json` instead of constructing the fragment yourself.
|
## Debug and preview
|
||||||
|
|
||||||
## 2. 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.
|
||||||
|
|
||||||
This section is optional. Only install the package locally if you need the debug Viewer or an icon preview:
|
Use the official Viewer for visual checks. It displays every icon in the sprite and helps you verify its colors and rendering.
|
||||||
|
|
||||||
```bash
|
Viewer is optional and intended only for development. You do not need to install the package through npm.
|
||||||
npm install --save-dev @gromlab/svg-sprites
|
|
||||||
```
|
|
||||||
|
|
||||||
Without a bundler, self-host the browser bundle by copying it from `node_modules` into the deploy output:
|
Viewer works directly with files from `.svg-sprite`. Nothing needs to be copied.
|
||||||
|
|
||||||
```bash
|
### Add Viewer to the page
|
||||||
cp node_modules/@gromlab/svg-sprites/dist/viewer-element.js public/debug/viewer-element.js
|
|
||||||
```
|
|
||||||
|
|
||||||
Then provide both public asset URLs through HTML attributes:
|
Add a module script to `index.html` and provide paths to the generated manifest and sprite:
|
||||||
|
|
||||||
```html
|
|
||||||
<script type="module" src="/debug/viewer-element.js"></script>
|
|
||||||
|
|
||||||
<gromlab-sprite-viewer
|
|
||||||
viewer-title="Project icons"
|
|
||||||
manifest-url="/assets/icons.manifest.json"
|
|
||||||
sprite-url="/assets/icons.svg"
|
|
||||||
></gromlab-sprite-viewer>
|
|
||||||
```
|
|
||||||
|
|
||||||
For a quick preview, a pinned CDN file can replace the self-hosted script:
|
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<script
|
<script
|
||||||
type="module"
|
type="module"
|
||||||
src="https://unpkg.com/@gromlab/svg-sprites@1.1.5/dist/viewer-element.js"
|
src="https://cdn.jsdelivr.net/npm/@gromlab/svg-sprites/dist/viewer-element.js"
|
||||||
></script>
|
></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>
|
||||||
```
|
```
|
||||||
|
|
||||||
Self-host the file for controlled environments and pin the CDN version if you use the alternative. Viewer is optional tooling, not part of the production icon runtime.
|
You can move Viewer to a separate HTML file in the site root used only for development and icon checks.
|
||||||
|
|
||||||
## 3. Type the config
|
|
||||||
|
|
||||||
This guide uses a JSON config, which works without TypeScript types. If config autocomplete is needed, replace `svg-sprite.config.json` with `svg-sprite.config.ts` and choose one of these approaches.
|
|
||||||
|
|
||||||
### With a local package installation
|
|
||||||
|
|
||||||
After installing the package locally, use the helper:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineSpriteConfig({
|
|
||||||
mode: 'standalone',
|
|
||||||
name: 'icons',
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
You can alternatively import `type SpriteConfig` and apply `satisfies SpriteConfig`.
|
|
||||||
|
|
||||||
### Without the package
|
|
||||||
|
|
||||||
Keep a narrow local type directly in the config:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type LocalSpriteConfig = {
|
|
||||||
mode: 'standalone'
|
|
||||||
name?: string
|
|
||||||
description?: string
|
|
||||||
input?: string | string[]
|
|
||||||
transform?: {
|
|
||||||
removeSize?: boolean
|
|
||||||
replaceColors?: boolean
|
|
||||||
addTransition?: boolean
|
|
||||||
}
|
|
||||||
generatedNotice?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mode: 'standalone',
|
|
||||||
name: 'icons',
|
|
||||||
} satisfies LocalSpriteConfig
|
|
||||||
```
|
|
||||||
|
|||||||
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,4 +0,0 @@
|
|||||||
# Next.js App Router Guides Moved
|
|
||||||
|
|
||||||
- [App Router + Turbopack](guides/next-app-turbopack.md)
|
|
||||||
- [App Router + Webpack](guides/next-app-webpack.md)
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
# Next.js Pages Router Guides Moved
|
|
||||||
|
|
||||||
- [Pages Router + Turbopack](guides/next-pages-turbopack.md)
|
|
||||||
- [Pages Router + Webpack](guides/next-pages-webpack.md)
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# Programmatic API Moved
|
|
||||||
|
|
||||||
The canonical document is now the [programmatic API](reference/programmatic-api.md).
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# React + Vite Guide Moved
|
|
||||||
|
|
||||||
The canonical guide is now [React + Vite](guides/react-vite.md).
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# React + Webpack Guide Moved
|
|
||||||
|
|
||||||
The canonical guide is now [React + Webpack](guides/react-webpack.md).
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# Technical Reference Moved
|
|
||||||
|
|
||||||
The canonical document is now the [technical reference](reference/technical.md).
|
|
||||||
@@ -14,6 +14,24 @@ const result = await generateSprite(
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
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
|
For static standalone mode, use `result.spritePath` in a build script to publish the
|
||||||
SVG under an application URL:
|
SVG under an application URL:
|
||||||
|
|
||||||
@@ -29,7 +47,7 @@ await copyFile(result.spritePath, 'dist/app-icons/sprite.svg')
|
|||||||
`spritePath` is a filesystem path, not a browser URL. A deployment-neutral JSON
|
`spritePath` is a filesystem path, not a browser URL. A deployment-neutral JSON
|
||||||
manifest is available through `result.manifestPath` and is copied independently.
|
manifest is available through `result.manifestPath` and is copied independently.
|
||||||
|
|
||||||
The first argument accepts the full 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 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:
|
The second argument contains optional overrides and always takes precedence over the config:
|
||||||
|
|
||||||
@@ -51,7 +69,7 @@ Configuration is resolved in this order:
|
|||||||
defaults → config → API overrides
|
defaults → config → API overrides
|
||||||
```
|
```
|
||||||
|
|
||||||
For fully programmatic generation, pass a directory and provide the required settings as 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
|
```ts
|
||||||
await generateSprite('src/ui/file-manager/svg-sprite', {
|
await generateSprite('src/ui/file-manager/svg-sprite', {
|
||||||
@@ -107,13 +125,17 @@ An explicitly supplied target overrides `mode` from the file. Prefer `generateSp
|
|||||||
|
|
||||||
```ts
|
```ts
|
||||||
import {
|
import {
|
||||||
|
isSpriteMode,
|
||||||
loadSpriteConfig,
|
loadSpriteConfig,
|
||||||
resolveSpriteConfig,
|
resolveSpriteConfig,
|
||||||
|
resolveSpriteConfigSource,
|
||||||
validateSpriteConfig,
|
validateSpriteConfig,
|
||||||
} from '@gromlab/svg-sprites'
|
} 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.
|
- `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.
|
- `validateSpriteConfig(value)` performs runtime validation.
|
||||||
- `resolveSpriteConfig(root, config, overrides)` merges values, applies defaults, and resolves paths relative to `root`.
|
- `resolveSpriteConfig(root, config, overrides)` merges values, applies defaults, and resolves paths relative to `root`.
|
||||||
|
|
||||||
@@ -138,6 +160,22 @@ 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.
|
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:
|
The React bridge keeps the component API:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
[Documentation index](../README.md)
|
[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:
|
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)
|
- [Bare standalone](../guides/standalone.md)
|
||||||
@@ -13,6 +15,26 @@ Reference for the configuration, generated API, and behavior of `@gromlab/svg-sp
|
|||||||
- [Next.js App Router + Webpack](../guides/next-app-webpack.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 + Turbopack](../guides/next-pages-turbopack.md)
|
||||||
- [Next.js Pages Router + Webpack](../guides/next-pages-webpack.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
|
## Requirements
|
||||||
|
|
||||||
@@ -24,7 +46,7 @@ Reference for the configuration, generated API, and behavior of `@gromlab/svg-sp
|
|||||||
Generation does not require a project dependency. Run the CLI through `npx`:
|
Generation does not require a project dependency. Run the CLI through `npx`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites path/to/svg-sprite.config.ts
|
npx --yes @gromlab/svg-sprites path/to/svg-sprite.config.json
|
||||||
```
|
```
|
||||||
|
|
||||||
Install the package as a development dependency only when the project needs the
|
Install the package as a development dependency only when the project needs the
|
||||||
@@ -49,16 +71,36 @@ svg-sprites [options] <config-file-or-directory>
|
|||||||
| Standalone + Webpack 5 | `standalone@webpack` |
|
| Standalone + Webpack 5 | `standalone@webpack` |
|
||||||
| React + Vite | `react@vite` |
|
| React + Vite | `react@vite` |
|
||||||
| React + Webpack 5 | `react@webpack` |
|
| 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 + Turbopack | `next@app/turbopack` |
|
||||||
| Next.js App Router + Webpack 5 | `next@app/webpack` |
|
| Next.js App Router + Webpack 5 | `next@app/webpack` |
|
||||||
| Next.js Pages Router + Turbopack | `next@pages/turbopack` |
|
| Next.js Pages Router + Turbopack | `next@pages/turbopack` |
|
||||||
| Next.js Pages Router + Webpack 5 | `next@pages/webpack` |
|
| 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 guides use `svg-sprite.config.ts` as the recommended name.
|
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`.
|
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`.
|
||||||
|
|
||||||
Available 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.
|
`--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:
|
Quote CLI glob patterns with single quotes so the shell does not expand them before the generator receives them:
|
||||||
|
|
||||||
@@ -96,7 +138,7 @@ export default defineSpriteConfig({
|
|||||||
| Option | Type | Default | Purpose |
|
| Option | Type | Default | Purpose |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| `mode` | `SpriteMode` | None | Generation mode; may be supplied by CLI/API |
|
| `mode` | `SpriteMode` | None | Generation mode; may be supplied by CLI/API |
|
||||||
| `name` | `string` | Derived from the directory | Name of the sprite, component, and public types |
|
| `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 |
|
| `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 |
|
| `input` | `string \| string[]` | `./icons` | SVG folders, files, and glob patterns relative to the config directory |
|
||||||
| `transform` | `TransformOptions` | All enabled | SVG preparation settings |
|
| `transform` | `TransformOptions` | All enabled | SVG preparation settings |
|
||||||
@@ -111,7 +153,7 @@ app → AppIcon
|
|||||||
file-manager → FileManagerIcon
|
file-manager → FileManagerIcon
|
||||||
```
|
```
|
||||||
|
|
||||||
If `name` is omitted, the generator derives it from the directory. For a directory named `svg-sprite` or `svg-sprites`, the parent directory's name is used.
|
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
|
### Icon sources
|
||||||
|
|
||||||
@@ -141,7 +183,7 @@ After generation, a React or Next.js sprite directory looks like this:
|
|||||||
```text
|
```text
|
||||||
app-icons/
|
app-icons/
|
||||||
├── .gitignore
|
├── .gitignore
|
||||||
├── svg-sprite.config.ts
|
├── svg-sprite.config.json
|
||||||
├── index.ts # optional user-owned barrel
|
├── index.ts # optional user-owned barrel
|
||||||
└── .svg-sprite/
|
└── .svg-sprite/
|
||||||
├── index.js
|
├── index.js
|
||||||
@@ -183,10 +225,10 @@ runtime asset and deployment-neutral manifest data:
|
|||||||
native generated Web Component with no external runtime dependencies. Bare
|
native generated Web Component with no external runtime dependencies. Bare
|
||||||
`standalone` intentionally does not generate a JavaScript component.
|
`standalone` intentionally does not generate a JavaScript component.
|
||||||
|
|
||||||
The generator overwrites and deletes only files that contain its marker. If a user file occupies a managed path, generation fails. The root `index.ts` is user-owned; create a barrel when needed:
|
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
|
```ts
|
||||||
export * from './.svg-sprite'
|
export * from './.svg-sprite/index.js'
|
||||||
```
|
```
|
||||||
|
|
||||||
## Standalone Web Component and TypeScript
|
## Standalone Web Component and TypeScript
|
||||||
@@ -308,7 +350,7 @@ The component does not add accessibility semantics automatically. Pass appropria
|
|||||||
|
|
||||||
## Multiple sprites
|
## Multiple sprites
|
||||||
|
|
||||||
Each directory with a configuration creates an independent component, types, manifest, and SVG asset:
|
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
|
```text
|
||||||
app-icons → AppIcon → shared icons
|
app-icons → AppIcon → shared icons
|
||||||
@@ -330,7 +372,7 @@ All current modes generate the `stack` format.
|
|||||||
|
|
||||||
### Generated component
|
### Generated component
|
||||||
|
|
||||||
For React and Next.js, use the generated React component. It knows the internal IDs, constructs the URL, and provides a TypeScript API:
|
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
|
```tsx
|
||||||
<AppIcon icon="search" width={24} height={24} />
|
<AppIcon icon="search" width={24} height={24} />
|
||||||
@@ -354,7 +396,7 @@ Static HTML after the application publishes `.svg-sprite/sprite.svg`:
|
|||||||
</svg>
|
</svg>
|
||||||
```
|
```
|
||||||
|
|
||||||
Standalone Vite/Webpack provides generated `getIconsIconHref()` and an internal ID
|
Standalone Vite/Webpack provides generated `getAppIconHref()` and an internal ID
|
||||||
map. Do not construct fragments from unsafe file names manually.
|
map. Do not construct fragments from unsafe file names manually.
|
||||||
|
|
||||||
Vite:
|
Vite:
|
||||||
@@ -568,7 +610,7 @@ export const IconsDebugPage = () => (
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
The Viewer displays groups, search, `viewBox`, CSS custom properties, and fallback colors. React/Next manifests get React, SVG, IMG, and CSS tabs; standalone manifests get SVG, IMG, and CSS. You can change color values in the interface and immediately inspect the result.
|
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
|
### Viewer theme
|
||||||
|
|
||||||
@@ -603,7 +645,7 @@ Commit the local `.gitignore` to the repository once. It excludes the other gene
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/ui/app-icons/svg-sprite.config.ts",
|
"sprites": "npx --yes @gromlab/svg-sprites src/ui/app-icons/svg-sprite.config.ts",
|
||||||
"predev": "npm run sprites",
|
"predev": "npm run sprites",
|
||||||
"prebuild": "npm run sprites",
|
"prebuild": "npm run sprites",
|
||||||
"pretypecheck": "npm run sprites"
|
"pretypecheck": "npm run sprites"
|
||||||
@@ -611,22 +653,22 @@ Commit the local `.gitignore` to the repository once. It excludes the other gene
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
CI must run generation before building or type-checking. Replace `latest` with an exact version for reproducibility. A local package installation is not required unless CI also uses the Viewer, package config types, or the programmatic API.
|
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 or modify `.gitignore`; the application decides whether its `.svg-sprite/` output is committed or ignored. In other modes, the generator will not overwrite a user-created `.gitignore`. It also refuses to overwrite a user-owned file inside `.svg-sprite`. The root `index.ts` remains user-owned and may re-export the generated 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
|
## Troubleshooting
|
||||||
|
|
||||||
- Missing `.svg-sprite/index.js`: run the generation script before importing the generated module.
|
- 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.
|
- Source not found: pass an existing config file or sprite module directory.
|
||||||
- Mode missing: add `mode` to the config or pass `--mode`.
|
- 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`.
|
- 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.
|
- Name conflict: two different SVG files have the same basename; rename one of them.
|
||||||
- `Refusing to overwrite a user file`: a file without the generated marker occupies a managed path.
|
- `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`.
|
- 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.
|
- 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.
|
- 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: check the path to `.svg-sprite/svg-sprite.manifest.js` and run generation before starting the application.
|
- 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.
|
- 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).
|
For custom orchestration and low-level compilation, see the [Programmatic API](programmatic-api.md).
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
Для настройки выберите guide одного exact mode. Каждый guide является
|
Для настройки выберите guide одного exact mode. Каждый guide является
|
||||||
самостоятельным документом и без изменений используется в AI skills.
|
самостоятельным документом и без изменений используется в AI skills.
|
||||||
|
|
||||||
|
Общий формат JSON, JavaScript и TypeScript config-файлов описан в [руководстве по конфигурации](configuration.md).
|
||||||
|
|
||||||
## Гайды быстрого старта
|
## Гайды быстрого старта
|
||||||
|
|
||||||
| Проект | Exact mode | Guide |
|
| Проект | Exact mode | Guide |
|
||||||
@@ -12,6 +14,26 @@
|
|||||||
| Vanilla + Webpack 5 | `standalone@webpack` | [Standalone + Webpack](guides/standalone-webpack.md) |
|
| Vanilla + Webpack 5 | `standalone@webpack` | [Standalone + Webpack](guides/standalone-webpack.md) |
|
||||||
| React + Vite | `react@vite` | [React + Vite](guides/react-vite.md) |
|
| React + Vite | `react@vite` | [React + Vite](guides/react-vite.md) |
|
||||||
| React + Webpack 5 | `react@webpack` | [React + Webpack](guides/react-webpack.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 + 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 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 + Turbopack | `next@pages/turbopack` | [Pages Router + Turbopack](guides/next-pages-turbopack.md) |
|
||||||
@@ -20,10 +42,11 @@
|
|||||||
Все guides используют один порядок:
|
Все guides используют один порядок:
|
||||||
|
|
||||||
1. Генерация спрайта через `npx` без добавления package в проект.
|
1. Генерация спрайта через `npx` без добавления package в проект.
|
||||||
2. Необязательное подключение Viewer для дебага и превью.
|
2. Использование спрайта в приложении.
|
||||||
3. Необязательная типизация конфига через package или локальный copy-paste type.
|
3. Необязательное подключение Viewer для дебага и превью.
|
||||||
|
|
||||||
## Справочники
|
## Справочники
|
||||||
|
|
||||||
|
- [Конфигурация](configuration.md)
|
||||||
- [Технический справочник](reference/technical.md)
|
- [Технический справочник](reference/technical.md)
|
||||||
- [Программный API](reference/programmatic-api.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-документации.
|
||||||
|
|
||||||
|
## Стиль
|
||||||
|
|
||||||
|
Писать для пользователя, а не для разработчика библиотеки.
|
||||||
|
|
||||||
|
Использовать короткие, прямые и практические формулировки.
|
||||||
|
|
||||||
|
Сначала объяснять пользу или цель шага, затем показывать действие.
|
||||||
|
|
||||||
|
Не использовать воду, рекламные формулировки и технические термины, которые не помогают выполнить инструкцию.
|
||||||
|
|
||||||
|
Не начинать документ с перечисления сгенерированных компонентов или особенностей реализации.
|
||||||
@@ -5,6 +5,26 @@
|
|||||||
- `standalone@webpack`: [standalone с Webpack](standalone-webpack.md)
|
- `standalone@webpack`: [standalone с Webpack](standalone-webpack.md)
|
||||||
- `react@vite`: [React с Vite](react-vite.md)
|
- `react@vite`: [React с Vite](react-vite.md)
|
||||||
- `react@webpack`: [React с Webpack](react-webpack.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/turbopack`: [App Router с Turbopack](next-app-turbopack.md)
|
||||||
- `next@app/webpack`: [App Router с Webpack](next-app-webpack.md)
|
- `next@app/webpack`: [App Router с Webpack](next-app-webpack.md)
|
||||||
- `next@pages/turbopack`: [Pages Router с Turbopack](next-pages-turbopack.md)
|
- `next@pages/turbopack`: [Pages Router с Turbopack](next-pages-turbopack.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`.
|
||||||
@@ -1,153 +1,108 @@
|
|||||||
# Next.js App Router с Turbopack
|
# SVG-спрайт для Next.js App Router с Turbopack
|
||||||
|
|
||||||
Это автономный quick start для exact mode key `next@app/turbopack`: generated `IconsIcon` совместим с Server Components и asset pipeline Turbopack.
|
Инструкция по быстрому созданию SVG-спрайта в приложении Next.js с App Router и Turbopack.
|
||||||
|
|
||||||
## 1. Генерация спрайта
|
## Генерация спрайта
|
||||||
|
|
||||||
Главное преимущество: генератор не нужно устанавливать и добавлять в `package.json`. `npx` временно скачивает CLI, а generated production runtime не импортирует `@gromlab/svg-sprites`.
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
```text
|
Пример конфига:
|
||||||
src/sprite/
|
|
||||||
├── icons/
|
|
||||||
│ ├── check.svg
|
|
||||||
│ └── warning.svg
|
|
||||||
├── index.ts
|
|
||||||
└── svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Минимальный plain config:
|
```json
|
||||||
|
{
|
||||||
```ts
|
"mode": "next@app/turbopack",
|
||||||
export default {
|
"name": "app",
|
||||||
mode: 'next@app/turbopack',
|
"input": "../svg-icons/**/*.svg"
|
||||||
name: 'icons',
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Если `input` не указан, SVG читаются из `./icons` относительно конфига. Конфиг может быть `.ts`, `.js` с `default export` или `.json`.
|
Пакет не нужно добавлять в зависимости проекта: генерация запускается через `npx`.
|
||||||
|
|
||||||
```bash
|
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
|
||||||
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
В CI зафиксируйте точную версию, например `@gromlab/svg-sprites@1.1.5`. Mode и команды Next должны указывать один bundler:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts",
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
"dev": "npm run sprites && next dev --turbopack",
|
"predev": "npm run sprites",
|
||||||
"build": "npm run sprites && next build --turbopack",
|
"dev": "next dev --turbopack",
|
||||||
"start": "next start",
|
"prebuild": "npm run sprites",
|
||||||
"typecheck": "npm run sprites && tsc --noEmit"
|
"build": "next build --turbopack"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Не добавляйте одновременно `predev`/`prebuild` и явный `npm run sprites`. Generated `.svg-sprite` не коммитится. Generated локальный `.gitignore`, который исключает этот каталог, нужно добавить в Git один раз. Его `.d.ts` self-contained и не импортируют generator package.
|
## Использование спрайта
|
||||||
|
|
||||||
|
Значение `name: "app"` создаёт React-компонент `AppIcon`.
|
||||||
|
|
||||||
|
Создайте точку входа `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
// src/sprite/index.ts
|
|
||||||
export * from './.svg-sprite/index.js'
|
export * from './.svg-sprite/index.js'
|
||||||
```
|
```
|
||||||
|
|
||||||
Generated icon не содержит `'use client'`, поэтому его можно импортировать прямо в Server Component:
|
Используйте компонент в Server Component:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// app/page.tsx
|
// app/page.tsx
|
||||||
import { IconsIcon, iconsIconNames } from '../src/sprite'
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return (
|
return (
|
||||||
<main>
|
<AppIcon
|
||||||
<IconsIcon
|
icon="icon-name"
|
||||||
icon="check"
|
width={24}
|
||||||
width={24}
|
height={24}
|
||||||
height={24}
|
role="img"
|
||||||
aria-label="Готово"
|
aria-label="Готово"
|
||||||
style={{ '--icon-color-1': '#16a34a' }}
|
style={{
|
||||||
/>
|
color: '#334155',
|
||||||
<span>{iconsIconNames.length} иконок</span>
|
'--icon-color-2': '#f59e0b',
|
||||||
</main>
|
}}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Turbopack обрабатывает generated `new URL('../sprite.svg', import.meta.url).href` и выпускает внешний hashed asset. Не добавляйте Client Component boundary только ради `IconsIcon`.
|
Для `AppIcon` не нужен `'use client'`. Turbopack сам добавляет `sprite.svg` в итоговую сборку, поэтому переносить его в `public` не нужно.
|
||||||
|
|
||||||
## 2. Дебаг и превью
|
## Дебаг и превью
|
||||||
|
|
||||||
Viewer необязателен и нужен только для debug/preview:
|
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки и устанавливается отдельно:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install --save-dev @gromlab/svg-sprites
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
```
|
```
|
||||||
|
|
||||||
Viewer интерактивен, поэтому создайте для него отдельный Client Component:
|
Создайте Client Component `app/svg-sprite/SvgSpriteViewer.tsx`:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// app/icons-debug/sprite-viewer.tsx
|
|
||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
|
||||||
const sources = [
|
const sources = [
|
||||||
() => import('../../src/sprite/.svg-sprite/svg-sprite.manifest.js'),
|
() => import('../../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
] as const
|
] as const
|
||||||
|
|
||||||
export function AppSpriteViewer() {
|
export function SvgSpriteViewer() {
|
||||||
return <SpriteViewer sources={sources} title="Иконки проекта" />
|
return <SpriteViewer sources={sources} title="Иконки проекта" />
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Server page импортирует только эту boundary:
|
Создайте маршрут `app/svg-sprite/page.tsx`:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// app/icons-debug/page.tsx
|
import { notFound } from 'next/navigation'
|
||||||
import { AppSpriteViewer } from './sprite-viewer'
|
|
||||||
|
|
||||||
export default function IconsDebugPage() {
|
import { SvgSpriteViewer } from './SvgSpriteViewer'
|
||||||
return <AppSpriteViewer />
|
|
||||||
|
export default function SvgSpritePage() {
|
||||||
|
if (process.env.NODE_ENV !== 'development') notFound()
|
||||||
|
|
||||||
|
return <SvgSpriteViewer />
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Viewer не входит в production icon runtime и не нужен обычным страницам с `IconsIcon`.
|
Запустите `npm run dev` и откройте `/svg-sprite`. В production маршрут вернёт 404.
|
||||||
|
|
||||||
## 3. Типизация конфига
|
|
||||||
|
|
||||||
После локальной установки package используйте helper:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineSpriteConfig({
|
|
||||||
mode: 'next@app/turbopack',
|
|
||||||
name: 'icons',
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
Возможен и type-only import `SpriteConfig` с `satisfies SpriteConfig`.
|
|
||||||
|
|
||||||
Без package добавьте локальный type в config:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type LocalSpriteConfig = {
|
|
||||||
mode: 'next@app/turbopack'
|
|
||||||
name?: string
|
|
||||||
description?: string
|
|
||||||
input?: string | string[]
|
|
||||||
transform?: {
|
|
||||||
removeSize?: boolean
|
|
||||||
replaceColors?: boolean
|
|
||||||
addTransition?: boolean
|
|
||||||
}
|
|
||||||
generatedNotice?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mode: 'next@app/turbopack',
|
|
||||||
name: 'icons',
|
|
||||||
} satisfies LocalSpriteConfig
|
|
||||||
```
|
|
||||||
|
|
||||||
Exact literal защищает от смешивания App Router и других bundler contracts.
|
|
||||||
|
|||||||
@@ -1,151 +1,108 @@
|
|||||||
# Next.js App Router с Webpack
|
# SVG-спрайт для Next.js App Router с Webpack
|
||||||
|
|
||||||
Это автономный quick start для exact mode key `next@app/webpack`: generated `IconsIcon` совместим с Server Components и Webpack pipeline Next.js.
|
Инструкция по быстрому созданию SVG-спрайта в приложении Next.js с App Router и Webpack.
|
||||||
|
|
||||||
## 1. Генерация спрайта
|
## Генерация спрайта
|
||||||
|
|
||||||
Главное преимущество: генератор не нужно устанавливать и добавлять в `package.json`. `npx` временно скачивает CLI, а generated production runtime не импортирует `@gromlab/svg-sprites`.
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
```text
|
Пример конфига:
|
||||||
src/sprite/
|
|
||||||
├── icons/
|
|
||||||
│ ├── check.svg
|
|
||||||
│ └── warning.svg
|
|
||||||
├── index.ts
|
|
||||||
└── svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Минимальный plain config:
|
```json
|
||||||
|
{
|
||||||
```ts
|
"mode": "next@app/webpack",
|
||||||
export default {
|
"name": "app",
|
||||||
mode: 'next@app/webpack',
|
"input": "../svg-icons/**/*.svg"
|
||||||
name: 'icons',
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Если `input` не указан, SVG читаются из `./icons` относительно конфига. Также поддерживаются `.js` с `default export` и `.json`.
|
Пакет не нужно добавлять в зависимости проекта: генерация запускается через `npx`.
|
||||||
|
|
||||||
```bash
|
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
|
||||||
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
В CI замените `latest` точной версией, например `@gromlab/svg-sprites@1.1.5`. Exact Next commands для этого mode:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts",
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
"dev": "npm run sprites && next dev --webpack",
|
"predev": "npm run sprites",
|
||||||
"build": "npm run sprites && next build --webpack",
|
"dev": "next dev --webpack",
|
||||||
"start": "next start",
|
"prebuild": "npm run sprites",
|
||||||
"typecheck": "npm run sprites && tsc --noEmit"
|
"build": "next build --webpack"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Не сочетайте явный `npm run sprites` с `predev` или `prebuild`. `.svg-sprite` generated и не коммитится. Generated локальный `.gitignore`, который исключает этот каталог, нужно добавить в Git один раз. Generated declarations self-contained и не зависят от `@gromlab/svg-sprites`.
|
## Использование спрайта
|
||||||
|
|
||||||
|
Значение `name: "app"` создаёт React-компонент `AppIcon`.
|
||||||
|
|
||||||
|
Создайте точку входа `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
// src/sprite/index.ts
|
|
||||||
export * from './.svg-sprite/index.js'
|
export * from './.svg-sprite/index.js'
|
||||||
```
|
```
|
||||||
|
|
||||||
Production usage в Server Component:
|
Используйте компонент в Server Component:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// app/page.tsx
|
// app/page.tsx
|
||||||
import { IconsIcon, iconsIconNames } from '../src/sprite'
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return (
|
return (
|
||||||
<main>
|
<AppIcon
|
||||||
<IconsIcon
|
icon="icon-name"
|
||||||
icon="check"
|
width={24}
|
||||||
width={24}
|
height={24}
|
||||||
height={24}
|
role="img"
|
||||||
aria-label="Готово"
|
aria-label="Готово"
|
||||||
style={{ '--icon-color-1': '#16a34a' }}
|
style={{
|
||||||
/>
|
color: '#334155',
|
||||||
<span>{iconsIconNames.length} иконок</span>
|
'--icon-color-2': '#f59e0b',
|
||||||
</main>
|
}}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Generated component не содержит `'use client'`. Next Webpack обрабатывает `new URL('../sprite.svg', import.meta.url).href` и публикует отдельный SVG asset; не переписывайте этот URL и не переносите sprite в `public` вручную.
|
Для `AppIcon` не нужен `'use client'`. Next.js сам добавляет `sprite.svg` в итоговую сборку, поэтому переносить его в `public` не нужно.
|
||||||
|
|
||||||
## 2. Дебаг и превью
|
## Дебаг и превью
|
||||||
|
|
||||||
Viewer необязателен. Для debug/preview установите package:
|
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки и устанавливается отдельно:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install --save-dev @gromlab/svg-sprites
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
```
|
```
|
||||||
|
|
||||||
App Router требует отдельную Client Component boundary для Viewer:
|
Создайте Client Component `app/svg-sprite/SvgSpriteViewer.tsx`:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// app/icons-debug/sprite-viewer.tsx
|
|
||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
|
||||||
const sources = [
|
const sources = [
|
||||||
() => import('../../src/sprite/.svg-sprite/svg-sprite.manifest.js'),
|
() => import('../../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
] as const
|
] as const
|
||||||
|
|
||||||
export function AppSpriteViewer() {
|
export function SvgSpriteViewer() {
|
||||||
return <SpriteViewer sources={sources} title="Иконки проекта" />
|
return <SpriteViewer sources={sources} title="Иконки проекта" />
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Создайте маршрут `app/svg-sprite/page.tsx`:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// app/icons-debug/page.tsx
|
import { notFound } from 'next/navigation'
|
||||||
import { AppSpriteViewer } from './sprite-viewer'
|
|
||||||
|
|
||||||
export default function IconsDebugPage() {
|
import { SvgSpriteViewer } from './SvgSpriteViewer'
|
||||||
return <AppSpriteViewer />
|
|
||||||
|
export default function SvgSpritePage() {
|
||||||
|
if (process.env.NODE_ENV !== 'development') notFound()
|
||||||
|
|
||||||
|
return <SvgSpriteViewer />
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Статический loader позволяет Webpack связать manifest и emitted SVG. Viewer не входит в production runtime `IconsIcon`.
|
Запустите `npm run dev` и откройте `/svg-sprite`. В production маршрут вернёт 404.
|
||||||
|
|
||||||
## 3. Типизация конфига
|
|
||||||
|
|
||||||
При локально установленном package используйте helper:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineSpriteConfig({
|
|
||||||
mode: 'next@app/webpack',
|
|
||||||
name: 'icons',
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
Другой package-вариант: type-only import `SpriteConfig` и `satisfies SpriteConfig`.
|
|
||||||
|
|
||||||
Без package вставьте локальный type прямо в config:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type LocalSpriteConfig = {
|
|
||||||
mode: 'next@app/webpack'
|
|
||||||
name?: string
|
|
||||||
description?: string
|
|
||||||
input?: string | string[]
|
|
||||||
transform?: {
|
|
||||||
removeSize?: boolean
|
|
||||||
replaceColors?: boolean
|
|
||||||
addTransition?: boolean
|
|
||||||
}
|
|
||||||
generatedNotice?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mode: 'next@app/webpack',
|
|
||||||
name: 'icons',
|
|
||||||
} satisfies LocalSpriteConfig
|
|
||||||
```
|
|
||||||
|
|
||||||
Локальный exact literal исключает случайную генерацию Turbopack или Pages Router output.
|
|
||||||
|
|||||||
@@ -1,140 +1,98 @@
|
|||||||
# Next.js Pages Router с Turbopack
|
# SVG-спрайт для Next.js Pages Router с Turbopack
|
||||||
|
|
||||||
Это автономный quick start для exact mode key `next@pages/turbopack`: generated `IconsIcon` работает при SSR, SSG и клиентских переходах Pages Router.
|
Инструкция по быстрому созданию SVG-спрайта в приложении Next.js с Pages Router и Turbopack.
|
||||||
|
|
||||||
## 1. Генерация спрайта
|
## Генерация спрайта
|
||||||
|
|
||||||
Главное преимущество: генератор не нужно устанавливать и добавлять в `package.json`. `npx` временно скачивает CLI, а generated production runtime не импортирует `@gromlab/svg-sprites`.
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
```text
|
Пример конфига:
|
||||||
src/sprite/
|
|
||||||
├── icons/
|
|
||||||
│ ├── check.svg
|
|
||||||
│ └── warning.svg
|
|
||||||
├── index.ts
|
|
||||||
└── svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Минимальный plain config:
|
```json
|
||||||
|
{
|
||||||
```ts
|
"mode": "next@pages/turbopack",
|
||||||
export default {
|
"name": "app",
|
||||||
mode: 'next@pages/turbopack',
|
"input": "../svg-icons/**/*.svg"
|
||||||
name: 'icons',
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Если `input` не указан, SVG читаются из `./icons` относительно конфига. Конфиг также может быть `.js` с `default export` или `.json`.
|
Пакет не нужно добавлять в зависимости проекта: генерация запускается через `npx`.
|
||||||
|
|
||||||
```bash
|
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
|
||||||
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Для CI зафиксируйте точную версию, например `@gromlab/svg-sprites@1.1.5`. Exact commands должны сохранять Turbopack и для dev, и для production build:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts",
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
"dev": "npm run sprites && next dev --turbopack",
|
"predev": "npm run sprites",
|
||||||
"build": "npm run sprites && next build --turbopack",
|
"dev": "next dev --turbopack",
|
||||||
"start": "next start",
|
"prebuild": "npm run sprites",
|
||||||
"typecheck": "npm run sprites && tsc --noEmit"
|
"build": "next build --turbopack"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Не добавляйте `predev`/`prebuild`, если scripts уже явно вызывают `npm run sprites`. Generated `.svg-sprite` не коммитится. Generated локальный `.gitignore`, который исключает этот каталог, нужно добавить в Git один раз. Generated `.d.ts` self-contained и не импортируют generator package.
|
## Использование спрайта
|
||||||
|
|
||||||
|
Значение `name: "app"` создаёт React-компонент `AppIcon`.
|
||||||
|
|
||||||
|
Создайте точку входа `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
// src/sprite/index.ts
|
|
||||||
export * from './.svg-sprite/index.js'
|
export * from './.svg-sprite/index.js'
|
||||||
```
|
```
|
||||||
|
|
||||||
Production usage на обычной page:
|
Используйте компонент на странице:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// pages/index.tsx
|
// pages/index.tsx
|
||||||
import { IconsIcon, iconsIconNames } from '../src/sprite'
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return (
|
return (
|
||||||
<main>
|
<AppIcon
|
||||||
<IconsIcon
|
icon="icon-name"
|
||||||
icon="check"
|
width={24}
|
||||||
width={24}
|
height={24}
|
||||||
height={24}
|
role="img"
|
||||||
aria-label="Готово"
|
aria-label="Готово"
|
||||||
style={{ '--icon-color-1': '#16a34a' }}
|
style={{
|
||||||
/>
|
color: '#334155',
|
||||||
<span>{iconsIconNames.length} иконок</span>
|
'--icon-color-2': '#f59e0b',
|
||||||
</main>
|
}}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Компонент одинаково работает с `getServerSideProps`, `getStaticProps` и client navigation. Turbopack разрешает generated `new URL('../sprite.svg', import.meta.url).href` в отдельный hashed asset.
|
Компонент работает с SSR, SSG и клиентскими переходами. Turbopack сам добавляет `sprite.svg` в итоговую сборку, поэтому переносить его в `public` не нужно.
|
||||||
|
|
||||||
## 2. Дебаг и превью
|
## Дебаг и превью
|
||||||
|
|
||||||
Viewer необязателен и нужен только для debug/preview:
|
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки и устанавливается отдельно:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install --save-dev @gromlab/svg-sprites
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
```
|
```
|
||||||
|
|
||||||
В Pages Router Viewer можно использовать прямо в page, без отдельной App Router Client Component boundary:
|
Создайте страницу `pages/svg-sprite.tsx`:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// pages/icons-debug.tsx
|
import type { GetStaticProps } from 'next'
|
||||||
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
|
||||||
const sources = [
|
const sources = [
|
||||||
() => import('../src/sprite/.svg-sprite/svg-sprite.manifest.js'),
|
() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
] as const
|
] as const
|
||||||
|
|
||||||
export default function IconsDebugPage() {
|
export default function SvgSpritePage() {
|
||||||
return <SpriteViewer sources={sources} title="Иконки проекта" />
|
return <SpriteViewer sources={sources} title="Иконки проекта" />
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getStaticProps: GetStaticProps = () =>
|
||||||
|
process.env.NODE_ENV === 'development'
|
||||||
|
? { props: {} }
|
||||||
|
: { notFound: true }
|
||||||
```
|
```
|
||||||
|
|
||||||
Оставляйте эту page только во внутреннем debug-разделе. Viewer не входит в production icon runtime `IconsIcon`.
|
Запустите `npm run dev` и откройте `/svg-sprite`. В production маршрут вернёт 404.
|
||||||
|
|
||||||
## 3. Типизация конфига
|
|
||||||
|
|
||||||
Если package установлен локально, используйте helper:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineSpriteConfig({
|
|
||||||
mode: 'next@pages/turbopack',
|
|
||||||
name: 'icons',
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
Альтернатива: type-only import `SpriteConfig` и объект `satisfies SpriteConfig`.
|
|
||||||
|
|
||||||
Без package добавьте copy-paste type в config:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type LocalSpriteConfig = {
|
|
||||||
mode: 'next@pages/turbopack'
|
|
||||||
name?: string
|
|
||||||
description?: string
|
|
||||||
input?: string | string[]
|
|
||||||
transform?: {
|
|
||||||
removeSize?: boolean
|
|
||||||
replaceColors?: boolean
|
|
||||||
addTransition?: boolean
|
|
||||||
}
|
|
||||||
generatedNotice?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mode: 'next@pages/turbopack',
|
|
||||||
name: 'icons',
|
|
||||||
} satisfies LocalSpriteConfig
|
|
||||||
```
|
|
||||||
|
|
||||||
Exact literal не позволяет незаметно смешать Pages Router с App Router или Webpack output.
|
|
||||||
|
|||||||
@@ -1,140 +1,98 @@
|
|||||||
# Next.js Pages Router с Webpack
|
# SVG-спрайт для Next.js Pages Router с Webpack
|
||||||
|
|
||||||
Это автономный quick start для exact mode key `next@pages/webpack`: generated `IconsIcon` работает в Pages Router и публикует SVG через Webpack pipeline Next.js.
|
Инструкция по быстрому созданию SVG-спрайта в приложении Next.js с Pages Router и Webpack.
|
||||||
|
|
||||||
## 1. Генерация спрайта
|
## Генерация спрайта
|
||||||
|
|
||||||
Главное преимущество: генератор не нужно устанавливать и добавлять в `package.json`. `npx` временно скачивает CLI, а generated production runtime не импортирует `@gromlab/svg-sprites`.
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
```text
|
Пример конфига:
|
||||||
src/sprite/
|
|
||||||
├── icons/
|
|
||||||
│ ├── check.svg
|
|
||||||
│ └── warning.svg
|
|
||||||
├── index.ts
|
|
||||||
└── svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Минимальный plain config:
|
```json
|
||||||
|
{
|
||||||
```ts
|
"mode": "next@pages/webpack",
|
||||||
export default {
|
"name": "app",
|
||||||
mode: 'next@pages/webpack',
|
"input": "../svg-icons/**/*.svg"
|
||||||
name: 'icons',
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Если `input` не указан, SVG читаются из `./icons` относительно конфига. Поддерживаются `.ts`, `.js` с `default export` и `.json` configs.
|
Пакет не нужно добавлять в зависимости проекта: генерация запускается через `npx`.
|
||||||
|
|
||||||
```bash
|
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
|
||||||
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
В CI замените `latest` на точную проверенную версию, например `@gromlab/svg-sprites@1.1.5`. Exact Next commands для Webpack:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts",
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
"dev": "npm run sprites && next dev --webpack",
|
"predev": "npm run sprites",
|
||||||
"build": "npm run sprites && next build --webpack",
|
"dev": "next dev --webpack",
|
||||||
"start": "next start",
|
"prebuild": "npm run sprites",
|
||||||
"typecheck": "npm run sprites && tsc --noEmit"
|
"build": "next build --webpack"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Не дублируйте эти вызовы через `predev`, `prebuild` или `pretypecheck`. `.svg-sprite` generated и не коммитится. Generated локальный `.gitignore`, который исключает этот каталог, нужно добавить в Git один раз. Generated declarations self-contained и не требуют `@gromlab/svg-sprites`.
|
## Использование спрайта
|
||||||
|
|
||||||
|
Значение `name: "app"` создаёт React-компонент `AppIcon`.
|
||||||
|
|
||||||
|
Создайте точку входа `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
// src/sprite/index.ts
|
|
||||||
export * from './.svg-sprite/index.js'
|
export * from './.svg-sprite/index.js'
|
||||||
```
|
```
|
||||||
|
|
||||||
Production usage:
|
Используйте компонент на странице:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// pages/index.tsx
|
// pages/index.tsx
|
||||||
import { IconsIcon, iconsIconNames } from '../src/sprite'
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return (
|
return (
|
||||||
<main>
|
<AppIcon
|
||||||
<IconsIcon
|
icon="icon-name"
|
||||||
icon="check"
|
width={24}
|
||||||
width={24}
|
height={24}
|
||||||
height={24}
|
role="img"
|
||||||
aria-label="Готово"
|
aria-label="Готово"
|
||||||
style={{ '--icon-color-1': '#16a34a' }}
|
style={{
|
||||||
/>
|
color: '#334155',
|
||||||
<span>{iconsIconNames.length} иконок</span>
|
'--icon-color-2': '#f59e0b',
|
||||||
</main>
|
}}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Компонент поддерживает SSR, SSG и клиентские переходы. Next Webpack преобразует generated `new URL('../sprite.svg', import.meta.url).href` во внешний hashed asset; не конструируйте URL спрайта вручную.
|
Компонент работает с SSR, SSG и клиентскими переходами. Next.js сам добавляет `sprite.svg` в итоговую сборку, поэтому переносить его в `public` не нужно.
|
||||||
|
|
||||||
## 2. Дебаг и превью
|
## Дебаг и превью
|
||||||
|
|
||||||
Viewer необязателен. Устанавливайте package только для debug/preview:
|
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки и устанавливается отдельно:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install --save-dev @gromlab/svg-sprites
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
```
|
```
|
||||||
|
|
||||||
Pages Router позволяет разместить Viewer непосредственно в page без отдельной App Router boundary:
|
Создайте страницу `pages/svg-sprite.tsx`:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// pages/icons-debug.tsx
|
import type { GetStaticProps } from 'next'
|
||||||
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
|
||||||
const sources = [
|
const sources = [
|
||||||
() => import('../src/sprite/.svg-sprite/svg-sprite.manifest.js'),
|
() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
] as const
|
] as const
|
||||||
|
|
||||||
export default function IconsDebugPage() {
|
export default function SvgSpritePage() {
|
||||||
return <SpriteViewer sources={sources} title="Иконки проекта" />
|
return <SpriteViewer sources={sources} title="Иконки проекта" />
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getStaticProps: GetStaticProps = () =>
|
||||||
|
process.env.NODE_ENV === 'development'
|
||||||
|
? { props: {} }
|
||||||
|
: { notFound: true }
|
||||||
```
|
```
|
||||||
|
|
||||||
Статический loader даёт Webpack точный manifest module и связанный SVG asset. Не импортируйте Viewer из production pages, если preview там не нужен; runtime `IconsIcon` от него независим.
|
Запустите `npm run dev` и откройте `/svg-sprite`. В production маршрут вернёт 404.
|
||||||
|
|
||||||
## 3. Типизация конфига
|
|
||||||
|
|
||||||
После локальной установки package доступен helper:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineSpriteConfig({
|
|
||||||
mode: 'next@pages/webpack',
|
|
||||||
name: 'icons',
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
Также можно применить `satisfies SpriteConfig` с type-only импортом `SpriteConfig`.
|
|
||||||
|
|
||||||
Без package вставьте локальный type прямо в config:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type LocalSpriteConfig = {
|
|
||||||
mode: 'next@pages/webpack'
|
|
||||||
name?: string
|
|
||||||
description?: string
|
|
||||||
input?: string | string[]
|
|
||||||
transform?: {
|
|
||||||
removeSize?: boolean
|
|
||||||
replaceColors?: boolean
|
|
||||||
addTransition?: boolean
|
|
||||||
}
|
|
||||||
generatedNotice?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mode: 'next@pages/webpack',
|
|
||||||
name: 'icons',
|
|
||||||
} satisfies LocalSpriteConfig
|
|
||||||
```
|
|
||||||
|
|
||||||
Такой exact literal выявляет ошибочный выбор App Router или Turbopack ещё при проверке config.
|
|
||||||
|
|||||||
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} />
|
||||||
|
})
|
||||||
|
```
|
||||||
@@ -1,141 +1,115 @@
|
|||||||
# React-компонент для Vite
|
# SVG-спрайт для React на Vite
|
||||||
|
|
||||||
Это автономный quick start для exact mode key `react@vite`: генератор создаёт типизированный `IconsIcon`, а Vite публикует отдельный SVG asset.
|
Инструкция по быстрому созданию SVG-спрайта в React-приложении на Vite.
|
||||||
|
|
||||||
## 1. Генерация спрайта
|
## Генерация спрайта
|
||||||
|
|
||||||
Главное преимущество: генератор не нужно устанавливать и добавлять в `package.json`. `npx` временно скачивает CLI, а generated production runtime не импортирует `@gromlab/svg-sprites`.
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
```text
|
Пример конфига:
|
||||||
src/sprite/
|
|
||||||
├── icons/
|
|
||||||
│ ├── check.svg
|
|
||||||
│ └── warning.svg
|
|
||||||
├── index.ts
|
|
||||||
└── svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Минимальный plain config:
|
```json
|
||||||
|
{
|
||||||
```ts
|
"mode": "react@vite",
|
||||||
export default {
|
"name": "app",
|
||||||
mode: 'react@vite',
|
"input": "../svg-icons/**/*.svg"
|
||||||
name: 'icons',
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Если `input` не указан, SVG читаются из `./icons` относительно конфига. Вместо `.ts` можно использовать `.js` с `default export` или `.json`.
|
Пакет не нужно добавлять в зависимости проекта: генерация запускается через `npx`.
|
||||||
|
|
||||||
```bash
|
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
|
||||||
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
В CI замените `latest` на точную версию, например `@gromlab/svg-sprites@1.1.5`. Exact Vite commands:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts",
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
"dev": "npm run sprites && vite",
|
"predev": "npm run sprites",
|
||||||
"build": "npm run sprites && tsc --noEmit && vite build",
|
"dev": "vite",
|
||||||
"typecheck": "npm run sprites && tsc --noEmit"
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "tsc --noEmit && vite build"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Не добавляйте `predev`, `prebuild` или `pretypecheck`, если соответствующие scripts уже явно запускают `npm run sprites`. Generated `.svg-sprite` не коммитится. Generated локальный `.gitignore`, который исключает этот каталог, нужно добавить в Git один раз. Generated declarations self-contained: они описывают компонент и manifest без импорта `@gromlab/svg-sprites`.
|
## Использование спрайта
|
||||||
|
|
||||||
Пользовательский barrel возвращает generated API:
|
Значение `name: "app"` создаёт React-компонент `AppIcon`.
|
||||||
|
|
||||||
|
Создайте точку входа `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
// src/sprite/index.ts
|
|
||||||
export * from './.svg-sprite/index.js'
|
export * from './.svg-sprite/index.js'
|
||||||
```
|
```
|
||||||
|
|
||||||
Production usage:
|
Используйте компонент в приложении:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
import { IconsIcon, iconsIconNames } from './sprite'
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
export function SaveButton() {
|
export function SaveIcon() {
|
||||||
return (
|
return (
|
||||||
<button type="button">
|
<AppIcon
|
||||||
<IconsIcon
|
icon="icon-name"
|
||||||
icon="check"
|
width={24}
|
||||||
width={24}
|
height={24}
|
||||||
height={24}
|
role="img"
|
||||||
aria-hidden="true"
|
aria-label="Готово"
|
||||||
style={{ '--icon-color-1': '#16a34a' }}
|
style={{
|
||||||
/>
|
color: '#334155',
|
||||||
Сохранить
|
'--icon-color-2': '#f59e0b',
|
||||||
</button>
|
}}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(iconsIconNames)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Prop `icon` является union имён исходных файлов. Vite автоматически обрабатывает generated CSS Module и импорт `sprite.svg?no-inline`; query запрещает inline и заставляет Vite выпустить отдельный hashed SVG asset. Если TypeScript не знает Vite asset imports, добавьте `/// <reference types="vite/client" />` в `src/vite-env.d.ts`.
|
Свойство `icon` принимает имена исходных SVG без расширения. Монохромная иконка наследует `color`, а цвета многоцветной переопределяются через `--icon-color-N`.
|
||||||
|
|
||||||
## 2. Дебаг и превью
|
Vite сам подключает стили компонента и добавляет `sprite.svg` в итоговую сборку.
|
||||||
|
|
||||||
Viewer необязателен и нужен только для debug/preview. Установите package отдельно:
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки и устанавливается отдельно:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install --save-dev @gromlab/svg-sprites
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
```
|
```
|
||||||
|
|
||||||
Используйте React bridge со статическим массивом loaders:
|
Создайте `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
|
```tsx
|
||||||
|
import { createRoot } from 'react-dom/client'
|
||||||
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
|
||||||
const sources = [
|
const sources = [
|
||||||
() => import('./sprite/.svg-sprite/svg-sprite.manifest.js'),
|
() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
] as const
|
] as const
|
||||||
|
|
||||||
export function IconsDebugPage() {
|
createRoot(document.getElementById('svg-sprite-viewer')!).render(
|
||||||
return <SpriteViewer sources={sources} title="Иконки проекта" />
|
<SpriteViewer sources={sources} title="Иконки проекта" />,
|
||||||
}
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
Строковый путь в `import()` должен указывать на generated JS manifest. Держите страницу за debug-маршрутом; `SpriteViewer` не входит в production runtime `IconsIcon`.
|
Запустите `npm run dev` и откройте `/svg-sprite.html`.
|
||||||
|
|
||||||
## 3. Типизация конфига
|
Стандартная production-сборка Vite использует только `index.html` и не включает страницу Viewer.
|
||||||
|
|
||||||
Если package установлен локально, используйте helper:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineSpriteConfig({
|
|
||||||
mode: 'react@vite',
|
|
||||||
name: 'icons',
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
Также можно импортировать `SpriteConfig` только как type и написать объект `satisfies SpriteConfig`.
|
|
||||||
|
|
||||||
Без package добавьте локальный type прямо в config:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type LocalSpriteConfig = {
|
|
||||||
mode: 'react@vite'
|
|
||||||
name?: string
|
|
||||||
description?: string
|
|
||||||
input?: string | string[]
|
|
||||||
transform?: {
|
|
||||||
removeSize?: boolean
|
|
||||||
replaceColors?: boolean
|
|
||||||
addTransition?: boolean
|
|
||||||
}
|
|
||||||
generatedNotice?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mode: 'react@vite',
|
|
||||||
name: 'icons',
|
|
||||||
} satisfies LocalSpriteConfig
|
|
||||||
```
|
|
||||||
|
|
||||||
Локальный type проверяет только этот exact mode и не создаёт runtime-зависимость.
|
|
||||||
|
|||||||
@@ -1,141 +1,132 @@
|
|||||||
# React-компонент для Webpack 5
|
# SVG-спрайт для React на Webpack 5
|
||||||
|
|
||||||
Это автономный quick start для exact mode key `react@webpack`: generated `IconsIcon` использует Webpack 5 Asset Modules и CSS Modules.
|
Инструкция по быстрому созданию SVG-спрайта в React-приложении на Webpack 5.
|
||||||
|
|
||||||
## 1. Генерация спрайта
|
## Генерация спрайта
|
||||||
|
|
||||||
Главное преимущество: генератор не нужно устанавливать и добавлять в `package.json`. `npx` временно скачивает CLI, а generated production runtime не импортирует `@gromlab/svg-sprites`.
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
```text
|
Пример конфига:
|
||||||
src/sprite/
|
|
||||||
├── icons/
|
|
||||||
│ ├── check.svg
|
|
||||||
│ └── warning.svg
|
|
||||||
├── index.ts
|
|
||||||
└── svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Минимальный plain config:
|
```json
|
||||||
|
{
|
||||||
```ts
|
"mode": "react@webpack",
|
||||||
export default {
|
"name": "app",
|
||||||
mode: 'react@webpack',
|
"input": "../svg-icons/**/*.svg"
|
||||||
name: 'icons',
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Если `input` не указан, SVG читаются из `./icons` относительно конфига. Поддерживаются `.ts`, `.js` с `default export` и `.json` configs.
|
Пакет не нужно добавлять в зависимости проекта: генерация запускается через `npx`.
|
||||||
|
|
||||||
```bash
|
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
|
||||||
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
В CI замените `latest` на точную версию, например `@gromlab/svg-sprites@1.1.5`. Exact Webpack commands:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts",
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
"dev": "npm run sprites && webpack serve --mode development",
|
"predev": "npm run sprites",
|
||||||
"build": "npm run sprites && webpack --mode production",
|
"dev": "webpack serve --mode development",
|
||||||
"typecheck": "npm run sprites && tsc --noEmit"
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "webpack --mode production"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Не сочетайте эти явные вызовы с `predev`/`prebuild`: иначе генерация задублируется. `.svg-sprite` не коммитится. Generated локальный `.gitignore`, который исключает этот каталог, нужно добавить в Git один раз. Generated `.d.ts` self-contained и не импортируют generator package.
|
## Использование спрайта
|
||||||
|
|
||||||
|
Значение `name: "app"` создаёт React-компонент `AppIcon`.
|
||||||
|
|
||||||
|
Создайте точку входа `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
// src/sprite/index.ts
|
|
||||||
export * from './.svg-sprite/index.js'
|
export * from './.svg-sprite/index.js'
|
||||||
```
|
```
|
||||||
|
|
||||||
Production usage:
|
Используйте компонент в приложении:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
import { IconsIcon, iconsIconNames } from './sprite'
|
import { AppIcon } from '../assets/app-icons'
|
||||||
|
|
||||||
export function SaveButton() {
|
export function SaveIcon() {
|
||||||
return (
|
return (
|
||||||
<button type="button">
|
<AppIcon
|
||||||
<IconsIcon
|
icon="icon-name"
|
||||||
icon="check"
|
width={24}
|
||||||
width={24}
|
height={24}
|
||||||
height={24}
|
role="img"
|
||||||
aria-hidden="true"
|
aria-label="Готово"
|
||||||
style={{ '--icon-color-1': '#16a34a' }}
|
style={{
|
||||||
/>
|
color: '#334155',
|
||||||
Сохранить
|
'--icon-color-2': '#f59e0b',
|
||||||
</button>
|
}}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(iconsIconNames)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Generated component получает URL через `new URL('../sprite.svg', import.meta.url).href`. Webpack 5 должен обработать SVG как Asset Module. Исключите generated `sprite.svg` из `@svgr/webpack`, inline/raw loaders и других общих SVG rules либо задайте для него `type: 'asset/resource'`.
|
Свойство `icon` принимает имена исходных SVG без расширения. Монохромная иконка наследует `color`, а цвета многоцветной переопределяются через `--icon-color-N`.
|
||||||
|
|
||||||
Компонент импортирует `react-component.module.css`. Webpack config должен обрабатывать `*.module.css` через `css-loader` с CSS Modules и `style-loader` или `MiniCssExtractPlugin`. Для TypeScript при необходимости добавьте декларацию `declare module '*.module.css'`.
|
Компонент использует CSS Modules. Если проект ещё не обрабатывает их, установите loaders:
|
||||||
|
|
||||||
## 2. Дебаг и превью
|
```bash
|
||||||
|
npm install --save-dev style-loader css-loader
|
||||||
|
```
|
||||||
|
|
||||||
Viewer необязателен. Устанавливайте package только для debug/preview:
|
Затем добавьте правило с 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
|
```bash
|
||||||
npm install --save-dev @gromlab/svg-sprites
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
```
|
```
|
||||||
|
|
||||||
Webpack не использует `import.meta.glob`; передайте статический loader:
|
Создайте entry `src/svg-sprite-debug.tsx`:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
|
import { createRoot } from 'react-dom/client'
|
||||||
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
import { SpriteViewer } from '@gromlab/svg-sprites/react'
|
||||||
|
|
||||||
const sources = [
|
const sources = [
|
||||||
() => import('./sprite/.svg-sprite/svg-sprite.manifest.js'),
|
() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
|
||||||
] as const
|
] as const
|
||||||
|
|
||||||
export function IconsDebugPage() {
|
const container = document.createElement('div')
|
||||||
return <SpriteViewer sources={sources} title="Иконки проекта" />
|
document.body.append(container)
|
||||||
}
|
|
||||||
|
createRoot(container).render(
|
||||||
|
<SpriteViewer sources={sources} title="Иконки проекта" />,
|
||||||
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
Webpack создаст chunk manifest и разрешит его SVG через тот же Asset Modules pipeline. Viewer держите только в debug route; production `IconsIcon` от него не зависит.
|
Добавьте скрипт к основному entry только в development-режиме. Сохраните остальные настройки `webpack.config.js`:
|
||||||
|
|
||||||
## 3. Типизация конфига
|
```js
|
||||||
|
export default (_env, argv) => ({
|
||||||
С локально установленным package доступен helper:
|
// Остальные настройки Webpack.
|
||||||
|
entry: [
|
||||||
```ts
|
'./src/main.tsx',
|
||||||
import { defineSpriteConfig } from '@gromlab/svg-sprites'
|
...(argv.mode === 'development' ? ['./src/svg-sprite-debug.tsx'] : []),
|
||||||
|
],
|
||||||
export default defineSpriteConfig({
|
|
||||||
mode: 'react@webpack',
|
|
||||||
name: 'icons',
|
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
Эквивалентная проверка: type-only import `SpriteConfig` и `satisfies SpriteConfig`.
|
Запустите `npm run dev`. Viewer появится на основной странице приложения и не попадёт в production-сборку.
|
||||||
|
|
||||||
Без package используйте copy-paste type в config:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type LocalSpriteConfig = {
|
|
||||||
mode: 'react@webpack'
|
|
||||||
name?: string
|
|
||||||
description?: string
|
|
||||||
input?: string | string[]
|
|
||||||
transform?: {
|
|
||||||
removeSize?: boolean
|
|
||||||
replaceColors?: boolean
|
|
||||||
addTransition?: boolean
|
|
||||||
}
|
|
||||||
generatedNotice?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mode: 'react@webpack',
|
|
||||||
name: 'icons',
|
|
||||||
} satisfies LocalSpriteConfig
|
|
||||||
```
|
|
||||||
|
|
||||||
Локальный literal не разрешит случайно выбрать Vite или Next mode.
|
|
||||||
|
|||||||
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)
|
||||||
|
```
|
||||||
@@ -1,151 +1,114 @@
|
|||||||
# Нативный icon Web Component с Vite
|
# SVG-спрайт для Vite без фреймворка
|
||||||
|
|
||||||
Это автономный quick start для exact mode key `standalone@vite`: generated facade регистрирует `<icons-icon>` и отдаёт SVG в asset pipeline Vite.
|
Инструкция по быстрому созданию SVG-спрайта в приложении на Vite без фреймворка.
|
||||||
|
|
||||||
## 1. Генерация спрайта
|
## Генерация спрайта
|
||||||
|
|
||||||
Главное преимущество: генератор не нужно устанавливать и добавлять в `package.json`. `npx` временно скачивает CLI, а generated production runtime не импортирует `@gromlab/svg-sprites`.
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
Рекомендуемая структура держит конфиг и иконки рядом:
|
Пример конфига:
|
||||||
|
|
||||||
```text
|
```json
|
||||||
src/sprite/
|
{
|
||||||
├── icons/
|
"mode": "standalone@vite",
|
||||||
│ ├── check.svg
|
"name": "app",
|
||||||
│ └── warning.svg
|
"input": "../svg-icons/**/*.svg"
|
||||||
├── index.ts
|
|
||||||
└── svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Минимальный plain config:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
export default {
|
|
||||||
mode: 'standalone@vite',
|
|
||||||
name: 'icons',
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Если `input` не указан, SVG читаются из `./icons` относительно конфига. Конфиг также может быть `.js` с `default export` или `.json`.
|
Пакет не нужно добавлять в зависимости проекта: генерация запускается через `npx`.
|
||||||
|
|
||||||
```bash
|
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
|
||||||
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
В CI замените `latest` на точную версию, например `@gromlab/svg-sprites@1.1.5`. Exact dev/build commands для Vite:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts",
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
"dev": "npm run sprites && vite",
|
"predev": "npm run sprites",
|
||||||
"build": "npm run sprites && vite build",
|
"dev": "vite",
|
||||||
"typecheck": "npm run sprites && tsc --noEmit"
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "vite build"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Не добавляйте одновременно `predev`/`prebuild` и явный `npm run sprites` в этих scripts. `.svg-sprite` является generated-каталогом и не коммитится. Generated локальный `.gitignore`, который исключает этот каталог, нужно добавить в Git один раз. Generated `.d.ts` self-contained и не импортируют `@gromlab/svg-sprites`.
|
## Использование спрайта
|
||||||
|
|
||||||
Верните facade через пользовательский barrel:
|
Значение `name: "app"` создаёт элемент `<app-icon>`.
|
||||||
|
|
||||||
|
Создайте точку входа `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
// src/sprite/index.ts
|
|
||||||
export * from './.svg-sprite/index.js'
|
export * from './.svg-sprite/index.js'
|
||||||
```
|
```
|
||||||
|
|
||||||
Production entry регистрирует native Web Component:
|
Зарегистрируйте элемент в `src/main.ts`:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import { defineIconsIconElement, iconsIconNames } from './sprite'
|
import { defineAppIconElement } from '../assets/app-icons'
|
||||||
|
import './style.css'
|
||||||
|
|
||||||
defineIconsIconElement()
|
defineAppIconElement()
|
||||||
|
|
||||||
document.querySelector<HTMLDivElement>('#app')!.innerHTML = `
|
|
||||||
<icons-icon icon="check" role="img" aria-label="Готово"></icons-icon>
|
|
||||||
`
|
|
||||||
|
|
||||||
console.log(iconsIconNames)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Generated facade импортирует `sprite.svg?no-inline`: Vite автоматически выпускает отдельный hashed SVG asset и не превращает его в data URL. TypeScript-проекту при необходимости добавьте стандартные Vite types:
|
Используйте иконку в HTML:
|
||||||
|
|
||||||
```ts
|
```html
|
||||||
/// <reference types="vite/client" />
|
<app-icon icon="icon-name" role="img" aria-label="Готово"></app-icon>
|
||||||
```
|
```
|
||||||
|
|
||||||
Размер по умолчанию равен `1em`, поэтому компонент удобно масштабировать через `font-size`. Цвет задаётся через `color` и generated custom properties:
|
Значение `icon` — имя исходного SVG без расширения. Размер и цвета настраиваются через CSS:
|
||||||
|
|
||||||
```css
|
```css
|
||||||
icons-icon {
|
app-icon {
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
color: #334155;
|
color: #334155;
|
||||||
--icon-color-2: #f59e0b;
|
--icon-color-2: #f59e0b;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## 2. Дебаг и превью
|
Монохромная иконка наследует `color`, а цвета многоцветной иконки переопределяются через `--icon-color-N`. Нужные переменные показывает Viewer.
|
||||||
|
|
||||||
Viewer необязателен и нужен только для debug/preview. Установите его отдельно:
|
Vite сам добавит `sprite.svg` в итоговую сборку. Копировать его в `public` не нужно.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки и устанавливается отдельно:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install --save-dev @gromlab/svg-sprites
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
```
|
```
|
||||||
|
|
||||||
Зарегистрируйте Viewer и передайте generated JS manifest через свойство `sources`:
|
Создайте `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
|
```ts
|
||||||
import '@gromlab/svg-sprites/viewer/element'
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
||||||
import spriteManifest from './sprite/.svg-sprite/svg-sprite.manifest.js'
|
import spriteManifest from '../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
|
||||||
document.querySelector<HTMLDivElement>('#app')!.insertAdjacentHTML(
|
|
||||||
'beforeend',
|
|
||||||
'<gromlab-sprite-viewer></gromlab-sprite-viewer>',
|
|
||||||
)
|
|
||||||
|
|
||||||
const viewer = document.querySelector<SpriteViewerElement>('gromlab-sprite-viewer')!
|
const viewer = document.querySelector<SpriteViewerElement>('gromlab-sprite-viewer')!
|
||||||
viewer.viewerTitle = 'Иконки проекта'
|
|
||||||
viewer.sources = [spriteManifest]
|
viewer.sources = [spriteManifest]
|
||||||
```
|
```
|
||||||
|
|
||||||
Расположите этот код только в debug entry или внутреннем маршруте. Viewer не входит в production runtime `<icons-icon>`.
|
Запустите `npm run dev` и откройте `/svg-sprite.html`.
|
||||||
|
|
||||||
## 3. Типизация конфига
|
Viewer не требуется для работы `<app-icon>` и не подключается к основному коду приложения.
|
||||||
|
|
||||||
При локально установленном package используйте helper:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { defineSpriteConfig } from '@gromlab/svg-sprites'
|
|
||||||
|
|
||||||
export default defineSpriteConfig({
|
|
||||||
mode: 'standalone@vite',
|
|
||||||
name: 'icons',
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
Альтернатива с package: `import type { SpriteConfig }` и объект `satisfies SpriteConfig`.
|
|
||||||
|
|
||||||
Без package скопируйте локальный type прямо в config:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type LocalSpriteConfig = {
|
|
||||||
mode: 'standalone@vite'
|
|
||||||
name?: string
|
|
||||||
description?: string
|
|
||||||
input?: string | string[]
|
|
||||||
transform?: {
|
|
||||||
removeSize?: boolean
|
|
||||||
replaceColors?: boolean
|
|
||||||
addTransition?: boolean
|
|
||||||
}
|
|
||||||
generatedNotice?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mode: 'standalone@vite',
|
|
||||||
name: 'icons',
|
|
||||||
} satisfies LocalSpriteConfig
|
|
||||||
```
|
|
||||||
|
|
||||||
Локальный type ограничивает `mode` одним exact literal и ничего не загружает во время генерации.
|
|
||||||
|
|||||||
@@ -1,145 +1,111 @@
|
|||||||
# Нативный icon Web Component с Webpack 5
|
# SVG-спрайт для Webpack 5 без фреймворка
|
||||||
|
|
||||||
Это автономный quick start для exact mode key `standalone@webpack`: generated facade предоставляет `<icons-icon>`, а Webpack 5 публикует SVG через Asset Modules.
|
Инструкция по быстрому созданию SVG-спрайта в приложении на Webpack 5 без фреймворка.
|
||||||
|
|
||||||
## 1. Генерация спрайта
|
## Генерация спрайта
|
||||||
|
|
||||||
Главное преимущество: генератор не нужно устанавливать и добавлять в `package.json`. `npx` временно скачивает CLI, а generated production runtime не импортирует `@gromlab/svg-sprites`.
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
```text
|
Пример конфига:
|
||||||
src/sprite/
|
|
||||||
├── icons/
|
|
||||||
│ ├── check.svg
|
|
||||||
│ └── warning.svg
|
|
||||||
├── index.ts
|
|
||||||
└── svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Минимальный config рядом с `icons/`:
|
```json
|
||||||
|
{
|
||||||
```ts
|
"mode": "standalone@webpack",
|
||||||
export default {
|
"name": "app",
|
||||||
mode: 'standalone@webpack',
|
"input": "../svg-icons/**/*.svg"
|
||||||
name: 'icons',
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Если `input` не указан, SVG читаются из `./icons` относительно конфига. Поддерживаются также `.js` с `default export` и `.json`.
|
Пакет не нужно добавлять в зависимости проекта: генерация запускается через `npx`.
|
||||||
|
|
||||||
```bash
|
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
|
||||||
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Для CI закрепите точную версию, например `@gromlab/svg-sprites@1.1.5`. Exact Webpack commands:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts",
|
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
|
||||||
"dev": "npm run sprites && webpack serve --mode development",
|
"predev": "npm run sprites",
|
||||||
"build": "npm run sprites && webpack --mode production",
|
"dev": "webpack serve --mode development",
|
||||||
"typecheck": "npm run sprites && tsc --noEmit"
|
"prebuild": "npm run sprites",
|
||||||
|
"build": "webpack --mode production"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Не дублируйте запуск через `predev`/`prebuild`, если scripts уже явно вызывают `npm run sprites`. Generated `.svg-sprite` не коммитится. Generated локальный `.gitignore`, который исключает этот каталог, нужно добавить в Git один раз. Его declarations self-contained и не требуют `@gromlab/svg-sprites`.
|
## Использование спрайта
|
||||||
|
|
||||||
|
Значение `name: "app"` создаёт элемент `<app-icon>`.
|
||||||
|
|
||||||
|
Создайте точку входа `assets/app-icons/index.ts`:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
// src/sprite/index.ts
|
|
||||||
export * from './.svg-sprite/index.js'
|
export * from './.svg-sprite/index.js'
|
||||||
```
|
```
|
||||||
|
|
||||||
Production usage:
|
Зарегистрируйте элемент в основном entry приложения:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import { defineIconsIconElement, iconsIconNames } from './sprite'
|
import { defineAppIconElement } from '../assets/app-icons'
|
||||||
|
import './style.css'
|
||||||
|
|
||||||
defineIconsIconElement()
|
defineAppIconElement()
|
||||||
|
|
||||||
document.querySelector<HTMLDivElement>('#app')!.innerHTML = `
|
|
||||||
<icons-icon icon="check" role="img" aria-label="Готово"></icons-icon>
|
|
||||||
`
|
|
||||||
|
|
||||||
console.log(iconsIconNames)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Generated facade использует `new URL('./sprite.svg', import.meta.url).href`. Webpack 5 Asset Modules выпускают отдельный asset; его итоговый URL учитывает `output.publicPath` и `assetModuleFilename`.
|
Используйте иконку в HTML:
|
||||||
|
|
||||||
Если проект использует `@svgr/webpack`, `svg-inline-loader`, `raw-loader` или общий SVG rule, исключите `src/sprite/.svg-sprite/sprite.svg` из этого правила. Generated SVG должен обрабатываться как `asset/resource`, а не как React-компонент или inline source.
|
```html
|
||||||
|
<app-icon icon="icon-name" role="img" aria-label="Готово"></app-icon>
|
||||||
|
```
|
||||||
|
|
||||||
Размер Web Component по умолчанию `1em`; управляйте им и цветами обычным CSS:
|
Значение `icon` — имя исходного SVG без расширения. Размер и цвета настраиваются через CSS:
|
||||||
|
|
||||||
```css
|
```css
|
||||||
icons-icon {
|
app-icon {
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
color: #334155;
|
color: #334155;
|
||||||
--icon-color-2: #f59e0b;
|
--icon-color-2: #f59e0b;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## 2. Дебаг и превью
|
Монохромная иконка наследует `color`, а цвета многоцветной иконки переопределяются через `--icon-color-N`. Нужные переменные показывает Viewer.
|
||||||
|
|
||||||
Viewer необязателен. Для debug/preview установите package как dev dependency:
|
Webpack 5 сам добавит `sprite.svg` в итоговую сборку.
|
||||||
|
|
||||||
|
## Дебаг и превью
|
||||||
|
|
||||||
|
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки.
|
||||||
|
|
||||||
|
Установите Viewer:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install --save-dev @gromlab/svg-sprites
|
npm install --save-dev @gromlab/svg-sprites
|
||||||
```
|
```
|
||||||
|
|
||||||
Подключите element entry и generated JS manifest:
|
Создайте entry `src/svg-sprite-debug.ts`:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import '@gromlab/svg-sprites/viewer/element'
|
import '@gromlab/svg-sprites/viewer/element'
|
||||||
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
||||||
import spriteManifest from './sprite/.svg-sprite/svg-sprite.manifest.js'
|
import spriteManifest from '../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'
|
||||||
|
|
||||||
document.querySelector<HTMLDivElement>('#app')!.insertAdjacentHTML(
|
const viewer = document.createElement('gromlab-sprite-viewer') as SpriteViewerElement
|
||||||
'beforeend',
|
|
||||||
'<gromlab-sprite-viewer></gromlab-sprite-viewer>',
|
|
||||||
)
|
|
||||||
|
|
||||||
const viewer = document.querySelector<SpriteViewerElement>('gromlab-sprite-viewer')!
|
|
||||||
viewer.viewerTitle = 'Иконки проекта'
|
viewer.viewerTitle = 'Иконки проекта'
|
||||||
viewer.sources = [spriteManifest]
|
viewer.sources = [spriteManifest]
|
||||||
|
document.body.append(viewer)
|
||||||
```
|
```
|
||||||
|
|
||||||
Webpack свяжет manifest с тем же emitted SVG asset. Оставляйте Viewer только в debug entry: production `<icons-icon>` от него не зависит.
|
Добавьте скрипт к основному entry только в development-режиме. Сохраните остальные настройки `webpack.config.js`:
|
||||||
|
|
||||||
## 3. Типизация конфига
|
```js
|
||||||
|
export default (_env, argv) => ({
|
||||||
После локальной установки package можно использовать helper:
|
// Остальные настройки Webpack.
|
||||||
|
entry: [
|
||||||
```ts
|
'./src/main.ts',
|
||||||
import { defineSpriteConfig } from '@gromlab/svg-sprites'
|
...(argv.mode === 'development' ? ['./src/svg-sprite-debug.ts'] : []),
|
||||||
|
],
|
||||||
export default defineSpriteConfig({
|
|
||||||
mode: 'standalone@webpack',
|
|
||||||
name: 'icons',
|
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
Либо импортируйте только `SpriteConfig` как type и примените `satisfies SpriteConfig`.
|
Запустите `npm run dev`. Viewer появится на основной странице приложения.
|
||||||
|
|
||||||
Без package добавьте copy-paste type в сам config:
|
Viewer добавляется только в development-сборку и не попадает в production.
|
||||||
|
|
||||||
```ts
|
|
||||||
type LocalSpriteConfig = {
|
|
||||||
mode: 'standalone@webpack'
|
|
||||||
name?: string
|
|
||||||
description?: string
|
|
||||||
input?: string | string[]
|
|
||||||
transform?: {
|
|
||||||
removeSize?: boolean
|
|
||||||
replaceColors?: boolean
|
|
||||||
addTransition?: boolean
|
|
||||||
}
|
|
||||||
generatedNotice?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mode: 'standalone@webpack',
|
|
||||||
name: 'icons',
|
|
||||||
} satisfies LocalSpriteConfig
|
|
||||||
```
|
|
||||||
|
|
||||||
Этот вариант сохраняет проверку exact mode без runtime import и без записи generator package в проект.
|
|
||||||
|
|||||||
@@ -6,32 +6,9 @@
|
|||||||
|
|
||||||
Устанавливать пакет в проект не нужно.
|
Устанавливать пакет в проект не нужно.
|
||||||
|
|
||||||
В руководстве используется следующая структура проекта:
|
|
||||||
|
|
||||||
```text
|
|
||||||
/
|
|
||||||
├── index.html
|
|
||||||
└── assets/
|
|
||||||
├── app-icons/
|
|
||||||
└── svg-icons/
|
|
||||||
├── check.svg
|
|
||||||
└── warning.svg
|
|
||||||
```
|
|
||||||
|
|
||||||
### 1. Создайте конфиг спрайта
|
### 1. Создайте конфиг спрайта
|
||||||
|
|
||||||
Выберите папку для спрайта. В этом примере используется `assets/app-icons`. Создайте в ней файл `svg-sprite.config.json`:
|
Выберите каталог для будущего SVG-спрайта, например `assets/app-icons`, и создайте в нём `svg-sprite.config.json`. В `input` укажите путь к существующим SVG относительно файла конфигурации. Перемещать или копировать иконки не требуется.
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"mode": "standalone",
|
|
||||||
"name": "icons"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Укажите источник иконок
|
|
||||||
|
|
||||||
В `input` можно указать папку, отдельный SVG-файл или glob-шаблон. Для нескольких источников используйте массив с любой комбинацией этих значений:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -41,7 +18,7 @@
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. Сгенерируйте спрайт
|
### 2. Сгенерируйте спрайт
|
||||||
|
|
||||||
Передайте команде путь к конфигу:
|
Передайте команде путь к конфигу:
|
||||||
|
|
||||||
@@ -62,7 +39,7 @@ assets/app-icons/.svg-sprite/
|
|||||||
|
|
||||||
Каталог `.svg-sprite` создаётся автоматически и полностью заменяется при каждой генерации. Не редактируйте его содержимое вручную.
|
Каталог `.svg-sprite` создаётся автоматически и полностью заменяется при каждой генерации. Не редактируйте его содержимое вручную.
|
||||||
|
|
||||||
### 4. Используйте иконку
|
### 3. Используйте иконку
|
||||||
|
|
||||||
В `index.html` укажите путь к созданному `sprite.svg`. После `#` добавьте имя нужной иконки без расширения `.svg`:
|
В `index.html` укажите путь к созданному `sprite.svg`. После `#` добавьте имя нужной иконки без расширения `.svg`:
|
||||||
|
|
||||||
@@ -72,12 +49,10 @@ assets/app-icons/.svg-sprite/
|
|||||||
height="24"
|
height="24"
|
||||||
aria-label="Готово"
|
aria-label="Готово"
|
||||||
>
|
>
|
||||||
<use href="./assets/app-icons/.svg-sprite/sprite.svg#check"></use>
|
<use href="./assets/app-icons/.svg-sprite/sprite.svg#icon-name"></use>
|
||||||
</svg>
|
</svg>
|
||||||
```
|
```
|
||||||
|
|
||||||
Иконка из файла `check.svg` будет доступна как `#check`.
|
|
||||||
|
|
||||||
## Дебаг и превью
|
## Дебаг и превью
|
||||||
|
|
||||||
`sprite.svg` — технический файл, а не галерея иконок. При его открытии нельзя удобно просмотреть весь набор. Кроме того, градиенты, маски, фильтры и ссылки на внутренние `id` могут отображаться с артефактами.
|
`sprite.svg` — технический файл, а не галерея иконок. При его открытии нельзя удобно просмотреть весь набор. Кроме того, градиенты, маски, фильтры и ссылки на внутренние `id` могут отображаться с артефактами.
|
||||||
|
|||||||
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,4 +0,0 @@
|
|||||||
# Guides Next.js App Router перемещены
|
|
||||||
|
|
||||||
- [App Router + Turbopack](guides/next-app-turbopack.md)
|
|
||||||
- [App Router + Webpack](guides/next-app-webpack.md)
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
# Guides Next.js Pages Router перемещены
|
|
||||||
|
|
||||||
- [Pages Router + Turbopack](guides/next-pages-turbopack.md)
|
|
||||||
- [Pages Router + Webpack](guides/next-pages-webpack.md)
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# Программный API перемещён
|
|
||||||
|
|
||||||
Canonical документ: [программный API](reference/programmatic-api.md).
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# Guide React + Vite перемещён
|
|
||||||
|
|
||||||
Canonical guide: [React + Vite](guides/react-vite.md).
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# Guide React + Webpack перемещён
|
|
||||||
|
|
||||||
Canonical guide: [React + Webpack](guides/react-webpack.md).
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# Технический справочник перемещён
|
|
||||||
|
|
||||||
Canonical документ: [технический справочник](reference/technical.md).
|
|
||||||
@@ -14,6 +14,21 @@ const result = await generateSprite(
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Результат содержит имя и 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-скрипте,
|
Для static standalone mode `result.spritePath` можно использовать в build-скрипте,
|
||||||
чтобы опубликовать SVG по URL приложения:
|
чтобы опубликовать SVG по URL приложения:
|
||||||
|
|
||||||
@@ -29,7 +44,7 @@ await copyFile(result.spritePath, 'dist/app-icons/sprite.svg')
|
|||||||
`spritePath` является filesystem path, а не browser URL. Deployment-neutral JSON
|
`spritePath` является filesystem path, а не browser URL. Deployment-neutral JSON
|
||||||
manifest доступен через `result.manifestPath` и копируется независимо от SVG.
|
manifest доступен через `result.manifestPath` и копируется независимо от SVG.
|
||||||
|
|
||||||
Первый аргумент принимает полный путь к config-файлу с любым именем и расширением `.ts`, `.js` или `.json`. Каталог вместо файла включает config-less режим: корнем sprite-модуля становится этот каталог.
|
Первый аргумент принимает абсолютный или относительный путь к config-файлу с любым именем и расширением `.ts`, `.js` или `.json`. Каталог вместо файла включает config-less режим: корнем sprite-модуля становится этот каталог.
|
||||||
|
|
||||||
Второй аргумент содержит необязательные overrides и всегда имеет приоритет над конфигом:
|
Второй аргумент содержит необязательные overrides и всегда имеет приоритет над конфигом:
|
||||||
|
|
||||||
@@ -107,13 +122,17 @@ await generateNextSprite('path/to/config.ts', {
|
|||||||
|
|
||||||
```ts
|
```ts
|
||||||
import {
|
import {
|
||||||
|
isSpriteMode,
|
||||||
loadSpriteConfig,
|
loadSpriteConfig,
|
||||||
resolveSpriteConfig,
|
resolveSpriteConfig,
|
||||||
|
resolveSpriteConfigSource,
|
||||||
validateSpriteConfig,
|
validateSpriteConfig,
|
||||||
} from '@gromlab/svg-sprites'
|
} from '@gromlab/svg-sprites'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- `isSpriteMode(value)` проверяет, является ли значение поддерживаемым exact mode.
|
||||||
- `loadSpriteConfig(file)` загружает явно указанный `.ts`, `.js` или `.json` файл.
|
- `loadSpriteConfig(file)` загружает явно указанный `.ts`, `.js` или `.json` файл.
|
||||||
|
- `resolveSpriteConfigSource(source)` разрешает путь как config-файл или config-less каталог.
|
||||||
- `validateSpriteConfig(value)` выполняет runtime-валидацию объекта.
|
- `validateSpriteConfig(value)` выполняет runtime-валидацию объекта.
|
||||||
- `resolveSpriteConfig(root, config, overrides)` объединяет значения, добавляет defaults и разрешает пути относительно `root`.
|
- `resolveSpriteConfig(root, config, overrides)` объединяет значения, добавляет defaults и разрешает пути относительно `root`.
|
||||||
|
|
||||||
@@ -138,6 +157,16 @@ import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
|
|||||||
|
|
||||||
Browser entry регистрирует `<gromlab-sprite-viewer>`. Bare standalone также может загрузить самостоятельный `dist/viewer-element.js` без bundler.
|
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:
|
React bridge сохраняет компонентный API:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
[Индекс документации](../README.md)
|
[Индекс документации](../README.md)
|
||||||
|
|
||||||
|
[Конфигурация JSON, JavaScript и TypeScript](../configuration.md)
|
||||||
|
|
||||||
Справочник по конфигурации, generated API и поведению `@gromlab/svg-sprites`. Пошаговую установку смотрите в руководстве для вашего стека:
|
Справочник по конфигурации, generated API и поведению `@gromlab/svg-sprites`. Пошаговую установку смотрите в руководстве для вашего стека:
|
||||||
|
|
||||||
- [Bare standalone](../guides/standalone.md)
|
- [Bare standalone](../guides/standalone.md)
|
||||||
@@ -13,6 +15,26 @@
|
|||||||
- [Next.js App Router + Webpack](../guides/next-app-webpack.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 + Turbopack](../guides/next-pages-turbopack.md)
|
||||||
- [Next.js Pages Router + Webpack](../guides/next-pages-webpack.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)
|
||||||
|
|
||||||
## Требования
|
## Требования
|
||||||
|
|
||||||
@@ -24,7 +46,7 @@
|
|||||||
Для генерации не нужна dependency проекта. Запускайте CLI через `npx`:
|
Для генерации не нужна dependency проекта. Запускайте CLI через `npx`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites path/to/svg-sprite.config.ts
|
npx --yes @gromlab/svg-sprites path/to/svg-sprite.config.json
|
||||||
```
|
```
|
||||||
|
|
||||||
Устанавливайте пакет как development dependency, только если проекту нужны
|
Устанавливайте пакет как development dependency, только если проекту нужны
|
||||||
@@ -36,7 +58,7 @@ npm install --save-dev @gromlab/svg-sprites
|
|||||||
|
|
||||||
## CLI и режимы генерации
|
## CLI и режимы генерации
|
||||||
|
|
||||||
CLI принимает ровно один путь: явно выбранный config-файл либо каталог для config-less генерации:
|
Для генерации CLI принимает ровно один путь: явно выбранный config-файл либо каталог для config-less генерации:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
svg-sprites [options] <config-file-or-directory>
|
svg-sprites [options] <config-file-or-directory>
|
||||||
@@ -49,16 +71,36 @@ svg-sprites [options] <config-file-or-directory>
|
|||||||
| Standalone + Webpack 5 | `standalone@webpack` |
|
| Standalone + Webpack 5 | `standalone@webpack` |
|
||||||
| React + Vite | `react@vite` |
|
| React + Vite | `react@vite` |
|
||||||
| React + Webpack 5 | `react@webpack` |
|
| 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 + Turbopack | `next@app/turbopack` |
|
||||||
| Next.js App Router + Webpack 5 | `next@app/webpack` |
|
| Next.js App Router + Webpack 5 | `next@app/webpack` |
|
||||||
| Next.js Pages Router + Turbopack | `next@pages/turbopack` |
|
| Next.js Pages Router + Turbopack | `next@pages/turbopack` |
|
||||||
| Next.js Pages Router + Webpack 5 | `next@pages/webpack` |
|
| Next.js Pages Router + Webpack 5 | `next@pages/webpack` |
|
||||||
|
|
||||||
Config-файл может иметь любое имя и расширение `.ts`, `.js` или `.json`. CLI не ищет конфиг по соглашению: файл нужно передать явно. В руководствах используется рекомендуемое имя `svg-sprite.config.ts`.
|
Config-файл может иметь любое имя и расширение `.ts`, `.js` или `.json`. CLI не ищет конфиг по соглашению: файл нужно передать явно. В руководствах используется рекомендуемое имя `svg-sprite.config.json`.
|
||||||
|
|
||||||
Если передан каталог, все настройки берутся из CLI. Если передан config-файл, CLI-параметры перекрывают значения файла. Общий порядок: `defaults → config → CLI`.
|
Если передан каталог, все настройки берутся из CLI. Если передан config-файл, CLI-параметры перекрывают значения файла. Общий порядок: `defaults → config → CLI`.
|
||||||
|
|
||||||
Доступны `--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.
|
`--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 не раскрыл их до запуска генератора:
|
В CLI заключайте glob-паттерны в одинарные кавычки, чтобы shell не раскрыл их до запуска генератора:
|
||||||
|
|
||||||
@@ -96,7 +138,7 @@ export default defineSpriteConfig({
|
|||||||
| Опция | Тип | По умолчанию | Назначение |
|
| Опция | Тип | По умолчанию | Назначение |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| `mode` | `SpriteMode` | Нет | Режим генерации; можно передать через CLI/API |
|
| `mode` | `SpriteMode` | Нет | Режим генерации; можно передать через CLI/API |
|
||||||
| `name` | `string` | Выводится из каталога | Имя спрайта, компонента и публичных типов |
|
| `name` | `string` | Выводится из каталога | Имя спрайта; в modes с компонентом также задаёт имя компонента и публичных типов |
|
||||||
| `description` | `string` | Нет | Описание для типов и debug manifest |
|
| `description` | `string` | Нет | Описание для типов и debug manifest |
|
||||||
| `input` | `string \| string[]` | `./icons` | Папки, SVG-файлы и glob-паттерны относительно папки конфига |
|
| `input` | `string \| string[]` | `./icons` | Папки, SVG-файлы и glob-паттерны относительно папки конфига |
|
||||||
| `transform` | `TransformOptions` | Все включены | Настройки подготовки SVG |
|
| `transform` | `TransformOptions` | Все включены | Настройки подготовки SVG |
|
||||||
@@ -111,7 +153,7 @@ app → AppIcon
|
|||||||
file-manager → FileManagerIcon
|
file-manager → FileManagerIcon
|
||||||
```
|
```
|
||||||
|
|
||||||
Если `name` не задано, генератор выводит его из каталога. Для каталога с именем `svg-sprite` или `svg-sprites` используется имя родительского каталога.
|
Если `name` не задано, генератор преобразует имя каталога в kebab-case. Для каталога с именем `svg-sprite` или `svg-sprites` используется имя родительского каталога.
|
||||||
|
|
||||||
### Источники иконок
|
### Источники иконок
|
||||||
|
|
||||||
@@ -141,7 +183,7 @@ file-manager → FileManagerIcon
|
|||||||
```text
|
```text
|
||||||
app-icons/
|
app-icons/
|
||||||
├── .gitignore
|
├── .gitignore
|
||||||
├── svg-sprite.config.ts
|
├── svg-sprite.config.json
|
||||||
├── index.ts # необязательный пользовательский barrel
|
├── index.ts # необязательный пользовательский barrel
|
||||||
└── .svg-sprite/
|
└── .svg-sprite/
|
||||||
├── index.js
|
├── index.js
|
||||||
@@ -183,10 +225,10 @@ runtime asset и deployment-neutral manifest data:
|
|||||||
generated Web Component без внешних runtime-зависимостей. Bare `standalone`
|
generated Web Component без внешних runtime-зависимостей. Bare `standalone`
|
||||||
намеренно не создаёт JavaScript-компонент.
|
намеренно не создаёт JavaScript-компонент.
|
||||||
|
|
||||||
Генератор перезаписывает и удаляет только файлы со своим marker. Если в managed-пути находится пользовательский файл, генерация завершается ошибкой. Корневой `index.ts` генератору не принадлежит; при необходимости создайте пользовательский barrel:
|
`.svg-sprite` полностью управляется генератором и при каждой генерации заменяется целиком. Любые добавленные в него файлы будут удалены. Пользовательские файлы размещайте рядом, например в корневом `index.ts`:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
export * from './.svg-sprite'
|
export * from './.svg-sprite/index.js'
|
||||||
```
|
```
|
||||||
|
|
||||||
## Standalone Web Component и TypeScript
|
## Standalone Web Component и TypeScript
|
||||||
@@ -307,7 +349,7 @@ folder open.svg → icon="folder open" → id="icon-<stable-hash>"
|
|||||||
|
|
||||||
## Множественные спрайты
|
## Множественные спрайты
|
||||||
|
|
||||||
Каждый каталог с конфигом создаёт независимый компонент, типы, manifest и SVG asset:
|
Каждый каталог с конфигом создаёт независимый mode-specific контракт. Framework modes создают нативный компонент и declarations, standalone bundler modes — Web Component и declarations, а bare `standalone` — SVG и JSON manifest:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
app-icons → AppIcon → общие иконки
|
app-icons → AppIcon → общие иконки
|
||||||
@@ -329,7 +371,7 @@ editor-icons → EditorIcon → иконки редактора
|
|||||||
|
|
||||||
### Generated-компонент
|
### Generated-компонент
|
||||||
|
|
||||||
Для React и Next.js используйте generated React-компонент. Он знает внутренние ID, формирует URL и предоставляет TypeScript API:
|
Используйте generated native-компонент из guide выбранного exact mode. Он знает внутренние ID, формирует URL и предоставляет TypeScript API. Для React и Next.js это выглядит так:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
<AppIcon icon="search" width={24} height={24} />
|
<AppIcon icon="search" width={24} height={24} />
|
||||||
@@ -353,7 +395,7 @@ Static HTML после публикации `.svg-sprite/sprite.svg` прило
|
|||||||
</svg>
|
</svg>
|
||||||
```
|
```
|
||||||
|
|
||||||
Standalone Vite/Webpack предоставляет generated `getIconsIconHref()` и mapping
|
Standalone Vite/Webpack предоставляет generated `getAppIconHref()` и mapping
|
||||||
внутренних IDs. Не конструируйте fragment из небезопасного имени файла вручную.
|
внутренних IDs. Не конструируйте fragment из небезопасного имени файла вручную.
|
||||||
|
|
||||||
Vite:
|
Vite:
|
||||||
@@ -567,7 +609,7 @@ export const IconsDebugPage = () => (
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
Viewer показывает группы, поиск, `viewBox`, CSS-переменные и fallback-цвета. React/Next manifests получают вкладки React, SVG, IMG и CSS; standalone manifests получают SVG, IMG и CSS. Цветовые значения можно менять в интерфейсе и сразу проверять результат.
|
Viewer показывает группы, поиск, `viewBox`, CSS-переменные и fallback-цвета. Framework manifests получают вкладку своего framework, а также SVG, IMG и CSS; standalone manifests получают SVG, IMG и CSS. Цветовые значения можно менять в интерфейсе и сразу проверять результат.
|
||||||
|
|
||||||
### Тема Viewer
|
### Тема Viewer
|
||||||
|
|
||||||
@@ -602,7 +644,7 @@ Viewer показывает группы, поиск, `viewBox`, CSS-перем
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/ui/app-icons/svg-sprite.config.ts",
|
"sprites": "npx --yes @gromlab/svg-sprites src/ui/app-icons/svg-sprite.config.ts",
|
||||||
"predev": "npm run sprites",
|
"predev": "npm run sprites",
|
||||||
"prebuild": "npm run sprites",
|
"prebuild": "npm run sprites",
|
||||||
"pretypecheck": "npm run sprites"
|
"pretypecheck": "npm run sprites"
|
||||||
@@ -610,22 +652,22 @@ Viewer показывает группы, поиск, `viewBox`, CSS-перем
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
CI должен выполнять generation script до сборки или проверки типов. Для воспроизводимости замените `latest` на точную версию. Локальная установка package не нужна, если CI не использует Viewer, package-типы config или программный API.
|
CI должен выполнять generation script до сборки или проверки типов. Локальная установка package не нужна, если CI не использует Viewer, package-типы config или программный API.
|
||||||
|
|
||||||
Bare `standalone` не создаёт и не изменяет `.gitignore`: приложение само решает, коммитить или игнорировать его `.svg-sprite/`. В остальных modes генератор не перезапишет пользовательский `.gitignore`. Он также откажется перезаписывать пользовательский файл внутри `.svg-sprite`. Корневой `index.ts` остаётся пользовательским и может переэкспортировать generated API.
|
Bare `standalone` не создаёт `.gitignore` и сохраняет пользовательский файл. Если после другого mode остался управляемый `.gitignore`, bare mode удалит его. В остальных modes генератор откажется перезаписать пользовательский `.gitignore` без generated marker. Корневой `index.ts` остаётся пользовательским и может переэкспортировать generated API.
|
||||||
|
|
||||||
## Диагностика
|
## Диагностика
|
||||||
|
|
||||||
- Нет `.svg-sprite/index.js`: запустите generation script до импорта generated-модуля.
|
- Для всех modes, кроме bare `standalone`: если нет `.svg-sprite/index.js`, запустите generation script до импорта generated-модуля.
|
||||||
- Не найден источник: передайте существующий config-файл или каталог sprite-модуля.
|
- Не найден источник: передайте существующий config-файл или каталог sprite-модуля.
|
||||||
- Не указан mode: добавьте `mode` в config либо передайте `--mode`.
|
- Не указан mode: добавьте `mode` в config либо передайте `--mode`.
|
||||||
- Иконка отсутствует в типе: проверьте `input`, расширение `.svg`, glob-исключения и необходимость `**/*.svg` для вложенных папок.
|
- Иконка отсутствует в типе: проверьте `input`, расширение `.svg`, glob-исключения и необходимость `**/*.svg` для вложенных папок.
|
||||||
- Конфликт имени: два разных SVG имеют одинаковый basename; переименуйте один файл.
|
- Конфликт имени: два разных SVG имеют одинаковый basename; переименуйте один файл.
|
||||||
- `Refusing to overwrite a user file`: в managed-пути находится файл без generated marker.
|
- `Refusing to overwrite a user file`: в корне sprite-модуля находится пользовательский `.gitignore`, который генератор не может заменить.
|
||||||
- Иконка не меняет цвет: используйте `<svg><use>` или generated-компонент и проверьте `replaceColors`.
|
- Иконка не меняет цвет: используйте `<svg><use>` или generated-компонент и проверьте `replaceColors`.
|
||||||
- Webpack выдаёт неверный URL: проверьте Asset Modules, `output.publicPath` и SVG loaders.
|
- Webpack выдаёт неверный URL: проверьте Asset Modules, `output.publicPath` и SVG loaders.
|
||||||
- Static sprite возвращает 404: проверьте post-generation copy или server alias и не передавайте filesystem `spritePath` в HTML.
|
- Static sprite возвращает 404: проверьте post-generation copy или server alias и не передавайте filesystem `spritePath` в HTML.
|
||||||
- Viewer не видит спрайт: проверьте путь к `.svg-sprite/svg-sprite.manifest.js` и выполните генерацию до запуска приложения.
|
- Viewer не видит спрайт: для bundler modes проверьте путь к `.svg-sprite/svg-sprite.manifest.js`; для bare `standalone` — URL опубликованных `svg-sprite.manifest.json` и `sprite.svg`. Выполните генерацию до запуска приложения.
|
||||||
- Build и mode не совпадают: используйте target, соответствующий фактическому сборщику.
|
- Build и mode не совпадают: используйте target, соответствующий фактическому сборщику.
|
||||||
|
|
||||||
Для собственного orchestration и низкоуровневой компиляции смотрите [Программный API](programmatic-api.md).
|
Для собственного orchestration и низкоуровневой компиляции смотрите [Программный API](programmatic-api.md).
|
||||||
|
|||||||
1
integration/.gitignore
vendored
1
integration/.gitignore
vendored
@@ -8,6 +8,7 @@ apps/*/.next/
|
|||||||
apps/*/.nuxt/
|
apps/*/.nuxt/
|
||||||
apps/*/.output/
|
apps/*/.output/
|
||||||
apps/*/.svelte-kit/
|
apps/*/.svelte-kit/
|
||||||
|
apps/*/.vinxi/
|
||||||
apps/*/build/
|
apps/*/build/
|
||||||
apps/*/out-tsc/
|
apps/*/out-tsc/
|
||||||
apps/*/public/sprites/
|
apps/*/public/sprites/
|
||||||
|
|||||||
@@ -12,13 +12,32 @@ production build и отображения внешнего SVG-спрайта
|
|||||||
| `standalone-webpack` | `standalone@webpack` | Vanilla TypeScript + Webpack 5 |
|
| `standalone-webpack` | `standalone@webpack` | Vanilla TypeScript + Webpack 5 |
|
||||||
| `react-vite` | `react@vite` | React + Vite |
|
| `react-vite` | `react@vite` | React + Vite |
|
||||||
| `react-webpack` | `react@webpack` | React + Webpack 5 |
|
| `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-turbopack` | `next@app/turbopack` | App Router + Turbopack |
|
||||||
| `next-app-webpack` | `next@app/webpack` | App Router + Webpack |
|
| `next-app-webpack` | `next@app/webpack` | App Router + Webpack |
|
||||||
| `next-pages-turbopack` | `next@pages/turbopack` | Pages Router + Turbopack |
|
| `next-pages-turbopack` | `next@pages/turbopack` | Pages Router + Turbopack |
|
||||||
| `next-pages-webpack` | `next@pages/webpack` | Pages Router + Webpack |
|
| `next-pages-webpack` | `next@pages/webpack` | Pages Router + Webpack |
|
||||||
|
|
||||||
В verify-матрицу входят только поддерживаемые exact modes. Fixtures остальных
|
В verify-матрицу входят все exact modes из корневого `MODES_CHECKLIST.md`.
|
||||||
frameworks сохранены как заготовки и будут подключаться после появления их adapters.
|
|
||||||
|
|
||||||
## Первый запуск
|
## Первый запуск
|
||||||
|
|
||||||
@@ -46,10 +65,12 @@ npm run integration:test
|
|||||||
Для запуска команды только в одном fixture:
|
Для запуска команды только в одном fixture:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
node integration/scripts/run-workspaces.mjs build react-vite
|
node scripts/run-workspaces.mjs build react-vite
|
||||||
npm run dev --workspace @svg-sprites-fixtures/react-vite --prefix integration
|
npm run dev --workspace @svg-sprites-fixtures/react-vite --prefix integration
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Первую команду запускайте из каталога `integration`.
|
||||||
|
|
||||||
Перед E2E production builds должны существовать. Тест запускает каждый server
|
Перед E2E production builds должны существовать. Тест запускает каждый server
|
||||||
последовательно, проверяет внешний `href`, HTTP status и Content-Type спрайта,
|
последовательно, проверяет внешний `href`, HTTP status и Content-Type спрайта,
|
||||||
наличие symbol ID, отсутствие browser errors и зелёные пиксели отрисованной иконки.
|
наличие symbol ID, отсутствие browser errors и зелёные пиксели отрисованной иконки.
|
||||||
|
|||||||
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()
|
||||||
2
integration/apps/alpine-vite/src/sprite/.gitignore
vendored
Normal file
2
integration/apps/alpine-vite/src/sprite/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# @generated by @gromlab/svg-sprites. Do not edit.
|
||||||
|
/.svg-sprite/
|
||||||
1
integration/apps/alpine-vite/src/sprite/index.d.ts
vendored
Normal file
1
integration/apps/alpine-vite/src/sprite/index.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from './.svg-sprite/index.js'
|
||||||
1
integration/apps/alpine-vite/src/sprite/index.js
Normal file
1
integration/apps/alpine-vite/src/sprite/index.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from './.svg-sprite/index.js'
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"mode": "alpine@vite",
|
||||||
|
"name": "icons",
|
||||||
|
"input": "../../../../fixtures/icons/check.svg",
|
||||||
|
"generatedNotice": false
|
||||||
|
}
|
||||||
12
integration/apps/alpine-vite/tsconfig.json
Normal file
12
integration/apps/alpine-vite/tsconfig.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2022",
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "Bundler",
|
||||||
|
"lib": ["ES2022", "DOM"],
|
||||||
|
"strict": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"skipLibCheck": true
|
||||||
|
},
|
||||||
|
"include": ["src/generated-contract.typecheck.ts"]
|
||||||
|
}
|
||||||
16
integration/apps/alpine-webpack/index.html
Normal file
16
integration/apps/alpine-webpack/index.html
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Alpine Webpack 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>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
23
integration/apps/alpine-webpack/package.json
Normal file
23
integration/apps/alpine-webpack/package.json
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"name": "@svg-sprites-fixtures/alpine-webpack",
|
||||||
|
"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 && webpack --mode production",
|
||||||
|
"dev": "npm run sprites && webpack serve --mode development"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"alpinejs": "3.15.12"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@gromlab/svg-sprites": "file:../../..",
|
||||||
|
"html-webpack-plugin": "5.6.7",
|
||||||
|
"typescript": "6.0.2",
|
||||||
|
"webpack": "5.108.4",
|
||||||
|
"webpack-cli": "7.2.1",
|
||||||
|
"webpack-dev-server": "5.2.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user