Skip to content
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(Button,Link): add component prop #3521

Merged
merged 8 commits into from
Sep 30, 2024
Merged

feat(Button,Link): add component prop #3521

merged 8 commits into from
Sep 30, 2024

Conversation

zhzz
Copy link
Member

@zhzz zhzz commented Sep 26, 2024

Этот ПР - версия #3421 для 5.x.

Проблема

В Button нет возможности внутри отрендерить <a /> с соответствующими пропами: href, rel и т.д.
В Link нет публичной возможности отрендерить <button /> или <NavLink /> из react-router-dom.

Решение

Добавлен проп component в Button и Link. Проп принимает значения: a | button | React.ElementType;

Стали возможны следующие сценарии использования:

import { NavLink } from 'react-router-dom';

<Button component="a" href="https://google.com" target="blank" />
<Button component={NavLink} to="/" />

<Link component="button" type="submit" />
<Link component={NavLink} to="/" use="danger" />
Изменения по сравнению с оригинальным ПР для ревьюера

Документация
После добавления пропов component и доработки типов Button и Link в доке перестали отображаться пропы нативных button и a, которые принимаются в них по умолчанию. Решить эту проблему не удалось. Обошел добавлением соответствующих примеров в доку. Доку скоро обновим, возможно эта проблема пропадет.

Также, перенес другие примеры с component повыше, чтобы были на виду, т.к. кейс должен быть популярным.

globalClasses.customComponent
Кажется, был добавлен лишний глобальный класс в Button. Убрал, прогнал тесты, ничего не сломалось.

Проп component в defaultProps
Добавил, чтобы можно было делать type guard'ы, например, isAnchorProps в Link. Это помогает безопаснее работать с пропами внутри компонентов.

Переименования
Константы *_DEFAULT_ELEMENT переименовал в *_DEFAULT_COMPONENT. А файл react-ref.d.ts переименовал в polymorphic-component.d.ts. Так вроде больше соответствует действительности.

Проп as в Button
Удалил его, так как он более не был нужен и дублировал проп component. Вместо него для use="link" по назначению заиспользовал component, создав более минималистичный компонент SpanComponent, чем использовался там раньше. Однако в этом месте вывод типов в Link почему-то не сработал и пришлось прокинуть дженерик.

Логика handleClick в Link
Убрал preventDefault при клике на ссылку с пустым href. По-моему, это нужно было раньше только потому, что без указания href нативная ссылка внутри была неактивной из-за чего компонент выглядел неправильно. Поэтому в href добавлялась пустая строка. Но клик по такой ссылке вызывал смену урла, что было нежелательным для Link, в который вообще ничего не передали. Поэтому делали делали preventDefault. Однако это все больше неактуально, т.к. новые стили работают и для неактивной ссылки и для любого другого компонента.

Однако, ссылки без href считаются не a11y в тестах не находятся через getByRole('link'). Поэтому в тестах его пришлось проставить.

Проброс пропов в Root
Убрал явный проброс linkOnlyProps в Link, т.к. он все равно случится через передачу rest.

По этой же причине убрал манипуляции с aria-аттрибутами, role и обработчиками событий в Button. Также в нем пришлось переделать оборачивание в CommonWrapper таким образом, чтобы в Root через rest не попали пропы, которые должны попасть на обертку (это className, style и все data-пропы). Так уже было сделано в Link, например. Но Button раньше не принимал всех пропов HTMLButtonElement, поэтому в нем такие переделки понадобились только сейчас. Подробнее тут.

outline-обводка в Link
z-index: -1, который был на обводке ранее, иногда прятал ее за другие элементы на странице. Переверстал, чтобы такого не происходило. Из-за этого вроде незначительно обновились скриншоты <Select use="link" /> в хроме.

Депрекейт
Решил пока закомментировать, потому что сперва захотелось проверить их взаимозаменяемость с <Link component="button" /> и обсудить решение в отдельной статье.

Ломающие изменения

  1. В обработчике клика Link убран preventDefault в случае пустого href.
  2. Button по умолчанию начал принимать все пропы нативного <button />

Ссылки

Задача: IF-1733.
Обновленная песочница для тестов.

Чек-лист перед запросом ревью

  1. Добавлены тесты на все изменения
    ✅ unit-тесты для логики
    ✅ скриншоты для верстки и кросс-браузерности
    ⬜ нерелевантно

  2. Добавлена (обновлена) документация
    ✅ styleguidist для пропов и примеров использования компонентов
    ⬜ jsdoc для утилит и хелперов
    ⬜ комментарии для неочевидных мест в коде
    ⬜ прочие инструкции (README.md, contributing.md и др.)
    ⬜ нерелевантно

  3. Изменения корректно типизированы
    ✅ без использования any (см. PR 2856)
    ⬜ нерелевантно

  4. Прочее
    ✅ все тесты и линтеры на CI проходят
    ✅ в коде нет лишних изменений
    ✅ заголовок PR кратко и доступно отражает суть изменений (он попадет в changelog)

@zhzz zhzz force-pushed the button-link-5.x branch 2 times, most recently from f17fa3c to 917c30a Compare September 26, 2024 17:38
@zhzz zhzz requested a review from Funkicide September 26, 2024 18:52
@zhzz zhzz marked this pull request as ready for review September 27, 2024 04:59
Copy link
Member

@Funkicide Funkicide left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Остались ещё скриншоты старых тем у теста 'Button As Link Icon Color'.

@zhzz zhzz requested a review from Funkicide September 30, 2024 12:36
@zhzz zhzz merged commit 27726a9 into 5.x Sep 30, 2024
7 checks passed
@zhzz zhzz deleted the button-link-5.x branch September 30, 2024 12:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants