Initial ui-kit: Button, дизайн-токены, сборка Vite, Storybook

This commit is contained in:
Тимур Городецкий
2026-08-13 12:33:41 +05:00
commit c12c5b591b
18 changed files with 6709 additions and 0 deletions
+98
View File
@@ -0,0 +1,98 @@
# @tnsu/ui-kit — память проекта
Единый пакет UI-компонентов для SPFx web part'ов ТНСУ + Storybook как витрина.
Этот файл — источник правды по решениям, плану и прогрессу. Обновлять по ходу работы.
## Зачем проект
У команды много SPFx web part'ов в **разных репозиториях** (request-portal, бывший
1c-ticket-form, pto-tracker и др.). В каждом дизайн разъезжается, компоненты копируются
и пишутся заново. Цель — вынести компоненты в один npm-пакет, подключать его в любую
web part через `npm i`, и держать единый вид через дизайн-токены.
Источник компонентов: `request-portal/src/webparts/requestPortal/shared/ui/` — там уже
~30 чистых компонентов на SCSS-модулях с barrel-экспортом (`ui/index.ts`). Это база.
## Ключевые архитектурные решения
- **Гибридный подход**: отдельный репозиторий `tnsu-ui-kit` (пакет + Storybook),
публикуется в GitLab Package Registry. Существующие web part'ы остаются в своих репах
и просто ставят пакет. НЕ монорепо (не хотим переселять существующие проекты).
- **Сборка — Vite (library mode)**, не tsup. Причина: компоненты на `.module.scss`,
Vite понимает SCSS-модули из коробки и он же движок Storybook → один инструмент.
- **React/Fluent/tslib — только `peerDependencies`** (React 17, @fluentui/react 8, tslib).
Защита от двух React в бандле («Invalid hook call»). Локально те же версии стоят как
devDependencies для сборки и Storybook.
- **Дизайн-токены** (`tokens.scss`: цвета, отступы, радиусы) — единый рычаг общего вида.
Компоненты тянут значения оттуда, а не хардкодят.
- **Скоуп имени `@tnsu`** — сверить с именем группы в GitLab на шаге публикации.
Пока имя ни на что не влияет, переименование = find-replace.
- **Что переносим**: только чистые UI-примитивы (Button, TextInput, FormCard, Select,
ItemsTable, PeopleField...). НЕ переносим бизнес-логику: `approval/`, `pnp/`,
`dictionary/`, сервисы SharePoint — они привязаны к спискам. Возможно позже отдельный
пакет `@tnsu/sp-core`.
- **Расширение через пропсы**, не форки. Если в старом проекте компонент выглядел иначе —
добавляем `variant`/`size` в ui-kit, а не плодим копии.
- **Версии инструментов синхронны с SPFx**: TypeScript пинить на `~5.8.0` (как в
request-portal). Без пина `npm i typescript` ставит TS 7 (нативный компилятор без
JS Compiler API) — vite-plugin-dts падает. То же правило для React/Fluent.
## План (маршрут)
1. [x] Скелет репо — папка, git, package.json, зависимости
2. [x] Сборка (Vite) — vite.config.ts, пакет собирается в dist/
3. [x] Первый компонент — Button перенесён, сборка чистая
4. [x] Дизайн-токены — src/tokens/_tokens.scss перенесён из request-portal
5. [x] Storybook — витрина работает (SB 10.4 + Vite), Button виден со всеми вариантами
6. [x] Публикация — @tnsu/ui-kit@0.0.1 опубликован в Gitea (это Gitea 1.26.4, НЕ GitLab!)
7. [~] Потребление проверено ПОЛНОСТЬЮ: request-portal собрался (heft webpack ок) +
кнопки из пакета отрисовались в SharePoint workbench со стилями (accent-золото,
secondary-рамки). CSS из пакета применяется в рантайме. Осталась публикация в registry.
ВАЖНО про потребление (проверено 2026-08-13):
- Тест через локальный тарбол (`npm pack` → `npm i ../tnsu-ui-kit/*.tgz`), НЕ npm link
(link тащит второй React → Invalid hook call).
- CSS подключается в SPFx через `import '@tnsu/ui-kit/styles.css'` в корневом компоненте
веб-парта (RequestPortal.tsx). SPFx-webpack (5.95) обрабатывает .css из node_modules — ОК.
- Заменён Button в SubmitActions.tsx (`../Button/Button` → `@tnsu/ui-kit`). Правки НЕ
коммитить, пока пакет не опубликован в registry (сейчас ссылается на file:-тарбол).
Известный tech-debt: Sass `@import` устарел (Dart Sass 3.0). Мигрировать токены и
модули на `@use`/`@forward` — отдельной задачей, сейчас работает с варнингом.
## Прогресс / журнал
- **Шаг 1 готов**: создан репо `C:\Users\gorodetskiy.timur\Documents\Projects\tnsu-ui-kit`,
`git init`, болванка package.json.
- **Шаг 2 в работе**: переписан package.json (@tnsu/ui-kit, exports, peerDeps, Vite-скрипты),
ставятся devDependencies, добавлен .gitignore.
## Как мигрировать старый проект (памятка на будущее)
1. `npm i @tnsu/ui-kit` — ничего не ломается, пакет просто лежит рядом.
2. Заменяем импорты по одному компоненту/форме: `../shared/ui` → `@tnsu/ui-kit`.
Пропсы те же, JSX не меняется. Старый и новый компонент могут сосуществовать.
3. Проверили форму → удалили старый компонент из `shared/ui`.
4. Повторяем, пока `shared/ui` не опустеет.
5. Перед миграцией проекта проверить: его версии React/Fluent совместимы с peerDeps ui-kit.
## Публикация (Gitea, НЕ GitLab!)
- Хостинг git — **Gitea 1.26.4** на http://git.tnsu.kz (не GitLab). Registry npm привязан
к ВЛАДЕЛЬЦУ, не к проекту. Никакого "project ID" не нужно.
- Адрес registry: `http://git.tnsu.kz/api/packages/timur.gorodetskiy/npm/`
- `.npmrc` в проекте (можно коммитить, НЕ секрет):
`@tnsu:registry=http://git.tnsu.kz/api/packages/timur.gorodetskiy/npm/`
- Токен (СЕКРЕТ) — в `~/.npmrc` (C:\Users\gorodetskiy.timur\.npmrc), в git НЕ попадает:
`//git.tnsu.kz/api/packages/timur.gorodetskiy/npm/:_authToken=<TOKEN>`
- Токен создаётся в Gitea: аватар → Настройки → Приложения → права `package` = Чтение и запись.
- Публикация: `npm run build && npm publish`. Бамп версии в package.json перед каждой
публикацией (npm не даёт перезаписать уже опубликованную версию).
- Потребителю (request-portal и др.) нужен такой же `@tnsu:registry` в его `.npmrc` +
свой токен на чтение пакетов.
## Окружение
- Node: v22.x (как в SPFx: >=22.14 <23)
- React 17.0.1, @fluentui/react ^8.106.4, tslib 2.3.1
- GitLab: http://git.tnsu.kz/timur.gorodetskiy/tnsu-ui-kit.git