import {Meta} from '@storybook/addon-docs/blocks'

<Meta title='@dxtmisha/ru/functional/Classes/DesignComponents - Базовый менеджер компонентов'/>

# Класс DesignComponents

Базовый класс для работы с подключенными компонентами и управления логикой их рендеринга в рамках дизайн-системы. Позволяет регистрировать компоненты, модифицировать их свойства по умолчанию и гибко генерировать VNode.

## Ключевые особенности

- **Управление компонентами** — централизованная регистрация и получение Vue-компонентов.
- **Динамические модификации** — поддержка применения глобальных или специфических модификаций свойств к компонентам перед рендерингом.
- **Гибкий рендеринг** — предоставляет несколько методов (`render`, `renderOne`, `renderAdd`) для генерации Vue VNode с автоматической привязкой свойств.
- **Оптимизация производительности** — использует внутреннее кэширование с помощью вычисляемых свойств Vue (`computed`) для модификаций свойств.

## Инициализация

Создает новый экземпляр `DesignComponents`. Класс позволяет объединять компоненты и их модификации в единый механизм управления рендерингом.

### Ограничения дженериков (Generic Constraints)

Класс использует дженерики для обеспечения гибкой настройки типов рендеринга:
- `COMP extends ConstrComponent` — Объект со списком доступных компонентов. Определяет структуру, по которой `DesignComponents` будет искать и возвращать компоненты для рендеринга.
- `P extends ConstrItem` — Тип свойств (props), который используется для типизации модификаций и передаваемых данных при рендеринге.

**Параметры:**
- `components: COMP = {}` — список подключаемых компонентов (объект, где ключи — названия, а значения — Vue-компоненты).
- `modification?: ConstrComponentMod<P>` — объект модификаций, позволяющий переопределять свойства (props) для каждого компонента.

```typescript
import { DesignComponents } from '@dxtmisha/functional'
import MyButton from './MyButton.vue'
import MyInput from './MyInput.vue'

// 1. Регистрация компонентов
const components = {
  button: MyButton,
  input: MyInput
}

// 2. Определение модификаций (props по умолчанию)
const modification = {
  button: { size: 'large', color: 'primary' },
  input: { focus: true }
}

const design = new DesignComponents(components, modification)
```


## Методы рендеринга

### `render`

Рендерит компонент по его имени и возвращает массив, содержащий один `VNode`. Это полезно для Vue, где часто требуются массивы узлов.

**Параметры:**
- `name: string` — Название зарегистрированного компонента.
- `props: object` — Свойства, передаваемые компоненту.
- `children: any` — Дочерние элементы или слоты.
- `index: string` — Ключ (key) для VNode.

**Возвращает:** `VNode[]` — Массив, содержащий сгенерированный VNode.

### `renderOne`

Рендерит один компонент и возвращает объект `VNode` напрямую. Если компонент не найден, возвращает `undefined`.

**Параметры:**
- `name: string` — Название зарегистрированного компонента.
- `props: object` — Свойства для компонента.
- `children: any` — Дочерние элементы.
- `index: string` — Ключ (key) для VNode.

**Возвращает:** `VNode | undefined` — Объект VNode или `undefined`.

### `renderAdd`

Рендерит компонент и добавляет полученный `VNode` в предоставленный массив. Позволяет собирать список узлов в один проход.

**Параметры:**
- `item: any[]` — Массив, в который будет добавлен результат рендеринга.
- `name: string` — Название компонента.
- `props: object` — Свойства для компонента.
- `children: any` — Дочерние элементы.
- `index: string` — Ключ (key) для VNode.

**Возвращает:** `this` — Ссылка на текущий экземпляр для цепочки вызовов.

## Дополнительные методы

- `is(name: string): boolean` — Проверяет наличие зарегистрированного компонента.
- `get(name: string): COMP[K]` — Возвращает объект зарегистрированного компонента по его имени.
- `getModification(index?: string, props?: object): object | undefined` — Возвращает модифицированные входные данные для подключенных компонентов.
