You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This issue documents my exploration into the various APG patterns and how focusgroup might (or might not) be used in them. I anticipate using this information to provide new examples for the explainer that are based on a more diverse set of use-case patterns from which the APG patterns are derived.
First, there are a number of patterns that focusgroup does not seem to apply to. These are:
Alert
Alert and Message Dialogs
Breadcrumb (though it might be a nice supplement for reducing tab stops?)
Combobox (but see also the listbox popup, grid popup, and tree popup patterns when used with combobox)
Dialog
Disclosure (for simple show/hide cases like image description disclosures and FAQ disclosures)
Feed (this has very interesting and somewhat unique keyboard patterns that might be a good future addition for focusgroup... e.g., page down/page up, control+Home, Control+End)
Landmarks
Link
Menu button
Meter
Slider
Slider (multi-thumb)
Spinbutton
Switch
Table (because these are supposed to be static... see grid)
Tooltip
Window splitter
The following patterns are good focusgroup use cases for (some of) the keyboard accessibility recommendations in those patterns:
focusgroup on the root <nav>. focusgroup on each popover <ul>.
The top-level <nav> menu supports both ➡️ & ⬇️ for forward nav and the opposite for reverse direction--but when the button with an open menu is focused, then the 'down' arrow key captures and enters the menu.
Same focusgroup attributes as Pill List above (manual-grid)
Use case requires arrow key event handlers in the axis of block movement on the visible extremes in order to adjust the 'hidden' elements (and the number of visible items indicator UI). TBD if focusgroup can handle movement to recently-visible elements in this case in the key event handler! (Order is important: key down handler then focusgroup default processing or vice-versa...)
Grid / Data Grid / Sortable Data Grid w/Editable Cells
focusgroup=grid on the outer <table> with focusgroup=wrap in the <td>'s popover menu.
Note, grid focusgroups and their interactions with other kinds of focusgroups need careful description--e.g., this use case should be allowed--but should other focusgroups inside the grid structure?
The example uses aria-activedescendant and doesn't make any content other than the root container DOM-focusable. These aria-activedescendant use cases aren't generally compatible with focusgroup becuase of the lack of a DOM-focusable set of elements.
Cross-axis nested focusgroups: the outer role=menubar element gets focusgroup="inline wrap" and the menus (role=menu i.e., popovers) get focusgroup="block wrap".
The no-memory option is not needed in the sub-menus of this example because show/hide will reset the memory anyway, AND focus needs to be explicitly set on the submenus by the parent up/down event handlers, so this would bypass the memory feature anyway. "Typeahead" is a recommended feature for this scenario that could be handled by focusgroup. ⚠️ALSO NOTE 🪲 BUG: in the submenu wrapping for Size (down-key-on-last item doesn't wrap) and for Style/Color (down-key-on-last item doesn't wrap)
focusgroup="inline wrap no-memory" on the role=tablist div.
role=tabpanel s must be tabindex "chorded" to their tab for proper tab-sequencing when multiple panels are visible. In this case: because all non-active tab's tabpanels are hidden, they can all simply use tabindex=0, and the only visible tab will always be in the correct tab sequence! Note: no-memory is necessary to ensure focus always goes to the selected tab (the one that is designated via sequential focus navigation).
Same focusgroup attributes as Automatic Tab Activation above.
The 'selected' tab is always sequentially focusable, so 'Tab key' from a tab before the selected tab (when focus is before it) will bring focus to the selected tab. If focus is after the selected tab, 'Tab key' takes focus to the visible content panel (as expected).
Cross-axis nested focusgroups: the outer role=toolbar element gets focusgroup="inline wrap" and the ⬆️/⬇️-activatable menus (role=menu i.e., popovers) get focusgroup="block wrap". (See also Menu & Menubar pattern.)
The "alignment" buttons have special ⬆️/⬇️ wrapping within their group. This would not be accomplished via a built-in focusgroup behavior, but would need special handling with event handlers (you can't put two separate focusgroups on a set of elements to extend a single-axis focusgroup into a dual-axis focusgroup). Attempting to do so given the spec's behavior now would opt-out the dual-axis focusgroup from the parent's focusgroup.
Two approaches: either focusgroup=grid and treat the treegrid primarily as a grid, or focusgroup=block and treat the treegrid primarily like a tree. Both cases need special handling.
**See below.
**Note: this use case (treegrid) does not easily fit a focusgroup because the tree-grid combines navigational elements of a tree (linear focusgroup) with that of a grid (2d navigation of grid cells). Two approaches could be used--each requires some special case handling.
Approach 1: (act primarily as a grid--special case the linear parts)
Use focusgroup=grid. Special case handling for row-selection ⬆️/⬇️ behavior (move by row)
OPEN QUESTION: should focusable row elements have default handling, or be ignored by the grid focusgroup?
Probably ignored so that expand/collapse can be implemented without focusgroup getting in the way...
Approach 2: (act primarily as a tree view--special case the grid parts)
A block-direction focusgroup is applied to all the rows for linear row navigation, and cells within the row require special case handling: ⬆️/⬇️ to move to adjacent-row's cells, ⬅️/➡️ to move among the cells.
NOTE: this could be a use case for excluding the declaring focusgroup from being included in its focusgroup, since <tr> is focusable, but should be included in the parent's focusgroup=block, while declaring that it's children should be in a focusgroup=inline --⬆️/⬇️ adjacent cell movement would still need to be special-cased.
The text was updated successfully, but these errors were encountered:
In thinking about the treegrid cases noted above, and when editing text recently about how "direction" limits are only for linear focusgroups, I got wondering... what if there was a "direction" feature that would apply to grids too? And then I thought that author's might really appreciate having a focusgroup="grid include-rows" feature that would allow grid navigation to include any focusable row elements (not really a thing right now--grid focusgroups only opt-in cells at the moment). An include-rows feature would make the treegrid pattern's Approach 1 above work perfectly, while avoiding needing to have the more general "exclusion" opt-out mentioned in Approach 2. I also like it, because there's clearly a use-case for row-selection that justifies the feature addition.
travisleithead
changed the title
Focusgroup and APG patterns
Focusgroup use cases and APG patterns
Mar 26, 2024
This issue documents my exploration into the various APG patterns and how
focusgroup
might (or might not) be used in them. I anticipate using this information to provide new examples for the explainer that are based on a more diverse set of use-case patterns from which the APG patterns are derived.First, there are a number of patterns that focusgroup does not seem to apply to. These are:
The following patterns are good
focusgroup
use cases for (some of) the keyboard accessibility recommendations in those patterns:focusgroup
usagefocusgroup=block
on the root,focusgroup=none
on the regions to opt-them out.focusgroup=inline
on the tablistfocusgroup
on the root<nav>
.focusgroup
on each popover<ul>
.<nav>
menu supports both ➡️ & ⬇️ for forward nav and the opposite for reverse direction--but when the button with an open menu is focused, then the 'down' arrow key captures and enters the menu.focusgroup
on the root<div>
focusgroup="manual-grid row-flow"
on the root<div>
.focusgroup=grid-row
on therole=row
elements, andfocusgroup=grid-cell
onrole=gridcell
spans.focusgroup=grid
on the<table>
root element.focusgroup=grid
on the outer<table>
withfocusgroup=wrap
in the<td>
's popover menu.aria-activedescendant
and doesn't make any content other than the root container DOM-focusable. Thesearia-activedescendant
use cases aren't generally compatible with focusgroup becuase of the lack of a DOM-focusable set of elements.role=menubar
element getsfocusgroup="inline wrap"
and the menus (role=menu
i.e.,popovers
) getfocusgroup="block wrap"
.no-memory
option is not needed in the sub-menus of this example because show/hide will reset the memory anyway, AND focus needs to be explicitly set on the submenus by the parent up/down event handlers, so this would bypass the memory feature anyway. "Typeahead" is a recommended feature for this scenario that could be handled by focusgroup.Size
(down-key-on-last item doesn't wrap) and forStyle/Color
(down-key-on-last item doesn't wrap)focusgroup
onrole=radiogroup
focusgroup
attribute for both the Radio Group w/roving tabindex example AND the Rating Radio Group.focusgroup="inline wrap no-memory"
on therole=tablist
div.role=tabpanel
s must be tabindex "chorded" to their tab for proper tab-sequencing when multiple panels are visible. In this case: because all non-active tab's tabpanels are hidden, they can all simply use tabindex=0, and the only visible tab will always be in the correct tab sequence! Note:no-memory
is necessary to ensure focus always goes to the selected tab (the one that is designated via sequential focus navigation).role=toolbar
element getsfocusgroup="inline wrap"
and the ⬆️/⬇️-activatable menus (role=menu
i.e.,popovers
) getfocusgroup="block wrap"
. (See also Menu & Menubar pattern.)focusgroup=block
on therole=tree
root element.treeitem
s.focusgroup=grid
and treat the treegrid primarily as a grid, orfocusgroup=block
and treat the treegrid primarily like a tree. Both cases need special handling.**Note: this use case (treegrid) does not easily fit a
focusgroup
because the tree-grid combines navigational elements of a tree (linear focusgroup) with that of a grid (2d navigation of grid cells). Two approaches could be used--each requires some special case handling.focusgroup=grid
. Special case handling for row-selection ⬆️/⬇️ behavior (move by row)focusgroup
from being included in its focusgroup, since<tr>
is focusable, but should be included in the parent'sfocusgroup=block
, while declaring that it's children should be in afocusgroup=inline
--⬆️/⬇️ adjacent cell movement would still need to be special-cased.The text was updated successfully, but these errors were encountered: