Макеты
Этот документ охватывает компоненты макетов уровня 3 в архитектуре@ui8kit/core: DashLayout, LayoutBlock и SplitBlock. Это компоненты уровня шаблонов (организмы), которые организуют UI-компоненты уровня 2 и примитивы уровня 1 в структурные макеты страниц. Эта страница фокусируется на паттернах композиции макетов, системах хуков контента и особых соображениях при создании структур приложений.
Для базовых примитивов макетов (Grid, Flex, Stack) см. Базовые компоненты.Для UI-компонентов, используемых внутри макетов, см. UI-компоненты.
Для деталей API и справки по пропсам см. API компонентов макетов.
Обзор архитектуры макетов
Система макетов работает на самом высоком архитектурном уровне, компонуя UI-компоненты и примитивы в полные структуры страниц. Три компонента макетов служат различным структурным целям:DashLayout - Шаблон дашборда
DashLayout предоставляет полную структуру дашборда с изменяемыми панелями, навигационным заголовком и сворачиваемой боковой панелью. Он использует react-resizable-panels для интерактивного управления панелями.
Структура компонента
Ключевые интерфейсы и пропсы
| Интерфейс | Назначение | Ключевые пропсы |
|---|---|---|
DashboardProps | Конфигурация основного макета | page, children, sidebar, navbarProps |
NavbarProps | Конфигурация заголовка | isDarkMode, toggleDarkMode, brand |
SidebarProps | Конфигурация боковой панели | children, title, dataClass |
Детали реализации
КомпонентDashboard в src/layouts/DashLayout.tsx64-91 организует макет:
- Navbar рендерится вверху с переключателем темы в src/layouts/DashLayout.tsx34-49
- PanelGroup с
direction="horizontal"создает изменяемый макет в src/layouts/DashLayout.tsx75-88 - Panel компоненты определяют боковую панель (20% по умолчанию, диапазон 10-40%) и область контента (80% по умолчанию, минимум 50%) в src/layouts/DashLayout.tsx76-86
- PanelResizeHandle обеспечивает интерактивное изменение размера в src/layouts/DashLayout.tsx80
- Container оборачивает основной контент с адаптивным размером в src/layouts/DashLayout.tsx84
Паттерн использования
autoSaveId="dashlayout-panels" в src/layouts/DashLayout.tsx75
Источники: src/layouts/DashLayout.tsx1-99 README.md155-168
LayoutBlock - Гибкие секции контента
LayoutBlock - это универсальный компонент макета, который рендерит секции контента с тремя режимами макета (grid, flex, stack) и мощной системой хуков контента для динамического рендеринга.
Режимы макета и конфигурация
Система хуков контента
Система хуков контента в src/layouts/LayoutBlock.tsx22-30 позволяет заменить любую часть рендерящегося контента:| Хук | Назначение | Сигнатура |
|---|---|---|
beforeHeader | Контент перед секцией заголовка | (content: any) => ReactNode |
header | Кастомный рендерер заголовка | (content: any) => ReactNode |
afterHeader | Контент после секции заголовка | (content: any) => ReactNode |
beforeItems | Контент перед списком элементов | (content: any) => ReactNode |
item | Кастомный рендерер элемента | (item: any, index: number) => ReactNode |
afterItems | Контент после списка элементов | (content: any) => ReactNode |
Рендереры по умолчанию
Компонент предоставляет рендереры по умолчанию в src/layouts/LayoutBlock.tsx123-227:- DefaultHeaderRenderer в src/layouts/LayoutBlock.tsx87-121 - Рендерит бейдж, заголовок и описание с выравниванием
- DefaultItemRenderers.gridCard в src/layouts/LayoutBlock.tsx126-166 - Элементы сетки на основе карточек с изображениями/иконками
- DefaultItemRenderers.gridSimple в src/layouts/LayoutBlock.tsx169-196 - Минимальные элементы сетки без карточек
- DefaultItemRenderers.flexItem в src/layouts/LayoutBlock.tsx199-226 - Горизонтальный групповой макет для режимов flex/stack
Пропсы конфигурации
| Категория пропсов | Пропсы | Назначение |
|---|---|---|
| Управление макетом | layout, useContainer, containerSize | Режим и настройки контейнера |
| Настройки Grid | cols, gridCols, gap, align, justify | Конфигурация CSS Grid |
| Настройки Flex | wrap, flexWrap | Поведение переноса Flexbox |
| Настройки Stack | stackAlign | Вертикальное выравнивание |
| Настройки заголовка | showHeader, headerAlign | Отображение и выравнивание заголовка |
| Данные контента | content, content.items | Структура данных для рендеринга |
| Кастомизация | contentHooks | Кастомные функции рендеринга |
Структура данных контента
Пропсcontent в src/layouts/LayoutBlock.tsx61-77 следует этой схеме:
Рендеринг режимов макета
Логика рендеринга в src/layouts/LayoutBlock.tsx298-353 выбирает соответствующий компонент макета:data-class для таргетинга DOM в src/layouts/LayoutBlock.tsx320-348
Примеры использования
Grid с карточками:SplitBlock - Двухколоночный разделенный макет
SplitBlock создает двухколоночные макеты с гибкими медиа и контентными секциями, обычно используемые для героических секций, демонстрации функций и комбинаций контента/изображений.
Режимы макета
Система хуков контента
ПодобноLayoutBlock, SplitBlock поддерживает хуки контента в src/layouts/SplitBlock.tsx11-15:
| Хук | Назначение | Сигнатура |
|---|---|---|
beforeContent | Контент перед основной секцией | (content: any) => ReactNode |
content | Рендерер основного контента | (content: any) => ReactNode |
afterContent | Контент после основной секции | (content: any) => ReactNode |
API слотов
API слотов в src/layouts/SplitBlock.tsx36-42 предоставляет именованные переопределения:Пропсы конфигурации
| Пропс | Тип | По умолчанию | Назначение |
|---|---|---|---|
mediaSection | ReactNode | - | Контент для медиа-колонки |
contentSection | ReactNode | - | Контент для контентной колонки |
leftMedia | boolean | false | Позиционировать медиа слева |
splitSection | boolean | true | Использовать grid на всю ширину vs контейнер |
containerSize | ContainerSizingProps["size"] | "lg" | Размер контейнера (когда splitSection=false) |
gap | VariantGridProps["gap"] | "lg" | Промежуток между колонками |
align | VariantGridProps["align"] | "center" | Вертикальное выравнивание |
Логика рендеринга макета
Логика рендеринга в src/layouts/SplitBlock.tsx94-136 создает два различных макета: Режим Container (splitSection=false) в src/layouts/SplitBlock.tsx96-111:
- Оборачивает grid в адаптивный
Container - Применяет пропсы
containerSizeиpadding - Подходит для стандартных секций страниц
splitSection=true) в src/layouts/SplitBlock.tsx115-135:
- Grid непосредственно после
Blockбез контейнера - Использует
data-class="split-grid"для идентификации в src/layouts/SplitBlock.tsx129 - Применяет
flex-1 items-centerдля высоты на весь viewport
Порядок колонок
Порядок колонок определяется пропсомleftMedia в src/layouts/SplitBlock.tsx106-107 и src/layouts/SplitBlock.tsx131-132:
leftMedia=true:[mediaSection, contentSection]leftMedia=false:[contentSection, mediaSection]
Примеры использования
Базовый Split с медиа:Интеграция с примитивами макетов
Компоненты макетов активно используют примитивы уровня 1 для структуры. Понимание этих примитивов важно для работы с макетами.Компонент Grid
ИспользуетсяLayoutBlock (режим grid) и SplitBlock для макетов CSS Grid:
cols="1-2-3"- Адаптивные 1/2/3 колонкиcols="2"- Фиксированные 2 колонкиgap="lg"- Большой промежуток между элементамиalign="center"- Центрировать элементы вертикально
Компонент Stack
ИспользуетсяLayoutBlock (режим stack) и внутри контентных секций для вертикальных макетов:
| Пропс | Значения | Назначение |
|---|---|---|
gap | "sm", "md", "lg", "xl", "2xl", "3xl" | Вертикальный интервал |
align | "start", "center", "end" | Горизонтальное выравнивание |
ta | "left", "center", "right" | Выравнивание текста |
Компонент Block
Все компоненты макетов используютBlock как корневой семантический контейнер:
component в src/layouts/DashLayout.tsx16 src/layouts/DashLayout.tsx36 и src/layouts/DashLayout.tsx74 обеспечивает семантическую HTML структуру (<section>, <nav>, <aside>, <main>).
Источники: src/layouts/LayoutBlock.tsx3-16 src/layouts/SplitBlock.tsx3-8 src/layouts/DashLayout.tsx2
Паттерны композиции
Компоненты макетов следуют специфическим паттернам композиции для построения сложных структур.Паттерн 1: Вложенная композиция макетов
Макеты могут быть вложены для создания сложных структур страниц:Паттерн 2: Управление контейнером
Макеты используют компонентContainer для адаптивного контроля ширины:
| Макет | Использование Container | Когда используется |
|---|---|---|
DashLayout | Всегда использует Container в src/layouts/DashLayout.tsx84 | Оборачивает основную панель контента |
LayoutBlock | Опционально через пропс useContainer в src/layouts/LayoutBlock.tsx259 | По умолчанию true, можно отключить для полной ширины |
SplitBlock | Условно через пропс splitSection в src/layouts/SplitBlock.tsx94-112 | Используется когда splitSection=false |
Паттерн 3: Переопределение хука контента
Система хуков контента обеспечивает прогрессивное улучшение:- Проверить наличие кастомного
contentHooks.itemв src/layouts/LayoutBlock.tsx302 - Откатиться к рендереру по умолчанию в src/layouts/LayoutBlock.tsx285
- Применить умолчания специфичные для макета в src/layouts/LayoutBlock.tsx230-254
Паттерн 4: Переопределения на основе слотов
СлотыSplitBlock предоставляют целенаправленную кастомизацию без полных хуков контента:
Паттерн 5: Рендеринг на основе данных
Макеты принимают структурированные данные и рендерят автоматически:- Рендеринг заголовка из
content.badge/title/description - Итерацию и рендеринг элементов из
content.items - Обертку макета на основе режима
layout
Особые соображения
Семантическая HTML структура
Компоненты макетов обеспечивают семантическую HTML5 структуру:| Компонент | Корневой элемент | Назначение |
|---|---|---|
DashLayout | <nav> + <main> | Навигационный заголовок + основной контент в src/layouts/DashLayout.tsx36-74 |
DashLayout.Sidebar | <aside> | Боковая навигация в src/layouts/DashLayout.tsx16 |
LayoutBlock | <section> | Контентные секции в src/layouts/LayoutBlock.tsx366 |
SplitBlock | <section> | Разделенные контентные секции в src/layouts/SplitBlock.tsx97-117 |
Атрибуты Data-Class
Все макеты применяют атрибутыdata-class для консистентного таргетинга DOM:
| Компонент | Значение Data-Class | Расположение |
|---|---|---|
DashLayout.Navbar | data-role="dash-navbar" | src/layouts/DashLayout.tsx36 |
DashLayout.Sidebar | Кастомный через пропс | src/layouts/DashLayout.tsx16 |
LayoutBlock | data-class="layout-block" | src/layouts/LayoutBlock.tsx371 |
LayoutBlock Grid | data-class="layout-grid" | src/layouts/LayoutBlock.tsx320 |
LayoutBlock Flex | data-class="layout-flex" | src/layouts/LayoutBlock.tsx333 |
LayoutBlock Stack | data-class="layout-stack" | src/layouts/LayoutBlock.tsx344 |
SplitBlock Grid | data-class="split-grid" | src/layouts/SplitBlock.tsx129 |
Адаптивное поведение
Макеты обрабатывают адаптивный дизайн через пропсы вариантов: Адаптивные колонки Grid:cols="1-2-3"создает брейкпоинты мобильная→планшет→десктоп- Автоматически сворачивается в 1 колонку на мобильных
- Масштабируется до 2 колонок на планшете (
md:) - Расширяется до 3 колонок на десктопе (
lg:)
containerSize="lg"применяетmax-w-7xlс корректировками брейкпоинтов- Автоматически добавляет горизонтальный padding на мобильных
- Центрирует контент с
mx="auto"
- Боковая панель:
defaultSize={20},minSize={10},maxSize={40}в src/layouts/DashLayout.tsx76 - Контент:
defaultSize={80},minSize={50}в src/layouts/DashLayout.tsx82 - Размеры сохраняются через
autoSaveIdв src/layouts/DashLayout.tsx75
Соображения производительности
Управление ключами элементов: КомпонентLayoutBlock требует уникальный id в элементах контента в src/layouts/LayoutBlock.tsx66 для эффективной reconciliation React. Ключи применяются в src/layouts/LayoutBlock.tsx306
Возможности мемоизации: Хуки и рендереры контента оцениваются при каждом рендере. Для дорогих вычислений оберните в useMemo:
DashLayout автоматически сохраняет размеры панелей в localStorage через react-resizable-panels, уменьшая сдвиг макета при перезагрузке.
Внешние зависимости
| Компонент | Зависимость | Назначение | Установка |
|---|---|---|---|
DashLayout | react-resizable-panels | Система изменяемых панелей | npm install react-resizable-panels |
| Все макеты | lucide-react | Опциональные компоненты иконок | npm install lucide-react |