leobalter / cross-root-aria-delegation

Explainer for the Cross-root ARIA delegation proposal
https://leobalter.github.io/cross-root-aria-delegation/
25 stars 3 forks source link

Reflection as a counterpart to delegation #14

Closed nolanlawson closed 1 year ago

nolanlawson commented 2 years ago

@westbrook has a related proposal that proposes "reflection" as a counterpart to delegation. Should that proposal be merged into this one?

It seems to me that the two concepts are related, and they may benefit from a unified API surface to capture both of them.

For example, here is a case (a combobox) where you would need both delegation and reflection:

<fancy-input aria-controls="the-listbox" aria-activedescendant="the-listbox">
  #shadow-root delegates-aria-controls delegates-aria-activedescendant
    <!-- delegates aria-controls / aria-activedescendant to the host -->
    <input type=text autoariacontrols autoariaactivedescendant>
</fancy-input>

<fancy-listbox id="the-listbox">
  #shadow-root reflects-aria-controls reflects-aria-activedescendant
    <!-- reflects aria-controls to the host -->
    <div role="listbox" reflectsariacontrols>
      <!-- reflects aria-activedescendant to the host -->
      <div role="option" reflectsariaactivedescendant>One</div>
      <div role="option">Two</div>
    </div>
</fancy-listbox>

(BTW this is just a sketch and should not be taken literally.)

In the above example, the <input> needs to have its aria-controls point to the role="listbox", and also have its aria-activedescendant point to the role="option".

The difference between "delegation" and "reflection" is this:

Westbrook commented 2 years ago

I’d prefer to manage scope creep and get something out as soon as possible. The Chrome team is interested in moving this ahead as soon as there’s spec text and I wouldn’t want to hold this up with doubling the scope to include reflection as well.

Westbrook commented 2 years ago

Might be worth bringing this up in tomorrows AOM sync to see what other thing about this. I’ll try really hard to get a draft copy of this repo with reflect semantics for the convo.

Westbrook commented 2 years ago

Making some quick work of the basic: https://github.com/Westbrook/cross-root-aria-reflection

Getting into the spec site may be a bridge too far, but I'll do my best!

Westbrook commented 2 years ago

Copy and paste is magical. Lots of nuanced changes to do, but: https://westbrook.github.io/cross-root-aria-reflection/

nolanlawson commented 2 years ago

Thanks for the hard work on this!

This might be a :bike: shed, but I agree with https://github.com/Westbrook/cross-root-aria-reflection/pull/6 that "reflection" is a bit confusing. I also wonder about the auto in the Delegation spec.

When @bkardell said "import / export," those terms made sense to me. Although they are overloaded with ES module imports/exports.

This is part of the reason I wondered about combining the two specs, or at least ensuring their conventions/API surface is harmonized. E.g.:

<fancy-input aria-controls="the-listbox" aria-activedescendant="the-listbox">
  #shadow-root exports-aria-controls exports-aria-activedescendant
    <input type=text exports-aria-controls exports-aria-activedescendant>
</fancy-input>

<fancy-listbox id="the-listbox">
  #shadow-root imports-aria-controls imports-aria-activedescendant
    <div role="listbox" imports-aria-controls>
      <div role="option" imports-aria-activedescendant>One</div>
      <div role="option">Two</div>
    </div>
</fancy-listbox>

I'm not married to import / export, but my point is that the two specs could have roughly the same API surface, the same kebab-style naming conventions, etc. And maybe reflection / delegation should be changed in favor of words that are obviously opposites.

mrego commented 2 years ago

@nolanlawson do you have any example that combines both things in a single element?

nolanlawson commented 2 years ago

@mrego Hmm, off the top of my head, I think a tab panel might illustrate this:

<div role="tablist">
  <x-tab aria-controls="tabpanel-1" id="tab-1">
    #shadow-root delegates-aria-controls reflects-aria-labelledby
      <button role="tab" aria-selected="true" delegates-aria-controls reflects-aria-labelledby>
        Tab title
      </button>
  </x-tab>
  <!-- more tabs -->
</div>
<x-tabpanel id="tabpanel-1" aria-labelledby="tab-1">
  #shadow-root delegates-aria-labelledby
    <div role="tabpanel" delegates-aria-labelledby>
      Tab content
    </div>
</x-tabpanel>
<!-- more tabpanels -->

In this case, the <button> aria-controls the tabpanel, and the tabpanel is aria-labelledby the <button>. So the button needs to delegate aria-controls and reflect aria-labelledby. (Yes, you could just point aria-labelledby to the whole host, but this is just an example. :slightly_smiling_face:)

One unrelated thing I noticed while writing this: I don't think it would be possible to wrap multiple <x-tab>s into a single shadow root (e.g. an <x-tablist> component), because then the tab panels wouldn't be able to target individual tabs with aria-labelledby. Not sure if this is something that can be tackled with reflection. (We had a similar issue with aria-activedescendant in a combobox, but it was mitigated by the fact that only one option could have aria-activedescendant at a time.)

mrego commented 2 years ago

There's some related information in #4, the updated explainer has a section about this topic.

mrego commented 2 years ago

Let's use this issue to discuss this topic, but first we need to solve in the final form of both delegation and reflection proposals, before we can see how they work together and if they need any kind of adjustment.

nolanlawson commented 1 year ago

@mrego Can this issue be closed? The latest version of the explainer seems to explicitly cover reflection.

mrego commented 1 year ago

I don't mind if we prefer to close it, or if we want to keep this open. The idea of having this open was to discuss both the combination of both parts in the proposal: https://github.com/leobalter/cross-root-aria-delegation/blob/main/explainer.md#combination-of-both-proposals

But feel free to close it, if you think it's better.

keithamus commented 1 year ago

WCCG had their spring F2F in which this was discussed. You can read the full notes of the discussion (https://github.com/WICG/webcomponents/issues/978#issuecomment-1516897276) in which this was discussed, heading entitled "ARIA Mixin & Cross Root ARIA" - where this issue was specifically discussed.

In the meeting, present members of WCCG reached a consensus to discuss further in breakout sessions. I'd like to call out that https://github.com/WICG/webcomponents/issues/1005 is the tracking issue for that breakout, in which this will likely be discussed.

nolanlawson commented 1 year ago

This was discussed in today's F2F, and there seemed to be broad consensus that the concept of reflection was relevant to the concept of delegation, and that both should be handled in the same spec. (Although we may disagree about the exact shape of the API.)

Closing this issue.