retail-ui
retail-ui copied to clipboard
feat(Clickable): add new component
Проблема
Пользователям нужен компонент, который может выглядеть как кнопка или как ссылка, при этом под капотом у которого может быть любой тег: button
, a
и даже div
, для тех случаев когда нужен внешний вид, но не нужна семантика. Например, когда сверху компонента есть <button>
и внутрь нужно вложить нашу кнопку — в таком случае пригодится просто представление компонента без семантики и обработки событий, которую организуют <button>
и <a>
.
Решение
Создал компонент <Clickable>
, который представляет из себя единый интерфейс доступа к внешнему виду и семантике кнопки и ссылки. Компонент основан на обсуждении из #2598 и задаче IF-959, а также ещё некоторых незадокументированных обсуждениях.
Идея:
Я добавил два новых пропа: as
и view
. Они призваны отделить внешнее представление компонента от его семантики. Проп as
позволяет задавать корневой тег, а проп view
задаёт внешний вид контрола.
Изменения:
Помимо нового компонента и пропов я внёс несколько изменений в API
, которые призваны сделать его более удобным для пользователей, а также закрыл несколько параллельных задач
- Появился новый про
rightIcon
(IF-1450); - Компонент не поддерживает
DEFAULT_THEME
иIE11
. Я отказался от их поддержки, в пользу простоты кода, с учётом того, что в скором будущем мы планируем отказаться от их поддержки; - Проп
arrow
теперь принимает'left' | 'right'
, вместоboolean | 'left'
; - У контрола расширился
use
в связи с тем, что он теперь хранитuse
'ы, которые ему достались отButton
иLink
; - В
<Clickable>
нет скриншота со сбросом (reset) стилей, так как стили стали сбрасываться черезall: unset
, который не сбрасывает те стили, которые проверяются в скриншоте. Настолько сильно сбрасывать стили мне показалось избыточным, поэтому я не стал реализовывать эту логику в новом компоненте; - Я убрал селектор по
:enabled
из стилей<ClickableButton>
, так как только кнопка поддерживает этот псевдокласс. Он заменён на селектор поaria-disabled
, там где это необходимо; - Упростил логику и переписал
<ComponentTable>
в силу того, что он не умел работать с функциональными компонентами. Я удалил часть логики из<ComponentTable>
, но она не использовалась ни в одном из тестируемых компонентов. После этого пришлось обновить несколько скриншотов, но на самих скриншотах ничего не изменилось, кроме того, что в некоторых местах пропали кавычки от<ComponentTable>
, изменился порядок пропов, если в компонент передаётсяchildren
, а также стали выводиться все пропы, которые передаются вchildren
.
Исправления/улучшения:
- На корень больше не прокидывается атрибут
disabled
(IF-1661). Вместо него прокидывается атрибутaria-disabled
. Это позволяет фокусироваться на кнопке и сообщать пользователям скрин-ридеров, что она отключена. На замену HTML-состояниюdisabled
в стилях для состояния контролаdisabled
пришёл стильpointer-events: none
; - Добавлена поддержка всех атрибутов кнопки и ссылки, включая
aria
-аттрибуты; - Добавлен атрибут
aria-live="assertive"
, который позволяет озвучивать текст в кнопке, если он поменялся по ходу работы приложения; - Удалил старые скриншоты для
<Link>
и заменил их на более продвинутые скриншоты, которые используются в<ClickableLink>
; - Проп
theme
больше не падает на корневой тег (IF-1660); - Компонент можно программно зафокусить (IF-638) — исправлено использованием
:focus-visible
; - Подчёркивание у
<Clickable as="a" view="button"
отображается корректно (IF-521), но возможно этого бага в новой теме и не было, вероятно стоит просто закрыть IF-521 задачу; - Добавлено состояние
error
для ссылки (IF-1651).
Итог:
Перенёс всю логику из <Button>
и <Link>
в <Clickable>
, объединил и дополнил тесты для компонентов (как скриншотные, так и интеграционные), написал документацию к новому компоненту.
Ссылки
IF-969, #2598, IF-1450, IF-1661, IF-1660, IF-638, IF-521, IF-1651
Чек-лист перед запросом ревью
-
Добавлены тесты на все изменения ✅ unit-тесты для логики ✅ скриншоты для верстки и кросс-браузерности ⬜ нерелевантно
-
Добавлена (обновлена) документация ✅ styleguidist для пропов и примеров использования компонентов ✅ jsdoc для утилит и хелперов ✅ комментарии для неочевидных мест в коде ⬜ прочие инструкции (
README.md
,contributing.md
и др.) ⬜ нерелевантно -
Изменения корректно типизированы ✅ без использования
any
(см. PR2856
) ⬜ нерелевантно -
Прочее ✅ все тесты и линтеры на CI проходят ✅ в коде нет лишних изменений ✅ заголовок PR кратко и доступно отражает суть изменений (он попадет в changelog)
- Концептуально хочется чтобы по умолчанию "Clickable" был просто button без каких либо стилей, чтобы в продуктах можно было выпилить "велосипеды Clickable"
Концептуально хочется чтобы по умолчанию "Clickable" был просто button без каких либо стилей, чтобы в продуктах можно было выпилить "велосипеды Clickable"
Добавил view="custom"
, который позволяет сбросить стили. По умолчанию оставил view="button"
, думаю что лучше изменять это значение на основе фидбека от пользователей. Пока что кажется, что плавный переезд со старых компонентов круче, чем view="custom"
по умолчанию