Documentation Index
Fetch the complete documentation index at: https://ui8kit.buildy.tw/llms.txt
Use this file to discover all available pages before exploring further.
Компоненты макетов
Этот документ предоставляет справочник по API и паттерны построения для компонентов макетов в @ui8kit/core. Компоненты макетов организуют множество UI-компонентов в полноценные структуры приложений, таких как панели управления, целевые страницы и административные панели.
Для базовых примитивных компонентов макета (Grid, Flex, Stack) см. Базовые компоненты. Для паттернов композиции UI-компонентов см. UI-компоненты. Для общих лучших практик по построению макетов см. Лучшие практики.
Обзор
Библиотека предоставляет три специализированных компонента макета, которые составляют примитивы и UI-компоненты в шаблоны приложений:
| Компонент | Назначение | Основной сценарий использования |
DashLayout | Макет панели управления с изменяемым размером боковой панели | Административные панели, дашборды |
LayoutBlock | Гибкие секции контента с режимами grid/flex/stack | Целевые страницы, маркетинговые сайты |
SplitBlock | Двухколоночные разделенные макеты | Секции функций, героические секции |
Эти макеты находятся на уровне 3 архитектуры и строятся на основе примитивов уровня 1 (Block, Box, Grid, Container) и UI-компонентов уровня 2 (Card, Button, Text, Title).
Источники: src/layouts/DashLayout.tsx src/layouts/LayoutBlock.tsx src/layouts/SplitBlock.tsx README.md147-168
Взаимосвязи компонентов
Внешние зависимости
Уровень 1: Базовые примитивы
Уровень 2: UI-компоненты
Уровень 3: Компоненты макетов
использует
использует
использует
использует
использует
использует
использует
использует
использует
использует
использует
использует
использует
использует
использует
использует
использует
использует
использует
использует
использует
использует
использует
использует
использует
использует
использует
использует
DashLayout
LayoutBlock
SplitBlock
Navbar
Sidebar
Card
Button
Text
Title
Icon
Badge
Group
Image
Block
Box
Grid
Stack
Container
PanelGroup
(react-resizable-panels)
Panel
(react-resizable-panels)
PanelResizeHandle
(react-resizable-panels)
Диаграмма: Дерево зависимостей компонентов макета, показывающее, как макеты уровня 3 составляют UI-компоненты уровня 2 и примитивы уровня 1, плюс внешние зависимости для продвинутых функций.
Источники: src/layouts/DashLayout.tsx1-99 src/layouts/LayoutBlock.tsx1-389 src/layouts/SplitBlock.tsx1-145
DashLayout
Компонент макета панели управления с изменяемой боковой панелью, навигационной панелью и основной областью контента. Построен на react-resizable-panels для функциональности изменения размера панелей.
Свойства DashLayout
interface DashboardProps {
page?: React.ComponentType;
children?: React.ReactNode;
sidebar?: React.ReactNode;
navbarProps?: Omit<NavbarProps, 'toggleDarkMode' | 'isDarkMode'> &
Partial<Pick<NavbarProps, 'isDarkMode' | 'toggleDarkMode'>>;
}
| Свойство | Тип | По умолчанию | Описание |
page | React.ComponentType | - | Компонент для рендеринга в основной области контента |
children | React.ReactNode | - | Альтернатива свойству page для основного контента |
sidebar | React.ReactNode | - | Контент для изменяемой боковой панели |
navbarProps | Partial<NavbarProps> | - | Свойства для навигационной панели, включая бренд, переключатель темы |
Подкомпонент Navbar
interface NavbarProps {
isDarkMode: boolean;
toggleDarkMode: () => void;
brand?: string;
}
Минималистичная навигационная панель с идентификацией бренда и переключателем темы. Рендерится как семантический элемент <nav> с атрибутом data-role="dash-navbar".
Реализация: src/layouts/DashLayout.tsx34-49
interface SidebarProps {
children?: React.ReactNode;
className?: string;
dataClass?: string;
title?: string;
}
Контейнер изменяемой боковой панели, рендерится как семантический элемент <aside>. Оборачивает дочерние элементы в Stack макет с опциональным заголовком.
Реализация: src/layouts/DashLayout.tsx14-25
Структура панелей
DashLayout
Navbar
(component='nav')
Block
(component='main')
PanelGroup
(direction='horizontal'
autoSaveId='dashlayout-panels')
Panel
(defaultSize=20
minSize=10
maxSize=40)
Panel
(defaultSize=80
minSize=50)
PanelResizeHandle
Sidebar
(component='aside')
Box + Container
Диаграмма: Структура панелей DashLayout, показывающая PanelGroup с изменяемой боковой панелью (20% по умолчанию) и основным контентом (80% по умолчанию), разделенными ручкой изменения размера.
Источники: src/layouts/DashLayout.tsx64-91
Паттерн импорта
// Полный импорт
import { DashLayout } from '@ui8kit/core';
// Импорт подкомпонентов
import { Dashboard, Navbar, Sidebar } from '@ui8kit/core';
Источники: src/layouts/DashLayout.tsx93-96
LayoutBlock
Гибкий компонент секции контента, поддерживающий три режима макета: grid, flex и stack. Включает систему хуков контента для настраиваемого рендеринга и презентеры по умолчанию для распространенных паттернов.
Свойства LayoutBlock
interface LayoutBlockProps {
// Управление макетом
layout: LayoutType; // "grid" | "flex" | "stack"
// Настройки контейнера
useContainer?: boolean;
containerSize?: "xs" | "sm" | "md" | "lg" | "xl" | "2xl";
padding?: VariantSpacingProps["px"] | null;
py?: VariantSpacingProps["py"];
// Настройки Grid (layout="grid")
cols?: VariantGridProps["cols"];
gridCols?: VariantGridProps["cols"];
gap?: VariantGridProps["gap"];
align?: VariantGridProps["align"];
justify?: VariantGridProps["justify"];
// Настройки Flex (layout="flex")
wrap?: VariantFlexProps["wrap"];
flexWrap?: boolean;
// Настройки Stack (layout="stack")
stackAlign?: VariantFlexProps["align"];
// Настройки заголовка
showHeader?: boolean;
headerAlign?: "start" | "center" | "end";
// Данные контента
content?: {
badge?: string;
title?: string;
description?: string;
items?: Array<{
id: string;
title?: string;
description: string;
image?: { src: string; alt: string; };
lucideIcon?: any;
[key: string]: any;
}>;
[key: string]: any;
};
// Хуки контента
contentHooks?: LayoutContentHooks;
className?: string;
}
Источники: src/layouts/LayoutBlock.tsx32-84
Режимы макета
| Режим | Компонент | Сценарий использования | Свойства |
grid | Grid | Сетки функций, галереи карточек | cols, gridCols, gap, align, justify |
flex | Group | Гибкие переносимые макеты | wrap, flexWrap, gap, align, justify |
stack | Stack | Вертикальные списки, таймлайны | stackAlign, gap |
Система хуков контента
interface LayoutContentHooks {
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;
}
Хуки контента обеспечивают пользовательскую логику рендеринга в определенных точках жизненного цикла макета. Хуки по умолчанию предоставляются для распространенных паттернов:
| Набор хуков | Режим макета | Рендерер элемента | Сценарий использования |
defaultLayoutContentHooks.gridCards | grid | DefaultItemRenderers.gridCard | Сетки на основе карточек с изображениями |
defaultLayoutContentHooks.gridSimple | grid | DefaultItemRenderers.gridSimple | Простые сетки иконка + текст |
defaultLayoutContentHooks.flex | flex | DefaultItemRenderers.flexItem | Горизонтальные списки функций |
defaultLayoutContentHooks.stack | stack | DefaultItemRenderers.flexItem | Вертикальные списки функций |
Источники: src/layouts/LayoutBlock.tsx23-30 src/layouts/LayoutBlock.tsx229-254
Рендереры элементов по умолчанию
layout='grid'
есть изображения
layout='grid'
нет изображений
layout='flex'
layout='stack'
LayoutBlock
gridCard
Card + Image + Icon
Макет Stack
gridSimple
Icon + Title + Text
Макет Stack
flexItem
Icon + Title + Text
Макет Group
Диаграмма: Логика выбора рендерера элемента по умолчанию на основе режима макета и структуры контента.
Источники: src/layouts/LayoutBlock.tsx123-227
Паттерн импорта
// Базовый импорт
import { LayoutBlock } from '@ui8kit/core';
// С хуками контента
import {
LayoutBlock,
defaultLayoutContentHooks,
createLayoutContentHook
} from '@ui8kit/core';
Источники: src/layouts/LayoutBlock.tsx256-389
SplitBlock
Компонент двухколоночного разделенного макета для героических секций и демонстрации функций. Поддерживает позиционирование медиа слева/справа и опциональную обертку в контейнер.
Свойства SplitBlock
interface SplitBlockProps {
// Основные секции
mediaSection?: ReactNode;
contentSection?: ReactNode;
// Управление макетом
leftMedia?: boolean;
splitSection?: boolean;
// Данные контента
content?: {
[key: string]: any;
};
// Хуки контента
contentHooks?: ContentHooks;
// Именованные слоты
slots?: {
media?: ReactNode;
header?: ReactNode;
body?: ReactNode;
actions?: ReactNode;
};
// Настройки контейнера (splitSection=false)
containerSize?: "xs" | "sm" | "md" | "lg" | "xl" | "2xl";
padding?: VariantSpacingProps["px"];
py?: VariantSpacingProps["py"];
// Настройки Grid (splitSection=true)
gap?: VariantGridProps["gap"];
align?: VariantGridProps["align"];
className?: string;
}
Источники: src/layouts/SplitBlock.tsx17-55
Режимы макета
| Режим | Описание | Структура |
splitSection={false} | Макет в контейнере | Block > Container > Grid(cols="1-2") |
splitSection={true} | Полноширинный макет | Block > Grid(cols="1-2") |
Система хуков контента
interface ContentHooks {
beforeContent?: (content: any) => ReactNode;
content?: (content: any) => ReactNode;
afterContent?: (content: any) => ReactNode;
}
Минимальная система хуков для настройки контента. Рендерер контента по умолчанию применяет хуки последовательно:
Реализация: src/layouts/SplitBlock.tsx57-65
Паттерн импорта
// Базовый импорт
import { SplitBlock } from '@ui8kit/core';
// С утилитами
import {
SplitBlock,
DefaultContentSection,
createContentHook
} from '@ui8kit/core';
Источники: src/layouts/SplitBlock.tsx67-145
Паттерны построения по сценариям использования
Целевые страницы
Целевые страницы обычно комбинируют множество компонентов LayoutBlock и SplitBlock для героических секций, функций и призывов к действию.
Структура целевой страницы
SplitBlock
Героическая секция
leftMedia=true
LayoutBlock
Сетка функций
layout='grid'
cols='1-2-3'
LayoutBlock
Карусель отзывов
layout='flex'
SplitBlock
Призыв к действию
leftMedia=false
Диаграмма: Типичная структура целевой страницы с использованием компонентов макета.
Паттерн импорта:
import {
LayoutBlock,
SplitBlock,
Container,
Card,
Button,
Text,
Title,
Badge,
Image
} from '@ui8kit/core';
Пример структуры:
// Героическая секция с медиа слева
<SplitBlock
leftMedia={true}
splitSection={false}
containerSize="xl"
mediaSection={<Image src="hero.jpg" alt="Hero" />}
contentSection={
<Stack gap="lg">
<Badge>Новая функция</Badge>
<Title order={1}>Название продукта</Title>
<Text>Текст описания</Text>
<Button variant="primary">Начать</Button>
</Stack>
}
/>
// Сетка функций с 3 колонками
<LayoutBlock
layout="grid"
cols="1-2-3"
content={{
title: "Функции",
items: [
{ id: "1", title: "Быстрый", description: "...", lucideIcon: Zap },
{ id: "2", title: "Безопасный", description: "...", lucideIcon: Lock },
{ id: "3", title: "Простой", description: "...", lucideIcon: Smile }
]
}}
/>
Источники: src/layouts/LayoutBlock.tsx1-389 src/layouts/SplitBlock.tsx1-145
Панели управления
Панели управления используют DashLayout как основной контейнер с изменяемой боковой панелью для навигации.
Приложение панели управления
DashLayout
Navbar
Бренд + переключатель темы
Sidebar
Навигационные ссылки
Основная область контента
LayoutBlock
Карточки статистики
layout='grid'
cols='1-2-4'
Grid
Компоненты графиков
Card
Таблица данных
Диаграмма: Структура панели управления с DashLayout и вложенными макетами контента.
Паттерн импорта:
import {
DashLayout,
LayoutBlock,
Card,
Grid,
Stack,
Button,
Icon,
Text,
Title
} from '@ui8kit/core';
import { useTheme } from '@ui8kit/core';
Пример структуры:
// Обертка панели управления
<DashLayout
sidebar={
<Stack gap="md">
<Button variant="ghost" fullWidth>
<Icon lucideIcon={Home} /> Панель управления
</Button>
<Button variant="ghost" fullWidth>
<Icon lucideIcon={Users} /> Пользователи
</Button>
</Stack>
}
navbarProps={{
brand: "Административная панель",
isDarkMode: isDark,
toggleDarkMode: toggleDark
}}
>
{/* Сетка карточек статистики */}
<LayoutBlock
layout="grid"
cols="1-2-4"
gap="md"
useContainer={false}
content={{
items: [
{ id: "1", title: "1,234", description: "Всего пользователей" },
{ id: "2", title: "$12,345", description: "Выручка" }
]
}}
/>
{/* Графики и таблицы */}
<Grid cols="1-2" gap="lg">
<Card p="lg">
<Card.Header>
<Title order={3}>Аналитика</Title>
</Card.Header>
<Card.Content>{/* Компонент графика */}</Card.Content>
</Card>
</Grid>
</DashLayout>
Источники: src/layouts/DashLayout.tsx1-99 src/layouts/LayoutBlock.tsx1-389
Веб-сайты
Многостраничные веб-сайты составляют секции LayoutBlock с различными режимами макета для разнообразных типов контента.
Структура веб-сайта
Block
Навигация заголовка
SplitBlock
Героическая секция О нас
splitSection=true
LayoutBlock
Сетка команды
layout='grid'
cols='1-2-3'
LayoutBlock
Таймлайн компании
layout='stack'
Block
Ссылки подвала
Диаграмма: Структура страницы веб-сайта, комбинирующая различные типы макетов.
Паттерн импорта:
import {
Block,
LayoutBlock,
SplitBlock,
Container,
Stack,
Grid,
Card,
Image,
Text,
Title
} from '@ui8kit/core';
Пример структуры:
// Героическая секция страницы О нас
<SplitBlock
leftMedia={false}
splitSection={true}
mediaSection={<Image src="team.jpg" alt="Команда" />}
contentSection={
<Stack gap="lg" align="start">
<Title order={1}>О нас</Title>
<Text size="lg">История компании...</Text>
</Stack>
}
/>
// Сетка членов команды
<LayoutBlock
layout="grid"
cols="1-2-3"
content={{
title: "Наша команда",
items: teamMembers.map(member => ({
id: member.id,
title: member.name,
description: member.role,
image: { src: member.photo, alt: member.name }
}))
}}
contentHooks={defaultLayoutContentHooks.gridCards}
/>
// Таймлайн компании
<LayoutBlock
layout="stack"
content={{
title: "Наш путь",
items: milestones.map(milestone => ({
id: milestone.year,
title: milestone.year,
description: milestone.event,
lucideIcon: Calendar
}))
}}
/>
Источники: src/layouts/LayoutBlock.tsx1-389 src/layouts/SplitBlock.tsx1-145
Административные панели
Административные панели расширяют паттерн панели управления с макетами форм и интерфейсами управления данными.
Приложение административной панели
DashLayout
Navbar
Бренд администратора
Sidebar
Навигация администратора
Настройки, Пользователи, Контент
Основная область контента
Container
LayoutBlock
Форма настроек
layout='stack'
useContainer=false
Card
Таблица пользователей
Элементы управления пагинацией
Stack
Кнопки действий
Диаграмма: Структура административной панели с макетами форм и компонентами управления данными.
Паттерн импорта:
import {
DashLayout,
LayoutBlock,
Card,
Stack,
Grid,
Button,
Text,
Title,
Icon,
Badge
} from '@ui8kit/core';
Пример структуры:
<DashLayout
sidebar={
<Stack gap="md">
<Text c="muted" size="xs">УПРАВЛЕНИЕ</Text>
<Button variant="ghost" fullWidth>
<Icon lucideIcon={Users} /> Пользователи
</Button>
<Button variant="ghost" fullWidth>
<Icon lucideIcon={FileText} /> Контент
</Button>
<Text c="muted" size="xs">НАСТРОЙКИ</Text>
<Button variant="ghost" fullWidth>
<Icon lucideIcon={Settings} /> Конфигурация
</Button>
</Stack>
}
navbarProps={{
brand: "Панель администратора"
}}
>
{/* Форма настроек */}
<Card p="xl">
<Card.Header>
<Title order={2}>Настройки сайта</Title>
</Card.Header>
<Card.Content>
<LayoutBlock
layout="stack"
gap="lg"
useContainer={false}
content={{
items: settingsFields.map(field => ({
id: field.name,
title: field.label,
description: field.description
}))
}}
contentHooks={{
item: (item) => (
<Stack gap="xs">
<Text weight="medium">{item.title}</Text>
<input type="text" />
<Text size="sm" c="muted">{item.description}</Text>
</Stack>
)
}}
/>
</Card.Content>
<Card.Footer>
<Grid cols="2" gap="md">
<Button variant="secondary">Сбросить</Button>
<Button variant="primary">Сохранить изменения</Button>
</Grid>
</Card.Footer>
</Card>
</DashLayout>
Источники: src/layouts/DashLayout.tsx1-99 src/layouts/LayoutBlock.tsx1-389
Распространенные паттерны композиции
Конфигурации адаптивной сетки
| Сценарий использования | Значение Cols | Описание |
| Сетка функций | "1-2-3" | 1 колонка мобильная, 2 планшет, 3 десктоп |
| Карточки статистики | "1-2-4" | 1 колонка мобильная, 2 планшет, 4 десктоп |
| Две колонки | "1-2" | 1 колонка мобильная, 2 десктоп |
| Простая сетка | "2" | Всегда 2 колонки |
Источники: src/layouts/LayoutBlock.tsx280-324
Композиция хуков контента
// Переопределение рендерера элемента по умолчанию
const customHooks = {
...defaultLayoutContentHooks.gridCards,
item: (item, index) => (
<Card variant="outlined" p="lg">
<Stack gap="md">
<Title order={3}>{item.title}</Title>
<Text>{item.description}</Text>
<Button variant="primary">Узнать больше</Button>
</Stack>
</Card>
)
};
<LayoutBlock
layout="grid"
cols="1-2-3"
content={content}
contentHooks={customHooks}
/>
Источники: src/layouts/LayoutBlock.tsx388-389
Вложенная композиция макетов
// Внешний блок макета с вложенными разделенными блоками
<LayoutBlock
layout="stack"
gap="3xl"
content={{
title: "Витрина продуктов",
items: products
}}
contentHooks={{
item: (product) => (
<SplitBlock
leftMedia={product.id % 2 === 0}
mediaSection={<Image src={product.image} />}
contentSection={
<Stack gap="md">
<Title order={3}>{product.name}</Title>
<Text>{product.description}</Text>
<Button variant="primary">Подробности</Button>
</Stack>
}
/>
)
}}
/>
Источники: src/layouts/LayoutBlock.tsx256-383 src/layouts/SplitBlock.tsx67-137
Атрибуты данных для таргетинга
Компоненты макета включают атрибуты data-class и data-role для согласованного таргетинга DOM:
| Компонент | Атрибут | Значение | Элемент |
DashLayout | data-role | "dash-main" | Блок основного контента |
Navbar | data-role | "dash-navbar" | Элемент Nav |
Sidebar | data-role | "dash-sidebar-stack" | Контейнер Stack |
LayoutBlock | data-class | "layout-block" | Элемент Section |
LayoutBlock | data-class | "layout-grid" / "layout-flex" / "layout-stack" | Контейнер макета |
SplitBlock | data-class | "split-grid" | Контейнер Grid |
Источники: src/layouts/DashLayout.tsx18-48 src/layouts/LayoutBlock.tsx320-345 src/layouts/SplitBlock.tsx129