-
Notifications
You must be signed in to change notification settings - Fork 3.7k
fix: Screen Readers: Many Pages: The status message of no results is not announced. #85166
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
Changes from all commits
84927fa
1a417b0
c2a11d3
f54c868
7cb8320
6d3ea6e
297d2cb
8c1a333
f2343cf
b41225b
1f05dcb
5866cac
5409b5a
8ff7400
460abcd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| import type {ListRenderItem} from '@shopify/flash-list'; | ||
| import lodashDebounce from 'lodash/debounce'; | ||
| import React, {useCallback} from 'react'; | ||
| import React, {useCallback, useMemo, useRef, useState} from 'react'; | ||
| import {InteractionManager, View} from 'react-native'; | ||
| import type {Emoji} from '@assets/emojis/types'; | ||
| import EmojiPickerMenuItem from '@components/EmojiPicker/EmojiPickerMenuItem'; | ||
|
|
@@ -42,6 +42,7 @@ function EmojiPickerMenu({onEmojiSelected, activeEmoji, ref}: EmojiPickerMenuPro | |
| emojiListRef, | ||
| } = useEmojiPickerMenu(); | ||
| const StyleUtils = useStyleUtils(); | ||
| const [searchText, setSearchText] = useState(''); | ||
|
|
||
| const updateEmojiList = (emojiData: EmojiPickerList | Emoji[], headerData: number[] = []) => { | ||
| setFilteredEmojis(emojiData); | ||
|
|
@@ -55,18 +56,21 @@ function EmojiPickerMenu({onEmojiSelected, activeEmoji, ref}: EmojiPickerMenuPro | |
| }); | ||
| }; | ||
|
|
||
| /** | ||
| * Filter the entire list of emojis to only emojis that have the search term in their keywords | ||
| */ | ||
| const filterEmojis = lodashDebounce((searchTerm: string) => { | ||
| const filterCallbackRef = useRef<(searchTerm: string) => void>(undefined); | ||
| filterCallbackRef.current = (searchTerm: string) => { | ||
| const [normalizedSearchTerm, newFilteredEmojiList] = suggestEmojis(searchTerm); | ||
|
|
||
| if (normalizedSearchTerm === '') { | ||
| updateEmojiList(allEmojis, headerRowIndices); | ||
| } else { | ||
| updateEmojiList(newFilteredEmojiList ?? [], []); | ||
| } | ||
| }, 300); | ||
| }; | ||
|
|
||
| // Stable debounced function that delegates to the latest callback via ref, | ||
| // preventing re-renders from recreating the debounce timer. | ||
| // eslint-disable-next-line react-hooks/exhaustive-deps | ||
| const filterEmojis = useMemo(() => lodashDebounce((text: string) => filterCallbackRef.current?.(text), 300), []); | ||
|
|
||
| const scrollToHeader = useCallback( | ||
| (headerIndex: number) => { | ||
|
|
@@ -124,7 +128,10 @@ function EmojiPickerMenu({onEmojiSelected, activeEmoji, ref}: EmojiPickerMenuPro | |
| label={translate('common.search')} | ||
| accessibilityLabel={translate('common.search')} | ||
| role={CONST.ROLE.PRESENTATION} | ||
| onChangeText={filterEmojis} | ||
| onChangeText={(text: string) => { | ||
| setSearchText(text); | ||
| filterEmojis(text); | ||
|
Comment on lines
+131
to
+133
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Updating Useful? React with 👍 / 👎.
Krishna2323 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }} | ||
| submitBehavior={filteredEmojis.length > 0 ? 'blurAndSubmit' : 'submit'} | ||
| sentryLabel={CONST.SENTRY_LABEL.EMOJI_PICKER.SEARCH_INPUT} | ||
| /> | ||
|
|
@@ -145,6 +152,7 @@ function EmojiPickerMenu({onEmojiSelected, activeEmoji, ref}: EmojiPickerMenuPro | |
| extraData={[filteredEmojis, preferredSkinTone]} | ||
| stickyHeaderIndices={headerIndices} | ||
| alwaysBounceVertical={filteredEmojis.length !== 0} | ||
| searchValue={searchText} | ||
| /> | ||
| </View> | ||
| ); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,7 +6,7 @@ import type {TextInputOptions} from '@components/SelectionList/types'; | |
| import Text from '@components/Text'; | ||
| import BaseTextInput from '@components/TextInput'; | ||
| import type {BaseTextInputRef} from '@components/TextInput/BaseTextInput/types'; | ||
| import useAccessibilityAnnouncement from '@hooks/useAccessibilityAnnouncement'; | ||
| import useDebouncedAccessibilityAnnouncement from '@hooks/useDebouncedAccessibilityAnnouncement'; | ||
| import useLocalize from '@hooks/useLocalize'; | ||
| import useThemeStyles from '@hooks/useThemeStyles'; | ||
| import mergeRefs from '@libs/mergeRefs'; | ||
|
|
@@ -71,9 +71,8 @@ function TextInput({ | |
| const isNoResultsFoundMessage = headerMessage === noResultsFoundText; | ||
| const noData = dataLength === 0 && !shouldShowLoadingPlaceholder; | ||
| const shouldShowHeaderMessage = !!shouldShowTextInput && !!headerMessage && (!isLoadingNewOptions || !isNoResultsFoundMessage || noData); | ||
| const shouldAnnounceNoResults = shouldShowHeaderMessage && isNoResultsFoundMessage; | ||
|
|
||
| useAccessibilityAnnouncement(headerMessage, shouldAnnounceNoResults, {shouldAnnounceOnNative: true}); | ||
| useDebouncedAccessibilityAnnouncement(headerMessage ?? '', shouldShowHeaderMessage, value ?? ''); | ||
|
|
||
| const focusTimeoutRef = useRef<NodeJS.Timeout | null>(null); | ||
| const mergedRef = mergeRefs<BaseTextInputRef>(ref, optionsRef); | ||
|
|
@@ -145,7 +144,12 @@ function TextInput({ | |
| </View> | ||
| {shouldShowHeaderMessage && ( | ||
| <View style={[styles.ph5, styles.pb5, style?.headerMessageStyle]}> | ||
| <Text style={[styles.textLabel, styles.colorMuted, styles.minHeight5]}>{headerMessage}</Text> | ||
| <Text | ||
| style={[styles.textLabel, styles.colorMuted, styles.minHeight5]} | ||
| aria-hidden | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| > | ||
| {headerMessage} | ||
| </Text> | ||
| </View> | ||
| )} | ||
| </> | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.