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

<Meta title='@dxtmisha/ru/functional/Classes/DesignConstructorAbstract - Базовая логика конструктора'/>

# Класс DesignConstructorAbstract

Абстрактный базовый класс, предоставляющий стандартизированную структуру для логики конструктора компонентов. Он облегчает управление данными компонентов, стилями и модификациями на основе состояния.

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

- **Стандартизированная структура данных** — обработка свойств, классов и стилей.
- **Интеграция с состоянием** — реактивные обновления на основе состояния компонента.
- **Гибкие расширения** — основа для создания специализированных конструкторов.

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

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

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

Класс использует сложную систему дженериков для обеспечения полной типизации компонента:
- `E extends Element` — Тип корневого HTML-элемента (например, `HTMLElement`).
- `COMP extends ConstrComponent` — Список подключенных подкомпонентов.
- `EMITS extends ConstrItem` — Типизация событий (emits), генерируемых компонентом.
- `EXPOSE extends ConstrItem` — Структура данных, экспортируемых во внешнюю среду через `expose`.
- `SLOTS extends ConstrItem` — Доступные слоты компонента.
- `CLASSES extends ConstrClasses` — Результирующий объект классов CSS.
- `P extends ConstrItem` — Свойства (props) компонента.

**Параметры конструктора:**
- `name: string` — базовое название компонента (используется для генерации имен классов и стилей).
- `props: Readonly<P>` — объект свойств компонента.
- `options?: ConstrOptions<COMP, EMITS, P>` — дополнительные параметры (компоненты, модификации, обработчики событий, переопределения стилей и классов).

```typescript
import { DesignConstructorAbstract } from '@dxtmisha/functional'

// 1. Определение интерфейсов компонента
interface MyProps { size?: 'small' | 'medium' }
interface MyClasses { main: { [key: string]: boolean } }

// 2. Реализация конструктора
class ButtonDesign extends DesignConstructorAbstract<
  HTMLButtonElement, // E
  {},                // COMP
  {},                // EMITS
  {},                // EXPOSE
  {},                // SLOTS
  MyClasses,         // CLASSES
  MyProps            // P
> {
  constructor(name: string, props: MyProps) {
    super(name, props)
    this.init()
  }

  // Обязательные методы для реализации
  protected initExpose() { return {} }
  protected initClasses() { return { main: { active: true } } }
  protected initStyles() { return {} }
  protected initRender() { return h('button', this.getAttrs(), this.slots.default?.()) }
}
```

## Методы жизненного цикла и рендеринга

- `init(): this` — Инициализирует экземпляр, подготавливает внутреннее состояние, классы и стили.
- `render(): Function` — Возвращает функцию рендеринга для использования в `setup()` Vue-компонента.
- `setup(): void` — Выполняет основную последовательность настройки логики компонента.

## Вспомогательные методы именования

- `getName(): string` — Возвращает полное название компонента (например, `button-large`).
- `getDesign(): string` — Возвращает базовое название дизайна (первая часть названия).
- `getSubClass(name: string | string[]): string` — Генерирует название класса для подэлемента (BEM: `__`).
- `getStatusClass(name: string | string[]): string` — Генерирует название класса состояния (BEM: `--`).
- `getStyle(name: string | string[]): string` — Генерирует название системной CSS-переменной.

## Данные компонента

- `getAttrs(): object` — Возвращает атрибуты, исключая зарезервированные `class` и `style`.
- `expose(): object` — Возвращает данные и ссылки для экспорта через `expose` Vue.
