# @gromlab/svg-sprites [πŸ‡¬πŸ‡§ English](README.md) | πŸ‡·πŸ‡Ί Русский ![npm](https://img.shields.io/npm/v/@gromlab/svg-sprites) ![license](https://img.shields.io/npm/l/@gromlab/svg-sprites) CLI для Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ SVG-спрайтов ΠΈ Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² ΠΈΠΊΠΎΠ½ΠΎΠΊ для React ΠΈ Next.js. ![Preview](https://raw.githubusercontent.com/gromov-sergei/svg-sprites/master/preview-image.png) ## Навигация - [ВозмоТности](#возмоТности) - [Π’Π°Π±Π»ΠΈΡ†Π° ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ](#Ρ‚Π°Π±Π»ΠΈΡ†Π°-ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ) - [ВрСбования](#трСбования) - [Быстрый старт](#быстрый-старт) - [React + Vite](docs/ru/react-vite.md) - [React + Webpack 5](docs/ru/react-webpack.md) - [Next.js App Router](docs/ru/next-app.md) - [Next.js Pages Router](docs/ru/next-pages.md) - [ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ](#конфигурация) - [React](#react) - [Next.js](#nextjs) - [ΠœΠ½ΠΎΠΆΠ΅ΡΡ‚Π²Π΅Π½Π½Ρ‹Π΅ спрайты](#мноТСствСнныС-спрайты) - [TypeScript](#typescript) - [Π€ΠΎΡ€ΠΌΠ°Ρ‚Ρ‹ спрайтов](#Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Ρ‹-спрайтов) - [Бпособы отобраТСния](#способы-отобраТСния) - [Врансформации](#трансформации) - [Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ†Π²Π΅Ρ‚ΠΎΠΌ ΠΈΠΊΠΎΠ½ΠΎΠΊ](#ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅-Ρ†Π²Π΅Ρ‚ΠΎΠΌ-ΠΈΠΊΠΎΠ½ΠΎΠΊ) - [ΠšΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅](#ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅) - [SpriteViewer](#spriteviewer) - [ΠœΠΈΠ³Ρ€Π°Ρ†ΠΈΡ с 0.1.x](docs/ru/migration-1.md) - [ДокумСнтация](#докумСнтация) ## ВозмоТности - **AI-agent friendly** β€” Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ содСрТит Π³ΠΎΡ‚ΠΎΠ²Ρ‹ΠΉ skill с Π°ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠΉ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠ΅ΠΉ для настройки, ΠΌΠΈΠ³Ρ€Π°Ρ†ΠΈΠΈ ΠΈ диагностики `@gromlab/svg-sprites`. - **TypeScript-friendly** β€” Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ React-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹, union-Ρ‚ΠΈΠΏΡ‹ ΠΈ runtime-списки доступных ΠΈΠΊΠΎΠ½ΠΎΠΊ. - **Чистая гСнСрация** β€” generated-Ρ„Π°ΠΉΠ»Ρ‹ автоматичСски ΠΈΡΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‚ΡΡ ΠΈΠ· Git, спрайт Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°Ρ‚ΡŒ Π² `public`, Π° Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ обновляСт Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°Ρ‰ΠΈΠ΅ Π΅ΠΌΡƒ Ρ„Π°ΠΉΠ»Ρ‹. - **ΠžΠ±Ρ‰ΠΈΠ΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ Π±Π΅Π· копирования** β€” SVG ΠΈΠ· локальной ΠΏΠ°ΠΏΠΊΠΈ ΠΈ `inputFiles` ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‚ΡΡ Π² ΠΎΠ΄ΠΈΠ½ спрайт; ΠΎΠ΄ΠΈΠ½ Ρ„Π°ΠΉΠ» ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… спрайтах. - **ВстроСнноС ΠΈΠ½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΠ΅ ΠΏΡ€Π΅Π²ΡŒΡŽ** β€” `` ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ ΠΊΠ°ΠΊ страница прилоТСния ΠΈ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Π΅ React- ΠΈ Next.js-спрайты с поиском, настройкой Ρ†Π²Π΅Ρ‚ΠΎΠ² ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°ΠΌΠΈ использования. - **НастраиваСмыС трансформации SVG** β€” ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ `width` ΠΈ `height` с сохранСниСм `viewBox`, Π·Π°ΠΌΠ΅Π½Π° исходных Ρ†Π²Π΅Ρ‚ΠΎΠ² Π½Π° CSS-ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΈ transitions для `fill` ΠΈ `stroke`. - **ΠžΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΊΠ΅ΡˆΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΉ SVG asset** β€” SVG path-Π΄Π°Π½Π½Ρ‹Π΅ Π½Π΅ ΠΏΠΎΠΏΠ°Π΄Π°ΡŽΡ‚ Π² JavaScript chunks, Π° сборщик выпускаСт Ρ„Π°ΠΉΠ» с content hash. - **ΠœΠ½ΠΎΠΆΠ΅ΡΡ‚Π²Π΅Π½Π½Ρ‹Π΅ спрайты** β€” нСзависимыС React- ΠΈ Next.js-ΠΌΠΎΠ΄ΡƒΠ»ΠΈ со своими ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°ΠΌΠΈ, Ρ‚ΠΈΠΏΠ°ΠΌΠΈ ΠΈ SVG assets. - **Server-first Next.js** β€” generated-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ Π² Server Components, SSR ΠΈ SSG Π±Π΅Π· Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΈΠ²Ρ‹ `'use client'`. - **Π€ΠΎΡ€ΠΌΠ°Ρ‚Ρ‹ ΠΏΠΎΠ΄ Ρ€Π°Π·Π½Ρ‹Π΅ сцСнарии** β€” React ΠΈ Next.js ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ `stack`, legacy-Ρ€Π΅ΠΆΠΈΠΌ Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ `symbol` для ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΉ. ## Π’Π°Π±Π»ΠΈΡ†Π° ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ | Π‘Ρ€Π΅Π΄Π° | ΠšΠ»ΡŽΡ‡ ΠΌΠΎΠ΄Π° API | Бтатус | |---|---|---| | React + Vite | `react@vite` | Π“ΠΎΡ‚ΠΎΠ²ΠΎ | | React + Webpack 5 | `react@webpack` | Π“ΠΎΡ‚ΠΎΠ²ΠΎ | | Next.js 16.2+ App Router + Turbopack | `next@app/turbopack` | Π“ΠΎΡ‚ΠΎΠ²ΠΎ | | Next.js 13.4+ App Router + Webpack 5 | `next@app/webpack` | Π“ΠΎΡ‚ΠΎΠ²ΠΎ | | Next.js 16.2+ Pages Router + Turbopack | `next@pages/turbopack` | Π“ΠΎΡ‚ΠΎΠ²ΠΎ | | Next.js 12.2+ Pages Router + Webpack 5 | `next@pages/webpack` | Π“ΠΎΡ‚ΠΎΠ²ΠΎ | | Vue | β€” | Π‘ΠΊΠΎΡ€ΠΎ | | Standalone | β€” | Π‘ΠΊΠΎΡ€ΠΎ | ## ВрСбования - Node.js 18 ΠΈΠ»ΠΈ Π½ΠΎΠ²Π΅Π΅; - ΠΏΠ°ΠΊΠ΅Ρ‚ распространяСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊΠ°ΠΊ ESM ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Ρ‡Π΅Ρ€Π΅Π· `import`; - React 18 ΠΈΠ»ΠΈ 19 трСбуСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для generated-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² ΠΈ Ρ‚ΠΎΡ‡ΠΊΠΈ Π²Ρ…ΠΎΠ΄Π° `@gromlab/svg-sprites/react`; - для Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΠΈ subpath exports ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ TypeScript 5+ с `moduleResolution: "bundler"`, `"node16"` ΠΈΠ»ΠΈ `"nodenext"`. ## Быстрый старт Для быстрого старта Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ΡΡŒ инструкциСй для вашСго стСка: - [React + Vite](docs/ru/react-vite.md) - [React + Webpack 5](docs/ru/react-webpack.md) - [Next.js App Router](docs/ru/next-app.md) - [Next.js Pages Router](docs/ru/next-pages.md) ## ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ ### React ```ts import { defineReactSpriteConfig } from '@gromlab/svg-sprites' export default defineReactSpriteConfig({ name: 'file-manager', description: 'Иконки Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠ³ΠΎ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Π°', inputFolder: './icons', inputFiles: [ '../../shared/icons/check.svg', ], transform: { removeSize: true, replaceColors: true, addTransition: true, }, generatedNotice: true, }) ``` | ΠžΠΏΡ†ΠΈΡ | Π’ΠΈΠΏ | По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ | НазначСниС | |---|---|---|---| | `name` | `string` | Имя ΠΏΠ°ΠΏΠΊΠΈ | Имя спрайта, ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° ΠΈ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² | | `description` | `string` | НСт | ОписаниС для Ρ‚ΠΈΠΏΠΎΠ² ΠΈ debug-манифСста | | `inputFolder` | `string` | `./icons` | Папка с исходными SVG ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΊΠΎΠ½Ρ„ΠΈΠ³Π° | | `inputFiles` | `string[]` | `[]` | Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ SVG-Ρ„Π°ΠΉΠ»Ρ‹ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΊΠΎΠ½Ρ„ΠΈΠ³Π° | | `transform` | `TransformOptions` | ВсС Π²ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ | [Настройки трансформации](#трансформации) исходных SVG | | `generatedNotice` | `boolean` | `true` | ПолноС Π»ΠΈΠ±ΠΎ ΠΊΠΎΡ€ΠΎΡ‚ΠΊΠΎΠ΅ ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅ Π² generated-Ρ„Π°ΠΉΠ»Π°Ρ… | `inputFolder` ΠΈ `inputFiles` ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‚ΡΡ Π² ΠΎΠ΄ΠΈΠ½ спрайт, поэтому ΠΎΠ΄ΠΈΠ½ SVG-Ρ„Π°ΠΉΠ» ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… спрайтах Π±Π΅Π· копирования. Если нСявной ΠΏΠ°ΠΏΠΊΠΈ `./icons` Π½Π΅Ρ‚, Π½ΠΎ `inputFiles` Π·Π°ΠΏΠΎΠ»Π½Π΅Π½, гСнСрация продолТаСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎ списку. Π―Π²Π½ΠΎ указанная ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π°Ρ ΠΏΠ°ΠΏΠΊΠ° считаСтся ошибкой. ΠžΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹Π΅ ΠΏΡƒΡ‚ΠΈ Π΄Π΅Π΄ΡƒΠΏΠ»ΠΈΡ†ΠΈΡ€ΡƒΡŽΡ‚ΡΡ, Π° Ρ€Π°Π·Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹ с ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹ΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ ΠΈΠΊΠΎΠ½ΠΊΠΈ ΡΡ‡ΠΈΡ‚Π°ΡŽΡ‚ΡΡ ошибкой. `name` записываСтся Π² kebab-case ΠΈ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π½Π°Ρ‡ΠΈΠ½Π°Ρ‚ΡŒΡΡ с латинской Π±ΡƒΠΊΠ²Ρ‹. React ΠΈ Next.js presets ΡΠΎΠ·Π΄Π°ΡŽΡ‚ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ `stack`. ### Next.js Next.js ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Ρ‚ΠΎΡ‚ ΠΆΠ΅ `svg-sprite.config.ts` ΠΈ Π½Π°Π±ΠΎΡ€ ΠΎΠΏΡ†ΠΈΠΉ. Для Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ Ρ…Π΅Π»ΠΏΠ΅Ρ€: ```ts import { defineNextSpriteConfig } from '@gromlab/svg-sprites' export default defineNextSpriteConfig({ name: 'file-manager', description: 'Иконки Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠ³ΠΎ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Π°', inputFolder: './icons', }) ``` Π ΠΎΡƒΡ‚Π΅Ρ€ ΠΈ сборщик Π²Ρ‹Π±ΠΈΡ€Π°ΡŽΡ‚ΡΡ Ρ‡Π΅Ρ€Π΅Π· mode key, поэтому ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΌΠ΅ΠΆΠ΄Ρƒ Turbopack ΠΈ Webpack всСгда явно ΠΎΡ‚Ρ€Π°ΠΆΠ΅Π½ΠΎ Π² ΠΊΠΎΠΌΠ°Π½Π΄Π΅ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ. ## ΠœΠ½ΠΎΠΆΠ΅ΡΡ‚Π²Π΅Π½Π½Ρ‹Π΅ спрайты ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ нСсколько нСзависимых спрайтов с Ρ€Π°Π·Π½ΠΎΠΉ ΠΎΠ±Π»Π°ΡΡ‚ΡŒΡŽ использования: **ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ°:** ΠΎΠ΄ΠΈΠ½ Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΉ спрайт Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ ΠΈΠΊΠΎΠ½ΠΊΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌΡƒ экрану Π½Π΅ Π½ΡƒΠΆΠ½Ρ‹. **РСшСниС:** ΠΎΠ±Ρ‰ΠΈΠ΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ глобально, Π° Π½Π°Π±ΠΎΡ€Ρ‹ страниц ΠΈ ΠΊΡ€ΡƒΠΏΠ½Ρ‹Ρ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² β€” Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… спрайтах, Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌΡ‹Ρ… вмСстС с Π½ΠΈΠΌΠΈ. ```text global β†’ GlobalIcon β†’ ΠΎΠ±Ρ‰ΠΈΠ΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ прилоТСния analytics-page β†’ AnalyticsPageIcon β†’ ΠΈΠΊΠΎΠ½ΠΊΠΈ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΉ страницы file-manager β†’ FileManagerIcon β†’ ΠΈΠΊΠΎΠ½ΠΊΠΈ ΠΊΡ€ΡƒΠΏΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° ``` - **Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΉ спрайт** содСрТит нСбольшиС ΠΎΠ±Ρ‰ΠΈΠ΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ Π² Ρ€Π°Π·Π½Ρ‹Ρ… частях прилоТСния: Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΡŽ, состояния ΠΈ Π±Π°Π·ΠΎΠ²Ρ‹Π΅ дСйствия. - **Π‘ΠΏΡ€Π°ΠΉΡ‚ страницы** загруТаСтся вмСстС с ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹ΠΌ Ρ€Π°Π·Π΄Π΅Π»ΠΎΠΌ ΠΈ Π½Π΅ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚ ΠΎΠ±Ρ‰ΠΈΠΉ спрайт ΠΈΠΊΠΎΠ½ΠΊΠ°ΠΌΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ большС Π½ΠΈΠ³Π΄Π΅ Π½Π΅ Π½ΡƒΠΆΠ½Ρ‹. - **Π‘ΠΏΡ€Π°ΠΉΡ‚ ΠΊΡ€ΡƒΠΏΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°** инкапсулируСт собствСнный Π½Π°Π±ΠΎΡ€ ΠΈΠΊΠΎΠ½ΠΎΠΊ слоТного UI-модуля, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠ³ΠΎ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Π° ΠΈΠ»ΠΈ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π°. КаТдая Π³Ρ€ΡƒΠΏΠΏΠ° ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚: - собствСнный SVG asset; - собствСнный Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚; - ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ список ΠΈΠΌΡ‘Π½ ΠΈΠΊΠΎΠ½ΠΎΠΊ; - ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ debug-манифСст; - нСзависимый cache lifecycle. ## TypeScript Главная Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ TypeScript API β€” Π°Π²Ρ‚ΠΎΠ΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΈΠΌΡ‘Π½ ΠΈΠΊΠΎΠ½ΠΎΠΊ нСпосрСдствСнно Π² prop `icon`: ```tsx // ↑ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€ ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚ всС ΠΈΠΊΠΎΠ½ΠΊΠΈ спрайта ``` ИмСна SVG-Ρ„Π°ΠΉΠ»ΠΎΠ² становятся допустимыми значСниями `icon`. ΠžΠΏΠ΅Ρ‡Π°Ρ‚ΠΊΠ° ΠΈΠ»ΠΈ нСизвСстноС имя сразу становятся ошибкой TypeScript: ```tsx // ошибка TypeScript ``` Для ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ доступа generated-ΠΌΠΎΠ΄ΡƒΠ»ΡŒ экспортируСт readonly-массив всСх доступных ΠΈΠΊΠΎΠ½ΠΎΠΊ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ спрайта: ```ts import { fileManagerIconNames } from './svg-sprite' // readonly ['check', 'folder', ...] ``` Π­Ρ‚ΠΎΡ‚ список ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² собствСнных ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π°Ρ…, select-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°Ρ…, тСстах ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΡ… runtime-сцСнариях. Из Π½Π΅Π³ΠΎ Ρ‚Π°ΠΊΠΆΠ΅ выводится union-Ρ‚ΠΈΠΏ `FileManagerIconName`. ИмСна Ρ„Π°ΠΉΠ»ΠΎΠ² с ΠΏΡ€ΠΎΠ±Π΅Π»Π°ΠΌΠΈ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ нСбСзопасными для SVG ID символами ΠΎΡΡ‚Π°ΡŽΡ‚ΡΡ Ρ‡Π°ΡΡ‚ΡŒΡŽ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½ΠΎΠ³ΠΎ TypeScript API. Для Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅Π³ΠΎ `` Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ создаёт ΡΡ‚Π°Π±ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ hash ID. ```text folder open.svg β†’ icon="folder open" β†’ id="icon-" ``` Для Ρ‚Π°ΠΊΠΈΡ… ΠΈΠΌΡ‘Π½ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ generated-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΈΠ»ΠΈ `id` ΠΈΠ· debug-манифСста. Π ΡƒΡ‡Π½Ρ‹Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ Π½ΠΈΠΆΠ΅ с `#<имя>` подходят Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для ΠΈΠΌΡ‘Π½, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡƒΠΆΠ΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ бСзопасными SVG ID. ## Π€ΠΎΡ€ΠΌΠ°Ρ‚Ρ‹ спрайтов `stack` β€” Π±ΠΎΠ»Π΅Π΅ соврСмСнный Ρ„ΠΎΡ€ΠΌΠ°Ρ‚, поэтому ΠΎΠ½ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ. Иконки ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Ρ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· ``, `` ΠΈ CSS `background-image`. `symbol` сохраняСтся для совмСстимости с ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌΠΈ интСграциями ΠΈ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Π΅Ρ€Π΅Π· ``. ## Бпособы отобраТСния ### React-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ β€” рСкомСндуСтся Generated-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ прСдоставляСт Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΡŽ, Π°Π²Ρ‚ΠΎΠ΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΈΠΌΡ‘Π½ ΠΈΠΊΠΎΠ½ΠΎΠΊ ΠΈ сам Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅Ρ‚ URL SVG asset. ```tsx ``` Π§Π΅Ρ€Π΅Π· `color` ΠΈ `--icon-color-N` доступны ΠΎΠ΄Π½ΠΎΡ†Π²Π΅Ρ‚Π½Ρ‹Π΅ ΠΈ ΠΌΠ½ΠΎΠ³ΠΎΡ†Π²Π΅Ρ‚Π½Ρ‹Π΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ. ### Π‘Π°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ Ρ‡Π΅Ρ€Π΅Π· `` Π₯ΠΎΡ€ΠΎΡˆΠΈΠΉ Π½ΠΈΠ·ΠΊΠΎΡƒΡ€ΠΎΠ²Π½Π΅Π²Ρ‹ΠΉ способ с ΠΏΠΎΠ»Π½Ρ‹ΠΌ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€Π°ΠΌΠΈ ΠΈ Ρ†Π²Π΅Ρ‚Π°ΠΌΠΈ. React-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΏΠΎΠ΄ ΠΊΠ°ΠΏΠΎΡ‚ΠΎΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΈΠΌΠ΅Π½Π½ΠΎ Π΅Π³ΠΎ. Бпособ получСния `spriteUrl` зависит ΠΎΡ‚ сборщика. **Vite:** ```tsx import spriteUrl from './svg-sprite/generated/sprite.svg?no-inline' ``` **Webpack 5:** ```tsx const spriteUrl = new URL( './svg-sprite/generated/sprite.svg', import.meta.url, ).href ``` **Next.js с Webpack 5 ΠΈΠ»ΠΈ Turbopack:** ```tsx const spriteUrl = new URL( './svg-sprite/generated/sprite.svg', import.meta.url, ).href ``` ПослС получСния URL ΠΈΠΊΠΎΠ½ΠΊΠ° отобраТаСтся ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΠΎ: ```tsx ``` Vite, Webpack 5 ΠΈ Next.js сами Π·Π°ΠΌΠ΅Π½ΡΡŽΡ‚ исходный ΠΏΡƒΡ‚ΡŒ Π½Π° ΠΈΡ‚ΠΎΠ³ΠΎΠ²Ρ‹ΠΉ URL asset с hash. ### Π§Π΅Ρ€Π΅Π· `` β€” ΠΌΠ΅Π½Π΅Π΅ эффСктивно ```tsx Π“ΠΎΡ‚ΠΎΠ²ΠΎ ``` SVG загруТаСтся ΠΊΠ°ΠΊ ΠΈΠ·ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅: ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π΅Π³ΠΎ Ρ†Π²Π΅Ρ‚Π° Ρ‡Π΅Ρ€Π΅Π· `color` ΠΈΠ»ΠΈ `--icon-color-N` нСльзя. ### Π§Π΅Ρ€Π΅Π· CSS `background-image` β€” ΠΌΠ΅Π½Π΅Π΅ эффСктивно ```css .icon { background: url('./svg-sprite/generated/sprite.svg#check') center / contain no-repeat; } ``` Как ΠΈ ``, этот способ Π½Π΅ позволяСт ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠΌΠΈ Ρ†Π²Π΅Ρ‚Π°ΠΌΠΈ SVG. ΠŸΡƒΡ‚ΡŒ указываСтся ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ CSS-Ρ„Π°ΠΉΠ»Π°, Π° Vite/Webpack замСняСт Π΅Π³ΠΎ Π½Π° ΠΈΡ‚ΠΎΠ³ΠΎΠ²Ρ‹ΠΉ URL с hash ΠΏΡ€ΠΈ сборкС. ### Π§Π΅Ρ€Π΅Π· CSS mask β€” ΠΌΠ΅Π½Π΅Π΅ эффСктивно ```css .icon { background-color: currentColor; mask: url('./svg-sprite/generated/sprite.svg#check') center / contain no-repeat; } ``` Mask оставляСт Ρ‚ΠΎΠ»ΡŒΠΊΠΎ силуэт ΠΈ ΠΎΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ Π΅Π³ΠΎ ΠΎΠ΄Π½ΠΈΠΌ Ρ†Π²Π΅Ρ‚ΠΎΠΌ. Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹Π΅ Ρ†Π²Π΅Ρ‚Π°, gradients ΠΈ различия ΠΌΠ΅ΠΆΠ΄Ρƒ `fill` ΠΈ `stroke` Ρ‚Π΅Ρ€ΡΡŽΡ‚ΡΡ. ## Врансформации ВсС трансформации Π²ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΈ Π½Π°ΡΡ‚Ρ€Π°ΠΈΠ²Π°ΡŽΡ‚ΡΡ нСзависимо Ρ‡Π΅Ρ€Π΅Π· `transform`. | ΠžΠΏΡ†ΠΈΡ | По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ | Π§Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ | |---|---|---| | `removeSize` | `true` | УдаляСт `width` ΠΈ `height` с ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ ``, сохраняя ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ `viewBox`. Π Π°Π·ΠΌΠ΅Ρ€ ΠΈΠΊΠΎΠ½ΠΊΠΈ послС этого задаётся снаруТи. | | `replaceColors` | `true` | ЗамСняСт Ρ†Π²Π΅Ρ‚Π° `fill` ΠΈ `stroke` Π½Π° `--icon-color-N`. Для ΠΎΠ΄Π½ΠΎΡ†Π²Π΅Ρ‚Π½ΠΎΠΉ ΠΈΠΊΠΎΠ½ΠΊΠΈ fallback становится `currentColor`, для ΠΌΠ½ΠΎΠ³ΠΎΡ†Π²Π΅Ρ‚Π½ΠΎΠΉ ΡΠΎΡ…Ρ€Π°Π½ΡΡŽΡ‚ΡΡ исходныС Ρ†Π²Π΅Ρ‚Π°. | | `addTransition` | `true` | ДобавляСт `style="transition:fill 0.3s,stroke 0.3s;"` нСпосрСдствСнно Ρ†Π²Π΅Ρ‚Π½Ρ‹ΠΌ элСмСнтам SVG. Π‘ΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ `transition` Π½Π΅ пСрСзаписываСтся. | Π§Ρ‚ΠΎΠ±Ρ‹ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅, ΠΏΠ΅Ρ€Π΅Π΄Π°ΠΉΡ‚Π΅ для ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΉ ΠΎΠΏΡ†ΠΈΠΈ `false`. ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ `replaceColors` β€” Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ [Β«Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ†Π²Π΅Ρ‚ΠΎΠΌ ΠΈΠΊΠΎΠ½ΠΎΠΊΒ»](#ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅-Ρ†Π²Π΅Ρ‚ΠΎΠΌ-ΠΈΠΊΠΎΠ½ΠΎΠΊ). ## Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ†Π²Π΅Ρ‚ΠΎΠΌ ΠΈΠΊΠΎΠ½ΠΎΠΊ ΠŸΡ€ΠΈ Π²ΠΊΠ»ΡŽΡ‡Ρ‘Π½Π½ΠΎΠΉ Π·Π°ΠΌΠ΅Π½Π΅ Ρ†Π²Π΅Ρ‚ΠΎΠ² Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ `fill` ΠΈ `stroke` ΠΈ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ ΠΈΡ… Π² CSS custom properties. ### ΠœΠΎΠ½ΠΎΡ…Ρ€ΠΎΠΌΠ½Ρ‹Π΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ Если Π½Π°ΠΉΠ΄Π΅Π½ ΠΎΠ΄ΠΈΠ½ Ρ†Π²Π΅Ρ‚, fallback замСняСтся Π½Π° `currentColor`: ```svg stroke="var(--icon-color-1, currentColor)" ``` Π¦Π²Π΅Ρ‚ΠΎΠΌ управляСт CSS-свойство `color` внСшнСго `` ΠΈΠ»ΠΈ Π΅Π³ΠΎ родитСля. ### ΠœΠ½ΠΎΠ³ΠΎΡ†Π²Π΅Ρ‚Π½Ρ‹Π΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ†Π²Π΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ с исходным fallback: ```svg fill="var(--icon-color-1, #798198)" fill="var(--icon-color-2, #ffffff)" fill="var(--icon-color-3, #129d9d)" ``` Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ Ρ†Π²Π΅Ρ‚Π°: ```css .icon { --icon-color-1: #4b5563; --icon-color-3: #14b8a6; } ``` ### ΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΡ Ρ†Π²Π΅Ρ‚ΠΎΠ² - `none`, `transparent`, `inherit`, `unset` ΠΈ `initial` Π½Π΅ Π·Π°ΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ; - Ρ†Π²Π΅Ρ‚Π° Π² Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π°Ρ… `fill`, `stroke` ΠΈ inline `style` ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ Π½Π°Π΄Ρ‘ΠΆΠ½Π΅Π΅ всСго; - CSS-классы ΠΈ внСшниС stylesheets Π²Π½ΡƒΡ‚Ρ€ΠΈ исходного SVG Π½Π΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ основным сцСнариСм трансформации; - gradients, patterns, filters ΠΈ значСния `url(#...)` Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΉ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ нСсовмСстимы с автоматичСской Π·Π°ΠΌΠ΅Π½ΠΎΠΉ Ρ†Π²Π΅Ρ‚ΠΎΠ²; - CSS-ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ страницы доступны ΠΏΡ€ΠΈ ``, Π½ΠΎ нСдоступны Π²Π½ΡƒΡ‚Ρ€ΠΈ `` ΠΈ `background-image`. ## ΠšΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Vite, Webpack ΠΈ Next.js target Π²Ρ‹ΠΏΡƒΡΠΊΠ°ΡŽΡ‚ спрайт ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΌ asset с content hash: ```text /assets/sprite-.svg ``` Π­Ρ‚ΠΎ Π΄Π°Ρ‘Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ свойства: - SVG ΠΊΠ΅ΡˆΠΈΡ€ΡƒΠ΅Ρ‚ΡΡ нСзависимо ΠΎΡ‚ JavaScript; - ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ React-ΠΊΠΎΠ΄Π° Π½Π΅ мСняСт содСрТимоС спрайта; - ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΈΠΊΠΎΠ½ΠΎΠΊ создаёт Π½ΠΎΠ²Ρ‹ΠΉ hash asset; - ΠΎΠ΄ΠΈΠ½ Ρ„Π°ΠΉΠ» ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ всСми экзСмплярами generated-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°; - SVG path-Π΄Π°Π½Π½Ρ‹Π΅ ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‚ Π² JavaScript chunks. Vite target Π·Π°ΠΏΡ€Π΅Ρ‰Π°Π΅Ρ‚ inline Ρ‡Π΅Ρ€Π΅Π· `?no-inline`. Webpack 5 target ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Asset Modules Ρ‡Π΅Ρ€Π΅Π· `new URL(..., import.meta.url)`. ## SpriteViewer `SpriteViewer` β€” React-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ для просмотра generated-спрайтов Π²Π½ΡƒΡ‚Ρ€ΠΈ debug-ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π° прилоТСния. Он ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ манифСсты ΠΈ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚: - Π³Ρ€ΡƒΠΏΠΏΡ‹ спрайтов; - список ΠΈ количСство ΠΈΠΊΠΎΠ½ΠΎΠΊ; - поиск ΠΈ ΡΠΈΡΡ‚Π΅ΠΌΠ½ΡƒΡŽ ΡΠ²Π΅Ρ‚Π»ΡƒΡŽ/Ρ‚Ρ‘ΠΌΠ½ΡƒΡŽ Ρ‚Π΅ΠΌΡƒ; - модальноС ΠΏΡ€Π΅Π²ΡŒΡŽ с `viewBox` ΠΈ настройкой Ρ†Π²Π΅Ρ‚ΠΎΠ²Ρ‹Ρ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…; - ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ React, SVG, IMG ΠΈ CSS с ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΠΊΠΎΠ΄Π°. Production-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ Π½Π΅ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ debug-манифСсты. Бпособ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ Viewer зависит ΠΎΡ‚ сборщика: - [React + Vite: автоматичСский `import.meta.glob`](docs/ru/react-vite.md#6-Π΄ΠΎΠ±Π°Π²ΡŒΡ‚Π΅-debug-страницу); - [React + Webpack 5: статичСскиС `import()`](docs/ru/react-webpack.md#6-Π΄ΠΎΠ±Π°Π²ΡŒΡ‚Π΅-debug-страницу); - [Next.js App Router](docs/ru/next-app.md#5-Π΄ΠΎΠ±Π°Π²ΡŒΡ‚Π΅-spriteviewer); - [Next.js Pages Router](docs/ru/next-pages.md#5-Π΄ΠΎΠ±Π°Π²ΡŒΡ‚Π΅-spriteviewer). Viewer ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ ΠΈΠ· ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΉ клиСнтской Ρ‚ΠΎΡ‡ΠΊΠΈ Π²Ρ…ΠΎΠ΄Π° `@gromlab/svg-sprites/react` ΠΈ Π½Π΅ ΠΏΠΎΠΏΠ°Π΄Π°Π΅Ρ‚ Π² production-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ ΠΈΠΊΠΎΠ½ΠΎΠΊ. ### Π’Π΅ΠΌΠ° Viewer По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ `colorTheme="auto"`: Viewer слСдуСт `prefers-color-scheme` ΠΈ Ρ€Π΅Π°Π³ΠΈΡ€ΡƒΠ΅Ρ‚ Π½Π° смСну систСмной Ρ‚Π΅ΠΌΡ‹. Π’Π΅ΠΌΡƒ прилоТСния ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ явно: ```tsx ``` ДопустимыС значСния `colorTheme`: `auto`, `light`, `dark`. ΠŸΡ€ΠΈ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠΈ Ρ‚Π΅ΠΌΠΎΠΉ ΠΈΠ·Π²Π½Π΅ встроСнный ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π°Ρ‚Π΅Π»ΡŒ скрываСтся. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π΅Π³ΠΎ ΠΈ ΠΎΠ±Π½ΠΎΠ²Π»ΡΡ‚ΡŒ Ρ‚Π΅ΠΌΡƒ прилоТСния Ρ‡Π΅Ρ€Π΅Π· Viewer, ΠΏΠ΅Ρ€Π΅Π΄Π°ΠΉΡ‚Π΅ callback: ```tsx ``` ## ДокумСнтация - [React + Vite](docs/ru/react-vite.md) - [React + Webpack 5](docs/ru/react-webpack.md) - [Next.js App Router](docs/ru/next-app.md) - [Next.js Pages Router](docs/ru/next-pages.md) - [Legacy mode](docs/ru/legacy.md) - [ΠœΠΈΠ³Ρ€Π°Ρ†ΠΈΡ с 0.1.x](docs/ru/migration-1.md) - [ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ API](docs/ru/programmatic-api.md) ## ЛицСнзия MIT