-
Notifications
You must be signed in to change notification settings - Fork 131
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(Clickable): add new component #3267
base: next
Are you sure you want to change the base?
Conversation
…n, add more tests, rework useTheme
|
Добавил |
/** | ||
* Состояние валидации при ошибке. | ||
*/ | ||
isError?: boolean; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
названия isError, isWarning сломают работу с библиотекой валидаций же? напиши пару тестов на интеграцию кликабл с либой валидаций плз
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Я никогда на практике не работал с библиотекой валидаций, но насколько знаю она в основном используется для валидации инпутов. Кнопки используются только для отправки формы (могу ошибаться тут). Не совсем понимаю, что тут могло сломаться. Можешь раскрыть эту тему?
/** | ||
* Позволяет отключить контрол. | ||
*/ | ||
isDisabled?: boolean; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
старые названия без "isXX" на мой взгляд лаконичнее были, "is" писали в стародавние времена когда не было языка с типизацией, чтобы было чуть понятнее что лежит в переменной, с тайпскриптом это рудимент, лучше писать коротко и ясно, + по кодовой базе названия без is (например input), + это ломает работу с либой валидаций
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Вернул названия без is
*/ | ||
size?: SizeProp; | ||
/** | ||
* Позвоялет перевести контрол в состояние загрузки. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
много опечаток, проверь плиз орфографию по всем файлам, например через nhunspell
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Поправил орфографию
className, | ||
)} | ||
type={Root === 'button' ? type : undefined} | ||
rel={getRel(rel, href)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rel в случае button бесполезен
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Оставил только для ссылки (<a />
)
onBlur={handleBlur} | ||
onClick={handleClick} | ||
style={{ textAlign: align, ...corners, ...style }} | ||
data-tid={ClickableDataTids.root} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
я предпочитаю сортировать пропсы, чтобы код читать и изменять было удобнее
например data-tid всегда ставлю первым атрибутом, далее системные пропсы (key, ref) далее остальные примитивные пропсы, за ними колбэки
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Думаю, что для этого лучше затащить ESLint
-правило, а не править ручками
Кажется, что это лучше тащить в другом пулл-реквесте и сразу фиксить везде
/** | ||
* Это гибридный контрол, который позволяет создавать ссылки и кнопки с любым семантическим тегом. | ||
*/ | ||
export const Clickable: PolymorphicForwardRefExoticComponent<ClickableOwnProps, typeof CLICKABLE_DEFAULT_ELEMENT> = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
очень смущает что в исходной задаче шла речь об изменении API в Button и Link, а получился новый компонент, не ясно будущее старых компонентов, давай это обсудим на команду
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Мы обсуждали это, кто-то был согласен с новым контролом, кто-то — нет. Сошлись на том, что дадим пользователям возможность протестировать новое API
, если им понравится — оставим новый контрол
В текущей реализации <Button />
и <Link />
есть много откровенных костылей, которые существуют только потому что, что эти контролы взаимозаменяемы. После совмещения их в <Clickable />
эти костыли получилось выпилить. Также в рамках <Clickable />
контролы шарят довольно много логики, а также типы, если разделять их, то логику придётся копипастить в оба контрола
По поводу дальнейшей судьбы <Button />
/<Link />
решили, что оставим их, но правки в них больше тащить не будем
…feat/button-link
Проблема
Пользователям нужен компонент, который может выглядеть как кнопка или как ссылка, при этом под капотом у которого может быть любой тег:
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);: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)