# Select Component

## Описание

Селектор - это UI-компонент, который позволяет пользователю выбирать одно или несколько значений из предопределенного списка опций. Компонент поддерживает различные типы отображения: выпадающий список, кнопки и поле ввода с автодополнением, а также настройки мультивыбора и другие параметры через систему пропсов.

## Пропсы

| Название       | Тип                                           | По умолчанию          | Описание                                                                                                                                         |
| -------------- | --------------------------------------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `id`           | `string`                                      | `crypto.randomUUID()` | Уникальный идентификатор компонента                                                                                                              |
| `wrapperClass` | `string`                                      | `""`                  | Дополнительные CSS-классы для обертки компонента                                                                                                 |
| `disabled`     | `boolean`                                     | `false`               | Состояние отключения компонента                                                                                                                  |
| `label`        | `object`                                      | `-`                   | Настройки заголовка компонента                                                                                                                   |
| `label.name`   | `string`                                      | `""`                  | Текст заголовка компонента                                                                                                                       |
| `label.class`  | `string`                                      | `""`                  | CSS-классы для стилизации текста заголовка                                                                                                       |
| `type`         | `"select" \| "buttons" \| "input"`            | `"select"`            | Тип отображения: `select` — выпадающий список с кнопкой, `buttons` — горизонтальный ряд кнопок, `input` — поле ввода с автодополнением и поиском |
| `multiSelect`  | `boolean`                                     | `false`               | Режим множественного выбора: работает только с `type: "buttons"`; при `true` позволяет выбирать несколько опций, значение передаётся как массив  |
| `listHeight`   | `string`                                      | `undefined`           | Максимальная высота выпадающего списка опций (для типов `select`/`input`)                                                                        |
| `value`        | `IOption<T> \| IOption<T>[] \| null`          | `null`                | Текущее выбранное значение(я); поддерживает двустороннее связывание (`$bindable`)                                                                |
| `options`      | `IOption<T>[]`                                | `[]`                  | Массив доступных опций                                                                                                                           |
| `bitMode`      | `boolean`                                     | `false`               | Режим битового выбора: значение и `range` интерпретируются как битовая маска                                                                     |
| `range`        | `object`                                      | `undefined`           | Диапазон битов, используемый в `bitMode`                                                                                                         |
| `range.start`  | `number`                                      | `-`                   | Начальный бит диапазона                                                                                                                          |
| `range.end`    | `number`                                      | `-`                   | Конечный бит диапазона                                                                                                                           |
| `onUpdate`     | `(value: IOption<T> \| IOption<T>[]) => void` | `undefined`           | Обработчик изменения значения                                                                                                                    |

### Вложенные типы

#### IOption

| Название   | Тип       | По умолчанию | Описание                        |
| ---------- | --------- | ------------ | ------------------------------- |
| `id`       | `string`  | `-`          | Уникальный идентификатор опции  |
| `value`    | `T`       | `undefined`  | Значение опции                  |
| `name`     | `string`  | `undefined`  | Отображаемое имя опции          |
| `class`    | `string`  | `undefined`  | CSS-классы для стилизации опции |
| `disabled` | `boolean` | `undefined`  | Состояние отключения опции      |

## События

| Название | Тип                                   | Описание                                      |
| -------- | ------------------------------------- | --------------------------------------------- |
| onUpdate | (value: IOption \| IOption[]) => void | Срабатывает при изменении выбранного значения |

## Примеры

### Выпадающий список

```svelte
<script>
  import * as UI from "poe-svelte-ui-lib"

  let options = [
    { id: "opt1", name: "Option 1", value: 1 },
    { id: "opt2", name: "Option 2", value: 2 },
    { id: "opt3", name: "Option 3", value: 3 },
  ]

  let selectedOption = options[0]

  const handleUpdate = (value) => {
    selectedOption = value
    console.log("Выбрана опция:", value)
  }
</script>

<UI.Select label={{ name: "Компоненты" }} {options} bind:value={selectedOption} onUpdate={handleUpdate} />
```

### Кнопочный селектор

```svelte
<script>
  import * as UI from "poe-svelte-ui-lib"

  let options = [
    { id: "btn1", name: "Button 1", value: 1, class: "bg-blue" },
    { id: "btn2", name: "Button 2", value: 2, class: "bg-green" },
    { id: "btn3", name: "Button 3", value: 3, class: "bg-red" },
  ]

  let selectedOption = options[1]
</script>

<UI.Select type="buttons" label={{ name: "Компоненты" }} {options} bind:value={selectedOption} onUpdate={handleUpdate} />
```

### С мультивыбором

```svelte
<script>
  import * as UI from "poe-svelte-ui-lib"

  let options = [
    { id: "opt1", name: "Option 1", value: 1 },
    { id: "opt2", name: "Option 2", value: 2 },
    { id: "opt3", name: "Option 3", value: 3 },
  ]

  let selectedOptions = [options[0]]

  const handleUpdate = (values) => {
    selectedOptions = values
    console.log("Выбраны опции:", values)
  }
</script>

<UI.Select type="buttons" multiSelect={true} label={{ name: "Компоненты" }} {options} bind:value={selectedOptions} onUpdate={handleUpdate} />
```

## Внутренняя архитектура

### Реактивность

- Переменная `isDropdownOpen` управляет состоянием выпадающего списка
- Переменная `searchValue` хранит значение поиска для типа "input"
- Переменная `filteredOptions` содержит отфильтрованные опции при поиске
- Функция `isSelected` определяет, выбрана ли опция

### Сторы и зависимости

- Используется стор `twMerge` для объединения Tailwind CSS классов
- Применяется переход `slide` из `svelte/transition` для анимации выпадающего списка

### Директивы

- `bind:value` для двусторонней привязки значения
- `transition:slide` для анимации выпадающего списка
- `onMount` и `onDestroy` для управления слушателями событий клика

### Слоты

- Компонент не использует внешних слотов

## Конструктор свойств (SelectProps.svelte)

### Описание

Компонент `SelectProps.svelte` предоставляет визуальный интерфейс для редактирования свойств компонента селектора. Поддерживает два режима отображения: для конструктора и для редактирования.

### Пропсы конструктора

| Название           | Тип                                                                                                                                 | По умолчанию | Описание                                                |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------- | ------------ | ------------------------------------------------------- |
| `component`        | `UIComponent & { properties: Partial<ISelectProps> }`                                                                               | `-`          | Объект компонента с его свойствами                      |
| `onPropertyChange` | `(updates: Partial<{ properties?: string \| object; name?: string; access?: string; eventHandler?: IUIComponentHandler }>) => void` | `-`          | Коллбэк для обновления свойств компонента               |
| `forConstructor`   | `boolean`                                                                                                                           | `true`       | Режим отображения (для конструктора или редактирования) |

### Особенности конструктора

- Предоставляет визуальные элементы управления для всех доступных свойств
- Поддерживает настройку типа отображения, значения и мультивыбора
- Включает управление списком опций с возможностью добавления/удаления
- Имеет различные наборы полей в зависимости от режима (`forConstructor`)
- Использует систему локализации через `$T('constructor.props.*')`

## Заметки

### Адаптивность

- Компонент использует Tailwind CSS для адаптивного дизайна
- Выпадающий список автоматически позиционируется относительно родителя
- Используются относительные единицы измерения для обеспечения масштабируемости

### Ограничения

- При использовании типа "input" доступна функция поиска по названию опций
- Мультивыбор поддерживается только для типа "buttons"
- При закрытии выпадающего списка оно закрывается при клике вне компонента

### Производительность

- Компонент использует оптимизации Svelte для минимизации перерисовок
- Фильтрация опций выполняется только при изменении поискового запроса
- Используется эффективное объединение классов через `twMerge`
