diff --git a/development/README.md b/development/README.md index 6b2d2bc..78121bb 100644 --- a/development/README.md +++ b/development/README.md @@ -4,8 +4,9 @@ - [Frontend workflow](frontend-workflow.md) — Node 22, локальный запуск и frontend verification. -- [UI-каталог Storybook](ui-catalog.md) — запуск, шесть групп реальных компонентов - и композиций, безопасные примеры и границы проверки интерфейса. +- [Дизайн-система](design-system.md) — shared theme, токены и общий UI-набор. +- [UI-каталог Storybook](ui-catalog.md) — запуск, блоки Design System и Product с реальными компонентами + и композициями, безопасные примеры и границы проверки интерфейса. - [Backend workflow](backend-workflow.md) — bootstrap backend, локальные non-mutating gates и границы e2e. - [Audit remediation registry](audit-remediation.md) — статусы findings, следующий diff --git a/development/design-system.md b/development/design-system.md new file mode 100644 index 0000000..0eda074 --- /dev/null +++ b/development/design-system.md @@ -0,0 +1,80 @@ +# Дизайн-система WealthLedger + +Общий фундамент находится в +[`frontend/src/shared/theme`](../../frontend/src/shared/theme/index.ts). +Его public API экспортирует `theme`, `cssVariablesResolver`, `colorRoles` и +подключает базовые CSS. App владеет MantineProvider; Storybook подключает свой +изолированный provider к тому же API. Тема и значения не копируются в preview. +Оба runtime используют светлую схему; dark theme не заявлена как поддерживаемая. + +## Тема и токены + +[`theme.ts`](../../frontend/src/shared/theme/theme.ts) сохраняет фирменную синюю +палитру 0–9, системный sans-serif и default radius md. Именованные шкалы +fontSizes, fontWeights, lineHeights, headings, spacing, radius, shadows, +breakpoints и monospace явно принимаются из `DEFAULT_THEME` Mantine 9.5.1. +Числовой дубликат шкал не хранится. Font family заголовков совпадает с общей. + +Используйте props Mantine (`gap="md"`, `p="xl"`, `radius="md"`, `shadow="xs"`) +или `--mantine-spacing-*`, `--mantine-radius-*` и другие native CSS variables. +[Foundations](http://localhost:6006/?path=/story/design-system-foundations--colors) +читает эффективную тему, показывает фактические значения и образцы. Обновление +Mantine требует повторной проверки шкал и внешнего вида приложения. + +`colorRoles` связывает смысл и native Mantine reference; resolver создаёт +`--wl-color-`, ссылающийся на Mantine variable, без повторного hex-значения. + +| Role | Native reference | Применение | +| --- | --- | --- | +| canvas | gray.2 | Фон приложения | +| surface | white | Paper и формы в светлой схеме | +| subtle | gray.0 | Приглушённая поверхность | +| text | dark.7 | Основной текст страницы | +| muted | gray.6 | Вторичный текст (dimmed светлой схемы) | +| border | gray.3 | Граница поверхности | +| primary | blue filled | Основное действие и активная навигация | +| info | blue.6 | Информация | +| positive | green.6 | Положительный результат с текстом/знаком | +| negative | red.6 | Ошибка или отрицательный результат с текстом/знаком | +| warning | yellow.6 | Предупреждение, не мелкий текст на белом | + +Базовые CSS используют canvas/text aliases. Остальные роли доступны для +постепенного использования; существующие локальные Mantine references не +переписаны массово. Цвет не заменяет подпись статуса. Палитра не гарантирует +доступный контраст произвольных сочетаний: для текста и фона проверяйте контекст. +Grape остаётся дополнительной палитрой графиков; предметные значения задаёт Product. + +Особые card gradients/shadows, размеры страницы и финансовые цвета CSS остаются +у своих FSD-владельцев. Это сохранение существующего UI, а не завершённый редизайн +или миграция всех literals в tokens. Новую общую шкалу стоит вводить только при +реальном повторном использовании, если native Mantine scale не подходит. + +## Общие компоненты + +Public API — [`shared/ui`](../../frontend/src/shared/ui/index.ts). Минимальный +каталог включает две существующие реализации, реально используемые приложением: + +| Компонент | Контракт и правила | +| --- | --- | +| StateView | Empty/error с title, text, необязательным action; error получает role alert. Кнопке нужен доступный текст; не использовать для initial loading. | +| LoadingSkeleton | Общая status/busy-область с доступной label; caller задаёт только декоративные shapes без фокуса. Структура skeleton принадлежит section/page. | + +Они не импортируют API, auth, счета или позиции. Не создаются wrappers над всеми +примитивами: для действий используется Mantine Button с общей темой. В каталоге +показаны filled для основного действия, default для вторичного/retry и subtle +для вспомогательного, а также loading и disabled. Provider не меняет defaults +Button или Paper ради каталога. Loading действия не заменяет loading страницы; +при refetch сохраняются данные и показывается локальное состояние. + +Route-aware AppShell не входит в заявленный общий набор. Бизнес-компоненты +и композиции остаются у entities/pages и показываются в Product; витрина не +определяет FSD ownership. Подробности запуска, взаимодействий и coverage — +[UI-каталог Storybook](ui-catalog.md). + +## Границы доказательств + +Каталог использует synthetic fixtures, локальные Actions и MemoryRouter, без +application API/auth/storage runtime. Dependency-cruiser проверяет FSD и +транзитивную runtime-изоляцию stories. Browser проверяет виды, размеры, focus и +действия. Эти примеры не доказывают API recovery и прохождение инвестиционного +сценария. Продуктовый пилот остаётся отдельным change и здесь не проводился. diff --git a/development/ui-catalog.md b/development/ui-catalog.md index 9d5ca0f..b393b27 100644 --- a/development/ui-catalog.md +++ b/development/ui-catalog.md @@ -28,20 +28,32 @@ npm run preview:catalog ## Компоненты и работа с примерами -В дереве Storybook доступны шесть групп: +В дереве доступны два блока, 9 групп / 30 историй: -| Группа | Что показывает | +| Блок / группа | Что показывает | | --- | --- | -| `BrokerageAccountList` | Счета со сводкой по нескольким валютам, недоступной или пустой сводкой и длинным названием. | -| `PositionCard` | Акцию с положительным результатом, облигацию с отрицательным, прочий инструмент и позицию без оценки. | -| `RecentEvents` | Полученные события, загрузку, ошибку, пустой результат и неизвестную ожидаемую сумму. | -| `PortfolioRefreshState` с `PortfolioTotals` | Сохранённые суммы при фоновом обновлении и его ошибке, локальный retry. | -| `StateView` | Пустое состояние и ошибку, с действием и без него. | -| `AccountPageLoading` через `LoadingSkeleton` | Реальный skeleton заголовка, сводки и строк страницы счёта. | +| `Design System/Foundations` | Цвета и семантические роли, типографику, интервалы, радиусы, тени и breakpoints из действующей темы. | +| `Design System/Components/StateView` | Четыре empty/error варианта с действием и без. | +| `Design System/Components/LoadingSkeleton` | Общую доступную busy-область с нейтральными structural shapes. | +| `Design System/Components/Button` | Прямой Mantine Button: primary, default, subtle, loading, disabled; локальное действие и keyboard interaction. | +| `Product/BrokerageAccountList` | Сводки счетов в нескольких валютах, недоступную/пустую сводку и длинное название. | +| `Product/PositionCard` | Акцию с положительным результатом, облигацию с отрицательным, прочий инструмент и позицию без оценки. | +| `Product/RecentEvents` | Полученные события, loading/error/empty и неизвестную ожидаемую сумму. | +| `Product/PortfolioRefreshState` с `PortfolioTotals` | Сохранённые суммы при обновлении и ошибке, локальный retry. | +| `Product/AccountPageLoading` | Реальный skeleton заголовка, сводки и строк страницы счёта. | -Стандартные Mantine primitives видны внутри этих компонентов. Отдельных копий -библиотечных demos или обёрток ради каталога нет. Каталог не заявляет полноту: -отсутствие компонента не запрещает его использование в приложении. +Быстрые входы: [Design System — цвета](http://localhost:6006/?path=/story/design-system-foundations--colors) +и [Product — карточка позиции](http://localhost:6006/?path=/story/product-positioncard--stock-gain). +Все исходные 21 истории сохранены; 9 новых добавляют foundations и общие примеры. +Бизнес-компоненты остаются в entities/pages, а общие StateView и LoadingSkeleton +— в shared/ui. Button показан напрямую: новое имя-wrapper не вводится. + +Каталог не перечисляет весь Mantine или все компоненты приложения. AppShell +с product navigation не объявлен компонентом общего набора. Отсутствие компонента +в каталоге не запрещает его использование. Foundations показывает используемые +шкалы, включая встроенные Mantine defaults; локальные размеры и особые тени +не объявляются глобальными токенами. [Дизайн-система](design-system.md) описывает +ownership и правила расширения. Выберите историю в дереве, чтобы открыть её состояние в Canvas. Docs описывает назначение, ограничения и свойства группы, а также её примеры. Controls меняют @@ -55,10 +67,11 @@ npm run preview:catalog можно менять без сброса args. Изолированный iframe позволяет отдельно проверить компонент на узком экране; навигацией самой витрины управляет Storybook. -Preview использует экспортируемую app theme, Mantine CSS, application styles, +Preview и приложение используют один public API `shared/theme`: theme, +CSSVariablesResolver и базовые styles вместе с Mantine CSS. Preview использует русскую i18n и фиксированную светлую схему без чтения сохранённой темы. Stories находятся рядом с существующими presentation components и импортируют -их реализации. Отдельных tokens нет. Error StateView сохраняет alert semantics, +их реализации. Токены и их семантические роли принадлежат shared/theme. Error StateView сохраняет alert semantics, skeleton — busy-область с декоративными фигурами без фокуса. Проверяйте доступность действий и ссылок с клавиатуры вместе с визуальным состоянием.