Everything a pointer does, the keyboard does too: lift, move, change the level, change the column, drop, put back, select several, open and close, rename and pick. A screen reader hears each step.
Roles
- A list is a
listbox, its itemsoptions. Withmultiple, the list hasaria-multiselectableand each itemaria-selected; withon_select, too. - A tree is a
tree, its itemstreeitems witharia-level,aria-posinsetandaria-setsizeamong their siblings, andaria-expandedon the items with children. An item whose children are loading isaria-busy. - A board is a
group. Each column is a section named by its header, and its cards are alistboxofoptions. - A tree picker is a tree whose items have
aria-selected; the items that cannot be picked arearia-disabled. labelnames the whole list, tree or board. Each item's name for the announcements is its label (item_label).
One item takes the Tab at a time (a roving tabindex): the focused one,
else the first selected, else the first shown.
Keys
| Key | |
|---|---|
| ↓ ↑ | the next, the previous item |
| Home, End | the first, the last item |
| → | a tree: open the item, or go to its first child; a board: the next column |
| ← | a tree: close the item, or go to its parent; a board: the previous column |
| Space | lift the item (and the others selected); in a picker, pick it |
| Enter | in a picker, pick the item |
| Shift+↓ ↑ | extend the selection (multiple) |
| Ctrl+A, Cmd+A | select all the items shown (multiple) |
| Escape | clear the selection |
| Ctrl+Shift+arrows, Cmd+Shift+arrows | move the item one step, without lifting it |
| F2 | rename (on_rename) |
While an item is lifted:
| Key | |
|---|---|
| ↓ ↑ | the next, the previous gap |
| Home, End | the first, the last gap |
| → ← | a tree: one level deeper, one level up; a board: the next, the previous column |
| Space, Enter | drop |
| Escape | put it back |
| Tab | put it back, and move on |
Focus that leaves the list puts a lifted item back. A list without
on_move, or readonly, does not lift: Space toggles the selection
with multiple.
Announcements
A live region says what happens, in the words of the list's locale:
- "Roadmap lifted. Arrows move it, Space drops it, Escape puts it back."
- "Roadmap, in Projects, 2 of 3" as it moves, and "Roadmap dropped, 2 of 3".
- "Roadmap is back in its place" when it is put back.
- Why a place is refused: "It can't go there: It would be nested too deep".
- "The move was not saved, and is undone" when the server says no, with its reason.
- How many items the filter shows, or "No matches"; how many are selected; a row opened or closed.
The words are in English, Portuguese, Spanish, French, German, Italian,
Dutch and Japanese; numbers are formatted by the browser for the locale.
A locale with a region (pt-BR) takes its language's words; another
language gets English. messages changes words by the keys of
Narabe.Messages.keys/0, and the config sets them for every list:
config :narabe, messages: %{"fr" => %{"dragHandle" => "Glisser pour déplacer"}}The pointer and touch
A mouse lifts an item once it moves a few pixels, so a click stays a click. A finger lifts it after a short hold, so a swipe still scrolls the page; the phone vibrates briefly where it can. On a touch screen rows are 2.75rem tall. Escape during a drag lets go and nothing moves.
Motion and color
With prefers-reduced-motion, rows and arrows do not animate. A refused
drop is shown by its red line and said in words: color is never the only
sign.
Tested
mix test.e2e checks the roles, levels, focus and announcements in
Chromium, Firefox and WebKit. Not tested yet: screen readers themselves
(see Known limits).