Ответ вслух Senior Паттерны компонентов обновлено

API компонента для дизайн-системы

Вопрос

Как бы ты спроектировал API компонента Select или Tabs для дизайн-системы, которым пользуются несколько команд?

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

Я бы сделал композиционный API на compound components: <Select, <Select.Trigger, <Select.Content, <Select.Item. Корень хранит состояние и раздаёт его через Context, поэтому команды сами решают разметку, могут добавить иконки, разделители, группы.

Что должно прозвучать в ответе

  • Композиционный API: compound components с общим Context

  • Поддержка контролируемого и неконтролируемого режимов (`value`/`defaultValue`/`onValueChange`)

  • Доступность из коробки: роли, aria-атрибуты, управление с клавиатуры, фокус

  • Слоты и `className`/стили для кастомизации вместо десятков булевых флагов

  • Проброс `ref` и остальных пропсов на корневой DOM-элемент

  • Возможность headless-варианта или опора на проверенные примитивы (Radix, React Aria)

Что могут спросить следом

  • Как не сломать потребителей при изменении API?
  • Как протестировать доступность такого компонента?
  • Как быть, если нужен полностью свой рендер пункта списка?

Разбор

Я бы сделал композиционный API на compound components: <Select>, <Select.Trigger>, <Select.Content>, <Select.Item>. Корень хранит состояние и раздаёт его через Context, поэтому команды сами решают разметку, могут добавить иконки, разделители, группы.

Компонент должен уметь оба режима, как нативный input: если передан value, правду хранит родитель, иначе внутреннее состояние с начальным defaultValue, а onValueChange вызывается всегда.

Доступность не опциональна: правильные роли, aria-expanded, aria-selected, навигация стрелками, Escape, возврат фокуса. Тут я бы опирался на проверенные примитивы вроде Radix или React Aria, а не писал всё с нуля.

Для кастомизации даю слоты и className, а не флаги. Корень принимает ref и остальные пропсы и прокидывает их на DOM. Изменения API выпускаю через semver, старые пропсы помечаю устаревшими и оставляю на переходный период.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.