-
Notifications
You must be signed in to change notification settings - Fork 184
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
fix(Select): make Select accessible for screen readers #6087
fix(Select): make Select accessible for screen readers #6087
Conversation
size-limit report 📦
|
e2e tests |
👀 Docs deployed
Commit 952e1ec |
eaea297
to
28897ff
Compare
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit 952e1ec:
|
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## master #6087 +/- ##
==========================================
+ Coverage 79.13% 79.17% +0.04%
==========================================
Files 312 313 +1
Lines 9957 10018 +61
Branches 3332 3352 +20
==========================================
+ Hits 7879 7932 +53
- Misses 2078 2086 +8
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
4ff2e40
to
ca60b21
Compare
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.
Андрей, ты 🚀 Огромная работа проделана!
packages/vkui/src/components/CustomSelect/CustomSelect.test.tsx
Outdated
Show resolved
Hide resolved
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.
❤️🔥❤️🔥❤️🔥
packages/vkui/src/components/CustomSelect/CustomSelectInput.module.css
Outdated
Show resolved
Hide resolved
packages/vkui/src/components/CustomSelect/CustomSelectInput.module.css
Outdated
Show resolved
Hide resolved
Group aria-attributes Improve focus on SelectMimicry in searchable mode Improve FromItem to use together with Select/CustomSelect Update doc for FormItem to recommend to use more attributes to correctly connect FormItem with Select Use a11y attributes in CustomSelect examples Update Select and NativeSelect examples to include a11y Update links in the FormItem doc Add a11y doc to Select and CustomSelect
We have it in the Text component
We don't use anything from RootComponent
1d04e7d
to
fcf39dc
Compare
Спасибо за ревью! 👍 |
Спасибо за ревью! 💪 |
Спасибо за ревью! 💪 ✍️ |
…ders (#6087) - close #3547 Описание Добавляем `aria`-аттрибуты `CustomSelect`'у, следуя паттерну [Combobox](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/). Как для обычного режима селекта, так и для `searchable` режима, когда в инпут можно вводить текст для фильтрации опций. Изменения - добавлены aria-аттрибуты для CustomSelect, следуя паттерну [Combobox](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/) - исправлена работа `onBlur/onFocus` пропов. Начиная с react17 react больше не реагирует на dispatch кастомных событий `blur/focus` и мы должны создавать события `focusin` `focusout`. - вместо попеременного использования `Input` и `SelectMimicry` мы теперь всегда используем внутренний компонент `CustomSelectInput`. Это позволило избавиться от множества проблем и блокеров для поддержки доступности. - ушла проблема с потерей фокуса при выборе опции в режиме `searchable` - при фокусе на селекте в режиме `searchable` сразу доступен ввод с клавиатуры для поиска опций, причём скрин ридер правильно зачитывает информацию о селект и выбранной опции если она есть, либо плейсхолдер. - стал из коробки работать фокус на селекте при клике на связанный с селектом лэйбл. - для связи с лэйблом достаточно просто задать `id` селекта в `htmlFor` аттрибуте лэйбла. Без инпута для этого надо было бы ещё и прокидывать связь через `aria-labelledby`. - инпут имеет свойство `autoComplete="off"`, потому что хром начинает предлагать свои варианты для заполнения инпута и мешает взаимодействовать с открытым списком. - новый компонент (`CustomSelectInput`) был добавлен ввиду того, что невозможно было переиспользовать имеющийся `Input` или `SelectMimicry` без внесений лишних изменений. Тем не менее `CustomSelectInput` продолжает внутри себя использовать `FormField` и заимствует часть свойство, имеющихся у `Input` и `SelectMimicry`. В данный момент я не собираюсь переделывать `SelectMimicry` в рамках этого PR, но не против попробовать сделать это в будущем. - после тестирования селекта специалистом по доступности, было принято решение убрать обёртку компонентом `label` из `CustomSelect` и `NativeSelect`, потому что это заставляет скринридер зачитывать текст дважды при навигации с помощью стрелок, если у селекта выбранна опция. Не всегда, лишь в некоторых версиях Хром, но поведение стабильное. - тем не менее мы оставили поведения подобное `label` с помощью дополнительного кода в CustomSelect. В NativeSelect дополнительного кода не требуется, потому что нативный селект растянут и лежит поверх визуальных элементов и гарантирует фокус на селекте при клике по любой области внутри компонента NativeSelect. - исправлено прыгающее поведение фокуса на опции при навигации с клавиатуры, если на одну из опций наведён курсор. https://github.com/VKCOM/VKUI/blob/9bae73ff784eaf7f6de096e8b7f56485f2e9cb50/packages/vkui/src/components/CustomSelect/CustomSelect.tsx#L677-L685 - в документацию по `Select/CustomSelect` добавлены разделы про доступность с рекомендацией использования label и связывания label с селект. - обновлены примеры документации, FormItem лэйблы теперь связаны с селектами, для демонстрации предпочтительного использования.
…7816) На touch устройстве не работает фокус на input при клике в зоне инпута ближе к стрелочке. Фокус есть на обертке, но сам инпут фокуса не имеет и клавиатура не появляется, как при клике на сам инпут, ближе к левому краю. Воспроизводится в симуляторе Iphone и на реальном устройстве. Дело в том, что не во всей видимой области инпута событие клика принимает input, и чтобы это победить мы программно вызываем фокус на инпуте. Изначально, в #6087, а конкретно в 0f45bb9 это было реализовано с помощью отложенного вызова фокуса для кнопки очистки, а потом функция с отложенным фокусом перекочевала и на остальной новый код. Объяснялось это тем, что без таймаута фокус просто не работал при клике на clear button. Финальный код был сложнее, чем тот, когда этот отложенный фокус был добавлен, и он уже мог работать без отложенного вызова фокуса. Протестировал в браузере и в симуляторе Iphone.
) На touch устройстве не работает фокус на input при клике в зоне инпута ближе к стрелочке. Фокус есть на обертке, но сам инпут фокуса не имеет и клавиатура не появляется, как при клике на сам инпут, ближе к левому краю. Воспроизводится в симуляторе Iphone и на реальном устройстве. Дело в том, что не во всей видимой области инпута событие клика принимает input, и чтобы это победить мы программно вызываем фокус на инпуте. Изначально, в #6087, а конкретно в 0f45bb9 это было реализовано с помощью отложенного вызова фокуса для кнопки очистки, а потом функция с отложенным фокусом перекочевала и на остальной новый код. Объяснялось это тем, что без таймаута фокус просто не работал при клике на clear button. Финальный код был сложнее, чем тот, когда этот отложенный фокус был добавлен, и он уже мог работать без отложенного вызова фокуса. Протестировал в браузере и в симуляторе Iphone.
…7816) На touch устройстве не работает фокус на input при клике в зоне инпута ближе к стрелочке. Фокус есть на обертке, но сам инпут фокуса не имеет и клавиатура не появляется, как при клике на сам инпут, ближе к левому краю. Воспроизводится в симуляторе Iphone и на реальном устройстве. Дело в том, что не во всей видимой области инпута событие клика принимает input, и чтобы это победить мы программно вызываем фокус на инпуте. Изначально, в #6087, а конкретно в 0f45bb9 это было реализовано с помощью отложенного вызова фокуса для кнопки очистки, а потом функция с отложенным фокусом перекочевала и на остальной новый код. Объяснялось это тем, что без таймаута фокус просто не работал при клике на clear button. Финальный код был сложнее, чем тот, когда этот отложенный фокус был добавлен, и он уже мог работать без отложенного вызова фокуса. Протестировал в браузере и в симуляторе Iphone.
…7816) (#7825) На touch устройстве не работает фокус на input при клике в зоне инпута ближе к стрелочке. Фокус есть на обертке, но сам инпут фокуса не имеет и клавиатура не появляется, как при клике на сам инпут, ближе к левому краю. Воспроизводится в симуляторе Iphone и на реальном устройстве. Дело в том, что не во всей видимой области инпута событие клика принимает input, и чтобы это победить мы программно вызываем фокус на инпуте. Изначально, в #6087, а конкретно в 0f45bb9 это было реализовано с помощью отложенного вызова фокуса для кнопки очистки, а потом функция с отложенным фокусом перекочевала и на остальной новый код. Объяснялось это тем, что без таймаута фокус просто не работал при клике на clear button. Финальный код был сложнее, чем тот, когда этот отложенный фокус был добавлен, и он уже мог работать без отложенного вызова фокуса. Протестировал в браузере и в симуляторе Iphone.
Select
#3547но я попросил ещё раз на всякий случайещё раз аппрувнул)Описание
Добавляем
aria
-аттрибутыCustomSelect
'у, следуя паттерну Combobox.Как для обычного режима селекта, так и для
searchable
режима, когда в инпут можно вводить текст для фильтрации опций.Изменения
onBlur/onFocus
пропов. Начиная с react17 react больше не реагирует на dispatch кастомных событийblur/focus
и мы должны создавать событияfocusin
focusout
.Input
иSelectMimicry
мы теперь всегда используем внутренний компонентCustomSelectInput
. Это позволило избавиться от множества проблем и блокеров для поддержки доступности.searchable
searchable
сразу доступен ввод с клавиатуры для поиска опций, причём скрин ридер правильно зачитывает информацию о селект и выбранной опции если она есть, либо плейсхолдер.id
селекта вhtmlFor
аттрибуте лэйбла. Без инпута для этого надо было бы ещё и прокидывать связь черезaria-labelledby
.autoComplete="off"
, потому что хром начинает предлагать свои варианты для заполнения инпута и мешает взаимодействовать с открытым списком.CustomSelectInput
) был добавлен ввиду того, что невозможно было переиспользовать имеющийсяInput
илиSelectMimicry
без внесений лишних изменений. Тем не менееCustomSelectInput
продолжает внутри себя использоватьFormField
и заимствует часть свойство, имеющихся уInput
иSelectMimicry
.В данный момент я не собираюсь переделывать
SelectMimicry
в рамках этого PR, но не против попробовать сделать это в будущем.label
изCustomSelect
иNativeSelect
, потому что это заставляет скринридер зачитывать текст дважды при навигации с помощью стрелок, если у селекта выбранна опция. Не всегда, лишь в некоторых версиях Хром, но поведение стабильное.label
с помощью дополнительного кода в CustomSelect. В NativeSelect дополнительного кода не требуется, потому что нативный селект растянут и лежит поверх визуальных элементов и гарантирует фокус на селекте при клике по любой области внутри компонента NativeSelect.VKUI/packages/vkui/src/components/CustomSelect/CustomSelect.tsx
Lines 677 to 685 in 9bae73f
Select/CustomSelect
добавлены разделы про доступность с рекомендацией использования label и связывания label с селект.