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

Reflection as a counterpart to delegation #14

Closed
nolanlawson opened this issue Jun 29, 2022 · 13 comments
Closed

Reflection as a counterpart to delegation #14

nolanlawson opened this issue Jun 29, 2022 · 13 comments

Comments

@nolanlawson
Copy link
Collaborator

@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:

  • Do you want your host to have the aria attribute pointing somewhere else? (Delegation)
  • Do you want someone else to have the aria attribute pointing at your host? (Reflection)
@Westbrook
Copy link
Contributor

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
Copy link
Contributor

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
Copy link
Contributor

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
Copy link
Contributor

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

@nolanlawson
Copy link
Collaborator Author

nolanlawson commented Jul 5, 2022

Thanks for the hard work on this!

This might be a 🚲 shed, but I agree with Westbrook#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
Copy link
Collaborator

mrego commented Jul 6, 2022

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

@nolanlawson
Copy link
Collaborator Author

@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. 🙂)

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
Copy link
Collaborator

mrego commented Oct 25, 2022

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

@mrego
Copy link
Collaborator

mrego commented Oct 25, 2022

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
Copy link
Collaborator Author

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

@mrego
Copy link
Collaborator

mrego commented Apr 18, 2023

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
Copy link

WCCG had their spring F2F in which this was discussed. You can read the full notes of the discussion (WICG/webcomponents#978 (comment)) 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 WICG/webcomponents#1005 is the tracking issue for that breakout, in which this will likely be discussed.

@nolanlawson
Copy link
Collaborator Author

nolanlawson commented May 11, 2023

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.

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

4 participants