Структура DOM

Slim Select строится вокруг идеи минимального вмешательства в исходный <select>-элемент при одновременном создании собственной управляемой DOM-обёртки. В результате библиотека не заменяет HTML-элемент полностью, а расширяет его поведение через дополнительную структуру узлов, синхронизируемую с оригинальным select.

Исходный элемент сохраняется в DOM и продолжает играть роль источника данных и состояния, однако становится скрытым от пользователя через стилизацию (display: none или аналогичные техники). Вся визуальная часть формируется отдельным контейнером.


Инициализация и корневой контейнер

После вызова инициализации Slim Select создаёт основной контейнер, который оборачивает исходный <select>.

Типичная структура:

<div class="ss-main">
    <select class="ss-hidden">
        <option value="1">Option 1</option>
        <option value="2">Option 2</option>
    </select>

    <div class="ss-single-selected">
        ...
    </div>

    <div class="ss-content">
        ...
    </div>
</div>

Основные элементы:

  • ss-main — корневой контейнер компонента
  • ss-hidden — скрытый оригинальный <select>
  • ss-single-selected — область отображения текущего значения
  • ss-content — выпадающий список опций

Скрытый оригинальный select

Исходный <select> не удаляется из DOM. Он:

  • сохраняет все <option> и <optgroup>
  • остаётся источником truth of state
  • синхронизируется при изменениях через API Slim Select
<select class="ss-hidden">
    <option value="a">A</option>
    <option value="b" selected>B</option>
</select>

Роль в архитектуре

Этот элемент выполняет критически важную функцию:

  • хранение значения формы
  • обеспечение совместимости с нативной отправкой формы
  • работа с внешними библиотеками, читающими DOM

Slim Select всегда обновляет его при любом изменении выбора.


Контейнер отображения выбранного значения

Блок .ss-single-selected формируется только для одиночного выбора.

<div class="ss-single-selected">
    <span class="placeholder">Select option</span>
    <span class="ss-arrow"></span>
</div>

Внутренние узлы:

  • placeholder — текст по умолчанию, когда ничего не выбрано
  • selected-value — отображаемое значение выбранного option (создаётся динамически)
  • ss-arrow — элемент UI для индикации раскрытия списка

Поведение:

  • при выборе option placeholder заменяется текстом выбранного элемента
  • при сбросе выбора возвращается placeholder
  • клик по контейнеру открывает dropdown

Выпадающий список (dropdown)

Контейнер .ss-content отвечает за список доступных опций.

<div class="ss-content">
    <div class="ss-search">
        <input type="text" />
    </div>

    <div class="ss-list">
        <div class="ss-option">Option 1</div>
        <div class="ss-option ss-selected">Option 2</div>
    </div>
</div>

Структура ss-content

1. Контейнер поиска

<div class="ss-search">
    <input type="text" autocomplete="off">
</div>

Функции:

  • фильтрация списка опций
  • управление фокусом
  • триггер событий поиска

Состояние input синхронизируется с внутренним фильтром Slim Select.


2. Список опций

<div class="ss-list">
    <div class="ss-option" data-value="1">Option 1</div>
    <div class="ss-option ss-disabled">Disabled option</div>
</div>

Каждый элемент .ss-option представляет один <option> из исходного select.

Ключевые состояния:

  • ss-selected — выбранный элемент
  • ss-disabled — недоступный элемент
  • ss-hide — скрытый после фильтрации

Отображение групп (optgroup)

При использовании <optgroup> структура усложняется:

<div class="ss-optgroup">
    <div class="ss-optgroup-label">Group 1</div>
    <div class="ss-option">A</div>
    <div class="ss-option">B</div>
</div>

Элементы:

  • ss-optgroup — контейнер группы
  • ss-optgroup-label — заголовок группы
  • вложенные ss-option — элементы группы

Группы сохраняют иерархию оригинального select, но визуально становятся управляемыми блоками.


Состояния элементов DOM

Slim Select активно использует классы для управления состоянием интерфейса.

Основные состояния:

  • ss-open — dropdown раскрыт
  • ss-disabled — компонент или опция отключены
  • ss-hide — элемент скрыт (фильтрация)
  • ss-selected — активный выбор
  • ss-focus — фокус ввода

Синхронизация DOM и состояния

Любое изменение в интерфейсе приводит к обновлению сразу нескольких уровней:

  1. UI слой (ss-option, ss-single-selected)
  2. скрытый <select>
  3. внутреннее состояние Slim Select (JS-объект)

Пример цепочки:

Выбор элемента:

click ss-option
→ update internal state
→ update select.value
→ rerender selected display
→ close dropdown

Множественный выбор и DOM

При multiple: true структура изменяется.

Добавляется блок выбранных элементов:

<div class="ss-values">
    <div class="ss-value">
        <span class="ss-value-text">Option 1</span>
        <span class="ss-value-delete"></span>
    </div>
</div>

Элементы:

  • ss-values — контейнер выбранных значений
  • ss-value — отдельный выбранный элемент
  • ss-value-delete — кнопка удаления

Отличия DOM при multiple режиме

  • отсутствует .ss-single-selected
  • вместо него используется .ss-values
  • каждый выбор добавляет новый DOM-узел
  • удаление значения удаляет соответствующий элемент

Производительность DOM-структуры

Slim Select минимизирует количество операций:

  • переиспользует DOM-узлы при рендере
  • избегает полного пересоздания списка
  • обновляет только изменённые элементы

Ключевая особенность — частичное обновление DOM, а не полная перерисовка.


Динамическая генерация элементов

При изменении данных через API:

  • список .ss-list пересобирается
  • .ss-option генерируются заново или обновляются
  • состояние сохраняется отдельно от DOM

Это позволяет быстро обрабатывать большие наборы данных без полной пересборки компонента.


Внутренние связки элементов

DOM Slim Select можно рассматривать как три слоя:

1. Исходный слой

  • <select>
  • <option>
  • <optgroup>

2. Логический слой

  • состояние выбора
  • фильтр
  • активный индекс

3. Визуальный слой

  • .ss-main
  • .ss-content
  • .ss-option
  • .ss-value

Итоговая архитектурная модель DOM

Slim Select реализует модель:

select (source of truth)
        ↓ sync
internal state (JS)
        ↓ render
custom DOM UI

Любое взаимодействие проходит через эту цепочку, что делает структуру предсказуемой и контролируемой при работе с динамическими формами и сложными интерфейсами.