-
Notifications
You must be signed in to change notification settings - Fork 219
Description
In the explainer today, focusgroup elements cause all of their direct-children to become focusgroup candidates, but that's it. If there are some other potential focusgroup candidates that are not direct-children, but the author would like them to be included in the original focusgroup, the extend feature provides a way to extend the parent's focusgroup to some descendant set of children.
I've started to take a look at the various patterns in the ARIA Authoring Practices Guide and the examples for Accordion and Tree View in an attempt to see how focusgroup would work in practice in those examples. In 2 of the 3 examples for Tree View, authors would end-up needing lots of redundant focusgroup definitions, just to ensure children are properly hooked up to ancestor focusgroup definitions. Similar story for the Accordion example (though it doesn't make use of optional keyup/down behaviors that are described in the Keyboard Interaction section). In just these few examples, it seems apparent that use of focusgroups as currently described will be annoying to authors in a lot of cases.
Given that, and the support expressed for dropping the children-only requirement expressed on the Discord focusgroup channel, I'd like to propose that this requirement be removed. In other words, use of a focusgroup attribute would setup a scope for all children and descendants of the focusgroup-declaring element to be focusgroup candidates.
If we decide to make this change, there are a couple of other changes that fall-out as a result:
- It becomes more important to have an opt-out mechanism since many more elements will be automatically added as focusgroup candidates. (The current proposal describes an opt-out mechanism for individual elements, but it requires CSS only and is considered an edge case.)
- The various use cases for
extendare reduced to just one case: flipping the orthogonality of a linear focusgroup (and potentially changing the wrapping behavior).
I like the simplification, and I really like how it reduces the complexity of focusgroup, and seems to increase the developer ease-of-use.
⭐ Note: in the below proposals, the element declaring the focusgroup is not a member of the focusgroup (this is the current explainer POV). With this change, we could re-evaluate whether the element declaring the focusgroup will become a part of the focusgroup itself. This could make more sense given the opt-out proposals.
Part 1: linear focusgroup declarations apply to an element's subtree (not just children only)
No change to existing syntax, this just expands the scope of a focusgroup declaration:
<form focusgroup>
<!-- all children and descendants (this whole subtree) is now part of the focusgroup -->
</form>Part 2: focusgroup subtree opt-out
With such a generous default opt-in behavior, we should provide a way to opt-out a subtree just as easily. focusgroup=none.
<div focusgroup>
<div>
<div>
<div focusgroup="none"> <!-- this subtree (this div's children and descendants) are excluded from the focusgroup -->
</div>
</div>
</div>
</div>Part 3: focusgroup individual element opt-out
Individual elements may want to opt-out of focusgroup participation (allowing their children and sub-tree to continue to be opted-in). This is described in the explainer today, but requires CSS (focus-group-item: none).
⭐Note: I'm having a hard time thinking of a use-case for this in which the element opting-out is not a leaf-node in the tree and wants its descendants to still participate. If no one else can think of a use case either, maybe this scenario can be dropped, especially if we change the above meaning of the focusgroup=none declaration to apply to the declaring element and its subtree.
Part 4: drop the extend concept
There is no need to extend focusgroups anymore when they automatically include the whole subtree. However, there is still a use-case to be able to switch the directionality of a linear focusgroup when it was constrained in one direction in an ancestor to be the opposite direction. In the current explainer text, authors can chose to make weird combinations of directionality such that arrow-key movement becomes non-bi-directional. From the current explainer:
The arrow key interactions will be clearer to users when nested focusgroups are strictly orthogonal to each other. Authors should not extend both direction linear focusgroups with single-directional linear focusgroups (and vice-versa) as a best practice.
We have an opportunity to remove this foot-gun and help ensure a good user experience for these cases. Instead of extend we replace it with orthogonal which means:
- if there is an ancestor focusgroup in scope
- if that ancestor focusgroup was limited in directionality to either horizontal or vertical
- swap the limited directionality for this element's subtree (and potentially apply a new wrapping behavior).
- if that ancestor focusgroup was limited in directionality to either horizontal or vertical
If any of the 'if' conditions fail, then... (reasonable fallback behavior, which could be to treat the orthogonal token as if it was omitted)
<div focusgroup=horizontal>
<div>
<div>
<div focusgroup=orthogonal> <!-- this subtree responds to vertical-direction arrow keys only-->
</div>
</div>
</div>
</div>This avoids a lot of potential developer pitfalls by dramatically limiting the previous expressive power of extend to just the use-case that remains.
In these scenarios where direction changes, I would like to propose a simpler way for how the focusgroup will determine what arrow keys to accept. From a given focusable element, a forward-direction arrow key (of either horizontal or vertical arrow keys) finds the next focusable element in DOM order whose focusgroup supports that direction (skipping orthogonal focusgroup subtrees where the direction doesn't match). This is a partial fix for the current explainer's example 12.