Each item (to be drag-and-dropped) has a button with
aria-haspopup="menu"
and
aria-expanded="true|false"
(following
Menu Button).
If the button has no visible text, it
must have either:
text inside the button that's visually hidden;
an aria-label (describing
the actions contained in the menu. E.g. "Move card". Don't use
"Expand" or similar, as that's covered by
aria-expanded). The image can have
aria-hidden="true".
If necessary, the button can be visually hidden, but must be shown on
focus (so that it's available to keyboard users).
When the menu is closed, focus returns to the button.
When the menu is opened, focus is set the first item in the menu.
Ideally, add
aria-controls="id-of-the-menu"
to the button.
The menu
The popped-up menu has role="menu" with either:
aria-labelledby="the-id-of-the-visible-label" (e.g.
the button text);
aria-label="A description of the actions in the menu"
(.e.g Move card).
Each drop target has role="menuitem" and is focusable using a
roving tabindex. Disabled targets have
aria-disabled="true".
To divide up menu items (e.g. when we have multiple drop zones in
multiple parts of the page), use an element with
role="separator". If necessary, add
tabindex="-1" so that it's not focusable.
Down Arrow / Up Arrow moves focus to the next /
previous item.
Either:
Down Arrow / Up Arrow movement wraps from last
to first / first to last;
Home / End move focus to the first / last
item.
Tab (or Shift + Tab) moves out of the menu, and
closes the menu.
Esc closes the menu and returns focus to the menu button.
Submenus are menus of their own and follow the same button and menu
pattern.