UIKit на Mantine
packages/ui — независимый React-пакет @atmanki/ui. Сайт использует его реальные
компоненты; Storybook показывает их изолированно с тем же UiProvider.
Установка и API, почему используются CSS-слои.
Базовые компоненты
Button, ActionIcon, Anchor, Text, Title, Paper, Card, поля, селекты, Checkbox,
Radio, Switch, Modal, Drawer, Alert, Tabs, Accordion, Table, Loader, Skeleton,
Progress и Tooltip берутся непосредственно из Mantine. Тема задаёт общую палитру,
шрифт, скругления и defaults. Нативные props (variant, size, loading, disabled,
error) сохраняются, поэтому библиотека не вводит собственную копию их API.
Notifications подключены один раз в UiProvider, управление — через
notifications.show из @mantine/notifications.
Составные компоненты
| Компонент | Ответственность |
|---|---|
| PageContainer / Section | Ширина, заголовок, якорь и действие раздела |
| SiteHeader / SiteNavigation / SiteFooter | Слоты шапки, адаптивное меню и подвал |
| Carousel / AwardCarousel / LogoCarousel | Готовый Mantine/Embla механизм слайдов |
| HeroCarousel | Изображение и текст большого слайда |
| ArticleCard / ArticleCollection | Карточки, featured desktop/mobile и обычная сетка |
| Schedule | Дни, площадки, время и ссылки событий |
| InformationCard / RoutePanel / MapEmbed | Выбор маршрута или размещения, карта |
| ImageText / Faq | Иллюстрированный текст и раскрываемые ответы |
У UIKit нет доступа к CMS и нет импортов Next.js. Для роутера передаётся renderLink.
Пример Next: renderLink={props => <Link {...props} />}. Маршруты передают содержимое
как ReactNode; Strapi Blocks рендерит адаптер приложения. Группировка расписания
находится в apps/web/src/lib/schedule.ts, использует Europe/Moscow и сохраняет
все события. Извлечение карточек из Blocks — в apps/web/src/lib/information.ts.
Для iframe разрешён только HTTPS yandex.ru/map-widget/v1/, остальные ссылки остаются
обычными ссылками и не превращаются в embed.
Storybook
pnpm --filter @atmanki/ui storybook запускает каталог на http://localhost:6006.
pnpm --filter @atmanki/ui build-storybook собирает статический каталог.
Используются React Webpack 5 и SWC, отдельной Vite-сборки нет.
Истории включают варианты кнопок, типографику, панели, поля с ошибками, модалки,
уведомления, загрузку, таблицы, пустые карусели, одиночный слайд, расписание с пустым
днём и длинный вопрос FAQ. Controls позволяют менять параметры, Autodocs показывает API.
Проверяйте эти состояния на узком и широком экране. /ui-kit в Next — небольшой
встроенный пример; полный каталог находится в Storybook.
Учебная документация в каталоге
Раздел «Обучение» находится первым в Storybook. Семь MDX-страниц в
packages/ui/src/docs объясняют устройство UIKit, подключение к React/Next,
тему и CSS Modules, композицию и адаптеры ссылок, CSF/Controls/Docs, а также
содержат практикум с критериями проверки и отдельный урок по типографике. Живые примеры используют существующие
stories. На Docs-странице каждого компонента есть назначение, пример применения,
ключевые параметры и ограничения; у примитивов приведены ссылки на API Mantine.
Для новой учебной страницы добавьте .mdx в src/docs с Meta title, для
описания компонента — parameters.docs.description.component в его CSF-файл.
Пример подключения задаётся строкой в parameters.docs.usage: общий шаблон
.storybook/component-docs.tsx выводит его через штатный блок Source, отдельно
от текста и живых stories. Это обходит отсутствие fenced-кода в Markdown-описаниях
текущего Storybook 10.6. На MDX-страницах обычные fenced-блоки работают.
Нумерация заголовков и storySort в .storybook/preview.tsx задают порядок уроков.
MDX подключён через stories в .storybook/main.ts; Canvas показывает живые
примеры существующих stories. Controls меняет args примера, а не код приложения.
Текст в MDX проверяется статической сборкой Storybook в CI: TypeScript сам по себе
не проверяет кодовые блоки, приведённые как учебные примеры.
Интеграция с CMS
Приложение загружает и преобразует данные; UIKit принимает готовые props. Изменения импортированного контента описаны в отдельной инструкции обновления оформления.
Учебные упражнения
- Измените primaryColor через UiProvider: компоненты должны сохранить общий вид.
- Добавьте историю собственного состояния поля без обёртки над TextInput.
- Подключите Section и ArticleCollection к обычному React-приложению без Next/CMS.
- Добавьте площадку в расписание: UIKit не должен знать, откуда пришли данные.
- Проверьте длинные подписи и пустые списки в Storybook на ширине 390 px.
Обзор события и фильтр по дням
EventOverview показывает название, описание, квадратную фотографию и произвольное действие. Данные берутся из Site.overviewTitle, overviewDescription, overviewImage; UIKit ничего не знает о Strapi. TabbedArticleCollection принимает группы { id, label, items }, опциональный initialGroup и адаптер ссылок. На главной странице адаптер группирует подсобытия по московской дате и сохраняет ссылки /events/[slug]. Обзор фестиваля и его подсобытия — разные блоки.
Публикация каталога
Порядок CI/CD, контейнер, сеть, digest и откат описаны в публикации Storybook.
Организация stories
У каждого базового компонента отдельный CSF-файл в src/stories с собственной
component-метаинформацией и типом Meta<typeof Component>. Разделы Actions,
Forms, Overlays, Typography, Surfaces, Feedback, Navigation и Data группируют
компоненты по назначению; состояния находятся внутри соответствующего компонента.
Default у Modal/Drawer связывает открытие и закрытие с args через useArgs: Controls
opened отражает состояние окна. Opened использует локальное состояние закрытия и
реагирует на изменение opened в Controls; при новом открытии story окно снова
открыто. В Docs Opened размещён в отдельном iframe высотой 450 px, чтобы портал,
фокус и блокировка прокрутки оставались внутри примера. Controls в Docs управляют
основным Default, а на отдельной странице Opened — его начальными параметрами. Составные
блоки также имеют собственные метаданные; они не наследуют Controls другой карусели
или расписания. Сценарии без одного компонента (пустое состояние, очередь уведомлений)
выделены отдельно, без фиктивной component: Button.
Страница 404 приложения — пример композиции UIKit и Mantine: разбор компонентов и серверной границы.
Дополнительные примитивы Mantine
В каталоге представлены Group и Stack для раскладки, MultiSelect и SegmentedControl для выбора, Avatar и Breadcrumbs. Типографика включает Blockquote, Code, Kbd, Highlight, List, Mark, Typography и Divider; у Text есть длинный абзац и усечение, у Title — все уровни h1–h6. Это нативные компоненты Mantine 9, без новых runtime- зависимостей и обёрток над API. У каждого свой CSF-файл, описание и пример подключения.