--- description: EvoBGP WebUI — React 19, shadcn/ui (base-nova), ReUI, TanStack Router/Query globs: - apps/web/** - packages/ui/** alwaysApply: false --- # Web UI — React + shadcn/ui + ReUI **Источники правды:** - **ReUI PRO first:** MCP `user-reui` ([`reui-mcp.mdc`](reui-mcp.mdc)) — pages / KPI / lists / settings / shell - shadcn primitives: MCP `plugin-shadcn-shadcn` (secondary) - ReUI Base UI: https://reui.io/docs/components/base/ · [llms.txt](https://reui.io/llms.txt) - shadcn/ui React: https://ui.shadcn.com/docs/components Иерархия: **ReUI PRO > shadcn**. Общие: `.cursor/rules/engineering.mdc`, `context7-stack.mdc`. ## Слои UI | Слой | Путь | Назначение | |------|------|------------| | shadcn-примитивы | `packages/ui/src/components/` | output `shadcn add` (не трогать под кейс) | | ReUI enterprise | `apps/web/src/components/reui/` | output `shadcn add @reui/*` | | Shared обёртки | `apps/web/src/components/` | PageHeader, QueryState, ConfirmDialog, StatusBadge, LoadingButton | | ReUI kit | `apps/web/src/components/reui-kit/` | ResourcePage, KpiStatGrid, QuickActionGrid, OpsDashboard, SettingsShell, DetailPanel, FrameSection | | Роуты | `apps/web/src/routes/` | TanStack Router (file-based) | **Design contract:** [`docs/ui-design-contract.md`](../../docs/ui-design-contract.md). Surface: **frame**. KPI hybrid SoT: [stats-12](https://reui.io/preview/base/stats-12). Lists: [data-grid-filtering-2](https://reui.io/preview/base/data-grid-filtering-2). Page tabs: [c-tabs-9](https://reui.io/preview/base/components/c-tabs-9). Grid status: [c-toggle-group-5](https://reui.io/preview/base/components/c-toggle-group-5). Quick Actions: `QuickActionGrid`. Тема: `packages/ui/src/styles/globals.css`. CLI из `apps/web`: `pnpm dlx shadcn@latest add `. ## Правила **WEB-01** | MUST | Перед новым UI — сначала MCP **`user-reui`** (`search` → `get_block` / `compose_page`, `surface: "frame"`) + cite `previewUrl`/`docsUrl`. Primitives — MCP `plugin-shadcn-shadcn`. Только после — JSX. *Rationale:* ReUI PRO выше shadcn; единый Frame surface. *Проверка:* review; [`reui-mcp.mdc`](reui-mcp.mdc). **WEB-02** | MUST | Отсутствующий shadcn-примитив — `pnpm dlx shadcn@latest add ` (из `apps/web`). ReUI — `pnpm dlx shadcn@latest add @reui/`. *Проверка:* файлы в `packages/ui/src/components/` (для shadcn) или `apps/web/src/components/reui/` (для ReUI). **WEB-03** | NEVER | Альтернативные UI-kit'ы (Material, Vuetify, Tabler, Bootstrap утилиты). *Проверка:* `apps/web/package.json` review. **WEB-04** | MUST | Композиция по docs: использовать под-компоненты (`CardHeader`, `TableRow`, `TabsList`, …). *Проверка:* сверка с shadcn/ReUI docs. **WEB-05** | MUST | Формы — `react-hook-form` + Zod; через `FormField`/`Form` обёртки. *Проверка:* https://ui.shadcn.com/docs/components/form **WEB-06** | MUST | Сложные data-списки — Frame + ReUI DataGrid через `reui-kit/ResourcePage` (не Card shell, не shadcn Data Table). Surface lock: `UI_SURFACE = 'frame'` (`lib/ui-surface.ts`). Простые списки — shadcn `Table`. *Проверка:* `@/components/reui-kit`, `@/components/reui/data-grid`, `docs/ui-design-contract.md`. **WEB-06a** | MUST | Переключатели по роли UX: - секции страницы (Сеть / Операции / Справочники) — native `Tabs` default list (`SegmentedTabs`, [c-tabs-9](https://reui.io/preview/base/components/c-tabs-9)); - статус грида (Все/Вкл) — `ToggleGroup` в toolbar (`StatusToggleGroup`, [c-toggle-group-5](https://reui.io/preview/base/components/c-toggle-group-5)); - настройки — вертикальный Tabs rail ([settings-3](https://reui.io/preview/base/settings-3)). Не `variant="line"` для page/in-grid tabs. *Проверка:* `@/components/segmented-tabs`, `@/components/status-toggle-group`. **WEB-07** | MUST | Toast — `sonner` (`Toaster` в `main.tsx`); `toast.success/error/message` из `sonner`. *Проверка:* https://ui.shadcn.com/docs/components/sonner **WEB-08** | MUST | Иконки — `lucide-react` (`components.json` → `iconLibrary: lucide`). *Проверка:* imports; нет `@tabler/icons-react`, `@lucide/svelte`. **WEB-09** | MUST | Цвета — CSS-переменные `globals.css` и ReUI semantic токены (`variant="success"/"info"/"warning"`); не hex/rgb на страницах. *Проверка:* grep `#[0-9a-f]{3,6}` в `apps/web/src/routes/`. **WEB-10** | SHOULD | Кастомизация — правка `packages/ui`/`reui` (Open Code), не `!important` поверх API. **WEB-11** | MUST | `apps/web/src/routes/**` — композиция `@evobgp/ui/components/*` + `@/components/*` + `@/components/reui/*`; не копировать целые примитивы в route. *Проверка:* review. **WEB-12** | NEVER | Примеры Svelte/SvelteKit, Tabler, Bootstrap — без адаптации под текущий React-стек. *Проверка:* `pnpm --filter @evobgp/web run typecheck`. **WEB-13** | MUST | Реактивность — React 19 (`useState`, `useEffect`, TanStack Query/Router хуки); не Svelte runes, не `export let`. *Проверка:* `pnpm --filter @evobgp/web run typecheck`. **WEB-14** | SHOULD | Нетривиальный UI — прочитать страницу компонента shadcn/ReUI (props, a11y). **WEB-15** | MUST | Сомнения — MCP `user-reui` + `plugin-shadcn-shadcn` + docs + `pnpm --filter @evobgp/web run typecheck`. **WEB-16** | MUST | Подтверждение удаления — `ConfirmDialog` из `@/components/confirm-dialog`, не `window.confirm`. **WEB-17** | MUST | Пустые списки — `EmptyState` или через `QueryState` с `emptyTitle`. *Проверка:* review. **WEB-18** | SHOULD | Повторяемая комбинация core (≥2 раза) — вынести в `apps/web/src/components/`. **WEB-19** | MUST | **После любого изменения `apps/web/**` или `packages/ui/**`** — перед завершением задачи агент **обязан**: ```powershell pnpm --filter @evobgp/web run typecheck pnpm --filter @evobgp/web run lint pnpm --filter @evobgp/web run build ``` Все три команды должны exit 0. Не сдавать PR/ответ, пока все три не пройдут. *Rationale:* CI job `web` = typecheck + lint + build. *Проверка:* CI job `web`. **WEB-20** | MUST | Роутинг — TanStack Router (file-based `apps/web/src/routes/`); типобезопасные `createFileRoute`, `useSearch`, `Link`. Не `react-router-dom`. *Проверка:* `tsr generate` в `build`/`typecheck` скриптах. **WEB-21** | MUST | Data fetching — TanStack Query (`useQuery`, `useMutation`, `queryOptions`); query-key factories в `apps/web/src/queries/`. Mutations invalidate keys, не refetch вручную. *Проверка:* review `queries/*.ts`. **WEB-22** | NEVER | Legacy Svelte UI удалён. Не восстанавливать `web-legacy-svelte/` и не копировать Svelte-паттерны в React-код. *Проверка:* отсутствие каталога `web-legacy-svelte/`; `pnpm --filter @evobgp/web run typecheck`. **WEB-23** | NEVER | **settings-7** как target ([preview](https://reui.io/preview/base/settings-7) — `surface: card`). Новые settings-экраны — [settings-3](https://reui.io/preview/base/settings-3) / [settings-16](https://reui.io/preview/base/settings-16) (`surface: frame`). Существующий `apps/web/src/components/settings/*` на DNA settings-7 **не** копировать как эталон; миграция — отдельный CHANGE. *Проверка:* review MCP `get_block` / cite; нет новых экранов с settings-7. --- ## Documentation Sync (Web) **DOC-SYNC-06** | MUST | UI — первично MCP + shadcn/ui docs (React) + ReUI docs (Base UI); при конфликте с блогами/Stack Overflow побеждает официальная страница. **DOC-SYNC-07** | MUST | Перед `add` — сверить Installation/Theming с `apps/web/components.json`, `packages/ui/components.json` и `packages/ui/src/styles/globals.css`. Tailwind v4 + base-nova: https://ui.shadcn.com/docs/migration/tailwind-v4 ReUI semantic tokens: https://reui.io/docs/styling --- ## Enforcement **Обязательный финальный шаг агента при правках `apps/web/**` или `packages/ui/**`** (см. **WEB-19**): ```powershell pnpm --filter @evobgp/web run typecheck pnpm --filter @evobgp/web run lint pnpm --filter @evobgp/web run build ``` **PR checklist `apps/web/**` / `packages/ui/**`:** - [ ] `pnpm --filter @evobgp/web run typecheck` — exit 0 - [ ] `pnpm --filter @evobgp/web run lint` — exit 0 - [ ] `pnpm --filter @evobgp/web run build` — exit 0 - [ ] shadcn-примитивы в `packages/ui/src/components/`, ReUI в `apps/web/src/components/reui/` - [ ] Новые примитивы через shadcn CLI (`@shadcn` или `@reui`) - [ ] Импорты: `@evobgp/ui/components/*` для shadcn, `@/components/reui/*` для ReUI - [ ] Ссылка на docs компонента (если новый паттерн) **CI:** job `web` — `typecheck` + `lint` + `build`.