diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..943b597 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,42 @@ +name: CI + +on: + push: + branches: + - master + pull_request: + branches: + - master + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + verify: + name: Verify and build + runs-on: ubuntu-latest + timeout-minutes: 30 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 24 + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Verify + run: npm run verify + + - name: Build + run: npm run build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..7bfa20f --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,107 @@ +name: Release + +on: + release: + types: + - published + +permissions: + contents: write + id-token: write + +concurrency: + group: release-${{ github.event.release.tag_name }} + cancel-in-progress: false + +jobs: + publish: + name: Publish package and skills + runs-on: ubuntu-latest + timeout-minutes: 30 + environment: npm + + steps: + - name: Checkout release tag + uses: actions/checkout@v4 + with: + ref: ${{ github.event.release.tag_name }} + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 24 + cache: npm + + - name: Update npm + run: npm install --global npm@latest + + - name: Check release version + env: + RELEASE_TAG: ${{ github.event.release.tag_name }} + run: | + node --input-type=module -e ' + import { readFileSync } from "node:fs" + + const packageJson = JSON.parse(readFileSync("package.json", "utf8")) + const expectedTag = `v${packageJson.version}` + + if (process.env.RELEASE_TAG !== expectedTag) { + throw new Error( + `Release tag ${process.env.RELEASE_TAG} does not match package version ${expectedTag}`, + ) + } + ' + + - name: Install dependencies + run: npm ci + + - name: Verify + run: npm run verify + + - name: Build package + run: npm run build + + - name: Build skills + run: npm run build:skill + + - name: Prepare release files + run: mkdir release + + - name: Pack npm package + run: npm pack --ignore-scripts --pack-destination release + + - name: Pack skills + working-directory: skills/artifacts + run: | + zip -r ../../release/svg-sprites.zip svg-sprites + zip -r ../../release/svg-sprites-ru.zip svg-sprites-ru + + - name: Create checksums + run: sha256sum release/* > release/SHA256SUMS + + - name: Publish npm package + env: + IS_PRERELEASE: ${{ github.event.release.prerelease }} + run: | + PACKAGE_SPEC=$(node -p "const pkg = require('./package.json'); pkg.name + '@' + pkg.version") + + if npm view "$PACKAGE_SPEC" version --json > /dev/null 2>&1; then + echo "$PACKAGE_SPEC is already published" + exit 0 + fi + + DIST_TAG=latest + if [ "$IS_PRERELEASE" = "true" ]; then + DIST_TAG=next + fi + + npm publish release/*.tgz --access public --provenance --tag "$DIST_TAG" + + - name: Upload GitHub Release assets + uses: softprops/action-gh-release@v2 + with: + files: | + release/*.tgz + release/*.zip + release/SHA256SUMS + overwrite_files: true diff --git a/README.md b/README.md index 8242cc9..c23d2d0 100644 --- a/README.md +++ b/README.md @@ -1,77 +1,80 @@ # @gromlab/svg-sprites +πŸ‡¬πŸ‡§ English | [πŸ‡·πŸ‡Ί Русский](README_RU.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. +A CLI for generating SVG sprites and typed icon components for React and Next.js. -![Preview](https://gromlab.ru/gromov/svg-sprites/media/branch/master/preview-image.png) +![Preview](https://raw.githubusercontent.com/gromov-sergei/svg-sprites/master/preview-image.png) -## Навигация +## Navigation -- [ВозмоТности](#возмоТности) -- [Π’Π°Π±Π»ΠΈΡ†Π° ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ](#Ρ‚Π°Π±Π»ΠΈΡ†Π°-ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ) -- [ВрСбования](#трСбования) -- [Быстрый старт](#быстрый-старт) - - [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) -- [ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ](#конфигурация) +- [Features](#features) +- [Support matrix](#support-matrix) +- [Requirements](#requirements) +- [Quick start](#quick-start) + - [React + Vite](docs/en/react-vite.md) + - [React + Webpack 5](docs/en/react-webpack.md) + - [Next.js App Router](docs/en/next-app.md) + - [Next.js Pages Router](docs/en/next-pages.md) +- [Configuration](#configuration) - [React](#react) - [Next.js](#nextjs) -- [ΠœΠ½ΠΎΠΆΠ΅ΡΡ‚Π²Π΅Π½Π½Ρ‹Π΅ спрайты](#мноТСствСнныС-спрайты) +- [Multiple sprites](#multiple-sprites) - [TypeScript](#typescript) -- [Π€ΠΎΡ€ΠΌΠ°Ρ‚Ρ‹ спрайтов](#Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Ρ‹-спрайтов) -- [Бпособы отобраТСния](#способы-отобраТСния) -- [Врансформации](#трансформации) -- [Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ†Π²Π΅Ρ‚ΠΎΠΌ ΠΈΠΊΠΎΠ½ΠΎΠΊ](#ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅-Ρ†Π²Π΅Ρ‚ΠΎΠΌ-ΠΈΠΊΠΎΠ½ΠΎΠΊ) -- [ΠšΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅](#ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅) +- [Sprite formats](#sprite-formats) +- [Rendering methods](#rendering-methods) +- [Transformations](#transformations) +- [Icon color management](#icon-color-management) +- [Caching](#caching) - [SpriteViewer](#spriteviewer) -- [ΠœΠΈΠ³Ρ€Π°Ρ†ΠΈΡ с 0.1.x](docs/ru/migration-1.md) -- [ДокумСнтация](#докумСнтация) +- [Migrating from 0.1.x](docs/en/migration-1.md) +- [Documentation](#documentation) -## ВозмоТности +## Features -- **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` для ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΉ. +- **AI-agent friendly** - the repository includes a ready-to-use skill with up-to-date documentation for configuring, migrating, and troubleshooting `@gromlab/svg-sprites`. +- **TypeScript-friendly** - typed React components, union types, and runtime lists of available icons. +- **Clean generation** - generated files are automatically excluded from Git, the sprite does not need to be placed in `public` manually, and the generator updates only files it owns. +- **Shared icons without copying** - SVGs from the local folder and `inputFiles` are merged into a single sprite; one file can be used in multiple sprites. +- **Built-in interactive preview** - `` is integrated as an application page and displays the provided React and Next.js sprites with search, color controls, and usage examples. +- **Configurable SVG transformations** - remove `width` and `height` while preserving `viewBox`, replace source colors with CSS variables, and add transitions for `fill` and `stroke`. +- **Separate cacheable SVG asset** - SVG path data does not end up in JavaScript chunks, and the bundler emits a file with a content hash. +- **Multiple sprites** - independent React and Next.js modules with their own components, types, and SVG assets. +- **Server-first Next.js** - generated components work in Server Components, SSR, and SSG without the `'use client'` directive. +- **Formats for different use cases** - React and Next.js use `stack`; legacy mode also supports `symbol` for existing integrations. -## Π’Π°Π±Π»ΠΈΡ†Π° ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ +## Support matrix -| Π‘Ρ€Π΅Π΄Π° | ΠšΠ»ΡŽΡ‡ ΠΌΠΎΠ΄Π° API | Бтатус | +| Environment | API mode key | Status | |---|---|---| -| 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 | β€” | Π‘ΠΊΠΎΡ€ΠΎ | +| React + Vite | `react@vite` | Ready | +| React + Webpack 5 | `react@webpack` | Ready | +| Next.js 16.2+ App Router + Turbopack | `next@app/turbopack` | Ready | +| Next.js 13.4+ App Router + Webpack 5 | `next@app/webpack` | Ready | +| Next.js 16.2+ Pages Router + Turbopack | `next@pages/turbopack` | Ready | +| Next.js 12.2+ Pages Router + Webpack 5 | `next@pages/webpack` | Ready | +| Vue | - | Coming soon | +| Standalone | - | Coming soon | -## ВрСбования +## Requirements -- Node.js 18 ΠΈΠ»ΠΈ Π½ΠΎΠ²Π΅Π΅; -- ΠΏΠ°ΠΊΠ΅Ρ‚ распространяСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊΠ°ΠΊ ESM ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Ρ‡Π΅Ρ€Π΅Π· `import`; -- React 18 ΠΈΠ»ΠΈ 19 трСбуСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для generated-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² ΠΈ Ρ‚ΠΎΡ‡ΠΊΠΈ Π²Ρ…ΠΎΠ΄Π° `@gromlab/svg-sprites/react`; -- для Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΠΈ subpath exports ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ TypeScript 5+ с `moduleResolution: "bundler"`, `"node16"` ΠΈΠ»ΠΈ `"nodenext"`. +- Node.js 18 or newer; +- the package is distributed as ESM only and is loaded via `import`; +- React 18 or 19 is required only for generated components and the `@gromlab/svg-sprites/react` entry point; +- for subpath export typings, use TypeScript 5+ with `moduleResolution: "bundler"`, `"node16"`, or `"nodenext"`. -## Быстрый старт +## Quick start -Для быстрого старта Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ΡΡŒ инструкциСй для вашСго стСка: +For a quick start, follow the guide for your stack: -- [React + Vite](docs/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 + Vite](docs/en/react-vite.md) +- [React + Webpack 5](docs/en/react-webpack.md) +- [Next.js App Router](docs/en/next-app.md) +- [Next.js Pages Router](docs/en/next-pages.md) -## ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ +## Configuration ### React @@ -80,7 +83,7 @@ import { defineReactSpriteConfig } from '@gromlab/svg-sprites' export default defineReactSpriteConfig({ name: 'file-manager', - description: 'Иконки Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠ³ΠΎ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Π°', + description: 'File manager icons', inputFolder: './icons', inputFiles: [ '../../shared/icons/check.svg', @@ -94,78 +97,78 @@ export default defineReactSpriteConfig({ }) ``` -| ΠžΠΏΡ†ΠΈΡ | Π’ΠΈΠΏ | По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ | НазначСниС | +| Option | Type | Default | Purpose | |---|---|---|---| -| `name` | `string` | Имя ΠΏΠ°ΠΏΠΊΠΈ | Имя спрайта, ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° ΠΈ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² | -| `description` | `string` | НСт | ОписаниС для Ρ‚ΠΈΠΏΠΎΠ² ΠΈ debug-манифСста | -| `inputFolder` | `string` | `./icons` | Папка с исходными SVG ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΊΠΎΠ½Ρ„ΠΈΠ³Π° | -| `inputFiles` | `string[]` | `[]` | Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ SVG-Ρ„Π°ΠΉΠ»Ρ‹ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΊΠΎΠ½Ρ„ΠΈΠ³Π° | -| `transform` | `TransformOptions` | ВсС Π²ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ | [Настройки трансформации](#трансформации) исходных SVG | -| `generatedNotice` | `boolean` | `true` | ПолноС Π»ΠΈΠ±ΠΎ ΠΊΠΎΡ€ΠΎΡ‚ΠΊΠΎΠ΅ ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅ Π² generated-Ρ„Π°ΠΉΠ»Π°Ρ… | +| `name` | `string` | Folder name | Name of the sprite, component, and public types | +| `description` | `string` | None | Description for types and the debug manifest | +| `inputFolder` | `string` | `./icons` | Folder containing source SVGs, relative to the config | +| `inputFiles` | `string[]` | `[]` | Additional SVG files, relative to the config | +| `transform` | `TransformOptions` | All enabled | [Transformation settings](#transformations) for source SVGs | +| `generatedNotice` | `boolean` | `true` | Full or short warning in generated files | -`inputFolder` ΠΈ `inputFiles` ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‚ΡΡ Π² ΠΎΠ΄ΠΈΠ½ спрайт, поэтому ΠΎΠ΄ΠΈΠ½ SVG-Ρ„Π°ΠΉΠ» ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… спрайтах Π±Π΅Π· копирования. Если нСявной ΠΏΠ°ΠΏΠΊΠΈ `./icons` Π½Π΅Ρ‚, Π½ΠΎ `inputFiles` Π·Π°ΠΏΠΎΠ»Π½Π΅Π½, гСнСрация продолТаСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎ списку. Π―Π²Π½ΠΎ указанная ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π°Ρ ΠΏΠ°ΠΏΠΊΠ° считаСтся ошибкой. ΠžΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹Π΅ ΠΏΡƒΡ‚ΠΈ Π΄Π΅Π΄ΡƒΠΏΠ»ΠΈΡ†ΠΈΡ€ΡƒΡŽΡ‚ΡΡ, Π° Ρ€Π°Π·Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹ с ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹ΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ ΠΈΠΊΠΎΠ½ΠΊΠΈ ΡΡ‡ΠΈΡ‚Π°ΡŽΡ‚ΡΡ ошибкой. +`inputFolder` and `inputFiles` are merged into a single sprite, so one SVG file can be used in multiple sprites without copying. If the implicit `./icons` folder does not exist but `inputFiles` is populated, generation continues using only the list. An explicitly specified missing folder is an error. Duplicate paths are deduplicated, while different files with the same icon name are treated as an error. -`name` записываСтся Π² kebab-case ΠΈ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π½Π°Ρ‡ΠΈΠ½Π°Ρ‚ΡŒΡΡ с латинской Π±ΡƒΠΊΠ²Ρ‹. React ΠΈ Next.js presets ΡΠΎΠ·Π΄Π°ΡŽΡ‚ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ `stack`. +`name` is stored in kebab-case and must start with a Latin letter. The React and Next.js presets produce the `stack` format. ### Next.js -Next.js ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Ρ‚ΠΎΡ‚ ΠΆΠ΅ `svg-sprite.config.ts` ΠΈ Π½Π°Π±ΠΎΡ€ ΠΎΠΏΡ†ΠΈΠΉ. Для Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ Ρ…Π΅Π»ΠΏΠ΅Ρ€: +Next.js uses the same `svg-sprite.config.ts` and set of options. For type checking, you can use a dedicated helper: ```ts import { defineNextSpriteConfig } from '@gromlab/svg-sprites' export default defineNextSpriteConfig({ name: 'file-manager', - description: 'Иконки Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠ³ΠΎ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Π°', + description: 'File manager icons', inputFolder: './icons', }) ``` -Π ΠΎΡƒΡ‚Π΅Ρ€ ΠΈ сборщик Π²Ρ‹Π±ΠΈΡ€Π°ΡŽΡ‚ΡΡ Ρ‡Π΅Ρ€Π΅Π· mode key, поэтому ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΌΠ΅ΠΆΠ΄Ρƒ Turbopack ΠΈ Webpack всСгда явно ΠΎΡ‚Ρ€Π°ΠΆΠ΅Π½ΠΎ Π² ΠΊΠΎΠΌΠ°Π½Π΄Π΅ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ. +The router and bundler are selected through the mode key, so switching between Turbopack and Webpack is always explicitly reflected in the generation command. -## ΠœΠ½ΠΎΠΆΠ΅ΡΡ‚Π²Π΅Π½Π½Ρ‹Π΅ спрайты +## Multiple sprites -ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ нСсколько нСзависимых спрайтов с Ρ€Π°Π·Π½ΠΎΠΉ ΠΎΠ±Π»Π°ΡΡ‚ΡŒΡŽ использования: +An application can contain several independent sprites for different scopes: -**ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ°:** ΠΎΠ΄ΠΈΠ½ Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΉ спрайт Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ ΠΈΠΊΠΎΠ½ΠΊΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌΡƒ экрану Π½Π΅ Π½ΡƒΠΆΠ½Ρ‹. +**Problem:** one global sprite loads icons that the current screen does not need. -**РСшСниС:** ΠΎΠ±Ρ‰ΠΈΠ΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ глобально, Π° Π½Π°Π±ΠΎΡ€Ρ‹ страниц ΠΈ ΠΊΡ€ΡƒΠΏΠ½Ρ‹Ρ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² β€” Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… спрайтах, Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌΡ‹Ρ… вмСстС с Π½ΠΈΠΌΠΈ. +**Solution:** keep shared icons globally, and place icon sets for pages and large components in separate sprites that load alongside them. ```text -global β†’ GlobalIcon β†’ ΠΎΠ±Ρ‰ΠΈΠ΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ прилоТСния -analytics-page β†’ AnalyticsPageIcon β†’ ΠΈΠΊΠΎΠ½ΠΊΠΈ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΉ страницы -file-manager β†’ FileManagerIcon β†’ ΠΈΠΊΠΎΠ½ΠΊΠΈ ΠΊΡ€ΡƒΠΏΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° +global -> GlobalIcon -> shared application icons +analytics-page -> AnalyticsPageIcon -> icons for a specific page +file-manager -> FileManagerIcon -> icons for a large component ``` -- **Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΉ спрайт** содСрТит нСбольшиС ΠΎΠ±Ρ‰ΠΈΠ΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ Π² Ρ€Π°Π·Π½Ρ‹Ρ… частях прилоТСния: Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΡŽ, состояния ΠΈ Π±Π°Π·ΠΎΠ²Ρ‹Π΅ дСйствия. -- **Π‘ΠΏΡ€Π°ΠΉΡ‚ страницы** загруТаСтся вмСстС с ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹ΠΌ Ρ€Π°Π·Π΄Π΅Π»ΠΎΠΌ ΠΈ Π½Π΅ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚ ΠΎΠ±Ρ‰ΠΈΠΉ спрайт ΠΈΠΊΠΎΠ½ΠΊΠ°ΠΌΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ большС Π½ΠΈΠ³Π΄Π΅ Π½Π΅ Π½ΡƒΠΆΠ½Ρ‹. -- **Π‘ΠΏΡ€Π°ΠΉΡ‚ ΠΊΡ€ΡƒΠΏΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°** инкапсулируСт собствСнный Π½Π°Π±ΠΎΡ€ ΠΈΠΊΠΎΠ½ΠΎΠΊ слоТного UI-модуля, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠ³ΠΎ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Π° ΠΈΠ»ΠΈ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π°. +- **Global sprite** contains a small set of shared icons used in different parts of the application: navigation, states, and basic actions. +- **Page sprite** loads with a specific section and does not increase the shared sprite with icons that are not needed anywhere else. +- **Large component sprite** encapsulates the icon set of a complex UI module, such as a file manager or editor. -КаТдая Π³Ρ€ΡƒΠΏΠΏΠ° ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚: +Each group gets: -- собствСнный SVG asset; -- собствСнный Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚; -- ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ список ΠΈΠΌΡ‘Π½ ΠΈΠΊΠΎΠ½ΠΎΠΊ; -- ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ debug-манифСст; -- нСзависимый cache lifecycle. +- its own SVG asset; +- its own typed component; +- a separate list of icon names; +- a separate debug manifest; +- an independent cache lifecycle. ## TypeScript -Главная Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ TypeScript API β€” Π°Π²Ρ‚ΠΎΠ΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΈΠΌΡ‘Π½ ΠΈΠΊΠΎΠ½ΠΎΠΊ нСпосрСдствСнно Π² prop `icon`: +The main feature of the TypeScript API is icon name autocomplete directly in the `icon` prop: ```tsx -// ↑ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€ ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚ всС ΠΈΠΊΠΎΠ½ΠΊΠΈ спрайта +// ^ the editor suggests every icon in the sprite ``` -ИмСна SVG-Ρ„Π°ΠΉΠ»ΠΎΠ² становятся допустимыми значСниями `icon`. ΠžΠΏΠ΅Ρ‡Π°Ρ‚ΠΊΠ° ΠΈΠ»ΠΈ нСизвСстноС имя сразу становятся ошибкой TypeScript: +SVG file names become valid `icon` values. A typo or unknown name immediately becomes a TypeScript error: ```tsx - // ошибка TypeScript + // TypeScript error ``` -Для ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ доступа generated-ΠΌΠΎΠ΄ΡƒΠ»ΡŒ экспортируСт readonly-массив всСх доступных ΠΈΠΊΠΎΠ½ΠΎΠΊ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ спрайта: +For programmatic access, the generated module exports a readonly array of all icons available in a specific sprite: ```ts import { fileManagerIconNames } from './svg-sprite' @@ -173,39 +176,39 @@ import { fileManagerIconNames } from './svg-sprite' // readonly ['check', 'folder', ...] ``` -Π­Ρ‚ΠΎΡ‚ список ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² собствСнных ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π°Ρ…, select-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°Ρ…, тСстах ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΡ… runtime-сцСнариях. Из Π½Π΅Π³ΠΎ Ρ‚Π°ΠΊΠΆΠ΅ выводится union-Ρ‚ΠΈΠΏ `FileManagerIconName`. +You can use this list in custom catalogs, select components, tests, and other runtime scenarios. The `FileManagerIconName` union type is also derived from it. -ИмСна Ρ„Π°ΠΉΠ»ΠΎΠ² с ΠΏΡ€ΠΎΠ±Π΅Π»Π°ΠΌΠΈ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ нСбСзопасными для SVG ID символами ΠΎΡΡ‚Π°ΡŽΡ‚ΡΡ Ρ‡Π°ΡΡ‚ΡŒΡŽ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½ΠΎΠ³ΠΎ TypeScript API. Для Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅Π³ΠΎ `` Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ создаёт ΡΡ‚Π°Π±ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ hash ID. +File names containing spaces and other characters unsafe for SVG IDs remain part of the public TypeScript API. For the internal ``, the generator creates a stable hash ID. ```text -folder open.svg β†’ icon="folder open" β†’ id="icon-" +folder open.svg -> icon="folder open" -> id="icon-" ``` -Для Ρ‚Π°ΠΊΠΈΡ… ΠΈΠΌΡ‘Π½ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ generated-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΈΠ»ΠΈ `id` ΠΈΠ· debug-манифСста. Π ΡƒΡ‡Π½Ρ‹Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ Π½ΠΈΠΆΠ΅ с `#<имя>` подходят Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для ΠΈΠΌΡ‘Π½, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡƒΠΆΠ΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ бСзопасными SVG ID. +For such names, use the generated component or the `id` from the debug manifest. The manual examples below using `#` are suitable only for names that are already safe SVG IDs. -## Π€ΠΎΡ€ΠΌΠ°Ρ‚Ρ‹ спрайтов +## Sprite formats -`stack` β€” Π±ΠΎΠ»Π΅Π΅ соврСмСнный Ρ„ΠΎΡ€ΠΌΠ°Ρ‚, поэтому ΠΎΠ½ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ. Иконки ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Ρ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· ``, `` ΠΈ CSS `background-image`. +`stack` is the more modern format, so it is used by default. Icons can be rendered through ``, ``, and CSS `background-image`. -`symbol` сохраняСтся для совмСстимости с ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌΠΈ интСграциями ΠΈ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Π΅Ρ€Π΅Π· ``. +`symbol` is retained for compatibility with existing integrations and supports rendering only through ``. -## Бпособы отобраТСния +## Rendering methods -### React-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ β€” рСкомСндуСтся +### React component - recommended -Generated-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ прСдоставляСт Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΡŽ, Π°Π²Ρ‚ΠΎΠ΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΈΠΌΡ‘Π½ ΠΈΠΊΠΎΠ½ΠΎΠΊ ΠΈ сам Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅Ρ‚ URL SVG asset. +The generated component provides type safety and icon name autocomplete, and constructs the SVG asset URL itself. ```tsx ``` -Π§Π΅Ρ€Π΅Π· `color` ΠΈ `--icon-color-N` доступны ΠΎΠ΄Π½ΠΎΡ†Π²Π΅Ρ‚Π½Ρ‹Π΅ ΠΈ ΠΌΠ½ΠΎΠ³ΠΎΡ†Π²Π΅Ρ‚Π½Ρ‹Π΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ. +Monochrome and multicolor icons are supported through `color` and `--icon-color-N`. -### Π‘Π°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ Ρ‡Π΅Ρ€Π΅Π· `` +### Manually with `` -Π₯ΠΎΡ€ΠΎΡˆΠΈΠΉ Π½ΠΈΠ·ΠΊΠΎΡƒΡ€ΠΎΠ²Π½Π΅Π²Ρ‹ΠΉ способ с ΠΏΠΎΠ»Π½Ρ‹ΠΌ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€Π°ΠΌΠΈ ΠΈ Ρ†Π²Π΅Ρ‚Π°ΠΌΠΈ. React-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΏΠΎΠ΄ ΠΊΠ°ΠΏΠΎΡ‚ΠΎΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΈΠΌΠ΅Π½Π½ΠΎ Π΅Π³ΠΎ. +A good low-level method that provides full control over dimensions and colors. This is exactly what the React component uses under the hood. -Бпособ получСния `spriteUrl` зависит ΠΎΡ‚ сборщика. +How you obtain `spriteUrl` depends on the bundler. **Vite:** @@ -222,7 +225,7 @@ const spriteUrl = new URL( ).href ``` -**Next.js с Webpack 5 ΠΈΠ»ΠΈ Turbopack:** +**Next.js with Webpack 5 or Turbopack:** ```tsx const spriteUrl = new URL( @@ -231,7 +234,7 @@ const spriteUrl = new URL( ).href ``` -ПослС получСния URL ΠΈΠΊΠΎΠ½ΠΊΠ° отобраТаСтся ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΠΎ: +After obtaining the URL, the icon is rendered the same way: ```tsx @@ -239,17 +242,17 @@ const spriteUrl = new URL( ``` -Vite, Webpack 5 ΠΈ Next.js сами Π·Π°ΠΌΠ΅Π½ΡΡŽΡ‚ исходный ΠΏΡƒΡ‚ΡŒ Π½Π° ΠΈΡ‚ΠΎΠ³ΠΎΠ²Ρ‹ΠΉ URL asset с hash. +Vite, Webpack 5, and Next.js replace the source path with the final hashed asset URL automatically. -### Π§Π΅Ρ€Π΅Π· `` β€” ΠΌΠ΅Π½Π΅Π΅ эффСктивно +### With `` - less efficient ```tsx -Π“ΠΎΡ‚ΠΎΠ²ΠΎ +Done ``` -SVG загруТаСтся ΠΊΠ°ΠΊ ΠΈΠ·ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅: ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π΅Π³ΠΎ Ρ†Π²Π΅Ρ‚Π° Ρ‡Π΅Ρ€Π΅Π· `color` ΠΈΠ»ΠΈ `--icon-color-N` нСльзя. +The SVG loads as an isolated image: its colors cannot be changed through `color` or `--icon-color-N`. -### Π§Π΅Ρ€Π΅Π· CSS `background-image` β€” ΠΌΠ΅Π½Π΅Π΅ эффСктивно +### With CSS `background-image` - less efficient ```css .icon { @@ -257,9 +260,9 @@ SVG загруТаСтся ΠΊΠ°ΠΊ ΠΈΠ·ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ } ``` -Как ΠΈ ``, этот способ Π½Π΅ позволяСт ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠΌΠΈ Ρ†Π²Π΅Ρ‚Π°ΠΌΠΈ SVG. ΠŸΡƒΡ‚ΡŒ указываСтся ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ CSS-Ρ„Π°ΠΉΠ»Π°, Π° Vite/Webpack замСняСт Π΅Π³ΠΎ Π½Π° ΠΈΡ‚ΠΎΠ³ΠΎΠ²Ρ‹ΠΉ URL с hash ΠΏΡ€ΠΈ сборкС. +Like ``, this method does not allow you to control internal SVG colors. The path is specified relative to the CSS file, and Vite/Webpack replaces it with the final hashed URL during the build. -### Π§Π΅Ρ€Π΅Π· CSS mask β€” ΠΌΠ΅Π½Π΅Π΅ эффСктивно +### With CSS mask - less efficient ```css .icon { @@ -268,37 +271,37 @@ SVG загруТаСтся ΠΊΠ°ΠΊ ΠΈΠ·ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ } ``` -Mask оставляСт Ρ‚ΠΎΠ»ΡŒΠΊΠΎ силуэт ΠΈ ΠΎΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ Π΅Π³ΠΎ ΠΎΠ΄Π½ΠΈΠΌ Ρ†Π²Π΅Ρ‚ΠΎΠΌ. Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹Π΅ Ρ†Π²Π΅Ρ‚Π°, gradients ΠΈ различия ΠΌΠ΅ΠΆΠ΄Ρƒ `fill` ΠΈ `stroke` Ρ‚Π΅Ρ€ΡΡŽΡ‚ΡΡ. +A mask retains only the silhouette and colors it with a single color. The original colors, gradients, and distinctions between `fill` and `stroke` are lost. -## Врансформации +## Transformations -ВсС трансформации Π²ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΈ Π½Π°ΡΡ‚Ρ€Π°ΠΈΠ²Π°ΡŽΡ‚ΡΡ нСзависимо Ρ‡Π΅Ρ€Π΅Π· `transform`. +All transformations are enabled by default and configured independently through `transform`. -| ΠžΠΏΡ†ΠΈΡ | По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ | Π§Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ | +| Option | Default | What it does | |---|---|---| -| `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` Π½Π΅ пСрСзаписываСтся. | +| `removeSize` | `true` | Removes `width` and `height` from the root `` while preserving the existing `viewBox`. The icon size is then set externally. | +| `replaceColors` | `true` | Replaces `fill` and `stroke` colors with `--icon-color-N`. For a monochrome icon, the fallback becomes `currentColor`; for a multicolor icon, the original colors are preserved. | +| `addTransition` | `true` | Adds `style="transition:fill 0.3s,stroke 0.3s;"` directly to colored SVG elements. An existing `transition` is not overwritten. | -Π§Ρ‚ΠΎΠ±Ρ‹ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅, ΠΏΠ΅Ρ€Π΅Π΄Π°ΠΉΡ‚Π΅ для ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΉ ΠΎΠΏΡ†ΠΈΠΈ `false`. ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ `replaceColors` β€” Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ [Β«Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ†Π²Π΅Ρ‚ΠΎΠΌ ΠΈΠΊΠΎΠ½ΠΎΠΊΒ»](#ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅-Ρ†Π²Π΅Ρ‚ΠΎΠΌ-ΠΈΠΊΠΎΠ½ΠΎΠΊ). +To disable a transformation, pass `false` for the corresponding option. For more details about the result of `replaceColors`, see [Icon color management](#icon-color-management). -## Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ†Π²Π΅Ρ‚ΠΎΠΌ ΠΈΠΊΠΎΠ½ΠΎΠΊ +## Icon color management -ΠŸΡ€ΠΈ Π²ΠΊΠ»ΡŽΡ‡Ρ‘Π½Π½ΠΎΠΉ Π·Π°ΠΌΠ΅Π½Π΅ Ρ†Π²Π΅Ρ‚ΠΎΠ² Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ `fill` ΠΈ `stroke` ΠΈ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ ΠΈΡ… Π² CSS custom properties. +When color replacement is enabled, the generator analyzes `fill` and `stroke` and converts them to CSS custom properties. -### ΠœΠΎΠ½ΠΎΡ…Ρ€ΠΎΠΌΠ½Ρ‹Π΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ +### Monochrome icons -Если Π½Π°ΠΉΠ΄Π΅Π½ ΠΎΠ΄ΠΈΠ½ Ρ†Π²Π΅Ρ‚, fallback замСняСтся Π½Π° `currentColor`: +If one color is found, the fallback is replaced with `currentColor`: ```svg stroke="var(--icon-color-1, currentColor)" ``` -Π¦Π²Π΅Ρ‚ΠΎΠΌ управляСт CSS-свойство `color` внСшнСго `` ΠΈΠ»ΠΈ Π΅Π³ΠΎ родитСля. +The color is controlled by the CSS `color` property of the outer `` or its parent. -### ΠœΠ½ΠΎΠ³ΠΎΡ†Π²Π΅Ρ‚Π½Ρ‹Π΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ +### Multicolor icons -ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ†Π²Π΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ с исходным fallback: +Each unique color gets a separate variable with the original fallback: ```svg fill="var(--icon-color-1, #798198)" @@ -306,7 +309,7 @@ fill="var(--icon-color-2, #ffffff)" fill="var(--icon-color-3, #129d9d)" ``` -Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ Ρ†Π²Π΅Ρ‚Π°: +The page can override only the required colors: ```css .icon { @@ -315,62 +318,62 @@ fill="var(--icon-color-3, #129d9d)" } ``` -### ΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΡ Ρ†Π²Π΅Ρ‚ΠΎΠ² +### Color limitations -- `none`, `transparent`, `inherit`, `unset` ΠΈ `initial` Π½Π΅ Π·Π°ΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ; -- Ρ†Π²Π΅Ρ‚Π° Π² Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π°Ρ… `fill`, `stroke` ΠΈ inline `style` ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ Π½Π°Π΄Ρ‘ΠΆΠ½Π΅Π΅ всСго; -- CSS-классы ΠΈ внСшниС stylesheets Π²Π½ΡƒΡ‚Ρ€ΠΈ исходного SVG Π½Π΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ основным сцСнариСм трансформации; -- gradients, patterns, filters ΠΈ значСния `url(#...)` Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΉ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ нСсовмСстимы с автоматичСской Π·Π°ΠΌΠ΅Π½ΠΎΠΉ Ρ†Π²Π΅Ρ‚ΠΎΠ²; -- CSS-ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ страницы доступны ΠΏΡ€ΠΈ ``, Π½ΠΎ нСдоступны Π²Π½ΡƒΡ‚Ρ€ΠΈ `` ΠΈ `background-image`. +- `none`, `transparent`, `inherit`, `unset`, and `initial` are not replaced; +- colors in `fill`, `stroke`, and inline `style` attributes are handled most reliably; +- CSS classes and external stylesheets inside the source SVG are not the primary transformation use case; +- gradients, patterns, filters, and `url(#...)` values require separate verification and may be incompatible with automatic color replacement; +- page CSS variables are available with ``, but are not available inside `` and `background-image`. -## ΠšΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ +## Caching -Vite, Webpack ΠΈ Next.js target Π²Ρ‹ΠΏΡƒΡΠΊΠ°ΡŽΡ‚ спрайт ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΌ asset с content hash: +The Vite, Webpack, and Next.js targets emit the sprite as a separate asset with a content hash: ```text /assets/sprite-.svg ``` -Π­Ρ‚ΠΎ Π΄Π°Ρ‘Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ свойства: +This provides the following properties: -- SVG ΠΊΠ΅ΡˆΠΈΡ€ΡƒΠ΅Ρ‚ΡΡ нСзависимо ΠΎΡ‚ JavaScript; -- ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ React-ΠΊΠΎΠ΄Π° Π½Π΅ мСняСт содСрТимоС спрайта; -- ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΈΠΊΠΎΠ½ΠΎΠΊ создаёт Π½ΠΎΠ²Ρ‹ΠΉ hash asset; -- ΠΎΠ΄ΠΈΠ½ Ρ„Π°ΠΉΠ» ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ всСми экзСмплярами generated-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°; -- SVG path-Π΄Π°Π½Π½Ρ‹Π΅ ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‚ Π² JavaScript chunks. +- the SVG is cached independently of JavaScript; +- changes to React code do not alter the sprite contents; +- icon changes produce a new hashed asset; +- one file is used by every instance of the generated component; +- SVG path data is absent from JavaScript chunks. -Vite target Π·Π°ΠΏΡ€Π΅Ρ‰Π°Π΅Ρ‚ inline Ρ‡Π΅Ρ€Π΅Π· `?no-inline`. Webpack 5 target ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Asset Modules Ρ‡Π΅Ρ€Π΅Π· `new URL(..., import.meta.url)`. +The Vite target prevents inlining through `?no-inline`. The Webpack 5 target uses Asset Modules through `new URL(..., import.meta.url)`. ## SpriteViewer -`SpriteViewer` β€” React-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ для просмотра generated-спрайтов Π²Π½ΡƒΡ‚Ρ€ΠΈ debug-ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π° прилоТСния. +`SpriteViewer` is a React component for viewing generated sprites inside an application's debug route. -Он ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ манифСсты ΠΈ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚: +It uses separate manifests and displays: -- Π³Ρ€ΡƒΠΏΠΏΡ‹ спрайтов; -- список ΠΈ количСство ΠΈΠΊΠΎΠ½ΠΎΠΊ; -- поиск ΠΈ ΡΠΈΡΡ‚Π΅ΠΌΠ½ΡƒΡŽ ΡΠ²Π΅Ρ‚Π»ΡƒΡŽ/Ρ‚Ρ‘ΠΌΠ½ΡƒΡŽ Ρ‚Π΅ΠΌΡƒ; -- модальноС ΠΏΡ€Π΅Π²ΡŒΡŽ с `viewBox` ΠΈ настройкой Ρ†Π²Π΅Ρ‚ΠΎΠ²Ρ‹Ρ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…; -- ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ React, SVG, IMG ΠΈ CSS с ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΠΊΠΎΠ΄Π°. +- sprite groups; +- the icon list and count; +- search and the system light/dark theme; +- a preview modal with the `viewBox` and color variable controls; +- React, SVG, IMG, and CSS examples with code copying. -Production-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ Π½Π΅ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ debug-манифСсты. Бпособ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ Viewer зависит ΠΎΡ‚ сборщика: +Production components do not import debug manifests. How you integrate the Viewer depends on the bundler: -- [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). +- [React + Vite: automatic `import.meta.glob`](docs/en/react-vite.md#6-add-a-debug-page); +- [React + Webpack 5: static `import()`](docs/en/react-webpack.md#6-add-a-debug-page); +- [Next.js App Router](docs/en/next-app.md#5-add-spriteviewer); +- [Next.js Pages Router](docs/en/next-pages.md#5-add-spriteviewer). -Viewer ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ ΠΈΠ· ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΉ клиСнтской Ρ‚ΠΎΡ‡ΠΊΠΈ Π²Ρ…ΠΎΠ΄Π° `@gromlab/svg-sprites/react` ΠΈ Π½Π΅ ΠΏΠΎΠΏΠ°Π΄Π°Π΅Ρ‚ Π² production-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ ΠΈΠΊΠΎΠ½ΠΎΠΊ. +The Viewer is imported from the separate `@gromlab/svg-sprites/react` client entry point and is not included in production icon components. -### Π’Π΅ΠΌΠ° Viewer +### Viewer theme -По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ `colorTheme="auto"`: Viewer слСдуСт `prefers-color-scheme` ΠΈ Ρ€Π΅Π°Π³ΠΈΡ€ΡƒΠ΅Ρ‚ Π½Π° смСну систСмной Ρ‚Π΅ΠΌΡ‹. Π’Π΅ΠΌΡƒ прилоТСния ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ явно: +By default, `colorTheme="auto"`: the Viewer follows `prefers-color-scheme` and responds to system theme changes. The application theme can be passed explicitly: ```tsx ``` -ДопустимыС значСния `colorTheme`: `auto`, `light`, `dark`. ΠŸΡ€ΠΈ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠΈ Ρ‚Π΅ΠΌΠΎΠΉ ΠΈΠ·Π²Π½Π΅ встроСнный ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π°Ρ‚Π΅Π»ΡŒ скрываСтся. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π΅Π³ΠΎ ΠΈ ΠΎΠ±Π½ΠΎΠ²Π»ΡΡ‚ΡŒ Ρ‚Π΅ΠΌΡƒ прилоТСния Ρ‡Π΅Ρ€Π΅Π· Viewer, ΠΏΠ΅Ρ€Π΅Π΄Π°ΠΉΡ‚Π΅ callback: +Valid `colorTheme` values are `auto`, `light`, and `dark`. When the theme is controlled externally, the built-in switch is hidden. To keep it and update the application theme through the Viewer, pass a callback: ```tsx ``` -## ДокумСнтация +## Documentation -- [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) +- [React + Vite](docs/en/react-vite.md) +- [React + Webpack 5](docs/en/react-webpack.md) +- [Next.js App Router](docs/en/next-app.md) +- [Next.js Pages Router](docs/en/next-pages.md) +- [Legacy mode](docs/en/legacy.md) +- [Migrating from 0.1.x](docs/en/migration-1.md) +- [Programmatic API](docs/en/programmatic-api.md) -## ЛицСнзия +## License MIT diff --git a/README_RU.md b/README_RU.md new file mode 100644 index 0000000..c4d9a90 --- /dev/null +++ b/README_RU.md @@ -0,0 +1,398 @@ +# @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 diff --git a/docs/en/legacy.md b/docs/en/legacy.md new file mode 100644 index 0000000..10b6ea1 --- /dev/null +++ b/docs/en/legacy.md @@ -0,0 +1,102 @@ +# Legacy mode + +[← Back to home](../../README.md) + +A quick guide to generating centralized SVG sprites in `symbol` and `stack` formats, with an optional HTML preview. + +## 1. Install the package + +```bash +npm install @gromlab/svg-sprites +``` + +## 2. Prepare the icons and config + +```text +project/ +β”œβ”€β”€ src/assets/icons/ +β”‚ β”œβ”€β”€ check.svg +β”‚ └── folder.svg +└── svg-sprites.config.ts +``` + +```ts +// svg-sprites.config.ts +import { defineLegacyConfig } from '@gromlab/svg-sprites' + +export default defineLegacyConfig({ + output: 'public/sprites', + preview: true, + sprites: [ + { + name: 'icons', + input: 'src/assets/icons', + format: 'symbol', + }, + ], +}) +``` + +## 3. Run generation + +```bash +npx svg-sprites --mode legacy . +``` + +Result: + +```text +public/sprites/ +β”œβ”€β”€ icons.sprite.svg +└── preview.html +``` + +With `preview: false`, the HTML file is not created. For the `stack` format, specify `format: 'stack'`. + +## 4. Use the symbol sprite + +```html + + + +``` + +## 5. Add a package script + +```json +{ + "scripts": { + "sprites": "svg-sprites --mode legacy .", + "prebuild": "npm run sprites" + } +} +``` + +## Multiple sprites + +Add multiple entries to `sprites`: + +```ts +sprites: [ + { + name: 'icons', + input: 'src/assets/icons', + format: 'symbol', + }, + { + name: 'logos', + input: 'src/assets/logos', + format: 'stack', + }, +] +``` + +All output files and the shared `preview.html` will be written to `output`. + +## Troubleshooting + +- Config not found: make sure `svg-sprites.config.ts` is located in the specified root directory. +- No icons: check `sprites[].input` and the `.svg` extension. +- Preview not needed: set `preview: false`. + +For programmatic use, see [`generateLegacy`](programmatic-api.md#generatelegacy). diff --git a/docs/en/migration-1.md b/docs/en/migration-1.md new file mode 100644 index 0000000..b53b915 --- /dev/null +++ b/docs/en/migration-1.md @@ -0,0 +1,96 @@ +# Migrating from 0.1.x to 1.0 + +[← Back to home](../../README.md) + +Version 1.0 separates local generation for React and Next.js from the centralized legacy mode. The old config cannot be mixed with the new API in a single CLI invocation. + +## CLI + +The CLI now always requires an explicit `--mode` and a path to the configuration directory: + +```text +svg-sprites +β†’ svg-sprites --mode +``` + +Choose a mode based on your environment: + +| Environment | Mode | +|---|---| +| React + Vite | `react@vite` | +| React + Webpack 5 | `react@webpack` | +| Next.js App Router + Turbopack | `next@app/turbopack` | +| Next.js App Router + Webpack 5 | `next@app/webpack` | +| Next.js Pages Router + Turbopack | `next@pages/turbopack` | +| Next.js Pages Router + Webpack 5 | `next@pages/webpack` | +| Centralized legacy setup | `legacy` | + +## React and Next.js + +Instead of a root-level `svg-sprites.config.ts`, create a local `svg-sprite.config.ts` next to the icon set: + +```ts +import { defineNextSpriteConfig } from '@gromlab/svg-sprites' + +export default defineNextSpriteConfig({ + name: 'global', + inputFolder: './icons', +}) +``` + +For regular React, use `defineReactSpriteConfig`. A folder and an explicit list of shared SVG files can be combined using `inputFolder` and `inputFiles`. + +The old `publicPath` and `react` options are no longer needed. The generated module is created next to the config and adds its own `.gitignore`, while Vite, Webpack, or Next.js emits the SVG as a separate asset with a content hash. + +The `` component is replaced by a component whose name is derived from `name`: + +```tsx + +``` + +To browse the icons, add `` as a debug page in the application. A separate `preview.html` is available only in legacy mode. + +## Legacy mode + +If you need to preserve the centralized structure, rename the helper and the format fields: + +```ts +import { defineLegacyConfig } from '@gromlab/svg-sprites' + +export default defineLegacyConfig({ + output: 'public/sprites', + preview: true, + sprites: [ + { + name: 'icons', + input: 'src/assets/icons', + format: 'stack', + }, + ], +}) +``` + +- `defineConfig` has been replaced with `defineLegacyConfig`; +- `sprites[].mode` has been renamed to `sprites[].format`; +- `generate` has been replaced with `generateLegacy`; +- `loadConfig` has been replaced with `loadLegacyConfig`; +- `publicPath` and generation of the old shared React component have been removed. + +Run: + +```bash +svg-sprites --mode legacy . +``` + +## Programmatic API + +The package is distributed as ESM only. Replace `require()` with `import`. + +`compileSpriteContent` now returns `Promise` so that the public declarations do not require `@types/node` to be installed. In Node.js, the actual result is compatible with APIs that accept `Uint8Array`. + +## After migration + +1. Remove the old generated files and rules that ignored the entire directory containing the source icons. +2. Add an explicit generation command before `dev`, `build`, and `typecheck`. +3. Run generation and type checking. +4. Check all icons and color variables using `SpriteViewer` or the legacy `preview.html`. diff --git a/docs/en/next-app.md b/docs/en/next-app.md new file mode 100644 index 0000000..1e334ce --- /dev/null +++ b/docs/en/next-app.md @@ -0,0 +1,102 @@ +# Next.js App Router + +[← Back to home](../../README.md) + +Two explicit modes are supported: + +| Bundler | Mode key | Next.js version | +|---|---|---| +| Turbopack | `next@app/turbopack` | 16.2+ | +| Webpack 5 | `next@app/webpack` | 13.4+ | + +## 1. Install the package + +```bash +npm install @gromlab/svg-sprites +``` + +## 2. Create a sprite module + +```text +src/ui/file-manager/svg-sprite/ +β”œβ”€β”€ icons/ +β”‚ β”œβ”€β”€ check.svg +β”‚ └── folder.svg +└── svg-sprite.config.ts +``` + +```ts +// src/ui/file-manager/svg-sprite/svg-sprite.config.ts +import { defineNextSpriteConfig } from '@gromlab/svg-sprites' + +export default defineNextSpriteConfig({ + name: 'file-manager', + description: 'File manager icons', +}) +``` + +## 3. Add generation + +For Turbopack: + +```json +{ + "scripts": { + "sprite:file-manager": "svg-sprites --mode next@app/turbopack src/ui/file-manager/svg-sprite", + "predev": "npm run sprite:file-manager", + "prebuild": "npm run sprite:file-manager" + } +} +``` + +For Webpack, replace the mode key with `next@app/webpack`. In Next 13–15, Webpack is used with the regular `next build` command; in Next 16, use `next build --webpack`. + +## 4. Use it in a Server Component + +The generated component does not contain `'use client'`, so it can be imported directly into `page.tsx` or `layout.tsx`: + +```tsx +import { FileManagerIcon } from '@/ui/file-manager/svg-sprite' + +export default function Page() { + return ( +
+ +
+ ) +} +``` + +Next.js emits a separate SVG asset with a content hash. The same generated code is used during SSR and in the browser, with no URL mismatch. + +## 5. Add SpriteViewer + +The viewer is interactive, so it requires a separate Client Component boundary: + +```tsx +'use client' + +import { SpriteViewer } from '@gromlab/svg-sprites/react' + +const sources = [ + () => import('@/ui/file-manager/svg-sprite/manifest'), +] + +export default function SpritesPage() { + return +} +``` + +## Verify the bundler + +```bash +# Turbopack +npx next build --turbopack + +# Webpack 5 +npx next build --webpack +``` + +For Next 13–15 with Webpack, use `npx next build` without the flag. + +The Next.js command and the generator mode key must target the same bundler. diff --git a/docs/en/next-pages.md b/docs/en/next-pages.md new file mode 100644 index 0000000..0de0136 --- /dev/null +++ b/docs/en/next-pages.md @@ -0,0 +1,96 @@ +# Next.js Pages Router + +[← Back to home](../../README.md) + +Two explicit modes are supported: + +| Bundler | Mode key | Next.js version | +|---|---|---| +| Turbopack | `next@pages/turbopack` | 16.2+ | +| Webpack 5 | `next@pages/webpack` | 12.2+ | + +Next.js 12.2 requires React 18. + +## 1. Install the package + +```bash +npm install @gromlab/svg-sprites +``` + +## 2. Create a sprite module + +```text +src/ui/file-manager/svg-sprite/ +β”œβ”€β”€ icons/ +β”‚ β”œβ”€β”€ check.svg +β”‚ └── folder.svg +└── svg-sprite.config.ts +``` + +```ts +// src/ui/file-manager/svg-sprite/svg-sprite.config.ts +import { defineNextSpriteConfig } from '@gromlab/svg-sprites' + +export default defineNextSpriteConfig({ + name: 'file-manager', + description: 'File manager icons', +}) +``` + +## 3. Add generation + +```json +{ + "scripts": { + "sprite:file-manager": "svg-sprites --mode next@pages/webpack src/ui/file-manager/svg-sprite", + "predev": "npm run sprite:file-manager", + "prebuild": "npm run sprite:file-manager" + } +} +``` + +For Next.js 16.2 with Turbopack, replace the mode key with `next@pages/turbopack`. + +## 4. Use it on a page + +```tsx +import { FileManagerIcon } from '@/ui/file-manager/svg-sprite' + +export default function FilesPage() { + return +} + +export function getServerSideProps() { + return { props: {} } +} +``` + +The component works the same way with SSR, SSG, and client-side navigation. Next.js emits a separate SVG asset with a content hash. + +## 5. Add SpriteViewer + +```tsx +import { SpriteViewer } from '@gromlab/svg-sprites/react' + +const sources = [ + () => import('@/ui/file-manager/svg-sprite/manifest'), +] + +export default function SpritesPage() { + return +} +``` + +## Verify the bundler + +```bash +# Turbopack +npx next build --turbopack + +# Webpack 5 +npx next build --webpack +``` + +For Next 12–15 with Webpack, use `npx next build` without the flag. + +The Next.js command and the generator mode key must target the same bundler. diff --git a/docs/en/programmatic-api.md b/docs/en/programmatic-api.md new file mode 100644 index 0000000..7a4d44b --- /dev/null +++ b/docs/en/programmatic-api.md @@ -0,0 +1,203 @@ +# Programmatic API + +[← Back to home](../../README.md) + +The package provides a main Node.js entry point and a separate React runtime entry point. Both are distributed as ESM only and must be loaded with `import`. + +To resolve `@gromlab/svg-sprites/react` in TypeScript, use `moduleResolution: "bundler"`, `"node16"`, or `"nodenext"`. + +## Main entry point + +```ts +import { + defineNextSpriteConfig, + defineReactSpriteConfig, + generateNextSprite, + generateReactSprite, +} from '@gromlab/svg-sprites' +``` + +The main entry point does not import React and can be used in CLIs, build scripts, and Node.js tools. + +## `generateReactSprite` + +```ts +import { generateReactSprite } from '@gromlab/svg-sprites' + +const result = await generateReactSprite( + 'src/ui/file-manager/svg-sprite', + 'vite', +) +``` + +The second argument is required: + +```ts +type ReactAssetTarget = 'vite' | 'webpack' +``` + +Result: + +```ts +type ReactSpriteGenerationResult = { + name: string + rootDir: string + generatedDir: string + spritePath: string + manifestPath: string + iconCount: number + target: 'vite' | 'webpack' +} +``` + +```ts +console.log(result.name) +console.log(result.iconCount) +console.log(result.spritePath) +console.log(result.manifestPath) +``` + +The function loads `svg-sprite.config.ts` from the specified root, compiles the SVG files, and safely updates managed files. + +## `generateNextSprite` + +```ts +import { generateNextSprite } from '@gromlab/svg-sprites' + +const result = await generateNextSprite( + 'src/ui/file-manager/svg-sprite', + { + router: 'app', + bundler: 'turbopack', + }, +) +``` + +Available values: + +```ts +type NextSpriteGenerationOptions = { + router: 'app' | 'pages' + bundler: 'turbopack' | 'webpack' +} +``` + +The result also contains the selected `router`, `bundler`, and the full target in the form `next@app/turbopack`. + +## `defineReactSpriteConfig` + +```ts +import { defineReactSpriteConfig } from '@gromlab/svg-sprites' + +export default defineReactSpriteConfig({ + name: 'file-manager', + description: 'File manager icons', + inputFolder: './icons', + inputFiles: [ + '../../shared/icons/check.svg', + ], + transform: { + removeSize: true, + replaceColors: true, + addTransition: true, + }, + generatedNotice: true, +}) +``` + +`inputFolder` and `inputFiles` are combined. The helper returns the configuration without runtime transformations and provides TypeScript autocomplete. + +## `defineNextSpriteConfig` + +```ts +import { defineNextSpriteConfig } from '@gromlab/svg-sprites' + +export default defineNextSpriteConfig({ + name: 'file-manager', + description: 'File manager icons', + inputFolder: './icons', +}) +``` + +Next.js uses the same configuration contract as the React presets. + +## `generateLegacy` + +```ts +import { generateLegacy } from '@gromlab/svg-sprites' + +const results = await generateLegacy({ + output: 'public/sprites', + preview: false, + sprites: [ + { + name: 'icons', + input: 'src/assets/icons', + format: 'symbol', + }, + ], +}) +``` + +Returns an array: + +```ts +type SpriteResult = { + name: string + format: 'symbol' | 'stack' + spritePath: string + iconCount: number +} +``` + +For details, see [Legacy mode](legacy.md). + +## Low-level functions + +The main entry point also exports: + +```ts +import { + compileSprite, + compileSpriteContent, + createShapeTransform, + generatePreview, + loadLegacyConfig, + loadReactSpriteConfig, + resolveSpriteEntry, + resolveSprites, +} from '@gromlab/svg-sprites' +``` + +These functions are intended for custom orchestration built on top of the existing compiler and writer. For standard usage, prefer `generateReactSprite` and `generateLegacy`. + +## React runtime entry point + +```tsx +import { SpriteViewer } from '@gromlab/svg-sprites/react' +``` + +Types: + +```ts +import type { + SpriteManifest, + SpriteManifestColor, + SpriteManifestIcon, + SpriteManifestLoader, + SpriteManifestModule, + SpriteViewerColorTheme, + SpriteViewerProps, + SpriteViewerSource, + SpriteViewerSources, +} from '@gromlab/svg-sprites/react' +``` + +The React entry point contains `'use client'` and is intended for debug tools. Generated production components are imported from the application's local sprite modules, not from the package's React entry point. + +`SpriteViewerProps.colorTheme` accepts `auto | light | dark`. The default is `auto`, which follows `prefers-color-scheme`; to synchronize it with the application theme, pass the computed `light` or `dark` value. + +## Related guides + +- [React + Vite](react-vite.md) +- [React + Webpack 5](react-webpack.md) diff --git a/docs/en/react-vite.md b/docs/en/react-vite.md new file mode 100644 index 0000000..1e37cc4 --- /dev/null +++ b/docs/en/react-vite.md @@ -0,0 +1,116 @@ +# React + Vite + +[← Back to home](../../README.md) + +A quick guide to installing and using SVG sprites in a React and Vite project. + +The result is a typed React component and a separate cacheable SVG asset. + +## 1. Install the package + +```bash +npm install @gromlab/svg-sprites +``` + +## 2. Create the sprite directory + +```text +src/ui/file-manager/svg-sprite/ +β”œβ”€β”€ icons/ +β”‚ β”œβ”€β”€ check.svg +β”‚ └── folder.svg +└── svg-sprite.config.ts +``` + +Place the source SVG files in `icons/`. + +## 3. Add the configuration + +```ts +// src/ui/file-manager/svg-sprite/svg-sprite.config.ts +import { defineReactSpriteConfig } from '@gromlab/svg-sprites' + +export default defineReactSpriteConfig({ + name: 'file-manager', + description: 'File manager icons', +}) +``` + +By default, SVG files are loaded from `./icons`. You can add shared icons from other directories through `inputFiles`: the directory and file list are combined into a single sprite. + +The complete list of options is available under [Configuration β†’ React](../../README.md#react). + +## 4. Add generation to package.json + +```json +{ + "scripts": { + "sprite:file-manager": "svg-sprites --mode react@vite src/ui/file-manager/svg-sprite", + "predev": "npm run sprite:file-manager", + "prebuild": "npm run sprite:file-manager", + "pretypecheck": "npm run sprite:file-manager" + } +} +``` + +Generated files are excluded from Git, so generation must run before `dev`, `build`, and `typecheck`. + +First run: + +```bash +npm run sprite:file-manager +``` + +## 5. Use the component + +The name `file-manager` is converted to `FileManagerIcon`: + +```tsx +import { FileManagerIcon } from './svg-sprite' + +export const OpenFolderButton = () => ( + +) +``` + +TypeScript checks the `icon` value against the file names: + +```tsx + // valid + // TypeScript error +``` + +Types, display methods, and color controls are described in the [main documentation](../../README.md#display-methods). + +Vite emits the sprite as a separate file named like `assets/sprite-.svg`. SVG path data is not included in JavaScript. + +## 6. Add a debug page + +After integrating the icons, you can display all React sprites with `SpriteViewer`: + +```tsx +import { SpriteViewer } from '@gromlab/svg-sprites/react' +import type { SpriteManifestModule } from '@gromlab/svg-sprites/react' + +const sources = import.meta.glob( + '/src/**/svg-sprite/manifest.ts', +) + +export const IconsDebugPage = () => ( + +) +``` + +Vite automatically finds the generated `manifest.ts` for each React sprite. The `import.meta.glob` pattern must be a string literal, and generation must run before Vite starts. + +Only include the Viewer on a debug route or in an internal tool. + +## Troubleshooting + +- Missing `index.ts`: run `npm run sprite:file-manager`. +- The Viewer cannot find the sprite: check the glob path and make sure `manifest.ts` exists. +- `Refusing to overwrite a user file` error: there is a user file at a generated path. +- The icon does not change color: use `color` or `--icon-color-N`. diff --git a/docs/en/react-webpack.md b/docs/en/react-webpack.md new file mode 100644 index 0000000..15383db --- /dev/null +++ b/docs/en/react-webpack.md @@ -0,0 +1,118 @@ +# React + Webpack 5 + +[← Back to home](../../README.md) + +A quick guide to installing and using SVG sprites in a React and Webpack 5 project. + +The result is a typed React component and a separate SVG asset emitted through Webpack Asset Modules. + +## 1. Install the package + +```bash +npm install @gromlab/svg-sprites +``` + +## 2. Create the sprite directory + +```text +src/ui/file-manager/svg-sprite/ +β”œβ”€β”€ icons/ +β”‚ β”œβ”€β”€ check.svg +β”‚ └── folder.svg +└── svg-sprite.config.ts +``` + +Place the source SVG files in `icons/`. + +## 3. Add the configuration + +```ts +// src/ui/file-manager/svg-sprite/svg-sprite.config.ts +import { defineReactSpriteConfig } from '@gromlab/svg-sprites' + +export default defineReactSpriteConfig({ + name: 'file-manager', + description: 'File manager icons', +}) +``` + +By default, SVG files are loaded from `./icons`. You can add shared icons from other directories through `inputFiles`: the directory and file list are combined into a single sprite. + +The complete list of options is available under [Configuration β†’ React](../../README.md#react). + +## 4. Add generation to package.json + +```json +{ + "scripts": { + "sprite:file-manager": "svg-sprites --mode react@webpack src/ui/file-manager/svg-sprite", + "predev": "npm run sprite:file-manager", + "prebuild": "npm run sprite:file-manager", + "pretypecheck": "npm run sprite:file-manager" + } +} +``` + +Generated files are excluded from Git, so generation must run before `dev`, `build`, and `typecheck`. + +First run: + +```bash +npm run sprite:file-manager +``` + +## 5. Use the component + +```tsx +import { FileManagerIcon } from './svg-sprite' + +export const OpenFolderButton = () => ( + +) +``` + +TypeScript checks the `icon` value against the file names: + +```tsx + // valid + // TypeScript error +``` + +Types, display methods, and color controls are described in the [main documentation](../../README.md#display-methods). + +Webpack processes the generated `new URL('./sprite.svg', import.meta.url)` through Asset Modules and emits a separate SVG asset. + +If the project already uses a custom SVG loader, make sure it does not intercept the generated `sprite.svg` instead of Asset Modules. + +## 6. Add a debug page + +Webpack does not support Vite's `import.meta.glob` API, so provide static loaders: + +```tsx +import { SpriteViewer } from '@gromlab/svg-sprites/react' + +const sources = [ + () => import('./ui/file-manager/svg-sprite/manifest'), + () => import('./ui/navigation/svg-sprite/manifest'), +] + +export const IconsDebugPage = () => ( + +) +``` + +The paths in `import()` must be string literals. Webpack creates chunks for the manifests and associates them with the SVG assets. + +Only include the Viewer on a debug route or in an internal tool. + +## Troubleshooting + +- Missing `index.ts`: run `npm run sprite:file-manager`. +- The Viewer does not load the sprite: check the path in `import()` and make sure `manifest.ts` exists. +- Incorrect asset URL: check `output.publicPath`. +- Another loader intercepts the SVG: exclude the generated sprite from the incompatible rule. + +For Next.js, use the separate mode keys described in the [App Router](next-app.md) and [Pages Router](next-pages.md) guides. diff --git a/docs/ru/legacy.md b/docs/ru/legacy.md index 5efd0cf..3d722b8 100644 --- a/docs/ru/legacy.md +++ b/docs/ru/legacy.md @@ -1,6 +1,6 @@ # Legacy mode -[← Главная](../../README.md) +[← Главная](../../README_RU.md) ΠšΡ€Π°Ρ‚ΠΊΠ°Ρ инструкция ΠΏΠΎ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹Ρ… SVG-спрайтов Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΎΠ² `symbol` ΠΈ `stack` с optional HTML preview. diff --git a/docs/ru/migration-1.md b/docs/ru/migration-1.md index a41d3d9..39b15d8 100644 --- a/docs/ru/migration-1.md +++ b/docs/ru/migration-1.md @@ -1,6 +1,6 @@ # ΠœΠΈΠ³Ρ€Π°Ρ†ΠΈΡ с 0.1.x Π½Π° 1.0 -[← Главная](../../README.md) +[← Главная](../../README_RU.md) ВСрсия 1.0 раздСляСт Π»ΠΎΠΊΠ°Π»ΡŒΠ½ΡƒΡŽ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ для React ΠΈ Next.js ΠΈ Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ legacy-Ρ€Π΅ΠΆΠΈΠΌ. Π‘Ρ‚Π°Ρ€Ρ‹ΠΉ config нСльзя ΡΠΌΠ΅ΡˆΠΈΠ²Π°Ρ‚ΡŒ с Π½ΠΎΠ²Ρ‹ΠΌ API Π² ΠΎΠ΄Π½ΠΎΠΌ Π²Ρ‹Π·ΠΎΠ²Π΅ CLI. diff --git a/docs/ru/next-app.md b/docs/ru/next-app.md index 593d02d..06049c6 100644 --- a/docs/ru/next-app.md +++ b/docs/ru/next-app.md @@ -1,6 +1,6 @@ # Next.js App Router -[← Главная](../../README.md) +[← Главная](../../README_RU.md) ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ Π΄Π²Π° явных Ρ€Π΅ΠΆΠΈΠΌΠ°: diff --git a/docs/ru/next-pages.md b/docs/ru/next-pages.md index d52750b..926f0ef 100644 --- a/docs/ru/next-pages.md +++ b/docs/ru/next-pages.md @@ -1,6 +1,6 @@ # Next.js Pages Router -[← Главная](../../README.md) +[← Главная](../../README_RU.md) ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ Π΄Π²Π° явных Ρ€Π΅ΠΆΠΈΠΌΠ°: diff --git a/docs/ru/programmatic-api.md b/docs/ru/programmatic-api.md index 510b5fc..999cd01 100644 --- a/docs/ru/programmatic-api.md +++ b/docs/ru/programmatic-api.md @@ -1,6 +1,6 @@ # ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ API -[← Главная](../../README.md) +[← Главная](../../README_RU.md) ΠŸΠ°ΠΊΠ΅Ρ‚ прСдоставляСт ΠΎΡΠ½ΠΎΠ²Π½ΡƒΡŽ Node.js Ρ‚ΠΎΡ‡ΠΊΡƒ Π²Ρ…ΠΎΠ΄Π° ΠΈ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ React runtime entry. ОбС Ρ‚ΠΎΡ‡ΠΊΠΈ Ρ€Π°ΡΠΏΡ€ΠΎΡΡ‚Ρ€Π°Π½ΡΡŽΡ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊΠ°ΠΊ ESM ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‚ΡΡ Ρ‡Π΅Ρ€Π΅Π· `import`. diff --git a/docs/ru/react-vite.md b/docs/ru/react-vite.md index 1aa146e..2ae3b39 100644 --- a/docs/ru/react-vite.md +++ b/docs/ru/react-vite.md @@ -1,6 +1,6 @@ # React + Vite -[← Главная](../../README.md) +[← Главная](../../README_RU.md) ΠšΡ€Π°Ρ‚ΠΊΠ°Ρ инструкция ΠΏΠΎ установкС ΠΈ использованию SVG-спрайтов Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅ Π½Π° React ΠΈ Vite. @@ -38,7 +38,7 @@ export default defineReactSpriteConfig({ По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ SVG бСрутся ΠΈΠ· `./icons`. ΠžΠ±Ρ‰ΠΈΠ΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΏΠ°ΠΏΠΎΠΊ ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· `inputFiles`: ΠΏΠ°ΠΏΠΊΠ° ΠΈ список ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‚ΡΡ Π² ΠΎΠ΄ΠΈΠ½ спрайт. -ΠŸΠΎΠ»Π½Ρ‹ΠΉ список ΠΎΠΏΡ†ΠΈΠΉ находится Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ [ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ β†’ React](../../README.md#react). +ΠŸΠΎΠ»Π½Ρ‹ΠΉ список ΠΎΠΏΡ†ΠΈΠΉ находится Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ [ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ β†’ React](../../README_RU.md#react). ## 4. Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ Π² package.json @@ -83,7 +83,7 @@ export const OpenFolderButton = () => ( // ошибка TypeScript ``` -Π’ΠΈΠΏΡ‹, способы отобраТСния ΠΈ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ†Π²Π΅Ρ‚Π°ΠΌΠΈ описаны Π² [основной Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ](../../README.md#способы-отобраТСния). +Π’ΠΈΠΏΡ‹, способы отобраТСния ΠΈ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ†Π²Π΅Ρ‚Π°ΠΌΠΈ описаны Π² [основной Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ](../../README_RU.md#способы-отобраТСния). Vite выпустит спрайт ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ„Π°ΠΉΠ»ΠΎΠΌ Π²ΠΈΠ΄Π° `assets/sprite-.svg`. SVG path-Π΄Π°Π½Π½Ρ‹Π΅ Π½Π΅ ΠΏΠΎΠΏΠ°Π΄ΡƒΡ‚ Π² JavaScript. diff --git a/docs/ru/react-webpack.md b/docs/ru/react-webpack.md index bd4ccd9..2a3c015 100644 --- a/docs/ru/react-webpack.md +++ b/docs/ru/react-webpack.md @@ -1,6 +1,6 @@ # React + Webpack 5 -[← Главная](../../README.md) +[← Главная](../../README_RU.md) ΠšΡ€Π°Ρ‚ΠΊΠ°Ρ инструкция ΠΏΠΎ установкС ΠΈ использованию SVG-спрайтов Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅ Π½Π° React ΠΈ Webpack 5. @@ -38,7 +38,7 @@ export default defineReactSpriteConfig({ По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ SVG бСрутся ΠΈΠ· `./icons`. ΠžΠ±Ρ‰ΠΈΠ΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΏΠ°ΠΏΠΎΠΊ ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· `inputFiles`: ΠΏΠ°ΠΏΠΊΠ° ΠΈ список ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‚ΡΡ Π² ΠΎΠ΄ΠΈΠ½ спрайт. -ΠŸΠΎΠ»Π½Ρ‹ΠΉ список ΠΎΠΏΡ†ΠΈΠΉ находится Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ [ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ β†’ React](../../README.md#react). +ΠŸΠΎΠ»Π½Ρ‹ΠΉ список ΠΎΠΏΡ†ΠΈΠΉ находится Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ [ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ β†’ React](../../README_RU.md#react). ## 4. Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ Π² package.json @@ -81,7 +81,7 @@ export const OpenFolderButton = () => ( // ошибка TypeScript ``` -Π’ΠΈΠΏΡ‹, способы отобраТСния ΠΈ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ†Π²Π΅Ρ‚Π°ΠΌΠΈ описаны Π² [основной Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ](../../README.md#способы-отобраТСния). +Π’ΠΈΠΏΡ‹, способы отобраТСния ΠΈ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ†Π²Π΅Ρ‚Π°ΠΌΠΈ описаны Π² [основной Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ](../../README_RU.md#способы-отобраТСния). Webpack ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ generated `new URL('./sprite.svg', import.meta.url)` Ρ‡Π΅Ρ€Π΅Π· Asset Modules ΠΈ выпустит ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ SVG asset. diff --git a/package.json b/package.json index 0459e55..8ecbf6f 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,8 @@ "dist/chunk-*.js", "dist/chunk-*.js.map", "dist/preview-template.html", + "README_RU.md", + "docs/en/*.md", "docs/ru/*.md", "LICENSE", "THIRD_PARTY_NOTICES.md" @@ -63,11 +65,11 @@ }, "repository": { "type": "git", - "url": "https://gromlab.ru/gromov/svg-sprites" + "url": "https://github.com/gromov-sergei/svg-sprites" }, - "homepage": "https://gromlab.ru/gromov/svg-sprites", + "homepage": "https://github.com/gromov-sergei/svg-sprites", "bugs": { - "url": "https://gromlab.ru/gromov/svg-sprites/issues" + "url": "https://github.com/gromov-sergei/svg-sprites/issues" }, "engines": { "node": ">=18" diff --git a/preview/.templates/business/{{name.kebabCase}}/index.ts b/preview/.templates/business/{{name.kebabCase}}/index.ts deleted file mode 100644 index 6c47526..0000000 --- a/preview/.templates/business/{{name.kebabCase}}/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { {{name.pascalCase}}Business } from './{{name.kebabCase}}.business' diff --git a/preview/.templates/business/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css b/preview/.templates/business/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css deleted file mode 100644 index c3a2af6..0000000 --- a/preview/.templates/business/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css +++ /dev/null @@ -1,2 +0,0 @@ -.root { -} diff --git a/preview/.templates/business/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts b/preview/.templates/business/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts deleted file mode 100644 index 59561c1..0000000 --- a/preview/.templates/business/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { HTMLAttributes } from 'react' - -/** - * ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ бизнСс-модуля {{name.pascalCase}}. - */ -export type {{name.pascalCase}}BusinessParams = {} - -/** HTML-Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ элСмСнта. */ -type RootAttrs = HTMLAttributes - -export type {{name.pascalCase}}BusinessProps = RootAttrs & {{name.pascalCase}}BusinessParams diff --git a/preview/.templates/business/{{name.kebabCase}}/{{name.kebabCase}}.business.tsx b/preview/.templates/business/{{name.kebabCase}}/{{name.kebabCase}}.business.tsx deleted file mode 100644 index a29fefc..0000000 --- a/preview/.templates/business/{{name.kebabCase}}/{{name.kebabCase}}.business.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import cl from 'clsx' -import type { {{name.pascalCase}}BusinessProps } from './types/{{name.kebabCase}}.type' -import styles from './styles/{{name.kebabCase}}.module.css' - -/** - * <НазначСниС бизнСс-модуля {{name.pascalCase}} Π² 1 строкС>. - * - * Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для: - * - <сцСнарий 1> - * - <сцСнарий 2> - */ -export const {{name.pascalCase}}Business = (props: {{name.pascalCase}}BusinessProps) => { - const { children, className, ...htmlAttr } = props - - return ( -
- {children} -
- ) -} diff --git a/preview/.templates/infrastructure/{{name.kebabCase}}/index.ts b/preview/.templates/infrastructure/{{name.kebabCase}}/index.ts deleted file mode 100644 index 482460d..0000000 --- a/preview/.templates/infrastructure/{{name.kebabCase}}/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { {{name.pascalCase}}Infra } from './{{name.kebabCase}}.infra' diff --git a/preview/.templates/infrastructure/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css b/preview/.templates/infrastructure/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css deleted file mode 100644 index c3a2af6..0000000 --- a/preview/.templates/infrastructure/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css +++ /dev/null @@ -1,2 +0,0 @@ -.root { -} diff --git a/preview/.templates/infrastructure/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts b/preview/.templates/infrastructure/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts deleted file mode 100644 index e6d1113..0000000 --- a/preview/.templates/infrastructure/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { HTMLAttributes } from 'react' - -/** - * ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ инфраструктурного модуля {{name.pascalCase}}. - */ -export type {{name.pascalCase}}InfraParams = {} - -/** HTML-Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ элСмСнта. */ -type RootAttrs = HTMLAttributes - -export type {{name.pascalCase}}InfraProps = RootAttrs & {{name.pascalCase}}InfraParams diff --git a/preview/.templates/infrastructure/{{name.kebabCase}}/{{name.kebabCase}}.infra.tsx b/preview/.templates/infrastructure/{{name.kebabCase}}/{{name.kebabCase}}.infra.tsx deleted file mode 100644 index c7e02bc..0000000 --- a/preview/.templates/infrastructure/{{name.kebabCase}}/{{name.kebabCase}}.infra.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import cl from 'clsx' -import type { {{name.pascalCase}}InfraProps } from './types/{{name.kebabCase}}.type' -import styles from './styles/{{name.kebabCase}}.module.css' - -/** - * <НазначСниС инфраструктурного модуля {{name.pascalCase}} Π² 1 строкС>. - * - * Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для: - * - <сцСнарий 1> - * - <сцСнарий 2> - */ -export const {{name.pascalCase}}Infra = (props: {{name.pascalCase}}InfraProps) => { - const { children, className, ...htmlAttr } = props - - return ( -
- {children} -
- ) -} diff --git a/preview/.templates/layout/{{name.kebabCase}}/index.ts b/preview/.templates/layout/{{name.kebabCase}}/index.ts deleted file mode 100644 index dcafc99..0000000 --- a/preview/.templates/layout/{{name.kebabCase}}/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { {{name.pascalCase}}Layout } from './{{name.kebabCase}}.layout' diff --git a/preview/.templates/layout/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css b/preview/.templates/layout/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css deleted file mode 100644 index c3a2af6..0000000 --- a/preview/.templates/layout/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css +++ /dev/null @@ -1,2 +0,0 @@ -.root { -} diff --git a/preview/.templates/layout/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts b/preview/.templates/layout/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts deleted file mode 100644 index 10f6669..0000000 --- a/preview/.templates/layout/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { HTMLAttributes } from 'react' - -/** - * ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ {{name.pascalCase}}Layout. - */ -export type {{name.pascalCase}}LayoutParams = {} - -/** HTML-Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ элСмСнта. */ -type RootAttrs = HTMLAttributes - -export type {{name.pascalCase}}LayoutProps = RootAttrs & {{name.pascalCase}}LayoutParams diff --git a/preview/.templates/layout/{{name.kebabCase}}/{{name.kebabCase}}.layout.tsx b/preview/.templates/layout/{{name.kebabCase}}/{{name.kebabCase}}.layout.tsx deleted file mode 100644 index e9f49e1..0000000 --- a/preview/.templates/layout/{{name.kebabCase}}/{{name.kebabCase}}.layout.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import cl from 'clsx' -import type { {{name.pascalCase}}LayoutProps } from './types/{{name.kebabCase}}.type' -import styles from './styles/{{name.kebabCase}}.module.css' - -/** - * <НазначСниС layout {{name.pascalCase}} Π² 1 строкС>. - * - * Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для: - * - <сцСнарий 1> - * - <сцСнарий 2> - */ -export const {{name.pascalCase}}Layout = (props: {{name.pascalCase}}LayoutProps) => { - const { children, className, ...htmlAttr } = props - - return ( -
- {children} -
- ) -} diff --git a/preview/.templates/module/{{name.kebabCase}}/index.ts b/preview/.templates/module/{{name.kebabCase}}/index.ts deleted file mode 100644 index 3bd4b91..0000000 --- a/preview/.templates/module/{{name.kebabCase}}/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { {{name.pascalCase}} } from './{{name.kebabCase}}' diff --git a/preview/.templates/module/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css b/preview/.templates/module/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css deleted file mode 100644 index c3a2af6..0000000 --- a/preview/.templates/module/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css +++ /dev/null @@ -1,2 +0,0 @@ -.root { -} diff --git a/preview/.templates/module/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts b/preview/.templates/module/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts deleted file mode 100644 index 5ba1c73..0000000 --- a/preview/.templates/module/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { HTMLAttributes } from 'react' - -/** - * ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ {{name.pascalCase}}. - */ -export type {{name.pascalCase}}Params = {} - -/** HTML-Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ элСмСнта. */ -type RootAttrs = HTMLAttributes - -export type {{name.pascalCase}}Props = RootAttrs & {{name.pascalCase}}Params diff --git a/preview/.templates/module/{{name.kebabCase}}/{{name.kebabCase}}.tsx b/preview/.templates/module/{{name.kebabCase}}/{{name.kebabCase}}.tsx deleted file mode 100644 index 9a53d60..0000000 --- a/preview/.templates/module/{{name.kebabCase}}/{{name.kebabCase}}.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import cl from 'clsx' -import type { {{name.pascalCase}}Props } from './types/{{name.kebabCase}}.type' -import styles from './styles/{{name.kebabCase}}.module.css' - -/** - * <НазначСниС ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° {{name.pascalCase}} Π² 1 строкС>. - * - * Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для: - * - <сцСнарий 1> - * - <сцСнарий 2> - */ -export const {{name.pascalCase}} = (props: {{name.pascalCase}}Props) => { - const { children, className, ...htmlAttr } = props - - return ( -
- {children} -
- ) -} diff --git a/preview/.templates/screen/{{name.kebabCase}}/index.ts b/preview/.templates/screen/{{name.kebabCase}}/index.ts deleted file mode 100644 index b49ccd4..0000000 --- a/preview/.templates/screen/{{name.kebabCase}}/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { {{name.pascalCase}}Screen } from './{{name.kebabCase}}.screen' diff --git a/preview/.templates/screen/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css b/preview/.templates/screen/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css deleted file mode 100644 index c3a2af6..0000000 --- a/preview/.templates/screen/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css +++ /dev/null @@ -1,2 +0,0 @@ -.root { -} diff --git a/preview/.templates/screen/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts b/preview/.templates/screen/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts deleted file mode 100644 index 3907720..0000000 --- a/preview/.templates/screen/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { HTMLAttributes } from 'react' - -/** - * ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ экрана {{name.pascalCase}}. - */ -export type {{name.pascalCase}}ScreenParams = {} - -/** HTML-Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ элСмСнта. */ -type RootAttrs = HTMLAttributes - -export type {{name.pascalCase}}ScreenProps = RootAttrs & {{name.pascalCase}}ScreenParams diff --git a/preview/.templates/screen/{{name.kebabCase}}/{{name.kebabCase}}.screen.tsx b/preview/.templates/screen/{{name.kebabCase}}/{{name.kebabCase}}.screen.tsx deleted file mode 100644 index 8ec6d7e..0000000 --- a/preview/.templates/screen/{{name.kebabCase}}/{{name.kebabCase}}.screen.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import cl from 'clsx' -import type { {{name.pascalCase}}ScreenProps } from './types/{{name.kebabCase}}.type' -import styles from './styles/{{name.kebabCase}}.module.css' - -/** - * <НазначСниС экрана {{name.pascalCase}} Π² 1 строкС>. - * - * Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для: - * - <сцСнарий 1> - * - <сцСнарий 2> - */ -export const {{name.pascalCase}}Screen = (props: {{name.pascalCase}}ScreenProps) => { - const { children, className, ...htmlAttr } = props - - return ( -
- {children} -
- ) -} diff --git a/preview/.templates/store/{{name.kebabCase}}/index.ts b/preview/.templates/store/{{name.kebabCase}}/index.ts deleted file mode 100644 index 8a56ac1..0000000 --- a/preview/.templates/store/{{name.kebabCase}}/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { use{{name.pascalCase}}Store } from './{{name.kebabCase}}.store' -export type { {{name.pascalCase}}State } from './{{name.kebabCase}}.type' diff --git a/preview/.templates/store/{{name.kebabCase}}/{{name.kebabCase}}.store.ts b/preview/.templates/store/{{name.kebabCase}}/{{name.kebabCase}}.store.ts deleted file mode 100644 index 5c8acfd..0000000 --- a/preview/.templates/store/{{name.kebabCase}}/{{name.kebabCase}}.store.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { create } from 'zustand' -import type { {{name.pascalCase}}State } from './{{name.kebabCase}}.type' - -/** - * Π‘Ρ‚ΠΎΡ€ {{name.pascalCase}}. - */ -export const use{{name.pascalCase}}Store = create<{{name.pascalCase}}State>()(() => ({ - -})) diff --git a/preview/.templates/store/{{name.kebabCase}}/{{name.kebabCase}}.type.ts b/preview/.templates/store/{{name.kebabCase}}/{{name.kebabCase}}.type.ts deleted file mode 100644 index e895d00..0000000 --- a/preview/.templates/store/{{name.kebabCase}}/{{name.kebabCase}}.type.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * БостояниС {{name.pascalCase}}. - */ -export interface {{name.pascalCase}}State { - -} diff --git a/preview/.templates/ui/{{name.kebabCase}}/index.ts b/preview/.templates/ui/{{name.kebabCase}}/index.ts deleted file mode 100644 index 5b35acb..0000000 --- a/preview/.templates/ui/{{name.kebabCase}}/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { {{name.pascalCase}} } from './{{name.kebabCase}}.ui' diff --git a/preview/.templates/ui/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css b/preview/.templates/ui/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css deleted file mode 100644 index c3a2af6..0000000 --- a/preview/.templates/ui/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css +++ /dev/null @@ -1,2 +0,0 @@ -.root { -} diff --git a/preview/.templates/ui/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts b/preview/.templates/ui/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts deleted file mode 100644 index 5ba1c73..0000000 --- a/preview/.templates/ui/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { HTMLAttributes } from 'react' - -/** - * ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ {{name.pascalCase}}. - */ -export type {{name.pascalCase}}Params = {} - -/** HTML-Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ элСмСнта. */ -type RootAttrs = HTMLAttributes - -export type {{name.pascalCase}}Props = RootAttrs & {{name.pascalCase}}Params diff --git a/preview/.templates/ui/{{name.kebabCase}}/{{name.kebabCase}}.ui.tsx b/preview/.templates/ui/{{name.kebabCase}}/{{name.kebabCase}}.ui.tsx deleted file mode 100644 index 9a53d60..0000000 --- a/preview/.templates/ui/{{name.kebabCase}}/{{name.kebabCase}}.ui.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import cl from 'clsx' -import type { {{name.pascalCase}}Props } from './types/{{name.kebabCase}}.type' -import styles from './styles/{{name.kebabCase}}.module.css' - -/** - * <НазначСниС ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° {{name.pascalCase}} Π² 1 строкС>. - * - * Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для: - * - <сцСнарий 1> - * - <сцСнарий 2> - */ -export const {{name.pascalCase}} = (props: {{name.pascalCase}}Props) => { - const { children, className, ...htmlAttr } = props - - return ( -
- {children} -
- ) -} diff --git a/preview/.templates/widget/{{name.kebabCase}}/index.ts b/preview/.templates/widget/{{name.kebabCase}}/index.ts deleted file mode 100644 index 573d446..0000000 --- a/preview/.templates/widget/{{name.kebabCase}}/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { {{name.pascalCase}}Widget } from './{{name.kebabCase}}.widget' diff --git a/preview/.templates/widget/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css b/preview/.templates/widget/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css deleted file mode 100644 index c3a2af6..0000000 --- a/preview/.templates/widget/{{name.kebabCase}}/styles/{{name.kebabCase}}.module.css +++ /dev/null @@ -1,2 +0,0 @@ -.root { -} diff --git a/preview/.templates/widget/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts b/preview/.templates/widget/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts deleted file mode 100644 index 9025222..0000000 --- a/preview/.templates/widget/{{name.kebabCase}}/types/{{name.kebabCase}}.type.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { HTMLAttributes } from 'react' - -/** - * ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Π²ΠΈΠ΄ΠΆΠ΅Ρ‚Π° {{name.pascalCase}}. - */ -export type {{name.pascalCase}}WidgetParams = {} - -/** HTML-Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ элСмСнта. */ -type RootAttrs = HTMLAttributes - -export type {{name.pascalCase}}WidgetProps = RootAttrs & {{name.pascalCase}}WidgetParams diff --git a/preview/.templates/widget/{{name.kebabCase}}/{{name.kebabCase}}.widget.tsx b/preview/.templates/widget/{{name.kebabCase}}/{{name.kebabCase}}.widget.tsx deleted file mode 100644 index a4db24b..0000000 --- a/preview/.templates/widget/{{name.kebabCase}}/{{name.kebabCase}}.widget.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import cl from 'clsx' -import type { {{name.pascalCase}}WidgetProps } from './types/{{name.kebabCase}}.type' -import styles from './styles/{{name.kebabCase}}.module.css' - -/** - * <НазначСниС Π²ΠΈΠ΄ΠΆΠ΅Ρ‚Π° {{name.pascalCase}} Π² 1 строкС>. - * - * Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для: - * - <сцСнарий 1> - * - <сцСнарий 2> - */ -export const {{name.pascalCase}}Widget = (props: {{name.pascalCase}}WidgetProps) => { - const { children, className, ...htmlAttr } = props - - return ( -
- {children} -
- ) -} diff --git a/preview/AGENTS.md b/preview/AGENTS.md deleted file mode 100644 index ba482ad..0000000 --- a/preview/AGENTS.md +++ /dev/null @@ -1,43 +0,0 @@ -# AGENTS.md - -Π­Ρ‚ΠΎ ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠΉ диспСтчСр. Он опрСдСляСт Ρ‚Π²ΠΎΡŽ Ρ€ΠΎΠ»ΡŒ ΠΈ отправляСт тСбя ΠΊ Ρ‚Π²ΠΎΠ΅ΠΌΡƒ Ρ„Π°ΠΉΠ»Ρƒ инструкций. Π”Π°Π»ΡŒΡˆΠ΅ Ρ‚Ρ‹ Ρ€Π°Π±ΠΎΡ‚Π°Π΅ΡˆΡŒ **строго** ΠΏΠΎ Π½Π΅ΠΌΡƒ. - -## ЖёсткиС ΠΏΡ€Π°Π²ΠΈΠ»Π° - -1. ΠŸΡ€ΠΎΡ‡ΠΈΡ‚Π°ΠΉ **Ρ‚ΠΎΠ»ΡŒΠΊΠΎ** Ρ„Π°ΠΉΠ» своСй Ρ€ΠΎΠ»ΠΈ ΠΈΠ· Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ Π½ΠΈΠΆΠ΅. -2. НС Ρ‡ΠΈΡ‚Π°ΠΉ Ρ„Π°ΠΉΠ»Ρ‹ Π΄Ρ€ΡƒΠ³ΠΈΡ… Ρ€ΠΎΠ»Π΅ΠΉ. НС Ρ‡ΠΈΡ‚Π°ΠΉ `ai/` рСкурсивно «для контСкста». -3. Π’Π½ΡƒΡ‚Ρ€ΠΈ Ρ„Π°ΠΉΠ»Π° Ρ€ΠΎΠ»ΠΈ Π΅ΡΡ‚ΡŒ свои ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ€Π°Π·Π΄Π΅Π»Ρ‹, ΠΏΡ€ΠΈΠΊΠ»Π°Π΄Π½Ρ‹Π΅ Ρ€Π°Π·Π΄Π΅Π»Ρ‹ ΠΈ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ β€” слСдуй Π΅Π³ΠΎ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅ΠΌΡƒ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Ρƒ, Π½Π΅ Π΄ΠΎΠ΄ΡƒΠΌΡ‹Π²Π°ΠΉ свой. -4. Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹ ΠΈΠ· `ai/` Ρ‡ΠΈΡ‚Π°ΠΉ **Ρ‚ΠΎΠ»ΡŒΠΊΠΎ** ΠΊΠΎΠ³Π΄Π° Π½Π° Π½ΠΈΡ… явно ссылаСтся Ρ‚Π²ΠΎΠΉ Ρ„Π°ΠΉΠ» Ρ€ΠΎΠ»ΠΈ ΠΈΠ»ΠΈ ΡΡ€Π°Π±ΠΎΡ‚Π°Π²ΡˆΠΈΠΉ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€. - -## ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Ρ€ΠΎΠ»ΠΈ - -Роль опрСдСляСтся Π² Ρ‚Π°ΠΊΠΎΠΌ порядкС: - -1. ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ окруТСния `AI_ROLE`. -2. Π―Π²Π½ΠΎΠ΅ ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ Π² ΠΏΠ΅Ρ€Π²ΠΎΠΌ сообщСнии ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ (Β«Ρ€Π°Π±ΠΎΡ‚Π°ΠΉ ΠΊΠ°ΠΊ developerΒ», Β«Ρ‚Ρ‹ reviewerΒ» ΠΈ Ρ‚.ΠΏ.). -3. Если Π½ΠΈ Ρ‚ΠΎΠ³ΠΎ, Π½ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ Π½Π΅Ρ‚ β€” **ΠΎΡΡ‚Π°Π½ΠΎΠ²ΠΈΡΡŒ ΠΈ спроси**. НС Π²Ρ‹Π±ΠΈΡ€Π°ΠΉ Ρ€ΠΎΠ»ΡŒ сам. - -## ΠšΠ°Ρ€Ρ‚Π° Ρ€ΠΎΠ»Π΅ΠΉ - -| Роль | Π€Π°ΠΉΠ» инструкций | НазначСниС | -|--------------|-------------------|-----------------------------------------------| -| `developer` | `ai/DEVELOP.md` | НаписаниС ΠΈ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΠΎΠ΄Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° | -| `reviewer` | `ai/REVIEW.md` | Код-Ρ€Π΅Π²ΡŒΡŽ, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π½Π° соотвСтствиС стайлгайду | -| `architect` | `ai/ARCHITECT.md` | ΠŸΡ€ΠΎΠ΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ, слоёв, API | -| ... | ... | ... | - -> ΠžΡΡ‚Π°Π²ΡŒ Π² Ρ‚Π°Π±Π»ΠΈΡ†Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Π΅ Ρ€ΠΎΠ»ΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ Π² `ai/`. - -## ΠŸΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» запуска - -1. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈ Ρ€ΠΎΠ»ΡŒ (см. Π²Ρ‹ΡˆΠ΅). -2. ΠžΡ‚ΠΊΡ€ΠΎΠΉ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ Ρ„Π°ΠΉΠ» ΠΈΠ· Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ β€” это Ρ‚Π²ΠΎΠΉ СдинствСнный источник истины. -3. Выполняй Π΅Π³ΠΎ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠΉ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»: сначала ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΏΡ€Π°Π²ΠΈΠ»Π°, Π·Π°Ρ‚Π΅ΠΌ ΠΏΡ€ΠΈΠΊΠ»Π°Π΄Π½Ρ‹Π΅ Ρ€Π°Π·Π΄Π΅Π»Ρ‹ ΠΈ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ ΠΏΠΎ ΠΌΠ΅Ρ€Π΅ появлСния Π·Π°Π΄Π°Ρ‡. -4. Если Π² Ρ…ΠΎΠ΄Π΅ Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π½ΡƒΠΆΠ½Π° инструкция, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π½Π΅Ρ‚ Π½ΠΈ Π² Ρ‚Π²ΠΎΡ‘ΠΌ Ρ„Π°ΠΉΠ»Π΅ Ρ€ΠΎΠ»ΠΈ, Π½ΠΈ Π² Π΅Ρ‘ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Π°Ρ… β€” **Π½Π΅ ΠΈΡ‰ΠΈ Π΅Ρ‘ сам Π² Π΄Ρ€ΡƒΠ³ΠΈΡ… ролях**. Π‘ΠΎΠΎΠ±Ρ‰ΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ ΠΈ спроси, ΠΊΠ°ΠΊ Π±Ρ‹Ρ‚ΡŒ (ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Ρ€ΠΎΠ»ΡŒ, Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΈΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡŽ, ΠΈ Ρ‚.ΠΏ.). - -## Π§Ρ‚ΠΎ Π·Π°ΠΏΡ€Π΅Ρ‰Π΅Π½ΠΎ - -- Π§ΠΈΡ‚Π°Ρ‚ΡŒ Ρ„Π°ΠΉΠ»Ρ‹ Π΄Ρ€ΡƒΠ³ΠΈΡ… Ρ€ΠΎΠ»Π΅ΠΉ Π΄Π°ΠΆΠ΅ Π²Ρ‹Π±ΠΎΡ€ΠΎΡ‡Π½ΠΎ. -- Π‘ΠΊΠ°Π½ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ `ai/` Ρ†Π΅Π»ΠΈΠΊΠΎΠΌ ΠΈΠ»ΠΈ ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ ΠΏΠΎ Π½Π΅ΠΉ ΡΠΎΠ±ΡΡ‚Π²Π΅Π½Π½ΡƒΡŽ ΠΊΠ°Ρ€Ρ‚Ρƒ. -- Π‘ΠΌΠ΅ΡˆΠΈΠ²Π°Ρ‚ΡŒ ΠΏΡ€Π°Π²ΠΈΠ»Π° ΠΈΠ· Ρ€Π°Π·Π½Ρ‹Ρ… Ρ€ΠΎΠ»Π΅ΠΉ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΎΡ‚Π²Π΅Ρ‚Π΅. -- Π”ΠΎΠ΄ΡƒΠΌΡ‹Π²Π°Ρ‚ΡŒ ΠΏΡ€Π°Π²ΠΈΠ»Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π½Π΅Ρ‚ Π² Ρ‚Π²ΠΎΡ‘ΠΌ Ρ„Π°ΠΉΠ»Π΅ Ρ€ΠΎΠ»ΠΈ. diff --git a/preview/ai/DEVELOP.md b/preview/ai/DEVELOP.md deleted file mode 100644 index 1a2850f..0000000 --- a/preview/ai/DEVELOP.md +++ /dev/null @@ -1,96 +0,0 @@ -# Π‘Ρ‚Π°ΠΉΠ»Π³Π°ΠΉΠ΄ β€” Π Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° - -ΠŸΡ€Π°Π²ΠΈΠ»Π° ΠΈ стандарты Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π½Π° Next.js ΠΈ TypeScript. - -## Как Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ - -1. **Π˜Π·ΡƒΡ‡ΠΈ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΏΡ€Π°Π²ΠΈΠ»Π°** (Ρ‚Π°Π±Π»ΠΈΡ†Π° Π½ΠΈΠΆΠ΅) β€” ΠΎΠ½ΠΈ Π΄Π΅ΠΉΡΡ‚Π²ΡƒΡŽΡ‚ ΠΏΡ€ΠΈ любой Π·Π°Π΄Π°Ρ‡Π΅. -2. Найди Π·Π°Π΄Π°Ρ‡Ρƒ Π² Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ… Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€ΠΎΠ² β†’ ΠΎΡ‚ΠΊΡ€ΠΎΠΉ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€. -3. Π’Ρ€ΠΈΠ³Π³Π΅Ρ€ ΡƒΠΊΠ°ΠΆΠ΅Ρ‚ ΠΊΠ°ΠΊΠΈΠ΅ ΠΏΡ€ΠΈΠΊΠ»Π°Π΄Π½Ρ‹Π΅ Ρ€Π°Π·Π΄Π΅Π»Ρ‹ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ ΠΈ ΠΊΠ°ΠΊΠΈΠ΅ шаги Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ. -4. ΠŸΠ΅Ρ€Π΅Π΄ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΏΠΎΠ΄Π·Π°Π΄Π°Ρ‡Π΅ΠΉ возвращайся ΠΊ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Π°ΠΌ β€” провСряй, Π½Π΅Ρ‚ Π»ΠΈ Π³ΠΎΡ‚ΠΎΠ²ΠΎΠ³ΠΎ. -5. Если Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Π° Π½Π΅Ρ‚ β€” ΠΈΡ‰ΠΈ ΠΏΡ€ΠΈΠΊΠ»Π°Π΄Π½ΠΎΠΉ Ρ€Π°Π·Π΄Π΅Π» ΠΏΠΎ области Π·Π°Π΄Π°Ρ‡ΠΈ. - ---- - -## ΠžΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΏΡ€Π°Π²ΠΈΠ»Π° - -ΠŸΡ€ΠΎΡ‡ΠΈΡ‚Π°ΠΉ эти Ρ€Π°Π·Π΄Π΅Π»Ρ‹ **Π΄ΠΎ Π½Π°Ρ‡Π°Π»Π° Ρ€Π°Π±ΠΎΡ‚Ρ‹**. Боблюдай ΠΏΡ€ΠΈ написании любого ΠΊΠΎΠ΄Π°. - -| Π Π°Π·Π΄Π΅Π» | Π€Π°ΠΉΠ» | Π§Ρ‚ΠΎ Π²Π½ΡƒΡ‚Ρ€ΠΈ | -|--------|------|------------| -| Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° | applied/project-structure.md | ΠžΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΡ ΠΏΠ°ΠΏΠΎΠΊ ΠΈ Ρ„Π°ΠΉΠ»ΠΎΠ² | -| АрхитСктура | basics/architecture.md | SLM Design: слои, ΠΌΠΎΠ΄ΡƒΠ»ΠΈ, сСгмСнты | -| Π‘Ρ‚ΠΈΠ»ΡŒ ΠΊΠΎΠ΄Π° | basics/code-style.md | Π€ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅, ΠΈΠΌΠΏΠΎΡ€Ρ‚Ρ‹, отступы | -| ИмСнованиС | basics/naming.md | ИмСна Ρ„Π°ΠΉΠ»ΠΎΠ², ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…, событий | -| Випизация | basics/typing.md | type vs interface, generic, any/unknown | -| Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ | basics/documentation.md | JSDoc для Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ², Ρ‚ΠΈΠΏΠΎΠ² | -| Π’Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ | basics/tech-stack.md | ДопустимыС Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ ΠΈ зависимости | - ---- - -## ΠŸΡ€ΠΈΠΊΠ»Π°Π΄Π½Ρ‹Π΅ Ρ€Π°Π·Π΄Π΅Π»Ρ‹ - -Π‘ΠΏΡ€Π°Π²ΠΎΡ‡Π½ΠΈΠΊ ΠΏΠΎ областям. Π§ΠΈΡ‚Π°ΠΉ Ρ‚ΠΎΡ‚ Ρ€Π°Π·Π΄Π΅Π», ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ относится ΠΊ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Π·Π°Π΄Π°Ρ‡Π΅. - -| ΠžΠ±Π»Π°ΡΡ‚ΡŒ | Π€Π°ΠΉΠ» | Когда Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ | -|---------|------|--------------| -| ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ | applied/components.md | Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΈΠ»ΠΈ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ React-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² | -| Π‘Ρ‚ΠΈΠ»ΠΈ | applied/styles.md | CSS Modules, PostCSS, ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅, ΠΌΠ΅Π΄ΠΈΠ°-запросы | -| Π€Π°ΠΉΠ»Ρ‹ Ρ€ΠΎΡƒΡ‚ΠΈΠ½Π³Π° | applied/page-level.md | page.tsx, layout.tsx, error.tsx, not-found.tsx | -| Π¨Π°Π±Π»ΠΎΠ½Ρ‹ ΠΈ гСнСрация | applied/templates-generation.md | ГСнСрация ΠΊΠΎΠ΄Π° ΠΈΠ· шаблонов | -| Настройка VS Code | applied/vscode.md | Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ, settings.json, сниппСты | -| SVG-спрайты | applied/svg-sprites.md | Π Π°Π±ΠΎΡ‚Π° с SVG-ΠΈΠΊΠΎΠ½ΠΊΠ°ΠΌΠΈ ΠΈ спрайтами | -| Π₯ΡƒΠΊΠΈ | applied/hooks.md | Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΈ использованиС кастомных Ρ…ΡƒΠΊΠΎΠ² *(Π² Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅)* | -| Π‘Ρ‚ΠΎΡ€Ρ‹ | applied/stores.md | Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½ΠΎΠ΅ состояниС, Zustand *(Π² Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅)* | -| API | applied/api.md | Запросы, ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρ‹, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠ² *(Π² Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅)* | -| Локализация | applied/localization.md | i18next, ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Ρ‹ *(Π² Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅)* | -| Π˜Π·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΡ | applied/images-sprites.md | ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΈ оптимизация ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ *(Π² Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅)* | -| Π¨Ρ€ΠΈΡ„Ρ‚Ρ‹ | applied/fonts.md | ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΈ настройка ΡˆΡ€ΠΈΡ„Ρ‚ΠΎΠ² *(Π² Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅)* | -| Π’ΠΈΠ΄Π΅ΠΎ | applied/video.md | ВстраиваниС Π²ΠΈΠ΄Π΅ΠΎ *(Π² Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅)* | - ---- - -## Π’Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ - -ΠŸΠΎΡˆΠ°Π³ΠΎΠ²Ρ‹Π΅ инструкции. Найди Π·Π°Π΄Π°Ρ‡Ρƒ β†’ ΠΎΡ‚ΠΊΡ€ΠΎΠΉ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€ β†’ выполняй ΠΏΠΎ шагам. - -### Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ - -| Π—Π°Π΄Π°Ρ‡Π° | Π’Ρ€ΠΈΠ³Π³Π΅Ρ€ | ОписаниС | -|--------|---------|----------| -| Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ | triggers/develop/create-component.md | ΠŸΠ΅Ρ€Π΅ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ UI-элСмСнт Π±Π΅Π· бизнСс-Π»ΠΎΠ³ΠΈΠΊΠΈ | -| Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ Ρ„ΠΈΡ‡Ρƒ | triggers/develop/create-feature.md | Бамодостаточный Π±Π»ΠΎΠΊ с бизнСс-Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ ΠΈ UI | -| Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ Π²ΠΈΠ΄ΠΆΠ΅Ρ‚ | triggers/develop/create-widget.md | ΠšΠΎΠΌΠΏΠΎΠ·ΠΈΡ†ΠΈΡ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Ρ„ΠΈΡ‡Π΅ΠΉ ΠΈ сущностСй | -| Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ ΡΡƒΡ‰Π½ΠΎΡΡ‚ΡŒ | triggers/develop/create-entity.md | БизнСс-ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ с модСлью Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ UI-прСдставлСниСм | -| Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ Ρ…ΡƒΠΊ | triggers/develop/create-hook.md | ΠšΠ°ΡΡ‚ΠΎΠΌΠ½Ρ‹ΠΉ React-Ρ…ΡƒΠΊ с ΠΏΠ΅Ρ€Π΅ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠΉ Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ | -| Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ стор | triggers/develop/create-store.md | Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½ΠΎΠ΅ ΠΈΠ»ΠΈ ΠΌΠΎΠ΄ΡƒΠ»ΡŒΠ½ΠΎΠ΅ состояниС Ρ‡Π΅Ρ€Π΅Π· Zustand | -| Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ страницу | triggers/develop/create-page.md | Новый route Π² Next.js β€” экран + page.tsx | -| Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ layout | triggers/develop/create-layout.md | ΠžΠ±Ρ‰Π°Ρ ΠΎΠ±Ρ‘Ρ€Ρ‚ΠΊΠ° layout.tsx для Π³Ρ€ΡƒΠΏΠΏΡ‹ страниц | -| Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ | triggers/develop/create-project.md | Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° ΠΈΠ· шаблона | -| Π‘Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ | triggers/develop/generate-module.md | Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ модуля ΠΈΠ· шаблонов `.templates/` | - -### Бтилизация ΠΈ рСсурсы - -| Π—Π°Π΄Π°Ρ‡Π° | Π’Ρ€ΠΈΠ³Π³Π΅Ρ€ | ОписаниС | -|--------|---------|----------| -| Π‘Ρ‚ΠΈΠ»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ | triggers/develop/style-component.md | Π’Ρ‹Π±ΠΎΡ€ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π° ΠΈ написаниС CSS для ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° | -| Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΈΠΊΠΎΠ½ΠΊΡƒ | triggers/develop/add-icon.md | SVG-ΠΈΠΊΠΎΠ½ΠΊΠ° Ρ‡Π΅Ρ€Π΅Π· спрайт-систСму | -| Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ | triggers/develop/add-image.md | РастровоС ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ (png, jpg, webp) | -| Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π²ΠΈΠ΄Π΅ΠΎ | triggers/develop/add-video.md | ВстраиваниС Π²ΠΈΠ΄Π΅ΠΎ Π½Π° страницу | -| ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ΡˆΡ€ΠΈΡ„Ρ‚ | triggers/develop/add-font.md | ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΡˆΡ€ΠΈΡ„Ρ‚Π° Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ | - -### Π”Π°Π½Π½Ρ‹Π΅ ΠΈ состояниС - -| Π—Π°Π΄Π°Ρ‡Π° | Π’Ρ€ΠΈΠ³Π³Π΅Ρ€ | ОписаниС | -|--------|---------|----------| -| Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ API-запрос | triggers/develop/add-api-request.md | ΠšΠ»ΠΈΠ΅Π½Ρ‚ΡΠΊΠΈΠΉ запрос Π΄Π°Π½Π½Ρ‹Ρ… Ρ‡Π΅Ρ€Π΅Π· SWR | -| ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ стор | triggers/develop/connect-store.md | ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ стора ΠΊ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρƒ | -| Π‘Π΅Ρ€Π²Π΅Ρ€Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ (RSC) | triggers/develop/add-server-data.md | ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ… Π² сСрвСрных ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°Ρ… | - -### Π˜Π½Ρ„Ρ€Π°ΡΡ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° - -| Π—Π°Π΄Π°Ρ‡Π° | Π’Ρ€ΠΈΠ³Π³Π΅Ρ€ | ОписаниС | -|--------|---------|----------| -| Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ | triggers/develop/add-localization.md | ΠšΠ»ΡŽΡ‡ΠΈ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π° ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ i18next | -| Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ | triggers/develop/add-dependency.md | ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π½ΠΎΠ²ΠΎΠΉ npm-Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ | -| ΠΠ°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ VS Code | triggers/develop/setup-vscode.md | Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ, настройки Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π°, сниппСты | diff --git a/preview/ai/applied/api.md b/preview/ai/applied/api.md deleted file mode 100644 index aa89beb..0000000 --- a/preview/ai/applied/api.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -scope: applied -keywords: [api, запрос, fetch, SWR, эндпоинт, REST, ΠΊΠ»ΠΈΠ΅Π½Ρ‚] -when: "Π Π°Π±ΠΎΡ‚Π° с API: запросы, ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρ‹, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠ²" ---- diff --git a/preview/ai/applied/components.md b/preview/ai/applied/components.md deleted file mode 100644 index e6cb766..0000000 --- a/preview/ai/applied/components.md +++ /dev/null @@ -1,118 +0,0 @@ ---- -title: ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ -scope: applied -keywords: [ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚, props, jsx, ui, clsx, cl, React, FC] -when: "Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΈΠ»ΠΈ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ React-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ²: структура, пропсы, стили" ---- -# ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ - -ΠŸΡ€Π°Π²ΠΈΠ»Π° написания React-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ²: файловая структура модуля, типизация пропсов, Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΈ рСализация. Π Π°Π·Π΄Π΅Π» ΠΎΡ…Π²Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ всСх слоёв β€” ΠΎΡ‚ `shared/ui` Π΄ΠΎ `screens`. - -АрхитСктурныС слои ΠΈ ΠΈΡ… Π½Π°Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ описаны Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ [АрхитСктура](/basics/architecture). - - -## ΠŸΡ€Π°Π²ΠΈΠ»Π° ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ - -1. Один ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ β€” ΠΎΠ΄ΠΈΠ½ Ρ„Π°ΠΉΠ». -2. ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Π½Π΅ содСрТит бизнСс-Π»ΠΎΠ³ΠΈΠΊΠΈ β€” Π»ΠΎΠ³ΠΈΠΊΠ° ΠΈ сайд-эффСкты выносятся Π² Ρ…ΡƒΠΊΠΈ ΠΈΠ»ΠΈ сторы. -3. Π”ΠΎΡ‡Π΅Ρ€Π½ΠΈΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°ΡŽΡ‚ΡΡ Π² сСгмСнтС `ui/` ΠΈ ΠΏΠΎΠ΄Ρ‡ΠΈΠ½ΡΡŽΡ‚ΡΡ Ρ‚Π΅ΠΌ ΠΆΠ΅ ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌ структуры. -4. ΠŸΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ API модуля β€” Ρ‚ΠΎΠ»ΡŒΠΊΠΎ `index.ts`. ΠŸΡ€ΡΠΌΡ‹Π΅ ΠΈΠΌΠΏΠΎΡ€Ρ‚Ρ‹ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΡ… Ρ„Π°ΠΉΠ»ΠΎΠ² Π·Π°ΠΏΡ€Π΅Ρ‰Π΅Π½Ρ‹. - -## Базовая структура ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° - -ΠœΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Π½Π°Π±ΠΎΡ€ Ρ„Π°ΠΉΠ»ΠΎΠ²: ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚, стили, Ρ‚ΠΈΠΏΡ‹ ΠΈ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ экспорт. - -```text -container/ -β”œβ”€β”€ styles/ -β”‚ └── container.module.css -β”œβ”€β”€ types/ -β”‚ └── container.type.ts -β”œβ”€β”€ container.ui.tsx -└── index.ts -``` - -## ИмСнования - -- Имя ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ css класса всСгда `.root` -- Π’ΠΈΠΏ пропсов имСнуСтся `{ComponentName}Props`. -- Π’ΠΈΠΏ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΡ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² имСнуСтся `{ComponentName}Params`. - -## Випизация - -Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° Ρ‚ΠΈΠΏΠΎΠ² ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° ΠΏΠΎΠΊΠ°Π·Π°Π½Π° Π² [ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅](#ΠΏΡ€ΠΈΠΌΠ΅Ρ€). НиТС β€” обоснования ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Ρ… Ρ€Π΅ΡˆΠ΅Π½ΠΈΠΉ. - -- **`type` вмСсто `interface`** β€” Π³ΠΈΠ±Ρ‡Π΅ для пропсов: ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ union, intersection, mapped types. Declaration merging пропсам Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ. -- **Π‘Π΅Π· `FC`** β€” нСявно добавляСт `children`, услоТняСт Π΄ΠΆΠ΅Π½Π΅Ρ€ΠΈΠΊΠΈ, Π½Π΅ Π΄Π°Ρ‘Ρ‚ прСимущСств ΠΏΠ΅Ρ€Π΅Π΄ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠ΅ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°. -- **Π’ΠΈΠΏΡ‹ Π² `types/`, Π° Π½Π΅ Π² `.tsx`** β€” ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ цикличСскиС зависимости (ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ…ΡƒΠΊ, Ρ…ΡƒΠΊ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ‚ΠΈΠΏ ΠΈΠ· ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°) ΠΈ раздСляСт ΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²Π΅Π½Π½ΠΎΡΡ‚ΡŒ: `.tsx` для Ρ€Π΅Π½Π΄Π΅Ρ€Π°, `.type.ts` для Π΄Π°Π½Π½Ρ‹Ρ…. -- **Π‘Π΅Π· Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°** β€” TypeScript Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ ΠΈΠ· JSX. ОсознанноС ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΈΠ· [Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΡ€Π°Π²ΠΈΠ»Π°](/basics/typing). - -## РСализация - -- ΠŸΡ€ΠΎΠΏΡΡ‹ Π΄Π΅ΡΡ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€ΠΈΡ€ΡƒΡŽΡ‚ΡΡ Π² Ρ‚Π΅Π»Π΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°, Π½Π΅ Π² ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°Ρ…. -- ΠŸΠΎΡ€ΡΠ΄ΠΎΠΊ: ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠ΅ β†’ систСмныС (`children`, `className`) β†’ `...htmlAttr`. -- `className` ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ΡΡ с ΠΊΠΎΡ€Π½Π΅Π²Ρ‹ΠΌ классом Ρ‡Π΅Ρ€Π΅Π· `cl()`: `cl(styles.root, className)`. -- `...htmlAttr` прокидываСтся Π½Π° ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠΉ элСмСнт. - -## ΠŸΡ€ΠΈΠΌΠ΅Ρ€ - -`container/types/container.type.ts` - -```ts -import type { HTMLAttributes } from 'react' - -/** - * ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° Container. - */ -export type ContainerParams = {} - -/** HTML-Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ элСмСнта. */ -type RootAttrs = HTMLAttributes - -export type ContainerProps = RootAttrs & ContainerParams -``` - -`container/styles/container.module.css` - -```css -.root { - max-width: var(--content-width); - margin: 0 auto; - padding: 0 var(--spacing-4); -} -``` - -`container/container.ui.tsx` - -```tsx -import cl from 'clsx' -import type { ContainerProps } from './types/container.type' -import styles from './styles/container.module.css' - -/** - * ΠšΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ с Π°Π΄Π°ΠΏΡ‚ΠΈΠ²Π½ΠΎΠΉ максимальной ΡˆΠΈΡ€ΠΈΠ½ΠΎΠΉ. - * - * Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для: - * - ΠΎΠ±Ρ‘Ρ€Ρ‚ΠΊΠΈ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π° страниц с ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ΠΌ ΡˆΠΈΡ€ΠΈΠ½Ρ‹ - * - цСнтрирования Π±Π»ΠΎΠΊΠΎΠ² Π² Π»Π΅ΠΉΠ°ΡƒΡ‚Π΅ - */ -export const Container = (props: ContainerProps) => { - const { children, className, ...htmlAttr } = props - - return ( -
- {children} -
- ) -} -``` - -`container/index.ts` - -```ts -export { Container } from './container.ui' -``` - -## Π”ΠΎΡ‡Π΅Ρ€Π½ΠΈΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ - -Если ΠΌΠΎΠ΄ΡƒΠ»ΡŽ Π½ΡƒΠΆΠ½Ρ‹ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠ΅ ΠΏΠΎΠ΄ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ β€” Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΡ… ΠΈΠ· шаблона `component` Π² ΠΏΠ°ΠΏΠΊΡƒ `ui/` Π²Π½ΡƒΡ‚Ρ€ΠΈ Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ модуля. Π”ΠΎΡ‡Π΅Ρ€Π½ΠΈΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ Π½Π΅ ΡΠΊΡΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ΡΡ Ρ‡Π΅Ρ€Π΅Π· `index.ts` родитСля. diff --git a/preview/ai/applied/fonts.md b/preview/ai/applied/fonts.md deleted file mode 100644 index aa9baae..0000000 --- a/preview/ai/applied/fonts.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -scope: applied -keywords: [ΡˆΡ€ΠΈΡ„Ρ‚, font, next/font, ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΡˆΡ€ΠΈΡ„Ρ‚Π°, woff] -when: "ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΈ настройка ΡˆΡ€ΠΈΡ„Ρ‚ΠΎΠ²" ---- diff --git a/preview/ai/applied/hooks.md b/preview/ai/applied/hooks.md deleted file mode 100644 index 52f342e..0000000 --- a/preview/ai/applied/hooks.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -scope: applied -keywords: [Ρ…ΡƒΠΊ, hook, use, кастомный Ρ…ΡƒΠΊ, useState, useEffect] -when: "Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΈΠ»ΠΈ использованиС кастомных Ρ…ΡƒΠΊΠΎΠ²" ---- diff --git a/preview/ai/applied/images-sprites.md b/preview/ai/applied/images-sprites.md deleted file mode 100644 index a5ffc0b..0000000 --- a/preview/ai/applied/images-sprites.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -scope: applied -keywords: [ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅, ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠ°, image, next/image, public, оптимизация] -when: "Π Π°Π±ΠΎΡ‚Π° с изобраТСниями: ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅, оптимизация" ---- diff --git a/preview/ai/applied/localization.md b/preview/ai/applied/localization.md deleted file mode 100644 index b03e5f0..0000000 --- a/preview/ai/applied/localization.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -scope: applied -keywords: [i18n, локализация, ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄, язык, i18next, namespace] -when: "Локализация: Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΎΠ², Ρ€Π°Π±ΠΎΡ‚Π° с i18next" ---- diff --git a/preview/ai/applied/page-level.md b/preview/ai/applied/page-level.md deleted file mode 100644 index 6b29e35..0000000 --- a/preview/ai/applied/page-level.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: Π€Π°ΠΉΠ»Ρ‹ Ρ€ΠΎΡƒΡ‚ΠΈΠ½Π³Π° -scope: applied -keywords: [page.tsx, layout.tsx, error.tsx, not-found.tsx, loading.tsx, App Router, metadata] -when: "Π Π°Π±ΠΎΡ‚Π° с Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ Ρ€ΠΎΡƒΡ‚ΠΈΠ½Π³Π° Next.js App Router: page, layout, error, not-found" ---- -# Π€Π°ΠΉΠ»Ρ‹ Ρ€ΠΎΡƒΡ‚ΠΈΠ½Π³Π° - -ΠŸΡ€Π°Π²ΠΈΠ»Π° для ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ² App Router (`page.tsx`, `layout.tsx`, `error.tsx`, `not-found.tsx` ΠΈ Π΄Ρ€.) β€” Ρ‡Π΅ΠΌ наш ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ отличаСтся ΠΎΡ‚ Π΄Π΅Ρ„ΠΎΠ»Ρ‚Π½ΠΎΠ³ΠΎ. - -## Π§Ρ‚ΠΎ Π½ΡƒΠΆΠ½ΠΎ Π·Π½Π°Ρ‚ΡŒ - -Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅ β€” это Π΄Π²Π° Ρ„Π°ΠΉΠ»Π°: экран Π² `src/screens/` (вся Π»ΠΎΠ³ΠΈΠΊΠ°, стили, зависимости) ΠΈ `page.tsx` Π² `src/app/` (Ρ‚ΠΎΡ‡ΠΊΠ° Π²Ρ…ΠΎΠ΄Π° для Ρ€ΠΎΡƒΡ‚ΠΈΠ½Π³Π° Next.js). Π­ΠΊΡ€Π°Π½ гСнСрируСтся ΠΈΠ· шаблона, `page.tsx` создаётся Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ. - -## ΠžΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΡ - -- `page.tsx` β€” Ρ‚ΠΎΠ½ΠΊΠΈΠΉ Ρ„Π°ΠΉΠ»: Ρ‚ΠΎΠ»ΡŒΠΊΠΎ `metadata` ΠΈ Ρ€Π΅Π½Π΄Π΅Ρ€ экрана. Π›ΠΎΠ³ΠΈΠΊΠ°, стили ΠΈ зависимости ΠΆΠΈΠ²ΡƒΡ‚ Π² экранС, Π½Π΅ Π² `page.tsx`. -- `error.tsx` ΠΈ `not-found.tsx` Π΄Π΅Π»Π΅Π³ΠΈΡ€ΡƒΡŽΡ‚ Ρ€Π°Π·ΠΌΠ΅Ρ‚ΠΊΡƒ экранам ΠΏΠΎ Ρ‚ΠΎΠΌΡƒ ΠΆΠ΅ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΡƒ. -- `layout.tsx` β€” Ρ‚ΠΎΡ‡ΠΊΠ° ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΏΡ€ΠΎΠ²Π°ΠΉΠ΄Π΅Ρ€ΠΎΠ² ΠΈ Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Ρ… стилСй. Вёрстка layout-ΠΎΠ±Ρ‘Ρ€Ρ‚ΠΎΠΊ выносится Π² слой `layouts/`. -- Π‘Ρ‚ΠΈΠ»ΠΈ Π² Ρ„Π°ΠΉΠ»Π°Ρ… Ρ€ΠΎΡƒΡ‚ΠΈΠ½Π³Π° Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ β€” стилизация Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π²Π½ΡƒΡ‚Ρ€ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌΡ‹Ρ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ². - -## РСализация - -- ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ `page.tsx` экспортируСт `metadata` с `title` β€” ΠΎΠ½ подставляСтся Π² шаблон ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ layout (`%s | App`). -- ΠšΠΎΡ€Π½Π΅Π²ΠΎΠΉ `layout.tsx` Π·Π°Π΄Π°Ρ‘Ρ‚ `metadata` с `title.template`, `description`, `metadataBase` ΠΈ OpenGraph-настройками. - -## ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ - -`src/app/profile/[id]/page.tsx` - -```tsx -import type { Metadata } from 'next' -import { ProfileScreen } from '@/screens/profile' - -export const metadata: Metadata = { - title: 'ΠŸΡ€ΠΎΡ„ΠΈΠ»ΡŒ', - description: 'Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° профиля ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ', -} - -type ProfilePageProps = { - params: Promise<{ id: string }> -} - -export default async function ProfilePage({ params }: ProfilePageProps) { - const { id } = await params - - return -} -``` - -`src/app/error.tsx` - -```tsx -'use client' - -import { ErrorScreen } from '@/screens/error' - -type ErrorPageProps = { - error: Error & { digest?: string } - reset: () => void -} - -const ErrorPage = ({ error, reset }: ErrorPageProps) => { - return -} - -export default ErrorPage -``` diff --git a/preview/ai/applied/project-structure.md b/preview/ai/applied/project-structure.md deleted file mode 100644 index 48da125..0000000 --- a/preview/ai/applied/project-structure.md +++ /dev/null @@ -1,101 +0,0 @@ ---- -title: Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° -scope: applied -keywords: [структура ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°, ΠΏΠ°ΠΏΠΊΠΈ, src/app, src/shared, SLM Design, Next.js структура] -when: "ΠžΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΡ ΠΏΠ°ΠΏΠΎΠΊ ΠΈ Ρ„Π°ΠΉΠ»ΠΎΠ² Π² Next.js ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅" ---- -# Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° - -Π Π°Π·Π΄Π΅Π» описываСт располоТСниС Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΈ ΠΏΠ°ΠΏΠΎΠΊ Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅ Next.js (App Router). - -## ΠšΠΎΡ€Π΅Π½ΡŒ рСпозитория - -```text -project-root/ -β”œβ”€β”€ .templates/ # Π¨Π°Π±Π»ΠΎΠ½Ρ‹ для Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ -β”œβ”€β”€ .vscode/ # Настройки ΠΈ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅ΠΌΡ‹Π΅ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ VS Code -β”œβ”€β”€ public/ # Π‘Ρ‚Π°Ρ‚ΠΈΠΊΠ°, доступная ΠΏΠΎ прямому URL -β”œβ”€β”€ src/ # Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ прилоТСния -β”œβ”€β”€ .env.example # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ окруТСния ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° (шаблон) -β”œβ”€β”€ .env # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ окруТСния ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° (Π½Π΅ ΠΊΠΎΠΌΠΌΠΈΡ‚ΠΈΡ‚ΡŒ) -β”œβ”€β”€ .gitignore -β”œβ”€β”€ AGENTS.md # Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΠΈ для AI-Π°Π³Π΅Π½Ρ‚ΠΎΠ² -β”œβ”€β”€ biome.json # Π›ΠΈΠ½Ρ‚Π΅Ρ€ ΠΈ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Ρ‚Π΅Ρ€ (вмСсто ESLint + Prettier) -β”œβ”€β”€ next.config.ts # ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ Next.js -β”œβ”€β”€ package.json # Зависимости ΠΈ скрипты -β”œβ”€β”€ postcss.config.mjs # ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ PostCSS -└── tsconfig.json # ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ TypeScript -``` - -## Папка `public/` - -Π₯Ρ€Π°Π½ΠΈΡ‚ статичСскиС Ρ„Π°ΠΉΠ»Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΡ‚Π΄Π°ΡŽΡ‚ΡΡ ΠΏΠΎ прямому URL Π±Π΅Π· ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ сборщиком: - -```text -public/ -└── og-image.png -``` - -ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹, стили ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠΉ исходный ΠΊΠΎΠ΄ здСсь Π½Π΅ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°ΡŽΡ‚ΡΡ. - -## Папка `src/` - -```text -src/ -β”œβ”€β”€ app/ # Π ΠΎΡƒΡ‚ΠΈΠ½Π³ Next.js, ΠΏΡ€ΠΎΠ²Π°ΠΉΠ΄Π΅Ρ€Ρ‹, Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Π΅ стили -β”œβ”€β”€ layouts/ # ΠšΠ°Ρ€ΠΊΠ°ΡΡ‹ страниц (header, footer, sidebar) -β”œβ”€β”€ screens/ # ΠšΠΎΠ½Ρ‚Π΅Π½Ρ‚ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΉ страницы -β”œβ”€β”€ widgets/ # БоставныС Π±Π»ΠΎΠΊΠΈ интСрфСйса, Π½Π΅ привязанныС ΠΊ Π΄ΠΎΠΌΠ΅Π½Ρƒ -β”œβ”€β”€ business/ # БизнСс-Π΄ΠΎΠΌΠ΅Π½Ρ‹ (auth, catalog, orders) -β”œβ”€β”€ infrastructure/ # ВСхсСрвисы (theme, i18n, API-Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Ρ‹) -β”œβ”€β”€ ui/ # UI-ΠΊΠΈΡ‚ Π±Π΅Π· бизнСс-Π»ΠΎΠ³ΠΈΠΊΠΈ (button, modal, toast) -└── shared/ # ΠžΠ±Ρ‰ΠΈΠ΅ рСсурсы (ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Ρ‹, Ρ‚ΠΈΠΏΡ‹, стили) -``` - -ΠŸΡ€ΠΈΠ½Ρ†ΠΈΠΏΡ‹ ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ слоёв описаны Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ [АрхитСктура](../basics/architecture). - -### Папка `app/` - -Π’ΠΎΡ‡ΠΊΠ° Π²Ρ…ΠΎΠ΄Π° прилоТСния. Π‘ΠΎΠ²ΠΌΠ΅Ρ‰Π°Π΅Ρ‚ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ (ΠΏΡ€ΠΎΠ²Π°ΠΉΠ΄Π΅Ρ€Ρ‹, Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Π΅ стили) ΠΈ Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΉ Ρ€ΠΎΡƒΡ‚ΠΈΠ½Π³ Next.js (`layout.tsx`, `page.tsx`, route-сСгмСнты). - -```text -src/app/ -β”œβ”€β”€ providers/ # ΠŸΡ€ΠΎΠ²Π°ΠΉΠ΄Π΅Ρ€Ρ‹ прилоТСния -β”œβ”€β”€ styles/ # Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Π΅ стили -β”œβ”€β”€ layout.tsx # ΠšΠΎΡ€Π½Π΅Π²ΠΎΠΉ layout -└── page.tsx # Главная страница -``` - -## Папка `.templates/` - -Π‘ΠΎΠ΄Π΅Ρ€ΠΆΠΈΡ‚ ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹ для Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ ΠΊΠΎΠ΄Π°. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΏΠΎΠ΄ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ β€” шаблон ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° модуля: - -```text -.templates/ -β”œβ”€β”€ component/ # Π¨Π°Π±Π»ΠΎΠ½ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° -β”œβ”€β”€ screen/ # Π¨Π°Π±Π»ΠΎΠ½ экрана -β”œβ”€β”€ layout/ # Π¨Π°Π±Π»ΠΎΠ½ layout -β”œβ”€β”€ widget/ # Π¨Π°Π±Π»ΠΎΠ½ Π²ΠΈΠ΄ΠΆΠ΅Ρ‚Π° -β”œβ”€β”€ business/ # Π¨Π°Π±Π»ΠΎΠ½ бизнСс-модуля -└── store/ # Π¨Π°Π±Π»ΠΎΠ½ стора -``` - -ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ ΠΎ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ описано Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ [Π¨Π°Π±Π»ΠΎΠ½Ρ‹ ΠΈ гСнСрация ΠΊΠΎΠ΄Π°](./templates-generation). - -## ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹ - -| Π€Π°ΠΉΠ» | НазначСниС | -|---|---| -| `next.config.ts` | Настройки Next.js: Ρ€Π΅Π΄ΠΈΡ€Π΅ΠΊΡ‚Ρ‹, ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ окруТСния, webpack | -| `tsconfig.json` | Настройки TypeScript: ΠΏΡƒΡ‚ΠΈ, ΡΡ‚Ρ€ΠΎΠ³ΠΎΡΡ‚ΡŒ, Ρ‚Π°Ρ€Π³Π΅Ρ‚ | -| `biome.json` | ΠŸΡ€Π°Π²ΠΈΠ»Π° Π»ΠΈΠ½Ρ‚Π΅Ρ€Π° ΠΈ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Ρ‚Π΅Ρ€Π° Biome | -| `postcss.config.mjs` | ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ PostCSS-ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ² (CSS Modules, custom media) | -| `package.json` | Зависимости, вСрсии, npm-скрипты | -| `AGENTS.md` | Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΠΈ для AI-Π°Π³Π΅Π½Ρ‚ΠΎΠ², Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΠΈΡ… Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅ | - -## ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ окруТСния - -- `.env` β€” ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ окруТСния ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°, Π·Π°ΠΏΡ€Π΅Ρ‰Π΅Π½ΠΎ ΠΊΠΎΠΌΠΌΠΈΡ‚ΠΈΡ‚ΡŒ -- `.env.example` β€” шаблон, коммитится Π² Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ - -ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ с прСфиксом `NEXT_PUBLIC_` доступны Π² клиСнтском ΠΊΠΎΠ΄Π΅. ΠžΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ доступны Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π° сСрвСрС. diff --git a/preview/ai/applied/stores.md b/preview/ai/applied/stores.md deleted file mode 100644 index a3f3a92..0000000 --- a/preview/ai/applied/stores.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -scope: applied -keywords: [стор, store, zustand, состояниС, глобальноС состояниС] -when: "Π Π°Π±ΠΎΡ‚Π° с Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΌ состояниСм: созданиС стора, подписка" ---- diff --git a/preview/ai/applied/styles.md b/preview/ai/applied/styles.md deleted file mode 100644 index 065397d..0000000 --- a/preview/ai/applied/styles.md +++ /dev/null @@ -1,285 +0,0 @@ ---- -title: Π‘Ρ‚ΠΈΠ»ΠΈ -scope: applied -keywords: [css, postcss, ΠΌΠΎΠ΄ΡƒΠ»ΠΈ, css modules, Ρ‚ΠΎΠΊΠ΅Π½Ρ‹, ΠΌΠ΅Π΄ΠΈΠ°-запросы, Π²Π»ΠΎΠΆΠ΅Π½Π½ΠΎΡΡ‚ΡŒ, класс] -when: "Бтилизация: CSS Modules, PostCSS, ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅, ΠΌΠ΅Π΄ΠΈΠ°-запросы" ---- -# Π‘Ρ‚ΠΈΠ»ΠΈ - -Π Π°Π·Π΄Π΅Π» описываСт ΠΏΡ€Π°Π²ΠΈΠ»Π° написания CSS: PostCSS Modules, Π²Π»ΠΎΠΆΠ΅Π½Π½ΠΎΡΡ‚ΡŒ, ΠΌΠ΅Π΄ΠΈΠ°-запросы, ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅, Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅. - -## ΠžΠ±Ρ‰ΠΈΠ΅ ΠΏΡ€Π°Π²ΠΈΠ»Π° - -- Волько **PostCSS** ΠΈ **CSS Modules** для кастомной стилизации. -- ΠŸΠΎΠ΄Ρ…ΠΎΠ΄ **Mobile First** β€” стили ΠΏΠΈΡˆΡƒΡ‚ΡΡ ΠΎΡ‚ ΠΌΠΎΠ±ΠΈΠ»ΡŒΠ½Ρ‹Ρ… ΠΊ дСсктопу. -- ИмСнованиС классов β€” `camelCase` (`.root`, `.buttonNext`, `.itemTitle`). -- ΠœΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Ρ‹ β€” ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ класс с `_`, примСняСтся Ρ‡Π΅Ρ€Π΅Π· `&._modifier`. - -**Π₯ΠΎΡ€ΠΎΡˆΠΎ** -```css -.submitButton { - padding: 8px 16px; - - &._disabled { - opacity: 0.5; - } -} -``` - -**ΠŸΠ»ΠΎΡ…ΠΎ** -```css -/* ΠŸΠ»ΠΎΡ…ΠΎ: kebab-case ΠΈ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΉ элСмСнт вмСсто ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ класса. */ -.submit-button { - padding: 8px 16px; - - &__icon { - margin-right: 8px; - } -} -``` - -## Π’Π»ΠΎΠΆΠ΅Π½Π½ΠΎΡΡ‚ΡŒ - -- Π’Π»ΠΎΠΆΠ΅Π½Π½ΠΎΡΡ‚ΡŒ сСлСкторов Π·Π°ΠΏΡ€Π΅Ρ‰Π΅Π½Π°. -- Π˜ΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ: - - ΠŸΡΠ΅Π²Π΄ΠΎΠΊΠ»Π°ΡΡΡ‹: `&:hover`, `&:active`, `&:focus`, `&:disabled` ΠΈ Ρ‚.Π΄. - - ΠŸΡΠ΅Π²Π΄ΠΎΡΠ»Π΅ΠΌΠ΅Π½Ρ‚Ρ‹: `&::before`, `&::after`. - - МСдиа-запросы: `@media`. - - ΠœΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Ρ‹: `&._active`, `&._disabled`. -- ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΉ Π±Π»ΠΎΠΊ отдСляСтся пустой строкой ΠΎΡ‚ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΡ… свойств. - -**Π₯ΠΎΡ€ΠΎΡˆΠΎ** -```css -.card { - padding: 16px; - background-color: var(--color-bg); - - &:hover { - background-color: var(--color-bg-hover); - } - - &::after { - content: ''; - display: block; - } - - &._highlighted { - border-color: var(--color-primary); - } - - @media (--md) { - padding: 24px; - } -} - -.cardTitle { - font-size: 16px; - - @media (--md) { - font-size: 20px; - } -} -``` - -**ΠŸΠ»ΠΎΡ…ΠΎ** -```css -/* ΠŸΠ»ΠΎΡ…ΠΎ: Π²Π»ΠΎΠΆΠ΅Π½Π½ΠΎΡΡ‚ΡŒ сСлСкторов, Π½Π΅Ρ‚ пустых строк ΠΌΠ΅ΠΆΠ΄Ρƒ Π±Π»ΠΎΠΊΠ°ΠΌΠΈ. */ -.card { - padding: 16px; - .cardTitle { - font-size: 16px; - } - &:hover { - background-color: var(--color-bg-hover); - } -} -``` - -## МСдиа-запросы - -- Волько **Custom Media Queries**: `@media (--md) {}`. -- Π—Π°ΠΏΡ€Π΅Ρ‰Π΅Π½Ρ‹ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹Π΅ breakpoints: `@media (min-width: 768px)`. -- `@media` ΠΏΠΈΡˆΠ΅Ρ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ **Π²Π½ΡƒΡ‚Ρ€ΠΈ** сСлСктора. -- Π—Π°ΠΏΡ€Π΅Ρ‰Π΅Π½ΠΎ ΠΏΠΈΡΠ°Ρ‚ΡŒ `@media` Π½Π° Π²Π΅Ρ€Ρ…Π½Π΅ΠΌ ΡƒΡ€ΠΎΠ²Π½Π΅ с сСлСкторами Π²Π½ΡƒΡ‚Ρ€ΠΈ. - -**Π₯ΠΎΡ€ΠΎΡˆΠΎ** -```css -.sidebar { - display: none; - - @media (--md) { - display: block; - } -} - -.sidebarTitle { - font-size: 14px; - - @media (--md) { - font-size: 18px; - } -} -``` - -**ΠŸΠ»ΠΎΡ…ΠΎ** -```css -/* ΠŸΠ»ΠΎΡ…ΠΎ: @media Π½Π° Π²Π΅Ρ€Ρ…Π½Π΅ΠΌ ΡƒΡ€ΠΎΠ²Π½Π΅ с сСлСкторами Π²Π½ΡƒΡ‚Ρ€ΠΈ. */ -@media (--md) { - .sidebar { - display: block; - } - - .sidebarTitle { - font-size: 18px; - } -} - -/* ΠŸΠ»ΠΎΡ…ΠΎ: ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ breakpoint вмСсто custom media. */ -.sidebar { - @media (min-width: 992px) { - display: block; - } -} -``` - -## CSS-ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ - -- Π¦Π²Π΅Ρ‚Π° (`--color-*`), отступы (`--space-*`), скруглСния (`--radius-*`) ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ΡΡ Π² `app/styles/variables.css` Ρ‡Π΅Ρ€Π΅Π· `:root`. -- Π€Π°ΠΉΠ» ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π· Π² ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠΌ layout/entry point β€” послС этого ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ доступны глобально Ρ‡Π΅Ρ€Π΅Π· каскад. -- НС Π΄ΡƒΠ±Π»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ магичСскиС значСния Π² ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°Ρ…. - -**Π₯ΠΎΡ€ΠΎΡˆΠΎ** -```css -/* app/styles/variables.css */ -:root { - --color-primary: #3b82f6; - --color-bg: #ffffff; - --color-bg-hover: #f5f5f5; - --space-1: 4px; - --space-2: 8px; - --space-3: 12px; - --radius-1: 4px; - --radius-2: 8px; -} -``` - -```css -/* ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ */ -.card { - padding: var(--space-3); - border-radius: var(--radius-2); - background-color: var(--color-bg); -} -``` - -**ΠŸΠ»ΠΎΡ…ΠΎ** -```css -/* ΠŸΠ»ΠΎΡ…ΠΎ: магичСскиС значСния вмСсто ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…. */ -.card { - padding: 12px; - border-radius: 8px; - background-color: #ffffff; -} -``` - -## Custom Media - -- Breakpoints ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ΡΡ Ρ‡Π΅Ρ€Π΅Π· Custom Media Queries Π² `app/styles/media.css`. -- Custom media ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‚ΡΡ глобально Ρ‡Π΅Ρ€Π΅Π· ΠΊΠΎΠ½Ρ„ΠΈΠ³ PostCSS (ΠΏΠ»Π°Π³ΠΈΠ½ `postcss-custom-media`) β€” Π½Π΅ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π² Ρ„Π°ΠΉΠ»Ρ‹ стилСй. - -```css -/* app/styles/media.css */ -@custom-media --sm (min-width: 36em); -@custom-media --md (min-width: 62em); -@custom-media --lg (min-width: 82em); -``` - -## Π˜ΠΌΠΏΠΎΡ€Ρ‚ стилСй - -- Π‘Ρ‚ΠΈΠ»ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π²Π½ΡƒΡ‚Ρ€ΠΈ своСго ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°. -- Π—Π°ΠΏΡ€Π΅Ρ‰Π΅Π½ΠΎ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ стили ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° Π² Π΄Ρ€ΡƒΠ³ΠΎΠΉ. -- Custom media Π½Π΅ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ΡΡ Π² Ρ„Π°ΠΉΠ»Ρ‹ стилСй β€” ΠΎΠ½ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‚ΡΡ глобально Ρ‡Π΅Ρ€Π΅Π· ΠΊΠΎΠ½Ρ„ΠΈΠ³ PostCSS. - -## Π€ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ - -- ΠŸΡƒΡΡ‚Π°Ρ строка ΠΌΠ΅ΠΆΠ΄Ρƒ сСлСкторами Π²Π΅Ρ€Ρ…Π½Π΅Π³ΠΎ уровня. -- ΠŸΡƒΡΡ‚Π°Ρ строка ΠΏΠ΅Ρ€Π΅Π΄ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΌ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΌ Π±Π»ΠΎΠΊΠΎΠΌ (ΠΌΠ΅Π΄ΠΈΠ°, псСвдокласс, ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€). - -**Π₯ΠΎΡ€ΠΎΡˆΠΎ** -```css -.userBar { - display: none; - color: var(--color-text); - - @media (--md) { - display: flex; - } -} - -.userBarButton { - background-color: var(--color-bg); - - &:hover { - background-color: var(--color-bg-hover); - } - - &._active { - background-color: var(--color-primary); - } -} -``` - -**ΠŸΠ»ΠΎΡ…ΠΎ** -```css -/* ΠŸΠ»ΠΎΡ…ΠΎ: Π½Π΅Ρ‚ пустых строк ΠΌΠ΅ΠΆΠ΄Ρƒ сСлСкторами ΠΈ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΌΠΈ Π±Π»ΠΎΠΊΠ°ΠΌΠΈ. */ -.userBar { - display: none; - color: var(--color-text); - @media (--md) { - display: flex; - } -} -.userBarButton { - background-color: var(--color-bg); - &:hover { - background-color: var(--color-bg-hover); - } - &._active { - background-color: var(--color-primary); - } -} -``` - -## Π•Π΄ΠΈΠ½ΠΈΡ†Ρ‹ измСрСния - -- `px` β€” основная Π΅Π΄ΠΈΠ½ΠΈΡ†Π° измСрСния. -- ΠžΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ (`em`, `rem`, `%`, `vh`/`vw`) β€” Π΄ΠΎΠΏΡƒΡΠΊΠ°ΡŽΡ‚ΡΡ ΠΏΠΎ нСобходимости Π΄ΠΈΠ·Π°ΠΉΠ½Π°. - -## ΠŸΠΎΡ€ΡΠ΄ΠΎΠΊ CSS-свойств - -Π’ стилях рСкомСндуСтся ΠΏΡ€ΠΈΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒΡΡ логичСского порядка свойств: - -1. ΠŸΠΎΠ·ΠΈΡ†ΠΈΠΎΠ½ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ (`position`, `top`, `left`, `z-index`). -2. Блочная модСль (`display`, `width`, `height`, `margin`, `padding`). -3. ΠžΡ„ΠΎΡ€ΠΌΠ»Π΅Π½ΠΈΠ΅ (`background`, `border`, `box-shadow`, `border-radius`). -4. ВСкст (`font`, `color`, `text-align`, `line-height`). -5. ΠŸΡ€ΠΎΡ‡Π΅Π΅ (`transition`, `animation`, `opacity`, `cursor`). - -## ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ - -- Π–Π΅Π»Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ Π½Π΅ ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ Π² CSS. -- Π˜ΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ β€” Π½Π΅Ρ‚Ρ€ΠΈΠ²ΠΈΠ°Π»ΡŒΠ½Ρ‹Π΅ Ρ…Π°ΠΊΠΈ ΠΈ ΠΎΠ±Ρ…ΠΎΠ΄Π½Ρ‹Π΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ стоит ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ пояснСниС. - -## ΠŸΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ стилизации - -Основной UI-Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° β€” **Mantine**. ΠŸΡ€ΠΈ стилизации ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² ΠΏΡ€ΠΈΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒΡΡ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π°: - -1. **Mantine-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ ΠΈ ΠΈΡ… пропсы** β€” Π² ΠΏΠ΅Ρ€Π²ΡƒΡŽ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ встроСнныС возмоТности Mantine (пропсы, `classNames`, `styles`). -2. **Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Π΅ CSS-Ρ‚ΠΎΠΊΠ΅Π½Ρ‹** (`--color-*`, `--space-*`, `--radius-*`) β€” для Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ ΠΏΠΎΠΊΡ€Ρ‹Π²Π°ΡŽΡ‚ΡΡ Mantine. -3. **PostCSS Modules** β€” ΠΊΠΎΠ³Π΄Π° Mantine Π½Π΅ ΠΏΠΎΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ Π·Π°Π΄Π°Ρ‡Ρƒ ΠΈ Π½ΡƒΠΆΠ½Π° кастомная стилизация. - -## Π§Ρ‚ΠΎ Π·Π°ΠΏΡ€Π΅Ρ‰Π΅Π½ΠΎ - -- **Инлайн-стили** β€” использованиС Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π° `style` Π² ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°Ρ… строго Π·Π°ΠΏΡ€Π΅Ρ‰Π΅Π½ΠΎ. -- **ΠœΠ°Π³ΠΈΡ‡Π΅ΡΠΊΠΈΠ΅ значСния** β€” ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹Π΅ Ρ†Π²Π΅Ρ‚Π°, отступы ΠΈ скруглСния Π·Π°ΠΏΡ€Π΅Ρ‰Π΅Π½Ρ‹, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠΊΠ΅Π½Ρ‹. -- **Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Π΅ стили** Π²Π½Π΅ `app/styles/` Π·Π°ΠΏΡ€Π΅Ρ‰Π΅Π½Ρ‹. diff --git a/preview/ai/applied/svg-sprites.md b/preview/ai/applied/svg-sprites.md deleted file mode 100644 index 1d59ecd..0000000 --- a/preview/ai/applied/svg-sprites.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: SVG-спрайты -scope: applied -keywords: [svg, спрайт, ΠΈΠΊΠΎΠ½ΠΊΠ°, icon, sprite] -when: "Π Π°Π±ΠΎΡ‚Π° с SVG-ΠΈΠΊΠΎΠ½ΠΊΠ°ΠΌΠΈ ΠΈ спрайтами" ---- -# SVG-спрайты diff --git a/preview/ai/applied/templates-generation.md b/preview/ai/applied/templates-generation.md deleted file mode 100644 index 60da81f..0000000 --- a/preview/ai/applied/templates-generation.md +++ /dev/null @@ -1,174 +0,0 @@ ---- -title: Π¨Π°Π±Π»ΠΎΠ½Ρ‹ ΠΈ гСнСрация ΠΊΠΎΠ΄Π° -scope: applied -keywords: [шаблон, гСнСрация, template, scaffold, plop, hygen, .templates] -when: "ГСнСрация ΠΊΠΎΠ΄Π° ΠΈΠ· шаблонов, созданиС Π½ΠΎΠ²Ρ‹Ρ… шаблонов" ---- - -::: v-pre - -# Π¨Π°Π±Π»ΠΎΠ½Ρ‹ ΠΈ гСнСрация ΠΊΠΎΠ΄Π° - -Как Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹, ΠΊΠ°ΠΊ ΠΈΡ… ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ, синтаксис ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΈ ΠΊΠ°ΠΊ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠ΄ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ VS Code ΠΈ CLI. - -## Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° шаблонов - -ВсС ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹ Π»Π΅ΠΆΠ°Ρ‚ Π² `.templates/` Π² ΠΊΠΎΡ€Π½Π΅ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°. КаТдая ΠΏΠ°ΠΏΠΊΠ° β€” ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ шаблон. - -```text -.templates/ -β”œβ”€β”€ component/ # шаблон ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° -β”‚ └── {{name.kebabCase}}/ -β”‚ β”œβ”€β”€ styles/ -β”‚ β”‚ └── {{name.kebabCase}}.module.css -β”‚ β”œβ”€β”€ types/ -β”‚ β”‚ └── {{name.kebabCase}}.type.ts -β”‚ β”œβ”€β”€ {{name.kebabCase}}.tsx -β”‚ └── index.ts -└── store/ # шаблон Zustand стора - └── {{name.kebabCase}}/ - β”œβ”€β”€ {{name.kebabCase}}.store.ts - β”œβ”€β”€ {{name.kebabCase}}.type.ts - └── index.ts -``` - -## Бинтаксис шаблонов - -ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ Π² ΠΈΠΌΠ΅Π½Π°Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ²/ΠΏΠ°ΠΏΠΎΠΊ ΠΈ Π²Π½ΡƒΡ‚Ρ€ΠΈ Ρ„Π°ΠΉΠ»ΠΎΠ². Базовая пСрСмСнная β€” `name`. - -```text -{{variable}} -``` - -ΠœΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Ρ‹ ΠΌΠ΅Π½ΡΡŽΡ‚ рСгистр ΠΈ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ записи: - -```text -{{name.pascalCase}} β†’ MyButton -{{name.camelCase}} β†’ myButton -{{name.kebabCase}} β†’ my-button -{{name.snakeCase}} β†’ my_button -{{name.screamingSnakeCase}} β†’ MY_BUTTON -``` - -## Как ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ шаблон - -1. Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΏΠ°ΠΏΠΊΡƒ Π² `.templates/` с ΠΈΠΌΠ΅Π½Π΅ΠΌ шаблона (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ `hook`). -2. Π’Π½ΡƒΡ‚Ρ€ΠΈ Ρ€Π°Π·ΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ Ρ„Π°ΠΉΠ»Ρ‹ ΠΈ ΠΏΠ°ΠΏΠΊΠΈ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ `{{name}}` ΠΈ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Ρ‹ Π² ΠΈΠΌΠ΅Π½Π°Ρ… ΠΈ содСрТимом. -3. Π¨Π°Π±Π»ΠΎΠ½ сразу доступСн ΠΈ Π² Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠΈ VS Code, ΠΈ Π² CLI. - -ΠŸΡ€ΠΈΠΌΠ΅Ρ€ β€” созданиС шаблона для Ρ…ΡƒΠΊΠ°: - -```text -.templates/ -└── hook/ - └── {{name.kebabCase}}/ - β”œβ”€β”€ {{name.kebabCase}}.hook.ts - └── index.ts -``` - -```ts -// .templates/hook/{{name.kebabCase}}.hook.ts -export const {{name.camelCase}} = () => { - -} -``` - -```ts -// .templates/hook/index.ts -export { {{name.camelCase}} } from './{{name.kebabCase}}.hook' -``` - -## ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ шаблонов - -### Π¨Π°Π±Π»ΠΎΠ½ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° - -```ts -// .templates/component/index.ts -export { {{name.pascalCase}} } from './{{name.kebabCase}}' -``` - -```ts -// .templates/component/types/{{name.kebabCase}}.type.ts -import type { HTMLAttributes } from 'react' - -/** - * ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ {{name.pascalCase}}. - */ -export type {{name.pascalCase}}Params = {} - -/** HTML-Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ элСмСнта. */ -type RootAttrs = HTMLAttributes - -export type {{name.pascalCase}}Props = RootAttrs & {{name.pascalCase}}Params -``` - -```tsx -// .templates/component/{{name.kebabCase}}.tsx -import cl from 'clsx' -import type { {{name.pascalCase}}Props } from './types/{{name.kebabCase}}.type' -import styles from './styles/{{name.kebabCase}}.module.css' - -/** - * {{name.pascalCase}}. - */ -export const {{name.pascalCase}} = (props: {{name.pascalCase}}Props) => { - const { children, className, ...htmlAttr } = props - - return ( -
- {children} -
- ) -} -``` - -```css -/* .templates/component/styles/{{name.kebabCase}}.module.css */ -.root { - -} -``` - -## ГСнСрация Ρ‡Π΅Ρ€Π΅Π· VS Code - -Template File Generator | gromlab ([Marketplace](https://marketplace.visualstudio.com/items?itemName=gromlab.vscode-templateFileGenerator), [Open VSX](https://open-vsx.org/extension/gromlab/vscode-templateFileGenerator)) β€” Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ для Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΈ ΠΏΠ°ΠΏΠΎΠΊ ΠΈΠ· шаблонов Ρ‡Π΅Ρ€Π΅Π· интСрфСйс Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π°. - -1. ПКМ Π½Π° Ρ†Π΅Π»Π΅Π²ΠΎΠΉ ΠΏΠ°ΠΏΠΊΠ΅ Π² ΠΏΡ€ΠΎΠ²ΠΎΠ΄Π½ΠΈΠΊΠ΅ VS Code. -2. **Generate from template** β†’ Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒ шаблон. -3. ВвСсти имя (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ `button`) β€” Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ подставит Π΅Π³ΠΎ Π²ΠΎ всС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ `{{name}}`. - -## ГСнСрация Ρ‡Π΅Ρ€Π΅Π· CLI - -[@gromlab/create](https://www.npmjs.com/package/@gromlab/create) β€” CLI для Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ ΠΈΠ· Ρ‚Π΅Ρ… ΠΆΠ΅ шаблонов. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Ρ‡Π΅Ρ€Π΅Π· npx, глобальная установка Π½Π΅ трСбуСтся. - -```bash -npx @gromlab/create <шаблон> <имя> <ΠΏΡƒΡ‚ΡŒ> -``` - -| Команда | Π§Ρ‚ΠΎ создаёт | -|---|---| -| `npx @gromlab/create component button src/ui` | ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ | -| `npx @gromlab/create business auth src/business` | БизнСс-ΠΌΠΎΠ΄ΡƒΠ»ΡŒ | -| `npx @gromlab/create widget header src/widgets` | Π’ΠΈΠ΄ΠΆΠ΅Ρ‚ | -| `npx @gromlab/create layout admin src/layouts` | Layout | -| `npx @gromlab/create screen home src/screens` | Π­ΠΊΡ€Π°Π½ | -| `npx @gromlab/create store auth src/business/auth/stores` | Π‘Ρ‚ΠΎΡ€ | - -::: - -## КакиС ΠΌΠΎΠ΄ΡƒΠ»ΠΈ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΈΠ· шаблонов - -| ΠœΠΎΠ΄ΡƒΠ»ΡŒ | Π‘Π»ΠΎΠΉ | Π¨Π°Π±Π»ΠΎΠ½ | -|---|---|---| -| ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ | `ui/` | `component` | -| БизнСс-ΠΌΠΎΠ΄ΡƒΠ»ΡŒ | `business/` | `business` | -| Π’ΠΈΠ΄ΠΆΠ΅Ρ‚ | `widgets/` | `widget` | -| Layout | `layouts/` | `layout` | -| Π­ΠΊΡ€Π°Π½ | `screens/` | `screen` | -| Π‘Ρ‚ΠΎΡ€ | `stores/` | `store` | - -## Когда ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ шаблон - -- ΠŸΠΎΠ²Ρ‚ΠΎΡ€ΡΡŽΡ‰Π°ΡΡΡ структура появляСтся большС ΠΎΠ΄Π½ΠΎΠ³ΠΎ Ρ€Π°Π·Π°. -- Π‘ΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ шаблон Π½Π΅ ΠΏΠΎΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ Π½ΡƒΠΆΠ½Ρ‹ΠΉ Ρ‚ΠΈΠΏ модуля. - diff --git a/preview/ai/applied/video.md b/preview/ai/applied/video.md deleted file mode 100644 index b8bd490..0000000 --- a/preview/ai/applied/video.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -scope: applied -keywords: [Π²ΠΈΠ΄Π΅ΠΎ, video, ΠΏΠ»Π΅Π΅Ρ€, mp4] -when: "ВстраиваниС ΠΈ Ρ€Π°Π±ΠΎΡ‚Π° с Π²ΠΈΠ΄Π΅ΠΎ" ---- diff --git a/preview/ai/applied/vscode.md b/preview/ai/applied/vscode.md deleted file mode 100644 index 5d313fe..0000000 --- a/preview/ai/applied/vscode.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: Настройка VS Code -scope: applied -keywords: [vscode, Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€, Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅, настройка, extension, .vscode] -when: "Настройка VS Code: Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ, settings.json, сниппСты" ---- -# Настройка VS Code - -ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ содСрТит ΠΏΠ°ΠΏΠΊΡƒ `.vscode/` с ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠ΅ΠΉ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π°. Π­Ρ‚ΠΎ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚, Ρ‡Ρ‚ΠΎ всС участники ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ с ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹ΠΌΠΈ настройками форматирования, Π»ΠΈΠ½Ρ‚ΠΈΠ½Π³Π° ΠΈ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡΠΌΠΈ. - -## Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° `.vscode/` - -```text -.vscode/ -β”œβ”€β”€ extensions.json # Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅ΠΌΡ‹Π΅ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ -└── settings.json # Настройки Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π° для ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° -``` - -Оба Ρ„Π°ΠΉΠ»Π° коммитятся Π² Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ. - -## Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ - -Π€Π°ΠΉΠ» `.vscode/extensions.json` опрСдСляСт список Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ VS Code ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠΈΡ‚ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΏΡ€ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°. - -```json -// .vscode/extensions.json -{ - "recommendations": [ - "biomejs.biome", - "MyTemplateGenerator.mytemplategenerator", - "csstools.postcss" - ] -} -``` - -| Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ | НазначСниС | -|---|---| -| [Biome](https://marketplace.visualstudio.com/items?itemName=biomejs.biome) | Π›ΠΈΠ½Ρ‚ΠΈΠ½Π³ ΠΈ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΠΎΠ΄Π°. ЗамСняСт ESLint ΠΈ Prettier | -| Template File Generator \| gromlab ([Marketplace](https://marketplace.visualstudio.com/items?itemName=gromlab.vscode-templateFileGenerator), [Open VSX](https://open-vsx.org/extension/gromlab/vscode-templateFileGenerator)) | ГСнСрация Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΈ ΠΏΠ°ΠΏΠΎΠΊ ΠΈΠ· шаблонов `.templates/` Ρ‡Π΅Ρ€Π΅Π· контСкстноС мСню | -| [PostCSS Language Support](https://marketplace.visualstudio.com/items?itemName=csstools.postcss) | ΠŸΠΎΠ΄ΡΠ²Π΅Ρ‚ΠΊΠ° синтаксиса ΠΈ Π°Π²Ρ‚ΠΎΠ΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ для PostCSS (`@custom-media`, `@nest` ΠΈ Π΄Ρ€.) | - -### Π—Π°Ρ‡Π΅ΠΌ это Π½ΡƒΠΆΠ½ΠΎ - -- Новый участник ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ всС Π½ΡƒΠΆΠ½Ρ‹Π΅ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ ΠΎΠ΄Π½ΠΈΠΌ ΠΊΠ»ΠΈΠΊΠΎΠΌ. -- НСт Ρ€Π°Π·Π½ΠΎΡ‡Ρ‚Π΅Π½ΠΈΠΉ: всС ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹ΠΉ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Ρ‚Π΅Ρ€ ΠΈ Π»ΠΈΠ½Ρ‚Π΅Ρ€. -- Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ привязаны ΠΊ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρƒ, Π° Π½Π΅ ΠΊ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΌΡƒ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΡƒ. - -## Настройки Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π° - -Π€Π°ΠΉΠ» `.vscode/settings.json` пСрСопрСдСляСт ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠ΅ настройки VS Code Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°. - -```json -// .vscode/settings.json -{ - "editor.defaultFormatter": "biomejs.biome", - "editor.formatOnSave": true, - "editor.codeActionsOnSave": { - "source.fixAll.biome": "explicit", - "source.organizeImports.biome": "explicit" - }, - "files.associations": { - "*.css": "postcss" - } -} -``` - -### Π Π°Π·Π±ΠΎΡ€ настроСк - -| Настройка | Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ | Π§Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ | -|---|---|---| -| `editor.defaultFormatter` | `biomejs.biome` | Biome ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΊΠ°ΠΊ СдинствСнный Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Ρ‚Π΅Ρ€ для всСх Ρ„Π°ΠΉΠ»ΠΎΠ² | -| `editor.formatOnSave` | `true` | Код автоматичСски форматируСтся ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ сохранСнии | -| `codeActionsOnSave.source.fixAll.biome` | `explicit` | Biome автоматичСски примСняСт бСзопасныС исправлСния ΠΏΡ€ΠΈ сохранСнии | -| `codeActionsOnSave.source.organizeImports.biome` | `explicit` | Π˜ΠΌΠΏΠΎΡ€Ρ‚Ρ‹ ΡΠΎΡ€Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΈ Π³Ρ€ΡƒΠΏΠΏΠΈΡ€ΡƒΡŽΡ‚ΡΡ автоматичСски ΠΏΡ€ΠΈ сохранСнии | -| `files.associations` | `"*.css": "postcss"` | ВсС CSS-Ρ„Π°ΠΉΠ»Ρ‹ ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°ΡŽΡ‚ΡΡ с подсвСткой PostCSS вмСсто стандартного CSS | - -### Π—Π°Ρ‡Π΅ΠΌ это Π½ΡƒΠΆΠ½ΠΎ - -- **Π•Π΄ΠΈΠ½Ρ‹ΠΉ ΡΡ‚ΠΈΠ»ΡŒ ΠΊΠΎΠ΄Π°** -- Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ происходит автоматичСски, Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΊΠΎΠΌΠΌΠΈΡ‚ΠΈΡ‚ΡŒ Π½Π΅Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ΄. -- **Автофикс ΠΏΡ€ΠΈ сохранСнии** -- распространённыС ошибки Π»ΠΈΠ½Ρ‚ΠΈΠ½Π³Π° ΠΈΡΠΏΡ€Π°Π²Π»ΡΡŽΡ‚ΡΡ Π±Π΅Π· Ρ€ΡƒΡ‡Π½ΠΎΠ³ΠΎ Π²ΠΌΠ΅ΡˆΠ°Ρ‚Π΅Π»ΡŒΡΡ‚Π²Π°. -- **Π‘ΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²ΠΊΠ° ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΎΠ²** -- ΠΈΠΌΠΏΠΎΡ€Ρ‚Ρ‹ всСгда Π² ΠΎΠ΄Π½ΠΎΠΌ порядкС, Π±Π΅Π· ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚ΠΎΠ² ΠΏΡ€ΠΈ ΠΌΠ΅Ρ€ΠΆΠ΅. -- **PostCSS-подсвСтка** -- кастомныС at-ΠΏΡ€Π°Π²ΠΈΠ»Π° (`@custom-media`, `@define-mixin`) ΠΏΠΎΠ΄ΡΠ²Π΅Ρ‡ΠΈΠ²Π°ΡŽΡ‚ΡΡ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ, Π° Π½Π΅ ΠΊΠ°ΠΊ ошибки. - -## Π§Ρ‚ΠΎ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ Π² `.vscode/` - -НС коммитятся Ρ„Π°ΠΉΠ»Ρ‹, спСцифичныС для ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°: - -- **НС ΠΊΠΎΠΌΠΌΠΈΡ‚ΠΈΡ‚ΡŒ**: ΠΎΡ‚Π»Π°Π΄ΠΎΡ‡Π½Ρ‹Π΅ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ с Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΌΠΈ путями, ΠΏΠ΅Ρ€ΡΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Π΅ сниппСты, настройки Ρ‚Π΅ΠΌ оформлСния. -- **ΠšΠΎΠΌΠΌΠΈΡ‚ΠΈΡ‚ΡŒ**: Ρ‚ΠΎΠ»ΡŒΠΊΠΎ `extensions.json` ΠΈ `settings.json` с ΠΎΠ±Ρ‰ΠΈΠΌΠΈ для ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ настройками. diff --git a/preview/ai/basics/architecture.md b/preview/ai/basics/architecture.md deleted file mode 100644 index 6a17d9d..0000000 --- a/preview/ai/basics/architecture.md +++ /dev/null @@ -1,665 +0,0 @@ ---- -title: АрхитСктура -scope: basics -keywords: [SLM Design, слой, ΠΌΠΎΠ΄ΡƒΠ»ΡŒ, сСгмСнт, Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°, FSD, scoped layered module] -when: "ΠžΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΡ ΠΊΠΎΠ΄Π°: слои, ΠΌΠΎΠ΄ΡƒΠ»ΠΈ, зависимости ΠΌΠ΅ΠΆΠ΄Ρƒ модулями" ---- - - -# SLM Design -Scoped Layered Module Design β€” ΠΌΠΎΠ΄ΡƒΠ»ΡŒΠ½Π°Ρ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π° Ρ„Ρ€ΠΎΠ½Ρ‚Π΅Π½Π΄-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ. Код ΠΎΡ€Π³Π°Π½ΠΈΠ·ΠΎΠ²Π°Π½ ΠΏΠΎ слоям отвСтствСнности, Π° ΠΌΠΎΠ΄ΡƒΠ»ΡŒ содСрТит всё, Ρ‡Ρ‚ΠΎ Π΅ΠΌΡƒ Π½ΡƒΠΆΠ½ΠΎ: ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹, Ρ…ΡƒΠΊΠΈ, сторы, Ρ‚ΠΈΠΏΡ‹, стили. - -## ΠŸΡ€Π΅ΠΈΠΌΡƒΡ‰Π΅ΡΡ‚Π²Π° - -### Π’Π΅Ρ€Ρ‚ΠΈΠΊΠ°Π»ΡŒΠ½Π°Ρ организация Π΄ΠΎΠΌΠ΅Π½Π° - -БизнСс-Π΄ΠΎΠΌΠ΅Π½ Π½Π΅ разбиваСтся ΠΏΠΎ тСхничСским слоям β€” сцСнарии, сущности, Ρ‚ΠΈΠΏΡ‹ ΠΈ UI ΠΆΠΈΠ²ΡƒΡ‚ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΌΠΎΠ΄ΡƒΠ»Π΅. Π­Ρ‚ΠΎ сокращаСт врСмя Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΠΈ ΠΈ ΡƒΠΏΡ€ΠΎΡ‰Π°Π΅Ρ‚ сопровоТдСниС: всС измСнСния Π΄ΠΎΠΌΠ΅Π½Π° Π»ΠΎΠΊΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Ρ‹. - -### Dependency Injection Π±Π΅Π· Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠΎΠ² - -Cross-domain зависимости Π² бизнСс-слоС Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‚ΡΡ Ρ‡Π΅Ρ€Π΅Π· Ρ„Π°Π±Ρ€ΠΈΠΊΠΈ β€” ΠΌΠΎΠ΄ΡƒΠ»ΡŒ Π΄Π΅ΠΊΠ»Π°Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ‡Ρ‚ΠΎ Π΅ΠΌΡƒ Π½ΡƒΠΆΠ½ΠΎ, Π° Ρ‚ΠΎΡ‡ΠΊΠ° использования прСдоставляСт зависимости. Π”ΠΎΠΌΠ΅Π½Ρ‹ ΠΈΠ·ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ Π±Π΅Π· DI-ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ΠΎΠ², ΠΏΡ€ΠΎΠ²Π°ΠΉΠ΄Π΅Ρ€ΠΎΠ² ΠΈ шин событий. - -### Π Π°Π·Π΄Π΅Π»Π΅Π½ΠΈΠ΅ отвСтствСнности Π±Π΅Π· ΠΏΠ΅Ρ€Π΅Π³Ρ€ΡƒΠ·ΠΊΠΈ слоёв - -БСрвисы прилоТСния (`infrastructure/`), UI-ΠΊΠΈΡ‚ (`ui/`) ΠΈ ΠΎΠ±Ρ‰ΠΈΠ΅ рСсурсы (`shared/`) β€” Ρ‚Ρ€ΠΈ Ρ€Π°Π·Π½Ρ‹Ρ… слоя с Ρ€Π°Π·Π½ΠΎΠΉ ΠΏΡ€ΠΈΡ€ΠΎΠ΄ΠΎΠΉ. Ни ΠΎΠ΄ΠΈΠ½ слой Π½Π΅ прСвращаСтся Π² свалку Ρ€Π°Π·Π½ΠΎΡ€ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°. - -### Π“ΠΎΡ€ΠΈΠ·ΠΎΠ½Ρ‚Π°Π»ΡŒΠ½Π°Ρ инкапсуляция - -Π’Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ ΠΌΠΎΠ΄ΡƒΠ»ΠΈ (`parts/`) ΠΈ Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ зависимостСй ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ нСскольким Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°ΠΌ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π½Π°Π΄ ΠΎΠ΄Π½ΠΎΠΉ ΠΎΠ±Π»Π°ΡΡ‚ΡŒΡŽ прилоТСния ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎ, Π½Π΅ затрагивая ΠΊΠΎΠ΄ Π΄Ρ€ΡƒΠ³ Π΄Ρ€ΡƒΠ³Π°. - -### ΠšΠΎΠ»ΠΎΠΊΠ°Ρ†ΠΈΡ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ - -Код Π½Π°Ρ‡ΠΈΠ½Π°Π΅Ρ‚ Тизнь рядом с мСстом использования ΠΈ поднимаСтся Π² ΠΎΠ±Ρ‰ΠΈΠ΅ слои Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΈ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΉ потрСбности. Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Π΅ слои Π½Π΅ Π·Π°ΡΠΎΡ€ΡΡŽΡ‚ΡΡ ΠΏΡ€Π΅ΠΆΠ΄Π΅Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ абстракциями. - -### Π―Π²Π½ΠΎΠ΅ Ρ€Π°Π·Π΄Π΅Π»Π΅Π½ΠΈΠ΅ каркаса ΠΈ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π° - -ΠšΠ°Ρ€ΠΊΠ°Ρ Π³Ρ€ΡƒΠΏΠΏΡ‹ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΎΠ² (`layouts/`) ΠΈ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΉ страницы (`screens/`) β€” нСзависимыС слои с собствСнной ΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²Π΅Π½Π½ΠΎΡΡ‚ΡŒΡŽ. - -### ΠœΠ°ΡΡˆΡ‚Π°Π±ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Ρ‡Π΅Ρ€Π΅Π· Π³Ρ€ΡƒΠΏΠΏΠΈΡ€ΠΎΠ²ΠΊΡƒ - -ΠŸΡ€ΠΈ ростС ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° слои Π½Π΅ Ρ‚Π΅Ρ€ΡΡŽΡ‚ структуру β€” ΠΌΠΎΠ΄ΡƒΠ»ΠΈ Π³Ρ€ΡƒΠΏΠΏΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΏΠΎ СстСствСнным ΠΏΡ€ΠΈΠ·Π½Π°ΠΊΠ°ΠΌ: бизнСс-Π΄ΠΎΠΌΠ΅Π½Ρ‹ ΠΏΠΎ субдомСнам, страницы ΠΏΠΎ Ρ€Π°Π·Π΄Π΅Π»Π°ΠΌ, UI-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ ΠΏΠΎ ΡƒΡ€ΠΎΠ²Π½ΡŽ абстракции (ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Ρ‹ ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ). - -## ΠŸΡ€ΠΎΠΈΡΡ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ - -SLM Design вырос Π½Π° основС: - -- **Feature-Sliced Design** β€” слоистая структура, ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ API модуля, Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ зависимостСй -- **Vertical Slice Architecture** β€” ΠΌΠΎΠ΄ΡƒΠ»ΡŒ ΠΊΠ°ΠΊ Π²Π΅Ρ€Ρ‚ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ срСз, содСрТащий всё Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΠ΅ -- **Screaming Architecture** β€” структура ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Β«ΠΊΡ€ΠΈΡ‡ΠΈΡ‚Β» ΠΎ Π½Π°Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΈ: ΠΎΡ‚ΠΊΡ€Ρ‹Π» `business/auth` β€” видишь Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΡŽ -- **Colocation Principle** β€” ΠΊΠΎΠ΄ ΠΆΠΈΠ²Ρ‘Ρ‚ рядом с мСстом использования - -## ΠŸΡ€ΠΈΠΌΠ΅Ρ€ структуры ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° - -```text -src/ -β”œβ”€β”€ app/ -β”‚ -β”œβ”€β”€ layouts/ -β”‚ β”œβ”€β”€ main/ -β”‚ └── dashboard/ -β”‚ -β”œβ”€β”€ screens/ -β”‚ β”œβ”€β”€ home/ -β”‚ β”œβ”€β”€ products/ -β”‚ β”œβ”€β”€ product-detail/ -β”‚ └── about/ -β”‚ -β”œβ”€β”€ widgets/ -β”‚ β”œβ”€β”€ page-heading/ -β”‚ β”œβ”€β”€ hero-section/ -β”‚ └── promo-banner/ -β”‚ -β”œβ”€β”€ business/ -β”‚ β”œβ”€β”€ auth/ -β”‚ β”œβ”€β”€ catalog/ -β”‚ β”œβ”€β”€ orders/ -β”‚ └── chat/ -β”‚ -β”œβ”€β”€ infrastructure/ -β”‚ β”œβ”€β”€ theme/ -β”‚ β”œβ”€β”€ i18n/ -β”‚ β”œβ”€β”€ backend-api/ -β”‚ └── logger/ -β”‚ -β”œβ”€β”€ ui/ -β”‚ β”œβ”€β”€ button/ -β”‚ β”œβ”€β”€ input/ -β”‚ β”œβ”€β”€ modal/ -β”‚ β”œβ”€β”€ toast/ -β”‚ └── dropdown/ -β”‚ -└── shared/ - β”œβ”€β”€ lib/ - β”œβ”€β”€ types/ - └── styles/ -``` - -## ΠŸΡ€ΠΈΠ½Ρ†ΠΈΠΏΡ‹ - -- **Π”ΠΎΠΌΠ΅Π½ β€” Π΅Π΄ΠΈΠ½ΠΎΠ΅ Ρ†Π΅Π»ΠΎΠ΅.** Всё, Ρ‡Ρ‚ΠΎ относится ΠΊ Π΄ΠΎΠΌΠ΅Π½Ρƒ, ΠΆΠΈΠ²Ρ‘Ρ‚ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΌΠΎΠ΄ΡƒΠ»Π΅. -- **ΠšΠΎΠ»ΠΎΠΊΠ°Ρ†ΠΈΡ.** Код роТдаСтся рядом с мСстом использования ΠΈ поднимаСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΈ нСобходимости. -- **Зависимости ΠΎΠ΄Π½ΠΎΠ½Π°ΠΏΡ€Π°Π²Π»Π΅Π½Ρ‹.** Π˜ΠΌΠΏΠΎΡ€Ρ‚Ρ‹ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ свСрху Π²Π½ΠΈΠ·, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Π΅Ρ€Π΅Π· ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ API. -- **АрхитСктура β€” каркас, Π½Π΅ ΠΊΠ»Π΅Ρ‚ΠΊΠ°.** ΠŸΡ€Π°Π²ΠΈΠ»Π° Ρ„ΠΈΠΊΡΠΈΡ€ΡƒΡŽΡ‚ Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ зависимостСй ΠΈ структуру модуля, ΠΎΡΡ‚Π°Π»ΡŒΠ½ΠΎΠ΅ опрСдСляСт ΠΊΠΎΠΌΠ°Π½Π΄Π°. - - -## Π‘Π»ΠΎΠΈ - -Π Π°Π·Π΄Π΅Π» описываСт слои SLM: Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ слой, ΠΊΠ°ΠΊΠΈΠ΅ Π±Ρ‹Π²Π°ΡŽΡ‚, ΠΊΠ°ΠΊ ΠΌΠ΅ΠΆΠ΄Ρƒ Π½ΠΈΠΌΠΈ Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½Ρ‹ зависимости ΠΈ ΠΊΠ°ΠΊΠΈΠ΅ ΠΏΡ€Π°Π²ΠΈΠ»Π° Π΄Π΅ΠΉΡΡ‚Π²ΡƒΡŽΡ‚ Π½Π° ΠΊΠ°ΠΆΠ΄ΠΎΠΌ. - -### ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ - -**Π‘Π»ΠΎΠΉ β€” ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΊΠΎΠ΄Π° Π²Π½ΡƒΡ‚Ρ€ΠΈ `src/`. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ слой ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Π·Π° свою ΠΎΠ±Π»Π°ΡΡ‚ΡŒ (каркас страницы, бизнСс-Π»ΠΎΠ³ΠΈΠΊΠ°, UI-ΠΊΠΈΡ‚) ΠΈ Π·Π°Π΄Π°Ρ‘Ρ‚ ΠΏΡ€Π°Π²ΠΈΠ»Π° для ΠΊΠΎΠ΄Π° Π²Π½ΡƒΡ‚Ρ€ΠΈ: Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΎΠ², ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ΠΈΠ΅, допустимыС связи ΠΌΠ΅ΠΆΠ΄Ρƒ модулями.** - -### Π“Ρ€ΡƒΠΏΠΏΡ‹ слоёв - -Π‘Π»ΠΎΠΈ дСлятся Π½Π° Ρ‚Ρ€ΠΈ Π³Ρ€ΡƒΠΏΠΏΡ‹: - -| Π“Ρ€ΡƒΠΏΠΏΠ° | Π‘Π»ΠΎΠΈ | ОписаниС | -|--------|------|----------| -| ΠšΠΎΠΌΠΏΠΎΠ·ΠΈΡ†ΠΈΡ | `app`, `layouts`, `screens`, `widgets` | Π‘ΠΎΠ±ΠΈΡ€Π°ΡŽΡ‚ интСрфСйс ΠΈΠ· Π³ΠΎΡ‚ΠΎΠ²Ρ‹Ρ… Π±Π»ΠΎΠΊΠΎΠ²: ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρ‹, каркасы, страницы | -| Π―Π΄Ρ€ΠΎ | `business`, `infrastructure`, `ui` | РСализация ΠΏΡ€ΠΎΠ΄ΡƒΠΊΡ‚Π°: бизнСс-Π΄ΠΎΠΌΠ΅Π½Ρ‹, тСхсСрвисы, UI-ΠΊΠΈΡ‚ | -| Π€ΡƒΠ½Π΄Π°ΠΌΠ΅Π½Ρ‚ | `shared` | ΠžΠ±Ρ‰ΠΈΠ΅ рСсурсы: ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Ρ‹, Ρ…Π΅Π»ΠΏΠ΅Ρ€Ρ‹, стили, ΠΊΠΎΠ½Ρ„ΠΈΠ³ΠΈ | - -### НаправлСниС зависимостСй - -Π›ΡŽΠ±ΠΎΠΉ ΠΈΠΌΠΏΠΎΡ€Ρ‚ ΠΌΠ΅ΠΆΠ΄Ρƒ модулями β€” Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Π΅Ρ€Π΅Π· ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ API. - -``` -app β†’ [ layouts | screens ] β†’ widgets β†’ business β†’ infrastructure β†’ ui β†’ shared -``` - -- `layouts` ΠΈ `screens` β€” ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Ρ‹Π΅ слои, Π½Π΅ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ Π΄Ρ€ΡƒΠ³ Π΄Ρ€ΡƒΠ³Π° -- ΠœΠΎΠ΄ΡƒΠ»ΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ слоя Π² Π³Ρ€ΡƒΠΏΠΏΠ΅ Β«ΠšΠΎΠΌΠΏΠΎΠ·ΠΈΡ†ΠΈΡΒ» ΠΈΠ·ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ Π΄Ρ€ΡƒΠ³ ΠΎΡ‚ Π΄Ρ€ΡƒΠ³Π° -- ΠœΠΎΠ΄ΡƒΠ»ΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ слоя `infrastructure` ΠΈ `ui` ΠΌΠΎΠ³ΡƒΡ‚ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΄Ρ€ΡƒΠ³ Π΄Ρ€ΡƒΠ³Π° Ρ‡Π΅Ρ€Π΅Π· ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ API -- ΠœΠΎΠ΄ΡƒΠ»ΠΈ `business` β€” cross-domain зависимости ΠΏΠΎ ΠΊΠΎΠ΄Ρƒ Ρ‡Π΅Ρ€Π΅Π· Ρ„Π°Π±Ρ€ΠΈΠΊΡƒ, `import type` Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ -- Π˜ΠΌΠΏΠΎΡ€Ρ‚ Ρ‚ΠΈΠΏΠΎΠ² (`import type`) Π² Β«Π―Π΄Ρ€Π΅Β» Ρ€Π°Π·Ρ€Π΅ΡˆΡ‘Π½ Π² ΠΎΠ±ΠΎΠΈΡ… направлСниях - - -### Π‘Π»ΠΎΠΉ App - -Π’ΠΎΡ‡ΠΊΠ° Π²Ρ…ΠΎΠ΄Π° прилоТСния. ΠžΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Π·Π° запуск, Ρ€ΠΎΡƒΡ‚ΠΈΠ½Π³ ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΎΠ² ΠΈΠ· layout ΠΈ screen. - -Π’ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ… слоёв, `app/` Π½Π΅ содСрТит ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ SLM. Π—Π΄Π΅ΡΡŒ ΠΆΠΈΠ²ΡƒΡ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ инфраструктурныС Ρ„Π°ΠΉΠ»Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π½ΠΈΠΊΠ°ΠΊΠΈΠΌ Π΄Ρ€ΡƒΠ³ΠΈΠΌ слоСм: Ρ„Π°ΠΉΠ»Ρ‹ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ° Ρ€ΠΎΡƒΡ‚ΠΈΠ½Π³Π°, Ρ‚ΠΎΡ‡ΠΊΠ° запуска ΠΈ ΠΊΠΎΠ΄ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ. - -#### ВрСбования - -- НС содСрТит ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ SLM β€” Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ„Π°ΠΉΠ»Ρ‹ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ°, Ρ€ΠΎΡƒΡ‚ΠΈΠ½Π³, инициализация -- Π‘ΠΎΠ΄Π΅Ρ€ΠΆΠΈΡ‚: Ρ„Π°ΠΉΠ»Ρ‹ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΎΠ², bootstrap, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ ошибок Π²Π΅Ρ€Ρ…Π½Π΅Π³ΠΎ уровня (404, error boundary), ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Ρ… стилСй ΠΈ ассСтов -- ΠŸΡ€ΠΎΠ²Π°ΠΉΠ΄Π΅Ρ€Ρ‹ ΠΈ Π³Π°Ρ€Π΄Ρ‹ β€” Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ Π³ΠΎΡ‚ΠΎΠ²Ρ‹Π΅ ΠΈΠ· Π½ΠΈΠΆΠ½ΠΈΡ… слоёв, Π½Π΅ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ -- НС содСрТит бизнСс-Π»ΠΎΠ³ΠΈΠΊΡƒ, UI-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹, Ρ…ΡƒΠΊΠΈ, сторы, сСрвисы -- НикСм Π½Π΅ импортируСтся - -### Π‘Π»ΠΎΠΉ Layouts - -ΠšΠ°Ρ€ΠΊΠ°Ρ страницы: ΠΎΠ±Ρ‰ΠΈΠ΅ элСмСнты, ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹Π΅ для Π³Ρ€ΡƒΠΏΠΏΡ‹ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΎΠ² (header, footer, sidebar). - -```text -src/layouts/ -β”œβ”€β”€ main/ -β”œβ”€β”€ dashboard/ -└── auth/ -``` - -#### ВрСбования - -- Π‘ΠΎΠ΄Π΅Ρ€ΠΆΠΈΡ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΌΠΎΠ΄ΡƒΠ»ΠΈ -- НС содСрТит бизнСс-Π»ΠΎΠ³ΠΈΠΊΡƒ -- ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚Π½ΠΎ-зависимыС Π±Π»ΠΎΠΊΠΈ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Ρ‡Π΅Ρ€Π΅Π· пропсы ΠΎΡ‚ `app`, Π½Π΅ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ - -### Π‘Π»ΠΎΠΉ Screens - -ΠšΠΎΠ½Ρ‚Π΅Π½Ρ‚ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΉ страницы: собираСт Π΅Ρ‘ ΠΈΠ· ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ Π½ΠΈΠΆΠ½ΠΈΡ… слоёв. - -```text -src/screens/ -β”œβ”€β”€ home/ -β”œβ”€β”€ products/ -β”œβ”€β”€ product-detail/ -β”œβ”€β”€ about/ -└── contacts/ -``` - -Когда количСство страниц затрудняСт Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΡŽ β€” вводится Π³Ρ€ΡƒΠΏΠΏΠΈΡ€ΠΎΠ²ΠΊΠ° ΠΏΠΎ Ρ€Π°Π·Π΄Π΅Π»Π°ΠΌ. Π“Ρ€ΡƒΠΏΠΏΠ° β€” ΠΏΠ°ΠΏΠΊΠ° для ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ, Π½Π΅ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ (Π±Π΅Π· `index.ts`). - -```text -src/screens/ -β”œβ”€β”€ shop/ -β”‚ β”œβ”€β”€ home/ -β”‚ β”œβ”€β”€ products/ -β”‚ β”œβ”€β”€ product-detail/ -β”‚ └── cart/ -β”œβ”€β”€ account/ -β”‚ β”œβ”€β”€ profile/ -β”‚ β”œβ”€β”€ settings/ -β”‚ └── order-history/ -└── info/ - β”œβ”€β”€ about/ - β”œβ”€β”€ contacts/ - └── faq/ -``` - -#### ВрСбования - -- Π‘ΠΎΠ΄Π΅Ρ€ΠΆΠΈΡ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΌΠΎΠ΄ΡƒΠ»ΠΈ -- НС содСрТит бизнСс-Π»ΠΎΠ³ΠΈΠΊΡƒ -- Π›ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ ΠΎΠ΄Π½ΠΎΡ€Π°Π·ΠΎΠ²Ρ‹Π΅ сСкции ΠΆΠΈΠ²ΡƒΡ‚ Π²Π½ΡƒΡ‚Ρ€ΠΈ screen-модуля, Π½Π΅ выносятся Π² `widgets`/`business` - -### Π‘Π»ΠΎΠΉ Widgets - -Боставной Π±Π»ΠΎΠΊ интСрфСйса, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½ΡƒΠ΅Ρ‚ ΠΌΠΎΠ΄ΡƒΠ»ΠΈ ядра, Π½ΠΎ Π½Π΅ ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠΈΡ‚ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΌΡƒ бизнСс-Π΄ΠΎΠΌΠ΅Π½Ρƒ. Widget появляСтся ΠΊΠΎΠ³Π΄Π° Π±Π»ΠΎΠΊ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π² Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… screens ΠΈΠ»ΠΈ layouts. - -Если Π±Π»ΠΎΠΊ ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠΈΡ‚ Π΄ΠΎΠΌΠ΅Π½Ρƒ β€” ΠΎΠ½ ΠΆΠΈΠ²Ρ‘Ρ‚ Π² `business/{area}/`, Π΄Π°ΠΆΠ΅ Ссли ΠΏΠ΅Ρ€Π΅ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ. Если Π±Π»ΠΎΠΊ Π½ΡƒΠΆΠ΅Π½ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² ΠΎΠ΄Π½ΠΎΠΌ мСстС β€” это `screens/{name}/parts/` ΠΈΠ»ΠΈ `layouts/{name}/parts/`, Π° Π½Π΅ widget. - -```text -src/widgets/ -β”œβ”€β”€ page-heading/ -β”œβ”€β”€ hero-section/ -β”œβ”€β”€ onboarding-checklist/ -β”œβ”€β”€ promo-banner/ -└── error-boundary/ -``` - -#### ВрСбования - -- НС ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠΈΡ‚ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΌΡƒ бизнСс-Π΄ΠΎΠΌΠ΅Π½Ρƒ. Если Π±Π»ΠΎΠΊ Π΄ΠΎΠΌΠ΅Π½Π½Ρ‹ΠΉ β€” ΠΎΠ½ ΠΆΠΈΠ²Ρ‘Ρ‚ Π² `business/` -- Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π² Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… screens ΠΈΠ»ΠΈ layouts - -### Π‘Π»ΠΎΠΉ Business - -БизнСс-Π΄ΠΎΠΌΠ΅Π½Ρ‹ прилоТСния: auth, catalog, orders, checkout, chat. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ Π΄ΠΎΠΌΠ΅Π½ β€” ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ со своими Ρ‚ΠΈΠΏΠ°ΠΌΠΈ, Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ, UI ΠΈ сСрвисами. - -Π‘Π»ΠΎΠΉ Π²Ρ…ΠΎΠ΄ΠΈΡ‚ Π² Π³Ρ€ΡƒΠΏΠΏΡƒ Β«Π―Π΄Ρ€ΠΎΒ». Π˜ΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ `infrastructure/`, `ui/`, `shared/`. Cross-domain зависимости ΠΏΠΎ ΠΊΠΎΠ΄Ρƒ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‚ΡΡ Ρ‡Π΅Ρ€Π΅Π· Ρ„Π°Π±Ρ€ΠΈΠΊΡƒ. `import type` ΠΌΠ΅ΠΆΠ΄Ρƒ Π΄ΠΎΠΌΠ΅Π½Π°ΠΌΠΈ Ρ€Π°Π·Ρ€Π΅ΡˆΡ‘Π½ Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ. - -Business ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π² FSD Ρ€Π°Π·Π΄Π΅Π»Π΅Π½ΠΎ Π½Π° `features` ΠΈ `entities`: ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠ΅ сцСнарии ΠΈ бизнСс-сущности ΠΆΠΈΠ²ΡƒΡ‚ вмСстС, Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π΄ΠΎΠΌΠ΅Π½Π°. Π’Π½ΡƒΡ‚Ρ€ΠΈ Π΄ΠΎΠΌΠ΅Π½Π° сСгмСнты Ρ€Π°Π·Π΄Π΅Π»ΡΡŽΡ‚ ΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²Π΅Π½Π½ΠΎΡΡ‚ΡŒ: `types/` β€” домСнная модСль, `hooks/` ΠΈ `services/` β€” сцСнарии ΠΈ Π»ΠΎΠ³ΠΈΠΊΠ°, `mappers/` β€” трансформация Π΄Π°Π½Π½Ρ‹Ρ…, `parts/` β€” составныС Π±Π»ΠΎΠΊΠΈ. - -```text -src/business/ -β”œβ”€β”€ auth/ -β”œβ”€β”€ catalog/ -β”œβ”€β”€ orders/ -β”œβ”€β”€ checkout/ -└── chat/ -``` - -Когда количСство Π΄ΠΎΠΌΠ΅Π½ΠΎΠ² затрудняСт Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΡŽ β€” вводится Π³Ρ€ΡƒΠΏΠΏΠΈΡ€ΠΎΠ²ΠΊΠ° ΠΏΠΎ субдомСнам. Π“Ρ€ΡƒΠΏΠΏΠ° β€” ΠΏΠ°ΠΏΠΊΠ° для ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ, Π½Π΅ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ (Π±Π΅Π· `index.ts`). - -```text -src/business/ -β”œβ”€β”€ commerce/ -β”‚ β”œβ”€β”€ catalog/ -β”‚ β”œβ”€β”€ cart/ -β”‚ β”œβ”€β”€ orders/ -β”‚ └── checkout/ -└── communication/ - β”œβ”€β”€ chat/ - └── notifications/ -``` - -#### ВрСбования - -- Один ΠΌΠΎΠ΄ΡƒΠ»ΡŒ = ΠΎΠ΄ΠΈΠ½ бизнСс-Π΄ΠΎΠΌΠ΅Π½ -- ЦикличСскиС зависимости ΠΌΠ΅ΠΆΠ΄Ρƒ Π΄ΠΎΠΌΠ΅Π½Π°ΠΌΠΈ Π·Π°ΠΏΡ€Π΅Ρ‰Π΅Π½Ρ‹ -- Π˜ΠΌΠΏΠΎΡ€Ρ‚ ΠΊΠΎΠ΄Π° ΠΌΠ΅ΠΆΠ΄Ρƒ Π΄ΠΎΠΌΠ΅Π½Π°ΠΌΠΈ β€” Ρ‡Π΅Ρ€Π΅Π· Ρ„Π°Π±Ρ€ΠΈΠΊΡƒ. `import type` β€” Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ -- Π”ΠΎΠΌΠ΅Π½Π½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ (`User`, `Product`) ΠΆΠΈΠ²ΡƒΡ‚ здСсь, Π½Π΅ Π² `shared/` - -### Π‘Π»ΠΎΠΉ Infrastructure - -ВСхсСрвисы прилоТСния: theme, i18n, API-Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Ρ‹, logger, realtime. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ сСрвис β€” ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ. - -Π‘Π»ΠΎΠΉ Π²Ρ…ΠΎΠ΄ΠΈΡ‚ Π² Π³Ρ€ΡƒΠΏΠΏΡƒ Β«Π―Π΄Ρ€ΠΎΒ». Π˜ΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ `infrastructure/`, `ui/`, `shared/`. - -ΠžΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ `shared/`: infrastructure β€” инфраструктура прилоТСния (сСрвисы, Ρ‚Π΅ΠΌΡ‹, Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Ρ‹ ΠΊ API), `shared/` β€” ΠΎΠ±Ρ‰ΠΈΠ΅ рСсурсы (ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Ρ‹, Ρ…Π΅Π»ΠΏΠ΅Ρ€Ρ‹, стили, ΠΊΠΎΠ½Ρ„ΠΈΠ³ΠΈ). - -```text -src/infrastructure/ -β”œβ”€β”€ theme/ -β”œβ”€β”€ i18n/ -β”œβ”€β”€ backend-api/ -β”œβ”€β”€ maps-api/ -β”œβ”€β”€ logger/ -β”œβ”€β”€ feature-flags/ -└── realtime/ -``` - -#### ВрСбования - -- Один ΠΌΠΎΠ΄ΡƒΠ»ΡŒ = ΠΎΠ΄ΠΈΠ½ тСхсСрвис -- Π˜ΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ `infrastructure/`, `ui/`, `shared/` - -### Π‘Π»ΠΎΠΉ UI - -UI-ΠΊΠΈΡ‚ Π±Π΅Π· бизнСс-Π»ΠΎΠ³ΠΈΠΊΠΈ: button, carousel, toast, modal. - -Π‘Π»ΠΎΠΉ Π²Ρ…ΠΎΠ΄ΠΈΡ‚ Π² Π³Ρ€ΡƒΠΏΠΏΡƒ Β«Π―Π΄Ρ€ΠΎΒ». Π˜ΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ `ui/` ΠΈ `shared/`. - -ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ строятся Π΄Ρ€ΡƒΠ³ Π½Π° Π΄Ρ€ΡƒΠ³Π΅: `button` ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ `icon`, `carousel` ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ `button`. - -```text -src/ui/ -β”œβ”€β”€ button/ -β”œβ”€β”€ input/ -β”œβ”€β”€ icon/ -β”œβ”€β”€ carousel/ -β”œβ”€β”€ modal/ -β”œβ”€β”€ toast/ -β”œβ”€β”€ dropdown/ -β”œβ”€β”€ tabs/ -└── tooltip/ -``` - -Когда количСство ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² затрудняСт Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΡŽ β€” вводится Π³Ρ€ΡƒΠΏΠΏΠΈΡ€ΠΎΠ²ΠΊΠ° Π½Π° ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Ρ‹ ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ. ΠŸΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Ρ‹ (`button`, `icon`, `input`) Π½Π΅ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ ΠΊΠΎΠΌΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ. ΠšΠΎΠΌΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ (`carousel`, `modal`, `dropdown`) строятся Π½Π° ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Π°Ρ…. - -```text -src/ui/ -β”œβ”€β”€ primitives/ -β”‚ β”œβ”€β”€ button/ -β”‚ β”œβ”€β”€ input/ -β”‚ β”œβ”€β”€ icon/ -β”‚ └── badge/ -└── composites/ - β”œβ”€β”€ carousel/ - β”œβ”€β”€ modal/ - β”œβ”€β”€ dropdown/ - β”œβ”€β”€ tabs/ - └── tooltip/ -``` - -#### ВрСбования - -- НС содСрТит бизнСс-Π»ΠΎΠ³ΠΈΠΊΡƒ -- Π˜ΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ `ui/` ΠΈ `shared/` - -### Π‘Π»ΠΎΠΉ Shared - -ΠžΠ±Ρ‰ΠΈΠ΅ рСсурсы: ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Ρ‹, Ρ…Π΅Π»ΠΏΠ΅Ρ€Ρ‹, стили, ΠΊΠΎΠ½Ρ„ΠΈΠ³ΠΈ. НС Π·Π½Π°Π΅Ρ‚ ΠΎ бизнСс-Π΄ΠΎΠΌΠ΅Π½Π΅. - -Π‘Π»ΠΎΠΉ Π²Ρ…ΠΎΠ΄ΠΈΡ‚ Π² Π³Ρ€ΡƒΠΏΠΏΡƒ Β«Π€ΡƒΠ½Π΄Π°ΠΌΠ΅Π½Ρ‚Β» β€” Π½ΠΈ ΠΎ ΠΊΠΎΠΌ Π½Π΅ Π·Π½Π°Π΅Ρ‚, Π½ΠΈΠΊΠΎΠ³ΠΎ Π½Π΅ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚. - -ΠžΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ `infrastructure/`: infrastructure β€” инфраструктура прилоТСния (сСрвисы, Ρ‚Π΅ΠΌΡ‹, Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Ρ‹ ΠΊ API), `shared/` β€” ΠΎΠ±Ρ‰ΠΈΠ΅ рСсурсы (ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Ρ‹, Ρ…Π΅Π»ΠΏΠ΅Ρ€Ρ‹, стили, ΠΊΠΎΠ½Ρ„ΠΈΠ³ΠΈ). - -ΠžΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ `ui/`: UI-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ (button, carousel, modal) ΠΆΠΈΠ²ΡƒΡ‚ Π² слоС `ui/`, Π° Π½Π΅ здСсь. - -```text -src/shared/ -β”œβ”€β”€ lib/ -β”œβ”€β”€ types/ -β”œβ”€β”€ styles/ -└── sprites/ -``` - -#### ВрСбования - -- НС ΠΈΠΌΠ΅Π΅Ρ‚ runtime-состояния - - -## ΠœΠΎΠ΄ΡƒΠ»ΠΈ - -Π Π°Π·Π΄Π΅Π» описываСт ΠΌΠΎΠ΄ΡƒΠ»ΠΈ SLM: Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ, ΠΈΠ· Ρ‡Π΅Π³ΠΎ ΠΎΠ½ состоит ΠΈ ΠΊΠ°ΠΊ взаимодСйствуСт с ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹ΠΌ ΠΊΠΎΠ΄ΠΎΠΌ. - -### ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ - -**ΠœΠΎΠ΄ΡƒΠ»ΡŒ β€” ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΡΡ‚Ρ€ΠΎΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ Π±Π»ΠΎΠΊ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Ρ‹. Π–ΠΈΠ²Ρ‘Ρ‚ Π½Π° слоС ΠΈ содСрТит всё Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΠ΅ для своСй Ρ€Π°Π±ΠΎΡ‚Ρ‹: ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹, Ρ…ΡƒΠΊΠΈ, сторы, сСрвисы, Ρ‚ΠΈΠΏΡ‹, стили. Набор содСрТимого Π½Π΅ фиксирован β€” Π²ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½ΡƒΠΆΠ½Ρ‹Π΅ части.** - -### ΠœΠΎΠ΄ΡƒΠ»ΡŒ vs ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ - -**ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚** β€” ΠΎΠ΄ΠΈΠ½ `.tsx` Ρ„Π°ΠΉΠ». НС ΠΈΠΌΠ΅Π΅Ρ‚ своих сСгмСнтов, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ сСгмСнты Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ модуля. Π–ΠΈΠ²Ρ‘Ρ‚ Π² ΠΊΠΎΡ€Π½Π΅ ΠΈΠ»ΠΈ `ui/` сСгмСнтС модуля. - -**ΠœΠΎΠ΄ΡƒΠ»ΡŒ** β€” ΠΏΠ°ΠΏΠΊΠ°, которая ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚, сСгмСнты (`hooks/`, `types/`, `styles/`, `ui/`, `parts/` ΠΈ Ρ‚.Π΄.) ΠΈ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ API (`index.ts`). - -```text -auth/ -β”œβ”€β”€ ui/ -β”‚ β”œβ”€β”€ auth-guard.tsx -β”‚ └── logout-button.tsx -β”œβ”€β”€ parts/ -β”‚ β”œβ”€β”€ login-form/ -β”‚ β”œβ”€β”€ registration-form/ -β”‚ └── restore-form/ -β”œβ”€β”€ hooks/ -β”œβ”€β”€ stores/ -β”œβ”€β”€ types/ -β”œβ”€β”€ auth.tsx # ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ (ΠΎΠΏΡ†ΠΈΠΎΠ½Π°Π»Π΅Π½) -└── index.ts -``` - -### Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° - -ΠœΠΎΠ΄ΡƒΠ»ΡŒ состоит ΠΈΠ· сСгмСнтов. Ни ΠΎΠ΄ΠΈΠ½ сСгмСнт Π½Π΅ обязатСлСн β€” ΠΌΠΎΠ΄ΡƒΠ»ΡŒ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΡΡ‚ΠΎΡΡ‚ΡŒ Π΄Π°ΠΆΠ΅ ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ `index.ts` с рСэкспортом Ρ‚ΠΈΠΏΠΎΠ². - -```text -{module-name}/ -β”œβ”€β”€ {module-name}.tsx # ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ (ΠΎΠΏΡ†ΠΈΠΎΠ½Π°Π»Π΅Π½) -β”œβ”€β”€ ui/ # ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ модуля (Ρ‚ΠΎΠ»ΡŒΠΊΠΎ .tsx) -β”œβ”€β”€ parts/ # Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ ΠΌΠΎΠ΄ΡƒΠ»ΠΈ (со своими сСгмСнтами) -β”œβ”€β”€ hooks/ # Ρ…ΡƒΠΊΠΈ -β”œβ”€β”€ stores/ # сторы состояния -β”œβ”€β”€ services/ # внСшниС источники Π΄Π°Π½Π½Ρ‹Ρ… -β”œβ”€β”€ mappers/ # трансформация Π΄Π°Π½Π½Ρ‹Ρ… ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π°ΠΌΠΈ -β”œβ”€β”€ types/ # Ρ‚ΠΈΠΏΡ‹ -β”œβ”€β”€ styles/ # стили -β”œβ”€β”€ lib/ # ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Ρ‹ модуля -β”œβ”€β”€ config/ # константы -└── index.ts # ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ API -``` - -ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΠ΅ описаниС ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ сСгмСнта β€” Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ [Π‘Π΅Π³ΠΌΠ΅Π½Ρ‚Ρ‹](/reference/segments). - -### ΠŸΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ API - -ΠœΠΎΠ΄ΡƒΠ»ΡŒ экспортируСт Π½Π°Ρ€ΡƒΠΆΡƒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π½ΡƒΠΆΠ½ΠΎ Π΄Ρ€ΡƒΠ³ΠΈΠΌ. Всё ΠΎΡΡ‚Π°Π»ΡŒΠ½ΠΎΠ΅ β€” Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅Π΅. - -```ts -// business/auth/index.ts -export type { User, Session } from './types/user.types' -export { useAuth } from './hooks/use-auth.hook' -export { AuthGuard } from './ui/auth-guard' -``` - -Π˜ΠΌΠΏΠΎΡ€Ρ‚ Π² ΠΎΠ±Ρ…ΠΎΠ΄ `index.ts` Π·Π°ΠΏΡ€Π΅Ρ‰Ρ‘Π½: - -```ts -// ΠŸΠ»ΠΎΡ…ΠΎ -import { validateToken } from '@/business/auth/lib/tokens' - -// Π₯ΠΎΡ€ΠΎΡˆΠΎ -import { useAuth } from '@/business/auth' -``` - -### Π€Π°Π±Ρ€ΠΈΠΊΠ° - -Если ΠΌΠΎΠ΄ΡƒΠ»ΡŒ зависит ΠΎΡ‚ ΠΊΠΎΠ΄Π° Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ бизнСс-Π΄ΠΎΠΌΠ΅Π½Π° β€” ΠΎΠ½ экспортируСт Ρ„Π°Π±Ρ€ΠΈΠΊΡƒ. Π€Π°Π±Ρ€ΠΈΠΊΠ° Π΄Π΅ΠΊΠ»Π°Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ зависимости ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ API модуля. Π’ΠΎΡ‡ΠΊΠ° использования (screen, widget, layout) прСдоставляСт зависимости ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅. - -ΠœΠΎΠ΄ΡƒΠ»ΡŒ Π±Π΅Π· cross-domain зависимостСй экспортируСт API Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ. Π’ΠΈΠΏΡ‹ всСгда ΡΠΊΡΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ΡΡ Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ β€” `import type` Π½Π΅ являСтся runtime-Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒΡŽ. - -#### ΠœΠΎΠ΄ΡƒΠ»ΡŒ Π±Π΅Π· зависимостСй β€” прямой экспорт: - -```ts -// business/auth/index.ts -export { useAuth } from './hooks/use-auth' -export { useCurrentUser } from './hooks/use-current-user' -export type { User, Session } from './types' -``` - -#### ΠœΠΎΠ΄ΡƒΠ»ΡŒ с зависимостями β€” Ρ„Π°Π±Ρ€ΠΈΠΊΠ°: - -```ts -// business/chat/types/deps.ts -import type { User } from '@/business/auth' - -export interface ChatDeps { - useCurrentUser: () => User | null -} -``` - -```ts -// business/chat/index.ts -import type { ChatDeps } from './types/deps' - -export function chatFactory(deps: ChatDeps) { - return { - useMessages: (roomId: string) => { - const user = deps.useCurrentUser() - // ... - }, - useSendMessage: (roomId: string) => { - const user = deps.useCurrentUser() - return (text: string) => { /* ... */ } - }, - useChatRooms: () => { - const user = deps.useCurrentUser() - // ... - }, - ChatBadge: ({ count }: { count: number }) => { /* ... */ }, - } -} - -export type { Message, ChatRoom } from './types' -export type { ChatDeps } from './types/deps' -``` - -#### ИспользованиС Π½Π° страницС: - -```tsx -// screens/support/support.tsx -import { useCurrentUser } from '@/business/auth' -import { chatFactory } from '@/business/chat' - -const chat = chatFactory({ useCurrentUser }) - -export function SupportScreen() { - const { useMessages, useSendMessage, ChatBadge } = chat - const messages = useMessages('support') - const sendMessage = useSendMessage('support') - - return ( -
- - {messages.map(m => )} - -
- ) -} -``` - -### Π–ΠΈΠ·Π½Π΅Π½Π½Ρ‹ΠΉ Ρ†ΠΈΠΊΠ» - -ΠœΠΎΠ΄ΡƒΠ»ΡŒ роТдаСтся Π½Π° самом Π½ΠΈΠ·ΠΊΠΎΠΌ ΡƒΡ€ΠΎΠ²Π½Π΅ использования ΠΈ поднимаСтся Π²Ρ‹ΡˆΠ΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΈ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΉ потрСбности. - -- НуТСн Π½Π° ΠΎΠ΄Π½ΠΎΠΉ страницС β†’ `screens/{name}/parts/` -- Появился Π² 2+ мСстах β†’ поднимаСтся ΠΏΠΎ ΠΏΡ€ΠΈΡ€ΠΎΠ΄Π΅: - - абстрактный UI β†’ `ui/` - - Π±Π»ΠΎΠΊ с Π΄Π°Π½Π½Ρ‹ΠΌΠΈ/Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ β†’ `widgets/` - - прСдставлСниС бизнСс-Π΄ΠΎΠΌΠ΅Π½Π° β†’ `business/{area}/parts/` - -ΠŸΠΎΠ΄ΡŠΡ‘ΠΌ β€” ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ Ρ€Π΅Ρ„Π°ΠΊΡ‚ΠΎΡ€ΠΈΠ½Π³ Π² Ρ€Π°ΠΌΠΊΠ°Ρ… Π·Π°Π΄Π°Ρ‡ΠΈ, Π° Π½Π΅ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Π°Ρ Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΡΡ‚ΡŒ. - - -## Π‘Π΅Π³ΠΌΠ΅Π½Ρ‚Ρ‹ - -Π Π°Π·Π΄Π΅Π» описываСт сСгмСнты SLM: Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ сСгмСнт, ΠΊΠ°ΠΊΠΈΠ΅ Π±Ρ‹Π²Π°ΡŽΡ‚ ΠΈ Ρ‡Ρ‚ΠΎ Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΈΠ· Π½ΠΈΡ… Π»Π΅ΠΆΠΈΡ‚. - -### ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ - -**Π‘Π΅Π³ΠΌΠ΅Π½Ρ‚ β€” ΠΏΠ°ΠΏΠΊΠ° Π²Π½ΡƒΡ‚Ρ€ΠΈ модуля, которая Π³Ρ€ΡƒΠΏΠΏΠΈΡ€ΡƒΠ΅Ρ‚ Ρ„Π°ΠΉΠ»Ρ‹ ΠΏΠΎ Π½Π°Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ. Набор сСгмСнтов Π½Π΅ фиксирован β€” ΠΌΠΎΠ΄ΡƒΠ»ΡŒ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π΅ΠΌΡƒ Π½ΡƒΠΆΠ½Ρ‹. Команда сама опрСдСляСт ΠΊΠ°ΠΊΠΈΠ΅ сСгмСнты ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅ β€” Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π° Π΄Π°Ρ‘Ρ‚ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ.** - -### ΠžΠ±Π·ΠΎΡ€ - -| Π‘Π΅Π³ΠΌΠ΅Π½Ρ‚ | Π‘ΠΎΠ΄Π΅Ρ€ΠΆΠΈΠΌΠΎΠ΅ | -|---------|------------| -| `ui/` | ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ модуля β€” Ρ‚ΠΎΠ»ΡŒΠΊΠΎ `.tsx` Ρ„Π°ΠΉΠ»Ρ‹ | -| `parts/` | Π’Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ ΠΌΠΎΠ΄ΡƒΠ»ΠΈ со своими сСгмСнтами | -| `hooks/` | React-Ρ…ΡƒΠΊΠΈ | -| `stores/` | Π‘Ρ‚ΠΎΡ€Ρ‹ состояния | -| `services/` | Π Π°Π±ΠΎΡ‚Π° с внСшними источниками Π΄Π°Π½Π½Ρ‹Ρ… | -| `mappers/` | Врансформация Π΄Π°Π½Π½Ρ‹Ρ… ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π°ΠΌΠΈ | -| `types/` | TypeScript-Ρ‚ΠΈΠΏΡ‹ ΠΈ интСрфСйсы | -| `styles/` | Π‘Ρ‚ΠΈΠ»ΠΈ | -| `lib/` | Π£Ρ‚ΠΈΠ»ΠΈΡ‚Ρ‹ ΠΈ Ρ…Π΅Π»ΠΏΠ΅Ρ€Ρ‹ модуля | -| `config/` | ΠšΠΎΠ½ΡΡ‚Π°Π½Ρ‚Ρ‹ ΠΈ конфигурация | - -### Π‘Π΅Π³ΠΌΠ΅Π½Ρ‚ ui/ - -ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹, ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°Ρ‰ΠΈΠ΅ ΠΌΠΎΠ΄ΡƒΠ»ΡŽ. Π‘ΠΎΠ΄Π΅Ρ€ΠΆΠΈΡ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ `.tsx` Ρ„Π°ΠΉΠ»Ρ‹ β€” Π±Π΅Π· своих сСгмСнтов, стилСй, Ρ‚ΠΈΠΏΠΎΠ², Ρ…ΡƒΠΊΠΎΠ². Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ сСгмСнты Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ модуля. - -```text -auth/ -β”œβ”€β”€ ui/ -β”‚ β”œβ”€β”€ auth-provider.tsx -β”‚ β”œβ”€β”€ auth-guard.tsx -β”‚ └── logout-button.tsx -β”œβ”€β”€ types/ -β”œβ”€β”€ hooks/ -└── index.ts -``` - -Если ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρƒ Π½ΡƒΠΆΠ½Ρ‹ собствСнныС сСгмСнты β€” это ΡƒΠΆΠ΅ Π½Π΅ `ui/`, Π° `parts/`. - -### Π‘Π΅Π³ΠΌΠ΅Π½Ρ‚ parts/ - -Π’Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ ΠΌΠΎΠ΄ΡƒΠ»ΠΈ со своими сСгмСнтами. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ элСмСнт `parts/` β€” ΠΏΠΎΠ»Π½ΠΎΡ†Π΅Π½Π½Ρ‹ΠΉ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ: ΠΏΠ°ΠΏΠΊΠ° с ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠΌ, Ρ…ΡƒΠΊΠ°ΠΌΠΈ, стилями, Ρ‚ΠΈΠΏΠ°ΠΌΠΈ ΠΈ Ρ‚.Π΄. - -```text -home/ -β”œβ”€β”€ parts/ -β”‚ β”œβ”€β”€ hero-section/ -β”‚ β”‚ β”œβ”€β”€ hero-section.tsx -β”‚ β”‚ β”œβ”€β”€ styles/ -β”‚ β”‚ └── parts/ -β”‚ β”‚ └── top-banner/ -β”‚ β”‚ └── top-banner.tsx -β”‚ └── features-section/ -β”‚ β”œβ”€β”€ features-section.tsx -β”‚ └── hooks/ -β”œβ”€β”€ home.screen.tsx -└── index.ts -``` - -ΠžΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ `ui/`: элСмСнт `parts/` β€” ΠΌΠΎΠ΄ΡƒΠ»ΡŒ со своими сСгмСнтами. Π­Π»Π΅ΠΌΠ΅Π½Ρ‚ `ui/` β€” ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚, ΠΎΠ΄ΠΈΠ½ `.tsx` Ρ„Π°ΠΉΠ». - -Π’Π»ΠΎΠΆΠ΅Π½Π½ΠΎΡΡ‚ΡŒ `parts/` инкапсулируСт ΠΎΠ±Π»Π°ΡΡ‚ΡŒ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π³ΠΎΡ€ΠΈΠ·ΠΎΠ½Ρ‚Π°Π»ΡŒΠ½ΠΎ: ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π² своём `parts/`-ΠΌΠΎΠ΄ΡƒΠ»Π΅, Π½Π΅ затрагивая Ρ‡ΡƒΠΆΠΈΠ΅. Π­Ρ‚ΠΎ сниТаСт ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚Ρ‹ ΠΏΡ€ΠΈ ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎΠΉ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅. - -Если Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΉ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ обрастаСт своими `parts/` β€” это сигнал, Ρ‡Ρ‚ΠΎ ΠΎΠ½ достаточно ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ для ΠΏΠΎΠ΄ΡŠΡ‘ΠΌΠ° Π½Π° ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ Π²Ρ‹ΡˆΠ΅. - -### Π‘Π΅Π³ΠΌΠ΅Π½Ρ‚ hooks/ - -React-Ρ…ΡƒΠΊΠΈ модуля. Π˜Π½ΠΊΠ°ΠΏΡΡƒΠ»ΠΈΡ€ΡƒΡŽΡ‚ Π»ΠΎΠ³ΠΈΠΊΡƒ, состояниС, подписки, ΠΏΠΎΠ±ΠΎΡ‡Π½Ρ‹Π΅ эффСкты. - -```text -hooks/ -β”œβ”€β”€ use-auth.hook.ts -β”œβ”€β”€ use-session.hook.ts -└── use-permissions.hook.ts -``` - -### Π‘Π΅Π³ΠΌΠ΅Π½Ρ‚ stores/ - -Π‘Ρ‚ΠΎΡ€Ρ‹ состояния модуля. ΠšΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Π°Ρ рСализация зависит ΠΎΡ‚ Π²Ρ‹Π±Ρ€Π°Π½Π½ΠΎΠ³ΠΎ стСйт-ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Π° (Zustand, MobX, Redux ΠΈ Ρ‚.Π΄.). - -```text -stores/ -β”œβ”€β”€ auth.store.ts -└── session.store.ts -``` - -### Π‘Π΅Π³ΠΌΠ΅Π½Ρ‚ services/ - -Π Π°Π±ΠΎΡ‚Π° с внСшними источниками Π΄Π°Π½Π½Ρ‹Ρ…: API-Π²Ρ‹Π·ΠΎΠ²Ρ‹, запросы, подписки. - -```text -services/ -β”œβ”€β”€ auth.service.ts -└── token.service.ts -``` - -### Π‘Π΅Π³ΠΌΠ΅Π½Ρ‚ mappers/ - -Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ трансформации Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° Π² Π΄Ρ€ΡƒΠ³ΠΎΠΉ: DTO Π² Π΄ΠΎΠΌΠ΅Π½Π½Ρ‹ΠΉ Ρ‚ΠΈΠΏ, Π΄ΠΎΠΌΠ΅Π½Π½Ρ‹ΠΉ Ρ‚ΠΈΠΏ Π² DTO, Π΄ΠΎΠΌΠ΅Π½Π½Ρ‹ΠΉ Ρ‚ΠΈΠΏ Π² ViewModel. - -```text -mappers/ -β”œβ”€β”€ map-user.ts -β”œβ”€β”€ map-product.ts -└── map-order-to-dto.ts -``` - -### Π‘Π΅Π³ΠΌΠ΅Π½Ρ‚ types/ - -TypeScript-Ρ‚ΠΈΠΏΡ‹ ΠΈ интСрфСйсы модуля. Π”ΠΎΠΌΠ΅Π½Π½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹, DTO, пропсы ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ². - -```text -types/ -β”œβ”€β”€ user.type.ts -└── session.type.ts -``` - -### Π‘Π΅Π³ΠΌΠ΅Π½Ρ‚ styles/ - -Π‘Ρ‚ΠΈΠ»ΠΈ модуля. Π€ΠΎΡ€ΠΌΠ°Ρ‚ зависит ΠΎΡ‚ Π²Ρ‹Π±Ρ€Π°Π½Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π° (CSS Modules, SCSS, CSS-in-JS ΠΈ Ρ‚.Π΄.). - -```text -styles/ -β”œβ”€β”€ auth.module.css -└── login-form.module.css -``` - -### Π‘Π΅Π³ΠΌΠ΅Π½Ρ‚ lib/ - -Π£Ρ‚ΠΈΠ»ΠΈΡ‚Ρ‹ ΠΈ Ρ…Π΅Π»ΠΏΠ΅Ρ€Ρ‹, спСцифичныС для модуля. ЧистыС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π±Π΅Π· ΠΏΠΎΠ±ΠΎΡ‡Π½Ρ‹Ρ… эффСктов. - -```text -lib/ -β”œβ”€β”€ validate-email.ts -└── format-phone.ts -``` - -ΠžΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ `shared/lib/`: здСсь Π»Π΅ΠΆΠ°Ρ‚ ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Ρ‹, Π½ΡƒΠΆΠ½Ρ‹Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ этому ΠΌΠΎΠ΄ΡƒΠ»ΡŽ. ΠžΠ±Ρ‰ΠΈΠ΅ ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Ρ‹ β€” Π² `shared/lib/`. - -### Π‘Π΅Π³ΠΌΠ΅Π½Ρ‚ config/ - -ΠšΠΎΠ½ΡΡ‚Π°Π½Ρ‚Ρ‹ ΠΈ конфигурация модуля: ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρ‹, Π»ΠΈΠΌΠΈΡ‚Ρ‹, Π΄Π΅Ρ„ΠΎΠ»Ρ‚Π½Ρ‹Π΅ значСния. - -```text -config/ -β”œβ”€β”€ routes.ts -└── constants.ts -``` diff --git a/preview/ai/basics/code-style.md b/preview/ai/basics/code-style.md deleted file mode 100644 index f933e18..0000000 --- a/preview/ai/basics/code-style.md +++ /dev/null @@ -1,154 +0,0 @@ ---- -title: Π‘Ρ‚ΠΈΠ»ΡŒ ΠΊΠΎΠ΄Π° -scope: basics -keywords: [Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅, ΠΈΠΌΠΏΠΎΡ€Ρ‚, отступ, ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠΈ, early return, Ρ‚ΠΎΡ‡ΠΊΠ° с запятой, Π»ΠΈΠ½Ρ‚Π΅Ρ€] -when: "НаписаниС ΠΈΠ»ΠΈ Ρ€Π΅Π²ΡŒΡŽ любого ΠΊΠΎΠ΄Π°: Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅, ΠΈΠΌΠΏΠΎΡ€Ρ‚Ρ‹, структура Ρ„Π°ΠΉΠ»Π°" ---- -# Π‘Ρ‚ΠΈΠ»ΡŒ ΠΊΠΎΠ΄Π° - -Π Π°Π·Π΄Π΅Π» описываСт Π΅Π΄ΠΈΠ½Ρ‹Π΅ ΠΏΡ€Π°Π²ΠΈΠ»Π° оформлСния ΠΊΠΎΠ΄Π°: отступы, пСрСносы, ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠΈ, порядок ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΎΠ² ΠΈ Π±Π°Π·ΠΎΠ²ΡƒΡŽ Ρ‡ΠΈΡ‚Π°Π΅ΠΌΠΎΡΡ‚ΡŒ. - -## ΠžΡ‚ΡΡ‚ΡƒΠΏΡ‹ - -- 2 ΠΏΡ€ΠΎΠ±Π΅Π»Π° (Π½Π΅ Ρ‚Π°Π±Ρ‹). - -## Π”Π»ΠΈΠ½Π° строк - -- ΠžΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π½Π° 100 символов, Π½ΠΎ ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ΅Π½ΠΈΠ΅ допустимо, Ссли строка читаСтся Π»Π΅Π³ΠΊΠΎ. -- ΠŸΠ΅Ρ€Π΅Π½ΠΎΡΠΈΡ‚ΡŒ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Π½Π° Π½ΠΎΠ²Ρ‹Π΅ строки, ΠΊΠΎΠ³Π΄Π° строка становится ΠΏΠ»ΠΎΡ…ΠΎ Ρ‡ΠΈΡ‚Π°Π΅ΠΌΠΎΠΉ. -- НС ΠΏΠ΅Ρ€Π΅Π½ΠΎΡΠΈΡ‚ΡŒ строку Π²Π½ΡƒΡ‚Ρ€ΠΈ строковых Π»ΠΈΡ‚Π΅Ρ€Π°Π»ΠΎΠ² Π±Π΅Π· нСобходимости. - -**Π₯ΠΎΡ€ΠΎΡˆΠΎ** -```ts -const config = createRequestConfig( - endpoint, - { - headers: { - 'X-Request-Id': requestId, - 'X-User-Id': userId, - }, - params: { - page, - pageSize, - sort: 'createdAt', - }, - }, - timeoutMs, -); -``` - -**ΠŸΠ»ΠΎΡ…ΠΎ** -```ts -// ΠŸΠ»ΠΎΡ…ΠΎ: длинная строка с Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΌΠΈ структурами ΠΏΠ»ΠΎΡ…ΠΎ читаСтся. -const config = createRequestConfig(endpoint, { headers: { 'X-Request-Id': requestId, 'X-User-Id': userId }, params: { page, pageSize, sort: 'createdAt' } }, timeoutMs); -``` - -## ΠšΠ°Π²Ρ‹Ρ‡ΠΊΠΈ - -- Π’ JavaScript/TypeScript ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½Π°Ρ€Π½Ρ‹Π΅ ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠΈ. -- Π’ JSX/TSX для Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ² ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π²ΠΎΠΉΠ½Ρ‹Π΅ ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠΈ. -- Π¨Π°Π±Π»ΠΎΠ½Π½Ρ‹Π΅ строки ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΈ интСрполяции ΠΈΠ»ΠΈ многострочном тСкстС. - -**Π₯ΠΎΡ€ΠΎΡˆΠΎ** -```ts -const label = 'Π‘ΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ'; -const title = `ΠŸΡ€ΠΈΠ²Π΅Ρ‚, ${name}`; -``` - -```tsx - -``` - -**ΠŸΠ»ΠΎΡ…ΠΎ** -```ts -// ΠŸΠ»ΠΎΡ…ΠΎ: Π΄Π²ΠΎΠΉΠ½Ρ‹Π΅ ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠΈ Π² TS ΠΈ конкатСнация вмСсто шаблонной строки. -const label = "Π‘ΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ"; -const title = 'ΠŸΡ€ΠΈΠ²Π΅Ρ‚, ' + name; -``` - -```tsx -// ΠŸΠ»ΠΎΡ…ΠΎ: ΠΎΠ΄ΠΈΠ½Π°Ρ€Π½Ρ‹Π΅ ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠΈ Π² JSX-Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π°Ρ…. - -``` - -## Π’ΠΎΡ‡ΠΊΠΈ с запятой ΠΈ запятыС - -- Π”ΠΎΠΏΡƒΡΠΊΠ°ΡŽΡ‚ΡΡ упущСния Ρ‚ΠΎΡ‡ΠΊΠΈ с запятой, Ссли ΠΊΠΎΠ΄ остаётся Ρ‡ΠΈΡ‚Π°Π΅ΠΌΡ‹ΠΌ ΠΈ ΠΎΠ΄Π½ΠΎΠ·Π½Π°Ρ‡Π½Ρ‹ΠΌ. -- Π’ многострочных массивах, ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°Ρ… ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ запятая Π² ΠΊΠΎΠ½Ρ†Π΅ допускаСтся, Π½ΠΎ Π½Π΅ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Π°. - -## Π˜ΠΌΠΏΠΎΡ€Ρ‚Ρ‹ - -- Π’ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Ρ… ΠΈΠΌΠΏΠΎΡ€Ρ‚Π°Ρ… ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ±Π΅Π»Ρ‹ Π²Π½ΡƒΡ‚Ρ€ΠΈ Ρ„ΠΈΠ³ΡƒΡ€Π½Ρ‹Ρ… скобок. -- Π’ΠΈΠΏΡ‹ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· `import type`. -- `default` экспорт ΠΈΠ·Π±Π΅Π³Π°Ρ‚ΡŒ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Π΅. `default` ΠΈΠΌΠΏΠΎΡ€Ρ‚ допустим (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, стили CSS Modules, сторонниС Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ). -- Π˜Π·Π±Π΅Π³Π°Ρ‚ΡŒ ΠΈΠΌΠΏΠΎΡ€Ρ‚Π° всСго модуля Ρ‡Π΅Ρ€Π΅Π· `*`. - -**Π₯ΠΎΡ€ΠΎΡˆΠΎ** -```ts -import { MyComponent } from 'MyComponent'; -import type { User } from '../model/types'; -import styles from './styles/button.module.css'; -``` - -**ΠŸΠ»ΠΎΡ…ΠΎ** -```ts -// ΠŸΠ»ΠΎΡ…ΠΎ: отсутствиС ΠΏΡ€ΠΎΠ±Π΅Π»ΠΎΠ² Π² ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½ΠΎΠΌ ΠΈΠΌΠΏΠΎΡ€Ρ‚Π΅. -import type {User} from '../model/types'; -// ΠŸΠ»ΠΎΡ…ΠΎ: default экспорт. -export default MyComponent; -``` - -## Π Π°Π½Π½ΠΈΠ΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Ρ‹ (early return) - -- Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π°Π½Π½ΠΈΠ΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Ρ‹ для упрощСния чтСния. -- Π˜Π·Π±Π΅Π³Π°Ρ‚ΡŒ `else` послС `return`. - -**Π₯ΠΎΡ€ΠΎΡˆΠΎ** -```ts -const getName = (user?: { name: string }) => { - if (!user) { - return 'Π“ΠΎΡΡ‚ΡŒ'; - } - - return user.name; -}; -``` - -**ΠŸΠ»ΠΎΡ…ΠΎ** -```ts -// ΠŸΠ»ΠΎΡ…ΠΎ: лишний else послС return услоТняСт Ρ‡Ρ‚Π΅Π½ΠΈΠ΅. -const getName = (user?: { name: string }) => { - if (user) { - return user.name; - } else { - return 'Π“ΠΎΡΡ‚ΡŒ'; - } -}; -``` - -## Π€ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² ΠΈ массивов - -- Π’ многострочных ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°Ρ… ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ свойство Π½Π° Π½ΠΎΠ²ΠΎΠΉ строкС. -- Π’ многострочных массивах ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ элСмСнт Π½Π° Π½ΠΎΠ²ΠΎΠΉ строкС. -- ΠžΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΈ массивы ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΈΡΠ°Ρ‚ΡŒ Π² ΠΎΠ΄Π½Ρƒ строку, Ссли Π΄Π»ΠΈΠ½Π° строки Π½Π΅ ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ°Π΅Ρ‚ 100 символов. -- Π’ однострочных ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°Ρ… ΠΈ массивах ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ±Π΅Π»Ρ‹ послС запятых. - -**Π₯ΠΎΡ€ΠΎΡˆΠΎ** -```ts -const roles = ['admin', 'editor', 'viewer']; -const options = { id: 1, name: 'User' }; - -const config = { - url: '/api/users', - method: 'GET', - params: { page: 1, pageSize: 20 }, -}; -``` - -**ΠŸΠ»ΠΎΡ…ΠΎ** -```ts -// ΠŸΠ»ΠΎΡ…ΠΎ: Π½Π΅Ρ‚ ΠΏΡ€ΠΎΠ±Π΅Π»ΠΎΠ² послС запятых ΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ слишком Π΄Π»ΠΈΠ½Π½Ρ‹ΠΉ для ΠΎΠ΄Π½ΠΎΠΉ строки. -const roles = ['admin','editor','viewer']; -const options = { id: 1,name: 'User' }; -const config = { url: '/api/users', method: 'GET', params: { page: 1, pageSize: 20 } }; -``` diff --git a/preview/ai/basics/documentation.md b/preview/ai/basics/documentation.md deleted file mode 100644 index 96ac8a5..0000000 --- a/preview/ai/basics/documentation.md +++ /dev/null @@ -1,136 +0,0 @@ ---- -title: Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ -scope: basics -keywords: [JSDoc, ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ, Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅, описаниС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, описаниС ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°] -when: "Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΠΎΠ΄Π°: JSDoc для Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ², Ρ‚ΠΈΠΏΠΎΠ²" ---- -# Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ - -Π­Ρ‚ΠΎΡ‚ Ρ€Π°Π·Π΄Π΅Π» описываСт ΠΏΡ€Π°Π²ΠΈΠ»Π° докумСнтирования ΠΊΠΎΠ΄Π°: ΠΊΠΎΠ³Π΄Π° ΠΈ ΠΊΠ°ΠΊ ΠΏΠΈΡΠ°Ρ‚ΡŒ -ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ ΠΊ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°ΠΌ, функциям, Ρ‚ΠΈΠΏΠ°ΠΌ ΠΈ интСрфСйсам. - -## ΠžΠ±Ρ‰ΠΈΠ΅ ΠΏΡ€Π°Π²ΠΈΠ»Π° - -- Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹, Ρ‚ΠΈΠΏΡ‹, интСрфСйсы ΠΈ enum. -- НС Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½ΠΎΠ΅ β€” Ссли Π½Π°Π·Π²Π°Π½ΠΈΠ΅ Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ само Π·Π° сСбя, ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ Π½Π΅ Π½ΡƒΠΆΠ΅Π½. -- НС Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ значСния ΠΈ Ρ‚ΠΈΠΏΡ‹ пропсов β€” ΠΎΠ½ΠΈ Π²ΠΈΠ΄Π½Ρ‹ ΠΈΠ· сигнатуры. -- ОписаниС Ρ‡Π΅Ρ€Π΅Π· ΠΏΠΎΠ»ΡŒΠ·Ρƒ ΠΈ Π½Π°Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π° Π½Π΅ Ρ‡Π΅Ρ€Π΅Π· Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΡŽΡŽ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ. -- ОписаниС Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ Ρ‚ΠΎΡ‡ΠΊΠΎΠΉ. - -## Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ - -Для докумСнтирования Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ шаблон. ОписаниС ΠΌΠ΅Ρ…Π°Π½ΠΈΠΊΠΈ ΠΎΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎ β€” -добавляСтся ΠΊΠΎΠ³Π΄Π° Π»ΠΎΠ³ΠΈΠΊΠ° Π½Π΅Ρ‚Ρ€ΠΈΠ²ΠΈΠ°Π»ΡŒΠ½Π°. - -**Π¨Π°Π±Π»ΠΎΠ½** -```ts -/** - * <Π§Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ функция Π² 1 строкС>. - * - * <ΠžΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎ: описаниС слоТной ΠΌΠ΅Ρ…Π°Π½ΠΈΠΊΠΈ ΠΈΠ»ΠΈ Π²Π°ΠΆΠ½Ρ‹Ρ… нюансов>. - */ -``` - -**Π₯ΠΎΡ€ΠΎΡˆΠΎ** -```ts -/** - * Π€ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ†Π΅Π½Ρƒ с символом Π²Π°Π»ΡŽΡ‚Ρ‹. - */ -export const formatPrice = (value: number): string => { ... } - -/** - * РСкурсивно собираСт Π΄Π΅Ρ€Π΅Π²ΠΎ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΉ ΠΈΠ· плоского списка. - * - * Π“Ρ€ΡƒΠΏΠΏΠΈΡ€ΡƒΠ΅Ρ‚ элСмСнты ΠΏΠΎ parentId, начиная с ΠΊΠΎΡ€Π½Π΅Π²Ρ‹Ρ… (parentId = null). - * ΠšΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ Π±Π΅Π· родитСля ΠΏΠΎΠΏΠ°Π΄Π°ΡŽΡ‚ Π² ΠΊΠΎΡ€Π΅Π½ΡŒ Π΄Π΅Ρ€Π΅Π²Π°. - */ -export const buildCategoryTree = (categories: Category[]): CategoryTree[] => { ... } -``` - -**ΠŸΠ»ΠΎΡ…ΠΎ** -```ts -// ΠŸΠ»ΠΎΡ…ΠΎ: Π΄ΡƒΠ±Π»ΠΈΡ€ΡƒΠ΅Ρ‚ сигнатуру. -/** - * @param value - число - * @returns строка с Ρ†Π΅Π½ΠΎΠΉ - */ -``` - -## ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ - -ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ описываСт своё **Π½Π°Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅** ΠΈ **сцСнарии примСнСния** β€” это ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ ΠΏΠΎΠ½ΡΡ‚ΡŒ, ΠΊΠΎΠ³Π΄Π° ΠΈ Π³Π΄Π΅ Π΅Π³ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ, Π±Π΅Π· нСобходимости Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ. - -**Π¨Π°Π±Π»ΠΎΠ½** -```ts -/** - * <НазначСниС ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° Π² 1 строкС>. - * - * Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для: - * - <сцСнарий 1> - * - <сцСнарий 2> - * - <сцСнарий 3> - */ -``` - -**Π₯ΠΎΡ€ΠΎΡˆΠΎ** -```tsx -/** - * ΠšΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ с Π°Π΄Π°ΠΏΡ‚ΠΈΠ²Π½ΠΎΠΉ максимальной ΡˆΠΈΡ€ΠΈΠ½ΠΎΠΉ. - * - * Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для: - * - ΠΎΠ±Ρ‘Ρ€Ρ‚ΠΊΠΈ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π° страниц с ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ΠΌ ΡˆΠΈΡ€ΠΈΠ½Ρ‹ - * - цСнтрирования Π±Π»ΠΎΠΊΠΎΠ² Π² Π»Π΅ΠΉΠ°ΡƒΡ‚Π΅ - */ -export const Container = (props: ContainerProps) => { ... } -``` - -**ΠŸΠ»ΠΎΡ…ΠΎ** -```tsx -// ΠŸΠ»ΠΎΡ…ΠΎ: описываСт Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ, Π° Π½Π΅ Π½Π°Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. -/** - * Π Π΅Π½Π΄Π΅Ρ€ΠΈΡ‚ div с className ΠΈ htmlAttr. - */ - -// ΠŸΠ»ΠΎΡ…ΠΎ: Π½Π΅Ρ‚ описания Π²ΠΎΠΎΠ±Ρ‰Π΅. -export const Container = (props: ContainerProps) => { ... } -``` - -## Π’ΠΈΠΏΡ‹, интСрфСйсы, enum - -Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ΡΡ Π½Π°Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ сущности ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ Π΅Ρ‘ ΠΏΠΎΠ»Π΅. - -**Π₯ΠΎΡ€ΠΎΡˆΠΎ** -```ts -/** - * Π€ΠΈΠ»ΡŒΡ‚Ρ€Ρ‹ списка Π·Π°Π΄Π°Ρ‡. - */ -export enum TodoFilter { - /** ВсС Π·Π°Π΄Π°Ρ‡ΠΈ. */ - ALL = 'all', - /** Волько Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹Π΅. */ - ACTIVE = 'active', - /** Волько Π·Π°Π²Π΅Ρ€ΡˆΡ‘Π½Π½Ρ‹Π΅. */ - COMPLETED = 'completed', -} - -/** - * Π—Π°Π΄Π°Ρ‡Π° ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ. - */ -export interface TodoItem { - /** Π£Π½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ Π·Π°Π΄Π°Ρ‡ΠΈ. */ - id: string; - /** ВСкст Π·Π°Π΄Π°Ρ‡ΠΈ. */ - text: string; - /** Бтатус выполнСния. */ - completed: boolean; -} -``` - -**ΠŸΠ»ΠΎΡ…ΠΎ** -```ts -// ΠŸΠ»ΠΎΡ…ΠΎ: описываСт ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½ΠΎΠ΅. -export interface TodoItem { - /** id β€” это id */ - id: string; -} -``` diff --git a/preview/ai/basics/naming.md b/preview/ai/basics/naming.md deleted file mode 100644 index 1519712..0000000 --- a/preview/ai/basics/naming.md +++ /dev/null @@ -1,149 +0,0 @@ ---- -title: ИмСнованиС -scope: basics -keywords: [camelCase, kebab-case, PascalCase, имя Ρ„Π°ΠΉΠ»Π°, имя ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ, имя ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°, имя Ρ…ΡƒΠΊΠ°] -when: "Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Ρ„Π°ΠΉΠ»ΠΎΠ², ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…, ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ², Ρ…ΡƒΠΊΠΎΠ² β€” Π²Ρ‹Π±ΠΎΡ€ ΠΈΠΌΠ΅Π½ΠΈ" ---- -# ИмСнованиС - -Π­Ρ‚ΠΎΡ‚ Ρ€Π°Π·Π΄Π΅Π» описываСт соглашСния ΠΎΠ± ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ΠΈΠΈ Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅. Π•Π΄ΠΈΠ½Ρ‹Π΅ ΠΏΡ€Π°Π²ΠΈΠ»Π° Π΄Π΅Π»Π°ΡŽΡ‚ ΠΊΠΎΠ΄ прСдсказуСмым ΠΈ ΡƒΠΏΡ€ΠΎΡ‰Π°ΡŽΡ‚ Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΡŽ ΠΏΠΎ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρƒ. - -## Π‘Π°Π·ΠΎΠ²Ρ‹Π΅ ΠΏΡ€Π°Π²ΠΈΠ»Π° - -| Π§Ρ‚ΠΎ | РСкомСндуСтся | -| ---------------- | ---------------------- | -| Папки | `kebab-case` | -| Π€Π°ΠΉΠ»Ρ‹ | `kebab-case` | -| ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ | `camelCase` | -| ΠšΠΎΠ½ΡΡ‚Π°Π½Ρ‚Ρ‹ | `SCREAMING_SNAKE_CASE` | -| ΠšΠ»Π°ΡΡΡ‹ | `PascalCase` | -| React-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ | `PascalCase` | -| Π₯ΡƒΠΊΠΈ | `useSomething` | -| CSS классы | `camelCase` | -| ΠšΠ»ΡŽΡ‡ΠΈ enum | `SCREAMING_SNAKE_CASE` | - - -## ИмСнованиС Ρ„Π°ΠΉΠ»ΠΎΠ² - -Буффикс ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ Ρ€ΠΎΠ»ΡŒ ΠΈΠ»ΠΈ Ρ‚ΠΈΠΏ Ρ„Π°ΠΉΠ»Π°. ΠŸΠΈΡˆΠ΅Ρ‚ΡΡ Π² СдинствСнном числС. -Π€ΠΎΡ€ΠΌΠ°Ρ‚: `name..ts`. - -**Π₯ΡƒΠΊΠΈ** -- `use-name.hook.ts` β€” Ρ„Π°ΠΉΠ» Ρ…ΡƒΠΊΠ°, функция имСнуСтся `useName` - -**ΠšΠΎΡ€Π½Π΅Π²Ρ‹Π΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ** -- `.business.tsx` β€” бизнСс-ΠΌΠΎΠ΄ΡƒΠ»ΡŒ (`business/`) -- `.infra.tsx` β€” инфраструктурный ΠΌΠΎΠ΄ΡƒΠ»ΡŒ (`infrastructure/`) -- `.ui.tsx` β€” UI-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ (`ui/`) -- `.screen.tsx` β€” экран (`screens/`) -- `.widget.tsx` β€” Π²ΠΈΠ΄ΠΆΠ΅Ρ‚ (`widgets/`) -- `.layout.tsx` β€” layout (`layouts/`) - -**Π›ΠΎΠ³ΠΈΠΊΠ°** -- `.store.ts` β€” стор -- `.service.ts` β€” сСрвис - -**Π’ΠΈΠΏΡ‹ ΠΈ ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Ρ‹** -- `.type.ts` β€” Ρ‚ΠΈΠΏΡ‹ ΠΈ интСрфСйсы -- `.interface.ts` β€” интСрфСйсы -- `.enum.ts` β€” enum -- `.dto.ts` β€” внСшниС DTO -- `.schema.ts` β€” схСмы Π²Π°Π»ΠΈΠ΄Π°Ρ†ΠΈΠΈ -- `.constant.ts` β€” константы -- `.config.ts` β€” конфигурация - -**Π£Ρ‚ΠΈΠ»ΠΈΡ‚Ρ‹** -- `.util.ts` β€” ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Ρ‹ -- `.helper.ts` β€” Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ -- `.lib.ts` β€” Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅Ρ‡Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ - -**ВСсты** -- `.test.ts` β€” тСсты -- `.mock.ts` β€” ΠΌΠΎΠΊΠΈ - -**Π₯ΠΎΡ€ΠΎΡˆΠΎ** -```text -business/ -└── auth-by-email/ - β”œβ”€β”€ ui/ - β”‚ └── login-form.tsx - β”œβ”€β”€ hooks/ - β”‚ └── use-auth.hook.ts - β”œβ”€β”€ stores/ - β”‚ └── auth.store.ts - β”œβ”€β”€ types/ - β”‚ └── auth.type.ts - β”œβ”€β”€ auth-by-email.business.tsx - └── index.ts -``` - -**ΠŸΠ»ΠΎΡ…ΠΎ** -```text -business/ -└── authByEmail/ - β”œβ”€β”€ LoginForm.tsx - β”œβ”€β”€ useAuth.ts - β”œβ”€β”€ authStore.ts - └── index.ts -``` - -## Π‘ΡƒΠ»Π΅Π²Ρ‹ значСния - -- Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ прСфиксы `is`, `has`, `can`, `should`. - -**Π₯ΠΎΡ€ΠΎΡˆΠΎ** -```ts -const isReady = true; -const hasAccess = false; -const canSubmit = true; -const shouldRedirect = false; -``` - -**ΠŸΠ»ΠΎΡ…ΠΎ** -```ts -// ΠŸΠ»ΠΎΡ…ΠΎ: нСясноС Π±ΡƒΠ»Π΅Π²ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π±Π΅Π· прСфикса. -const ready = true; -const access = false; -const submit = true; -``` - -## Бобытия ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ - -- ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ Π½Π°Ρ‡ΠΈΠ½Π°Ρ‚ΡŒ с `handle`. -- Бобытия ΠΈ колбэки Π½Π°Ρ‡ΠΈΠ½Π°Ρ‚ΡŒ с `on`. - -**Π₯ΠΎΡ€ΠΎΡˆΠΎ** -```ts -const handleSubmit = () => { ... }; -const onSubmit = () => { ... }; -``` - -**ΠŸΠ»ΠΎΡ…ΠΎ** -```ts -// ΠŸΠ»ΠΎΡ…ΠΎ: Π½Π΅ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½ΠΎΠ΅ Π½Π°Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈΠΌΠ΅Π½ΠΈ. -const submitClick = () => { ... }; -``` - -## ΠšΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΈ - -- Для массивов ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΠΌΠ΅Π½Π° Π²ΠΎ мноТСствСнном числС. -- Для словарСй/ΠΌΠ°ΠΏ β€” ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ суффиксы `ById`, `Map`, `Dict`. - -**Π₯ΠΎΡ€ΠΎΡˆΠΎ** -```ts -const users = []; -const usersById = {} as Record; -const userIds = ['u1', 'u2']; -const ordersMap = new Map(); -const featureFlagsDict = { beta: true, legacy: false } as Record; -``` - -**ΠŸΠ»ΠΎΡ…ΠΎ** -```ts -// ΠŸΠ»ΠΎΡ…ΠΎ: имя Π½Π΅ ΠΎΡ‚Ρ€Π°ΠΆΠ°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ это коллСкция. -const user = []; -// ΠŸΠ»ΠΎΡ…ΠΎ: ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ Π½Π°Π·Π²Π°Π½ ΠΊΠ°ΠΊ массив. -const usersMap = []; -// ΠŸΠ»ΠΎΡ…ΠΎ: ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ нСпонятно, Ρ‡Ρ‚ΠΎ это ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ. -const users = {} as Record; -``` diff --git a/preview/ai/basics/tech-stack.md b/preview/ai/basics/tech-stack.md deleted file mode 100644 index 14773db..0000000 --- a/preview/ai/basics/tech-stack.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: Π’Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ -scope: basics -keywords: [стСк, React, TypeScript, Next.js, Mantine, Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°, Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ] -when: "Π’Ρ‹Π±ΠΎΡ€ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ ΠΈΠ»ΠΈ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° допустимости зависимости" ---- -# Π’Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ - -Π­Ρ‚ΠΎΡ‚ Ρ€Π°Π·Π΄Π΅Π» описываСт Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ стСк Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΉ ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ, принятый Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅. - -## Π§Ρ‚ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ - -### Π‘Ρ‚Π΅ΠΊ -- `React` / `TypeScript` β€” основной стСк для UI ΠΈ прилоТСния. -- `Next.js` β€” для ΠΏΡ€ΠΎΠ΄ΡƒΠΊΡ‚ΠΎΠ²Ρ‹Ρ… сайтов. - -### АрхитСктура -- `SLM Design (Scoped Layered Module Design)` β€” ΠΌΠΎΠ΄ΡƒΠ»ΡŒΠ½Π°Ρ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°: слои, ΠΌΠΎΠ΄ΡƒΠ»ΠΈ, Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ зависимостСй. ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ [АрхитСктура](/basics/architecture). - -### UI ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ -- `Mantine UI` β€” Π±Π°Π·ΠΎΠ²Ρ‹Π΅ UI-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹. - -### Π Π°Π±ΠΎΡ‚Π° с Π΄Π°Π½Π½Ρ‹ΠΌΠΈ (API) -- `@gromlab/api-codegen` β€” гСнСрация API‑клиСнтов ΠΈ Ρ‚ΠΈΠΏΠΎΠ². -- `SWR` β€” ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅, ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅, рСвалидация, дСдубликация. -- `SWR (useSWRSubscription)` β€” сокСты, Ρ€Π΅Π°Π»Ρ‚Π°ΠΉΠΌ подписки. - -### Store -- `Zustand` β€” глобальноС состояниС. - -### Локализация -- `i18next (i18n)` β€” локализация всСх ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΡ… тСкстов. - -### ВСстированиС -- `Vitest` β€” тСстированиС. - -### Π‘Ρ‚ΠΈΠ»ΠΈ -- `PostCSS Modules` β€” изоляция стилСй. -- `Mobile First` β€” ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ ΠΊ Π°Π΄Π°ΠΏΡ‚ΠΈΠ²Π½ΠΎΠΉ вСрсткС. -- `clsx` β€” конкатСнация CSS‑классов. - -### ГСнСрация -- `@gromlab/create` β€” ΡˆΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°Ρ‚ΠΎΡ€ для создания слоёв ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΡ… Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΈΠ· шаблонов. diff --git a/preview/ai/basics/typing.md b/preview/ai/basics/typing.md deleted file mode 100644 index 297c8e3..0000000 --- a/preview/ai/basics/typing.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: Випизация -scope: basics -keywords: [type, interface, generic, any, unknown, enum, типизация, пропсы] -when: "Випизация ΠΊΠΎΠ΄Π°: Π²Ρ‹Π±ΠΎΡ€ type vs interface, Ρ€Π°Π±ΠΎΡ‚Π° с generic, Π·Π°ΠΏΡ€Π΅Ρ‚ any" ---- -# Випизация - -Π­Ρ‚ΠΎΡ‚ Ρ€Π°Π·Π΄Π΅Π» описываСт ΠΏΡ€Π°Π²ΠΈΠ»Π° Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΠΈ: ΠΊΠ°ΠΊ Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹, Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈ Ρ€Π°Π±ΠΎΡ‚Ρƒ с `any`/`unknown`. - -## ΠžΠ±Ρ‰ΠΈΠ΅ ΠΏΡ€Π°Π²ΠΈΠ»Π° - -- Π£ΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ Ρ‚ΠΈΠΏΡ‹ для ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ², Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Ρ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ. -- ΠŸΡ€Π΅Π΄ΠΏΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ `type` для описания сущностСй ΠΈ `interface` для Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅ΠΌΡ‹Ρ… ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚ΠΎΠ². -- Π˜Π·Π±Π΅Π³Π°Ρ‚ΡŒ `any` ΠΈ `unknown` Π±Π΅Π· нСобходимости. -- НС ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ `ts-ignore`, ΠΊΡ€ΠΎΠΌΠ΅ ΠΊΡ€Π°ΠΉΠ½ΠΈΡ… случаСв с явным ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠ΅ΠΌ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρ‹. - -## Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ - -- Для ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹ΠΉ Ρ‚ΠΈΠΏ. -- НС ΠΏΠΎΠ»Π°Π³Π°Ρ‚ΡŒΡΡ Π½Π° нСявный Π²Ρ‹Π²ΠΎΠ΄ для Π²Π°ΠΆΠ½Ρ‹Ρ… API. - -**Π₯ΠΎΡ€ΠΎΡˆΠΎ** -```ts -export const formatPrice = (value: number): string => { - return `${value} β‚½`; -}; -``` - -**ΠŸΠ»ΠΎΡ…ΠΎ** -```ts -// ΠŸΠ»ΠΎΡ…ΠΎ: Π½Π΅Ρ‚ явного Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°. -export const formatPrice = (value: number) => { - return `${value} β‚½`; -}; -``` - -## Π Π°Π±ΠΎΡ‚Π° с any/unknown - -- `any` ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… Π·Π°Π³Π»ΡƒΡˆΠ΅ΠΊ. -- `unknown` ΡΡƒΠΆΠ°Ρ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΠΏΠ΅Ρ€Π΅Π΄ использованиСм. - -**Π₯ΠΎΡ€ΠΎΡˆΠΎ** -```ts -const parse = (value: unknown): string => { - if (typeof value === 'string') { - return value; - } - - return ''; -}; -``` - -**ΠŸΠ»ΠΎΡ…ΠΎ** -```ts -// ΠŸΠ»ΠΎΡ…ΠΎ: any ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ Ρ‚ΠΈΠΏΠΎΠ². -const parse = (value: any) => value; -``` diff --git a/preview/ai/triggers/develop/add-api-request.md b/preview/ai/triggers/develop/add-api-request.md deleted file mode 100644 index ab91dbd..0000000 --- a/preview/ai/triggers/develop/add-api-request.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ API-запрос ---- - -# Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ API-запрос - -Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ ΠΏΠΎ добавлСнию запроса ΠΊ сСрвСру: созданиС ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, Ρ…ΡƒΠΊΠ°, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΎΡ‚Π²Π΅Ρ‚Π°. - -## ΠŸΡ€ΠΎΡ‡ΠΈΡ‚Π°ΠΉ ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ - -- applied/api.md β€” ΠΏΡ€Π°Π²ΠΈΠ»Π° API-слоя: ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρ‹, эндпоинты, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ошибок -- basics/typing.md β€” типизация запросов ΠΈ ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠ² - -## Π¨Π°Π³ΠΈ - -1. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄: - - ΠšΠ»ΠΈΠ΅Π½Ρ‚ΡΠΊΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Π΅ β†’ SWR / Ρ…ΡƒΠΊ - - Π‘Π΅Ρ€Π²Π΅Ρ€Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ β†’ сСрвСрный ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ (RSC) - -2. Опиши Ρ‚ΠΈΠΏΡ‹ запроса ΠΈ ΠΎΡ‚Π²Π΅Ρ‚Π°. - -3. Π‘ΠΎΠ·Π΄Π°ΠΉ ΠΈΠ»ΠΈ Ρ€Π°ΡΡˆΠΈΡ€ΡŒ API-ΠΊΠ»ΠΈΠ΅Π½Ρ‚ (β†’ applied/api.md). - -4. Π‘ΠΎΠ·Π΄Π°ΠΉ Ρ…ΡƒΠΊ для использования Π² ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π΅ (β†’ triggers/develop/create-hook.md). - -## Π‘ΠΌΠ΅ΠΆΠ½Ρ‹Π΅ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ - -- triggers/develop/create-hook.md β€” Ρ…ΡƒΠΊ для запроса -- triggers/develop/create-component.md β€” ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠΉ Π΄Π°Π½Π½Ρ‹Π΅ - -## ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒ сСбя - -- [ ] Π’ΠΈΠΏΡ‹ запроса ΠΈ ΠΎΡ‚Π²Π΅Ρ‚Π° описаны -- [ ] Π₯ΡƒΠΊ для использования Π² ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π΅ создан -- [ ] ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ошибок Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π° diff --git a/preview/ai/triggers/develop/add-dependency.md b/preview/ai/triggers/develop/add-dependency.md deleted file mode 100644 index ed7a7a1..0000000 --- a/preview/ai/triggers/develop/add-dependency.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ ---- - -# Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ - -Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ ΠΏΠΎ добавлСнию Π½ΠΎΠ²ΠΎΠΉ npm-зависимости Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒ Π΄ΠΎΠΏΡƒΡΡ‚ΠΈΠΌΠΎΡΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π΄ установкой. - -## ΠŸΡ€ΠΎΡ‡ΠΈΡ‚Π°ΠΉ ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ - -- basics/tech-stack.md β€” Ρ€Π°Π·Ρ€Π΅ΡˆΡ‘Π½Π½Ρ‹ΠΉ стСк, допустимыС Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ - -## Π¨Π°Π³ΠΈ - -1. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒ, Ρ‡Ρ‚ΠΎ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Π½Π΅ Π΄ΡƒΠ±Π»ΠΈΡ€ΡƒΠ΅Ρ‚ ΡƒΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡƒΡŽ (β†’ basics/tech-stack.md). - -2. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒ, Ρ‡Ρ‚ΠΎ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Π²Ρ…ΠΎΠ΄ΠΈΡ‚ Π² Ρ€Π°Π·Ρ€Π΅ΡˆΡ‘Π½Π½Ρ‹ΠΉ список ΠΈΠ»ΠΈ обоснуй Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ. - -3. Установи ΠΊΠ°ΠΊ `dependency` ΠΈΠ»ΠΈ `devDependency` Π² зависимости ΠΎΡ‚ назначСния. - -## ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒ сСбя - -- [ ] Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Π½Π΅ Π΄ΡƒΠ±Π»ΠΈΡ€ΡƒΠ΅Ρ‚ ΡƒΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡƒΡŽ -- [ ] Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Π²Ρ…ΠΎΠ΄ΠΈΡ‚ Π² Ρ€Π°Π·Ρ€Π΅ΡˆΡ‘Π½Π½Ρ‹ΠΉ список (β†’ basics/tech-stack.md) diff --git a/preview/ai/triggers/develop/add-font.md b/preview/ai/triggers/develop/add-font.md deleted file mode 100644 index abe29e6..0000000 --- a/preview/ai/triggers/develop/add-font.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ΡˆΡ€ΠΈΡ„Ρ‚ ---- - -# ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ΡˆΡ€ΠΈΡ„Ρ‚ - -Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ ΠΏΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡŽ ΠΈ настройкС ΡˆΡ€ΠΈΡ„Ρ‚Π° Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅. - -## ΠŸΡ€ΠΎΡ‡ΠΈΡ‚Π°ΠΉ ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ - -- applied/fonts.md β€” ΠΏΡ€Π°Π²ΠΈΠ»Π° ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΡˆΡ€ΠΈΡ„Ρ‚ΠΎΠ²: Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Ρ‹, Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ°, CSS-ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ - -## Π¨Π°Π³ΠΈ - -1. ΠŸΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΡŒ Ρ„Π°ΠΉΠ»Ρ‹ ΡˆΡ€ΠΈΡ„Ρ‚Π° (woff2). - -2. ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈ ΡˆΡ€ΠΈΡ„Ρ‚ ΠΏΠΎ ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌ (β†’ applied/fonts.md). - -3. ЗарСгистрируй CSS-ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ для ΡˆΡ€ΠΈΡ„Ρ‚Π°. - -## Π‘ΠΌΠ΅ΠΆΠ½Ρ‹Π΅ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ - -- triggers/develop/style-component.md β€” использованиС ΡˆΡ€ΠΈΡ„Ρ‚Π° Π² стилях - -## ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒ сСбя - -- [ ] Π€Π°ΠΉΠ» ΡˆΡ€ΠΈΡ„Ρ‚Π° Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ woff2 -- [ ] CSS-пСрСмСнная для ΡˆΡ€ΠΈΡ„Ρ‚Π° зарСгистрирована diff --git a/preview/ai/triggers/develop/add-icon.md b/preview/ai/triggers/develop/add-icon.md deleted file mode 100644 index f5dab10..0000000 --- a/preview/ai/triggers/develop/add-icon.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΈΠΊΠΎΠ½ΠΊΡƒ ---- - -# Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΈΠΊΠΎΠ½ΠΊΡƒ - -Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ ΠΏΠΎ добавлСнию SVG-ΠΈΠΊΠΎΠ½ΠΊΠΈ Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ Ρ‡Π΅Ρ€Π΅Π· спрайт-систСму. - -## ΠŸΡ€ΠΎΡ‡ΠΈΡ‚Π°ΠΉ ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ - -- applied/svg-sprites.md β€” ΠΏΡ€Π°Π²ΠΈΠ»Π° SVG-спрайтов: структура, ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ΠΈΠ΅, использованиС - -## Π¨Π°Π³ΠΈ - -1. ΠŸΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΡŒ SVG-Ρ„Π°ΠΉΠ»: ΡƒΠ±Π΅Ρ€ΠΈ лишниС Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹, ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΡƒΠΉ. - -2. Π”ΠΎΠ±Π°Π²ΡŒ SVG Π² спрайт ΠΏΠΎ ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌ (β†’ applied/svg-sprites.md). - -3. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ ΠΈΠΊΠΎΠ½ΠΊΡƒ Π² ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π΅ Ρ‡Π΅Ρ€Π΅Π· ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚-ΠΎΠ±Ρ‘Ρ€Ρ‚ΠΊΡƒ. - -## Π‘ΠΌΠ΅ΠΆΠ½Ρ‹Π΅ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ - -- triggers/develop/create-component.md β€” Ссли Π½ΡƒΠΆΠ΅Π½ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚-ΠΎΠ±Ρ‘Ρ€Ρ‚ΠΊΠ° для ΠΈΠΊΠΎΠ½ΠΊΠΈ -- triggers/develop/style-component.md β€” стилизация ΠΈΠΊΠΎΠ½ΠΊΠΈ (Ρ€Π°Π·ΠΌΠ΅Ρ€, Ρ†Π²Π΅Ρ‚) - -## ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒ сСбя - -- [ ] SVG ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½ β€” ΡƒΠ±Ρ€Π°Π½Ρ‹ лишниС Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ -- [ ] Иконка Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π° Π² спрайт ΠΏΠΎ ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌ (β†’ applied/svg-sprites.md) diff --git a/preview/ai/triggers/develop/add-image.md b/preview/ai/triggers/develop/add-image.md deleted file mode 100644 index cdefdc3..0000000 --- a/preview/ai/triggers/develop/add-image.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ---- - -# Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ - -Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ ΠΏΠΎ добавлСнию ΠΈ использованию растровых ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅. - -## ΠŸΡ€ΠΎΡ‡ΠΈΡ‚Π°ΠΉ ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ - -- applied/images-sprites.md β€” ΠΏΡ€Π°Π²ΠΈΠ»Π° Ρ€Π°Π±ΠΎΡ‚Ρ‹ с изобраТСниями: оптимизация, Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Ρ‹, ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ - -## Π¨Π°Π³ΠΈ - -1. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈ Ρ‚ΠΈΠΏ изобраТСния: - - БтатичСскоС (Π»ΠΎΠ³ΠΎΡ‚ΠΈΠΏ, Π΄Π΅ΠΊΠΎΡ€) β†’ `public/` - - ДинамичСскоС (ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π½ΠΎΠ΅) β†’ URL ΠΈΠ· API - -2. ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΡƒΠΉ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ (Ρ„ΠΎΡ€ΠΌΠ°Ρ‚, Ρ€Π°Π·ΠΌΠ΅Ρ€, сТатиС). - -3. ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈ Π² ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π΅ ΠΏΠΎ ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌ (β†’ applied/images-sprites.md). - -## Π‘ΠΌΠ΅ΠΆΠ½Ρ‹Π΅ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ - -- triggers/develop/create-component.md β€” Ссли Π½ΡƒΠΆΠ΅Π½ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚-ΠΎΠ±Ρ‘Ρ€Ρ‚ΠΊΠ° для изобраТСния - -## ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒ сСбя - -- [ ] Π˜Π·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½ΠΎ (Ρ„ΠΎΡ€ΠΌΠ°Ρ‚, Ρ€Π°Π·ΠΌΠ΅Ρ€, сТатиС) -- [ ] ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ ΠΏΠΎ ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌ (β†’ applied/images-sprites.md) diff --git a/preview/ai/triggers/develop/add-localization.md b/preview/ai/triggers/develop/add-localization.md deleted file mode 100644 index 330641f..0000000 --- a/preview/ai/triggers/develop/add-localization.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ ---- - -# Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ - -Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ ΠΏΠΎ добавлСнию Π»ΠΎΠΊΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ: созданиС ΠΊΠ»ΡŽΡ‡Π΅ΠΉ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π° ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π² ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π΅. - -## ΠŸΡ€ΠΎΡ‡ΠΈΡ‚Π°ΠΉ ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ - -- applied/localization.md β€” ΠΏΡ€Π°Π²ΠΈΠ»Π° Π»ΠΎΠΊΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ: namespace, ΠΊΠ»ΡŽΡ‡ΠΈ, Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ - -## Π¨Π°Π³ΠΈ - -1. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈ namespace для ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΎΠ² (β†’ applied/localization.md). - -2. Π”ΠΎΠ±Π°Π²ΡŒ ΠΊΠ»ΡŽΡ‡ΠΈ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π° Π² Ρ„Π°ΠΉΠ»Ρ‹ Π»ΠΎΠΊΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ. - -3. ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Ρ‹ Π² ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π΅ (β†’ applied/localization.md). - -## Π‘ΠΌΠ΅ΠΆΠ½Ρ‹Π΅ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ - -- triggers/develop/create-component.md β€” Ссли ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Π΅Ρ‰Ρ‘ Π½Π΅ создан - -## ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒ сСбя - -- [ ] ΠšΠ»ΡŽΡ‡ΠΈ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π° Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ Π² Ρ„Π°ΠΉΠ»Ρ‹ Π»ΠΎΠΊΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ -- [ ] Namespace ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½ (β†’ applied/localization.md) diff --git a/preview/ai/triggers/develop/add-server-data.md b/preview/ai/triggers/develop/add-server-data.md deleted file mode 100644 index 0857e39..0000000 --- a/preview/ai/triggers/develop/add-server-data.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ сСрвСрныС Π΄Π°Π½Π½Ρ‹Π΅ ---- - -# Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ сСрвСрныС Π΄Π°Π½Π½Ρ‹Π΅ - -Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ ΠΏΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΡŽ Π΄Π°Π½Π½Ρ‹Ρ… Π² сСрвСрных ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°Ρ… (RSC) Next.js. - -## ΠŸΡ€ΠΎΡ‡ΠΈΡ‚Π°ΠΉ ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ - -- applied/page-level.md β€” сСрвСрныС ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ Π² App Router -- applied/api.md β€” API-ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρ‹ - -## Π¨Π°Π³ΠΈ - -1. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈ Π³Π΄Π΅ ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅: - - Π’ `page.tsx` / `layout.tsx` β†’ сСрвСрный fetch - - Π’ клиСнтском ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π΅ β†’ SWR (β†’ triggers/develop/add-api-request.md) - -2. Π‘ΠΎΠ·Π΄Π°ΠΉ ΠΈΠ»ΠΈ Ρ€Π°ΡΡˆΠΈΡ€ΡŒ сСрвСрный API-ΠΊΠ»ΠΈΠ΅Π½Ρ‚. - -3. ΠŸΠΎΠ»ΡƒΡ‡ΠΈ Π΄Π°Π½Π½Ρ‹Π΅ Π² сСрвСрном ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π΅ ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°ΠΉ Ρ‡Π΅Ρ€Π΅Π· пропсы. - -## Π‘ΠΌΠ΅ΠΆΠ½Ρ‹Π΅ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ - -- triggers/develop/add-api-request.md β€” клиСнтскиС запросы (SWR) -- triggers/develop/create-page.md β€” сСрвСрный fetch Π² page.tsx - -## ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒ сСбя - -- [ ] ΠžΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½ Ρ‚ΠΈΠΏ: сСрвСрный fetch ΠΈΠ»ΠΈ клиСнтский SWR -- [ ] Π’ΠΈΠΏΡ‹ запроса ΠΈ ΠΎΡ‚Π²Π΅Ρ‚Π° описаны -- [ ] Π”Π°Π½Π½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ Ρ‡Π΅Ρ€Π΅Π· пропсы, Π½Π΅ Ρ‡Π΅Ρ€Π΅Π· глобальноС состояниС diff --git a/preview/ai/triggers/develop/add-video.md b/preview/ai/triggers/develop/add-video.md deleted file mode 100644 index a319276..0000000 --- a/preview/ai/triggers/develop/add-video.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π²ΠΈΠ΄Π΅ΠΎ ---- - -# Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π²ΠΈΠ΄Π΅ΠΎ - -Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ ΠΏΠΎ Π²ΡΡ‚Ρ€Π°ΠΈΠ²Π°Π½ΠΈΡŽ Π²ΠΈΠ΄Π΅ΠΎ Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚. - -## ΠŸΡ€ΠΎΡ‡ΠΈΡ‚Π°ΠΉ ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ - -- applied/video.md β€” ΠΏΡ€Π°Π²ΠΈΠ»Π° Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Π²ΠΈΠ΄Π΅ΠΎ: Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Ρ‹, ΠΏΠ»Π΅Π΅Ρ€, оптимизация - -## Π¨Π°Π³ΠΈ - -1. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈ Ρ‚ΠΈΠΏ Π²ΠΈΠ΄Π΅ΠΎ: - - Π›ΠΎΠΊΠ°Π»ΡŒΠ½ΠΎΠ΅ β†’ `public/` - - Π’Π½Π΅ΡˆΠ½Π΅Π΅ (YouTube, Vimeo) β†’ embed - -2. ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈ Π²ΠΈΠ΄Π΅ΠΎ ΠΏΠΎ ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌ (β†’ applied/video.md). - -## Π‘ΠΌΠ΅ΠΆΠ½Ρ‹Π΅ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ - -- triggers/develop/create-component.md β€” Ссли Π½ΡƒΠΆΠ΅Π½ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚-ΠΎΠ±Ρ‘Ρ€Ρ‚ΠΊΠ° для Π²ΠΈΠ΄Π΅ΠΎ - -## ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒ сСбя - -- [ ] Π’ΠΈΠ΄Π΅ΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ ΠΏΠΎ ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌ (β†’ applied/video.md) diff --git a/preview/ai/triggers/develop/connect-store.md b/preview/ai/triggers/develop/connect-store.md deleted file mode 100644 index 0457ef0..0000000 --- a/preview/ai/triggers/develop/connect-store.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ стор ΠΊ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρƒ ---- - -# ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ стор ΠΊ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρƒ - -Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ ΠΏΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡŽ стора ΠΊ React-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρƒ. - -## ΠŸΡ€ΠΎΡ‡ΠΈΡ‚Π°ΠΉ ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ - -- applied/stores.md β€” ΠΏΡ€Π°Π²ΠΈΠ»Π° сторов: подписка, сСлСкторы - -## Π¨Π°Π³ΠΈ - -1. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈ Π½ΡƒΠΆΠ΅Π½ Π»ΠΈ стор: - - Π›ΠΎΠΊΠ°Π»ΡŒΠ½ΠΎΠ΅ состояниС β†’ `useState` / `useReducer` - - Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½ΠΎΠ΅ состояниС β†’ стор - -2. Если стор Π½Π΅ сущСствуСт β€” создай Π΅Π³ΠΎ (β†’ triggers/develop/create-store.md). - -3. ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈ стор Π² ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π΅ Ρ‡Π΅Ρ€Π΅Π· сСлСктор (β†’ applied/stores.md). - -## Π‘ΠΌΠ΅ΠΆΠ½Ρ‹Π΅ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ - -- triggers/develop/create-store.md β€” созданиС Π½ΠΎΠ²ΠΎΠ³ΠΎ стора -- triggers/develop/create-hook.md β€” Ρ…ΡƒΠΊ-ΠΎΠ±Ρ‘Ρ€Ρ‚ΠΊΠ° Π½Π°Π΄ стором - -## ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒ сСбя - -- [ ] Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ сСлСктор, Π° Π½Π΅ подписка Π½Π° вСсь стор -- [ ] Π’Ρ‹Π±ΠΎΡ€ локальноС/глобальноС состояниС обоснован diff --git a/preview/ai/triggers/develop/create-component.md b/preview/ai/triggers/develop/create-component.md deleted file mode 100644 index 013ce3f..0000000 --- a/preview/ai/triggers/develop/create-component.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ---- - -# Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ - -Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ ΠΏΠΎ созданию React-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈ слой, сгСнСрируй ΠΈΠ· шаблона, Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠΉ ΠΏΠΎ ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌ. - -## ΠŸΡ€ΠΎΡ‡ΠΈΡ‚Π°ΠΉ ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ - -- applied/components.md β€” ΠΏΡ€Π°Π²ΠΈΠ»Π° ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ²: структура Ρ„Π°ΠΉΠ»ΠΎΠ², пропсы, Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ -- basics/naming.md β€” ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ΠΈΠ΅ Ρ„Π°ΠΉΠ»Π° ΠΈ экспортов - -## Π¨Π°Π³ΠΈ - -1. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈ слой ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° ΠΏΠΎ Π΅Π³ΠΎ Π½Π°Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ (β†’ basics/architecture.md): - - `ui/` β€” ΠΏΠ΅Ρ€Π΅ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ UI Π±Π΅Π· бизнСс-Π»ΠΎΠ³ΠΈΠΊΠΈ - - `business/` β€” бизнСс-Π΄ΠΎΠΌΠ΅Π½ с Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ ΠΈ UI - - `widgets/` β€” составной Π±Π»ΠΎΠΊ, Π½Π΅ привязанный ΠΊ Π΄ΠΎΠΌΠ΅Π½Ρƒ - - `screens/{name}/parts/` β€” Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ Π±Π»ΠΎΠΊ ΠΎΠ΄Π½ΠΎΠΉ страницы - -2. Π‘Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠΉ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ ΠΈΠ· шаблона (β†’ triggers/develop/generate-module.md). - -3. Π Π΅Π°Π»ΠΈΠ·ΡƒΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΏΠΎ ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌ (β†’ applied/components.md). - -4. Если Π½ΡƒΠΆΠ½Ρ‹ стили β€” см. triggers/develop/style-component.md. - -## Π‘ΠΌΠ΅ΠΆΠ½Ρ‹Π΅ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ - -- triggers/develop/style-component.md β€” стилизация ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° -- triggers/develop/add-icon.md β€” Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ Π² ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ -- triggers/develop/generate-module.md β€” гСнСрация ΠΈΠ· шаблона - -## ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒ сСбя - -- [ ] ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ создан ΠΈΠ· шаблона, Π½Π΅ Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ -- [ ] Π€Π°ΠΉΠ» ΠΈ экспорт ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Ρ‹ ΠΏΠΎ ΠΊΠΎΠ½Π²Π΅Π½Ρ†ΠΈΠΈ (β†’ basics/naming.md) -- [ ] ΠŸΡ€ΠΎΠΏΡΡ‹ Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ (β†’ basics/typing.md) diff --git a/preview/ai/triggers/develop/create-entity.md b/preview/ai/triggers/develop/create-entity.md deleted file mode 100644 index 36e5245..0000000 --- a/preview/ai/triggers/develop/create-entity.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ ΡΡƒΡ‰Π½ΠΎΡΡ‚ΡŒ ---- - -# Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ ΡΡƒΡ‰Π½ΠΎΡΡ‚ΡŒ - -Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ ΠΏΠΎ созданию бизнСс-модуля Π½Π° слоС `business/`. Π‘ΡƒΡ‰Π½ΠΎΡΡ‚ΡŒ β€” бизнСс-Π΄ΠΎΠΌΠ΅Π½ с UI-прСдставлСниСм ΠΈ модСлью Π΄Π°Π½Π½Ρ‹Ρ…. - -## ΠŸΡ€ΠΎΡ‡ΠΈΡ‚Π°ΠΉ ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ - -- basics/architecture.md β€” слои ΠΈ зависимости -- applied/components.md β€” ΠΏΡ€Π°Π²ΠΈΠ»Π° ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² - -## Π¨Π°Π³ΠΈ - -1. Π‘Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠΉ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ ΠΈΠ· шаблона `business` (β†’ triggers/develop/generate-module.md). - -2. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈ модСль Π΄Π°Π½Π½Ρ‹Ρ… β€” Ρ‚ΠΈΠΏΡ‹ Π² `types/`. - -3. Π Π΅Π°Π»ΠΈΠ·ΡƒΠΉ UI-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ сущности. - -4. Настрой ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ API β€” экспорт Ρ‡Π΅Ρ€Π΅Π· `index.ts`. - -## Π‘ΠΌΠ΅ΠΆΠ½Ρ‹Π΅ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ - -- triggers/develop/create-component.md β€” UI-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ сущности -- triggers/develop/create-store.md β€” стор для сущности -- triggers/develop/generate-module.md β€” гСнСрация ΠΈΠ· шаблона - -## ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒ сСбя - -- [ ] ΠœΠΎΠ΄ΡƒΠ»ΡŒ создан ΠΈΠ· шаблона `business` -- [ ] МодСль Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π° β€” Ρ‚ΠΈΠΏΡ‹ Π² `types/` -- [ ] ΠŸΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ API настроСн β€” экспорт Ρ‡Π΅Ρ€Π΅Π· `index.ts` diff --git a/preview/ai/triggers/develop/create-feature.md b/preview/ai/triggers/develop/create-feature.md deleted file mode 100644 index a8bdf7a..0000000 --- a/preview/ai/triggers/develop/create-feature.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ Ρ„ΠΈΡ‡Ρƒ ---- - -# Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ Ρ„ΠΈΡ‡Ρƒ - -Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ ΠΏΠΎ созданию бизнСс-модуля Π½Π° слоС `business/`. Π€ΠΈΡ‡Π° β€” самодостаточный Π±Π»ΠΎΠΊ с бизнСс-Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ ΠΈ UI. - -## ΠŸΡ€ΠΎΡ‡ΠΈΡ‚Π°ΠΉ ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ - -- basics/architecture.md β€” слои ΠΈ зависимости -- applied/components.md β€” ΠΏΡ€Π°Π²ΠΈΠ»Π° ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² - -## Π¨Π°Π³ΠΈ - -1. Π‘Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠΉ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ ΠΈΠ· шаблона `business` (β†’ triggers/develop/generate-module.md). - -2. Π Π΅Π°Π»ΠΈΠ·ΡƒΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Ρ„ΠΈΡ‡ΠΈ (β†’ applied/components.md). - -3. Если Π½ΡƒΠΆΠ΅Π½ стор β€” создай Π² `stores/` (β†’ triggers/develop/create-store.md). - -4. Если Π½ΡƒΠΆΠ½Ρ‹ Ρ…ΡƒΠΊΠΈ β€” создай Π² `hooks/` (β†’ triggers/develop/create-hook.md). - -5. Настрой ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ API β€” экспорт Ρ‡Π΅Ρ€Π΅Π· `index.ts`. - -## Π‘ΠΌΠ΅ΠΆΠ½Ρ‹Π΅ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ - -- triggers/develop/create-component.md β€” ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Π²Π½ΡƒΡ‚Ρ€ΠΈ Ρ„ΠΈΡ‡ΠΈ -- triggers/develop/create-store.md β€” стор для Ρ„ΠΈΡ‡ΠΈ -- triggers/develop/create-hook.md β€” Ρ…ΡƒΠΊ для Ρ„ΠΈΡ‡ΠΈ -- triggers/develop/generate-module.md β€” гСнСрация ΠΈΠ· шаблона - -## ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒ сСбя - -- [ ] ΠœΠΎΠ΄ΡƒΠ»ΡŒ создан ΠΈΠ· шаблона `business` -- [ ] ΠŸΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ API настроСн β€” экспорт Ρ‡Π΅Ρ€Π΅Π· `index.ts` -- [ ] Cross-domain зависимости Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Ρ‹ Ρ‡Π΅Ρ€Π΅Π· Ρ„Π°Π±Ρ€ΠΈΠΊΡƒ (β†’ basics/architecture.md) diff --git a/preview/ai/triggers/develop/create-hook.md b/preview/ai/triggers/develop/create-hook.md deleted file mode 100644 index 37e0ec2..0000000 --- a/preview/ai/triggers/develop/create-hook.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ Ρ…ΡƒΠΊ ---- - -# Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ Ρ…ΡƒΠΊ - -Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ ΠΏΠΎ созданию кастомного React-Ρ…ΡƒΠΊΠ°. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈ Π³Π΄Π΅ ΠΎΠ½ ΠΆΠΈΠ²Ρ‘Ρ‚, Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠΉ ΠΏΠΎ ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌ. - -## ΠŸΡ€ΠΎΡ‡ΠΈΡ‚Π°ΠΉ ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ - -- applied/hooks.md β€” ΠΏΡ€Π°Π²ΠΈΠ»Π° Ρ…ΡƒΠΊΠΎΠ² -- basics/naming.md β€” ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ΠΈΠ΅ (прСфикс `use`) -- basics/typing.md β€” типизация ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π° - -## Π¨Π°Π³ΠΈ - -1. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈ ΠΎΠ±Π»Π°ΡΡ‚ΡŒ Ρ…ΡƒΠΊΠ°: - - Π£Ρ‚ΠΈΠ»ΠΈΡ‚Π°Ρ€Π½Ρ‹ΠΉ (Π½Π΅ привязан ΠΊ бизнСс-Π»ΠΎΠ³ΠΈΠΊΠ΅) β†’ `shared/hooks/` - - ΠŸΡ€ΠΈΠ²ΡΠ·Π°Π½ ΠΊ Ρ„ΠΈΡ‡Π΅/сущности β†’ `model/` Π²Π½ΡƒΡ‚Ρ€ΠΈ модуля - -2. Π‘ΠΎΠ·Π΄Π°ΠΉ Ρ„Π°ΠΉΠ» с ΠΈΠΌΠ΅Π½Π΅ΠΌ `use-{name}.ts`. - -3. Π Π΅Π°Π»ΠΈΠ·ΡƒΠΉ Ρ…ΡƒΠΊ ΠΏΠΎ ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌ (β†’ applied/hooks.md). - -4. Экспортируй Ρ‡Π΅Ρ€Π΅Π· ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ API модуля. - -## Π‘ΠΌΠ΅ΠΆΠ½Ρ‹Π΅ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ - -- triggers/develop/create-component.md β€” Ссли Ρ…ΡƒΠΊ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π² Π½ΠΎΠ²ΠΎΠΌ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π΅ -- triggers/develop/connect-store.md β€” Ссли Ρ…ΡƒΠΊ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ стор - -## ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒ сСбя - -- [ ] Имя начинаСтся с `use` (β†’ basics/naming.md) -- [ ] ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ -- [ ] Π₯ΡƒΠΊ экспортирован Ρ‡Π΅Ρ€Π΅Π· ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ API модуля diff --git a/preview/ai/triggers/develop/create-layout.md b/preview/ai/triggers/develop/create-layout.md deleted file mode 100644 index 660be9f..0000000 --- a/preview/ai/triggers/develop/create-layout.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ layout ---- - -# Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ layout - -Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ ΠΏΠΎ созданию layout.tsx Π² Next.js App Router. - -## ΠŸΡ€ΠΎΡ‡ΠΈΡ‚Π°ΠΉ ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ - -- applied/page-level.md β€” ΠΏΡ€Π°Π²ΠΈΠ»Π° layout.tsx: ΠΏΡ€ΠΎΠ²Π°ΠΉΠ΄Π΅Ρ€Ρ‹, metadata, вёрстка -- applied/project-structure.md β€” структура `src/app/` - -## Π¨Π°Π³ΠΈ - -1. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ layout: - - ΠšΠΎΡ€Π½Π΅Π²ΠΎΠΉ (`src/app/layout.tsx`) β€” ΠΏΡ€ΠΎΠ²Π°ΠΉΠ΄Π΅Ρ€Ρ‹, Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Π΅ стили, metadata - - Π’Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΉ (`src/app/{route}/layout.tsx`) β€” layout для Π³Ρ€ΡƒΠΏΠΏΡ‹ страниц - -2. Π‘ΠΎΠ·Π΄Π°ΠΉ `layout.tsx` Π² Π½ΡƒΠΆΠ½ΠΎΠΌ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π΅. - -3. Вёрстку layout-ΠΎΠ±Ρ‘Ρ€Ρ‚ΠΎΠΊ вынСси Π² слой `layouts/` (β†’ applied/page-level.md). - -4. Layout содСрТит Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΎΠ²Π°ΠΉΠ΄Π΅Ρ€Ρ‹ ΠΈ Π²Ρ‹Π·ΠΎΠ² layout-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° β€” Π½Π΅ вёрстку. - -## Π‘ΠΌΠ΅ΠΆΠ½Ρ‹Π΅ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ - -- triggers/develop/create-page.md β€” страницы Π²Π½ΡƒΡ‚Ρ€ΠΈ layout -- triggers/develop/create-component.md β€” layout-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Π² `layouts/` - -## ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒ сСбя - -- [ ] Вёрстка вынСсСна Π² layout-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Π² `layouts/` -- [ ] layout.tsx содСрТит Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΎΠ²Π°ΠΉΠ΄Π΅Ρ€Ρ‹ ΠΈ Π²Ρ‹Π·ΠΎΠ² layout-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° diff --git a/preview/ai/triggers/develop/create-page.md b/preview/ai/triggers/develop/create-page.md deleted file mode 100644 index a23eb94..0000000 --- a/preview/ai/triggers/develop/create-page.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ страницу ---- - -# Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ страницу - -Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ ΠΏΠΎ добавлСнию Π½ΠΎΠ²ΠΎΠ³ΠΎ route Π² Next.js ΠΏΡ€ΠΎΠ΅ΠΊΡ‚. Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° β€” это экран + page.tsx. - -## ΠŸΡ€ΠΎΡ‡ΠΈΡ‚Π°ΠΉ ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ - -- applied/page-level.md β€” ΠΏΡ€Π°Π²ΠΈΠ»Π° Ρ„Π°ΠΉΠ»ΠΎΠ² Ρ€ΠΎΡƒΡ‚ΠΈΠ½Π³Π°: page.tsx, layout.tsx, metadata -- applied/project-structure.md β€” Π³Π΄Π΅ Ρ€Π°ΡΠΏΠΎΠ»Π°Π³Π°ΡŽΡ‚ΡΡ Ρ„Π°ΠΉΠ»Ρ‹ - -## Π¨Π°Π³ΠΈ - -1. Π‘Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠΉ экран ΠΈΠ· шаблона `screen` Π² `src/screens/` (β†’ triggers/develop/generate-module.md). - -2. Π—Π°ΠΏΠΎΠ»Π½ΠΈ экран Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ ΠΈ стилями. - -3. Π‘ΠΎΠ·Π΄Π°ΠΉ `page.tsx` Π² Π½ΡƒΠΆΠ½ΠΎΠΌ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π΅ `src/app/`. - - page.tsx Ρ‚ΠΎΠ½ΠΊΠΈΠΉ: Ρ‚ΠΎΠ»ΡŒΠΊΠΎ `metadata` ΠΈ Ρ€Π΅Π½Π΄Π΅Ρ€ экрана - - Никакой Π»ΠΎΠ³ΠΈΠΊΠΈ, стилСй ΠΈ Ρ…ΡƒΠΊΠΎΠ² Π² page.tsx - -4. Π”ΠΎΠ±Π°Π²ΡŒ `metadata` с `title` (β†’ applied/page-level.md). - -## Π‘ΠΌΠ΅ΠΆΠ½Ρ‹Π΅ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ - -- triggers/develop/generate-module.md β€” гСнСрация экрана ΠΈΠ· шаблона -- triggers/develop/create-layout.md β€” Ссли Π½ΡƒΠΆΠ΅Π½ Π½ΠΎΠ²Ρ‹ΠΉ layout для ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π° -- triggers/develop/create-component.md β€” ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ Π²Π½ΡƒΡ‚Ρ€ΠΈ экрана - -## ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒ сСбя - -- [ ] Π­ΠΊΡ€Π°Π½ создан ΠΈΠ· шаблона `screen` Π² `src/screens/` -- [ ] page.tsx Ρ‚ΠΎΠ½ΠΊΠΈΠΉ β€” Ρ‚ΠΎΠ»ΡŒΠΊΠΎ metadata ΠΈ Ρ€Π΅Π½Π΄Π΅Ρ€ экрана -- [ ] metadata содСрТит title ΠΈ description diff --git a/preview/ai/triggers/develop/create-project.md b/preview/ai/triggers/develop/create-project.md deleted file mode 100644 index 45adfa8..0000000 --- a/preview/ai/triggers/develop/create-project.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ -scope: applied -keywords: [ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚, Π½ΠΎΠ²Ρ‹ΠΉ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚, tiged, шаблон ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°, init] -when: "Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ Next.js ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° ΠΈΠ· шаблона" ---- - -# Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ - -Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ ΠΏΠΎ созданию Π½ΠΎΠ²ΠΎΠ³ΠΎ Next.js ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° ΠΈΠ· Π³ΠΎΡ‚ΠΎΠ²ΠΎΠ³ΠΎ шаблона. ΠŸΡ€ΠΎΠ΅ΠΊΡ‚ Π³ΠΎΡ‚ΠΎΠ² ΠΊ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ сразу послС установки зависимостСй. - -## ΠŸΡ€ΠΎΡ‡ΠΈΡ‚Π°ΠΉ ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ - -- basics/getting-started.md β€” знакомство со стСком ΠΈ особСнностями ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° -- applied/project-structure.md β€” структура ΠΏΠ°ΠΏΠΎΠΊ ΠΈ Ρ„Π°ΠΉΠ»ΠΎΠ² - -## Π¨Π°Π³ΠΈ - -1. Π‘ΠΎΠ·Π΄Π°ΠΉ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ ΠΈΠ· шаблона: - - ```bash - npx tiged git@gromlab.ru:templates/nextjs.git my-app - cd my-app - npm install - ``` - -2. Ознакомься со структурой ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° (β†’ applied/project-structure.md). - -3. Настрой VS Code (β†’ triggers/develop/setup-vscode.md). - -## Π§Ρ‚ΠΎ Π²Ρ…ΠΎΠ΄ΠΈΡ‚ Π² шаблон - -- Next.js + TypeScript (App Router) -- Mantine UI + PostCSS Modules -- Biome (Π»ΠΈΠ½Ρ‚ΠΈΠ½Π³ ΠΈ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅) -- Zustand, SWR -- Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° SLM Design (`screens/`, `layouts/`, `widgets/`, `business/`, `infrastructure/`, `ui/`, `shared/`) -- Π¨Π°Π±Π»ΠΎΠ½Ρ‹ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ (`.templates/`) -- ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ VS Code (`.vscode/`) -- CSS-Ρ‚ΠΎΠΊΠ΅Π½Ρ‹ (Ρ†Π²Π΅Ρ‚Π°, отступы, радиусы, ΠΌΠ΅Π΄ΠΈΠ°) -- Open Graph ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Π΅ - -## Π‘ΠΌΠ΅ΠΆΠ½Ρ‹Π΅ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ - -- triggers/develop/setup-vscode.md β€” настройка Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π° -- triggers/develop/create-page.md β€” Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π²ΠΎΠΉ страницы - -## ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒ сСбя - -- [ ] ΠŸΡ€ΠΎΠ΅ΠΊΡ‚ создан ΠΈΠ· шаблона Ρ‡Π΅Ρ€Π΅Π· `npx tiged` -- [ ] Зависимости установлСны -- [ ] VS Code настроСн (β†’ triggers/develop/setup-vscode.md) diff --git a/preview/ai/triggers/develop/create-store.md b/preview/ai/triggers/develop/create-store.md deleted file mode 100644 index 8ca9d13..0000000 --- a/preview/ai/triggers/develop/create-store.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ стор ---- - -# Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ стор - -Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ ΠΏΠΎ созданию стора для управлСния состояниСм. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈ ΠΎΠ±Π»Π°ΡΡ‚ΡŒ, сгСнСрируй ΠΈΠ· шаблона. - -## ΠŸΡ€ΠΎΡ‡ΠΈΡ‚Π°ΠΉ ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ - -- applied/stores.md β€” ΠΏΡ€Π°Π²ΠΈΠ»Π° сторов -- basics/naming.md β€” ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ΠΈΠ΅ -- basics/typing.md β€” типизация состояния ΠΈ экшСнов - -## Π¨Π°Π³ΠΈ - -1. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈ ΠΎΠ±Π»Π°ΡΡ‚ΡŒ стора: - - Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΉ β†’ `shared/model/` - - ΠŸΡ€ΠΈΠ²ΡΠ·Π°Π½ ΠΊ Ρ„ΠΈΡ‡Π΅/сущности β†’ `model/` Π²Π½ΡƒΡ‚Ρ€ΠΈ модуля - -2. Π‘Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠΉ ΠΈΠ· шаблона `store` (β†’ triggers/develop/generate-module.md). - -3. Π Π΅Π°Π»ΠΈΠ·ΡƒΠΉ стор ΠΏΠΎ ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌ (β†’ applied/stores.md). - -4. Экспортируй Ρ‡Π΅Ρ€Π΅Π· ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ API модуля. - -## Π‘ΠΌΠ΅ΠΆΠ½Ρ‹Π΅ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ - -- triggers/develop/connect-store.md β€” ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ стора ΠΊ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρƒ -- triggers/develop/generate-module.md β€” гСнСрация ΠΈΠ· шаблона - -## ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒ сСбя - -- [ ] Π‘Ρ‚ΠΎΡ€ создан ΠΈΠ· шаблона `store` -- [ ] БостояниС ΠΈ ΡΠΊΡˆΠ΅Π½Ρ‹ Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ -- [ ] Π‘Ρ‚ΠΎΡ€ экспортирован Ρ‡Π΅Ρ€Π΅Π· ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ API модуля diff --git a/preview/ai/triggers/develop/create-widget.md b/preview/ai/triggers/develop/create-widget.md deleted file mode 100644 index f717580..0000000 --- a/preview/ai/triggers/develop/create-widget.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ Π²ΠΈΠ΄ΠΆΠ΅Ρ‚ ---- - -# Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ Π²ΠΈΠ΄ΠΆΠ΅Ρ‚ - -Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ ΠΏΠΎ созданию модуля Π½Π° слоС `widgets/`. Π’ΠΈΠ΄ΠΆΠ΅Ρ‚ β€” композиция Ρ„ΠΈΡ‡Π΅ΠΉ ΠΈ сущностСй. - -## ΠŸΡ€ΠΎΡ‡ΠΈΡ‚Π°ΠΉ ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ - -- basics/architecture.md β€” слои ΠΈ зависимости -- applied/components.md β€” ΠΏΡ€Π°Π²ΠΈΠ»Π° ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² - -## Π¨Π°Π³ΠΈ - -1. Π‘Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠΉ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ ΠΈΠ· шаблона `widget` (β†’ triggers/develop/generate-module.md). - -2. Π‘ΠΊΠΎΠΌΠΏΠΎΠ½ΡƒΠΉ Π²ΠΈΠ΄ΠΆΠ΅Ρ‚ ΠΈΠ· ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… Ρ„ΠΈΡ‡Π΅ΠΉ ΠΈ сущностСй. - -3. Настрой ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ API β€” экспорт Ρ‡Π΅Ρ€Π΅Π· `index.ts`. - -## Π‘ΠΌΠ΅ΠΆΠ½Ρ‹Π΅ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ - -- triggers/develop/create-feature.md β€” Ссли Π½ΡƒΠΆΠ½Π° новая Ρ„ΠΈΡ‡Π° для Π²ΠΈΠ΄ΠΆΠ΅Ρ‚Π° -- triggers/develop/create-component.md β€” UI-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ Π²Π½ΡƒΡ‚Ρ€ΠΈ Π²ΠΈΠ΄ΠΆΠ΅Ρ‚Π° -- triggers/develop/generate-module.md β€” гСнСрация ΠΈΠ· шаблона - -## ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒ сСбя - -- [ ] Π’ΠΈΠ΄ΠΆΠ΅Ρ‚ создан ΠΈΠ· шаблона `widget` -- [ ] ΠšΠΎΠΌΠΏΠΎΠ·ΠΈΡ†ΠΈΡ ΠΈΠ· ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… Ρ„ΠΈΡ‡Π΅ΠΉ/сущностСй, Π½Π΅ Π΄ΡƒΠ±Π»ΠΈΡ€ΡƒΠ΅Ρ‚ Π»ΠΎΠ³ΠΈΠΊΡƒ -- [ ] ΠŸΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ API настроСн β€” экспорт Ρ‡Π΅Ρ€Π΅Π· `index.ts` diff --git a/preview/ai/triggers/develop/generate-module.md b/preview/ai/triggers/develop/generate-module.md deleted file mode 100644 index 8125ae4..0000000 --- a/preview/ai/triggers/develop/generate-module.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: Π‘Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ ΠΈΠ· шаблона ---- - -# Π‘Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ ΠΈΠ· шаблона - -Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ ΠΏΠΎ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ модуля ΠΈΠ· шаблонов `.templates/`. Π ΡƒΡ‡Π½ΠΎΠ΅ созданиС Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ структуры Π·Π°ΠΏΡ€Π΅Ρ‰Π΅Π½ΠΎ. - -## ΠŸΡ€ΠΎΡ‡ΠΈΡ‚Π°ΠΉ ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ - -- applied/templates-generation.md β€” ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹, синтаксис, инструмСнты Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ - -## Π¨Π°Π³ΠΈ - -1. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈ Ρ‚ΠΈΠΏ модуля ΠΈ шаблон (β†’ applied/templates-generation.md): - - ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ β†’ `component` - - БизнСс-ΠΌΠΎΠ΄ΡƒΠ»ΡŒ β†’ `business` - - Π’ΠΈΠ΄ΠΆΠ΅Ρ‚ β†’ `widget` - - Layout β†’ `layout` - - Π­ΠΊΡ€Π°Π½ β†’ `screen` - - Π‘Ρ‚ΠΎΡ€ β†’ `store` - -2. Запусти Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ (β†’ applied/templates-generation.md). - -3. Если подходящСго шаблона Π½Π΅Ρ‚ β€” сначала создай шаблон, Π·Π°Ρ‚Π΅ΠΌ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠΉ. - -## Π‘ΠΌΠ΅ΠΆΠ½Ρ‹Π΅ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ - -- triggers/develop/create-component.md β€” послС Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° -- triggers/develop/create-feature.md β€” послС Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ бизнСс-модуля -- triggers/develop/create-store.md β€” послС Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ стора - -## ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒ сСбя - -- [ ] ΠœΠΎΠ΄ΡƒΠ»ΡŒ создан ΠΈΠ· шаблона, Π½Π΅ Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ -- [ ] Π’Ρ‹Π±Ρ€Π°Π½ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ шаблон для Ρ‚ΠΈΠΏΠ° модуля (β†’ applied/templates-generation.md) diff --git a/preview/ai/triggers/develop/setup-vscode.md b/preview/ai/triggers/develop/setup-vscode.md deleted file mode 100644 index 953a78e..0000000 --- a/preview/ai/triggers/develop/setup-vscode.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: ΠΠ°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ VS Code ---- - -# ΠΠ°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ VS Code - -Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ ΠΏΠΎ настройкС VS Code для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΎΠΌ. - -## ΠŸΡ€ΠΎΡ‡ΠΈΡ‚Π°ΠΉ ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ - -- applied/vscode.md β€” настройки, Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ, сниппСты - -## Π¨Π°Π³ΠΈ - -1. Установи Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ (β†’ applied/vscode.md). - -2. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒ настройки `.vscode/settings.json`. - -3. Настрой сниппСты ΠΏΡ€ΠΈ нСобходимости. - -## ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒ сСбя - -- [ ] Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ установлСны -- [ ] Настройки `.vscode/settings.json` ΠΏΡ€ΠΎΠ²Π΅Ρ€Π΅Π½Ρ‹ diff --git a/preview/ai/triggers/develop/style-component.md b/preview/ai/triggers/develop/style-component.md deleted file mode 100644 index 175144f..0000000 --- a/preview/ai/triggers/develop/style-component.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: Π‘Ρ‚ΠΈΠ»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ---- - -# Π‘Ρ‚ΠΈΠ»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ - -Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ ΠΏΠΎ Π²Ρ‹Π±ΠΎΡ€Ρƒ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π° ΠΊ стилизации ΠΈ написанию стилСй для ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°. - -## ΠŸΡ€ΠΎΡ‡ΠΈΡ‚Π°ΠΉ ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ - -- applied/styles.md β€” ΠΏΡ€Π°Π²ΠΈΠ»Π° CSS: PostCSS Modules, Ρ‚ΠΎΠΊΠ΅Π½Ρ‹, ΠΌΠ΅Π΄ΠΈΠ°-запросы - -## Π¨Π°Π³ΠΈ - -1. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ (β†’ applied/styles.md): - - Mantine-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ β†’ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ пропсы Mantine, Π½Π΅ пиши CSS - - CSS-Ρ‚ΠΎΠΊΠ΅Π½Ρ‹ достаточно β†’ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ Ρ‚ΠΎΠΊΠ΅Π½Ρ‹ - - НуТна кастомная стилизация β†’ PostCSS Modules - -2. Π‘ΠΎΠ·Π΄Π°ΠΉ Ρ„Π°ΠΉΠ» стилСй `{component-name}.module.css` рядом с ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠΌ. - -3. Напиши стили ΠΏΠΎ ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌ (β†’ applied/styles.md). - -4. ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈ стили Π² ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π΅ Ρ‡Π΅Ρ€Π΅Π· `cl()`. - -## Π‘ΠΌΠ΅ΠΆΠ½Ρ‹Π΅ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ - -- triggers/develop/create-component.md β€” Ссли ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Π΅Ρ‰Ρ‘ Π½Π΅ создан -- triggers/develop/add-icon.md β€” Ссли Π½ΡƒΠΆΠ½Π° ΠΈΠΊΠΎΠ½ΠΊΠ° Π² ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π΅ - -## ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒ сСбя - -- [ ] ΠŸΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ стилизации ΡΠΎΠ±Π»ΡŽΠ΄Ρ‘Π½: Mantine β†’ Ρ‚ΠΎΠΊΠ΅Π½Ρ‹ β†’ PostCSS Modules -- [ ] НСт ΠΈΠ½Π»Π°ΠΉΠ½-стилСй ΠΈ магичСских Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ -- [ ] Π€Π°ΠΉΠ» стилСй ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ `{component-name}.module.css` diff --git a/preview/src/App.tsx b/preview/src/App.tsx index 24877b2..3201dd1 100644 --- a/preview/src/App.tsx +++ b/preview/src/App.tsx @@ -96,7 +96,7 @@ export const App = () => { @gromlab/svg-sprites diff --git a/skills/README.md b/skills/README.md index 8d74059..1b8676e 100644 --- a/skills/README.md +++ b/skills/README.md @@ -1,12 +1,12 @@ # AI skills -Π˜ΡΡ…ΠΎΠ΄Π½ΠΈΠΊΠΈ скила `svg-sprites` находятся Π² `skills/svg-sprites/`. Π“ΠΎΡ‚ΠΎΠ²Ρ‹ΠΉ самодостаточный Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚ записываСтся Π² `skills/artifacts/svg-sprites/` ΠΈ коммитится Π² Git. +Π˜ΡΡ…ΠΎΠ΄Π½ΠΈΠΊΠΈ скилов `svg-sprites` ΠΈ `svg-sprites-ru` находятся Π² `skills/svg-sprites/`. Π“ΠΎΡ‚ΠΎΠ²Ρ‹Π΅ самодостаточныС Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚Ρ‹ Π·Π°ΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ΡΡ Π² `skills/artifacts/svg-sprites/` ΠΈ `skills/artifacts/svg-sprites-ru/` ΠΈ коммитятся Π² Git. -ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ `README.md` ΠΈ `docs/ru/*.md` ΡΠ²Π»ΡΡŽΡ‚ΡΡ источником истины. Π‘Π±ΠΎΡ€ΠΊΠ° ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ ΠΈΡ… Π² `references/` Π³ΠΎΡ‚ΠΎΠ²ΠΎΠ³ΠΎ скила, поэтому Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ„Π°ΠΉΠ»Ρ‹ Π²Π½ΡƒΡ‚Ρ€ΠΈ `skills/artifacts/` нСльзя. +ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ `README.md`, `README_RU.md` ΠΈ Ρ„Π°ΠΉΠ»Ρ‹ `docs/{en,ru}/*.md` ΡΠ²Π»ΡΡŽΡ‚ΡΡ источником истины. Π‘Π±ΠΎΡ€ΠΊΠ° ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ ΠΈΡ… Π² `references/` Π³ΠΎΡ‚ΠΎΠ²ΠΎΠ³ΠΎ скила, поэтому Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ„Π°ΠΉΠ»Ρ‹ Π²Π½ΡƒΡ‚Ρ€ΠΈ `skills/artifacts/` нСльзя. ```bash npm run build:skill npm run check:skill ``` -`build:skill` обновляСт Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚, Π° `check:skill` Π±Π΅Π· измСнСния Ρ„Π°ΠΉΠ»ΠΎΠ² провСряСт Π΅Π³ΠΎ содСрТимоС ΠΈ ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½Π½ΠΎΡΡ‚ΡŒ с Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠ΅ΠΉ. +`build:skill` обновляСт ΠΎΠ±Π° Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚Π°, Π° `check:skill` Π±Π΅Π· измСнСния Ρ„Π°ΠΉΠ»ΠΎΠ² провСряСт ΠΈΡ… содСрТимоС ΠΈ ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½Π½ΠΎΡΡ‚ΡŒ с Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠ΅ΠΉ. ВСрсия Π±Π΅Π· суффикса ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ английский язык, вСрсия с суффиксом `-ru` β€” русский. diff --git a/skills/artifacts/svg-sprites-ru/SKILL.md b/skills/artifacts/svg-sprites-ru/SKILL.md new file mode 100644 index 0000000..b5ff569 --- /dev/null +++ b/skills/artifacts/svg-sprites-ru/SKILL.md @@ -0,0 +1,64 @@ +--- +name: svg-sprites-ru +description: "Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ ΠΏΡ€ΠΈ настройкС, Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ, ΠΌΠΈΠ³Ρ€Π°Ρ†ΠΈΠΈ ΠΈΠ»ΠΈ диагностикС SVG-спрайтов Ρ‡Π΅Ρ€Π΅Π· @gromlab/svg-sprites. Π’Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹: SVG sprite, SVG-спрайт, svg-sprites, svg-sprite.config.ts, svg-sprites.config.ts, defineReactSpriteConfig, defineNextSpriteConfig, react@vite, react@webpack, next@app, next@pages, inputFiles, SpriteViewer, icon=\"...\", --icon-color-N, generated-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΈΠ»ΠΈ ΠΈΠΊΠΎΠ½ΠΊΠ° Π½Π΅ появилась Π² ΠΏΡ€Π΅Π²ΡŒΡŽ ΠΈ Π°Π²Ρ‚ΠΎΠ΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ. НЕ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ для favicon, растровых ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ, icon fonts, Π²Ρ‹Π±ΠΎΡ€Π° Π½Π°Π±ΠΎΡ€Π° ΠΈΠΊΠΎΠ½ΠΎΠΊ ΠΈΠ»ΠΈ inline SVG Π±Π΅Π· спрайтов." +--- + + + +# SVG Sprites + +## НазначСниС + +Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ этот скил для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с `@gromlab/svg-sprites`: ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½ΠΎΠΉ настройки, добавлСния ΠΈ ΠΏΠ΅Ρ€Π΅ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΈΠΊΠΎΠ½ΠΎΠΊ, Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ React-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ², ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ `SpriteViewer`, ΠΌΠΈΠ³Ρ€Π°Ρ†ΠΈΠΈ legacy-ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ ΠΈ диагностики ошибок. + +НС навязывай ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρƒ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΡƒΡŽ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Ρƒ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ΠΎΠ². Π‘Π½Π°Ρ‡Π°Π»Π° ΠΈΠ·ΡƒΡ‡ΠΈ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ `package.json`, ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ спрайта, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ, Ρ€ΠΎΡƒΡ‚Π΅Ρ€ ΠΈ сборщик. + +## Π Π°Π±ΠΎΡ‡ΠΈΠΉ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ + +1. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅ΠΆΠΈΠΌ ΠΈ Π½Π΅ смСшивай Π΅Π³ΠΎ API с Π΄Ρ€ΡƒΠ³ΠΈΠΌ Ρ€Π΅ΠΆΠΈΠΌΠΎΠΌ. +2. Для React Π²Ρ‹Π±Π΅Ρ€ΠΈ `react@vite` ΠΈΠ»ΠΈ `react@webpack` ΠΈ ΠΎΡ‚ΠΊΡ€ΠΎΠΉ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ reference. +3. Для Next.js ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈ App Router ΠΈΠ»ΠΈ Pages Router, Π·Π°Ρ‚Π΅ΠΌ Turbopack ΠΈΠ»ΠΈ Webpack, ΠΈ ΠΎΡ‚ΠΊΡ€ΠΎΠΉ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ reference. +4. Для ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ `svg-sprites.config.ts` с нСсколькими спрайтами ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ legacy-Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ. НС ΠΌΠΈΠ³Ρ€ΠΈΡ€ΡƒΠΉ Ρ‚Π°ΠΊΠΎΠΉ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ Π±Π΅Π· явного запроса. +5. Π˜Π·ΡƒΡ‡ΠΈ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ scripts ΠΈ добавляй Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ ΠΏΠ΅Ρ€Π΅Π΄ `dev`, `build` ΠΈ `typecheck`, Ссли generated-Ρ„Π°ΠΉΠ»Ρ‹ Π½Π΅ хранятся Π² Git. +6. ПослС измСнСния ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ ΠΈΠ»ΠΈ SVG запусти Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ, Π·Π°Ρ‚Π΅ΠΌ Π΄ΠΎΡΡ‚ΡƒΠΏΠ½ΡƒΡŽ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ Ρ‚ΠΈΠΏΠΎΠ² ΠΈΠ»ΠΈ сборку ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°. + +## ΠŸΡ€Π°Π²ΠΈΠ»Π° React ΠΈ Next.js + +- Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ `svg-sprite.config.ts` ΠΈ подходящий config helper: `defineReactSpriteConfig` ΠΈΠ»ΠΈ `defineNextSpriteConfig`. +- НС Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΡƒΠΉ `generated/`, `index.ts`, `manifest.ts` ΠΈ созданный Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠΌ `.gitignore` Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ. +- ИмСна исходных SVG становятся допустимыми значСниями prop `icon`; ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ generated-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΈ Π΅Π³ΠΎ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ вмСсто deep imports. +- ОбъСдиняй Π»ΠΎΠΊΠ°Π»ΡŒΠ½ΡƒΡŽ ΠΏΠ°ΠΏΠΊΡƒ ΠΈ `inputFiles`, ΠΊΠΎΠ³Π΄Π° общая ΠΈΠΊΠΎΠ½ΠΊΠ° Π½ΡƒΠΆΠ½Π° нСскольким спрайтам. НС создавай ΠΊΠΎΠΏΠΈΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ SVG Π±Π΅Π· нСобходимости. +- Π’ Next.js generated-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² Server Components, SSR ΠΈ SSG. НС добавляй `'use client'` Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ€Π°Π΄ΠΈ ΠΈΠΊΠΎΠ½ΠΊΠΈ. +- Π‘ΠΏΡ€Π°ΠΉΡ‚ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΡΡ‚Π°Π²Π°Ρ‚ΡŒΡΡ внСшним asset сборщика: Π½Π΅ ΠΏΠ΅Ρ€Π΅Π½ΠΎΡΠΈΡ‚ΡŒ SVG path-Π΄Π°Π½Π½Ρ‹Π΅ Π² JavaScript ΠΈ Π½Π΅ ΠΊΠ»Π°ΡΡ‚ΡŒ generated-Ρ„Π°ΠΉΠ» Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ Π² `public`. + +## Π¦Π²Π΅Ρ‚Π° ΠΈ трансформации + +- По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ удаляСт `width` ΠΈ `height`, замСняСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Π΅ `fill` ΠΈ `stroke` Π½Π° CSS-ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΈ добавляСт transitions. +- Для ΠΌΠΎΠ½ΠΎΡ…Ρ€ΠΎΠΌΠ½ΠΎΠΉ ΠΈΠΊΠΎΠ½ΠΊΠΈ сначала управляй `color`; для ΠΌΠ½ΠΎΠ³ΠΎΡ†Π²Π΅Ρ‚Π½ΠΎΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ `--icon-color-N`. +- НС ΠΎΠ±Π΅Ρ‰Π°ΠΉ Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΡ‡Π΅ΡΠΊΡƒΡŽ Π·Π°ΠΌΠ΅Π½Ρƒ Ρ†Π²Π΅Ρ‚ΠΎΠ² Π²Π½ΡƒΡ‚Ρ€ΠΈ Π²Π½Π΅ΡˆΠ½ΠΈΡ… stylesheets, gradients, patterns, filters ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ `url(#...)` Π±Π΅Π· ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°. +- CSS-ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ страницы Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ ΠΏΡ€ΠΈ ``, Π½ΠΎ Π½Π΅ ΠΏΡ€ΠΎΠ½ΠΈΠΊΠ°ΡŽΡ‚ Π²Π½ΡƒΡ‚Ρ€ΡŒ `` ΠΈ `background-image`. + +## ΠŸΡ€Π΅Π²ΡŒΡŽ + +Для React ΠΈ Next.js ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°ΠΉ `` ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΉ debug-страницСй прилоТСния. ΠŸΠ΅Ρ€Π΅Π΄Π°ΠΉ Π΅ΠΌΡƒ manifests ΠΈΠ»ΠΈ lazy loaders спрайтов. Viewer ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ поиск, ΡΠ²Π΅Ρ‚Π»ΡƒΡŽ ΠΈ Ρ‚Ρ‘ΠΌΠ½ΡƒΡŽ Ρ‚Π΅ΠΌΡ‹, настройку Ρ†Π²Π΅Ρ‚ΠΎΠ² ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ React, SVG, IMG ΠΈ CSS. + +`SpriteViewer` являСтся клиСнтским debug-инструмСнтом ΠΈ импортируСтся ΠΈΠ· `@gromlab/svg-sprites/react`; production-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ ΠΈΠΊΠΎΠ½ΠΎΠΊ ΠΎΡ‚ Π½Π΅Π³ΠΎ Π½Π΅ зависят. + +## Диагностика + +- Если имя ΠΈΠΊΠΎΠ½ΠΊΠΈ отсутствуСт Π² Π°Π²Ρ‚ΠΎΠ΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒ Π²Ρ…ΠΎΠ΄Π½ΡƒΡŽ ΠΏΠ°ΠΏΠΊΡƒ ΠΈ `inputFiles`, Π·Π°Ρ‚Π΅ΠΌ пСрСзапусти Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ. +- Если Π΄Π²Π° Ρ„Π°ΠΉΠ»Π° ΠΈΠΌΠ΅ΡŽΡ‚ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΠΎΠ΅ имя ΠΈΠΊΠΎΠ½ΠΊΠΈ, устрани ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚ вмСсто Π²Ρ‹Π±ΠΎΡ€Π° ΠΎΠ΄Π½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π° нСявно. +- Если Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ отказываСтся ΠΏΠ΅Ρ€Π΅Π·Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ Ρ„Π°ΠΉΠ», Π½Π΅ удаляй Π·Π°Ρ‰ΠΈΡ‚Π½Ρ‹ΠΉ marker ΠΈ Π½Π΅ ΠΎΠ±Ρ…ΠΎΠ΄ΠΈ writer: пСрСнСси ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ Ρ„Π°ΠΉΠ» ΠΈΠ»ΠΈ Π²Ρ‹Π±Π΅Ρ€ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ спрайта. +- Если asset Π½Π΅ загруТаСтся, сначала ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒ соотвСтствиС CLI mode Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΌΡƒ сборщику ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ generated SVG Π΅Π³ΠΎ asset pipeline. +- Если ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ старый API, ΡΠ²Π΅Ρ€ΡŒ ΡƒΡΡ‚Π°Π½ΠΎΠ²Π»Π΅Π½Π½ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ ΠΏΠ°ΠΊΠ΅Ρ‚Π° ΠΈ legacy reference ΠΏΠ΅Ρ€Π΅Π΄ измСнСниями. + +## References + +- [Основная докумСнтация ΠΈ API](./references/README_RU.md) +- [React + Vite](./references/docs/ru/react-vite.md) +- [React + Webpack 5](./references/docs/ru/react-webpack.md) +- [Next.js App Router](./references/docs/ru/next-app.md) +- [Next.js Pages Router](./references/docs/ru/next-pages.md) +- [Legacy mode](./references/docs/ru/legacy.md) +- [ΠœΠΈΠ³Ρ€Π°Ρ†ΠΈΡ с 0.1.x](./references/docs/ru/migration-1.md) +- [ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ API](./references/docs/ru/programmatic-api.md) diff --git a/skills/artifacts/svg-sprites-ru/references/README.md b/skills/artifacts/svg-sprites-ru/references/README.md new file mode 100644 index 0000000..c23d2d0 --- /dev/null +++ b/skills/artifacts/svg-sprites-ru/references/README.md @@ -0,0 +1,398 @@ +# @gromlab/svg-sprites + +πŸ‡¬πŸ‡§ English | [πŸ‡·πŸ‡Ί Русский](README_RU.md) + +![npm](https://img.shields.io/npm/v/@gromlab/svg-sprites) ![license](https://img.shields.io/npm/l/@gromlab/svg-sprites) + +A CLI for generating SVG sprites and typed icon components for React and Next.js. + +![Preview](https://raw.githubusercontent.com/gromov-sergei/svg-sprites/master/preview-image.png) + +## Navigation + +- [Features](#features) +- [Support matrix](#support-matrix) +- [Requirements](#requirements) +- [Quick start](#quick-start) + - [React + Vite](docs/en/react-vite.md) + - [React + Webpack 5](docs/en/react-webpack.md) + - [Next.js App Router](docs/en/next-app.md) + - [Next.js Pages Router](docs/en/next-pages.md) +- [Configuration](#configuration) + - [React](#react) + - [Next.js](#nextjs) +- [Multiple sprites](#multiple-sprites) +- [TypeScript](#typescript) +- [Sprite formats](#sprite-formats) +- [Rendering methods](#rendering-methods) +- [Transformations](#transformations) +- [Icon color management](#icon-color-management) +- [Caching](#caching) +- [SpriteViewer](#spriteviewer) +- [Migrating from 0.1.x](docs/en/migration-1.md) +- [Documentation](#documentation) + +## Features + +- **AI-agent friendly** - the repository includes a ready-to-use skill with up-to-date documentation for configuring, migrating, and troubleshooting `@gromlab/svg-sprites`. +- **TypeScript-friendly** - typed React components, union types, and runtime lists of available icons. +- **Clean generation** - generated files are automatically excluded from Git, the sprite does not need to be placed in `public` manually, and the generator updates only files it owns. +- **Shared icons without copying** - SVGs from the local folder and `inputFiles` are merged into a single sprite; one file can be used in multiple sprites. +- **Built-in interactive preview** - `` is integrated as an application page and displays the provided React and Next.js sprites with search, color controls, and usage examples. +- **Configurable SVG transformations** - remove `width` and `height` while preserving `viewBox`, replace source colors with CSS variables, and add transitions for `fill` and `stroke`. +- **Separate cacheable SVG asset** - SVG path data does not end up in JavaScript chunks, and the bundler emits a file with a content hash. +- **Multiple sprites** - independent React and Next.js modules with their own components, types, and SVG assets. +- **Server-first Next.js** - generated components work in Server Components, SSR, and SSG without the `'use client'` directive. +- **Formats for different use cases** - React and Next.js use `stack`; legacy mode also supports `symbol` for existing integrations. + +## Support matrix + +| Environment | API mode key | Status | +|---|---|---| +| React + Vite | `react@vite` | Ready | +| React + Webpack 5 | `react@webpack` | Ready | +| Next.js 16.2+ App Router + Turbopack | `next@app/turbopack` | Ready | +| Next.js 13.4+ App Router + Webpack 5 | `next@app/webpack` | Ready | +| Next.js 16.2+ Pages Router + Turbopack | `next@pages/turbopack` | Ready | +| Next.js 12.2+ Pages Router + Webpack 5 | `next@pages/webpack` | Ready | +| Vue | - | Coming soon | +| Standalone | - | Coming soon | + +## Requirements + +- Node.js 18 or newer; +- the package is distributed as ESM only and is loaded via `import`; +- React 18 or 19 is required only for generated components and the `@gromlab/svg-sprites/react` entry point; +- for subpath export typings, use TypeScript 5+ with `moduleResolution: "bundler"`, `"node16"`, or `"nodenext"`. + +## Quick start + +For a quick start, follow the guide for your stack: + +- [React + Vite](docs/en/react-vite.md) +- [React + Webpack 5](docs/en/react-webpack.md) +- [Next.js App Router](docs/en/next-app.md) +- [Next.js Pages Router](docs/en/next-pages.md) + +## Configuration + +### React + +```ts +import { defineReactSpriteConfig } from '@gromlab/svg-sprites' + +export default defineReactSpriteConfig({ + name: 'file-manager', + description: 'File manager icons', + inputFolder: './icons', + inputFiles: [ + '../../shared/icons/check.svg', + ], + transform: { + removeSize: true, + replaceColors: true, + addTransition: true, + }, + generatedNotice: true, +}) +``` + +| Option | Type | Default | Purpose | +|---|---|---|---| +| `name` | `string` | Folder name | Name of the sprite, component, and public types | +| `description` | `string` | None | Description for types and the debug manifest | +| `inputFolder` | `string` | `./icons` | Folder containing source SVGs, relative to the config | +| `inputFiles` | `string[]` | `[]` | Additional SVG files, relative to the config | +| `transform` | `TransformOptions` | All enabled | [Transformation settings](#transformations) for source SVGs | +| `generatedNotice` | `boolean` | `true` | Full or short warning in generated files | + +`inputFolder` and `inputFiles` are merged into a single sprite, so one SVG file can be used in multiple sprites without copying. If the implicit `./icons` folder does not exist but `inputFiles` is populated, generation continues using only the list. An explicitly specified missing folder is an error. Duplicate paths are deduplicated, while different files with the same icon name are treated as an error. + +`name` is stored in kebab-case and must start with a Latin letter. The React and Next.js presets produce the `stack` format. + +### Next.js + +Next.js uses the same `svg-sprite.config.ts` and set of options. For type checking, you can use a dedicated helper: + +```ts +import { defineNextSpriteConfig } from '@gromlab/svg-sprites' + +export default defineNextSpriteConfig({ + name: 'file-manager', + description: 'File manager icons', + inputFolder: './icons', +}) +``` + +The router and bundler are selected through the mode key, so switching between Turbopack and Webpack is always explicitly reflected in the generation command. + +## Multiple sprites + +An application can contain several independent sprites for different scopes: + +**Problem:** one global sprite loads icons that the current screen does not need. + +**Solution:** keep shared icons globally, and place icon sets for pages and large components in separate sprites that load alongside them. + +```text +global -> GlobalIcon -> shared application icons +analytics-page -> AnalyticsPageIcon -> icons for a specific page +file-manager -> FileManagerIcon -> icons for a large component +``` + +- **Global sprite** contains a small set of shared icons used in different parts of the application: navigation, states, and basic actions. +- **Page sprite** loads with a specific section and does not increase the shared sprite with icons that are not needed anywhere else. +- **Large component sprite** encapsulates the icon set of a complex UI module, such as a file manager or editor. + +Each group gets: + +- its own SVG asset; +- its own typed component; +- a separate list of icon names; +- a separate debug manifest; +- an independent cache lifecycle. + + +## TypeScript + +The main feature of the TypeScript API is icon name autocomplete directly in the `icon` prop: + +```tsx + +// ^ the editor suggests every icon in the sprite +``` + +SVG file names become valid `icon` values. A typo or unknown name immediately becomes a TypeScript error: + +```tsx + // TypeScript error +``` + +For programmatic access, the generated module exports a readonly array of all icons available in a specific sprite: + +```ts +import { fileManagerIconNames } from './svg-sprite' + +// readonly ['check', 'folder', ...] +``` + +You can use this list in custom catalogs, select components, tests, and other runtime scenarios. The `FileManagerIconName` union type is also derived from it. + +File names containing spaces and other characters unsafe for SVG IDs remain part of the public TypeScript API. For the internal ``, the generator creates a stable hash ID. + +```text +folder open.svg -> icon="folder open" -> id="icon-" +``` + +For such names, use the generated component or the `id` from the debug manifest. The manual examples below using `#` are suitable only for names that are already safe SVG IDs. + +## Sprite formats + +`stack` is the more modern format, so it is used by default. Icons can be rendered through ``, ``, and CSS `background-image`. + +`symbol` is retained for compatibility with existing integrations and supports rendering only through ``. + +## Rendering methods + +### React component - recommended + +The generated component provides type safety and icon name autocomplete, and constructs the SVG asset URL itself. + +```tsx + +``` + +Monochrome and multicolor icons are supported through `color` and `--icon-color-N`. + +### Manually with `` + +A good low-level method that provides full control over dimensions and colors. This is exactly what the React component uses under the hood. + +How you obtain `spriteUrl` depends on the bundler. + +**Vite:** + +```tsx +import spriteUrl from './svg-sprite/generated/sprite.svg?no-inline' +``` + +**Webpack 5:** + +```tsx +const spriteUrl = new URL( + './svg-sprite/generated/sprite.svg', + import.meta.url, +).href +``` + +**Next.js with Webpack 5 or Turbopack:** + +```tsx +const spriteUrl = new URL( + './svg-sprite/generated/sprite.svg', + import.meta.url, +).href +``` + +After obtaining the URL, the icon is rendered the same way: + +```tsx + + + +``` + +Vite, Webpack 5, and Next.js replace the source path with the final hashed asset URL automatically. + +### With `` - less efficient + +```tsx +Done +``` + +The SVG loads as an isolated image: its colors cannot be changed through `color` or `--icon-color-N`. + +### With CSS `background-image` - less efficient + +```css +.icon { + background: url('./svg-sprite/generated/sprite.svg#check') center / contain no-repeat; +} +``` + +Like ``, this method does not allow you to control internal SVG colors. The path is specified relative to the CSS file, and Vite/Webpack replaces it with the final hashed URL during the build. + +### With CSS mask - less efficient + +```css +.icon { + background-color: currentColor; + mask: url('./svg-sprite/generated/sprite.svg#check') center / contain no-repeat; +} +``` + +A mask retains only the silhouette and colors it with a single color. The original colors, gradients, and distinctions between `fill` and `stroke` are lost. + +## Transformations + +All transformations are enabled by default and configured independently through `transform`. + +| Option | Default | What it does | +|---|---|---| +| `removeSize` | `true` | Removes `width` and `height` from the root `` while preserving the existing `viewBox`. The icon size is then set externally. | +| `replaceColors` | `true` | Replaces `fill` and `stroke` colors with `--icon-color-N`. For a monochrome icon, the fallback becomes `currentColor`; for a multicolor icon, the original colors are preserved. | +| `addTransition` | `true` | Adds `style="transition:fill 0.3s,stroke 0.3s;"` directly to colored SVG elements. An existing `transition` is not overwritten. | + +To disable a transformation, pass `false` for the corresponding option. For more details about the result of `replaceColors`, see [Icon color management](#icon-color-management). + +## Icon color management + +When color replacement is enabled, the generator analyzes `fill` and `stroke` and converts them to CSS custom properties. + +### Monochrome icons + +If one color is found, the fallback is replaced with `currentColor`: + +```svg +stroke="var(--icon-color-1, currentColor)" +``` + +The color is controlled by the CSS `color` property of the outer `` or its parent. + +### Multicolor icons + +Each unique color gets a separate variable with the original fallback: + +```svg +fill="var(--icon-color-1, #798198)" +fill="var(--icon-color-2, #ffffff)" +fill="var(--icon-color-3, #129d9d)" +``` + +The page can override only the required colors: + +```css +.icon { + --icon-color-1: #4b5563; + --icon-color-3: #14b8a6; +} +``` + +### Color limitations + +- `none`, `transparent`, `inherit`, `unset`, and `initial` are not replaced; +- colors in `fill`, `stroke`, and inline `style` attributes are handled most reliably; +- CSS classes and external stylesheets inside the source SVG are not the primary transformation use case; +- gradients, patterns, filters, and `url(#...)` values require separate verification and may be incompatible with automatic color replacement; +- page CSS variables are available with ``, but are not available inside `` and `background-image`. + +## Caching + +The Vite, Webpack, and Next.js targets emit the sprite as a separate asset with a content hash: + +```text +/assets/sprite-.svg +``` + +This provides the following properties: + +- the SVG is cached independently of JavaScript; +- changes to React code do not alter the sprite contents; +- icon changes produce a new hashed asset; +- one file is used by every instance of the generated component; +- SVG path data is absent from JavaScript chunks. + +The Vite target prevents inlining through `?no-inline`. The Webpack 5 target uses Asset Modules through `new URL(..., import.meta.url)`. + +## SpriteViewer + +`SpriteViewer` is a React component for viewing generated sprites inside an application's debug route. + +It uses separate manifests and displays: + +- sprite groups; +- the icon list and count; +- search and the system light/dark theme; +- a preview modal with the `viewBox` and color variable controls; +- React, SVG, IMG, and CSS examples with code copying. + +Production components do not import debug manifests. How you integrate the Viewer depends on the bundler: + +- [React + Vite: automatic `import.meta.glob`](docs/en/react-vite.md#6-add-a-debug-page); +- [React + Webpack 5: static `import()`](docs/en/react-webpack.md#6-add-a-debug-page); +- [Next.js App Router](docs/en/next-app.md#5-add-spriteviewer); +- [Next.js Pages Router](docs/en/next-pages.md#5-add-spriteviewer). + +The Viewer is imported from the separate `@gromlab/svg-sprites/react` client entry point and is not included in production icon components. + +### Viewer theme + +By default, `colorTheme="auto"`: the Viewer follows `prefers-color-scheme` and responds to system theme changes. The application theme can be passed explicitly: + +```tsx + +``` + +Valid `colorTheme` values are `auto`, `light`, and `dark`. When the theme is controlled externally, the built-in switch is hidden. To keep it and update the application theme through the Viewer, pass a callback: + +```tsx + +``` + +## Documentation + +- [React + Vite](docs/en/react-vite.md) +- [React + Webpack 5](docs/en/react-webpack.md) +- [Next.js App Router](docs/en/next-app.md) +- [Next.js Pages Router](docs/en/next-pages.md) +- [Legacy mode](docs/en/legacy.md) +- [Migrating from 0.1.x](docs/en/migration-1.md) +- [Programmatic API](docs/en/programmatic-api.md) + +## License + +MIT diff --git a/skills/artifacts/svg-sprites-ru/references/README_RU.md b/skills/artifacts/svg-sprites-ru/references/README_RU.md new file mode 100644 index 0000000..c4d9a90 --- /dev/null +++ b/skills/artifacts/svg-sprites-ru/references/README_RU.md @@ -0,0 +1,398 @@ +# @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 diff --git a/skills/artifacts/svg-sprites-ru/references/docs/en/legacy.md b/skills/artifacts/svg-sprites-ru/references/docs/en/legacy.md new file mode 100644 index 0000000..10b6ea1 --- /dev/null +++ b/skills/artifacts/svg-sprites-ru/references/docs/en/legacy.md @@ -0,0 +1,102 @@ +# Legacy mode + +[← Back to home](../../README.md) + +A quick guide to generating centralized SVG sprites in `symbol` and `stack` formats, with an optional HTML preview. + +## 1. Install the package + +```bash +npm install @gromlab/svg-sprites +``` + +## 2. Prepare the icons and config + +```text +project/ +β”œβ”€β”€ src/assets/icons/ +β”‚ β”œβ”€β”€ check.svg +β”‚ └── folder.svg +└── svg-sprites.config.ts +``` + +```ts +// svg-sprites.config.ts +import { defineLegacyConfig } from '@gromlab/svg-sprites' + +export default defineLegacyConfig({ + output: 'public/sprites', + preview: true, + sprites: [ + { + name: 'icons', + input: 'src/assets/icons', + format: 'symbol', + }, + ], +}) +``` + +## 3. Run generation + +```bash +npx svg-sprites --mode legacy . +``` + +Result: + +```text +public/sprites/ +β”œβ”€β”€ icons.sprite.svg +└── preview.html +``` + +With `preview: false`, the HTML file is not created. For the `stack` format, specify `format: 'stack'`. + +## 4. Use the symbol sprite + +```html + + + +``` + +## 5. Add a package script + +```json +{ + "scripts": { + "sprites": "svg-sprites --mode legacy .", + "prebuild": "npm run sprites" + } +} +``` + +## Multiple sprites + +Add multiple entries to `sprites`: + +```ts +sprites: [ + { + name: 'icons', + input: 'src/assets/icons', + format: 'symbol', + }, + { + name: 'logos', + input: 'src/assets/logos', + format: 'stack', + }, +] +``` + +All output files and the shared `preview.html` will be written to `output`. + +## Troubleshooting + +- Config not found: make sure `svg-sprites.config.ts` is located in the specified root directory. +- No icons: check `sprites[].input` and the `.svg` extension. +- Preview not needed: set `preview: false`. + +For programmatic use, see [`generateLegacy`](programmatic-api.md#generatelegacy). diff --git a/skills/artifacts/svg-sprites-ru/references/docs/en/migration-1.md b/skills/artifacts/svg-sprites-ru/references/docs/en/migration-1.md new file mode 100644 index 0000000..b53b915 --- /dev/null +++ b/skills/artifacts/svg-sprites-ru/references/docs/en/migration-1.md @@ -0,0 +1,96 @@ +# Migrating from 0.1.x to 1.0 + +[← Back to home](../../README.md) + +Version 1.0 separates local generation for React and Next.js from the centralized legacy mode. The old config cannot be mixed with the new API in a single CLI invocation. + +## CLI + +The CLI now always requires an explicit `--mode` and a path to the configuration directory: + +```text +svg-sprites +β†’ svg-sprites --mode +``` + +Choose a mode based on your environment: + +| Environment | Mode | +|---|---| +| React + Vite | `react@vite` | +| React + Webpack 5 | `react@webpack` | +| Next.js App Router + Turbopack | `next@app/turbopack` | +| Next.js App Router + Webpack 5 | `next@app/webpack` | +| Next.js Pages Router + Turbopack | `next@pages/turbopack` | +| Next.js Pages Router + Webpack 5 | `next@pages/webpack` | +| Centralized legacy setup | `legacy` | + +## React and Next.js + +Instead of a root-level `svg-sprites.config.ts`, create a local `svg-sprite.config.ts` next to the icon set: + +```ts +import { defineNextSpriteConfig } from '@gromlab/svg-sprites' + +export default defineNextSpriteConfig({ + name: 'global', + inputFolder: './icons', +}) +``` + +For regular React, use `defineReactSpriteConfig`. A folder and an explicit list of shared SVG files can be combined using `inputFolder` and `inputFiles`. + +The old `publicPath` and `react` options are no longer needed. The generated module is created next to the config and adds its own `.gitignore`, while Vite, Webpack, or Next.js emits the SVG as a separate asset with a content hash. + +The `` component is replaced by a component whose name is derived from `name`: + +```tsx + +``` + +To browse the icons, add `` as a debug page in the application. A separate `preview.html` is available only in legacy mode. + +## Legacy mode + +If you need to preserve the centralized structure, rename the helper and the format fields: + +```ts +import { defineLegacyConfig } from '@gromlab/svg-sprites' + +export default defineLegacyConfig({ + output: 'public/sprites', + preview: true, + sprites: [ + { + name: 'icons', + input: 'src/assets/icons', + format: 'stack', + }, + ], +}) +``` + +- `defineConfig` has been replaced with `defineLegacyConfig`; +- `sprites[].mode` has been renamed to `sprites[].format`; +- `generate` has been replaced with `generateLegacy`; +- `loadConfig` has been replaced with `loadLegacyConfig`; +- `publicPath` and generation of the old shared React component have been removed. + +Run: + +```bash +svg-sprites --mode legacy . +``` + +## Programmatic API + +The package is distributed as ESM only. Replace `require()` with `import`. + +`compileSpriteContent` now returns `Promise` so that the public declarations do not require `@types/node` to be installed. In Node.js, the actual result is compatible with APIs that accept `Uint8Array`. + +## After migration + +1. Remove the old generated files and rules that ignored the entire directory containing the source icons. +2. Add an explicit generation command before `dev`, `build`, and `typecheck`. +3. Run generation and type checking. +4. Check all icons and color variables using `SpriteViewer` or the legacy `preview.html`. diff --git a/skills/artifacts/svg-sprites-ru/references/docs/en/next-app.md b/skills/artifacts/svg-sprites-ru/references/docs/en/next-app.md new file mode 100644 index 0000000..1e334ce --- /dev/null +++ b/skills/artifacts/svg-sprites-ru/references/docs/en/next-app.md @@ -0,0 +1,102 @@ +# Next.js App Router + +[← Back to home](../../README.md) + +Two explicit modes are supported: + +| Bundler | Mode key | Next.js version | +|---|---|---| +| Turbopack | `next@app/turbopack` | 16.2+ | +| Webpack 5 | `next@app/webpack` | 13.4+ | + +## 1. Install the package + +```bash +npm install @gromlab/svg-sprites +``` + +## 2. Create a sprite module + +```text +src/ui/file-manager/svg-sprite/ +β”œβ”€β”€ icons/ +β”‚ β”œβ”€β”€ check.svg +β”‚ └── folder.svg +└── svg-sprite.config.ts +``` + +```ts +// src/ui/file-manager/svg-sprite/svg-sprite.config.ts +import { defineNextSpriteConfig } from '@gromlab/svg-sprites' + +export default defineNextSpriteConfig({ + name: 'file-manager', + description: 'File manager icons', +}) +``` + +## 3. Add generation + +For Turbopack: + +```json +{ + "scripts": { + "sprite:file-manager": "svg-sprites --mode next@app/turbopack src/ui/file-manager/svg-sprite", + "predev": "npm run sprite:file-manager", + "prebuild": "npm run sprite:file-manager" + } +} +``` + +For Webpack, replace the mode key with `next@app/webpack`. In Next 13–15, Webpack is used with the regular `next build` command; in Next 16, use `next build --webpack`. + +## 4. Use it in a Server Component + +The generated component does not contain `'use client'`, so it can be imported directly into `page.tsx` or `layout.tsx`: + +```tsx +import { FileManagerIcon } from '@/ui/file-manager/svg-sprite' + +export default function Page() { + return ( +
+ +
+ ) +} +``` + +Next.js emits a separate SVG asset with a content hash. The same generated code is used during SSR and in the browser, with no URL mismatch. + +## 5. Add SpriteViewer + +The viewer is interactive, so it requires a separate Client Component boundary: + +```tsx +'use client' + +import { SpriteViewer } from '@gromlab/svg-sprites/react' + +const sources = [ + () => import('@/ui/file-manager/svg-sprite/manifest'), +] + +export default function SpritesPage() { + return +} +``` + +## Verify the bundler + +```bash +# Turbopack +npx next build --turbopack + +# Webpack 5 +npx next build --webpack +``` + +For Next 13–15 with Webpack, use `npx next build` without the flag. + +The Next.js command and the generator mode key must target the same bundler. diff --git a/skills/artifacts/svg-sprites-ru/references/docs/en/next-pages.md b/skills/artifacts/svg-sprites-ru/references/docs/en/next-pages.md new file mode 100644 index 0000000..0de0136 --- /dev/null +++ b/skills/artifacts/svg-sprites-ru/references/docs/en/next-pages.md @@ -0,0 +1,96 @@ +# Next.js Pages Router + +[← Back to home](../../README.md) + +Two explicit modes are supported: + +| Bundler | Mode key | Next.js version | +|---|---|---| +| Turbopack | `next@pages/turbopack` | 16.2+ | +| Webpack 5 | `next@pages/webpack` | 12.2+ | + +Next.js 12.2 requires React 18. + +## 1. Install the package + +```bash +npm install @gromlab/svg-sprites +``` + +## 2. Create a sprite module + +```text +src/ui/file-manager/svg-sprite/ +β”œβ”€β”€ icons/ +β”‚ β”œβ”€β”€ check.svg +β”‚ └── folder.svg +└── svg-sprite.config.ts +``` + +```ts +// src/ui/file-manager/svg-sprite/svg-sprite.config.ts +import { defineNextSpriteConfig } from '@gromlab/svg-sprites' + +export default defineNextSpriteConfig({ + name: 'file-manager', + description: 'File manager icons', +}) +``` + +## 3. Add generation + +```json +{ + "scripts": { + "sprite:file-manager": "svg-sprites --mode next@pages/webpack src/ui/file-manager/svg-sprite", + "predev": "npm run sprite:file-manager", + "prebuild": "npm run sprite:file-manager" + } +} +``` + +For Next.js 16.2 with Turbopack, replace the mode key with `next@pages/turbopack`. + +## 4. Use it on a page + +```tsx +import { FileManagerIcon } from '@/ui/file-manager/svg-sprite' + +export default function FilesPage() { + return +} + +export function getServerSideProps() { + return { props: {} } +} +``` + +The component works the same way with SSR, SSG, and client-side navigation. Next.js emits a separate SVG asset with a content hash. + +## 5. Add SpriteViewer + +```tsx +import { SpriteViewer } from '@gromlab/svg-sprites/react' + +const sources = [ + () => import('@/ui/file-manager/svg-sprite/manifest'), +] + +export default function SpritesPage() { + return +} +``` + +## Verify the bundler + +```bash +# Turbopack +npx next build --turbopack + +# Webpack 5 +npx next build --webpack +``` + +For Next 12–15 with Webpack, use `npx next build` without the flag. + +The Next.js command and the generator mode key must target the same bundler. diff --git a/skills/artifacts/svg-sprites-ru/references/docs/en/programmatic-api.md b/skills/artifacts/svg-sprites-ru/references/docs/en/programmatic-api.md new file mode 100644 index 0000000..7a4d44b --- /dev/null +++ b/skills/artifacts/svg-sprites-ru/references/docs/en/programmatic-api.md @@ -0,0 +1,203 @@ +# Programmatic API + +[← Back to home](../../README.md) + +The package provides a main Node.js entry point and a separate React runtime entry point. Both are distributed as ESM only and must be loaded with `import`. + +To resolve `@gromlab/svg-sprites/react` in TypeScript, use `moduleResolution: "bundler"`, `"node16"`, or `"nodenext"`. + +## Main entry point + +```ts +import { + defineNextSpriteConfig, + defineReactSpriteConfig, + generateNextSprite, + generateReactSprite, +} from '@gromlab/svg-sprites' +``` + +The main entry point does not import React and can be used in CLIs, build scripts, and Node.js tools. + +## `generateReactSprite` + +```ts +import { generateReactSprite } from '@gromlab/svg-sprites' + +const result = await generateReactSprite( + 'src/ui/file-manager/svg-sprite', + 'vite', +) +``` + +The second argument is required: + +```ts +type ReactAssetTarget = 'vite' | 'webpack' +``` + +Result: + +```ts +type ReactSpriteGenerationResult = { + name: string + rootDir: string + generatedDir: string + spritePath: string + manifestPath: string + iconCount: number + target: 'vite' | 'webpack' +} +``` + +```ts +console.log(result.name) +console.log(result.iconCount) +console.log(result.spritePath) +console.log(result.manifestPath) +``` + +The function loads `svg-sprite.config.ts` from the specified root, compiles the SVG files, and safely updates managed files. + +## `generateNextSprite` + +```ts +import { generateNextSprite } from '@gromlab/svg-sprites' + +const result = await generateNextSprite( + 'src/ui/file-manager/svg-sprite', + { + router: 'app', + bundler: 'turbopack', + }, +) +``` + +Available values: + +```ts +type NextSpriteGenerationOptions = { + router: 'app' | 'pages' + bundler: 'turbopack' | 'webpack' +} +``` + +The result also contains the selected `router`, `bundler`, and the full target in the form `next@app/turbopack`. + +## `defineReactSpriteConfig` + +```ts +import { defineReactSpriteConfig } from '@gromlab/svg-sprites' + +export default defineReactSpriteConfig({ + name: 'file-manager', + description: 'File manager icons', + inputFolder: './icons', + inputFiles: [ + '../../shared/icons/check.svg', + ], + transform: { + removeSize: true, + replaceColors: true, + addTransition: true, + }, + generatedNotice: true, +}) +``` + +`inputFolder` and `inputFiles` are combined. The helper returns the configuration without runtime transformations and provides TypeScript autocomplete. + +## `defineNextSpriteConfig` + +```ts +import { defineNextSpriteConfig } from '@gromlab/svg-sprites' + +export default defineNextSpriteConfig({ + name: 'file-manager', + description: 'File manager icons', + inputFolder: './icons', +}) +``` + +Next.js uses the same configuration contract as the React presets. + +## `generateLegacy` + +```ts +import { generateLegacy } from '@gromlab/svg-sprites' + +const results = await generateLegacy({ + output: 'public/sprites', + preview: false, + sprites: [ + { + name: 'icons', + input: 'src/assets/icons', + format: 'symbol', + }, + ], +}) +``` + +Returns an array: + +```ts +type SpriteResult = { + name: string + format: 'symbol' | 'stack' + spritePath: string + iconCount: number +} +``` + +For details, see [Legacy mode](legacy.md). + +## Low-level functions + +The main entry point also exports: + +```ts +import { + compileSprite, + compileSpriteContent, + createShapeTransform, + generatePreview, + loadLegacyConfig, + loadReactSpriteConfig, + resolveSpriteEntry, + resolveSprites, +} from '@gromlab/svg-sprites' +``` + +These functions are intended for custom orchestration built on top of the existing compiler and writer. For standard usage, prefer `generateReactSprite` and `generateLegacy`. + +## React runtime entry point + +```tsx +import { SpriteViewer } from '@gromlab/svg-sprites/react' +``` + +Types: + +```ts +import type { + SpriteManifest, + SpriteManifestColor, + SpriteManifestIcon, + SpriteManifestLoader, + SpriteManifestModule, + SpriteViewerColorTheme, + SpriteViewerProps, + SpriteViewerSource, + SpriteViewerSources, +} from '@gromlab/svg-sprites/react' +``` + +The React entry point contains `'use client'` and is intended for debug tools. Generated production components are imported from the application's local sprite modules, not from the package's React entry point. + +`SpriteViewerProps.colorTheme` accepts `auto | light | dark`. The default is `auto`, which follows `prefers-color-scheme`; to synchronize it with the application theme, pass the computed `light` or `dark` value. + +## Related guides + +- [React + Vite](react-vite.md) +- [React + Webpack 5](react-webpack.md) diff --git a/skills/artifacts/svg-sprites-ru/references/docs/en/react-vite.md b/skills/artifacts/svg-sprites-ru/references/docs/en/react-vite.md new file mode 100644 index 0000000..1e37cc4 --- /dev/null +++ b/skills/artifacts/svg-sprites-ru/references/docs/en/react-vite.md @@ -0,0 +1,116 @@ +# React + Vite + +[← Back to home](../../README.md) + +A quick guide to installing and using SVG sprites in a React and Vite project. + +The result is a typed React component and a separate cacheable SVG asset. + +## 1. Install the package + +```bash +npm install @gromlab/svg-sprites +``` + +## 2. Create the sprite directory + +```text +src/ui/file-manager/svg-sprite/ +β”œβ”€β”€ icons/ +β”‚ β”œβ”€β”€ check.svg +β”‚ └── folder.svg +└── svg-sprite.config.ts +``` + +Place the source SVG files in `icons/`. + +## 3. Add the configuration + +```ts +// src/ui/file-manager/svg-sprite/svg-sprite.config.ts +import { defineReactSpriteConfig } from '@gromlab/svg-sprites' + +export default defineReactSpriteConfig({ + name: 'file-manager', + description: 'File manager icons', +}) +``` + +By default, SVG files are loaded from `./icons`. You can add shared icons from other directories through `inputFiles`: the directory and file list are combined into a single sprite. + +The complete list of options is available under [Configuration β†’ React](../../README.md#react). + +## 4. Add generation to package.json + +```json +{ + "scripts": { + "sprite:file-manager": "svg-sprites --mode react@vite src/ui/file-manager/svg-sprite", + "predev": "npm run sprite:file-manager", + "prebuild": "npm run sprite:file-manager", + "pretypecheck": "npm run sprite:file-manager" + } +} +``` + +Generated files are excluded from Git, so generation must run before `dev`, `build`, and `typecheck`. + +First run: + +```bash +npm run sprite:file-manager +``` + +## 5. Use the component + +The name `file-manager` is converted to `FileManagerIcon`: + +```tsx +import { FileManagerIcon } from './svg-sprite' + +export const OpenFolderButton = () => ( + +) +``` + +TypeScript checks the `icon` value against the file names: + +```tsx + // valid + // TypeScript error +``` + +Types, display methods, and color controls are described in the [main documentation](../../README.md#display-methods). + +Vite emits the sprite as a separate file named like `assets/sprite-.svg`. SVG path data is not included in JavaScript. + +## 6. Add a debug page + +After integrating the icons, you can display all React sprites with `SpriteViewer`: + +```tsx +import { SpriteViewer } from '@gromlab/svg-sprites/react' +import type { SpriteManifestModule } from '@gromlab/svg-sprites/react' + +const sources = import.meta.glob( + '/src/**/svg-sprite/manifest.ts', +) + +export const IconsDebugPage = () => ( + +) +``` + +Vite automatically finds the generated `manifest.ts` for each React sprite. The `import.meta.glob` pattern must be a string literal, and generation must run before Vite starts. + +Only include the Viewer on a debug route or in an internal tool. + +## Troubleshooting + +- Missing `index.ts`: run `npm run sprite:file-manager`. +- The Viewer cannot find the sprite: check the glob path and make sure `manifest.ts` exists. +- `Refusing to overwrite a user file` error: there is a user file at a generated path. +- The icon does not change color: use `color` or `--icon-color-N`. diff --git a/skills/artifacts/svg-sprites-ru/references/docs/en/react-webpack.md b/skills/artifacts/svg-sprites-ru/references/docs/en/react-webpack.md new file mode 100644 index 0000000..15383db --- /dev/null +++ b/skills/artifacts/svg-sprites-ru/references/docs/en/react-webpack.md @@ -0,0 +1,118 @@ +# React + Webpack 5 + +[← Back to home](../../README.md) + +A quick guide to installing and using SVG sprites in a React and Webpack 5 project. + +The result is a typed React component and a separate SVG asset emitted through Webpack Asset Modules. + +## 1. Install the package + +```bash +npm install @gromlab/svg-sprites +``` + +## 2. Create the sprite directory + +```text +src/ui/file-manager/svg-sprite/ +β”œβ”€β”€ icons/ +β”‚ β”œβ”€β”€ check.svg +β”‚ └── folder.svg +└── svg-sprite.config.ts +``` + +Place the source SVG files in `icons/`. + +## 3. Add the configuration + +```ts +// src/ui/file-manager/svg-sprite/svg-sprite.config.ts +import { defineReactSpriteConfig } from '@gromlab/svg-sprites' + +export default defineReactSpriteConfig({ + name: 'file-manager', + description: 'File manager icons', +}) +``` + +By default, SVG files are loaded from `./icons`. You can add shared icons from other directories through `inputFiles`: the directory and file list are combined into a single sprite. + +The complete list of options is available under [Configuration β†’ React](../../README.md#react). + +## 4. Add generation to package.json + +```json +{ + "scripts": { + "sprite:file-manager": "svg-sprites --mode react@webpack src/ui/file-manager/svg-sprite", + "predev": "npm run sprite:file-manager", + "prebuild": "npm run sprite:file-manager", + "pretypecheck": "npm run sprite:file-manager" + } +} +``` + +Generated files are excluded from Git, so generation must run before `dev`, `build`, and `typecheck`. + +First run: + +```bash +npm run sprite:file-manager +``` + +## 5. Use the component + +```tsx +import { FileManagerIcon } from './svg-sprite' + +export const OpenFolderButton = () => ( + +) +``` + +TypeScript checks the `icon` value against the file names: + +```tsx + // valid + // TypeScript error +``` + +Types, display methods, and color controls are described in the [main documentation](../../README.md#display-methods). + +Webpack processes the generated `new URL('./sprite.svg', import.meta.url)` through Asset Modules and emits a separate SVG asset. + +If the project already uses a custom SVG loader, make sure it does not intercept the generated `sprite.svg` instead of Asset Modules. + +## 6. Add a debug page + +Webpack does not support Vite's `import.meta.glob` API, so provide static loaders: + +```tsx +import { SpriteViewer } from '@gromlab/svg-sprites/react' + +const sources = [ + () => import('./ui/file-manager/svg-sprite/manifest'), + () => import('./ui/navigation/svg-sprite/manifest'), +] + +export const IconsDebugPage = () => ( + +) +``` + +The paths in `import()` must be string literals. Webpack creates chunks for the manifests and associates them with the SVG assets. + +Only include the Viewer on a debug route or in an internal tool. + +## Troubleshooting + +- Missing `index.ts`: run `npm run sprite:file-manager`. +- The Viewer does not load the sprite: check the path in `import()` and make sure `manifest.ts` exists. +- Incorrect asset URL: check `output.publicPath`. +- Another loader intercepts the SVG: exclude the generated sprite from the incompatible rule. + +For Next.js, use the separate mode keys described in the [App Router](next-app.md) and [Pages Router](next-pages.md) guides. diff --git a/skills/artifacts/svg-sprites-ru/references/docs/ru/legacy.md b/skills/artifacts/svg-sprites-ru/references/docs/ru/legacy.md new file mode 100644 index 0000000..3d722b8 --- /dev/null +++ b/skills/artifacts/svg-sprites-ru/references/docs/ru/legacy.md @@ -0,0 +1,102 @@ +# Legacy mode + +[← Главная](../../README_RU.md) + +ΠšΡ€Π°Ρ‚ΠΊΠ°Ρ инструкция ΠΏΠΎ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹Ρ… SVG-спрайтов Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΎΠ² `symbol` ΠΈ `stack` с optional HTML preview. + +## 1. УстановитС ΠΏΠ°ΠΊΠ΅Ρ‚ + +```bash +npm install @gromlab/svg-sprites +``` + +## 2. ΠŸΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΡŒΡ‚Π΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ ΠΈ ΠΊΠΎΠ½Ρ„ΠΈΠ³ + +```text +project/ +β”œβ”€β”€ src/assets/icons/ +β”‚ β”œβ”€β”€ check.svg +β”‚ └── folder.svg +└── svg-sprites.config.ts +``` + +```ts +// svg-sprites.config.ts +import { defineLegacyConfig } from '@gromlab/svg-sprites' + +export default defineLegacyConfig({ + output: 'public/sprites', + preview: true, + sprites: [ + { + name: 'icons', + input: 'src/assets/icons', + format: 'symbol', + }, + ], +}) +``` + +## 3. ЗапуститС Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ + +```bash +npx svg-sprites --mode legacy . +``` + +Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚: + +```text +public/sprites/ +β”œβ”€β”€ icons.sprite.svg +└── preview.html +``` + +ΠŸΡ€ΠΈ `preview: false` HTML-Ρ„Π°ΠΉΠ» Π½Π΅ создаётся. Для Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° `stack` ΡƒΠΊΠ°ΠΆΠΈΡ‚Π΅ `format: 'stack'`. + +## 4. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ symbol-спрайт + +```html + + + +``` + +## 5. Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ package script + +```json +{ + "scripts": { + "sprites": "svg-sprites --mode legacy .", + "prebuild": "npm run sprites" + } +} +``` + +## НСсколько спрайтов + +Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ нСсколько записСй Π² `sprites`: + +```ts +sprites: [ + { + name: 'icons', + input: 'src/assets/icons', + format: 'symbol', + }, + { + name: 'logos', + input: 'src/assets/logos', + format: 'stack', + }, +] +``` + +ВсС Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ ΠΈ ΠΎΠ±Ρ‰ΠΈΠΉ `preview.html` Π±ΡƒΠ΄ΡƒΡ‚ записаны Π² `output`. + +## Если Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ + +- НС Π½Π°ΠΉΠ΄Π΅Π½ ΠΊΠΎΠ½Ρ„ΠΈΠ³: ΡƒΠ±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ `svg-sprites.config.ts` находится Π² ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΠΎΠΌ ΠΊΠΎΡ€Π½Π΅. +- НСт ΠΈΠΊΠΎΠ½ΠΎΠΊ: ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ `sprites[].input` ΠΈ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ `.svg`. +- НС Π½ΡƒΠΆΠ΅Π½ preview: установитС `preview: false`. + +Для ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ запуска ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ [`generateLegacy`](programmatic-api.md#generatelegacy). diff --git a/skills/artifacts/svg-sprites-ru/references/docs/ru/migration-1.md b/skills/artifacts/svg-sprites-ru/references/docs/ru/migration-1.md new file mode 100644 index 0000000..39b15d8 --- /dev/null +++ b/skills/artifacts/svg-sprites-ru/references/docs/ru/migration-1.md @@ -0,0 +1,96 @@ +# ΠœΠΈΠ³Ρ€Π°Ρ†ΠΈΡ с 0.1.x Π½Π° 1.0 + +[← Главная](../../README_RU.md) + +ВСрсия 1.0 раздСляСт Π»ΠΎΠΊΠ°Π»ΡŒΠ½ΡƒΡŽ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ для React ΠΈ Next.js ΠΈ Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ legacy-Ρ€Π΅ΠΆΠΈΠΌ. Π‘Ρ‚Π°Ρ€Ρ‹ΠΉ config нСльзя ΡΠΌΠ΅ΡˆΠΈΠ²Π°Ρ‚ΡŒ с Π½ΠΎΠ²Ρ‹ΠΌ API Π² ΠΎΠ΄Π½ΠΎΠΌ Π²Ρ‹Π·ΠΎΠ²Π΅ CLI. + +## CLI + +CLI Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ всСгда Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ явный `--mode` ΠΈ ΠΏΡƒΡ‚ΡŒ ΠΊ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Ρƒ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ: + +```text +svg-sprites +β†’ svg-sprites --mode +``` + +Π’Ρ‹Π±Π΅Ρ€ΠΈΡ‚Π΅ mode ΠΏΠΎ ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΡŽ: + +| ΠžΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠ΅ | Mode | +|---|---| +| React + Vite | `react@vite` | +| React + Webpack 5 | `react@webpack` | +| Next.js App Router + Turbopack | `next@app/turbopack` | +| Next.js App Router + Webpack 5 | `next@app/webpack` | +| Next.js Pages Router + Turbopack | `next@pages/turbopack` | +| Next.js Pages Router + Webpack 5 | `next@pages/webpack` | +| ЦСнтрализованная старая схСма | `legacy` | + +## React ΠΈ Next.js + +ВмСсто ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ `svg-sprites.config.ts` создайтС Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ `svg-sprite.config.ts` рядом с Π½Π°Π±ΠΎΡ€ΠΎΠΌ ΠΈΠΊΠΎΠ½ΠΎΠΊ: + +```ts +import { defineNextSpriteConfig } from '@gromlab/svg-sprites' + +export default defineNextSpriteConfig({ + name: 'global', + inputFolder: './icons', +}) +``` + +Для ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠ³ΠΎ React ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ `defineReactSpriteConfig`. ΠŸΠ°ΠΏΠΊΡƒ ΠΈ явный список ΠΎΠ±Ρ‰ΠΈΡ… SVG ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· `inputFolder` ΠΈ `inputFiles`. + +Π‘Ρ‚Π°Ρ€Ρ‹Π΅ `publicPath` ΠΈ `react` большС Π½Π΅ Π½ΡƒΠΆΠ½Ρ‹. Generated-ΠΌΠΎΠ΄ΡƒΠ»ΡŒ создаётся рядом с ΠΊΠΎΠ½Ρ„ΠΈΠ³ΠΎΠΌ, сам добавляСт `.gitignore`, Π° Vite, Webpack ΠΈΠ»ΠΈ Next.js выпускаСт SVG ΠΊΠ°ΠΊ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ asset с content hash. + +ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ `` замСняСтся ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠΌ, имя ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ выводится ΠΈΠ· `name`: + +```tsx + +``` + +Для просмотра ΠΈΠΊΠΎΠ½ΠΎΠΊ Π΄ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ `` ΠΊΠ°ΠΊ debug-страницу прилоТСния. ΠžΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ `preview.html` остаётся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² legacy-Ρ€Π΅ΠΆΠΈΠΌΠ΅. + +## Legacy-Ρ€Π΅ΠΆΠΈΠΌ + +Если Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΡƒΡŽ структуру Π½ΡƒΠΆΠ½ΠΎ ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ, ΠΏΠ΅Ρ€Π΅ΠΈΠΌΠ΅Π½ΡƒΠΉΡ‚Π΅ helper ΠΈ поля Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π°: + +```ts +import { defineLegacyConfig } from '@gromlab/svg-sprites' + +export default defineLegacyConfig({ + output: 'public/sprites', + preview: true, + sprites: [ + { + name: 'icons', + input: 'src/assets/icons', + format: 'stack', + }, + ], +}) +``` + +- `defineConfig` Π·Π°ΠΌΠ΅Π½Ρ‘Π½ Π½Π° `defineLegacyConfig`; +- `sprites[].mode` ΠΏΠ΅Ρ€Π΅ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ Π² `sprites[].format`; +- `generate` Π·Π°ΠΌΠ΅Π½Ρ‘Π½ Π½Π° `generateLegacy`; +- `loadConfig` Π·Π°ΠΌΠ΅Π½Ρ‘Π½ Π½Π° `loadLegacyConfig`; +- `publicPath` ΠΈ гСнСрация старого ΠΎΠ±Ρ‰Π΅Π³ΠΎ React-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° ΡƒΠ΄Π°Π»Π΅Π½Ρ‹. + +Запуск: + +```bash +svg-sprites --mode legacy . +``` + +## ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ API + +ΠŸΠ°ΠΊΠ΅Ρ‚ распространяСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊΠ°ΠΊ ESM. Π—Π°ΠΌΠ΅Π½ΠΈΡ‚Π΅ `require()` Π½Π° `import`. + +`compileSpriteContent` Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ `Promise`, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹Π΅ Π΄Π΅ΠΊΠ»Π°Ρ€Π°Ρ†ΠΈΠΈ Π½Π΅ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π»ΠΈ установки `@types/node`. Π’ Node.js фактичСский Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ совмСстим с API, ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰ΠΈΠΌΠΈ `Uint8Array`. + +## ПослС ΠΌΠΈΠ³Ρ€Π°Ρ†ΠΈΠΈ + +1. Π£Π΄Π°Π»ΠΈΡ‚Π΅ старыС generated-Ρ„Π°ΠΉΠ»Ρ‹ ΠΈ ΠΏΡ€Π°Π²ΠΈΠ»Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Π»ΠΈ Ρ†Π΅Π»ΠΈΠΊΠΎΠΌ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ с исходными ΠΈΠΊΠΎΠ½ΠΊΠ°ΠΌΠΈ. +2. Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ ΡΠ²Π½ΡƒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ ΠΏΠ΅Ρ€Π΅Π΄ `dev`, `build` ΠΈ `typecheck`. +3. ЗапуститС Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ Ρ‚ΠΈΠΏΠΎΠ². +4. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ всС ΠΈΠΊΠΎΠ½ΠΊΠΈ ΠΈ Ρ†Π²Π΅Ρ‚ΠΎΠ²Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ Ρ‡Π΅Ρ€Π΅Π· `SpriteViewer` ΠΈΠ»ΠΈ legacy `preview.html`. diff --git a/skills/artifacts/svg-sprites-ru/references/docs/ru/next-app.md b/skills/artifacts/svg-sprites-ru/references/docs/ru/next-app.md new file mode 100644 index 0000000..06049c6 --- /dev/null +++ b/skills/artifacts/svg-sprites-ru/references/docs/ru/next-app.md @@ -0,0 +1,102 @@ +# Next.js App Router + +[← Главная](../../README_RU.md) + +ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ Π΄Π²Π° явных Ρ€Π΅ΠΆΠΈΠΌΠ°: + +| Π‘Π±ΠΎΡ€Ρ‰ΠΈΠΊ | Mode key | ВСрсия Next.js | +|---|---|---| +| Turbopack | `next@app/turbopack` | 16.2+ | +| Webpack 5 | `next@app/webpack` | 13.4+ | + +## 1. УстановитС ΠΏΠ°ΠΊΠ΅Ρ‚ + +```bash +npm install @gromlab/svg-sprites +``` + +## 2. Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ sprite-ΠΌΠΎΠ΄ΡƒΠ»ΡŒ + +```text +src/ui/file-manager/svg-sprite/ +β”œβ”€β”€ icons/ +β”‚ β”œβ”€β”€ check.svg +β”‚ └── folder.svg +└── svg-sprite.config.ts +``` + +```ts +// src/ui/file-manager/svg-sprite/svg-sprite.config.ts +import { defineNextSpriteConfig } from '@gromlab/svg-sprites' + +export default defineNextSpriteConfig({ + name: 'file-manager', + description: 'Иконки Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠ³ΠΎ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Π°', +}) +``` + +## 3. Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ + +Для Turbopack: + +```json +{ + "scripts": { + "sprite:file-manager": "svg-sprites --mode next@app/turbopack src/ui/file-manager/svg-sprite", + "predev": "npm run sprite:file-manager", + "prebuild": "npm run sprite:file-manager" + } +} +``` + +Для Webpack Π·Π°ΠΌΠ΅Π½ΠΈΡ‚Π΅ mode key Π½Π° `next@app/webpack`. Π’ Next 13–15 Webpack ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠΉ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ `next build`, Π² Next 16 β€” ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ `next build --webpack`. + +## 4. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ Π² Server Component + +Generated-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Π½Π΅ содСрТит `'use client'`, поэтому Π΅Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ нСпосрСдствСнно Π² `page.tsx` ΠΈΠ»ΠΈ `layout.tsx`: + +```tsx +import { FileManagerIcon } from '@/ui/file-manager/svg-sprite' + +export default function Page() { + return ( +
+ +
+ ) +} +``` + +Next.js выпустит ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ SVG asset с content hash. Один generated-ΠΊΠΎΠ΄ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΏΡ€ΠΈ SSR ΠΈ Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π΅ Π±Π΅Π· расхоТдСния URL. + +## 5. Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ SpriteViewer + +Viewer ΠΈΠ½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π΅Π½, поэтому для Π½Π΅Π³ΠΎ Π½ΡƒΠΆΠ½Π° ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Π°Ρ Client Component Π³Ρ€Π°Π½ΠΈΡ†Π°: + +```tsx +'use client' + +import { SpriteViewer } from '@gromlab/svg-sprites/react' + +const sources = [ + () => import('@/ui/file-manager/svg-sprite/manifest'), +] + +export default function SpritesPage() { + return +} +``` + +## ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° сборщика + +```bash +# Turbopack +npx next build --turbopack + +# Webpack 5 +npx next build --webpack +``` + +Для Next 13–15 с Webpack ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ `npx next build` Π±Π΅Π· Ρ„Π»Π°Π³Π°. + +Команда Next.js ΠΈ mode key Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½ ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅ сборщик. diff --git a/skills/artifacts/svg-sprites-ru/references/docs/ru/next-pages.md b/skills/artifacts/svg-sprites-ru/references/docs/ru/next-pages.md new file mode 100644 index 0000000..926f0ef --- /dev/null +++ b/skills/artifacts/svg-sprites-ru/references/docs/ru/next-pages.md @@ -0,0 +1,96 @@ +# Next.js Pages Router + +[← Главная](../../README_RU.md) + +ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ Π΄Π²Π° явных Ρ€Π΅ΠΆΠΈΠΌΠ°: + +| Π‘Π±ΠΎΡ€Ρ‰ΠΈΠΊ | Mode key | ВСрсия Next.js | +|---|---|---| +| Turbopack | `next@pages/turbopack` | 16.2+ | +| Webpack 5 | `next@pages/webpack` | 12.2+ | + +Для Next.js 12.2 трСбуСтся React 18. + +## 1. УстановитС ΠΏΠ°ΠΊΠ΅Ρ‚ + +```bash +npm install @gromlab/svg-sprites +``` + +## 2. Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ sprite-ΠΌΠΎΠ΄ΡƒΠ»ΡŒ + +```text +src/ui/file-manager/svg-sprite/ +β”œβ”€β”€ icons/ +β”‚ β”œβ”€β”€ check.svg +β”‚ └── folder.svg +└── svg-sprite.config.ts +``` + +```ts +// src/ui/file-manager/svg-sprite/svg-sprite.config.ts +import { defineNextSpriteConfig } from '@gromlab/svg-sprites' + +export default defineNextSpriteConfig({ + name: 'file-manager', + description: 'Иконки Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠ³ΠΎ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Π°', +}) +``` + +## 3. Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ + +```json +{ + "scripts": { + "sprite:file-manager": "svg-sprites --mode next@pages/webpack src/ui/file-manager/svg-sprite", + "predev": "npm run sprite:file-manager", + "prebuild": "npm run sprite:file-manager" + } +} +``` + +Для Next.js 16.2 с Turbopack Π·Π°ΠΌΠ΅Π½ΠΈΡ‚Π΅ mode key Π½Π° `next@pages/turbopack`. + +## 4. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ Π½Π° страницС + +```tsx +import { FileManagerIcon } from '@/ui/file-manager/svg-sprite' + +export default function FilesPage() { + return +} + +export function getServerSideProps() { + return { props: {} } +} +``` + +ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΏΡ€ΠΈ SSR, SSG ΠΈ клиСнтских ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄Π°Ρ…. Next.js выпускаСт ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ SVG asset с content hash. + +## 5. Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ SpriteViewer + +```tsx +import { SpriteViewer } from '@gromlab/svg-sprites/react' + +const sources = [ + () => import('@/ui/file-manager/svg-sprite/manifest'), +] + +export default function SpritesPage() { + return +} +``` + +## ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° сборщика + +```bash +# Turbopack +npx next build --turbopack + +# Webpack 5 +npx next build --webpack +``` + +Для Next 12–15 с Webpack ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ `npx next build` Π±Π΅Π· Ρ„Π»Π°Π³Π°. + +Команда Next.js ΠΈ mode key Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½ ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅ сборщик. diff --git a/skills/artifacts/svg-sprites-ru/references/docs/ru/programmatic-api.md b/skills/artifacts/svg-sprites-ru/references/docs/ru/programmatic-api.md new file mode 100644 index 0000000..999cd01 --- /dev/null +++ b/skills/artifacts/svg-sprites-ru/references/docs/ru/programmatic-api.md @@ -0,0 +1,203 @@ +# ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ API + +[← Главная](../../README_RU.md) + +ΠŸΠ°ΠΊΠ΅Ρ‚ прСдоставляСт ΠΎΡΠ½ΠΎΠ²Π½ΡƒΡŽ Node.js Ρ‚ΠΎΡ‡ΠΊΡƒ Π²Ρ…ΠΎΠ΄Π° ΠΈ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ React runtime entry. ОбС Ρ‚ΠΎΡ‡ΠΊΠΈ Ρ€Π°ΡΠΏΡ€ΠΎΡΡ‚Ρ€Π°Π½ΡΡŽΡ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊΠ°ΠΊ ESM ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‚ΡΡ Ρ‡Π΅Ρ€Π΅Π· `import`. + +Для Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ `@gromlab/svg-sprites/react` Π² TypeScript ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ `moduleResolution: "bundler"`, `"node16"` ΠΈΠ»ΠΈ `"nodenext"`. + +## Основной entry + +```ts +import { + defineNextSpriteConfig, + defineReactSpriteConfig, + generateNextSprite, + generateReactSprite, +} from '@gromlab/svg-sprites' +``` + +Основной entry Π½Π΅ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ React ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π² CLI, build scripts ΠΈ Node.js инструмСнтах. + +## `generateReactSprite` + +```ts +import { generateReactSprite } from '@gromlab/svg-sprites' + +const result = await generateReactSprite( + 'src/ui/file-manager/svg-sprite', + 'vite', +) +``` + +Π’Ρ‚ΠΎΡ€ΠΎΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ обязатСлСн: + +```ts +type ReactAssetTarget = 'vite' | 'webpack' +``` + +Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚: + +```ts +type ReactSpriteGenerationResult = { + name: string + rootDir: string + generatedDir: string + spritePath: string + manifestPath: string + iconCount: number + target: 'vite' | 'webpack' +} +``` + +```ts +console.log(result.name) +console.log(result.iconCount) +console.log(result.spritePath) +console.log(result.manifestPath) +``` + +Ѐункция Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ `svg-sprite.config.ts` ΠΈΠ· ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ корня, ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΠ΅Ρ‚ SVG ΠΈ бСзопасно обновляСт managed-Ρ„Π°ΠΉΠ»Ρ‹. + +## `generateNextSprite` + +```ts +import { generateNextSprite } from '@gromlab/svg-sprites' + +const result = await generateNextSprite( + 'src/ui/file-manager/svg-sprite', + { + router: 'app', + bundler: 'turbopack', + }, +) +``` + +ДоступныС значСния: + +```ts +type NextSpriteGenerationOptions = { + router: 'app' | 'pages' + bundler: 'turbopack' | 'webpack' +} +``` + +Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ содСрТит Π²Ρ‹Π±Ρ€Π°Π½Π½Ρ‹Π΅ `router`, `bundler` ΠΈ ΠΏΠΎΠ»Π½Ρ‹ΠΉ target Π²ΠΈΠ΄Π° `next@app/turbopack`. + +## `defineReactSpriteConfig` + +```ts +import { defineReactSpriteConfig } from '@gromlab/svg-sprites' + +export default defineReactSpriteConfig({ + name: 'file-manager', + description: 'Иконки Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠ³ΠΎ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Π°', + inputFolder: './icons', + inputFiles: [ + '../../shared/icons/check.svg', + ], + transform: { + removeSize: true, + replaceColors: true, + addTransition: true, + }, + generatedNotice: true, +}) +``` + +`inputFolder` ΠΈ `inputFiles` ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‚ΡΡ. Π₯Π΅Π»ΠΏΠ΅Ρ€ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΊΠΎΠ½Ρ„ΠΈΠ³ Π±Π΅Π· runtime-ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠΉ ΠΈ прСдоставляСт TypeScript autocomplete. + +## `defineNextSpriteConfig` + +```ts +import { defineNextSpriteConfig } from '@gromlab/svg-sprites' + +export default defineNextSpriteConfig({ + name: 'file-manager', + description: 'Иконки Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠ³ΠΎ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Π°', + inputFolder: './icons', +}) +``` + +Next.js ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Ρ‚ΠΎΡ‚ ΠΆΠ΅ ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ, Ρ‡Ρ‚ΠΎ ΠΈ React presets. + +## `generateLegacy` + +```ts +import { generateLegacy } from '@gromlab/svg-sprites' + +const results = await generateLegacy({ + output: 'public/sprites', + preview: false, + sprites: [ + { + name: 'icons', + input: 'src/assets/icons', + format: 'symbol', + }, + ], +}) +``` + +ВозвращаСтся массив: + +```ts +type SpriteResult = { + name: string + format: 'symbol' | 'stack' + spritePath: string + iconCount: number +} +``` + +ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅: [Legacy mode](legacy.md). + +## НизкоуровнСвыС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ + +Основная Ρ‚ΠΎΡ‡ΠΊΠ° Π²Ρ…ΠΎΠ΄Π° Ρ‚Π°ΠΊΠΆΠ΅ экспортируСт: + +```ts +import { + compileSprite, + compileSpriteContent, + createShapeTransform, + generatePreview, + loadLegacyConfig, + loadReactSpriteConfig, + resolveSpriteEntry, + resolveSprites, +} from '@gromlab/svg-sprites' +``` + +Π­Ρ‚ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Ρ‹ для собствСнного orchestration ΠΏΠΎΠ²Π΅Ρ€Ρ… ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ compiler ΠΈ writer. Для стандартного использования ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡Ρ‚ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ `generateReactSprite` ΠΈ `generateLegacy`. + +## React runtime entry + +```tsx +import { SpriteViewer } from '@gromlab/svg-sprites/react' +``` + +Π’ΠΈΠΏΡ‹: + +```ts +import type { + SpriteManifest, + SpriteManifestColor, + SpriteManifestIcon, + SpriteManifestLoader, + SpriteManifestModule, + SpriteViewerColorTheme, + SpriteViewerProps, + SpriteViewerSource, + SpriteViewerSources, +} from '@gromlab/svg-sprites/react' +``` + +React entry содСрТит `'use client'` ΠΈ ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ для debug-инструмСнтов. Generated production-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΈΠ· Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Ρ… sprite-ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ прилоТСния, Π° Π½Π΅ ΠΈΠ· React entry ΠΏΠ°ΠΊΠ΅Ρ‚Π°. + +`SpriteViewerProps.colorTheme` ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ `auto | light | dark`. Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ `auto` ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΈ слСдуСт `prefers-color-scheme`; для синхронизации с Ρ‚Π΅ΠΌΠΎΠΉ прилоТСния ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°ΠΉΡ‚Π΅ вычислСнноС `light` ΠΈΠ»ΠΈ `dark`. + +## БвязанныС руководства + +- [React + Vite](react-vite.md) +- [React + Webpack 5](react-webpack.md) diff --git a/skills/artifacts/svg-sprites-ru/references/docs/ru/react-vite.md b/skills/artifacts/svg-sprites-ru/references/docs/ru/react-vite.md new file mode 100644 index 0000000..2ae3b39 --- /dev/null +++ b/skills/artifacts/svg-sprites-ru/references/docs/ru/react-vite.md @@ -0,0 +1,116 @@ +# React + Vite + +[← Главная](../../README_RU.md) + +ΠšΡ€Π°Ρ‚ΠΊΠ°Ρ инструкция ΠΏΠΎ установкС ΠΈ использованию SVG-спрайтов Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅ Π½Π° React ΠΈ Vite. + +Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ Π²Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ React-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΈ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΊΠ΅ΡˆΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΉ SVG asset. + +## 1. УстановитС ΠΏΠ°ΠΊΠ΅Ρ‚ + +```bash +npm install @gromlab/svg-sprites +``` + +## 2. Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ ΠΏΠ°ΠΏΠΊΡƒ спрайта + +```text +src/ui/file-manager/svg-sprite/ +β”œβ”€β”€ icons/ +β”‚ β”œβ”€β”€ check.svg +β”‚ └── folder.svg +└── svg-sprite.config.ts +``` + +ΠŸΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚Π΅ исходныС SVG-Ρ„Π°ΠΉΠ»Ρ‹ Π² `icons/`. + +## 3. Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ ΠΊΠΎΠ½Ρ„ΠΈΠ³ + +```ts +// src/ui/file-manager/svg-sprite/svg-sprite.config.ts +import { defineReactSpriteConfig } from '@gromlab/svg-sprites' + +export default defineReactSpriteConfig({ + name: 'file-manager', + description: 'Иконки Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠ³ΠΎ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Π°', +}) +``` + +По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ SVG бСрутся ΠΈΠ· `./icons`. ΠžΠ±Ρ‰ΠΈΠ΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΏΠ°ΠΏΠΎΠΊ ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· `inputFiles`: ΠΏΠ°ΠΏΠΊΠ° ΠΈ список ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‚ΡΡ Π² ΠΎΠ΄ΠΈΠ½ спрайт. + +ΠŸΠΎΠ»Π½Ρ‹ΠΉ список ΠΎΠΏΡ†ΠΈΠΉ находится Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ [ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ β†’ React](../../README_RU.md#react). + +## 4. Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ Π² package.json + +```json +{ + "scripts": { + "sprite:file-manager": "svg-sprites --mode react@vite src/ui/file-manager/svg-sprite", + "predev": "npm run sprite:file-manager", + "prebuild": "npm run sprite:file-manager", + "pretypecheck": "npm run sprite:file-manager" + } +} +``` + +Generated-Ρ„Π°ΠΉΠ»Ρ‹ ΠΈΡΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‚ΡΡ ΠΈΠ· Git, поэтому гСнСрация Π΄ΠΎΠ»ΠΆΠ½Π° Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ ΠΏΠ΅Ρ€Π΅Π΄ `dev`, `build` ΠΈ `typecheck`. + +ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ запуск: + +```bash +npm run sprite:file-manager +``` + +## 5. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ + +Имя `file-manager` прСобразуСтся Π² `FileManagerIcon`: + +```tsx +import { FileManagerIcon } from './svg-sprite' + +export const OpenFolderButton = () => ( + +) +``` + +Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ `icon` провСряСтся TypeScript ΠΏΠΎ ΠΈΠΌΠ΅Π½Π°ΠΌ Ρ„Π°ΠΉΠ»ΠΎΠ²: + +```tsx + // допустимо + // ошибка TypeScript +``` + +Π’ΠΈΠΏΡ‹, способы отобраТСния ΠΈ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ†Π²Π΅Ρ‚Π°ΠΌΠΈ описаны Π² [основной Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ](../../README_RU.md#способы-отобраТСния). + +Vite выпустит спрайт ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ„Π°ΠΉΠ»ΠΎΠΌ Π²ΠΈΠ΄Π° `assets/sprite-.svg`. SVG path-Π΄Π°Π½Π½Ρ‹Π΅ Π½Π΅ ΠΏΠΎΠΏΠ°Π΄ΡƒΡ‚ Π² JavaScript. + +## 6. Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ debug-страницу + +ПослС ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΈΠΊΠΎΠ½ΠΎΠΊ ΠΌΠΎΠΆΠ½ΠΎ вывСсти всС React-спрайты Ρ‡Π΅Ρ€Π΅Π· `SpriteViewer`: + +```tsx +import { SpriteViewer } from '@gromlab/svg-sprites/react' +import type { SpriteManifestModule } from '@gromlab/svg-sprites/react' + +const sources = import.meta.glob( + '/src/**/svg-sprite/manifest.ts', +) + +export const IconsDebugPage = () => ( + +) +``` + +Vite автоматичСски Π½Π°ΠΉΠ΄Ρ‘Ρ‚ generated `manifest.ts` ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ React-спрайта. Π¨Π°Π±Π»ΠΎΠ½ `import.meta.glob` Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ строковым Π»ΠΈΡ‚Π΅Ρ€Π°Π»ΠΎΠΌ, Π° гСнСрация Π΄ΠΎΠ»ΠΆΠ½Π° Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒΡΡ Π΄ΠΎ запуска Vite. + +Π Π°Π·ΠΌΠ΅Ρ‰Π°ΠΉΡ‚Π΅ Viewer Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π° debug-ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π΅ ΠΈΠ»ΠΈ Π²ΠΎ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅ΠΌ инструмСнтС. + +## Если Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ + +- НСт `index.ts`: запуститС `npm run sprite:file-manager`. +- Viewer Π½Π΅ Π²ΠΈΠ΄ΠΈΡ‚ спрайт: ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ ΠΏΡƒΡ‚ΡŒ glob ΠΈ Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ `manifest.ts`. +- Ошибка `Refusing to overwrite a user file`: Π² generated-ΠΏΡƒΡ‚ΠΈ находится ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ Ρ„Π°ΠΉΠ». +- Иконка Π½Π΅ мСняСт Ρ†Π²Π΅Ρ‚: ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ `color` ΠΈΠ»ΠΈ `--icon-color-N`. diff --git a/skills/artifacts/svg-sprites-ru/references/docs/ru/react-webpack.md b/skills/artifacts/svg-sprites-ru/references/docs/ru/react-webpack.md new file mode 100644 index 0000000..2a3c015 --- /dev/null +++ b/skills/artifacts/svg-sprites-ru/references/docs/ru/react-webpack.md @@ -0,0 +1,118 @@ +# React + Webpack 5 + +[← Главная](../../README_RU.md) + +ΠšΡ€Π°Ρ‚ΠΊΠ°Ρ инструкция ΠΏΠΎ установкС ΠΈ использованию SVG-спрайтов Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅ Π½Π° React ΠΈ Webpack 5. + +Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ Π²Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ React-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΈ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ SVG asset Ρ‡Π΅Ρ€Π΅Π· Webpack Asset Modules. + +## 1. УстановитС ΠΏΠ°ΠΊΠ΅Ρ‚ + +```bash +npm install @gromlab/svg-sprites +``` + +## 2. Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ ΠΏΠ°ΠΏΠΊΡƒ спрайта + +```text +src/ui/file-manager/svg-sprite/ +β”œβ”€β”€ icons/ +β”‚ β”œβ”€β”€ check.svg +β”‚ └── folder.svg +└── svg-sprite.config.ts +``` + +ΠŸΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚Π΅ исходныС SVG-Ρ„Π°ΠΉΠ»Ρ‹ Π² `icons/`. + +## 3. Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ ΠΊΠΎΠ½Ρ„ΠΈΠ³ + +```ts +// src/ui/file-manager/svg-sprite/svg-sprite.config.ts +import { defineReactSpriteConfig } from '@gromlab/svg-sprites' + +export default defineReactSpriteConfig({ + name: 'file-manager', + description: 'Иконки Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠ³ΠΎ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Π°', +}) +``` + +По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ SVG бСрутся ΠΈΠ· `./icons`. ΠžΠ±Ρ‰ΠΈΠ΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΏΠ°ΠΏΠΎΠΊ ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· `inputFiles`: ΠΏΠ°ΠΏΠΊΠ° ΠΈ список ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‚ΡΡ Π² ΠΎΠ΄ΠΈΠ½ спрайт. + +ΠŸΠΎΠ»Π½Ρ‹ΠΉ список ΠΎΠΏΡ†ΠΈΠΉ находится Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ [ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ β†’ React](../../README_RU.md#react). + +## 4. Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ Π² package.json + +```json +{ + "scripts": { + "sprite:file-manager": "svg-sprites --mode react@webpack src/ui/file-manager/svg-sprite", + "predev": "npm run sprite:file-manager", + "prebuild": "npm run sprite:file-manager", + "pretypecheck": "npm run sprite:file-manager" + } +} +``` + +Generated-Ρ„Π°ΠΉΠ»Ρ‹ ΠΈΡΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‚ΡΡ ΠΈΠ· Git, поэтому гСнСрация Π΄ΠΎΠ»ΠΆΠ½Π° Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ ΠΏΠ΅Ρ€Π΅Π΄ `dev`, `build` ΠΈ `typecheck`. + +ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ запуск: + +```bash +npm run sprite:file-manager +``` + +## 5. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ + +```tsx +import { FileManagerIcon } from './svg-sprite' + +export const OpenFolderButton = () => ( + +) +``` + +Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ `icon` провСряСтся TypeScript ΠΏΠΎ ΠΈΠΌΠ΅Π½Π°ΠΌ Ρ„Π°ΠΉΠ»ΠΎΠ²: + +```tsx + // допустимо + // ошибка TypeScript +``` + +Π’ΠΈΠΏΡ‹, способы отобраТСния ΠΈ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ†Π²Π΅Ρ‚Π°ΠΌΠΈ описаны Π² [основной Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ](../../README_RU.md#способы-отобраТСния). + +Webpack ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ generated `new URL('./sprite.svg', import.meta.url)` Ρ‡Π΅Ρ€Π΅Π· Asset Modules ΠΈ выпустит ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ SVG asset. + +Если ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ ΡƒΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ собствСнный SVG loader, ΡƒΠ±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ Π½Π΅ ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ generated `sprite.svg` вмСсто Asset Modules. + +## 6. Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ debug-страницу + +Webpack Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Vite API `import.meta.glob`, поэтому ΠΏΠ΅Ρ€Π΅Π΄Π°ΠΉΡ‚Π΅ статичСскиС loaders: + +```tsx +import { SpriteViewer } from '@gromlab/svg-sprites/react' + +const sources = [ + () => import('./ui/file-manager/svg-sprite/manifest'), + () => import('./ui/navigation/svg-sprite/manifest'), +] + +export const IconsDebugPage = () => ( + +) +``` + +ΠŸΡƒΡ‚ΠΈ Π² `import()` Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ строковыми Π»ΠΈΡ‚Π΅Ρ€Π°Π»Π°ΠΌΠΈ. Webpack создаст chunks для манифСстов ΠΈ свяТСт ΠΈΡ… с SVG assets. + +Π Π°Π·ΠΌΠ΅Ρ‰Π°ΠΉΡ‚Π΅ Viewer Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π° debug-ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π΅ ΠΈΠ»ΠΈ Π²ΠΎ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅ΠΌ инструмСнтС. + +## Если Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ + +- НСт `index.ts`: запуститС `npm run sprite:file-manager`. +- Viewer Π½Π΅ Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ спрайт: ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ ΠΏΡƒΡ‚ΡŒ Π² `import()` ΠΈ Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ `manifest.ts`. +- НСвСрный URL asset: ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ `output.publicPath`. +- SVG ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ Π΄Ρ€ΡƒΠ³ΠΎΠΉ loader: ΠΈΡΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅ generated sprite ΠΈΠ· нСсовмСстимого ΠΏΡ€Π°Π²ΠΈΠ»Π°. + +Для Next.js ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ mode key ΠΈΠ· руководств [App Router](next-app.md) ΠΈ [Pages Router](next-pages.md). diff --git a/skills/artifacts/svg-sprites/SKILL.md b/skills/artifacts/svg-sprites/SKILL.md index ffdecf1..b33bec8 100644 --- a/skills/artifacts/svg-sprites/SKILL.md +++ b/skills/artifacts/svg-sprites/SKILL.md @@ -1,64 +1,64 @@ --- name: svg-sprites -description: "Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ ΠΏΡ€ΠΈ настройкС, Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ, ΠΌΠΈΠ³Ρ€Π°Ρ†ΠΈΠΈ ΠΈΠ»ΠΈ диагностикС SVG-спрайтов Ρ‡Π΅Ρ€Π΅Π· @gromlab/svg-sprites. Π’Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹: SVG sprite, SVG-спрайт, svg-sprites, svg-sprite.config.ts, svg-sprites.config.ts, defineReactSpriteConfig, defineNextSpriteConfig, react@vite, react@webpack, next@app, next@pages, inputFiles, SpriteViewer, icon=\"...\", --icon-color-N, generated-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΈΠ»ΠΈ ΠΈΠΊΠΎΠ½ΠΊΠ° Π½Π΅ появилась Π² ΠΏΡ€Π΅Π²ΡŒΡŽ ΠΈ Π°Π²Ρ‚ΠΎΠ΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ. НЕ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ для favicon, растровых ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ, icon fonts, Π²Ρ‹Π±ΠΎΡ€Π° Π½Π°Π±ΠΎΡ€Π° ΠΈΠΊΠΎΠ½ΠΎΠΊ ΠΈΠ»ΠΈ inline SVG Π±Π΅Π· спрайтов." +description: "Use when configuring, generating, migrating, or troubleshooting SVG sprites with @gromlab/svg-sprites. Triggers: SVG sprite, svg-sprites, svg-sprite.config.ts, svg-sprites.config.ts, defineReactSpriteConfig, defineNextSpriteConfig, react@vite, react@webpack, next@app, next@pages, inputFiles, SpriteViewer, icon=\"...\", --icon-color-N, generated component, or an icon missing from preview or autocomplete. Do NOT use for favicons, raster images, icon fonts, choosing an icon set, or inline SVG without sprites." --- # SVG Sprites -## НазначСниС +## Purpose -Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ этот скил для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с `@gromlab/svg-sprites`: ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½ΠΎΠΉ настройки, добавлСния ΠΈ ΠΏΠ΅Ρ€Π΅ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΈΠΊΠΎΠ½ΠΎΠΊ, Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ React-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ², ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ `SpriteViewer`, ΠΌΠΈΠ³Ρ€Π°Ρ†ΠΈΠΈ legacy-ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ ΠΈ диагностики ошибок. +Use this skill when working with `@gromlab/svg-sprites`: initial setup, adding and reusing icons, generating React components, integrating `SpriteViewer`, migrating legacy configurations, and troubleshooting errors. -НС навязывай ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρƒ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΡƒΡŽ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Ρƒ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ΠΎΠ². Π‘Π½Π°Ρ‡Π°Π»Π° ΠΈΠ·ΡƒΡ‡ΠΈ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ `package.json`, ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ спрайта, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ, Ρ€ΠΎΡƒΡ‚Π΅Ρ€ ΠΈ сборщик. +Do not impose a specific directory architecture on the project. First inspect the existing `package.json`, sprite configuration, framework, router, and bundler. -## Π Π°Π±ΠΎΡ‡ΠΈΠΉ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ +## Workflow -1. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅ΠΆΠΈΠΌ ΠΈ Π½Π΅ смСшивай Π΅Π³ΠΎ API с Π΄Ρ€ΡƒΠ³ΠΈΠΌ Ρ€Π΅ΠΆΠΈΠΌΠΎΠΌ. -2. Для React Π²Ρ‹Π±Π΅Ρ€ΠΈ `react@vite` ΠΈΠ»ΠΈ `react@webpack` ΠΈ ΠΎΡ‚ΠΊΡ€ΠΎΠΉ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ reference. -3. Для Next.js ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈ App Router ΠΈΠ»ΠΈ Pages Router, Π·Π°Ρ‚Π΅ΠΌ Turbopack ΠΈΠ»ΠΈ Webpack, ΠΈ ΠΎΡ‚ΠΊΡ€ΠΎΠΉ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ reference. -4. Для ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ `svg-sprites.config.ts` с нСсколькими спрайтами ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ legacy-Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ. НС ΠΌΠΈΠ³Ρ€ΠΈΡ€ΡƒΠΉ Ρ‚Π°ΠΊΠΎΠΉ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ Π±Π΅Π· явного запроса. -5. Π˜Π·ΡƒΡ‡ΠΈ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ scripts ΠΈ добавляй Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ ΠΏΠ΅Ρ€Π΅Π΄ `dev`, `build` ΠΈ `typecheck`, Ссли generated-Ρ„Π°ΠΉΠ»Ρ‹ Π½Π΅ хранятся Π² Git. -6. ПослС измСнСния ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ ΠΈΠ»ΠΈ SVG запусти Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ, Π·Π°Ρ‚Π΅ΠΌ Π΄ΠΎΡΡ‚ΡƒΠΏΠ½ΡƒΡŽ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ Ρ‚ΠΈΠΏΠΎΠ² ΠΈΠ»ΠΈ сборку ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°. +1. Identify the existing mode and do not mix its API with another mode. +2. For React, choose `react@vite` or `react@webpack` and open the corresponding reference. +3. For Next.js, identify the App Router or Pages Router, then Turbopack or Webpack, and open the corresponding reference. +4. For an existing `svg-sprites.config.ts` with multiple sprites, use the legacy documentation. Do not migrate such a project unless explicitly requested. +5. Inspect local scripts and run generation before `dev`, `build`, and `typecheck` when generated files are not committed to Git. +6. After changing a configuration or SVG file, run generation followed by the available type check or project build. -## ΠŸΡ€Π°Π²ΠΈΠ»Π° React ΠΈ Next.js +## React And Next.js Rules -- Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ `svg-sprite.config.ts` ΠΈ подходящий config helper: `defineReactSpriteConfig` ΠΈΠ»ΠΈ `defineNextSpriteConfig`. -- НС Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΡƒΠΉ `generated/`, `index.ts`, `manifest.ts` ΠΈ созданный Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠΌ `.gitignore` Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ. -- ИмСна исходных SVG становятся допустимыми значСниями prop `icon`; ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ generated-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΈ Π΅Π³ΠΎ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ вмСсто deep imports. -- ОбъСдиняй Π»ΠΎΠΊΠ°Π»ΡŒΠ½ΡƒΡŽ ΠΏΠ°ΠΏΠΊΡƒ ΠΈ `inputFiles`, ΠΊΠΎΠ³Π΄Π° общая ΠΈΠΊΠΎΠ½ΠΊΠ° Π½ΡƒΠΆΠ½Π° нСскольким спрайтам. НС создавай ΠΊΠΎΠΏΠΈΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ SVG Π±Π΅Π· нСобходимости. -- Π’ Next.js generated-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² Server Components, SSR ΠΈ SSG. НС добавляй `'use client'` Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ€Π°Π΄ΠΈ ΠΈΠΊΠΎΠ½ΠΊΠΈ. -- Π‘ΠΏΡ€Π°ΠΉΡ‚ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΡΡ‚Π°Π²Π°Ρ‚ΡŒΡΡ внСшним asset сборщика: Π½Π΅ ΠΏΠ΅Ρ€Π΅Π½ΠΎΡΠΈΡ‚ΡŒ SVG path-Π΄Π°Π½Π½Ρ‹Π΅ Π² JavaScript ΠΈ Π½Π΅ ΠΊΠ»Π°ΡΡ‚ΡŒ generated-Ρ„Π°ΠΉΠ» Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ Π² `public`. +- Use a local `svg-sprite.config.ts` and the appropriate config helper: `defineReactSpriteConfig` or `defineNextSpriteConfig`. +- Do not manually edit `generated/`, `index.ts`, `manifest.ts`, or the generator-created `.gitignore`. +- Source SVG names become valid values for the `icon` prop; use the generated component and its public types instead of deep imports. +- Combine the local folder with `inputFiles` when multiple sprites need a shared icon. Do not create unnecessary copies of the same SVG. +- In Next.js, generated components work in Server Components, SSR, and SSG. Do not add `'use client'` only for an icon. +- Keep the sprite as an external bundler asset: do not move SVG path data into JavaScript or manually place the generated file in `public`. -## Π¦Π²Π΅Ρ‚Π° ΠΈ трансформации +## Colors And Transformations -- По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ удаляСт `width` ΠΈ `height`, замСняСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Π΅ `fill` ΠΈ `stroke` Π½Π° CSS-ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΈ добавляСт transitions. -- Для ΠΌΠΎΠ½ΠΎΡ…Ρ€ΠΎΠΌΠ½ΠΎΠΉ ΠΈΠΊΠΎΠ½ΠΊΠΈ сначала управляй `color`; для ΠΌΠ½ΠΎΠ³ΠΎΡ†Π²Π΅Ρ‚Π½ΠΎΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ `--icon-color-N`. -- НС ΠΎΠ±Π΅Ρ‰Π°ΠΉ Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΡ‡Π΅ΡΠΊΡƒΡŽ Π·Π°ΠΌΠ΅Π½Ρƒ Ρ†Π²Π΅Ρ‚ΠΎΠ² Π²Π½ΡƒΡ‚Ρ€ΠΈ Π²Π½Π΅ΡˆΠ½ΠΈΡ… stylesheets, gradients, patterns, filters ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ `url(#...)` Π±Π΅Π· ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°. -- CSS-ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ страницы Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ ΠΏΡ€ΠΈ ``, Π½ΠΎ Π½Π΅ ΠΏΡ€ΠΎΠ½ΠΈΠΊΠ°ΡŽΡ‚ Π²Π½ΡƒΡ‚Ρ€ΡŒ `` ΠΈ `background-image`. +- By default, the generator removes `width` and `height`, replaces supported `fill` and `stroke` values with CSS variables, and adds transitions. +- For a monochrome icon, control `color` first; for a multicolor icon, use `--icon-color-N`. +- Do not promise automatic color replacement inside external stylesheets, gradients, patterns, filters, or `url(#...)` values without checking the result. +- Page CSS variables work with ``, but do not propagate into `` or `background-image`. -## ΠŸΡ€Π΅Π²ΡŒΡŽ +## Preview -Для React ΠΈ Next.js ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°ΠΉ `` ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΉ debug-страницСй прилоТСния. ΠŸΠ΅Ρ€Π΅Π΄Π°ΠΉ Π΅ΠΌΡƒ manifests ΠΈΠ»ΠΈ lazy loaders спрайтов. Viewer ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ поиск, ΡΠ²Π΅Ρ‚Π»ΡƒΡŽ ΠΈ Ρ‚Ρ‘ΠΌΠ½ΡƒΡŽ Ρ‚Π΅ΠΌΡ‹, настройку Ρ†Π²Π΅Ρ‚ΠΎΠ² ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ React, SVG, IMG ΠΈ CSS. +For React and Next.js, add `` as a separate debug page in the application. Pass sprite manifests or lazy loaders to it. The Viewer supports search, light and dark themes, color controls, and React, SVG, IMG, and CSS examples. -`SpriteViewer` являСтся клиСнтским debug-инструмСнтом ΠΈ импортируСтся ΠΈΠ· `@gromlab/svg-sprites/react`; production-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ ΠΈΠΊΠΎΠ½ΠΎΠΊ ΠΎΡ‚ Π½Π΅Π³ΠΎ Π½Π΅ зависят. +`SpriteViewer` is a client-side debug tool imported from `@gromlab/svg-sprites/react`; production icon components do not depend on it. -## Диагностика +## Troubleshooting -- Если имя ΠΈΠΊΠΎΠ½ΠΊΠΈ отсутствуСт Π² Π°Π²Ρ‚ΠΎΠ΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒ Π²Ρ…ΠΎΠ΄Π½ΡƒΡŽ ΠΏΠ°ΠΏΠΊΡƒ ΠΈ `inputFiles`, Π·Π°Ρ‚Π΅ΠΌ пСрСзапусти Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ. -- Если Π΄Π²Π° Ρ„Π°ΠΉΠ»Π° ΠΈΠΌΠ΅ΡŽΡ‚ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΠΎΠ΅ имя ΠΈΠΊΠΎΠ½ΠΊΠΈ, устрани ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚ вмСсто Π²Ρ‹Π±ΠΎΡ€Π° ΠΎΠ΄Π½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π° нСявно. -- Если Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ отказываСтся ΠΏΠ΅Ρ€Π΅Π·Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ Ρ„Π°ΠΉΠ», Π½Π΅ удаляй Π·Π°Ρ‰ΠΈΡ‚Π½Ρ‹ΠΉ marker ΠΈ Π½Π΅ ΠΎΠ±Ρ…ΠΎΠ΄ΠΈ writer: пСрСнСси ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ Ρ„Π°ΠΉΠ» ΠΈΠ»ΠΈ Π²Ρ‹Π±Π΅Ρ€ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ спрайта. -- Если asset Π½Π΅ загруТаСтся, сначала ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒ соотвСтствиС CLI mode Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΌΡƒ сборщику ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ generated SVG Π΅Π³ΠΎ asset pipeline. -- Если ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ старый API, ΡΠ²Π΅Ρ€ΡŒ ΡƒΡΡ‚Π°Π½ΠΎΠ²Π»Π΅Π½Π½ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ ΠΏΠ°ΠΊΠ΅Ρ‚Π° ΠΈ legacy reference ΠΏΠ΅Ρ€Π΅Π΄ измСнСниями. +- If an icon name is missing from autocomplete, check the input folder and `inputFiles`, then rerun generation. +- If two files have the same icon name, resolve the conflict instead of implicitly selecting one file. +- If the generator refuses to overwrite a file, do not remove the protection marker or bypass the writer: move the user file or choose another sprite directory. +- If an asset fails to load, first confirm that the CLI mode matches the project's actual bundler and that its asset pipeline handles the generated SVG. +- If the project uses the old API, check the installed package version and the legacy reference before making changes. ## References -- [Основная докумСнтация ΠΈ API](./references/README.md) -- [React + Vite](./references/docs/ru/react-vite.md) -- [React + Webpack 5](./references/docs/ru/react-webpack.md) -- [Next.js App Router](./references/docs/ru/next-app.md) -- [Next.js Pages Router](./references/docs/ru/next-pages.md) -- [Legacy mode](./references/docs/ru/legacy.md) -- [ΠœΠΈΠ³Ρ€Π°Ρ†ΠΈΡ с 0.1.x](./references/docs/ru/migration-1.md) -- [ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ API](./references/docs/ru/programmatic-api.md) +- [Main documentation and API](./references/README.md) +- [React + Vite](./references/docs/en/react-vite.md) +- [React + Webpack 5](./references/docs/en/react-webpack.md) +- [Next.js App Router](./references/docs/en/next-app.md) +- [Next.js Pages Router](./references/docs/en/next-pages.md) +- [Legacy mode](./references/docs/en/legacy.md) +- [Migrating from 0.1.x](./references/docs/en/migration-1.md) +- [Programmatic API](./references/docs/en/programmatic-api.md) diff --git a/skills/artifacts/svg-sprites/references/README.md b/skills/artifacts/svg-sprites/references/README.md index 8242cc9..c23d2d0 100644 --- a/skills/artifacts/svg-sprites/references/README.md +++ b/skills/artifacts/svg-sprites/references/README.md @@ -1,77 +1,80 @@ # @gromlab/svg-sprites +πŸ‡¬πŸ‡§ English | [πŸ‡·πŸ‡Ί Русский](README_RU.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. +A CLI for generating SVG sprites and typed icon components for React and Next.js. -![Preview](https://gromlab.ru/gromov/svg-sprites/media/branch/master/preview-image.png) +![Preview](https://raw.githubusercontent.com/gromov-sergei/svg-sprites/master/preview-image.png) -## Навигация +## Navigation -- [ВозмоТности](#возмоТности) -- [Π’Π°Π±Π»ΠΈΡ†Π° ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ](#Ρ‚Π°Π±Π»ΠΈΡ†Π°-ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ) -- [ВрСбования](#трСбования) -- [Быстрый старт](#быстрый-старт) - - [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) -- [ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ](#конфигурация) +- [Features](#features) +- [Support matrix](#support-matrix) +- [Requirements](#requirements) +- [Quick start](#quick-start) + - [React + Vite](docs/en/react-vite.md) + - [React + Webpack 5](docs/en/react-webpack.md) + - [Next.js App Router](docs/en/next-app.md) + - [Next.js Pages Router](docs/en/next-pages.md) +- [Configuration](#configuration) - [React](#react) - [Next.js](#nextjs) -- [ΠœΠ½ΠΎΠΆΠ΅ΡΡ‚Π²Π΅Π½Π½Ρ‹Π΅ спрайты](#мноТСствСнныС-спрайты) +- [Multiple sprites](#multiple-sprites) - [TypeScript](#typescript) -- [Π€ΠΎΡ€ΠΌΠ°Ρ‚Ρ‹ спрайтов](#Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Ρ‹-спрайтов) -- [Бпособы отобраТСния](#способы-отобраТСния) -- [Врансформации](#трансформации) -- [Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ†Π²Π΅Ρ‚ΠΎΠΌ ΠΈΠΊΠΎΠ½ΠΎΠΊ](#ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅-Ρ†Π²Π΅Ρ‚ΠΎΠΌ-ΠΈΠΊΠΎΠ½ΠΎΠΊ) -- [ΠšΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅](#ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅) +- [Sprite formats](#sprite-formats) +- [Rendering methods](#rendering-methods) +- [Transformations](#transformations) +- [Icon color management](#icon-color-management) +- [Caching](#caching) - [SpriteViewer](#spriteviewer) -- [ΠœΠΈΠ³Ρ€Π°Ρ†ΠΈΡ с 0.1.x](docs/ru/migration-1.md) -- [ДокумСнтация](#докумСнтация) +- [Migrating from 0.1.x](docs/en/migration-1.md) +- [Documentation](#documentation) -## ВозмоТности +## Features -- **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` для ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΉ. +- **AI-agent friendly** - the repository includes a ready-to-use skill with up-to-date documentation for configuring, migrating, and troubleshooting `@gromlab/svg-sprites`. +- **TypeScript-friendly** - typed React components, union types, and runtime lists of available icons. +- **Clean generation** - generated files are automatically excluded from Git, the sprite does not need to be placed in `public` manually, and the generator updates only files it owns. +- **Shared icons without copying** - SVGs from the local folder and `inputFiles` are merged into a single sprite; one file can be used in multiple sprites. +- **Built-in interactive preview** - `` is integrated as an application page and displays the provided React and Next.js sprites with search, color controls, and usage examples. +- **Configurable SVG transformations** - remove `width` and `height` while preserving `viewBox`, replace source colors with CSS variables, and add transitions for `fill` and `stroke`. +- **Separate cacheable SVG asset** - SVG path data does not end up in JavaScript chunks, and the bundler emits a file with a content hash. +- **Multiple sprites** - independent React and Next.js modules with their own components, types, and SVG assets. +- **Server-first Next.js** - generated components work in Server Components, SSR, and SSG without the `'use client'` directive. +- **Formats for different use cases** - React and Next.js use `stack`; legacy mode also supports `symbol` for existing integrations. -## Π’Π°Π±Π»ΠΈΡ†Π° ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ +## Support matrix -| Π‘Ρ€Π΅Π΄Π° | ΠšΠ»ΡŽΡ‡ ΠΌΠΎΠ΄Π° API | Бтатус | +| Environment | API mode key | Status | |---|---|---| -| 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 | β€” | Π‘ΠΊΠΎΡ€ΠΎ | +| React + Vite | `react@vite` | Ready | +| React + Webpack 5 | `react@webpack` | Ready | +| Next.js 16.2+ App Router + Turbopack | `next@app/turbopack` | Ready | +| Next.js 13.4+ App Router + Webpack 5 | `next@app/webpack` | Ready | +| Next.js 16.2+ Pages Router + Turbopack | `next@pages/turbopack` | Ready | +| Next.js 12.2+ Pages Router + Webpack 5 | `next@pages/webpack` | Ready | +| Vue | - | Coming soon | +| Standalone | - | Coming soon | -## ВрСбования +## Requirements -- Node.js 18 ΠΈΠ»ΠΈ Π½ΠΎΠ²Π΅Π΅; -- ΠΏΠ°ΠΊΠ΅Ρ‚ распространяСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊΠ°ΠΊ ESM ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Ρ‡Π΅Ρ€Π΅Π· `import`; -- React 18 ΠΈΠ»ΠΈ 19 трСбуСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для generated-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² ΠΈ Ρ‚ΠΎΡ‡ΠΊΠΈ Π²Ρ…ΠΎΠ΄Π° `@gromlab/svg-sprites/react`; -- для Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΠΈ subpath exports ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ TypeScript 5+ с `moduleResolution: "bundler"`, `"node16"` ΠΈΠ»ΠΈ `"nodenext"`. +- Node.js 18 or newer; +- the package is distributed as ESM only and is loaded via `import`; +- React 18 or 19 is required only for generated components and the `@gromlab/svg-sprites/react` entry point; +- for subpath export typings, use TypeScript 5+ with `moduleResolution: "bundler"`, `"node16"`, or `"nodenext"`. -## Быстрый старт +## Quick start -Для быстрого старта Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ΡΡŒ инструкциСй для вашСго стСка: +For a quick start, follow the guide for your stack: -- [React + Vite](docs/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 + Vite](docs/en/react-vite.md) +- [React + Webpack 5](docs/en/react-webpack.md) +- [Next.js App Router](docs/en/next-app.md) +- [Next.js Pages Router](docs/en/next-pages.md) -## ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ +## Configuration ### React @@ -80,7 +83,7 @@ import { defineReactSpriteConfig } from '@gromlab/svg-sprites' export default defineReactSpriteConfig({ name: 'file-manager', - description: 'Иконки Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠ³ΠΎ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Π°', + description: 'File manager icons', inputFolder: './icons', inputFiles: [ '../../shared/icons/check.svg', @@ -94,78 +97,78 @@ export default defineReactSpriteConfig({ }) ``` -| ΠžΠΏΡ†ΠΈΡ | Π’ΠΈΠΏ | По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ | НазначСниС | +| Option | Type | Default | Purpose | |---|---|---|---| -| `name` | `string` | Имя ΠΏΠ°ΠΏΠΊΠΈ | Имя спрайта, ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° ΠΈ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² | -| `description` | `string` | НСт | ОписаниС для Ρ‚ΠΈΠΏΠΎΠ² ΠΈ debug-манифСста | -| `inputFolder` | `string` | `./icons` | Папка с исходными SVG ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΊΠΎΠ½Ρ„ΠΈΠ³Π° | -| `inputFiles` | `string[]` | `[]` | Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ SVG-Ρ„Π°ΠΉΠ»Ρ‹ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΊΠΎΠ½Ρ„ΠΈΠ³Π° | -| `transform` | `TransformOptions` | ВсС Π²ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ | [Настройки трансформации](#трансформации) исходных SVG | -| `generatedNotice` | `boolean` | `true` | ПолноС Π»ΠΈΠ±ΠΎ ΠΊΠΎΡ€ΠΎΡ‚ΠΊΠΎΠ΅ ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅ Π² generated-Ρ„Π°ΠΉΠ»Π°Ρ… | +| `name` | `string` | Folder name | Name of the sprite, component, and public types | +| `description` | `string` | None | Description for types and the debug manifest | +| `inputFolder` | `string` | `./icons` | Folder containing source SVGs, relative to the config | +| `inputFiles` | `string[]` | `[]` | Additional SVG files, relative to the config | +| `transform` | `TransformOptions` | All enabled | [Transformation settings](#transformations) for source SVGs | +| `generatedNotice` | `boolean` | `true` | Full or short warning in generated files | -`inputFolder` ΠΈ `inputFiles` ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‚ΡΡ Π² ΠΎΠ΄ΠΈΠ½ спрайт, поэтому ΠΎΠ΄ΠΈΠ½ SVG-Ρ„Π°ΠΉΠ» ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… спрайтах Π±Π΅Π· копирования. Если нСявной ΠΏΠ°ΠΏΠΊΠΈ `./icons` Π½Π΅Ρ‚, Π½ΠΎ `inputFiles` Π·Π°ΠΏΠΎΠ»Π½Π΅Π½, гСнСрация продолТаСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎ списку. Π―Π²Π½ΠΎ указанная ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π°Ρ ΠΏΠ°ΠΏΠΊΠ° считаСтся ошибкой. ΠžΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹Π΅ ΠΏΡƒΡ‚ΠΈ Π΄Π΅Π΄ΡƒΠΏΠ»ΠΈΡ†ΠΈΡ€ΡƒΡŽΡ‚ΡΡ, Π° Ρ€Π°Π·Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹ с ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹ΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ ΠΈΠΊΠΎΠ½ΠΊΠΈ ΡΡ‡ΠΈΡ‚Π°ΡŽΡ‚ΡΡ ошибкой. +`inputFolder` and `inputFiles` are merged into a single sprite, so one SVG file can be used in multiple sprites without copying. If the implicit `./icons` folder does not exist but `inputFiles` is populated, generation continues using only the list. An explicitly specified missing folder is an error. Duplicate paths are deduplicated, while different files with the same icon name are treated as an error. -`name` записываСтся Π² kebab-case ΠΈ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π½Π°Ρ‡ΠΈΠ½Π°Ρ‚ΡŒΡΡ с латинской Π±ΡƒΠΊΠ²Ρ‹. React ΠΈ Next.js presets ΡΠΎΠ·Π΄Π°ΡŽΡ‚ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ `stack`. +`name` is stored in kebab-case and must start with a Latin letter. The React and Next.js presets produce the `stack` format. ### Next.js -Next.js ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Ρ‚ΠΎΡ‚ ΠΆΠ΅ `svg-sprite.config.ts` ΠΈ Π½Π°Π±ΠΎΡ€ ΠΎΠΏΡ†ΠΈΠΉ. Для Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ Ρ…Π΅Π»ΠΏΠ΅Ρ€: +Next.js uses the same `svg-sprite.config.ts` and set of options. For type checking, you can use a dedicated helper: ```ts import { defineNextSpriteConfig } from '@gromlab/svg-sprites' export default defineNextSpriteConfig({ name: 'file-manager', - description: 'Иконки Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠ³ΠΎ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Π°', + description: 'File manager icons', inputFolder: './icons', }) ``` -Π ΠΎΡƒΡ‚Π΅Ρ€ ΠΈ сборщик Π²Ρ‹Π±ΠΈΡ€Π°ΡŽΡ‚ΡΡ Ρ‡Π΅Ρ€Π΅Π· mode key, поэтому ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΌΠ΅ΠΆΠ΄Ρƒ Turbopack ΠΈ Webpack всСгда явно ΠΎΡ‚Ρ€Π°ΠΆΠ΅Π½ΠΎ Π² ΠΊΠΎΠΌΠ°Π½Π΄Π΅ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ. +The router and bundler are selected through the mode key, so switching between Turbopack and Webpack is always explicitly reflected in the generation command. -## ΠœΠ½ΠΎΠΆΠ΅ΡΡ‚Π²Π΅Π½Π½Ρ‹Π΅ спрайты +## Multiple sprites -ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ нСсколько нСзависимых спрайтов с Ρ€Π°Π·Π½ΠΎΠΉ ΠΎΠ±Π»Π°ΡΡ‚ΡŒΡŽ использования: +An application can contain several independent sprites for different scopes: -**ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ°:** ΠΎΠ΄ΠΈΠ½ Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΉ спрайт Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ ΠΈΠΊΠΎΠ½ΠΊΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌΡƒ экрану Π½Π΅ Π½ΡƒΠΆΠ½Ρ‹. +**Problem:** one global sprite loads icons that the current screen does not need. -**РСшСниС:** ΠΎΠ±Ρ‰ΠΈΠ΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ глобально, Π° Π½Π°Π±ΠΎΡ€Ρ‹ страниц ΠΈ ΠΊΡ€ΡƒΠΏΠ½Ρ‹Ρ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² β€” Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… спрайтах, Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌΡ‹Ρ… вмСстС с Π½ΠΈΠΌΠΈ. +**Solution:** keep shared icons globally, and place icon sets for pages and large components in separate sprites that load alongside them. ```text -global β†’ GlobalIcon β†’ ΠΎΠ±Ρ‰ΠΈΠ΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ прилоТСния -analytics-page β†’ AnalyticsPageIcon β†’ ΠΈΠΊΠΎΠ½ΠΊΠΈ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΉ страницы -file-manager β†’ FileManagerIcon β†’ ΠΈΠΊΠΎΠ½ΠΊΠΈ ΠΊΡ€ΡƒΠΏΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° +global -> GlobalIcon -> shared application icons +analytics-page -> AnalyticsPageIcon -> icons for a specific page +file-manager -> FileManagerIcon -> icons for a large component ``` -- **Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΉ спрайт** содСрТит нСбольшиС ΠΎΠ±Ρ‰ΠΈΠ΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ Π² Ρ€Π°Π·Π½Ρ‹Ρ… частях прилоТСния: Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΡŽ, состояния ΠΈ Π±Π°Π·ΠΎΠ²Ρ‹Π΅ дСйствия. -- **Π‘ΠΏΡ€Π°ΠΉΡ‚ страницы** загруТаСтся вмСстС с ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹ΠΌ Ρ€Π°Π·Π΄Π΅Π»ΠΎΠΌ ΠΈ Π½Π΅ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚ ΠΎΠ±Ρ‰ΠΈΠΉ спрайт ΠΈΠΊΠΎΠ½ΠΊΠ°ΠΌΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ большС Π½ΠΈΠ³Π΄Π΅ Π½Π΅ Π½ΡƒΠΆΠ½Ρ‹. -- **Π‘ΠΏΡ€Π°ΠΉΡ‚ ΠΊΡ€ΡƒΠΏΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°** инкапсулируСт собствСнный Π½Π°Π±ΠΎΡ€ ΠΈΠΊΠΎΠ½ΠΎΠΊ слоТного UI-модуля, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠ³ΠΎ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Π° ΠΈΠ»ΠΈ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π°. +- **Global sprite** contains a small set of shared icons used in different parts of the application: navigation, states, and basic actions. +- **Page sprite** loads with a specific section and does not increase the shared sprite with icons that are not needed anywhere else. +- **Large component sprite** encapsulates the icon set of a complex UI module, such as a file manager or editor. -КаТдая Π³Ρ€ΡƒΠΏΠΏΠ° ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚: +Each group gets: -- собствСнный SVG asset; -- собствСнный Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚; -- ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ список ΠΈΠΌΡ‘Π½ ΠΈΠΊΠΎΠ½ΠΎΠΊ; -- ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ debug-манифСст; -- нСзависимый cache lifecycle. +- its own SVG asset; +- its own typed component; +- a separate list of icon names; +- a separate debug manifest; +- an independent cache lifecycle. ## TypeScript -Главная Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ TypeScript API β€” Π°Π²Ρ‚ΠΎΠ΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΈΠΌΡ‘Π½ ΠΈΠΊΠΎΠ½ΠΎΠΊ нСпосрСдствСнно Π² prop `icon`: +The main feature of the TypeScript API is icon name autocomplete directly in the `icon` prop: ```tsx -// ↑ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€ ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚ всС ΠΈΠΊΠΎΠ½ΠΊΠΈ спрайта +// ^ the editor suggests every icon in the sprite ``` -ИмСна SVG-Ρ„Π°ΠΉΠ»ΠΎΠ² становятся допустимыми значСниями `icon`. ΠžΠΏΠ΅Ρ‡Π°Ρ‚ΠΊΠ° ΠΈΠ»ΠΈ нСизвСстноС имя сразу становятся ошибкой TypeScript: +SVG file names become valid `icon` values. A typo or unknown name immediately becomes a TypeScript error: ```tsx - // ошибка TypeScript + // TypeScript error ``` -Для ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ доступа generated-ΠΌΠΎΠ΄ΡƒΠ»ΡŒ экспортируСт readonly-массив всСх доступных ΠΈΠΊΠΎΠ½ΠΎΠΊ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ спрайта: +For programmatic access, the generated module exports a readonly array of all icons available in a specific sprite: ```ts import { fileManagerIconNames } from './svg-sprite' @@ -173,39 +176,39 @@ import { fileManagerIconNames } from './svg-sprite' // readonly ['check', 'folder', ...] ``` -Π­Ρ‚ΠΎΡ‚ список ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² собствСнных ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π°Ρ…, select-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°Ρ…, тСстах ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΡ… runtime-сцСнариях. Из Π½Π΅Π³ΠΎ Ρ‚Π°ΠΊΠΆΠ΅ выводится union-Ρ‚ΠΈΠΏ `FileManagerIconName`. +You can use this list in custom catalogs, select components, tests, and other runtime scenarios. The `FileManagerIconName` union type is also derived from it. -ИмСна Ρ„Π°ΠΉΠ»ΠΎΠ² с ΠΏΡ€ΠΎΠ±Π΅Π»Π°ΠΌΠΈ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ нСбСзопасными для SVG ID символами ΠΎΡΡ‚Π°ΡŽΡ‚ΡΡ Ρ‡Π°ΡΡ‚ΡŒΡŽ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½ΠΎΠ³ΠΎ TypeScript API. Для Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅Π³ΠΎ `` Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ создаёт ΡΡ‚Π°Π±ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ hash ID. +File names containing spaces and other characters unsafe for SVG IDs remain part of the public TypeScript API. For the internal ``, the generator creates a stable hash ID. ```text -folder open.svg β†’ icon="folder open" β†’ id="icon-" +folder open.svg -> icon="folder open" -> id="icon-" ``` -Для Ρ‚Π°ΠΊΠΈΡ… ΠΈΠΌΡ‘Π½ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ generated-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΈΠ»ΠΈ `id` ΠΈΠ· debug-манифСста. Π ΡƒΡ‡Π½Ρ‹Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ Π½ΠΈΠΆΠ΅ с `#<имя>` подходят Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для ΠΈΠΌΡ‘Π½, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡƒΠΆΠ΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ бСзопасными SVG ID. +For such names, use the generated component or the `id` from the debug manifest. The manual examples below using `#` are suitable only for names that are already safe SVG IDs. -## Π€ΠΎΡ€ΠΌΠ°Ρ‚Ρ‹ спрайтов +## Sprite formats -`stack` β€” Π±ΠΎΠ»Π΅Π΅ соврСмСнный Ρ„ΠΎΡ€ΠΌΠ°Ρ‚, поэтому ΠΎΠ½ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ. Иконки ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Ρ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· ``, `` ΠΈ CSS `background-image`. +`stack` is the more modern format, so it is used by default. Icons can be rendered through ``, ``, and CSS `background-image`. -`symbol` сохраняСтся для совмСстимости с ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌΠΈ интСграциями ΠΈ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Π΅Ρ€Π΅Π· ``. +`symbol` is retained for compatibility with existing integrations and supports rendering only through ``. -## Бпособы отобраТСния +## Rendering methods -### React-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ β€” рСкомСндуСтся +### React component - recommended -Generated-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ прСдоставляСт Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΡŽ, Π°Π²Ρ‚ΠΎΠ΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΈΠΌΡ‘Π½ ΠΈΠΊΠΎΠ½ΠΎΠΊ ΠΈ сам Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅Ρ‚ URL SVG asset. +The generated component provides type safety and icon name autocomplete, and constructs the SVG asset URL itself. ```tsx ``` -Π§Π΅Ρ€Π΅Π· `color` ΠΈ `--icon-color-N` доступны ΠΎΠ΄Π½ΠΎΡ†Π²Π΅Ρ‚Π½Ρ‹Π΅ ΠΈ ΠΌΠ½ΠΎΠ³ΠΎΡ†Π²Π΅Ρ‚Π½Ρ‹Π΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ. +Monochrome and multicolor icons are supported through `color` and `--icon-color-N`. -### Π‘Π°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ Ρ‡Π΅Ρ€Π΅Π· `` +### Manually with `` -Π₯ΠΎΡ€ΠΎΡˆΠΈΠΉ Π½ΠΈΠ·ΠΊΠΎΡƒΡ€ΠΎΠ²Π½Π΅Π²Ρ‹ΠΉ способ с ΠΏΠΎΠ»Π½Ρ‹ΠΌ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€Π°ΠΌΠΈ ΠΈ Ρ†Π²Π΅Ρ‚Π°ΠΌΠΈ. React-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΏΠΎΠ΄ ΠΊΠ°ΠΏΠΎΡ‚ΠΎΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΈΠΌΠ΅Π½Π½ΠΎ Π΅Π³ΠΎ. +A good low-level method that provides full control over dimensions and colors. This is exactly what the React component uses under the hood. -Бпособ получСния `spriteUrl` зависит ΠΎΡ‚ сборщика. +How you obtain `spriteUrl` depends on the bundler. **Vite:** @@ -222,7 +225,7 @@ const spriteUrl = new URL( ).href ``` -**Next.js с Webpack 5 ΠΈΠ»ΠΈ Turbopack:** +**Next.js with Webpack 5 or Turbopack:** ```tsx const spriteUrl = new URL( @@ -231,7 +234,7 @@ const spriteUrl = new URL( ).href ``` -ПослС получСния URL ΠΈΠΊΠΎΠ½ΠΊΠ° отобраТаСтся ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΠΎ: +After obtaining the URL, the icon is rendered the same way: ```tsx @@ -239,17 +242,17 @@ const spriteUrl = new URL( ``` -Vite, Webpack 5 ΠΈ Next.js сами Π·Π°ΠΌΠ΅Π½ΡΡŽΡ‚ исходный ΠΏΡƒΡ‚ΡŒ Π½Π° ΠΈΡ‚ΠΎΠ³ΠΎΠ²Ρ‹ΠΉ URL asset с hash. +Vite, Webpack 5, and Next.js replace the source path with the final hashed asset URL automatically. -### Π§Π΅Ρ€Π΅Π· `` β€” ΠΌΠ΅Π½Π΅Π΅ эффСктивно +### With `` - less efficient ```tsx -Π“ΠΎΡ‚ΠΎΠ²ΠΎ +Done ``` -SVG загруТаСтся ΠΊΠ°ΠΊ ΠΈΠ·ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅: ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π΅Π³ΠΎ Ρ†Π²Π΅Ρ‚Π° Ρ‡Π΅Ρ€Π΅Π· `color` ΠΈΠ»ΠΈ `--icon-color-N` нСльзя. +The SVG loads as an isolated image: its colors cannot be changed through `color` or `--icon-color-N`. -### Π§Π΅Ρ€Π΅Π· CSS `background-image` β€” ΠΌΠ΅Π½Π΅Π΅ эффСктивно +### With CSS `background-image` - less efficient ```css .icon { @@ -257,9 +260,9 @@ SVG загруТаСтся ΠΊΠ°ΠΊ ΠΈΠ·ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ } ``` -Как ΠΈ ``, этот способ Π½Π΅ позволяСт ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠΌΠΈ Ρ†Π²Π΅Ρ‚Π°ΠΌΠΈ SVG. ΠŸΡƒΡ‚ΡŒ указываСтся ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ CSS-Ρ„Π°ΠΉΠ»Π°, Π° Vite/Webpack замСняСт Π΅Π³ΠΎ Π½Π° ΠΈΡ‚ΠΎΠ³ΠΎΠ²Ρ‹ΠΉ URL с hash ΠΏΡ€ΠΈ сборкС. +Like ``, this method does not allow you to control internal SVG colors. The path is specified relative to the CSS file, and Vite/Webpack replaces it with the final hashed URL during the build. -### Π§Π΅Ρ€Π΅Π· CSS mask β€” ΠΌΠ΅Π½Π΅Π΅ эффСктивно +### With CSS mask - less efficient ```css .icon { @@ -268,37 +271,37 @@ SVG загруТаСтся ΠΊΠ°ΠΊ ΠΈΠ·ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ } ``` -Mask оставляСт Ρ‚ΠΎΠ»ΡŒΠΊΠΎ силуэт ΠΈ ΠΎΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ Π΅Π³ΠΎ ΠΎΠ΄Π½ΠΈΠΌ Ρ†Π²Π΅Ρ‚ΠΎΠΌ. Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹Π΅ Ρ†Π²Π΅Ρ‚Π°, gradients ΠΈ различия ΠΌΠ΅ΠΆΠ΄Ρƒ `fill` ΠΈ `stroke` Ρ‚Π΅Ρ€ΡΡŽΡ‚ΡΡ. +A mask retains only the silhouette and colors it with a single color. The original colors, gradients, and distinctions between `fill` and `stroke` are lost. -## Врансформации +## Transformations -ВсС трансформации Π²ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΈ Π½Π°ΡΡ‚Ρ€Π°ΠΈΠ²Π°ΡŽΡ‚ΡΡ нСзависимо Ρ‡Π΅Ρ€Π΅Π· `transform`. +All transformations are enabled by default and configured independently through `transform`. -| ΠžΠΏΡ†ΠΈΡ | По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ | Π§Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ | +| Option | Default | What it does | |---|---|---| -| `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` Π½Π΅ пСрСзаписываСтся. | +| `removeSize` | `true` | Removes `width` and `height` from the root `` while preserving the existing `viewBox`. The icon size is then set externally. | +| `replaceColors` | `true` | Replaces `fill` and `stroke` colors with `--icon-color-N`. For a monochrome icon, the fallback becomes `currentColor`; for a multicolor icon, the original colors are preserved. | +| `addTransition` | `true` | Adds `style="transition:fill 0.3s,stroke 0.3s;"` directly to colored SVG elements. An existing `transition` is not overwritten. | -Π§Ρ‚ΠΎΠ±Ρ‹ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅, ΠΏΠ΅Ρ€Π΅Π΄Π°ΠΉΡ‚Π΅ для ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΉ ΠΎΠΏΡ†ΠΈΠΈ `false`. ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ `replaceColors` β€” Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ [Β«Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ†Π²Π΅Ρ‚ΠΎΠΌ ΠΈΠΊΠΎΠ½ΠΎΠΊΒ»](#ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅-Ρ†Π²Π΅Ρ‚ΠΎΠΌ-ΠΈΠΊΠΎΠ½ΠΎΠΊ). +To disable a transformation, pass `false` for the corresponding option. For more details about the result of `replaceColors`, see [Icon color management](#icon-color-management). -## Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ†Π²Π΅Ρ‚ΠΎΠΌ ΠΈΠΊΠΎΠ½ΠΎΠΊ +## Icon color management -ΠŸΡ€ΠΈ Π²ΠΊΠ»ΡŽΡ‡Ρ‘Π½Π½ΠΎΠΉ Π·Π°ΠΌΠ΅Π½Π΅ Ρ†Π²Π΅Ρ‚ΠΎΠ² Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ `fill` ΠΈ `stroke` ΠΈ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ ΠΈΡ… Π² CSS custom properties. +When color replacement is enabled, the generator analyzes `fill` and `stroke` and converts them to CSS custom properties. -### ΠœΠΎΠ½ΠΎΡ…Ρ€ΠΎΠΌΠ½Ρ‹Π΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ +### Monochrome icons -Если Π½Π°ΠΉΠ΄Π΅Π½ ΠΎΠ΄ΠΈΠ½ Ρ†Π²Π΅Ρ‚, fallback замСняСтся Π½Π° `currentColor`: +If one color is found, the fallback is replaced with `currentColor`: ```svg stroke="var(--icon-color-1, currentColor)" ``` -Π¦Π²Π΅Ρ‚ΠΎΠΌ управляСт CSS-свойство `color` внСшнСго `` ΠΈΠ»ΠΈ Π΅Π³ΠΎ родитСля. +The color is controlled by the CSS `color` property of the outer `` or its parent. -### ΠœΠ½ΠΎΠ³ΠΎΡ†Π²Π΅Ρ‚Π½Ρ‹Π΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ +### Multicolor icons -ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ†Π²Π΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ с исходным fallback: +Each unique color gets a separate variable with the original fallback: ```svg fill="var(--icon-color-1, #798198)" @@ -306,7 +309,7 @@ fill="var(--icon-color-2, #ffffff)" fill="var(--icon-color-3, #129d9d)" ``` -Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ Ρ†Π²Π΅Ρ‚Π°: +The page can override only the required colors: ```css .icon { @@ -315,62 +318,62 @@ fill="var(--icon-color-3, #129d9d)" } ``` -### ΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΡ Ρ†Π²Π΅Ρ‚ΠΎΠ² +### Color limitations -- `none`, `transparent`, `inherit`, `unset` ΠΈ `initial` Π½Π΅ Π·Π°ΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ; -- Ρ†Π²Π΅Ρ‚Π° Π² Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π°Ρ… `fill`, `stroke` ΠΈ inline `style` ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ Π½Π°Π΄Ρ‘ΠΆΠ½Π΅Π΅ всСго; -- CSS-классы ΠΈ внСшниС stylesheets Π²Π½ΡƒΡ‚Ρ€ΠΈ исходного SVG Π½Π΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ основным сцСнариСм трансформации; -- gradients, patterns, filters ΠΈ значСния `url(#...)` Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΉ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ нСсовмСстимы с автоматичСской Π·Π°ΠΌΠ΅Π½ΠΎΠΉ Ρ†Π²Π΅Ρ‚ΠΎΠ²; -- CSS-ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ страницы доступны ΠΏΡ€ΠΈ ``, Π½ΠΎ нСдоступны Π²Π½ΡƒΡ‚Ρ€ΠΈ `` ΠΈ `background-image`. +- `none`, `transparent`, `inherit`, `unset`, and `initial` are not replaced; +- colors in `fill`, `stroke`, and inline `style` attributes are handled most reliably; +- CSS classes and external stylesheets inside the source SVG are not the primary transformation use case; +- gradients, patterns, filters, and `url(#...)` values require separate verification and may be incompatible with automatic color replacement; +- page CSS variables are available with ``, but are not available inside `` and `background-image`. -## ΠšΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ +## Caching -Vite, Webpack ΠΈ Next.js target Π²Ρ‹ΠΏΡƒΡΠΊΠ°ΡŽΡ‚ спрайт ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΌ asset с content hash: +The Vite, Webpack, and Next.js targets emit the sprite as a separate asset with a content hash: ```text /assets/sprite-.svg ``` -Π­Ρ‚ΠΎ Π΄Π°Ρ‘Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ свойства: +This provides the following properties: -- SVG ΠΊΠ΅ΡˆΠΈΡ€ΡƒΠ΅Ρ‚ΡΡ нСзависимо ΠΎΡ‚ JavaScript; -- ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ React-ΠΊΠΎΠ΄Π° Π½Π΅ мСняСт содСрТимоС спрайта; -- ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΈΠΊΠΎΠ½ΠΎΠΊ создаёт Π½ΠΎΠ²Ρ‹ΠΉ hash asset; -- ΠΎΠ΄ΠΈΠ½ Ρ„Π°ΠΉΠ» ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ всСми экзСмплярами generated-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°; -- SVG path-Π΄Π°Π½Π½Ρ‹Π΅ ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‚ Π² JavaScript chunks. +- the SVG is cached independently of JavaScript; +- changes to React code do not alter the sprite contents; +- icon changes produce a new hashed asset; +- one file is used by every instance of the generated component; +- SVG path data is absent from JavaScript chunks. -Vite target Π·Π°ΠΏΡ€Π΅Ρ‰Π°Π΅Ρ‚ inline Ρ‡Π΅Ρ€Π΅Π· `?no-inline`. Webpack 5 target ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Asset Modules Ρ‡Π΅Ρ€Π΅Π· `new URL(..., import.meta.url)`. +The Vite target prevents inlining through `?no-inline`. The Webpack 5 target uses Asset Modules through `new URL(..., import.meta.url)`. ## SpriteViewer -`SpriteViewer` β€” React-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ для просмотра generated-спрайтов Π²Π½ΡƒΡ‚Ρ€ΠΈ debug-ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π° прилоТСния. +`SpriteViewer` is a React component for viewing generated sprites inside an application's debug route. -Он ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ манифСсты ΠΈ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚: +It uses separate manifests and displays: -- Π³Ρ€ΡƒΠΏΠΏΡ‹ спрайтов; -- список ΠΈ количСство ΠΈΠΊΠΎΠ½ΠΎΠΊ; -- поиск ΠΈ ΡΠΈΡΡ‚Π΅ΠΌΠ½ΡƒΡŽ ΡΠ²Π΅Ρ‚Π»ΡƒΡŽ/Ρ‚Ρ‘ΠΌΠ½ΡƒΡŽ Ρ‚Π΅ΠΌΡƒ; -- модальноС ΠΏΡ€Π΅Π²ΡŒΡŽ с `viewBox` ΠΈ настройкой Ρ†Π²Π΅Ρ‚ΠΎΠ²Ρ‹Ρ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…; -- ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ React, SVG, IMG ΠΈ CSS с ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΠΊΠΎΠ΄Π°. +- sprite groups; +- the icon list and count; +- search and the system light/dark theme; +- a preview modal with the `viewBox` and color variable controls; +- React, SVG, IMG, and CSS examples with code copying. -Production-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ Π½Π΅ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ debug-манифСсты. Бпособ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ Viewer зависит ΠΎΡ‚ сборщика: +Production components do not import debug manifests. How you integrate the Viewer depends on the bundler: -- [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). +- [React + Vite: automatic `import.meta.glob`](docs/en/react-vite.md#6-add-a-debug-page); +- [React + Webpack 5: static `import()`](docs/en/react-webpack.md#6-add-a-debug-page); +- [Next.js App Router](docs/en/next-app.md#5-add-spriteviewer); +- [Next.js Pages Router](docs/en/next-pages.md#5-add-spriteviewer). -Viewer ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ ΠΈΠ· ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΉ клиСнтской Ρ‚ΠΎΡ‡ΠΊΠΈ Π²Ρ…ΠΎΠ΄Π° `@gromlab/svg-sprites/react` ΠΈ Π½Π΅ ΠΏΠΎΠΏΠ°Π΄Π°Π΅Ρ‚ Π² production-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ ΠΈΠΊΠΎΠ½ΠΎΠΊ. +The Viewer is imported from the separate `@gromlab/svg-sprites/react` client entry point and is not included in production icon components. -### Π’Π΅ΠΌΠ° Viewer +### Viewer theme -По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ `colorTheme="auto"`: Viewer слСдуСт `prefers-color-scheme` ΠΈ Ρ€Π΅Π°Π³ΠΈΡ€ΡƒΠ΅Ρ‚ Π½Π° смСну систСмной Ρ‚Π΅ΠΌΡ‹. Π’Π΅ΠΌΡƒ прилоТСния ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ явно: +By default, `colorTheme="auto"`: the Viewer follows `prefers-color-scheme` and responds to system theme changes. The application theme can be passed explicitly: ```tsx ``` -ДопустимыС значСния `colorTheme`: `auto`, `light`, `dark`. ΠŸΡ€ΠΈ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠΈ Ρ‚Π΅ΠΌΠΎΠΉ ΠΈΠ·Π²Π½Π΅ встроСнный ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π°Ρ‚Π΅Π»ΡŒ скрываСтся. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π΅Π³ΠΎ ΠΈ ΠΎΠ±Π½ΠΎΠ²Π»ΡΡ‚ΡŒ Ρ‚Π΅ΠΌΡƒ прилоТСния Ρ‡Π΅Ρ€Π΅Π· Viewer, ΠΏΠ΅Ρ€Π΅Π΄Π°ΠΉΡ‚Π΅ callback: +Valid `colorTheme` values are `auto`, `light`, and `dark`. When the theme is controlled externally, the built-in switch is hidden. To keep it and update the application theme through the Viewer, pass a callback: ```tsx ``` -## ДокумСнтация +## Documentation -- [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) +- [React + Vite](docs/en/react-vite.md) +- [React + Webpack 5](docs/en/react-webpack.md) +- [Next.js App Router](docs/en/next-app.md) +- [Next.js Pages Router](docs/en/next-pages.md) +- [Legacy mode](docs/en/legacy.md) +- [Migrating from 0.1.x](docs/en/migration-1.md) +- [Programmatic API](docs/en/programmatic-api.md) -## ЛицСнзия +## License MIT diff --git a/skills/artifacts/svg-sprites/references/README_RU.md b/skills/artifacts/svg-sprites/references/README_RU.md new file mode 100644 index 0000000..c4d9a90 --- /dev/null +++ b/skills/artifacts/svg-sprites/references/README_RU.md @@ -0,0 +1,398 @@ +# @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 diff --git a/skills/artifacts/svg-sprites/references/docs/en/legacy.md b/skills/artifacts/svg-sprites/references/docs/en/legacy.md new file mode 100644 index 0000000..10b6ea1 --- /dev/null +++ b/skills/artifacts/svg-sprites/references/docs/en/legacy.md @@ -0,0 +1,102 @@ +# Legacy mode + +[← Back to home](../../README.md) + +A quick guide to generating centralized SVG sprites in `symbol` and `stack` formats, with an optional HTML preview. + +## 1. Install the package + +```bash +npm install @gromlab/svg-sprites +``` + +## 2. Prepare the icons and config + +```text +project/ +β”œβ”€β”€ src/assets/icons/ +β”‚ β”œβ”€β”€ check.svg +β”‚ └── folder.svg +└── svg-sprites.config.ts +``` + +```ts +// svg-sprites.config.ts +import { defineLegacyConfig } from '@gromlab/svg-sprites' + +export default defineLegacyConfig({ + output: 'public/sprites', + preview: true, + sprites: [ + { + name: 'icons', + input: 'src/assets/icons', + format: 'symbol', + }, + ], +}) +``` + +## 3. Run generation + +```bash +npx svg-sprites --mode legacy . +``` + +Result: + +```text +public/sprites/ +β”œβ”€β”€ icons.sprite.svg +└── preview.html +``` + +With `preview: false`, the HTML file is not created. For the `stack` format, specify `format: 'stack'`. + +## 4. Use the symbol sprite + +```html + + + +``` + +## 5. Add a package script + +```json +{ + "scripts": { + "sprites": "svg-sprites --mode legacy .", + "prebuild": "npm run sprites" + } +} +``` + +## Multiple sprites + +Add multiple entries to `sprites`: + +```ts +sprites: [ + { + name: 'icons', + input: 'src/assets/icons', + format: 'symbol', + }, + { + name: 'logos', + input: 'src/assets/logos', + format: 'stack', + }, +] +``` + +All output files and the shared `preview.html` will be written to `output`. + +## Troubleshooting + +- Config not found: make sure `svg-sprites.config.ts` is located in the specified root directory. +- No icons: check `sprites[].input` and the `.svg` extension. +- Preview not needed: set `preview: false`. + +For programmatic use, see [`generateLegacy`](programmatic-api.md#generatelegacy). diff --git a/skills/artifacts/svg-sprites/references/docs/en/migration-1.md b/skills/artifacts/svg-sprites/references/docs/en/migration-1.md new file mode 100644 index 0000000..b53b915 --- /dev/null +++ b/skills/artifacts/svg-sprites/references/docs/en/migration-1.md @@ -0,0 +1,96 @@ +# Migrating from 0.1.x to 1.0 + +[← Back to home](../../README.md) + +Version 1.0 separates local generation for React and Next.js from the centralized legacy mode. The old config cannot be mixed with the new API in a single CLI invocation. + +## CLI + +The CLI now always requires an explicit `--mode` and a path to the configuration directory: + +```text +svg-sprites +β†’ svg-sprites --mode +``` + +Choose a mode based on your environment: + +| Environment | Mode | +|---|---| +| React + Vite | `react@vite` | +| React + Webpack 5 | `react@webpack` | +| Next.js App Router + Turbopack | `next@app/turbopack` | +| Next.js App Router + Webpack 5 | `next@app/webpack` | +| Next.js Pages Router + Turbopack | `next@pages/turbopack` | +| Next.js Pages Router + Webpack 5 | `next@pages/webpack` | +| Centralized legacy setup | `legacy` | + +## React and Next.js + +Instead of a root-level `svg-sprites.config.ts`, create a local `svg-sprite.config.ts` next to the icon set: + +```ts +import { defineNextSpriteConfig } from '@gromlab/svg-sprites' + +export default defineNextSpriteConfig({ + name: 'global', + inputFolder: './icons', +}) +``` + +For regular React, use `defineReactSpriteConfig`. A folder and an explicit list of shared SVG files can be combined using `inputFolder` and `inputFiles`. + +The old `publicPath` and `react` options are no longer needed. The generated module is created next to the config and adds its own `.gitignore`, while Vite, Webpack, or Next.js emits the SVG as a separate asset with a content hash. + +The `` component is replaced by a component whose name is derived from `name`: + +```tsx + +``` + +To browse the icons, add `` as a debug page in the application. A separate `preview.html` is available only in legacy mode. + +## Legacy mode + +If you need to preserve the centralized structure, rename the helper and the format fields: + +```ts +import { defineLegacyConfig } from '@gromlab/svg-sprites' + +export default defineLegacyConfig({ + output: 'public/sprites', + preview: true, + sprites: [ + { + name: 'icons', + input: 'src/assets/icons', + format: 'stack', + }, + ], +}) +``` + +- `defineConfig` has been replaced with `defineLegacyConfig`; +- `sprites[].mode` has been renamed to `sprites[].format`; +- `generate` has been replaced with `generateLegacy`; +- `loadConfig` has been replaced with `loadLegacyConfig`; +- `publicPath` and generation of the old shared React component have been removed. + +Run: + +```bash +svg-sprites --mode legacy . +``` + +## Programmatic API + +The package is distributed as ESM only. Replace `require()` with `import`. + +`compileSpriteContent` now returns `Promise` so that the public declarations do not require `@types/node` to be installed. In Node.js, the actual result is compatible with APIs that accept `Uint8Array`. + +## After migration + +1. Remove the old generated files and rules that ignored the entire directory containing the source icons. +2. Add an explicit generation command before `dev`, `build`, and `typecheck`. +3. Run generation and type checking. +4. Check all icons and color variables using `SpriteViewer` or the legacy `preview.html`. diff --git a/skills/artifacts/svg-sprites/references/docs/en/next-app.md b/skills/artifacts/svg-sprites/references/docs/en/next-app.md new file mode 100644 index 0000000..1e334ce --- /dev/null +++ b/skills/artifacts/svg-sprites/references/docs/en/next-app.md @@ -0,0 +1,102 @@ +# Next.js App Router + +[← Back to home](../../README.md) + +Two explicit modes are supported: + +| Bundler | Mode key | Next.js version | +|---|---|---| +| Turbopack | `next@app/turbopack` | 16.2+ | +| Webpack 5 | `next@app/webpack` | 13.4+ | + +## 1. Install the package + +```bash +npm install @gromlab/svg-sprites +``` + +## 2. Create a sprite module + +```text +src/ui/file-manager/svg-sprite/ +β”œβ”€β”€ icons/ +β”‚ β”œβ”€β”€ check.svg +β”‚ └── folder.svg +└── svg-sprite.config.ts +``` + +```ts +// src/ui/file-manager/svg-sprite/svg-sprite.config.ts +import { defineNextSpriteConfig } from '@gromlab/svg-sprites' + +export default defineNextSpriteConfig({ + name: 'file-manager', + description: 'File manager icons', +}) +``` + +## 3. Add generation + +For Turbopack: + +```json +{ + "scripts": { + "sprite:file-manager": "svg-sprites --mode next@app/turbopack src/ui/file-manager/svg-sprite", + "predev": "npm run sprite:file-manager", + "prebuild": "npm run sprite:file-manager" + } +} +``` + +For Webpack, replace the mode key with `next@app/webpack`. In Next 13–15, Webpack is used with the regular `next build` command; in Next 16, use `next build --webpack`. + +## 4. Use it in a Server Component + +The generated component does not contain `'use client'`, so it can be imported directly into `page.tsx` or `layout.tsx`: + +```tsx +import { FileManagerIcon } from '@/ui/file-manager/svg-sprite' + +export default function Page() { + return ( +
+ +
+ ) +} +``` + +Next.js emits a separate SVG asset with a content hash. The same generated code is used during SSR and in the browser, with no URL mismatch. + +## 5. Add SpriteViewer + +The viewer is interactive, so it requires a separate Client Component boundary: + +```tsx +'use client' + +import { SpriteViewer } from '@gromlab/svg-sprites/react' + +const sources = [ + () => import('@/ui/file-manager/svg-sprite/manifest'), +] + +export default function SpritesPage() { + return +} +``` + +## Verify the bundler + +```bash +# Turbopack +npx next build --turbopack + +# Webpack 5 +npx next build --webpack +``` + +For Next 13–15 with Webpack, use `npx next build` without the flag. + +The Next.js command and the generator mode key must target the same bundler. diff --git a/skills/artifacts/svg-sprites/references/docs/en/next-pages.md b/skills/artifacts/svg-sprites/references/docs/en/next-pages.md new file mode 100644 index 0000000..0de0136 --- /dev/null +++ b/skills/artifacts/svg-sprites/references/docs/en/next-pages.md @@ -0,0 +1,96 @@ +# Next.js Pages Router + +[← Back to home](../../README.md) + +Two explicit modes are supported: + +| Bundler | Mode key | Next.js version | +|---|---|---| +| Turbopack | `next@pages/turbopack` | 16.2+ | +| Webpack 5 | `next@pages/webpack` | 12.2+ | + +Next.js 12.2 requires React 18. + +## 1. Install the package + +```bash +npm install @gromlab/svg-sprites +``` + +## 2. Create a sprite module + +```text +src/ui/file-manager/svg-sprite/ +β”œβ”€β”€ icons/ +β”‚ β”œβ”€β”€ check.svg +β”‚ └── folder.svg +└── svg-sprite.config.ts +``` + +```ts +// src/ui/file-manager/svg-sprite/svg-sprite.config.ts +import { defineNextSpriteConfig } from '@gromlab/svg-sprites' + +export default defineNextSpriteConfig({ + name: 'file-manager', + description: 'File manager icons', +}) +``` + +## 3. Add generation + +```json +{ + "scripts": { + "sprite:file-manager": "svg-sprites --mode next@pages/webpack src/ui/file-manager/svg-sprite", + "predev": "npm run sprite:file-manager", + "prebuild": "npm run sprite:file-manager" + } +} +``` + +For Next.js 16.2 with Turbopack, replace the mode key with `next@pages/turbopack`. + +## 4. Use it on a page + +```tsx +import { FileManagerIcon } from '@/ui/file-manager/svg-sprite' + +export default function FilesPage() { + return +} + +export function getServerSideProps() { + return { props: {} } +} +``` + +The component works the same way with SSR, SSG, and client-side navigation. Next.js emits a separate SVG asset with a content hash. + +## 5. Add SpriteViewer + +```tsx +import { SpriteViewer } from '@gromlab/svg-sprites/react' + +const sources = [ + () => import('@/ui/file-manager/svg-sprite/manifest'), +] + +export default function SpritesPage() { + return +} +``` + +## Verify the bundler + +```bash +# Turbopack +npx next build --turbopack + +# Webpack 5 +npx next build --webpack +``` + +For Next 12–15 with Webpack, use `npx next build` without the flag. + +The Next.js command and the generator mode key must target the same bundler. diff --git a/skills/artifacts/svg-sprites/references/docs/en/programmatic-api.md b/skills/artifacts/svg-sprites/references/docs/en/programmatic-api.md new file mode 100644 index 0000000..7a4d44b --- /dev/null +++ b/skills/artifacts/svg-sprites/references/docs/en/programmatic-api.md @@ -0,0 +1,203 @@ +# Programmatic API + +[← Back to home](../../README.md) + +The package provides a main Node.js entry point and a separate React runtime entry point. Both are distributed as ESM only and must be loaded with `import`. + +To resolve `@gromlab/svg-sprites/react` in TypeScript, use `moduleResolution: "bundler"`, `"node16"`, or `"nodenext"`. + +## Main entry point + +```ts +import { + defineNextSpriteConfig, + defineReactSpriteConfig, + generateNextSprite, + generateReactSprite, +} from '@gromlab/svg-sprites' +``` + +The main entry point does not import React and can be used in CLIs, build scripts, and Node.js tools. + +## `generateReactSprite` + +```ts +import { generateReactSprite } from '@gromlab/svg-sprites' + +const result = await generateReactSprite( + 'src/ui/file-manager/svg-sprite', + 'vite', +) +``` + +The second argument is required: + +```ts +type ReactAssetTarget = 'vite' | 'webpack' +``` + +Result: + +```ts +type ReactSpriteGenerationResult = { + name: string + rootDir: string + generatedDir: string + spritePath: string + manifestPath: string + iconCount: number + target: 'vite' | 'webpack' +} +``` + +```ts +console.log(result.name) +console.log(result.iconCount) +console.log(result.spritePath) +console.log(result.manifestPath) +``` + +The function loads `svg-sprite.config.ts` from the specified root, compiles the SVG files, and safely updates managed files. + +## `generateNextSprite` + +```ts +import { generateNextSprite } from '@gromlab/svg-sprites' + +const result = await generateNextSprite( + 'src/ui/file-manager/svg-sprite', + { + router: 'app', + bundler: 'turbopack', + }, +) +``` + +Available values: + +```ts +type NextSpriteGenerationOptions = { + router: 'app' | 'pages' + bundler: 'turbopack' | 'webpack' +} +``` + +The result also contains the selected `router`, `bundler`, and the full target in the form `next@app/turbopack`. + +## `defineReactSpriteConfig` + +```ts +import { defineReactSpriteConfig } from '@gromlab/svg-sprites' + +export default defineReactSpriteConfig({ + name: 'file-manager', + description: 'File manager icons', + inputFolder: './icons', + inputFiles: [ + '../../shared/icons/check.svg', + ], + transform: { + removeSize: true, + replaceColors: true, + addTransition: true, + }, + generatedNotice: true, +}) +``` + +`inputFolder` and `inputFiles` are combined. The helper returns the configuration without runtime transformations and provides TypeScript autocomplete. + +## `defineNextSpriteConfig` + +```ts +import { defineNextSpriteConfig } from '@gromlab/svg-sprites' + +export default defineNextSpriteConfig({ + name: 'file-manager', + description: 'File manager icons', + inputFolder: './icons', +}) +``` + +Next.js uses the same configuration contract as the React presets. + +## `generateLegacy` + +```ts +import { generateLegacy } from '@gromlab/svg-sprites' + +const results = await generateLegacy({ + output: 'public/sprites', + preview: false, + sprites: [ + { + name: 'icons', + input: 'src/assets/icons', + format: 'symbol', + }, + ], +}) +``` + +Returns an array: + +```ts +type SpriteResult = { + name: string + format: 'symbol' | 'stack' + spritePath: string + iconCount: number +} +``` + +For details, see [Legacy mode](legacy.md). + +## Low-level functions + +The main entry point also exports: + +```ts +import { + compileSprite, + compileSpriteContent, + createShapeTransform, + generatePreview, + loadLegacyConfig, + loadReactSpriteConfig, + resolveSpriteEntry, + resolveSprites, +} from '@gromlab/svg-sprites' +``` + +These functions are intended for custom orchestration built on top of the existing compiler and writer. For standard usage, prefer `generateReactSprite` and `generateLegacy`. + +## React runtime entry point + +```tsx +import { SpriteViewer } from '@gromlab/svg-sprites/react' +``` + +Types: + +```ts +import type { + SpriteManifest, + SpriteManifestColor, + SpriteManifestIcon, + SpriteManifestLoader, + SpriteManifestModule, + SpriteViewerColorTheme, + SpriteViewerProps, + SpriteViewerSource, + SpriteViewerSources, +} from '@gromlab/svg-sprites/react' +``` + +The React entry point contains `'use client'` and is intended for debug tools. Generated production components are imported from the application's local sprite modules, not from the package's React entry point. + +`SpriteViewerProps.colorTheme` accepts `auto | light | dark`. The default is `auto`, which follows `prefers-color-scheme`; to synchronize it with the application theme, pass the computed `light` or `dark` value. + +## Related guides + +- [React + Vite](react-vite.md) +- [React + Webpack 5](react-webpack.md) diff --git a/skills/artifacts/svg-sprites/references/docs/en/react-vite.md b/skills/artifacts/svg-sprites/references/docs/en/react-vite.md new file mode 100644 index 0000000..1e37cc4 --- /dev/null +++ b/skills/artifacts/svg-sprites/references/docs/en/react-vite.md @@ -0,0 +1,116 @@ +# React + Vite + +[← Back to home](../../README.md) + +A quick guide to installing and using SVG sprites in a React and Vite project. + +The result is a typed React component and a separate cacheable SVG asset. + +## 1. Install the package + +```bash +npm install @gromlab/svg-sprites +``` + +## 2. Create the sprite directory + +```text +src/ui/file-manager/svg-sprite/ +β”œβ”€β”€ icons/ +β”‚ β”œβ”€β”€ check.svg +β”‚ └── folder.svg +└── svg-sprite.config.ts +``` + +Place the source SVG files in `icons/`. + +## 3. Add the configuration + +```ts +// src/ui/file-manager/svg-sprite/svg-sprite.config.ts +import { defineReactSpriteConfig } from '@gromlab/svg-sprites' + +export default defineReactSpriteConfig({ + name: 'file-manager', + description: 'File manager icons', +}) +``` + +By default, SVG files are loaded from `./icons`. You can add shared icons from other directories through `inputFiles`: the directory and file list are combined into a single sprite. + +The complete list of options is available under [Configuration β†’ React](../../README.md#react). + +## 4. Add generation to package.json + +```json +{ + "scripts": { + "sprite:file-manager": "svg-sprites --mode react@vite src/ui/file-manager/svg-sprite", + "predev": "npm run sprite:file-manager", + "prebuild": "npm run sprite:file-manager", + "pretypecheck": "npm run sprite:file-manager" + } +} +``` + +Generated files are excluded from Git, so generation must run before `dev`, `build`, and `typecheck`. + +First run: + +```bash +npm run sprite:file-manager +``` + +## 5. Use the component + +The name `file-manager` is converted to `FileManagerIcon`: + +```tsx +import { FileManagerIcon } from './svg-sprite' + +export const OpenFolderButton = () => ( + +) +``` + +TypeScript checks the `icon` value against the file names: + +```tsx + // valid + // TypeScript error +``` + +Types, display methods, and color controls are described in the [main documentation](../../README.md#display-methods). + +Vite emits the sprite as a separate file named like `assets/sprite-.svg`. SVG path data is not included in JavaScript. + +## 6. Add a debug page + +After integrating the icons, you can display all React sprites with `SpriteViewer`: + +```tsx +import { SpriteViewer } from '@gromlab/svg-sprites/react' +import type { SpriteManifestModule } from '@gromlab/svg-sprites/react' + +const sources = import.meta.glob( + '/src/**/svg-sprite/manifest.ts', +) + +export const IconsDebugPage = () => ( + +) +``` + +Vite automatically finds the generated `manifest.ts` for each React sprite. The `import.meta.glob` pattern must be a string literal, and generation must run before Vite starts. + +Only include the Viewer on a debug route or in an internal tool. + +## Troubleshooting + +- Missing `index.ts`: run `npm run sprite:file-manager`. +- The Viewer cannot find the sprite: check the glob path and make sure `manifest.ts` exists. +- `Refusing to overwrite a user file` error: there is a user file at a generated path. +- The icon does not change color: use `color` or `--icon-color-N`. diff --git a/skills/artifacts/svg-sprites/references/docs/en/react-webpack.md b/skills/artifacts/svg-sprites/references/docs/en/react-webpack.md new file mode 100644 index 0000000..15383db --- /dev/null +++ b/skills/artifacts/svg-sprites/references/docs/en/react-webpack.md @@ -0,0 +1,118 @@ +# React + Webpack 5 + +[← Back to home](../../README.md) + +A quick guide to installing and using SVG sprites in a React and Webpack 5 project. + +The result is a typed React component and a separate SVG asset emitted through Webpack Asset Modules. + +## 1. Install the package + +```bash +npm install @gromlab/svg-sprites +``` + +## 2. Create the sprite directory + +```text +src/ui/file-manager/svg-sprite/ +β”œβ”€β”€ icons/ +β”‚ β”œβ”€β”€ check.svg +β”‚ └── folder.svg +└── svg-sprite.config.ts +``` + +Place the source SVG files in `icons/`. + +## 3. Add the configuration + +```ts +// src/ui/file-manager/svg-sprite/svg-sprite.config.ts +import { defineReactSpriteConfig } from '@gromlab/svg-sprites' + +export default defineReactSpriteConfig({ + name: 'file-manager', + description: 'File manager icons', +}) +``` + +By default, SVG files are loaded from `./icons`. You can add shared icons from other directories through `inputFiles`: the directory and file list are combined into a single sprite. + +The complete list of options is available under [Configuration β†’ React](../../README.md#react). + +## 4. Add generation to package.json + +```json +{ + "scripts": { + "sprite:file-manager": "svg-sprites --mode react@webpack src/ui/file-manager/svg-sprite", + "predev": "npm run sprite:file-manager", + "prebuild": "npm run sprite:file-manager", + "pretypecheck": "npm run sprite:file-manager" + } +} +``` + +Generated files are excluded from Git, so generation must run before `dev`, `build`, and `typecheck`. + +First run: + +```bash +npm run sprite:file-manager +``` + +## 5. Use the component + +```tsx +import { FileManagerIcon } from './svg-sprite' + +export const OpenFolderButton = () => ( + +) +``` + +TypeScript checks the `icon` value against the file names: + +```tsx + // valid + // TypeScript error +``` + +Types, display methods, and color controls are described in the [main documentation](../../README.md#display-methods). + +Webpack processes the generated `new URL('./sprite.svg', import.meta.url)` through Asset Modules and emits a separate SVG asset. + +If the project already uses a custom SVG loader, make sure it does not intercept the generated `sprite.svg` instead of Asset Modules. + +## 6. Add a debug page + +Webpack does not support Vite's `import.meta.glob` API, so provide static loaders: + +```tsx +import { SpriteViewer } from '@gromlab/svg-sprites/react' + +const sources = [ + () => import('./ui/file-manager/svg-sprite/manifest'), + () => import('./ui/navigation/svg-sprite/manifest'), +] + +export const IconsDebugPage = () => ( + +) +``` + +The paths in `import()` must be string literals. Webpack creates chunks for the manifests and associates them with the SVG assets. + +Only include the Viewer on a debug route or in an internal tool. + +## Troubleshooting + +- Missing `index.ts`: run `npm run sprite:file-manager`. +- The Viewer does not load the sprite: check the path in `import()` and make sure `manifest.ts` exists. +- Incorrect asset URL: check `output.publicPath`. +- Another loader intercepts the SVG: exclude the generated sprite from the incompatible rule. + +For Next.js, use the separate mode keys described in the [App Router](next-app.md) and [Pages Router](next-pages.md) guides. diff --git a/skills/artifacts/svg-sprites/references/docs/ru/legacy.md b/skills/artifacts/svg-sprites/references/docs/ru/legacy.md index 5efd0cf..3d722b8 100644 --- a/skills/artifacts/svg-sprites/references/docs/ru/legacy.md +++ b/skills/artifacts/svg-sprites/references/docs/ru/legacy.md @@ -1,6 +1,6 @@ # Legacy mode -[← Главная](../../README.md) +[← Главная](../../README_RU.md) ΠšΡ€Π°Ρ‚ΠΊΠ°Ρ инструкция ΠΏΠΎ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹Ρ… SVG-спрайтов Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΎΠ² `symbol` ΠΈ `stack` с optional HTML preview. diff --git a/skills/artifacts/svg-sprites/references/docs/ru/migration-1.md b/skills/artifacts/svg-sprites/references/docs/ru/migration-1.md index a41d3d9..39b15d8 100644 --- a/skills/artifacts/svg-sprites/references/docs/ru/migration-1.md +++ b/skills/artifacts/svg-sprites/references/docs/ru/migration-1.md @@ -1,6 +1,6 @@ # ΠœΠΈΠ³Ρ€Π°Ρ†ΠΈΡ с 0.1.x Π½Π° 1.0 -[← Главная](../../README.md) +[← Главная](../../README_RU.md) ВСрсия 1.0 раздСляСт Π»ΠΎΠΊΠ°Π»ΡŒΠ½ΡƒΡŽ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ для React ΠΈ Next.js ΠΈ Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ legacy-Ρ€Π΅ΠΆΠΈΠΌ. Π‘Ρ‚Π°Ρ€Ρ‹ΠΉ config нСльзя ΡΠΌΠ΅ΡˆΠΈΠ²Π°Ρ‚ΡŒ с Π½ΠΎΠ²Ρ‹ΠΌ API Π² ΠΎΠ΄Π½ΠΎΠΌ Π²Ρ‹Π·ΠΎΠ²Π΅ CLI. diff --git a/skills/artifacts/svg-sprites/references/docs/ru/next-app.md b/skills/artifacts/svg-sprites/references/docs/ru/next-app.md index 593d02d..06049c6 100644 --- a/skills/artifacts/svg-sprites/references/docs/ru/next-app.md +++ b/skills/artifacts/svg-sprites/references/docs/ru/next-app.md @@ -1,6 +1,6 @@ # Next.js App Router -[← Главная](../../README.md) +[← Главная](../../README_RU.md) ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ Π΄Π²Π° явных Ρ€Π΅ΠΆΠΈΠΌΠ°: diff --git a/skills/artifacts/svg-sprites/references/docs/ru/next-pages.md b/skills/artifacts/svg-sprites/references/docs/ru/next-pages.md index d52750b..926f0ef 100644 --- a/skills/artifacts/svg-sprites/references/docs/ru/next-pages.md +++ b/skills/artifacts/svg-sprites/references/docs/ru/next-pages.md @@ -1,6 +1,6 @@ # Next.js Pages Router -[← Главная](../../README.md) +[← Главная](../../README_RU.md) ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ Π΄Π²Π° явных Ρ€Π΅ΠΆΠΈΠΌΠ°: diff --git a/skills/artifacts/svg-sprites/references/docs/ru/programmatic-api.md b/skills/artifacts/svg-sprites/references/docs/ru/programmatic-api.md index 510b5fc..999cd01 100644 --- a/skills/artifacts/svg-sprites/references/docs/ru/programmatic-api.md +++ b/skills/artifacts/svg-sprites/references/docs/ru/programmatic-api.md @@ -1,6 +1,6 @@ # ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ API -[← Главная](../../README.md) +[← Главная](../../README_RU.md) ΠŸΠ°ΠΊΠ΅Ρ‚ прСдоставляСт ΠΎΡΠ½ΠΎΠ²Π½ΡƒΡŽ Node.js Ρ‚ΠΎΡ‡ΠΊΡƒ Π²Ρ…ΠΎΠ΄Π° ΠΈ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ React runtime entry. ОбС Ρ‚ΠΎΡ‡ΠΊΠΈ Ρ€Π°ΡΠΏΡ€ΠΎΡΡ‚Ρ€Π°Π½ΡΡŽΡ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊΠ°ΠΊ ESM ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‚ΡΡ Ρ‡Π΅Ρ€Π΅Π· `import`. diff --git a/skills/artifacts/svg-sprites/references/docs/ru/react-vite.md b/skills/artifacts/svg-sprites/references/docs/ru/react-vite.md index 1aa146e..2ae3b39 100644 --- a/skills/artifacts/svg-sprites/references/docs/ru/react-vite.md +++ b/skills/artifacts/svg-sprites/references/docs/ru/react-vite.md @@ -1,6 +1,6 @@ # React + Vite -[← Главная](../../README.md) +[← Главная](../../README_RU.md) ΠšΡ€Π°Ρ‚ΠΊΠ°Ρ инструкция ΠΏΠΎ установкС ΠΈ использованию SVG-спрайтов Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅ Π½Π° React ΠΈ Vite. @@ -38,7 +38,7 @@ export default defineReactSpriteConfig({ По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ SVG бСрутся ΠΈΠ· `./icons`. ΠžΠ±Ρ‰ΠΈΠ΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΏΠ°ΠΏΠΎΠΊ ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· `inputFiles`: ΠΏΠ°ΠΏΠΊΠ° ΠΈ список ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‚ΡΡ Π² ΠΎΠ΄ΠΈΠ½ спрайт. -ΠŸΠΎΠ»Π½Ρ‹ΠΉ список ΠΎΠΏΡ†ΠΈΠΉ находится Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ [ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ β†’ React](../../README.md#react). +ΠŸΠΎΠ»Π½Ρ‹ΠΉ список ΠΎΠΏΡ†ΠΈΠΉ находится Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ [ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ β†’ React](../../README_RU.md#react). ## 4. Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ Π² package.json @@ -83,7 +83,7 @@ export const OpenFolderButton = () => ( // ошибка TypeScript ``` -Π’ΠΈΠΏΡ‹, способы отобраТСния ΠΈ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ†Π²Π΅Ρ‚Π°ΠΌΠΈ описаны Π² [основной Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ](../../README.md#способы-отобраТСния). +Π’ΠΈΠΏΡ‹, способы отобраТСния ΠΈ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ†Π²Π΅Ρ‚Π°ΠΌΠΈ описаны Π² [основной Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ](../../README_RU.md#способы-отобраТСния). Vite выпустит спрайт ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ„Π°ΠΉΠ»ΠΎΠΌ Π²ΠΈΠ΄Π° `assets/sprite-.svg`. SVG path-Π΄Π°Π½Π½Ρ‹Π΅ Π½Π΅ ΠΏΠΎΠΏΠ°Π΄ΡƒΡ‚ Π² JavaScript. diff --git a/skills/artifacts/svg-sprites/references/docs/ru/react-webpack.md b/skills/artifacts/svg-sprites/references/docs/ru/react-webpack.md index bd4ccd9..2a3c015 100644 --- a/skills/artifacts/svg-sprites/references/docs/ru/react-webpack.md +++ b/skills/artifacts/svg-sprites/references/docs/ru/react-webpack.md @@ -1,6 +1,6 @@ # React + Webpack 5 -[← Главная](../../README.md) +[← Главная](../../README_RU.md) ΠšΡ€Π°Ρ‚ΠΊΠ°Ρ инструкция ΠΏΠΎ установкС ΠΈ использованию SVG-спрайтов Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅ Π½Π° React ΠΈ Webpack 5. @@ -38,7 +38,7 @@ export default defineReactSpriteConfig({ По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ SVG бСрутся ΠΈΠ· `./icons`. ΠžΠ±Ρ‰ΠΈΠ΅ ΠΈΠΊΠΎΠ½ΠΊΠΈ ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΏΠ°ΠΏΠΎΠΊ ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· `inputFiles`: ΠΏΠ°ΠΏΠΊΠ° ΠΈ список ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‚ΡΡ Π² ΠΎΠ΄ΠΈΠ½ спрайт. -ΠŸΠΎΠ»Π½Ρ‹ΠΉ список ΠΎΠΏΡ†ΠΈΠΉ находится Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ [ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ β†’ React](../../README.md#react). +ΠŸΠΎΠ»Π½Ρ‹ΠΉ список ΠΎΠΏΡ†ΠΈΠΉ находится Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ [ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ β†’ React](../../README_RU.md#react). ## 4. Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ Π² package.json @@ -81,7 +81,7 @@ export const OpenFolderButton = () => ( // ошибка TypeScript ``` -Π’ΠΈΠΏΡ‹, способы отобраТСния ΠΈ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ†Π²Π΅Ρ‚Π°ΠΌΠΈ описаны Π² [основной Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ](../../README.md#способы-отобраТСния). +Π’ΠΈΠΏΡ‹, способы отобраТСния ΠΈ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ†Π²Π΅Ρ‚Π°ΠΌΠΈ описаны Π² [основной Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ](../../README_RU.md#способы-отобраТСния). Webpack ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ generated `new URL('./sprite.svg', import.meta.url)` Ρ‡Π΅Ρ€Π΅Π· Asset Modules ΠΈ выпустит ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ SVG asset. diff --git a/skills/svg-sprites/build.mjs b/skills/svg-sprites/build.mjs index 38d05c2..4923526 100644 --- a/skills/svg-sprites/build.mjs +++ b/skills/svg-sprites/build.mjs @@ -13,10 +13,9 @@ import { tmpdir } from 'node:os' import path from 'node:path' import { fileURLToPath } from 'node:url' -import config from './skill.config.mjs' +import configs from './skill.config.mjs' const skillDir = path.dirname(fileURLToPath(import.meta.url)) -const outputDir = path.resolve(skillDir, config.output) const artifactsDir = path.resolve(skillDir, '../artifacts') const isCheck = process.argv.slice(2).includes('--check') @@ -37,7 +36,7 @@ function assertInside(parentDir, childPath) { throw new Error(`Path is outside ${parentDir}: ${childPath}`) } -function validateConfig() { +function validateConfig(config, outputDir) { if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(config.name)) { throw new Error(`Invalid skill name: ${config.name}`) } @@ -68,7 +67,7 @@ function readRegularFile(filePath) { return readFileSync(filePath, 'utf8') } -function renderSkill() { +function renderSkill(config) { const sourcePath = path.resolve(skillDir, config.source) assertInside(skillDir, sourcePath) const body = readRegularFile(sourcePath).trim() @@ -80,17 +79,17 @@ function renderSkill() { `description: ${JSON.stringify(config.description)}`, '---', '', - '', + ``, '', body, '', ].join('\n') } -function buildSkill(targetDir) { +function buildSkill(config, targetDir) { rmSync(targetDir, { recursive: true, force: true }) mkdirSync(targetDir, { recursive: true }) - writeFileSync(path.join(targetDir, 'SKILL.md'), renderSkill()) + writeFileSync(path.join(targetDir, 'SKILL.md'), renderSkill(config)) for (const reference of config.references) { const sourcePath = path.resolve(skillDir, reference.from) @@ -133,7 +132,7 @@ function validateMarkdown(skillRoot, relativePath) { } } -function validateArtifact(skillRoot) { +function validateArtifact(config, skillRoot) { const expectedFiles = [ 'SKILL.md', ...config.references.map((reference) => reference.to), @@ -174,21 +173,36 @@ function compareArtifacts(expectedDir, actualDir) { } } -validateConfig() - -if (isCheck) { - const temporaryRoot = mkdtempSync(path.join(tmpdir(), 'svg-sprites-skill-')) - try { - const expectedDir = path.join(temporaryRoot, config.name) - buildSkill(expectedDir) - validateArtifact(expectedDir) - compareArtifacts(expectedDir, outputDir) - console.log(`Skill is up to date: ${path.relative(process.cwd(), outputDir)}`) - } finally { - rmSync(temporaryRoot, { recursive: true, force: true }) - } -} else { - buildSkill(outputDir) - validateArtifact(outputDir) - console.log(`Built skill: ${path.relative(process.cwd(), outputDir)}`) +if (!Array.isArray(configs) || configs.length === 0) { + throw new Error('Skill configs must be a non-empty array') +} + +const names = new Set() +const outputs = new Set() + +for (const config of configs) { + const outputDir = path.resolve(skillDir, config.output) + validateConfig(config, outputDir) + + if (names.has(config.name)) throw new Error(`Duplicate skill name: ${config.name}`) + if (outputs.has(outputDir)) throw new Error(`Duplicate skill output: ${config.output}`) + names.add(config.name) + outputs.add(outputDir) + + if (isCheck) { + const temporaryRoot = mkdtempSync(path.join(tmpdir(), `${config.name}-skill-`)) + try { + const expectedDir = path.join(temporaryRoot, config.name) + buildSkill(config, expectedDir) + validateArtifact(config, expectedDir) + compareArtifacts(expectedDir, outputDir) + console.log(`Skill is up to date: ${path.relative(process.cwd(), outputDir)}`) + } finally { + rmSync(temporaryRoot, { recursive: true, force: true }) + } + } else { + buildSkill(config, outputDir) + validateArtifact(config, outputDir) + console.log(`Built skill: ${path.relative(process.cwd(), outputDir)}`) + } } diff --git a/skills/svg-sprites/skill.config.mjs b/skills/svg-sprites/skill.config.mjs index 9bc7577..4de3b7d 100644 --- a/skills/svg-sprites/skill.config.mjs +++ b/skills/svg-sprites/skill.config.mjs @@ -1,16 +1,35 @@ -export default { - name: 'svg-sprites', - description: 'Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ ΠΏΡ€ΠΈ настройкС, Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ, ΠΌΠΈΠ³Ρ€Π°Ρ†ΠΈΠΈ ΠΈΠ»ΠΈ диагностикС SVG-спрайтов Ρ‡Π΅Ρ€Π΅Π· @gromlab/svg-sprites. Π’Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹: SVG sprite, SVG-спрайт, svg-sprites, svg-sprite.config.ts, svg-sprites.config.ts, defineReactSpriteConfig, defineNextSpriteConfig, react@vite, react@webpack, next@app, next@pages, inputFiles, SpriteViewer, icon="...", --icon-color-N, generated-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΈΠ»ΠΈ ΠΈΠΊΠΎΠ½ΠΊΠ° Π½Π΅ появилась Π² ΠΏΡ€Π΅Π²ΡŒΡŽ ΠΈ Π°Π²Ρ‚ΠΎΠ΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ. НЕ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ для favicon, растровых ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ, icon fonts, Π²Ρ‹Π±ΠΎΡ€Π° Π½Π°Π±ΠΎΡ€Π° ΠΈΠΊΠΎΠ½ΠΎΠΊ ΠΈΠ»ΠΈ inline SVG Π±Π΅Π· спрайтов.', - source: 'src/SKILL.md', - output: '../artifacts/svg-sprites', - references: [ - { from: '../../README.md', to: 'references/README.md' }, - { from: '../../docs/ru/react-vite.md', to: 'references/docs/ru/react-vite.md' }, - { from: '../../docs/ru/react-webpack.md', to: 'references/docs/ru/react-webpack.md' }, - { from: '../../docs/ru/next-app.md', to: 'references/docs/ru/next-app.md' }, - { from: '../../docs/ru/next-pages.md', to: 'references/docs/ru/next-pages.md' }, - { from: '../../docs/ru/legacy.md', to: 'references/docs/ru/legacy.md' }, - { from: '../../docs/ru/migration-1.md', to: 'references/docs/ru/migration-1.md' }, - { from: '../../docs/ru/programmatic-api.md', to: 'references/docs/ru/programmatic-api.md' }, - ], -} +const references = [ + { from: '../../README.md', to: 'references/README.md' }, + { from: '../../README_RU.md', to: 'references/README_RU.md' }, + { from: '../../docs/en/react-vite.md', to: 'references/docs/en/react-vite.md' }, + { from: '../../docs/en/react-webpack.md', to: 'references/docs/en/react-webpack.md' }, + { from: '../../docs/en/next-app.md', to: 'references/docs/en/next-app.md' }, + { from: '../../docs/en/next-pages.md', to: 'references/docs/en/next-pages.md' }, + { from: '../../docs/en/legacy.md', to: 'references/docs/en/legacy.md' }, + { from: '../../docs/en/migration-1.md', to: 'references/docs/en/migration-1.md' }, + { from: '../../docs/en/programmatic-api.md', to: 'references/docs/en/programmatic-api.md' }, + { from: '../../docs/ru/react-vite.md', to: 'references/docs/ru/react-vite.md' }, + { from: '../../docs/ru/react-webpack.md', to: 'references/docs/ru/react-webpack.md' }, + { from: '../../docs/ru/next-app.md', to: 'references/docs/ru/next-app.md' }, + { from: '../../docs/ru/next-pages.md', to: 'references/docs/ru/next-pages.md' }, + { from: '../../docs/ru/legacy.md', to: 'references/docs/ru/legacy.md' }, + { from: '../../docs/ru/migration-1.md', to: 'references/docs/ru/migration-1.md' }, + { from: '../../docs/ru/programmatic-api.md', to: 'references/docs/ru/programmatic-api.md' }, +] + +export default [ + { + name: 'svg-sprites', + description: 'Use when configuring, generating, migrating, or troubleshooting SVG sprites with @gromlab/svg-sprites. Triggers: SVG sprite, svg-sprites, svg-sprite.config.ts, svg-sprites.config.ts, defineReactSpriteConfig, defineNextSpriteConfig, react@vite, react@webpack, next@app, next@pages, inputFiles, SpriteViewer, icon="...", --icon-color-N, generated component, or an icon missing from preview or autocomplete. Do NOT use for favicons, raster images, icon fonts, choosing an icon set, or inline SVG without sprites.', + source: 'src/SKILL.md', + output: '../artifacts/svg-sprites', + references, + }, + { + name: 'svg-sprites-ru', + description: 'Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ ΠΏΡ€ΠΈ настройкС, Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ, ΠΌΠΈΠ³Ρ€Π°Ρ†ΠΈΠΈ ΠΈΠ»ΠΈ диагностикС SVG-спрайтов Ρ‡Π΅Ρ€Π΅Π· @gromlab/svg-sprites. Π’Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹: SVG sprite, SVG-спрайт, svg-sprites, svg-sprite.config.ts, svg-sprites.config.ts, defineReactSpriteConfig, defineNextSpriteConfig, react@vite, react@webpack, next@app, next@pages, inputFiles, SpriteViewer, icon="...", --icon-color-N, generated-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΈΠ»ΠΈ ΠΈΠΊΠΎΠ½ΠΊΠ° Π½Π΅ появилась Π² ΠΏΡ€Π΅Π²ΡŒΡŽ ΠΈ Π°Π²Ρ‚ΠΎΠ΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ. НЕ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ для favicon, растровых ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ, icon fonts, Π²Ρ‹Π±ΠΎΡ€Π° Π½Π°Π±ΠΎΡ€Π° ΠΈΠΊΠΎΠ½ΠΎΠΊ ΠΈΠ»ΠΈ inline SVG Π±Π΅Π· спрайтов.', + source: 'src/SKILL_RU.md', + output: '../artifacts/svg-sprites-ru', + references, + }, +] diff --git a/skills/svg-sprites/src/SKILL.md b/skills/svg-sprites/src/SKILL.md index 31e0f56..e3e868c 100644 --- a/skills/svg-sprites/src/SKILL.md +++ b/skills/svg-sprites/src/SKILL.md @@ -1,57 +1,57 @@ # SVG Sprites -## НазначСниС +## Purpose -Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ этот скил для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с `@gromlab/svg-sprites`: ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½ΠΎΠΉ настройки, добавлСния ΠΈ ΠΏΠ΅Ρ€Π΅ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΈΠΊΠΎΠ½ΠΎΠΊ, Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ React-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ², ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ `SpriteViewer`, ΠΌΠΈΠ³Ρ€Π°Ρ†ΠΈΠΈ legacy-ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ ΠΈ диагностики ошибок. +Use this skill when working with `@gromlab/svg-sprites`: initial setup, adding and reusing icons, generating React components, integrating `SpriteViewer`, migrating legacy configurations, and troubleshooting errors. -НС навязывай ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρƒ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΡƒΡŽ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Ρƒ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ΠΎΠ². Π‘Π½Π°Ρ‡Π°Π»Π° ΠΈΠ·ΡƒΡ‡ΠΈ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ `package.json`, ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ спрайта, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ, Ρ€ΠΎΡƒΡ‚Π΅Ρ€ ΠΈ сборщик. +Do not impose a specific directory architecture on the project. First inspect the existing `package.json`, sprite configuration, framework, router, and bundler. -## Π Π°Π±ΠΎΡ‡ΠΈΠΉ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ +## Workflow -1. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅ΠΆΠΈΠΌ ΠΈ Π½Π΅ смСшивай Π΅Π³ΠΎ API с Π΄Ρ€ΡƒΠ³ΠΈΠΌ Ρ€Π΅ΠΆΠΈΠΌΠΎΠΌ. -2. Для React Π²Ρ‹Π±Π΅Ρ€ΠΈ `react@vite` ΠΈΠ»ΠΈ `react@webpack` ΠΈ ΠΎΡ‚ΠΊΡ€ΠΎΠΉ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ reference. -3. Для Next.js ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈ App Router ΠΈΠ»ΠΈ Pages Router, Π·Π°Ρ‚Π΅ΠΌ Turbopack ΠΈΠ»ΠΈ Webpack, ΠΈ ΠΎΡ‚ΠΊΡ€ΠΎΠΉ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ reference. -4. Для ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ `svg-sprites.config.ts` с нСсколькими спрайтами ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ legacy-Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ. НС ΠΌΠΈΠ³Ρ€ΠΈΡ€ΡƒΠΉ Ρ‚Π°ΠΊΠΎΠΉ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ Π±Π΅Π· явного запроса. -5. Π˜Π·ΡƒΡ‡ΠΈ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ scripts ΠΈ добавляй Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ ΠΏΠ΅Ρ€Π΅Π΄ `dev`, `build` ΠΈ `typecheck`, Ссли generated-Ρ„Π°ΠΉΠ»Ρ‹ Π½Π΅ хранятся Π² Git. -6. ПослС измСнСния ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ ΠΈΠ»ΠΈ SVG запусти Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ, Π·Π°Ρ‚Π΅ΠΌ Π΄ΠΎΡΡ‚ΡƒΠΏΠ½ΡƒΡŽ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ Ρ‚ΠΈΠΏΠΎΠ² ΠΈΠ»ΠΈ сборку ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°. +1. Identify the existing mode and do not mix its API with another mode. +2. For React, choose `react@vite` or `react@webpack` and open the corresponding reference. +3. For Next.js, identify the App Router or Pages Router, then Turbopack or Webpack, and open the corresponding reference. +4. For an existing `svg-sprites.config.ts` with multiple sprites, use the legacy documentation. Do not migrate such a project unless explicitly requested. +5. Inspect local scripts and run generation before `dev`, `build`, and `typecheck` when generated files are not committed to Git. +6. After changing a configuration or SVG file, run generation followed by the available type check or project build. -## ΠŸΡ€Π°Π²ΠΈΠ»Π° React ΠΈ Next.js +## React And Next.js Rules -- Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ `svg-sprite.config.ts` ΠΈ подходящий config helper: `defineReactSpriteConfig` ΠΈΠ»ΠΈ `defineNextSpriteConfig`. -- НС Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΡƒΠΉ `generated/`, `index.ts`, `manifest.ts` ΠΈ созданный Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠΌ `.gitignore` Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ. -- ИмСна исходных SVG становятся допустимыми значСниями prop `icon`; ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ generated-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΈ Π΅Π³ΠΎ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ вмСсто deep imports. -- ОбъСдиняй Π»ΠΎΠΊΠ°Π»ΡŒΠ½ΡƒΡŽ ΠΏΠ°ΠΏΠΊΡƒ ΠΈ `inputFiles`, ΠΊΠΎΠ³Π΄Π° общая ΠΈΠΊΠΎΠ½ΠΊΠ° Π½ΡƒΠΆΠ½Π° нСскольким спрайтам. НС создавай ΠΊΠΎΠΏΠΈΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ SVG Π±Π΅Π· нСобходимости. -- Π’ Next.js generated-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² Server Components, SSR ΠΈ SSG. НС добавляй `'use client'` Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ€Π°Π΄ΠΈ ΠΈΠΊΠΎΠ½ΠΊΠΈ. -- Π‘ΠΏΡ€Π°ΠΉΡ‚ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΡΡ‚Π°Π²Π°Ρ‚ΡŒΡΡ внСшним asset сборщика: Π½Π΅ ΠΏΠ΅Ρ€Π΅Π½ΠΎΡΠΈΡ‚ΡŒ SVG path-Π΄Π°Π½Π½Ρ‹Π΅ Π² JavaScript ΠΈ Π½Π΅ ΠΊΠ»Π°ΡΡ‚ΡŒ generated-Ρ„Π°ΠΉΠ» Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ Π² `public`. +- Use a local `svg-sprite.config.ts` and the appropriate config helper: `defineReactSpriteConfig` or `defineNextSpriteConfig`. +- Do not manually edit `generated/`, `index.ts`, `manifest.ts`, or the generator-created `.gitignore`. +- Source SVG names become valid values for the `icon` prop; use the generated component and its public types instead of deep imports. +- Combine the local folder with `inputFiles` when multiple sprites need a shared icon. Do not create unnecessary copies of the same SVG. +- In Next.js, generated components work in Server Components, SSR, and SSG. Do not add `'use client'` only for an icon. +- Keep the sprite as an external bundler asset: do not move SVG path data into JavaScript or manually place the generated file in `public`. -## Π¦Π²Π΅Ρ‚Π° ΠΈ трансформации +## Colors And Transformations -- По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ удаляСт `width` ΠΈ `height`, замСняСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Π΅ `fill` ΠΈ `stroke` Π½Π° CSS-ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΈ добавляСт transitions. -- Для ΠΌΠΎΠ½ΠΎΡ…Ρ€ΠΎΠΌΠ½ΠΎΠΉ ΠΈΠΊΠΎΠ½ΠΊΠΈ сначала управляй `color`; для ΠΌΠ½ΠΎΠ³ΠΎΡ†Π²Π΅Ρ‚Π½ΠΎΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ `--icon-color-N`. -- НС ΠΎΠ±Π΅Ρ‰Π°ΠΉ Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΡ‡Π΅ΡΠΊΡƒΡŽ Π·Π°ΠΌΠ΅Π½Ρƒ Ρ†Π²Π΅Ρ‚ΠΎΠ² Π²Π½ΡƒΡ‚Ρ€ΠΈ Π²Π½Π΅ΡˆΠ½ΠΈΡ… stylesheets, gradients, patterns, filters ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ `url(#...)` Π±Π΅Π· ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°. -- CSS-ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ страницы Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ ΠΏΡ€ΠΈ ``, Π½ΠΎ Π½Π΅ ΠΏΡ€ΠΎΠ½ΠΈΠΊΠ°ΡŽΡ‚ Π²Π½ΡƒΡ‚Ρ€ΡŒ `` ΠΈ `background-image`. +- By default, the generator removes `width` and `height`, replaces supported `fill` and `stroke` values with CSS variables, and adds transitions. +- For a monochrome icon, control `color` first; for a multicolor icon, use `--icon-color-N`. +- Do not promise automatic color replacement inside external stylesheets, gradients, patterns, filters, or `url(#...)` values without checking the result. +- Page CSS variables work with ``, but do not propagate into `` or `background-image`. -## ΠŸΡ€Π΅Π²ΡŒΡŽ +## Preview -Для React ΠΈ Next.js ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°ΠΉ `` ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΉ debug-страницСй прилоТСния. ΠŸΠ΅Ρ€Π΅Π΄Π°ΠΉ Π΅ΠΌΡƒ manifests ΠΈΠ»ΠΈ lazy loaders спрайтов. Viewer ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ поиск, ΡΠ²Π΅Ρ‚Π»ΡƒΡŽ ΠΈ Ρ‚Ρ‘ΠΌΠ½ΡƒΡŽ Ρ‚Π΅ΠΌΡ‹, настройку Ρ†Π²Π΅Ρ‚ΠΎΠ² ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ React, SVG, IMG ΠΈ CSS. +For React and Next.js, add `` as a separate debug page in the application. Pass sprite manifests or lazy loaders to it. The Viewer supports search, light and dark themes, color controls, and React, SVG, IMG, and CSS examples. -`SpriteViewer` являСтся клиСнтским debug-инструмСнтом ΠΈ импортируСтся ΠΈΠ· `@gromlab/svg-sprites/react`; production-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ ΠΈΠΊΠΎΠ½ΠΎΠΊ ΠΎΡ‚ Π½Π΅Π³ΠΎ Π½Π΅ зависят. +`SpriteViewer` is a client-side debug tool imported from `@gromlab/svg-sprites/react`; production icon components do not depend on it. -## Диагностика +## Troubleshooting -- Если имя ΠΈΠΊΠΎΠ½ΠΊΠΈ отсутствуСт Π² Π°Π²Ρ‚ΠΎΠ΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒ Π²Ρ…ΠΎΠ΄Π½ΡƒΡŽ ΠΏΠ°ΠΏΠΊΡƒ ΠΈ `inputFiles`, Π·Π°Ρ‚Π΅ΠΌ пСрСзапусти Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ. -- Если Π΄Π²Π° Ρ„Π°ΠΉΠ»Π° ΠΈΠΌΠ΅ΡŽΡ‚ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΠΎΠ΅ имя ΠΈΠΊΠΎΠ½ΠΊΠΈ, устрани ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚ вмСсто Π²Ρ‹Π±ΠΎΡ€Π° ΠΎΠ΄Π½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π° нСявно. -- Если Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ отказываСтся ΠΏΠ΅Ρ€Π΅Π·Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ Ρ„Π°ΠΉΠ», Π½Π΅ удаляй Π·Π°Ρ‰ΠΈΡ‚Π½Ρ‹ΠΉ marker ΠΈ Π½Π΅ ΠΎΠ±Ρ…ΠΎΠ΄ΠΈ writer: пСрСнСси ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ Ρ„Π°ΠΉΠ» ΠΈΠ»ΠΈ Π²Ρ‹Π±Π΅Ρ€ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ спрайта. -- Если asset Π½Π΅ загруТаСтся, сначала ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒ соотвСтствиС CLI mode Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΌΡƒ сборщику ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ generated SVG Π΅Π³ΠΎ asset pipeline. -- Если ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ старый API, ΡΠ²Π΅Ρ€ΡŒ ΡƒΡΡ‚Π°Π½ΠΎΠ²Π»Π΅Π½Π½ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ ΠΏΠ°ΠΊΠ΅Ρ‚Π° ΠΈ legacy reference ΠΏΠ΅Ρ€Π΅Π΄ измСнСниями. +- If an icon name is missing from autocomplete, check the input folder and `inputFiles`, then rerun generation. +- If two files have the same icon name, resolve the conflict instead of implicitly selecting one file. +- If the generator refuses to overwrite a file, do not remove the protection marker or bypass the writer: move the user file or choose another sprite directory. +- If an asset fails to load, first confirm that the CLI mode matches the project's actual bundler and that its asset pipeline handles the generated SVG. +- If the project uses the old API, check the installed package version and the legacy reference before making changes. ## References -- [Основная докумСнтация ΠΈ API](./references/README.md) -- [React + Vite](./references/docs/ru/react-vite.md) -- [React + Webpack 5](./references/docs/ru/react-webpack.md) -- [Next.js App Router](./references/docs/ru/next-app.md) -- [Next.js Pages Router](./references/docs/ru/next-pages.md) -- [Legacy mode](./references/docs/ru/legacy.md) -- [ΠœΠΈΠ³Ρ€Π°Ρ†ΠΈΡ с 0.1.x](./references/docs/ru/migration-1.md) -- [ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ API](./references/docs/ru/programmatic-api.md) +- [Main documentation and API](./references/README.md) +- [React + Vite](./references/docs/en/react-vite.md) +- [React + Webpack 5](./references/docs/en/react-webpack.md) +- [Next.js App Router](./references/docs/en/next-app.md) +- [Next.js Pages Router](./references/docs/en/next-pages.md) +- [Legacy mode](./references/docs/en/legacy.md) +- [Migrating from 0.1.x](./references/docs/en/migration-1.md) +- [Programmatic API](./references/docs/en/programmatic-api.md) diff --git a/skills/svg-sprites/src/SKILL_RU.md b/skills/svg-sprites/src/SKILL_RU.md new file mode 100644 index 0000000..e1a1a78 --- /dev/null +++ b/skills/svg-sprites/src/SKILL_RU.md @@ -0,0 +1,57 @@ +# SVG Sprites + +## НазначСниС + +Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ этот скил для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с `@gromlab/svg-sprites`: ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½ΠΎΠΉ настройки, добавлСния ΠΈ ΠΏΠ΅Ρ€Π΅ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΈΠΊΠΎΠ½ΠΎΠΊ, Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ React-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ², ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ `SpriteViewer`, ΠΌΠΈΠ³Ρ€Π°Ρ†ΠΈΠΈ legacy-ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ ΠΈ диагностики ошибок. + +НС навязывай ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρƒ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΡƒΡŽ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Ρƒ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ΠΎΠ². Π‘Π½Π°Ρ‡Π°Π»Π° ΠΈΠ·ΡƒΡ‡ΠΈ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ `package.json`, ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ спрайта, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ, Ρ€ΠΎΡƒΡ‚Π΅Ρ€ ΠΈ сборщик. + +## Π Π°Π±ΠΎΡ‡ΠΈΠΉ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ + +1. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅ΠΆΠΈΠΌ ΠΈ Π½Π΅ смСшивай Π΅Π³ΠΎ API с Π΄Ρ€ΡƒΠ³ΠΈΠΌ Ρ€Π΅ΠΆΠΈΠΌΠΎΠΌ. +2. Для React Π²Ρ‹Π±Π΅Ρ€ΠΈ `react@vite` ΠΈΠ»ΠΈ `react@webpack` ΠΈ ΠΎΡ‚ΠΊΡ€ΠΎΠΉ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ reference. +3. Для Next.js ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈ App Router ΠΈΠ»ΠΈ Pages Router, Π·Π°Ρ‚Π΅ΠΌ Turbopack ΠΈΠ»ΠΈ Webpack, ΠΈ ΠΎΡ‚ΠΊΡ€ΠΎΠΉ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ reference. +4. Для ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ `svg-sprites.config.ts` с нСсколькими спрайтами ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ legacy-Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ. НС ΠΌΠΈΠ³Ρ€ΠΈΡ€ΡƒΠΉ Ρ‚Π°ΠΊΠΎΠΉ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ Π±Π΅Π· явного запроса. +5. Π˜Π·ΡƒΡ‡ΠΈ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ scripts ΠΈ добавляй Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ ΠΏΠ΅Ρ€Π΅Π΄ `dev`, `build` ΠΈ `typecheck`, Ссли generated-Ρ„Π°ΠΉΠ»Ρ‹ Π½Π΅ хранятся Π² Git. +6. ПослС измСнСния ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ ΠΈΠ»ΠΈ SVG запусти Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ, Π·Π°Ρ‚Π΅ΠΌ Π΄ΠΎΡΡ‚ΡƒΠΏΠ½ΡƒΡŽ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ Ρ‚ΠΈΠΏΠΎΠ² ΠΈΠ»ΠΈ сборку ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°. + +## ΠŸΡ€Π°Π²ΠΈΠ»Π° React ΠΈ Next.js + +- Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ `svg-sprite.config.ts` ΠΈ подходящий config helper: `defineReactSpriteConfig` ΠΈΠ»ΠΈ `defineNextSpriteConfig`. +- НС Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΡƒΠΉ `generated/`, `index.ts`, `manifest.ts` ΠΈ созданный Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠΌ `.gitignore` Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ. +- ИмСна исходных SVG становятся допустимыми значСниями prop `icon`; ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ generated-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΈ Π΅Π³ΠΎ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ вмСсто deep imports. +- ОбъСдиняй Π»ΠΎΠΊΠ°Π»ΡŒΠ½ΡƒΡŽ ΠΏΠ°ΠΏΠΊΡƒ ΠΈ `inputFiles`, ΠΊΠΎΠ³Π΄Π° общая ΠΈΠΊΠΎΠ½ΠΊΠ° Π½ΡƒΠΆΠ½Π° нСскольким спрайтам. НС создавай ΠΊΠΎΠΏΠΈΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ SVG Π±Π΅Π· нСобходимости. +- Π’ Next.js generated-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² Server Components, SSR ΠΈ SSG. НС добавляй `'use client'` Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ€Π°Π΄ΠΈ ΠΈΠΊΠΎΠ½ΠΊΠΈ. +- Π‘ΠΏΡ€Π°ΠΉΡ‚ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΡΡ‚Π°Π²Π°Ρ‚ΡŒΡΡ внСшним asset сборщика: Π½Π΅ ΠΏΠ΅Ρ€Π΅Π½ΠΎΡΠΈΡ‚ΡŒ SVG path-Π΄Π°Π½Π½Ρ‹Π΅ Π² JavaScript ΠΈ Π½Π΅ ΠΊΠ»Π°ΡΡ‚ΡŒ generated-Ρ„Π°ΠΉΠ» Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ Π² `public`. + +## Π¦Π²Π΅Ρ‚Π° ΠΈ трансформации + +- По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ удаляСт `width` ΠΈ `height`, замСняСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Π΅ `fill` ΠΈ `stroke` Π½Π° CSS-ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΈ добавляСт transitions. +- Для ΠΌΠΎΠ½ΠΎΡ…Ρ€ΠΎΠΌΠ½ΠΎΠΉ ΠΈΠΊΠΎΠ½ΠΊΠΈ сначала управляй `color`; для ΠΌΠ½ΠΎΠ³ΠΎΡ†Π²Π΅Ρ‚Π½ΠΎΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ `--icon-color-N`. +- НС ΠΎΠ±Π΅Ρ‰Π°ΠΉ Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΡ‡Π΅ΡΠΊΡƒΡŽ Π·Π°ΠΌΠ΅Π½Ρƒ Ρ†Π²Π΅Ρ‚ΠΎΠ² Π²Π½ΡƒΡ‚Ρ€ΠΈ Π²Π½Π΅ΡˆΠ½ΠΈΡ… stylesheets, gradients, patterns, filters ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ `url(#...)` Π±Π΅Π· ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°. +- CSS-ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ страницы Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ ΠΏΡ€ΠΈ ``, Π½ΠΎ Π½Π΅ ΠΏΡ€ΠΎΠ½ΠΈΠΊΠ°ΡŽΡ‚ Π²Π½ΡƒΡ‚Ρ€ΡŒ `` ΠΈ `background-image`. + +## ΠŸΡ€Π΅Π²ΡŒΡŽ + +Для React ΠΈ Next.js ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°ΠΉ `` ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΉ debug-страницСй прилоТСния. ΠŸΠ΅Ρ€Π΅Π΄Π°ΠΉ Π΅ΠΌΡƒ manifests ΠΈΠ»ΠΈ lazy loaders спрайтов. Viewer ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ поиск, ΡΠ²Π΅Ρ‚Π»ΡƒΡŽ ΠΈ Ρ‚Ρ‘ΠΌΠ½ΡƒΡŽ Ρ‚Π΅ΠΌΡ‹, настройку Ρ†Π²Π΅Ρ‚ΠΎΠ² ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ React, SVG, IMG ΠΈ CSS. + +`SpriteViewer` являСтся клиСнтским debug-инструмСнтом ΠΈ импортируСтся ΠΈΠ· `@gromlab/svg-sprites/react`; production-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ ΠΈΠΊΠΎΠ½ΠΎΠΊ ΠΎΡ‚ Π½Π΅Π³ΠΎ Π½Π΅ зависят. + +## Диагностика + +- Если имя ΠΈΠΊΠΎΠ½ΠΊΠΈ отсутствуСт Π² Π°Π²Ρ‚ΠΎΠ΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒ Π²Ρ…ΠΎΠ΄Π½ΡƒΡŽ ΠΏΠ°ΠΏΠΊΡƒ ΠΈ `inputFiles`, Π·Π°Ρ‚Π΅ΠΌ пСрСзапусти Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ. +- Если Π΄Π²Π° Ρ„Π°ΠΉΠ»Π° ΠΈΠΌΠ΅ΡŽΡ‚ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΠΎΠ΅ имя ΠΈΠΊΠΎΠ½ΠΊΠΈ, устрани ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚ вмСсто Π²Ρ‹Π±ΠΎΡ€Π° ΠΎΠ΄Π½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π° нСявно. +- Если Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ отказываСтся ΠΏΠ΅Ρ€Π΅Π·Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ Ρ„Π°ΠΉΠ», Π½Π΅ удаляй Π·Π°Ρ‰ΠΈΡ‚Π½Ρ‹ΠΉ marker ΠΈ Π½Π΅ ΠΎΠ±Ρ…ΠΎΠ΄ΠΈ writer: пСрСнСси ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ Ρ„Π°ΠΉΠ» ΠΈΠ»ΠΈ Π²Ρ‹Π±Π΅Ρ€ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ спрайта. +- Если asset Π½Π΅ загруТаСтся, сначала ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒ соотвСтствиС CLI mode Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΌΡƒ сборщику ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ generated SVG Π΅Π³ΠΎ asset pipeline. +- Если ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ старый API, ΡΠ²Π΅Ρ€ΡŒ ΡƒΡΡ‚Π°Π½ΠΎΠ²Π»Π΅Π½Π½ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ ΠΏΠ°ΠΊΠ΅Ρ‚Π° ΠΈ legacy reference ΠΏΠ΅Ρ€Π΅Π΄ измСнСниями. + +## References + +- [Основная докумСнтация ΠΈ API](./references/README_RU.md) +- [React + Vite](./references/docs/ru/react-vite.md) +- [React + Webpack 5](./references/docs/ru/react-webpack.md) +- [Next.js App Router](./references/docs/ru/next-app.md) +- [Next.js Pages Router](./references/docs/ru/next-pages.md) +- [Legacy mode](./references/docs/ru/legacy.md) +- [ΠœΠΈΠ³Ρ€Π°Ρ†ΠΈΡ с 0.1.x](./references/docs/ru/migration-1.md) +- [ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ API](./references/docs/ru/programmatic-api.md) diff --git a/src/modes/react/codegen.ts b/src/modes/react/codegen.ts index 560ffdb..755f2ff 100644 --- a/src/modes/react/codegen.ts +++ b/src/modes/react/codegen.ts @@ -16,7 +16,7 @@ const GENERATED_NOTICE = [ '## Для ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ ΠΏΠ΅Ρ€Π΅Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠΉΡ‚Π΅ SVG-спрайт. ##', '## ##', '## Π“Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€: @gromlab/svg-sprites ##', - '## Π Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ: https://gromlab.ru/gromov/svg-sprites ##', + '## Π Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ: https://github.com/gromov-sergei/svg-sprites ##', '----------------------------------------------------------------------', ] diff --git a/src/react/sprite-viewer.tsx b/src/react/sprite-viewer.tsx index 9518636..471ea12 100644 --- a/src/react/sprite-viewer.tsx +++ b/src/react/sprite-viewer.tsx @@ -284,7 +284,7 @@ export function SpriteViewer({
{selected && (