Combo box with ARIA 1.2 groups
A combo box modified to use ARIA 1.2 groups.
The group role is not allowed as a child of a listbox in ARIA 1.0 or ARIA 1.1 and consequently is not supported in the majority of screen readers.
In ARIA 1.2 the group role is now allowed.
In the main implementation groups are simulated with a visual text label, and hidden text for screen-readers. This examples modifies the combo-box to use true groups.
import { useState } from 'react';
import { ComboBox, useTokenSearch } from '@citizensadvice/react-combo-boxes';
const options = [
{ label: 'Apple' },
{ label: 'Orange', group: 'Citrus' },
{ label: 'Lemon', group: 'Citrus' },
{ label: 'Raspberry', group: 'Berry' },
{ label: 'Strawberry', group: 'Berry' },
];
function renderGroup(props, { groupChildren, group: { key, label } }) {
return (
<li
key={key}
role="group"
aria-labelledby={key}
>
<div
className="react-combo-boxes-combobox__group-label"
id={key}
>
{label}
</div>
<ul
role="presentation"
className="react-combo-boxes-combobox__group"
>
{groupChildren}
</ul>
</li>
);
}
export function Example() {
const [value, setValue] = useState(null);
const [search, setSearch] = useState(null);
const [managedFocus, setManagedFocus] = useState(true);
const filteredOptions = useTokenSearch(search, { options });
return (
<>
<label
id="select-label"
htmlFor="select"
>
Select
</label>
<ComboBox
id="select"
aria-labelledby="select-label"
value={value}
onValue={setValue}
onSearch={setSearch}
options={filteredOptions}
managedFocus={managedFocus}
renderGroup={renderGroup}
renderGroupAccessibleLabel={() => null}
/>
<label>
<input
type="checkbox"
onChange={({ target: { checked } }) => setManagedFocus(checked)}
checked={managedFocus}
/>{' '}
Toggle managed focus
</label>
<label htmlFor="output">Current value</label>
<output
htmlFor="select"
id="output"
>
{JSON.stringify(value, undefined, ' ')}
</output>
</>
);
}