mirror of
https://github.com/gromlab-ru/svg-sprites.git
synced 2026-07-22 04:40:17 +03:00
- обновлены русская и английская версии README - добавлены технические справочники на двух языках - актуализированы ссылки и инструкции для React-сборок
266 lines
13 KiB
Markdown
266 lines
13 KiB
Markdown
# @gromlab/svg-sprites
|
||
|
||
[🇬🇧 English](README.md) | 🇷🇺 Русский
|
||
|
||
 
|
||
|
||
`@gromlab/svg-sprites` — генератор SVG-спрайтов для современных веб-приложений. Он собирает выбранные SVG-иконки в один или несколько внешних кешируемых спрайтов и подготавливает их для использования в интерфейсе.
|
||
|
||
Для React и Next.js пакет создаёт типизированные компоненты и поддерживает Vite, Webpack 5 и Turbopack. В основе при этом остаётся обычный SVG-спрайт, который можно использовать без фреймворка, в том числе в нативном HTML.
|
||
|
||
## SVG-спрайт так же прост, как обычная SVG-иконка
|
||
|
||
Для всего спрайта генерируется один типизированный React-компонент. Выберите иконку через `icon`, а редактор покажет автокомплит всех доступных имён.
|
||
|
||
```tsx
|
||
<AppIcon icon="search" width={24} height={24} />
|
||
```
|
||
|
||
Компонент принимает привычные SVG-атрибуты: размеры, `color`, `className`, `style`, `aria-*` и обработчики событий. Если нужен внешний контейнер, добавьте `wrapped`.
|
||
|
||
```tsx
|
||
<AppIcon icon="search" wrapped className="iconWrapper" />
|
||
```
|
||
|
||
В приложении не приходится работать со спрайтом напрямую. Вы используете его так же, как обычную SVG-иконку, но получаете один компонент, автокомплит и TypeScript-проверку всех имён.
|
||
|
||
## AI-friendly из коробки
|
||
|
||
`@gromlab/svg-sprites` сразу рассчитан на работу с AI-агентами. Подключите готовый skill и поручите агенту настройку, миграцию или диагностику без длинных инструкций и ручного изучения документации.
|
||
|
||
[🇷🇺 Скачать AI skill (на русском)](https://github.com/gromov-sergei/svg-sprites/releases/latest/download/svg-sprites-ru.zip)
|
||
|
||
[🇬🇧 Скачать AI skill (на английском)](https://github.com/gromov-sergei/svg-sprites/releases/latest/download/svg-sprites.zip)
|
||
|
||
## От SVG до компонента за четыре шага
|
||
|
||
Основной пример использует Next.js App Router и Turbopack.
|
||
|
||
### 1. Установите пакет
|
||
|
||
```bash
|
||
npm install --save-dev @gromlab/svg-sprites
|
||
```
|
||
|
||
### 2. Укажите нужные иконки
|
||
|
||
SVG могут оставаться в существующей структуре проекта:
|
||
|
||
```text
|
||
src/
|
||
├── assets/icons/
|
||
│ ├── search.svg
|
||
│ └── settings.svg
|
||
├── features/profile/
|
||
│ └── user.svg
|
||
└── ui/app-icons/
|
||
└── svg-sprite.config.ts
|
||
```
|
||
|
||
Создайте конфигурацию спрайта:
|
||
|
||
```ts
|
||
// src/ui/app-icons/svg-sprite.config.ts
|
||
import { defineNextSpriteConfig } from '@gromlab/svg-sprites'
|
||
|
||
export default defineNextSpriteConfig({
|
||
name: 'app',
|
||
inputFiles: [
|
||
'../../assets/icons/search.svg',
|
||
'../../assets/icons/settings.svg',
|
||
'../../features/profile/user.svg',
|
||
],
|
||
})
|
||
```
|
||
|
||
### 3. Добавьте генерацию
|
||
|
||
```json
|
||
{
|
||
"scripts": {
|
||
"sprites": "svg-sprites --mode next@app/turbopack src/ui/app-icons",
|
||
"predev": "npm run sprites",
|
||
"prebuild": "npm run sprites"
|
||
}
|
||
}
|
||
```
|
||
|
||
Первый запуск:
|
||
|
||
```bash
|
||
npm run sprites
|
||
```
|
||
|
||
Пакет создаст `AppIcon`, TypeScript-типы и отдельный SVG-спрайт.
|
||
|
||
### 4. Используйте как обычную иконку
|
||
|
||
```tsx
|
||
import { AppIcon } from '@/ui/app-icons'
|
||
|
||
export default function SearchButton() {
|
||
return (
|
||
<button type="button">
|
||
<AppIcon icon="search" width={20} height={20} />
|
||
Найти
|
||
</button>
|
||
)
|
||
}
|
||
```
|
||
|
||
Это Server Component. Для иконки не нужны provider, `'use client'` или ручная сборка URL.
|
||
|
||
## Типизированный React-компонент с автокомплитом
|
||
|
||
Каждый спрайт получает собственный готовый компонент. Свойство `icon` формируется из реальных имён SVG, поэтому редактор показывает точный список доступных иконок, а TypeScript сразу обнаруживает опечатки.
|
||
|
||
```tsx
|
||
<AppIcon icon="search" /> // доступная иконка
|
||
<AppIcon icon="serach" /> // ошибка TypeScript
|
||
```
|
||
|
||
После добавления новой SVG-иконки и повторной генерации её имя автоматически появляется в типах и автокомплите. Не нужно вручную поддерживать компоненты, union-типы или реестр имён.
|
||
|
||
## Next.js App Router и SSR из коробки
|
||
|
||
Generated-компоненты работают в Server Components, SSR и SSG без `'use client'`.
|
||
|
||
Подключение иконки не переносит страницу на клиент, не требует provider и не создаёт дополнительную границу гидратации.
|
||
|
||
Один и тот же компонент можно использовать в `page.tsx`, `layout.tsx`, серверных и клиентских компонентах.
|
||
|
||
## Множественные спрайты вместо одного глобального
|
||
|
||
Проект не ограничен одним набором иконок. Создавайте независимые спрайты для общих элементов, отдельных страниц и крупных UI-модулей.
|
||
|
||
```tsx
|
||
<AppIcon icon="search" />
|
||
<AnalyticsIcon icon="chart" />
|
||
<EditorIcon icon="bold" />
|
||
```
|
||
|
||
Каждый набор получает собственный типизированный компонент и SVG asset, поэтому разделы приложения не несут иконки, которые им не нужны.
|
||
|
||
## Каждая иконка хранится в одном экземпляре
|
||
|
||
В библиотеке исходников каждая SVG-иконка хранится в одном экземпляре и может входить в любое количество спрайтов. Общие иконки не приходится копировать между страницами и модулями: они обновляются для всех наборов из одного места.
|
||
|
||
```text
|
||
search.svg ─┬─→ AppIcon
|
||
├─→ AnalyticsIcon
|
||
└─→ EditorIcon
|
||
```
|
||
|
||
Спрайты разделяются ради производительности, но библиотека исходных иконок остаётся единой.
|
||
|
||
## Браузерное кеширование
|
||
|
||
При стандартной конфигурации Vite, Webpack или Next.js каждый спрайт выпускается отдельным версионированным SVG-файлом.
|
||
|
||
Пока набор иконок не меняется, браузер может использовать сохранённую копию независимо от обновлений JavaScript приложения.
|
||
|
||
Изменение React-компонентов не требует повторно загружать геометрию всех иконок.
|
||
|
||
## JavaScript без SVG-балласта
|
||
|
||
Контуры иконок остаются во внешних SVG assets и не увеличивают chunks приложения.
|
||
|
||
```text
|
||
React-код → JavaScript chunks
|
||
SVG-иконки → отдельные SVG assets
|
||
```
|
||
|
||
JavaScript отвечает за интерфейс и поведение, а графика загружается и кешируется отдельно.
|
||
|
||
## Трансформации SVG из коробки
|
||
|
||
Во время генерации пакет автоматически подготавливает исходные SVG для интерфейса:
|
||
|
||
- удаляет фиксированные `width` и `height`;
|
||
- сохраняет существующий `viewBox`;
|
||
- преобразует `fill` и `stroke` в CSS-переменные;
|
||
- добавляет плавные transitions непосредственно в цветные элементы иконки.
|
||
|
||
Каждую трансформацию можно настроить или отключить независимо.
|
||
|
||
## Каждый цвет под контролем CSS
|
||
|
||
При генерации цвета `fill` и `stroke` автоматически преобразуются в CSS-переменные `--icon-color-N`.
|
||
|
||
Монохромная иконка наследует `currentColor`:
|
||
|
||
```tsx
|
||
<AppIcon icon="search" color="rebeccapurple" />
|
||
```
|
||
|
||
В многоцветной иконке каждый цвет можно менять отдельно:
|
||
|
||
```tsx
|
||
<AppIcon
|
||
icon="user"
|
||
style={{
|
||
'--icon-color-1': '#2563eb',
|
||
'--icon-color-2': '#dbeafe',
|
||
}}
|
||
/>
|
||
```
|
||
|
||
Темы, состояния и hover-эффекты создаются без редактирования SVG и дополнительных копий иконки.
|
||
|
||
## SpriteViewer: все спрайты на одной debug-странице
|
||
|
||
`SpriteViewer` рендерит все спрайты проекта в одном месте и показывает, какие иконки вошли в каждый набор и как они выглядят.
|
||
|
||
Для каждой иконки видны созданные CSS-переменные и их fallback-цвета. Значения можно менять прямо в Viewer и сразу наблюдать результат.
|
||
|
||
Здесь же доступны готовые примеры подключения через:
|
||
|
||
- React;
|
||
- `<svg><use>`;
|
||
- `<img>`;
|
||
- CSS.
|
||
|
||

|
||
|
||
Viewer подключается только к внутренней debug-странице и не становится частью generated-компонентов иконок.
|
||
|
||
## От нативного HTML до Next.js
|
||
|
||
В основе остаётся обычный SVG-спрайт, который можно использовать даже без фреймворка и сборщика.
|
||
|
||
Для React и Next.js пакет генерирует типизированные компоненты и поддерживает Vite, Webpack 5 и Turbopack. Список готовых интеграций будет расширяться новыми фреймворками.
|
||
|
||
## Чистый Git
|
||
|
||
Генератор создаёт локальный `.gitignore`, который исключает generated-файлы и не позволяет им засорять историю, pull requests и код проекта.
|
||
|
||
В репозитории остаются исходные SVG, конфигурация и правило `.gitignore`, а локально и в CI спрайты, компоненты и типы заново создаются через `prebuild`.
|
||
|
||
## В production только иконки
|
||
|
||
`@gromlab/svg-sprites` выполняет основную работу на этапе генерации и остаётся в `devDependencies`.
|
||
|
||
Production-компоненты используют только локальный generated-код, стили и внешний SVG-файл. Compiler и CLI не попадают в клиентское приложение, а `SpriteViewer` подключается отдельно только там, где нужна debug-страница.
|
||
|
||
## Документация
|
||
|
||
README знакомит с возможностями проекта и показывает основной сценарий использования. Для настройки выберите руководство под свой стек.
|
||
|
||
### Быстрый старт
|
||
|
||
- [Next.js App Router](docs/ru/next-app.md)
|
||
- [Next.js Pages Router](docs/ru/next-pages.md)
|
||
- [React + Vite](docs/ru/react-vite.md)
|
||
- [React + Webpack 5](docs/ru/react-webpack.md)
|
||
- [Нативный HTML и классические SVG-спрайты](docs/ru/legacy.md)
|
||
|
||
### Технические материалы
|
||
|
||
- [Технический справочник](docs/ru/reference.md)
|
||
- [Программный API](docs/ru/programmatic-api.md)
|
||
- [Миграция с 0.1.x](docs/ru/migration-1.md)
|
||
|
||
## Лицензия
|
||
|
||
MIT
|