Drop down with ARIA 1.2 groups

A drop down modified to use ARIA 1.2 groups. In the main implementation groups are simulated using text label, and are not associated with the option. These are true groups and can be associated with an option by a compatible screen-reader.

The group role is only been allowed as a child of a list box in ARIA 1.2, which is still a working draft.

Therefore this is not compatible with the majority of screen readers and is only here as an example.

import { useRef, useState } from 'react';
import { DropDown } 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-dropdown__group-label"
        id={key}
      >
        {label}
      </div>
      <ul
        role="presentation"
        className="react-combo-boxes-dropdown__group"
      >
        {groupChildren}
      </ul>
    </li>
  );
}

export function Example() {
  const [value, setValue] = useState(null);
  const [managedFocus, setManagedFocus] = useState(true);
  const ref = useRef();
  return (
    <>
      <div
        className="label"
        onClick={() => ref.current.focus()}
        id="drop-down-label"
      >
        Drop down
      </div>
      <DropDown
        id="drop-down"
        ref={ref}
        aria-labelledby="drop-down-label"
        value={value}
        onValue={setValue}
        options={options}
        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="drop-down"
        id="output"
      >
        {JSON.stringify(value, undefined, ' ')}
      </output>
    </>
  );
}