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

[focusgroup] How does focusgroup interplay with autofocus?

Open keithamus opened this issue 1 year ago • 7 comments
trafficstars

In https://github.com/openui/open-ui/issues/989 we discussed a scenario for orthogonal focus groups; say you have something like:

<div focusgroup=horizontal>
  <button></button>
  <button invoketarget=more-menu>More</button>
  <div popover id=more-menu focusgroup=vertical>
    <button autofocus></button>    
  </div>
</div>

Supposedly, opening the popover menu would land focus on the button, and then the vertical group would focus? What happens in light of the resolutions in https://github.com/openui/open-ui/issues/989 where the element with focusgroup is part of the group?

Perhaps also interesting, what if we change from invoketarget to interesttarget?

<div focusgroup=horizontal>
  <button></button>
  <button interesttarget=more-menu>More</button>
  <div popover id=more-menu focusgroup=vertical>
    <button autofocus></button>    
  </div>
</div>

keithamus avatar Mar 07 '24 20:03 keithamus

Supposedly, opening the popover menu would land focus on the button, and then the vertical group would focus?

Yes, that's my expectation as well, given how the popover focusing steps are written. (If there's an autofocus delegate under the popover node, it pulls focus to it.) Because focus now lands inside of a vertical (block-orientation) focusgroup, the up/down arrow keys will work to move the focus around within that focusgroup.

What happens in light of the resolutions in https://github.com/openui/open-ui/issues/989 where the element with focusgroup is part of the group?

In this scenario, I don't think there's any change (no difference). If you adjusted the markup slightly so that the <div popover ...> element could also be focusable (was made click/keyboard focusable with tabindex), you could put the autofocus attribute on it so that the entire popover container element would get focus on opening...

As an aside: by having the focusgroup attribute apply to the element declaring it, the other [good] side effect is that it opts-out the child div element from the parent's focusgroup (because a declaring child focusgroup will be an implicit focusgroup=none for any ancestor focusgroups--it removes itself from consideration in the parent's group, which is the desired behavior in this scenario, I believe).

travisleithead avatar Mar 13 '24 20:03 travisleithead

(because a declaring child focusgroup will be an implicit focusgroup=none for any ancestor focusgroups--it removes itself from consideration in the parent's group, which is the desired behavior in this scenario, I believe)

I'm not sure if I understand this correctly. Would a child focusgroup declare it's own individual focusgroup or implicitly opt-out it's subtree from any focusgroup behavior?

<div focusgroup> <!-- Parent -->
  <div focusgroup> <!-- implicit focusgroup=none? -->
    <button>Am I a candidate, if yes, for which group?</button>
    <div focusgroup></div> <!-- what happens here? -->
  </div>
</div>

gfellerph avatar Mar 14 '24 05:03 gfellerph

Note, the following is not currently written in the explainer, but is planned for inclusion.

@gfellerph my expectation is that whenever a focusgroup attribute is declared it does two things:

  1. It implicitly opts-out of any ancestor focusgroups like it was declared as focusgroup=none. Therefore both itself and its subtree would be excluded from an ancestor's focusgroup.
  2. It declares a new focusgroup starting from that node and including its subtree.

So in your example:

<div focusgroup> <!-- Parent -->
  <div focusgroup> <!-- implicit focusgroup=none? -->
    <button>Am I a candidate, if yes, for which group?</button>
    <div focusgroup></div> <!-- what happens here? -->
  </div>
</div>
  • <-- Parent --> is a focusgroup that currently has no focusable candidates in it. IF other children were added with it as the parent, then they and their descendants would be candidates for inclusion in that Parent focusgroup.
  • <button> is in the focusgroup declared by its parent.
  • <-- what happens here? --> declares another focusgroup with no focusable candidates. At the same time it is also opting itself out of inclusion in the focusgroup that includes the <button>.

The reason for having a focusgroup declaration automatically opt-out the element from any ancestor focusgroups is to avoid the situation where an element might belong to more than one focusgroup at a time. If such a thing were possible it seems like it opens up a whole lot more complexity (similar to what extend was doing) without a motivating use case.

travisleithead avatar Mar 14 '24 21:03 travisleithead

Regarding any planned interaction with autofocus, I'm leaning toward not having any kind of relationship between focusgroup and autofocus (which is kind of sad given the naming... 😔). Elements with a focusgroup will likely be fairly static (e.g., not showing/hiding a lot) so re-using autofocus to have some kind of redirection pattern for focusgroups doesn't make a lot of sense to me. Also, autofocus (outside of popover) is mostly a one-and-done feature, which also doesn't make a lot of sense in terms of focusgroup whose memory and other actions kick-in when focus enters and leaves a lot--so that might be stretching the definition of autofocus a bit too far also.

If we did want to tweak autofocus for special-case use in a focusgroup then one possibility is to have it be a "memory override" such that focus would always go initially to the autofocus-decorated focusable element. However, tabindex=0 already handles that use case combined with disabling the focusgroup's memory.

Anyone else have a good use case or creative way to use autofocus within a focusgroup?

travisleithead avatar Mar 21 '24 20:03 travisleithead

I'm not sure if this is a case that can happen, but consider:

  • A focusgroup that the user has already entered once (it has a memory now)
  • An autofocus attribute inside that focusgroup that hasn't been triggered yet
  • An action that triggers the autofocus code but that doesn't clear the focusgroup memory (e.g., can't be a show/hide of a menu, movement in the DOM, change in focusability, etc.)

If such a use case is possible, then it would be reasonable to assume that the autofocus code might have an integration with focusgroup's memory such that the autofocus element's selection process would give preference to the focusgroup's memory element.

travisleithead avatar Mar 27 '24 18:03 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 Sep 24 '24 00:09 github-actions[bot]

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 Mar 24 '25 00:03 github-actions[bot]