-
Notifications
You must be signed in to change notification settings - Fork 59
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
Encapsulation-preserving IDL Element reference attributes #195
Comments
I think I need to see a clearer motivating example. For the case presented above we wouldn't want |
The question of "why would the attr-associated element ever be anything not in a shadow-including ancestor" has come up a few times in the AOM group. A few examples I can think of:
If #2 seems far-fetched, I can say that the two most prominent comboboxes in the Salesforce UI both use this pattern (our searchbox and our app picker). We have investigated moving from our current shadow DOM polyfill to native shadow DOM, and this was one of the issues we found. (Our polyfill covers styling, slotting, and most DOM APIs, but still allows ARIA references across shadows.) |
@nolanlawson I think these descriptions might be too abstract. It's not clear to me for instance if the host of the shadow root could fulfill the role of intermediary for these relationships. That's the solution space I would like to explore further. |
@annevk I'm not entirely clear on what you're asking for - what do you mean about the shadow host being an intermediary? Are you proposing that instead of authors being able to set the relationship directly, that the shadow host be required to perform indirection (iterated through as many shadow roots as necessary)? Or is this a request for a more specific use case demonstrating how the shadow host might mediate the relationship? |
I might be proposing that, yes. I mean that something like https://github.com/leobalter/cross-root-aria-delegation/blob/main/explainer.md seems more reasonable, details TBD. And that if something like that isn't deemed feasible, I'd like to see more details. |
I certainly don't mean that this is the only thing we need. Unlike ARIA reflection/delegation, an API like this requires components which need to be associated across shadow roots to either:
Also, ARIA delegation/reflection have important use cases which this proposal wouldn't solve, or at least not well - specifically that of honouring author provided attributes. However, the benefits that having this more direct kind of connection possible as well would be that it allows a connection to be made in cases where an author does need to create a direct reference and does have the ability to do that (e.g. they're writing code where they are authoring all of the relevant components/page), but doing so using the reflection/delegation APIs would be either extremely inconvenient/verbose (potentially because it's crossing multiple shadow root boundaries which would each have to set up the correct reflection/delegation mechanisms) or impossible (because of the bottleneck effect, which is obviously more likely to be an issue when crossing multiple shadow root boundaries.) |
Just to put it out there: I really like this proposal.
The major downsides I see are 1) no SSR support, and 2) would require component authors to potentially expose implementation details they wouldn't otherwise want to expose*. Neither one is a dealbreaker to me, and would be addressed by either the semantic delegate or cross-root ARIA as nice additions on top of this API. * To expand on (2): For example, today a React component might pass around string IDs to allow for ARIA wiring (e.g. |
For (1) there are a couple of ideas in https://gist.github.com/alice/54108d8037f865876702b07755f771a5#some-kind-of-id-syntax-to-allow-arbitrary-cross-shadow-root-id-references - I don't know that we have to commit to using either of them, or any other declarative option, in order to proceed with the proposal in this issue, but I would envision either working as a declarative version of this API if they did exist. |
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. |
This was discussed in today's cross-root ARIA F2F. One sticking point we discussed is that this API would expose internal details of the component. For example, the input.ariaActiveDescendantElement = opt1; One potential solution would be to have some kind of proxy/wrapper object that stands in for the element itself. For example: const wrappedOpt1 = document.createAriaProxy(opt1);
input.ariaActiveDescendantElement = wrappedOpt1; This proxy/wrapper object would be capable of being the target of an This would allow the ARIA relationship to be set without exposing the private element itself. |
Background: @nolanlawson proposed on #192 that IDL attributes be allowed to refer into open shadow roots (through arbitrarily many layers of open shadow roots, as long as no closed shadow roots were involved). It was noted during that discussion that as currently specified, setting an IDL attribute to an element does have an effect, except the effect is only to set some data internal to the browser that can't be observed unless the DOM structure changes - trying to read back the IDL attribute simply returns
null
, as if no value had been set, and nothing is exposed to AT. The question was raised whether it might be possible to expose that data to assistive technology even though it wasn't exposed to the DOM API - so encapsulation might be preserved, but setting the attribute still have an observable (via AT/developer tools only) effect. This was dismissed as having developer ergonomics which were too bad to be workable. There was also concern around the idea of treating open shadow roots and closed shadow roots differently in this context.Proposal:
I'd like to iterate on Nolan's proposal by proposing that
For example,
This preserves encapsulation by requiring an explicit step (and access to the shadow root) to access elements inside shadow roots.
This proposal is inspired by several precedents:
getComposedRanges(shadowRoots)
in the Selection API, which takes a list of known shadow roots and "enables the method to return Nodes within the provided list of shadow roots, if necessary."Event.composedPath()
which returns the objects an event will be fired on during propagation, including any nodes in the event path which are inside open shadow roots, but no closed shadow roots. (@annevk has noted that "that was more of a compromise than a desired design path," in the context of the discussion which led togetComposedRanges()
.)Document.activeElement
which also performs retargeting in its getter.The text was updated successfully, but these errors were encountered: