diff --git a/.storybook/snapshots/__snapshots__/filtersearch--dropdown-sectioned.png b/.storybook/snapshots/__snapshots__/filtersearch--dropdown-sectioned.png index e0262696..06a954e9 100644 Binary files a/.storybook/snapshots/__snapshots__/filtersearch--dropdown-sectioned.png and b/.storybook/snapshots/__snapshots__/filtersearch--dropdown-sectioned.png differ diff --git a/.storybook/snapshots/__snapshots__/filtersearch--dropdown-unsectioned.png b/.storybook/snapshots/__snapshots__/filtersearch--dropdown-unsectioned.png index 2323eebf..94fa12f6 100644 Binary files a/.storybook/snapshots/__snapshots__/filtersearch--dropdown-unsectioned.png and b/.storybook/snapshots/__snapshots__/filtersearch--dropdown-unsectioned.png differ diff --git a/.storybook/snapshots/__snapshots__/filtersearch--primary.png b/.storybook/snapshots/__snapshots__/filtersearch--primary.png index b1694d86..cb080404 100644 Binary files a/.storybook/snapshots/__snapshots__/filtersearch--primary.png and b/.storybook/snapshots/__snapshots__/filtersearch--primary.png differ diff --git a/package-lock.json b/package-lock.json index c3212de5..f38c1bc4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@yext/search-ui-react", - "version": "2.1.0", + "version": "2.1.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@yext/search-ui-react", - "version": "2.1.0", + "version": "2.1.1", "license": "BSD-3-Clause", "dependencies": { "@restart/ui": "^1.0.1", diff --git a/package.json b/package.json index 0b8d5c88..9418feb5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@yext/search-ui-react", - "version": "2.1.0", + "version": "2.1.1", "description": "A library of React Components for powering Yext Search integrations", "author": "watson@yext.com", "license": "BSD-3-Clause", diff --git a/src/components/Dropdown/DropdownInput.tsx b/src/components/Dropdown/DropdownInput.tsx index f7970bef..a34e02f2 100644 --- a/src/components/Dropdown/DropdownInput.tsx +++ b/src/components/Dropdown/DropdownInput.tsx @@ -10,7 +10,10 @@ import { useInputContext } from './InputContext'; export function DropdownInput(props: { className?: string, placeholder?: string, + inputId?: string, ariaLabel?: string, + ariaLabelledBy?: string, + ariaDescribedBy?: string, onSubmit?: (value: string, index: number, focusedItemData: FocusedItemData | undefined ) => void, onFocus?: (value: string) => void, onChange?: (value: string) => void, @@ -19,7 +22,10 @@ export function DropdownInput(props: { const { className, placeholder, + inputId, ariaLabel, + ariaLabelledBy, + ariaDescribedBy, onSubmit, onFocus, onChange, @@ -36,6 +42,8 @@ export function DropdownInput(props: { updateFocusedItem } = useFocusContext(); const [isTyping, setIsTyping] = useState(true); + const describedBy = [screenReaderUUID, ariaDescribedBy].filter(Boolean).join(' ') || undefined; + const resolvedAriaLabel = ariaLabelledBy ? undefined : ariaLabel; const handleChange = useCallback((e: ChangeEvent) => { setIsTyping(true); @@ -86,13 +94,14 @@ export function DropdownInput(props: { onChange={handleChange} onKeyDown={handleKeyDown} onFocus={handleFocus} - id={generateDropdownId(screenReaderUUID, -1)} + id={inputId ?? generateDropdownId(screenReaderUUID, -1)} autoComplete='off' - aria-describedby={screenReaderUUID} + aria-describedby={describedBy} aria-activedescendant={ !isTyping ? generateDropdownId(screenReaderUUID, focusedIndex) : undefined } - aria-label={ariaLabel} + aria-label={resolvedAriaLabel} + aria-labelledby={ariaLabelledBy} aria-autocomplete="list" role="combobox" aria-controls={dropdownListUUID} diff --git a/src/components/FilterSearch.tsx b/src/components/FilterSearch.tsx index 2318f613..5766f2c1 100644 --- a/src/components/FilterSearch.tsx +++ b/src/components/FilterSearch.tsx @@ -6,6 +6,7 @@ import { useSynchronizedRequest } from '../hooks/useSynchronizedRequest'; import { useDebouncedFunction } from '../hooks/useDebouncedFunction'; import { executeSearch } from '../utils'; import { isDuplicateStaticFilter } from '../utils/filterutils'; +import { useId } from '../hooks/useId'; import { Dropdown } from './Dropdown/Dropdown'; import { DropdownInput } from './Dropdown/DropdownInput'; import { DropdownItem } from './Dropdown/DropdownItem'; @@ -156,6 +157,8 @@ export function FilterSearch({ }: FilterSearchProps): React.JSX.Element { const { t } = useTranslation(); const searchActions = useSearchActions(); + const inputId = useId('filter-search-input'); + const labelId = useId('filter-search-label'); const searchParamFields = searchFields.map((searchField) => { return { ...searchField, fetchEntities: false }; }); @@ -356,7 +359,9 @@ export function FilterSearch({ onChange={handleInputChange} onFocus={handleInputFocus} submitCriteria={meetsSubmitCritera} + inputId={inputId} ariaLabel={ariaLabel} + ariaLabelledBy={label ? labelId : undefined} /> ); @@ -372,7 +377,11 @@ export function FilterSearch({ return (
- {label &&

{label}

} + {label && ( + + )}
{instructions}