> ## 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.

# Макеты архитектура

> Система макетов UI8Kit Core - Слой 3 компонентов (DashLayout, LayoutBlock, SplitBlock) для шаблонов структуры приложений

# Макеты

Этот документ охватывает компоненты макетов уровня 3 в архитектуре `@ui8kit/core`: `DashLayout`, `LayoutBlock` и `SplitBlock`. Это компоненты уровня шаблонов (организмы), которые организуют UI-компоненты уровня 2 и примитивы уровня 1 в структурные макеты страниц. Эта страница фокусируется на паттернах композиции макетов, системах хуков контента и особых соображениях при создании структур приложений.

Для базовых примитивов макетов (`Grid`, `Flex`, `Stack`) см. [Базовые компоненты](#3.1).\
Для UI-компонентов, используемых внутри макетов, см. [UI-компоненты](#3.3).\
Для деталей API и справки по пропсам см. [API компонентов макетов](#4.3).

***

## Обзор архитектуры макетов

Система макетов работает на самом высоком архитектурном уровне, компонуя UI-компоненты и примитивы в полные структуры страниц. Три компонента макетов служат различным структурным целям:

```
Внешние зависимости

Уровень 1: Используемые примитивы

Уровень 2: Используемые UI-компоненты

Уровень 3: Компоненты макетов

использует

использует

использует

использует

использует

использует

требует

использует

использует

использует

использует

использует

использует

использует

использует

использует

использует

использует

использует

использует

опциональные иконки

опциональные иконки

DashLayout
(Структура дашборда)

LayoutBlock
(Секции контента)

SplitBlock
(Двухколоночные макеты)

Card

Button

Text

Title

Badge

Icon

Image

Container

Group

Block
(Семантические секции)

Box
(Общий контейнер)

Grid
(CSS Grid)

Stack
(Вертикальный/горизонтальный)

react-resizable-panels
(PanelGroup, Panel)

lucide-react
(Компоненты иконок)
```

**Источники:** [src/layouts/DashLayout.tsx1-99](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/DashLayout.tsx#L1-L99) [src/layouts/LayoutBlock.tsx1-389](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L1-L389) [src/layouts/SplitBlock.tsx1-145](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/SplitBlock.tsx#L1-L145) [README.md147-168](https://github.com/ui8kit/core/blob/2afe2195/README.md#L147-L168)

***

## DashLayout - Шаблон дашборда

`DashLayout` предоставляет полную структуру дашборда с изменяемыми панелями, навигационным заголовком и сворачиваемой боковой панелью. Он использует `react-resizable-panels` для интерактивного управления панелями.

### Структура компонента

```
рендерит

рендерит

содержит

содержит

содержит

оборачивает

оборачивает

использует

использует

использует

использует

использует

использует

использует

использует

Dashboard
(Основной компонент)

Navbar
(Заголовок с брендом + переключатель темы)

Sidebar
(Сворачиваемая навигация)

Main Panel
(Область контента)

PanelGroup
(direction: horizontal)

Panel
(Контейнер боковой панели)

PanelResizeHandle
(Ручка перетаскивания)

Panel
(Контейнер контента)

Block component='nav'

Group

Button variant='ghost'

Icon

Text

Block component='aside'

Stack

Container
```

### Ключевые интерфейсы и пропсы

| Интерфейс | Назначение | Ключевые пропсы |
| - | - | - |
| `DashboardProps` | Конфигурация основного макета | `page`, `children`, `sidebar`, `navbarProps` |
| `NavbarProps` | Конфигурация заголовка | `isDarkMode`, `toggleDarkMode`, `brand` |
| `SidebarProps` | Конфигурация боковой панели | `children`, `title`, `dataClass` |

### Детали реализации

Компонент `Dashboard` в [src/layouts/DashLayout.tsx64-91](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/DashLayout.tsx#L64-L91) организует макет:

1. **Navbar** рендерится вверху с переключателем темы в [src/layouts/DashLayout.tsx34-49](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/DashLayout.tsx#L34-L49)
2. **PanelGroup** с `direction="horizontal"` создает изменяемый макет в [src/layouts/DashLayout.tsx75-88](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/DashLayout.tsx#L75-L88)
3. **Panel** компоненты определяют боковую панель (20% по умолчанию, диапазон 10-40%) и область контента (80% по умолчанию, минимум 50%) в [src/layouts/DashLayout.tsx76-86](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/DashLayout.tsx#L76-L86)
4. **PanelResizeHandle** обеспечивает интерактивное изменение размера в [src/layouts/DashLayout.tsx80](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/DashLayout.tsx#L80-L80)
5. **Container** оборачивает основной контент с адаптивным размером в [src/layouts/DashLayout.tsx84](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/DashLayout.tsx#L84-L84)

### Паттерн использования

```
import { DashLayout } from '@ui8kit/core';

<DashLayout
  sidebar={<NavSidebar />}
  navbarProps={{
    brand: "MyApp",
    isDarkMode: true,
    toggleDarkMode: handleToggle
  }}
>
  <Container>
    <Card p="lg">Content</Card>
  </Container>
</DashLayout>
```

Макет автоматически сохраняет размеры панелей через `autoSaveId="dashlayout-panels"` в [src/layouts/DashLayout.tsx75](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/DashLayout.tsx#L75-L75)

**Источники:** [src/layouts/DashLayout.tsx1-99](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/DashLayout.tsx#L1-L99) [README.md155-168](https://github.com/ui8kit/core/blob/2afe2195/README.md#L155-L168)

***

## LayoutBlock - Гибкие секции контента

`LayoutBlock` - это универсальный компонент макета, который рендерит секции контента с тремя режимами макета (`grid`, `flex`, `stack`) и мощной системой хуков контента для динамического рендеринга.

### Режимы макета и конфигурация

```
рендерит

рендерит

рендерит

использует

использует

использует

оборачивает с

оборачивает в

LayoutBlock

Режим Grid
(layout='grid')

Режим Flex
(layout='flex')

Режим Stack
(layout='stack')

Компонент Grid
cols, gap, align, justify

Компонент Group
gap, align, justify, wrap

Компонент Stack
gap, align

Container
(опциональная обертка)

Block component='section'
```

### Система хуков контента

Система хуков контента в [src/layouts/LayoutBlock.tsx22-30](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L22-L30) позволяет заменить любую часть рендерящегося контента:

| Хук | Назначение | Сигнатура |
| - | - | - |
| `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](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L123-L227):

* **DefaultHeaderRenderer** в [src/layouts/LayoutBlock.tsx87-121](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L87-L121) - Рендерит бейдж, заголовок и описание с выравниванием
* **DefaultItemRenderers.gridCard** в [src/layouts/LayoutBlock.tsx126-166](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L126-L166) - Элементы сетки на основе карточек с изображениями/иконками
* **DefaultItemRenderers.gridSimple** в [src/layouts/LayoutBlock.tsx169-196](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L169-L196) - Минимальные элементы сетки без карточек
* **DefaultItemRenderers.flexItem** в [src/layouts/LayoutBlock.tsx199-226](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L199-L226) - Горизонтальный групповой макет для режимов 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](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L61-L77) следует этой схеме:

```
content: {
  badge?: string;          // Опциональный текст бейджа
  title?: string;          // Заголовок секции
  description?: string;    // Описание секции
  items?: Array<{
    id: string;           // Обязательный уникальный идентификатор
    title?: string;       // Заголовок элемента
    description: string;  // Описание элемента (обязательно)
    image?: {             // Опциональное изображение
      src: string;
      alt: string;
    };
    lucideIcon?: any;     // Опциональный компонент иконки Lucide
    [key: string]: any;   // Дополнительные кастомные данные
  }>;
}
```

### Рендеринг режимов макета

Логика рендеринга в [src/layouts/LayoutBlock.tsx298-353](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L298-L353) выбирает соответствующий компонент макета:

```
grid

flex

stack

renderItems()

тип layout?

Компонент Grid
cols, gap, align, justify
data-class='layout-grid'

Компонент Group
gap, align, justify, wrap
data-class='layout-flex'

Компонент Stack
gap, align
data-class='layout-stack'

itemRenderer(item, index)
```

Каждый макет оборачивает элементы в соответствующий примитивный компонент с атрибутами `data-class` для таргетинга DOM в [src/layouts/LayoutBlock.tsx320-348](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L320-L348)

### Примеры использования

**Grid с карточками:**

```
<LayoutBlock
  layout="grid"
  cols="1-2-3"
  gap="lg"
  content={{
    badge: "Features",
    title: "Why Choose Us",
    description: "Discover our advantages",
    items: [
      {
        id: "1",
        title: "Fast",
        description: "Lightning speed",
        lucideIcon: Zap
      }
    ]
  }}
/>
```

**Flex с кастомными хуками:**

```
<LayoutBlock
  layout="flex"
  wrap="wrap"
  contentHooks={{
    header: (content) => <CustomHeader {...content} />,
    item: (item, index) => <CustomCard key={item.id} {...item} />
  }}
  content={data}
/>
```

**Источники:** [src/layouts/LayoutBlock.tsx1-389](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L1-L389) [README.md149-154](https://github.com/ui8kit/core/blob/2afe2195/README.md#L149-L154)

***

## SplitBlock - Двухколоночный разделенный макет

`SplitBlock` создает двухколоночные макеты с гибкими медиа и контентными секциями, обычно используемые для героических секций, демонстрации функций и комбинаций контента/изображений.

### Режимы макета

```
SplitBlock

Режим Container
(splitSection=false)

Режим на всю ширину
(splitSection=true)

Block component='section'

Обертка Container

Grid cols='1-2'

Grid cols='1-2'
data-class='split-grid'

leftMedia=true

leftMedia=false
```

### Система хуков контента

Подобно `LayoutBlock`, `SplitBlock` поддерживает хуки контента в [src/layouts/SplitBlock.tsx11-15](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/SplitBlock.tsx#L11-L15):

| Хук | Назначение | Сигнатура |
| - | - | - |
| `beforeContent` | Контент перед основной секцией | `(content: any) => ReactNode` |
| `content` | Рендерер основного контента | `(content: any) => ReactNode` |
| `afterContent` | Контент после основной секции | `(content: any) => ReactNode` |

### API слотов

API слотов в [src/layouts/SplitBlock.tsx36-42](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/SplitBlock.tsx#L36-L42) предоставляет именованные переопределения:

```
slots?: {
  media?: ReactNode;      // Переопределить медиа секцию
  header?: ReactNode;     // Будущее: Слот заголовка
  body?: ReactNode;       // Будущее: Слот тела
  actions?: ReactNode;    // Будущее: Слот действий
}
```

Разрешение медиа-слота в [src/layouts/SplitBlock.tsx91](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/SplitBlock.tsx#L91-L91) приоритизирует переопределения слотов над прямыми пропсами.

### Пропсы конфигурации

| Пропс | Тип | По умолчанию | Назначение |
| - | - | - | - |
| `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](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/SplitBlock.tsx#L94-L136) создает два различных макета:

**Режим Container** (`splitSection=false`) в [src/layouts/SplitBlock.tsx96-111](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/SplitBlock.tsx#L96-L111):

* Оборачивает grid в адаптивный `Container`
* Применяет пропсы `containerSize` и `padding`
* Подходит для стандартных секций страниц

**Режим на всю ширину** (`splitSection=true`) в [src/layouts/SplitBlock.tsx115-135](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/SplitBlock.tsx#L115-L135):

* Grid непосредственно после `Block` без контейнера
* Использует `data-class="split-grid"` для идентификации в [src/layouts/SplitBlock.tsx129](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/SplitBlock.tsx#L129-L129)
* Применяет `flex-1 items-center` для высоты на весь viewport

### Порядок колонок

Порядок колонок определяется пропсом `leftMedia` в [src/layouts/SplitBlock.tsx106-107](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/SplitBlock.tsx#L106-L107) и [src/layouts/SplitBlock.tsx131-132](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/SplitBlock.tsx#L131-L132):

* `leftMedia=true`: `[mediaSection, contentSection]`
* `leftMedia=false`: `[contentSection, mediaSection]`

### Примеры использования

**Базовый Split с медиа:**

```
<SplitBlock
  mediaSection={
    <Image src="/hero.jpg" alt="Hero" fit="cover" />
  }
  contentSection={
    <Stack gap="lg">
      <Title order={1}>Welcome</Title>
      <Text>Description text</Text>
      <Button>Get Started</Button>
    </Stack>
  }
  leftMedia
/>
```

**С хуками контента:**

```
<SplitBlock
  content={{ title: "Feature", description: "Details" }}
  contentHooks={{
    beforeContent: (content) => <Badge>{content.badge}</Badge>,
    content: (content) => (
      <Stack gap="md">
        <Title>{content.title}</Title>
        <Text>{content.description}</Text>
      </Stack>
    ),
    afterContent: () => <Button>Learn More</Button>
  }}
  slots={{
    media: <Image src="/feature.jpg" />
  }}
/>
```

**Hero на всю ширину:**

```
<SplitBlock
  splitSection
  leftMedia={false}
  mediaSection={<HeroImage />}
  contentSection={<HeroContent />}
/>
```

**Источники:** [src/layouts/SplitBlock.tsx1-145](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/SplitBlock.tsx#L1-L145) [README.md149-154](https://github.com/ui8kit/core/blob/2afe2195/README.md#L149-L154)

***

## Интеграция с примитивами макетов

Компоненты макетов активно используют примитивы уровня 1 для структуры. Понимание этих примитивов важно для работы с макетами.

### Компонент Grid

Используется `LayoutBlock` (режим grid) и `SplitBlock` для макетов CSS Grid:

```
применяет

применяет

применяет

применяет

'1-2-3' создает

Grid
(CSS Grid)

вариант cols
'1-2-3', '2', '3', '4'

вариант gap
'sm', 'md', 'lg', 'xl'

вариант align
'start', 'center', 'end'

вариант justify
'start', 'center', 'between'

Адаптивные колонки
1 колонка мобильная
2 колонки планшет
3 колонки десктоп
```

**Общие конфигурации 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` как корневой семантический контейнер:

```
<Block
  component="section"  // Семантический HTML5 тег
  w="full"            // Полная ширина
  py="xl"             // Вертикальный padding
  data-class="layout-block"  // Идентификация DOM
>
  {/* Контент макета */}
</Block>
```

Пропс `component` в [src/layouts/DashLayout.tsx16](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/DashLayout.tsx#L16-L16) [src/layouts/DashLayout.tsx36](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/DashLayout.tsx#L36-L36) и [src/layouts/DashLayout.tsx74](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/DashLayout.tsx#L74-L74) обеспечивает семантическую HTML структуру (`<section>`, `<nav>`, `<aside>`, `<main>`).

**Источники:** [src/layouts/LayoutBlock.tsx3-16](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L3-L16) [src/layouts/SplitBlock.tsx3-8](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/SplitBlock.tsx#L3-L8) [src/layouts/DashLayout.tsx2](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/DashLayout.tsx#L2-L2)

***

## Паттерны композиции

Компоненты макетов следуют специфическим паттернам композиции для построения сложных структур.

### Паттерн 1: Вложенная композиция макетов

Макеты могут быть вложены для создания сложных структур страниц:

```
children

children

children

рендерит

рендерит

рендерит

DashLayout
(Оболочка приложения)

LayoutBlock layout='grid'
(Секция Hero)

LayoutBlock layout='flex'
(Секция Features)

SplitBlock
(Секция контента)

Card

Card

Card
```

**Пример:**

```
<DashLayout sidebar={<Navigation />}>
  <LayoutBlock layout="grid" cols="1-2-3" content={heroData} />
  <SplitBlock mediaSection={<Image />} contentSection={<Content />} />
  <LayoutBlock layout="stack" content={testimonialsData} />
</DashLayout>
```

### Паттерн 2: Управление контейнером

Макеты используют компонент `Container` для адаптивного контроля ширины:

| Макет | Использование Container | Когда используется |
| - | - | - |
| `DashLayout` | Всегда использует `Container` в [src/layouts/DashLayout.tsx84](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/DashLayout.tsx#L84-L84) | Оборачивает основную панель контента |
| `LayoutBlock` | Опционально через пропс `useContainer` в [src/layouts/LayoutBlock.tsx259](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L259-L259) | По умолчанию `true`, можно отключить для полной ширины |
| `SplitBlock` | Условно через пропс `splitSection` в [src/layouts/SplitBlock.tsx94-112](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/SplitBlock.tsx#L94-L112) | Используется когда `splitSection=false` |

### Паттерн 3: Переопределение хука контента

Система хуков контента обеспечивает прогрессивное улучшение:

```
переопределяет

fallback

Рендерер по умолчанию
(Встроенный)

Кастомный хук
(Предоставленный пользователем)

Финальный рендер
(Вывод)

Данные контента
```

**Цепочка fallback:**

1. Проверить наличие кастомного `contentHooks.item` в [src/layouts/LayoutBlock.tsx302](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L302-L302)
2. Откатиться к рендереру по умолчанию в [src/layouts/LayoutBlock.tsx285](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L285-L285)
3. Применить умолчания специфичные для макета в [src/layouts/LayoutBlock.tsx230-254](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L230-L254)

### Паттерн 4: Переопределения на основе слотов

Слоты `SplitBlock` предоставляют целенаправленную кастомизацию без полных хуков контента:

```
<SplitBlock
  // Базовые пропсы
  leftMedia
  gap="xl"
  
  // Оригинальные секции
  mediaSection={<DefaultImage />}
  contentSection={<DefaultContent />}
  
  // Переопределения слотов
  slots={{
    media: <CustomVideo />  // Переопределяет mediaSection
  }}
/>
```

Разрешение в [src/layouts/SplitBlock.tsx91](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/SplitBlock.tsx#L91-L91) приоритизирует слоты над прямыми пропсами.

### Паттерн 5: Рендеринг на основе данных

Макеты принимают структурированные данные и рендерят автоматически:

```
const pageData = {
  badge: "New",
  title: "Feature Section",
  description: "Amazing features",
  items: [
    { id: "1", title: "Fast", description: "Speed", lucideIcon: Zap },
    { id: "2", title: "Secure", description: "Safe", lucideIcon: Lock }
  ]
};

<LayoutBlock layout="grid" cols="2" content={pageData} />
```

Конвейер рендеринга в [src/layouts/LayoutBlock.tsx288-361](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L288-L361) обрабатывает:

1. Рендеринг заголовка из `content.badge/title/description`
2. Итерацию и рендеринг элементов из `content.items`
3. Обертку макета на основе режима `layout`

**Источники:** [src/layouts/LayoutBlock.tsx256-386](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L256-L386) [src/layouts/SplitBlock.tsx67-143](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/SplitBlock.tsx#L67-L143) [src/layouts/DashLayout.tsx64-91](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/DashLayout.tsx#L64-L91)

***

## Особые соображения

### Семантическая HTML структура

Компоненты макетов обеспечивают семантическую HTML5 структуру:

| Компонент | Корневой элемент | Назначение |
| - | - | - |
| `DashLayout` | `<nav>` + `<main>` | Навигационный заголовок + основной контент в [src/layouts/DashLayout.tsx36-74](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/DashLayout.tsx#L36-L74) |
| `DashLayout.Sidebar` | `<aside>` | Боковая навигация в [src/layouts/DashLayout.tsx16](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/DashLayout.tsx#L16-L16) |
| `LayoutBlock` | `<section>` | Контентные секции в [src/layouts/LayoutBlock.tsx366](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L366-L366) |
| `SplitBlock` | `<section>` | Разделенные контентные секции в [src/layouts/SplitBlock.tsx97-117](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/SplitBlock.tsx#L97-L117) |

Это обеспечивает доступность и SEO соответствие без дополнительной конфигурации.

### Атрибуты Data-Class

Все макеты применяют атрибуты `data-class` для консистентного таргетинга DOM:

| Компонент | Значение Data-Class | Расположение |
| - | - | - |
| `DashLayout.Navbar` | `data-role="dash-navbar"` | [src/layouts/DashLayout.tsx36](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/DashLayout.tsx#L36-L36) |
| `DashLayout.Sidebar` | Кастомный через пропс | [src/layouts/DashLayout.tsx16](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/DashLayout.tsx#L16-L16) |
| `LayoutBlock` | `data-class="layout-block"` | [src/layouts/LayoutBlock.tsx371](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L371-L371) |
| `LayoutBlock` Grid | `data-class="layout-grid"` | [src/layouts/LayoutBlock.tsx320](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L320-L320) |
| `LayoutBlock` Flex | `data-class="layout-flex"` | [src/layouts/LayoutBlock.tsx333](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L333-L333) |
| `LayoutBlock` Stack | `data-class="layout-stack"` | [src/layouts/LayoutBlock.tsx344](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L344-L344) |
| `SplitBlock` Grid | `data-class="split-grid"` | [src/layouts/SplitBlock.tsx129](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/SplitBlock.tsx#L129-L129) |

Это обеспечивает надежное тестирование и стилизацию без зависимости от className.

### Адаптивное поведение

Макеты обрабатывают адаптивный дизайн через пропсы вариантов:

**Адаптивные колонки Grid:**

* `cols="1-2-3"` создает брейкпоинты мобильная→планшет→десктоп
* Автоматически сворачивается в 1 колонку на мобильных
* Масштабируется до 2 колонок на планшете (`md:`)
* Расширяется до 3 колонок на десктопе (`lg:`)

**Адаптивный размер Container:**

* `containerSize="lg"` применяет `max-w-7xl` с корректировками брейкпоинтов
* Автоматически добавляет горизонтальный padding на мобильных
* Центрирует контент с `mx="auto"`

**Изменение размера панелей (DashLayout):**

* Боковая панель: `defaultSize={20}`, `minSize={10}`, `maxSize={40}` в [src/layouts/DashLayout.tsx76](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/DashLayout.tsx#L76-L76)
* Контент: `defaultSize={80}`, `minSize={50}` в [src/layouts/DashLayout.tsx82](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/DashLayout.tsx#L82-L82)
* Размеры сохраняются через `autoSaveId` в [src/layouts/DashLayout.tsx75](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/DashLayout.tsx#L75-L75)

### Соображения производительности

**Управление ключами элементов:** Компонент `LayoutBlock` требует уникальный `id` в элементах контента в [src/layouts/LayoutBlock.tsx66](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L66-L66) для эффективной reconciliation React. Ключи применяются в [src/layouts/LayoutBlock.tsx306](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L306-L306)

**Возможности мемоизации:** Хуки и рендереры контента оцениваются при каждом рендере. Для дорогих вычислений оберните в `useMemo`:

```
const contentHooks = useMemo(() => ({
  item: (item, index) => <ExpensiveComponent {...item} />
}), [dependencies]);
```

**Сохранение состояния панели:** `DashLayout` автоматически сохраняет размеры панелей в localStorage через `react-resizable-panels`, уменьшая сдвиг макета при перезагрузке.

### Внешние зависимости

| Компонент | Зависимость | Назначение | Установка |
| - | - | - | - |
| `DashLayout` | `react-resizable-panels` | Система изменяемых панелей | `npm install react-resizable-panels` |
| Все макеты | `lucide-react` | Опциональные компоненты иконок | `npm install lucide-react` |

Они перечислены как peer зависимости и должны быть установлены отдельно при использовании макетов.

**Источники:** [src/layouts/DashLayout.tsx4](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/DashLayout.tsx#L4-L4) [src/layouts/LayoutBlock.tsx366-383](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L366-L383) [src/layouts/SplitBlock.tsx94-136](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/SplitBlock.tsx#L94-L136)

***

## Примеры использования

### Приложение дашборд

Полный дашборд с навигацией, изменяемыми панелями и контентными секциями:

```
import { DashLayout, LayoutBlock, Card } from '@ui8kit/core';
import { Home, Settings, Users } from 'lucide-react';

function DashboardApp() {
  const [darkMode, setDarkMode] = useState(false);
  
  return (
    <DashLayout
      navbarProps={{
        brand: "Admin Panel",
        isDarkMode: darkMode,
        toggleDarkMode: () => setDarkMode(!darkMode)
      }}
      sidebar={
        <Stack gap="md">
          <Button variant="ghost" leftSection={<Home />}>
            Dashboard
          </Button>
          <Button variant="ghost" leftSection={<Users />}>
            Users
          </Button>
          <Button variant="ghost" leftSection={<Settings />}>
            Settings
          </Button>
        </Stack>
      }
    >
      <LayoutBlock
        layout="grid"
        cols="1-2-3"
        gap="lg"
        content={{
          title: "Overview",
          description: "Key metrics",
          items: statsData
        }}
      />
    </DashLayout>
  );
}
```

### Маркетинговая целевая страница

Hero секция с разделенным макетом и сеткой функций:

```
import { SplitBlock, LayoutBlock } from '@ui8kit/core';
import { Zap, Shield, Globe } from 'lucide-react';

function LandingPage() {
  return (
    <>
      <SplitBlock
        leftMedia={false}
        splitSection
        mediaSection={
          <Image
            src="/hero.jpg"
            alt="Hero"
            fit="cover"
            h="full"
          />
        }
        contentSection={
          <Stack gap="xl" align="start" p="2xl">
            <Badge variant="secondary">New Release</Badge>
            <Title order={1} size="4xl" fw="bold">
              Build Faster
            </Title>
            <Text size="xl" c="secondary-foreground">
              Create amazing interfaces with minimal code
            </Text>
            <Group gap="md">
              <Button variant="primary" size="lg">
                Get Started
              </Button>
              <Button variant="outline" size="lg">
                Learn More
              </Button>
            </Group>
          </Stack>
        }
      />
      
      <LayoutBlock
        layout="grid"
        cols="1-2-3"
        gap="xl"
        py="3xl"
        content={{
          badge: "Features",
          title: "Why Choose Us",
          description: "Everything you need to succeed",
          items: [
            {
              id: "fast",
              title: "Lightning Fast",
              description: "Optimized for performance",
              lucideIcon: Zap
            },
            {
              id: "secure",
              title: "Secure by Default",
              description: "Built with security in mind",
              lucideIcon: Shield
            },
            {
              id: "global",
              title: "Global Scale",
              description: "Deploy worldwide instantly",
              lucideIcon: Globe
            }
          ]
        }}
      />
    </>
  );
}
```

### Макет статьи с насыщенным контентом

Макет Stack с кастомными хуками контента для богатого контента:

```
import { LayoutBlock, createLayoutContentHook } from '@ui8kit/core';

const articleHooks = createLayoutContentHook({
  header: (content) => (
    <Stack gap="md" align="center" ta="center">
      <Badge>{content.category}</Badge>
      <Title order={1} size="4xl">{content.title}</Title>
      <Text c="muted" size="sm">
        {content.author} • {content.date}
      </Text>
    </Stack>
  ),
  item: (item, index) => (
    <Card p="xl" rounded="lg" shadow="sm">
      <Stack gap="lg">
        <Title order={2} size="2xl">{item.title}</Title>
        <Text>{item.content}</Text>
        {item.quote && (
          <Box p="lg" bg="muted" rounded="md" border="1px solid border">
            <Text size="lg" fw="medium">"{item.quote}"</Text>
          </Box>
        )}
      </Stack>
    </Card>
  )
});

function ArticlePage() {
  return (
    <LayoutBlock
      layout="stack"
      gap="2xl"
      containerSize="md"
      contentHooks={articleHooks}
      content={articleData}
    />
  );
}
```

**Источники:** [README.md36-168](https://github.com/ui8kit/core/blob/2afe2195/README.md#L36-L168) [src/layouts/DashLayout.tsx53-96](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/DashLayout.tsx#L53-L96) [src/layouts/LayoutBlock.tsx256-389](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/LayoutBlock.tsx#L256-L389) [src/layouts/SplitBlock.tsx67-143](https://github.com/ui8kit/core/blob/2afe2195/src/layouts/SplitBlock.tsx#L67-L143)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.