C-46 · Components · Inputs
All elements · IconPicker on the Components page
Last checked 2026-10-22 · Awaiting approval · Accessibility tests
Approve IconPicker
Approving as
IconPicker
C-46WCAG 2.2 AA · PassedChoose a sprite icon and its color, as for a saved search's sidebar row (Change icon… on its row menu, in a dialog titled "Icon for <name>"): a search field, the color keys as a ColorPicker row, a label naming the chosen icon, then the sprite's icons as a scrolling, keyboard-navigable grid. The chosen icon is drawn in the chosen color.
| Axis / element | Values |
|---|---|
__colors |
a .qf-color-picker of the ten color keys, flush with the field above |
__grid · __row · __cell |
role=grid · row · gridcell; command-height cells, ten to a row, seven rows tall then it scrolls |
__label · __empty |
"Icon: Users", labels the grid · "No icons match …" |
aria-selected · --_tint |
the chosen icon · the chosen color, set on .qf-icon-picker; the chosen icon is
drawn in it
|
Guidance
When to use
- Use it to let a user choose the icon a thing they own is drawn with, such as a saved search's sidebar row (Change icon… on the row menu).
- Use it in a dialog titled for the thing ("Icon for Team queue") with Cancel and Save; Save stores the icon and the color together.
- Offer the sprite's own icons only, so every choice draws; the app reads the list from the sprite.
When to consider something else
- When the choice is a color alone, use a ColorPicker. See ColorPicker.
- When there are only a handful of fixed choices, use a Select or a segmented ButtonGroup with icons. See Select.
- When an icon is fixed by what the thing is (an entry such as Inbox or Tasks), draw it; don't ask. See Icon.
Usability
-
Lead with the search field and give it initial focus; filter the grid as the user types and say so
when nothing matches (
__empty). - Name the chosen icon in
__label("Icon: Users") and make it the grid's label. -
Set
--_tinton.qf-icon-pickerto the chosen color, so the chosen icon previews in it. - Draw the saved choice in the sidebar row exactly as the picker previewed it: the icon in its color, the label in the row's ink.
- Don't use the colors to carry meaning; they are the owner's own marks and the label stays the row's name (1.4.1).
- Don't let Save send more than the icon and color.
- Don't render the whole sprite unfiltered in a short dialog without the scrolling grid; the grid stops at seven rows.
Accessibility
Keyboard
| Keys | Action |
|---|---|
| Tab / Shift+Tab | Moves between the search field, the color grid, the icon grid and the dialog's buttons. |
| Arrow Left / Arrow Right | Moves between cells in a row. |
| Arrow Up / Arrow Down | Moves to the cell above or below (a row of ten icons, or the color row). |
| Home / End | Moves to the first or last cell of the grid. |
| Enter or Space | Chooses the focused icon or color and marks it selected. |
| Escape | Closes the dialog without saving and returns focus to the row menu's trigger. |
Roles and names
-
The icon
__gridisrole="grid"labeled by__labelthrougharia-labelledby;__rowisrole="row"and each__cella button withrole="gridcell", anaria-labeland atitlenaming the icon ("Circle check") andaria-selected. -
The colors are a
.qf-color-picker__grid(role=grid) labeled "Color", one gridcell per key with its name asaria-label. - Each icon inside a cell is
aria-hidden; the cell's name is the icon's name.
Focus
-
Each grid is one tab stop (roving
tabindex): the chosen cell when it is shown, else the first. - A cell shows the focus ring, which differs from the selected outline and fill.
Other requirements
- Cells are command height (32px), above the 24px of 2.5.8.
- In forced colors the selected cell's outline is Highlight.
Test your implementation too. This guidance covers the element as specified here. How a screen composes it (labels, order, announcements) still needs its own keyboard and screen reader check.
Accessibility tests
Passed the gate (run 358b316 on 2026-10-22): no finding in any theme. Awaiting a person’s approval of the checklist below.
| Area | Automated | A person checks |
|---|---|---|
| General | Passed | Color is never the only cue, text alternatives say the same thing as the graphic, and the element reads the same in the light and the dark theme. |
| Zoom | Passed | At 200% zoom, at 320 CSS pixels wide and with the WCAG text-spacing overrides, nothing is lost, clipped or overlapping. |
| Keyboard | Passed | Every row of the Keyboard table works, focus is always visible and never trapped, and the tab order follows the reading order. (6 rows) |
| Screen reader | Passed | With NVDA or JAWS on Windows and VoiceOver on macOS, names, roles and states are announced as Roles and names says, and changes are announced once. (3 items) |
Approving. When the checklist passes on the checked run, record it with
bun run a11y:approve -- icon-picker --by "Your name" and commit
a11y/approvals.json with the rebuilt pages.
All test status
Package
Consumers link one stylesheet, css/classic/index.css, which includes every element. The
files below are where this element is defined.
Latest updates
| Date | Version | Breaking | Description |
|---|---|---|---|
| 2026-10-20 | 0.1 | No |
IconPicker (.qf-icon-picker), new: choose a sprite icon and its color, as for a saved search's
sidebar row. A search field, __colors (a .qf-color-picker of the ten color keys),
__label naming the chosen icon, and __grid · __row ·
__cell (role=grid · row · gridcell; command-height cells, ten to a row, seven rows
then it scrolls), __empty for no match; aria-selected marks the choice
and --_tint on the block draws it in the chosen color (components/icon-picker.css),
classic skin
|