Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Focusgroup use cases and APG patterns #1018

Open
travisleithead opened this issue Mar 15, 2024 · 1 comment
Open

Focusgroup use cases and APG patterns #1018

travisleithead opened this issue Mar 15, 2024 · 1 comment

Comments

@travisleithead
Copy link
Collaborator

travisleithead commented Mar 15, 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:

  • Alert
  • Alert and Message Dialogs
  • Breadcrumb (though it might be a nice supplement for reducing tab stops?)
  • Button
  • Carousel (for basic carousel & grouped carousel sub-patterns)
  • Checkbox
  • 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:

Pattern focusgroup usage Notes
Accordion focusgroup=block on the root, focusgroup=none on the regions to opt-them out. ⬆️/⬇️, Home/End are optional
Carousel (tabbed sub-pattern) focusgroup=inline on the tablist
Disclosure (navigation menu sub-pattern) 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.
Grid / Layout Grid / Linear List Nav focusgroup on the root <div>
Grid / Layout Grid / Pill List focusgroup="manual-grid row-flow" on the root <div>. focusgroup=grid-row on the role=row elements, and focusgroup=grid-cell on role=gridcell spans. Arrow keys act like a 2d table, even though the layout is not a visual table.
Grid / Layout Grid / Scrollable Search Results 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 / Minimal Data Grid focusgroup=grid on the <table> root element.
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?
Listbox n/a 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.
Menu & Menubar / Menubar Editor 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)
Menu & Menubar / Navibation Menubar Same focusgroup attributes as Menubar Editor above (cross-axis nested focusgroups)
Radio group focusgroup on role=radiogroup Same focusgroup attribute for both the Radio Group w/roving tabindex example AND the Rating Radio Group.
Tabs / Automatic Tab Activation 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).
Tabs / Manual Tab Activation 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).
Toolbar 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.
Tree View focusgroup=block on the role=tree root element. Lots of custom cross-axis handlers still needed to open/close and set focus on sub treeitems.
Treegrid / Only cells focusable Same as Grid / Data Grid attributes above.
Treegrid / Focusable rows 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.
@travisleithead
Copy link
Collaborator Author

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 travisleithead changed the title Focusgroup and APG patterns Focusgroup use cases and APG patterns Mar 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant