Accessibility
SortControl and Filter compose @prepared911/ui-core Menu, IconButton, and ButtonGroup. Those primitives own focus trap, arrow navigation, Escape dismissal, and focus return. This page covers what you must wire when using the Filters package APIs.
MenuItemRadio inside MenuGroup with menuitemradio and aria-checked. Unselected rows are named by the criterion label. The selected row's accessible name is {criterion}, {direction} so assistive tech hears ascending vs descending without a nested control. Re-activating the checked row clears sort (criterionId: "") via useSortState.toggleCriterion.MenuItemCheckbox rows (menuitemcheckbox + aria-checked) with bare trailing checkmarks and optional decorative leading icons (aria-hidden). Single-select is enforced by SortControl / useSortState.toggleGroup — re-activating the checked row clears grouping (null). There is no explicit None option.Icon on the selected non-fixedDirection criterion only. The slot is aria-hidden and must not introduce a nested button. Primary-button isolation keeps pointer toggles off the menuitemradio selection path until the gesture is confirmed (pointerup on the trailing region, or click without pointerdown for AT). pointercancel and drag-off do not change direction. Keyboard: ArrowLeft/ArrowRight on the selected radio toggles direction; that shortcut is also in description. Enter/Space still select or clear the criterion.IconButton with morphing ascending/descending icons, top tooltip of "Ascending" / "Descending", a stable localized aria-label (Sort {criterion}), and aria-pressed (true = ascending, false = descending).grouping is set: default localized aria-label ("Sort and group"); override via the aria-label prop.SortCriterion.label / GroupCriterion.label strings (localized at the call site when they are product copy).criteria / grouping configs so selection state and announcements stay consistent across re-renders.label / groupLabel / aria-label, keep them short and unique in the toolbar.criterionId: ""), matching pointer activation on the row. On a checked group row, Enter/Space clears grouping.menuitemradio / menuitemcheckbox options while a menu is open. On the selected sort criterion, ArrowLeft/ArrowRight toggle direction without changing the criterion.| Control | Role / state |
|---|---|
| Sort / group triggers | button named via IconButton title |
| Sort criterion options | menuitemradio + aria-checked; selected name includes direction |
| Group options | menuitemcheckbox + aria-checked (single-select via state) |
| Direction trailing (selected row) | decorative aria-hidden paint; pointer isolation + ArrowLeft/ArrowRight |
| Simple direction toggle | button + aria-pressed (true ascending, false descending); stable name |
| Paired sort + group | group with accessible name |
fixedDirection. It is aria-hidden; the selected radio's name includes the current direction, and description exposes ArrowLeft/ArrowRight. Direction is changed by pointer on that region or those arrow keys.groupValue === null with all group checkboxes unchecked.criterionId: "" with all criterion radios unchecked.