open-ui icon indicating copy to clipboard operation
open-ui copied to clipboard

[focusgroup] "descend" into non-child descendent should callout limitation

Open travisleithead opened this issue 2 years ago • 3 comments

In this scenario:

<!-- assume all elements are focusable -->
<grandparent focusgroup="horizontal">
 <parent>
  <child focusgroup="vertical extend">...</child>
  <child focusgroup="vertical extend">...</child>
 </parent>
</grandparent>

where two child elements extend the grandparent (in an orthogonal direction), the spec allows for a down-arrow on parent to descend into child with

"When a focusgroup is considering a cross-axis arrow key to descend, only the currently focused element and any of its extending focusgroup descendants are considered." (section 6.2.2.)

but is ambiguous about which child element will be the target of the descent operation, and in general does not consider this case where there are more than one set of children that want to be orthogonal targets for a descent operation.

There may be some use cases to support this type of configuration. For example:

  1. Double sub-menus (very weird, but for size/space accommodations it might make sense to split a sub-menu into two logical parts and position them separately. In this case, the descent would need to pick the first one in DOM order to descend into (logically). A variation of this use case is if one large sub-menu is too long for the available space, then it could be displayed in two or more columns, for example.
  2. Paged content. (Not necessarily a menu scenario). Some card might have "child" items that are organized in groups for the purpose of "paging" them in rather than scrolling. The multiple pages would be in separate child extending groups, but would be linearly connected to each other and would "reveal" when focus moved from the end of one group to the start of the next group.

In both of the above use cases, there is an expectation that the separately-grouped child descenders are still related/connected such that arrow key movement should flow seamlessly from the end of one group into the start of the next group. Unfortunately, the way the markup is specified above, there is no way to express this linear connection between siblings because focusgroup definitions apply only to parents. Rather than inventing a new mechanism to bind sibling focusgroups together, we opt to keep the feature simple and require that the common ancestor (parent in this case) be used as a workaround to make the focusgroup connection between siblings.

The spec should add clarity that the descend operation can still happen for a non-child descendent, but that only the first eligible extending focusgroup in DOM order is considered. Specifically:

<grandparent focusgroup="horizontal">
 <parent>
  <child id=one focusgroup="horizontal extend">...</child>
  <child id=two focusgroup="vertical extend">...</child>
  <child id=three focusgroup="horizontal extend">...</child>
  <child id=four focusgroup="vertical extend">...</child>
  <child id=five focusgroup="horizontal extend">...</child>
 </parent>
</grandparent>

With focus on grandparent, pressing the right-arrow 3 times will move focus to: [ one, three, five] because they extend focus in the same dimension and become part of grandparent's linear focus group.

With focus on grandparent, pressing the down-arrow 3 times will move focus to: [ two, n/a, n/a ] since two is the first extending descendant that supports the vertical direction (in DOM order). Sibling element four is not related by focusgroup to two despite extending in the same orthogonal direction.

The above example is already a bit non-sensical. If the scenario is purely one of multiple siblings of orthogonal direction needing to be connected, the proper way to do this is to create a focusgroup on the nearest common ancestor and not try to mix-and-match different focusgroup directions...

<grandparent focusgroup="horizontal">
 <parent focusgroup="vertical extend">
  <!-- <child id=one focusgroup="horizontal extend">...</child> -->
  <child id=two focusgroup="vertical extend">...</child>
  <!-- <child id=three focusgroup="horizontal extend">...</child> -->
  <child id=four focusgroup="vertical extend">...</child>
  <!-- <child id=five focusgroup="horizontal extend">...</child> -->
 </parent>
</grandparent>

travisleithead avatar Jun 27 '22 23:06 travisleithead

There hasn't been any discussion on this issue for a while, so we're marking it as stale. If you choose to kick off the discussion again, we'll remove the 'stale' label.

github-actions[bot] avatar Dec 25 '22 00:12 github-actions[bot]

Issue #989 largely renders this issue obsolete. In 989, we propose changing the semantics of focusgroups such that:

  • 'extend' is no longer necessary because all descendants are considered for focusgroup candidacy
  • 'orthogonal' (or 'flip') is added to toggle the opposite directionality in a subtree... and
    • the algorithm to respond to an orthogonal direction press is simplified to check the next candidate in a supporting focusgroup subtree and pick it if it supports the given direction--so the notion of "descent" and "ascent" effectively goes away.

travisleithead avatar Feb 21 '24 19:02 travisleithead

Current plan:

  • close this issue when issue #989 is completed.

travisleithead avatar Feb 21 '24 19:02 travisleithead

The linked issue is now closed. Closing this one.

travisleithead avatar Mar 28 '24 23:03 travisleithead