# Cuby UI - агентская документация (RU)

Документ для кодовых агентов. Описывает публичный API пакета `@cuby-ui/core`, а также примеры использования.

Критически важно:
- Оверлеи (`cui-dialogs`, `cui-alerts`, `cui-select`, `cui-context-menu`) требуют наличия `cui-root` в DOM.
- `open()` у `CuiAlertService` и `CuiDialogService` выполняется только после подписки на Observable.

## Оглавление
- [Компоненты (Core)](#компоненты-core)
- [Директивы (Core)](#директивы-core)
- [Сервисы (Core)](#сервисы-core)
- [Интерфейсы и типы (Core)](#интерфейсы-и-типы-core)
- [Утилиты (Core)](#утилиты-core)
- [Темы и стили](#темы-и-стили)
- [Рецепты (How-to)](#рецепты-how-to)
- [Анти-паттерны](#анти-паттерны)
- [FAQ / типовые ошибки](#faq--типовые-ошибки)
- [Структура репозитория](#структура-репозитория)
- [Линт и форматирование](#линт-и-форматирование)
- [Версии и совместимость](#версии-и-совместимость)

## Компоненты (Core)

### Feature: CuiAccordionComponent (`cui-accordion`)
Описание: контейнер для набора `cui-accordion-item`, управляет только разметкой.
Публичный API:
- Модуль: `CuiAccordionModule`
- Inputs: нет
- Outputs: нет
Пример:
```html
<cui-accordion>
  <cui-accordion-item>Заголовок
    <ng-container cuiAccordionItemContent>Контент</ng-container>
  </cui-accordion-item>
</cui-accordion>
```

### Feature: CuiAccordionItemComponent (`cui-accordion-item`)
Описание: элемент аккордеона с кнопкой переключения и скрываемым контентом.
Публичный API:
- Модуль: `CuiAccordionModule`
- Inputs: `isOpen: boolean` (по умолчанию `true`)
- Outputs: `isOpenChange: EventEmitter<boolean>`
- Контент: тело передается через `cuiAccordionItemContent`
Пример:
```html
<cui-accordion-item [(isOpen)]="isOpen">
  Заголовок
  <ng-container cuiAccordionItemContent>Тело</ng-container>
</cui-accordion-item>
```

### Feature: CuiAlertService
Описание: сервис для показа алертов поверх UI, построен на `CuiPopoverService`.
Публичный API:
- Методы: `open(content: string, options?: Partial<CuiAlertOptions>)`, `closeAll()`
- Опции: `label`, `needAutoClose`, `isCloseable`, `position`, `resizing`, `status`, `mode`
- Типы: `CuiAlertOptions`, `CuiAlertPosition`, `CuiAlertResizing`
- Константы/токены: `CUI_ALERT_DEFAULT_OPTIONS`, `CUI_ALERT_OPTIONS`, `CUI_ALERTS`, `CUI_ALERT_CONTEXT`
Пример:
```ts
const alerts = inject(CuiAlertService);

alerts.open('Задача создана', {
  status: 'success',
  label: 'Готово',
  position: 'right',
}).subscribe();
```
Пример (переопределение дефолтов):
```ts
providers: [
  { provide: CUI_ALERT_OPTIONS, useValue: { position: 'center', needAutoClose: false } }
]
```

### Feature: CuiAlertsComponent (`cui-alerts`)
Описание: контейнер для отрисовки списка алертов. Обычно не нужен напрямую, используется в `cui-root`.
Публичный API:
- Модуль: `CuiAlertModule`
- Inputs/Outputs: нет
Пример:
```html
<cui-alerts></cui-alerts>
```

### Feature: CuiAlertComponent (`cui-alert`)
Описание: рендер одного алерта, требует `CUI_ALERT_CONTEXT`. Обычно используется только контейнером.
Публичный API:
- Модуль: `CuiAlertModule`
- Inputs/Outputs: нет
Пример:
```ts
providers: [{ provide: CUI_ALERT_CONTEXT, useValue: alertContext }]
```

### Feature: CuiBadgeComponent (`cui-badge`)
Описание: бейдж с цветом и размером; опциональная иконка слева — через проекцию с атрибутом `cuiBadgeIcon`.
Публичный API:
- Модуль: `CuiBadgeModule`
- Inputs: `color`, `size`, `variant`
- `color`: `light-blue | yellow | green | gray | dark-gray | red | violet` (и др. из `CuiBadgeColor`)
- `size`: `sm | md`
Пример:
```html
<cui-badge color="green" size="md">
    <cui-svg cuiBadgeIcon icon="cuiIconCheckSm" />
    Online
</cui-badge>
```

Цвет иконки по умолчанию совпадает с акцентом баджа (`--cui-badge-accent`). Свой цвет — через input `color` у `cui-svg`.

### Feature: CuiBannerComponent (`cui-banner`)
Описание: баннер для статуса/уведомлений с действием и закрытием.
Публичный API:
- Модуль: `CuiBannerModule`
- Inputs: `status`, `isCloseable`, `label`, `actionButtonText`
- Outputs: `actionButtonClicked`, `closed`
- Типы: `CuiBannerOptions`, `CuiBannerIconOptions`
- Константы/токены: `CUI_BANNER_DEFAULT_OPTIONS`, `CUI_BANNER_OPTIONS`
Пример:
```html
<cui-banner
  label="Сохранено"
  status="success"
  actionButtonText="Отменить"
  (actionButtonClicked)="onUndo()"
  (closed)="onDismiss()"
>
  Запись обновлена
</cui-banner>
```

### Feature: CuiBreadcrumbsComponent (`cui-breadcrumbs`)
Описание: контейнер хлебных крошек, использует `*cuiItem`.
Публичный API:
- Модуль: `CuiBreadcrumbsModule`
- Inputs/Outputs: нет
Пример:
```html
<cui-breadcrumbs>
  <a cuiBreadcrumb *cuiItem>Главная</a>
  <a cuiBreadcrumb *cuiItem>Каталог</a>
  <a cuiBreadcrumb *cuiItem>Товар</a>
</cui-breadcrumbs>
```

### Feature: CuiBreadcrumbComponent (`[cuiBreadcrumb]`)
Описание: элемент хлебных крошек (обычно `a`), стиль задается директивой.
Публичный API:
- Модуль: `CuiBreadcrumbsModule`
- Inputs: `isLast: boolean` (если нужно вручную пометить последний)
Пример:
```html
<a cuiBreadcrumb *cuiItem [isLast]="true">Текущая</a>
```

### Feature: CuiButtonComponent (`button[cuiButton], a[cuiButton]`)
Описание: кнопка с набором appearance/size/shape и иконками.
Публичный API:
- Модуль: `CuiButtonModule`
- Inputs: `appearance`, `size`, `shape`, `disabled`, `isLoaderShown`, `icon`, `iconRight`
- `appearance`: `action | secondary | outlined | outlined-gray | ghost | flat | destructive | link`
- `size`: `xxs | xs | sm | md`
- Типы: `CuiButtonOptions`
- Константы/токены: `CUI_BUTTON_DEFAULT_OPTIONS`, `CUI_BUTTON_OPTIONS`
Пример:
```html
<button
  cuiButton
  appearance="secondary"
  size="sm"
  icon="cuiIconPlus"
  [isLoaderShown]="isSaving"
>
  Создать
</button>
```

### Feature: CuiButtonGroupComponent (`cui-button-group`)
Описание: группировка кнопок `cuiButton` в одну линию.
Публичный API:
- Модуль: `CuiButtonGroupModule`
- Inputs/Outputs: нет
Пример:
```html
<cui-button-group>
  <button cuiButton icon="cuiIconPlus"></button>
  <button cuiButton icon="cuiIconCheck"></button>
</cui-button-group>
```

### Feature: CuiCheckboxComponent (`input[type="checkbox"][cuiCheckbox]`)
Описание: стилизованный checkbox, логика остается нативной.
Публичный API:
- Модуль: `CuiCheckboxModule`
- Inputs/Outputs: нет
Пример:
```html
<input cuiCheckbox type="checkbox" [formControl]="flagControl">
```

### Feature: CuiContextMenuComponent (`cui-context-menu[items][target]`)
Описание: контекстное меню, привязанное к `target`, рендерится в `cui-root`.
Публичный API:
- Модуль: `CuiContextMenuModule`
- Inputs: `items: CuiContextMenuItem[]`, `target: HTMLElement`
Пример:
```html
<button cuiButton cuiElement #btn="elementRef">...</button>
<cui-context-menu [target]="btn.nativeElement" [items]="menuItems"></cui-context-menu>
```

### Feature: CuiDialogService
Описание: сервис модальных диалогов. Контент может быть компонентом, шаблоном или строкой.
Публичный API:
- Методы: `open(content, options?)`, `closeAll()`
- Опции: `size: 'xl' | 'auto'`, `data`, `dismissible`, `injector`
- Типы: `CuiDialogOptions`, `CuiDialogContext`, `CuiDialogSize`
- Константы/токены: `CUI_DIALOG_DEFAULT_OPTIONS`, `CUI_DIALOG_OPTIONS`, `CUI_DIALOGS`, `CUI_DIALOG_CONTEXT`
Пример:
```ts
const dialogs = inject(CuiDialogService);

dialogs.open(ModalComponent, { size: 'xl', data: { id: 123 } })
  .subscribe(result => console.log(result));
```

### Feature: CuiDialogsComponent (`cui-dialogs`)
Описание: контейнер для всех открытых диалогов. Обычно используется через `cui-root`.
Публичный API:
- Модуль: `CuiDialogModule`
- Inputs/Outputs: нет
Пример:
```html
<cui-dialogs></cui-dialogs>
```

### Feature: CuiDialogComponent (`cui-dialog`)
Описание: базовый компонент диалога, получает контекст из `CUI_DIALOG_CONTEXT`.
Публичный API:
- Модуль: `CuiDialogModule`
- Inputs/Outputs: нет
Пример:
```ts
const context = inject<CuiDialogContext<MyData>>(CUI_DIALOG_CONTEXT);
context.completeWith({ ok: true });
```

### Feature: CuiDialogHeaderComponent (`header[cuiDialogHeader][heading]`)
Описание: шапка диалога с заголовком (Polymorpheus) и кнопкой закрытия.
Публичный API:
- Модуль: `CuiDialogModule`
- Inputs: `heading`, `headingContext`, `subheading`
- Outputs: `closed`
Пример:
```html
<header
  cuiDialogHeader
  [heading]="'Редактирование'"
  [subheading]="'Поля обязательны'"
  (closed)="context.completeWith()"
></header>
```

### Feature: CuiDialogActionsComponent (`cui-dialog-actions`)
Описание: контейнер для футера/кнопок диалога.
Публичный API:
- Модуль: `CuiDialogModule`
- Inputs/Outputs: нет
Пример:
```html
<cui-dialog-actions>
  <button cuiButton>Сохранить</button>
  <button cuiButton appearance="secondary">Отмена</button>
</cui-dialog-actions>
```

### Feature: CuiFormFieldComponent (`cui-form-field`)
Описание: обертка для поля формы, собирает `cuiLabel`, поле и `cui-hint`.
Публичный API:
- Модуль: `CuiFormFieldModule`
- Inputs/Outputs: нет
Пример:
```html
<cui-form-field>
  <label cuiLabel for="name">Имя</label>
  <cui-input-text cuiTextFieldId="name"></cui-input-text>
  <cui-hint>Введите полное имя</cui-hint>
</cui-form-field>
```

### Feature: CuiHintComponent (`cui-hint`)
Описание: текстовая подсказка под полем.
Публичный API:
- Модуль: `CuiHintModule`
- Inputs: `hintType: 'info' | 'error'`
Пример:
```html
<cui-hint hintType="error">Поле обязательно</cui-hint>
```

### Feature: CuiIconButtonComponent (`button[cuiIconButton][icon], a[cuiIconButton][icon]`)
Описание: иконка-кнопка с цветом и hover цветом.
Публичный API:
- Модуль: `CuiIconButtonModule`
- Inputs: `icon`, `color`, `hoverColor`
Пример:
```html
<button
  cuiIconButton
  icon="cuiIconTrash"
  color="var(--cui-danger)"
  hoverColor="var(--cui-red-600)"
></button>
```

### Feature: CuiInputNumberComponent (`cui-input-number`)
Описание: числовой инпут с маской (maskito), поддерживает min/max/precision.
Публичный API:
- Модуль: `CuiInputNumberModule`
- Inputs: `precision`, `min`, `max`
- Значение: `number | null` через ControlValueAccessor
Пример:
```html
<cui-input-number
  [formControl]="priceControl"
  [precision]="2"
  [min]="0"
  [max]="9999"
  cuiTextFieldPlaceholder="Цена"
  cuiTextFieldIconLeft="cuiIconSearch"
></cui-input-number>
```

### Feature: CuiInputPasswordComponent (`cui-input-password`)
Описание: парольный инпут с кнопкой показать/скрыть.
Публичный API:
- Модуль: `CuiInputPasswordModule`
- Inputs: нет (используются `cuiTextField*` директивы)
Пример:
```html
<cui-input-password
  [formControl]="passwordControl"
  cuiTextFieldId="password"
  cuiTextFieldPlaceholder="Пароль"
></cui-input-password>
```

### Feature: CuiInputTextComponent (`cui-input-text`)
Описание: текстовый инпут с кнопкой очистки.
Публичный API:
- Модуль: `CuiInputModule` (важно: имя модуля именно такое)
- Inputs: нет (используются `cuiTextField*` директивы)
Пример:
```html
<cui-input-text
  [formControl]="searchControl"
  cuiTextFieldId="search"
  cuiTextFieldPlaceholder="Поиск"
  cuiTextFieldIconLeft="cuiIconSearch"
></cui-input-text>
```

### Feature: CuiInputTimeComponent (`cui-input-time`)
Описание: ввод времени с маской, значение - `CuiTime`.
Публичный API:
- Модуль: `CuiInputTimeModule`
- Inputs: `mode: CuiTimeMode` (по умолчанию `HH:MM`)
- Типы: `CuiInputTimeOptions`
- Константы/токены: `CUI_INPUT_TIME_DEFAULT_OPTIONS`, `CUI_INPUT_TIME_OPTIONS`
Пример:
```html
<cui-input-time
  [formControl]="timeControl"
  mode="HH:MM:SS"
  cuiTextFieldPlaceholder="Время"
></cui-input-time>
```

### Feature: CuiLabelComponent (`label[cuiLabel]`)
Описание: стилизованный label с возможностью показать звездочку.
Публичный API:
- Модуль: `CuiLabelModule`
- Inputs: `isRequired: boolean`
Пример:
```html
<label cuiLabel [isRequired]="true" for="email">Email</label>
```

### Feature: CuiNotificationComponent (`cui-notification`)
Описание: уведомление со статусом и иконкой, опционально с кнопкой закрытия.
Публичный API:
- Модуль: `CuiNotificationModule`
- Inputs: `status`, `mode`, `isCloseable`
- Outputs: `closed`
- Типы: `CuiNotificationOptions`, `CuiNotificationIcons`, `CuiNotificationIconOptions`
- Константы/токены: `CUI_NOTIFICATION_DEFAULT_OPTIONS`, `CUI_NOTIFICATION_OPTIONS`, `CUI_NOTIFICATION_ICONS`, `CUI_NOTIFICATION_ICON_OPTIONS`, `CUI_NOTIFICATION_ICON_OPTIONS_DEFAULT_MODE`, `CUI_NOTIFICATION_ICON_OPTIONS_LIGHT_MODE`
Пример:
```html
<cui-notification status="success" mode="light" [isCloseable]="true" (closed)="onClosed()">
  Успешно сохранено
</cui-notification>
```

### Feature: CuiRadioComponent (`input[type="radio"][cuiRadio]`)
Описание: стилизованный radio, логика остается нативной.
Публичный API:
- Модуль: `CuiRadioModule`
- Inputs/Outputs: нет
Пример:
```html
<input cuiRadio type="radio" [formControl]="choiceControl" value="a">
```

### Feature: CuiRootComponent (`cui-root`)
Описание: корневой контейнер UI, включает `cui-dialogs` и `cui-alerts`, устанавливает атрибут `cuiTheme`.
Публичный API:
- Модуль: `CuiRootModule`
- Inputs/Outputs: нет
- Константа: `CUI_ROOT_SELECTOR`
Пример:
```html
<cui-root>
  <app-root-content></app-root-content>
</cui-root>
```

### Feature: CuiSelectComponent (`cui-select[options]`)
Описание: селект с выпадающим списком, использует `cui-root` для оверлея.
Публичный API:
- Модуль: `CuiSelectModule`
- Inputs: `options: CuiOption[]`, `defaultOptionText?: string`
- Значение: `unknown` через ControlValueAccessor
Пример:
```html
<cui-select
  [options]="statusOptions"
  [formControl]="statusControl"
  cuiTextFieldId="status"
  cuiTextFieldPlaceholder="Статус"
></cui-select>
```

### Feature: CuiSvgComponent (`cui-svg[icon]`)
Описание: рендер SVG по имени иконки или по сырому SVG string.
Публичный API:
- Модуль: `CuiSvgModule`
- Inputs: `icon`, `width`, `height`, `strokeWidth`, `color`
Пример:
```html
<cui-svg icon="cuiIconCheck" [width]="16" [height]="16" color="var(--cui-success)"></cui-svg>
```

### Feature: CuiTabsComponent (`cui-tabs`)
Описание: контейнер табов, управляет активным индексом.
Публичный API:
- Модуль: `CuiTabsModule`
- Inputs: `activeItemIndex: number`
- Outputs: `activeItemIndexChange`
Пример:
```html
<cui-tabs [(activeItemIndex)]="tabIndex">
  <button cuiTab>Общее</button>
  <button cuiTab>Настройки</button>
</cui-tabs>
```

### Feature: CuiTabComponent (`button[cuiTab]`)
Описание: кнопка таба, эмитит событие активации.
Публичный API:
- Модуль: `CuiTabsModule`
- Inputs/Outputs: нет
Пример:
```html
<button cuiTab>Таб</button>
```

### Feature: CuiTextareaComponent (`textarea[cuiTextarea]`)
Описание: стилизованный textarea с авто-ресайзом.
Публичный API:
- Модуль: `CuiTextareaModule`
- Inputs: `rows`, `noBordersAndPaddings`
Пример:
```html
<textarea
  cuiTextarea
  [rows]="3"
  [noBordersAndPaddings]="false"
  [cuiTextFieldIsError]="true"
></textarea>
```

### Feature: CuiToggleComponent (`input[type="checkbox"][cuiToggle]`)
Описание: стилизованный toggle на базе checkbox.
Публичный API:
- Модуль: `CuiToggleModule`
- Inputs/Outputs: нет
Пример:
```html
<input cuiToggle type="checkbox" [formControl]="toggleControl">
```

## Директивы (Core)

### Feature: CuiTextFieldControllerModule
Описание: модуль с директивами управления полями (`cuiTextField*`). Экспортируется входными компонентами.
Публичный API:
- Экспортирует: `CuiTextFieldIconLeftDirective`, `CuiTextFieldIdDirective`, `CuiTextFieldIsErrorDirective`, `CuiTextFieldPlaceholderDirective`, `CuiTextFieldSizeDirective`
Пример:
```ts
imports: [CuiTextFieldControllerModule]
```

### Feature: CuiTextFieldIconLeftDirective (`[cuiTextFieldIconLeft]`)
Описание: задает иконку слева для текстовых полей.
Публичный API:
- Input: `cuiTextFieldIconLeft: CuiIcon`
Пример:
```html
<cui-input-text cuiTextFieldIconLeft="cuiIconSearch"></cui-input-text>
```

### Feature: CuiTextFieldIdDirective (`[cuiTextFieldId]`)
Описание: прокидывает `id` внутрь поля.
Публичный API:
- Input: `cuiTextFieldId: string`
Пример:
```html
<cui-input-text cuiTextFieldId="search"></cui-input-text>
```

### Feature: CuiTextFieldIsErrorDirective (`[cuiTextFieldIsError]`)
Описание: задает состояние ошибки для поля.
Публичный API:
- Input: `cuiTextFieldIsError: boolean`
Пример:
```html
<cui-input-text [cuiTextFieldIsError]="hasError"></cui-input-text>
```

### Feature: CuiTextFieldPlaceholderDirective (`[cuiTextFieldPlaceholder]`)
Описание: задает placeholder для поля.
Публичный API:
- Input: `cuiTextFieldPlaceholder: string`
Пример:
```html
<cui-input-text cuiTextFieldPlaceholder="Введите текст"></cui-input-text>
```

### Feature: CuiTextFieldSizeDirective (`[cuiTextFieldSize]`)
Описание: задает размер поля.
Публичный API:
- Input: `cuiTextFieldSize: 'sm' | 'md'`
Пример:
```html
<cui-input-text cuiTextFieldSize="md"></cui-input-text>
```

### Feature: CuiTextFieldController
Описание: класс, агрегирующий параметры из `cuiTextField*` директив.
Пример:
```ts
const controller = inject(CUI_TEXT_FIELD_CONTROLLER);
console.log(controller.size);
```

### Feature: CUI_TEXT_FIELD_CONTROLLER и CUI_TEXT_FILED_CONTROLLER_PROVIDER
Описание: DI токен и провайдер, собирающие параметры из `cuiTextField*` директив в единый контроллер.
Публичный API:
- Токен: `CUI_TEXT_FIELD_CONTROLLER`
- Провайдер: `CUI_TEXT_FILED_CONTROLLER_PROVIDER`
- Токены директив: `CUI_TEXT_FIELD_ICON_LEFT`, `CUI_TEXT_FIELD_ID`, `CUI_TEXT_FIELD_IS_ERROR`, `CUI_TEXT_FIELD_PLACEHOLDER`, `CUI_TEXT_FIELD_SIZE`
Пример:
```ts
const controller = inject(CUI_TEXT_FIELD_CONTROLLER);
console.log(controller.placeholder);
```

## Сервисы (Core)

### Feature: CuiThemeService
Описание: сервис темы, хранит состояние в localStorage и выставляет `cuiTheme` через `CuiRootComponent`.
Публичный API:
- Методы: `next(theme: 'light' | 'dark')`, `switch()`
- Токены/константы: `CUI_THEME`, `CUI_THEME_STORAGE_KEY`, `CUI_THEME_STORAGE_DEFAULT_KEY`, `CUI_DEFAULT_THEME`
Пример:
```ts
const theme = inject(CuiThemeService);
theme.switch();
```
Пример (дефолтная тема и ключ хранения):
```ts
providers: [
  { provide: CUI_THEME, useValue: 'dark' },
  { provide: CUI_THEME_STORAGE_KEY, useValue: 'myThemeKey' }
]
```

## Интерфейсы и типы (Core)

### Feature: CuiOption
Описание: модель опции для `cui-select`.
Публичный API:
- Поля: `label: string`, `value: unknown`, `isDisabled?: boolean`
Пример:
```ts
const options: CuiOption[] = [
  { label: 'Active', value: 'active' },
  { label: 'Archived', value: 'archived', isDisabled: true }
];
```

### Feature: CuiContextMenuItem
Описание: модель элемента контекстного меню.
Публичный API:
- Поля: `label`, `icon?`, `color?`, `command?`
Пример:
```ts
const items: CuiContextMenuItem[] = [
  { label: 'Edit', icon: 'cuiIconEdit', command: () => onEdit() },
  { label: 'Delete', icon: 'cuiIconTrash', color: 'var(--cui-danger)' }
];
```

### Feature: CuiAppearance* types
Описание: набор типов appearance для кнопок.
Публичный API:
- Значения: `action | secondary | outlined | outlined-gray | ghost | flat | destructive | link`
Пример:
```ts
const appearance: CuiAppearanceAction = 'action';
```

### Feature: CuiHintType
Описание: тип подсказки `cui-hint`.
Публичный API:
- Значения: `info | error`
Пример:
```ts
const hintType: CuiHintType = 'error';
```

### Feature: CuiPosition* types
Описание: позиции для алертов.
Публичный API:
- Значения: `center | right`
Пример:
```ts
const position: CuiPositionCenter = 'center';
```

### Feature: CuiResizing* types
Описание: режимы ресайза для алертов.
Публичный API:
- Значения: `hug | fixed`
Пример:
```ts
const resizing: CuiResizingFixed = 'fixed';
```

### Feature: CuiShapeRounded
Описание: shape тип для кнопок.
Публичный API:
- Значение: `rounded`
Пример:
```ts
const shape: CuiShapeRounded = 'rounded';
```

### Feature: CuiSize* types
Описание: типы размеров.
Публичный API:
- Значения: `xxs | xs | sm | md`
Пример:
```ts
const size: CuiSizeSm = 'sm';
```

### Feature: CuiStatus
Описание: статусы для уведомлений/баннеров.
Публичный API:
- Значения: `success | info | alert | error`
Пример:
```ts
const status: CuiStatus = 'success';
```

## Утилиты (Core)

### Feature: cuiRemoveSpaces
Описание: удаляет все пробелы из строки.
Публичный API:
- Сигнатура: `(value: string) => string`
Пример:
```ts
cuiRemoveSpaces('a b  c'); // "abc"
```

### Feature: cuiReplace
Описание: безопасная замена всех вхождений подстроки.
Публичный API:
- Сигнатура: `(value: string, search: string, replace: string) => string`
Пример:
```ts
cuiReplace('a.b.c', '.', '-'); // "a-b-c"
```

## Темы и стили

### Feature: CSS переменные темы
Описание: базовые и темные токены описаны в `projects/core/styles/theme.scss`. Темная тема задается через атрибут `cuiTheme="dark"`.
Пример:
```scss
:root {
  --cui-main-font: 'Inter', sans-serif;
}
[cuiTheme='dark'] {
  --cui-base-0: var(--cui-slate-900);
}
```

### Feature: SCSS переменные и миксины
Описание: `projects/core/styles/global.scss` форвардит миксины и переменные (`mixins/*`, `variables/*`).
Пример:
```scss
@use '@cuby-ui/core/styles/global' as cui;

.btn-reset {
  @include cui.cui-clear-button();
}
```

## Рецепты (How-to)

### Feature: Рецепт - показать alert
Описание: использовать `CuiAlertService` и убедиться, что есть `cui-root`.
Пример:
```ts
const alerts = inject(CuiAlertService);
alerts.open('Все ок', { status: 'success', label: 'Готово' }).subscribe();
```

### Feature: Рецепт - открыть диалог с данными
Описание: открыть компонент и прочитать `data` через `CUI_DIALOG_CONTEXT`.
Пример:
```ts
dialogs.open(EditDialogComponent, { size: 'xl', data: { id: 42 } }).subscribe();
```
```ts
const context = inject<CuiDialogContext<{ id: number }>>(CUI_DIALOG_CONTEXT);
console.log(context.data.id);
```

### Feature: Рецепт - использовать `cui-select` с ошибкой
Описание: задать опции и состояние ошибки через `cuiTextFieldIsError`.
Пример:
```html
<cui-select
  [options]="options"
  [formControl]="control"
  [cuiTextFieldIsError]="hasError"
></cui-select>
```

### Feature: Рецепт - переопределить дефолтные опции кнопки
Описание: использовать `CUI_BUTTON_OPTIONS` в провайдерах.
Пример:
```ts
providers: [
  { provide: CUI_BUTTON_OPTIONS, useValue: { appearance: 'secondary', size: 'md', shape: 'rounded' } }
]
```

### Feature: Рецепт - переключение темы
Описание: вызвать `switch()` у `CuiThemeService`.
Пример:
```ts
inject(CuiThemeService).switch();
```

## Анти-паттерны
- Анти-паттерн: использовать `CuiAlertService.open()` без подписки. Описание: Observable ленивый, без `subscribe()` алерт не создается.
- Анти-паттерн: использовать `cui-select` или `cui-context-menu` без `cui-root`. Описание: оверлей некуда монтировать.
- Анти-паттерн: передавать `ElementRef` вместо `HTMLElement` в `target`. Описание: компонент ожидает `HTMLElement`.
- Анти-паттерн: передавать строку вместо `CuiTime` в `cui-input-time`. Описание: компонент ожидает `CuiTime`.

## FAQ / типовые ошибки
- Вопрос: почему не открывается диалог? Ответ: проверьте, что вы подписались на `open()` и в DOM есть `cui-root`.
- Вопрос: почему не видно placeholder в `cui-input-text`? Ответ: используйте `cuiTextFieldPlaceholder`, а не нативный `placeholder`.
- Вопрос: почему select не закрывается? Ответ: убедитесь, что есть `cui-root` и не блокируется событие клика снаружи.

## Структура репозитория
- `projects/core` - UI компоненты, стили, темы.
- `projects/cdk` - утилиты, директивы, сервисы.
- `projects/icons` - SVG иконки и типы.
- `projects/test` - sandbox приложение с примерами.
- `angular.json` - конфигурация Angular workspace.

## Линт и форматирование
- Явных конфигураций ESLint/Prettier в репозитории нет. Ориентируйтесь на текущий стиль файлов и типичные правила Angular/TypeScript.

## Версии и совместимость
- Angular: `>=15.0.0`
- RxJS: `>=7.0.0`
- `@maskito/*`: `^2.5.0` (input number/time)
- `@tinkoff/ng-polymorpheus`: `^4.3.0` (dialog header)
- Пакеты `@cuby-ui/*`: версия `0.0.177` (см. `projects/*/package.json`)
