-
Notifications
You must be signed in to change notification settings - Fork 424
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
Aria Elements: Support for aria-
prefixed Element reference attributes
#627
base: main
Are you sure you want to change the base?
Conversation
@marcoroth I'd love some feedback on the idea and how it might co-exist with Outlets. @adrienpoly I'd love some feedback on how it fits into the idea of attribute change callbacks, as it takes one step past listening for |
da0f125
to
08dcaf4
Compare
Hey @seanpdoyle, thanks for exploring this idea! I like the concept of having an API which allows to target any reference on the page. The thing I'm wondering about is if we should introduce this as a "Stimulus API using a static property" or if we should provide some kind of "helper" that you can access via something like Since the Referencing any element on a pageSo let's say we want to target a Then we would do static references = ["data-navigation"] Which would then allow use the reference the element as "Elements API" ?I'm wondering if we should introduce something like a more general "Elements API" which more or less follows the Targets API, but with the difference that you can target any element on the page. static elements = ["navigation"] Defining the reference to the element on the controller element<nav id="nav">...</nav>
<!-- ... -->
<div data-controller="layout" data-layout-navigation-element="nav"></div> and then allows us to reference Defining the reference anywhere in the DOMWe could also do it the other way around and say: <nav data-layout-element="navigation">...</nav>
<!-- ... -->
<div data-controller="layout"></div> ConclusionPersonally I don't think an "ARIA helper" and something like an Elements API would contradict each other. Or how do you feel about this? Do you think this is one and the same concern and should be handled in the same API? |
Specifically for ARIA, ARIA 1.3 adds attributes to access referenced elements in The first examples eventually becomes: export default class extends Controller {
toggle() {
const expanded = this.element.ariaExpanded
for (const ariaControlsElement of this.element.ariaControlsElements) {
ariaControlsElement.hidden = expanded != "true"
}
}
} These attributes are also setters so you can do: element.ariaControlsElements = [otherElement] This is not implemented in shipping browsers but from a quick test, it is in Safari Technology Preview 162 and Chrome Canary 111. I'm sharing this to help design the API with upcoming standard changes in mind. |
f97694b
to
6605c4d
Compare
aria-
prefixed Element reference attributes
@rik thank you for sharing that document! @marcoroth I've updated this work to reference "ARIA Elements" and "aria[name]Element" instead of "aria[name]Reference". In the short term, we'll stick with declaring This means that elements referenced by the singular In the future, as support for |
6605c4d
to
1ad8b4f
Compare
@marcoroth defining the Controllers already define singular- and collection-returning properties (suffixed by Some day, controller code will be able to choose the property that is most appropriate, without making substantiate property name changes (for example, they'll be able to choose between The callback naming ( |
@seanpdoyle I completely agree that defining the The names you proposed for the accessors, I think the thing I was thrown off by was that these properties just exist without declaring them compared to what we have in other Stimulus APIs, which is what made me believe that this should use something like a I know that the first version of your PR used a static property, even if it wasn't really user-facing since it had the defaults set already, unless you did actually override them. I guess what I was alluding to is that there might be an opportunity here for a general "Elements API" which incorporates ARIA, data and other attributes for element lookups in a single API. I was wondering if we could take this one step further by (re-)introducing a For So the end result would look something like this:
Maybe the second case above for the |
Having the
To me, having ARIA attributes magically appear is a strength of the proposal. This is Stimulus knowing about web standards and providing added functionality on top of them. |
We can also leave out the I agree that it shouldn't "encourage" people to make applications "less accessible" by default. It was more of an idea to make the existing Stimulus conventions work with this concept. But it's fine to me, if we can agree that ARIA attributes are "special enough" to treat them differently by just allowing the "short version".
Maybe it's just me, but I feel like I can grasp Stimulus controllers better and quicker if I can glance at the the top of the class and can see what the controllers "depends" on and what possible things it can have. Having to declare the elements which could be used in the a controller does not only benefit that, but also helps with performance, since it doesn't need to register Mutation Observers and properties for every possible element that can be used. Because every Stimulus controller instance would otherwise get at least 8 more Mutation Observers for just covering elements which aren't even used. |
Unfortunately, not all We're already documenting this mapping, but we wouldn't want to burden callers with declarations that get the mapping correct. Would the |
I have to admit, I missed that detail until now, sorry about that! I remember looking at that table and wondering why it's there. That makes sense now.
Yeah, I guess we can handle that mapping behind the scenes. And maybe even that |
@seanpdoyle thanks for your work on this – in my opinion it's a breath of fresh air to see Stimulus embracing web standards.
I strongly agree with this statement, I think it demonstrates a good separation of concerns – the role/behaviour of the element is documented, vs coupling it to the controller's internal behaviour. Controllers serve the dom, not the other way around. I strongly prefer this convention over configuration approach compared to the verbose and pedantic syntax required for outlets and targets (especially for namespaced controllers). I'd like to see more examples of Stimulus embracing existing dom functionality. |
Do you think this PR can be merged? |
1ad8b4f
to
ca37d6b
Compare
ca37d6b
to
c869d0d
Compare
While it borrows from [targets][] and [outlets][], the idea of `ariaElements` also draws inspiration from the The [ARIAMixin][] introduced in the ARIA 1.3 specification and the [WAI ARIA concept of an [ID Ref and ID Ref List][aria-ref] attribute, like: * [aria-activedescendant](https://www.w3.org/TR/wai-aria-1.2/#aria-activedescendant) * [aria-controls](https://www.w3.org/TR/wai-aria-1.2/#aria-controls) * [aria-describedby](https://www.w3.org/TR/wai-aria-1.2/#aria-describedby) * [aria-details](https://www.w3.org/TR/wai-aria-1.2/#aria-details) * [aria-errormessage](https://www.w3.org/TR/wai-aria-1.2/#aria-errormessage) * [aria-flowto](https://www.w3.org/TR/wai-aria-1.2/#aria-flowto) * [aria-labelledby](https://www.w3.org/TR/wai-aria-1.2/#aria-labelledby) * [aria-owns](https://www.w3.org/TR/wai-aria-1.2/#aria-owns) Providing built-in support from Stimulus for elements that a controller establishes an [`[id]`-based relationship][id-relationship] with through ARIA attributes could cultivate a virtuous cycle between assistive technologies (reliant on semantics and document-hierarchy driven relationships) and client-side feature development (reliant on low-friction DOM traversal and state change callbacks). [targets]: https://stimulus.hotwired.dev/reference/targets [outlets]: https://stimulus.hotwired.dev/reference/outlets [aria-ref]: https://www.w3.org/TR/wai-aria-1.2/#propcharacteristic_value [id-relationship]: https://www.w3.org/TR/wai-aria-1.2/#attrs_relationships [ARIAMixin]: https://w3c.github.io/aria/#ARIAMixin
c869d0d
to
b3c175e
Compare
While it borrows from targets and outlets, the idea of
ariaElements
also draws inspiration from the The ARIAMixinintroduced in the ARIA 1.3 specification and the [WAI ARIA concept of an
ID Ref and ID Ref List attribute, like:
Providing built-in support from Stimulus for elements that a controller
establishes an
[id]
-based relationship with throughARIA attributes could cultivate a virtuous cycle between assistive
technologies (reliant on semantics and document-hierarchy driven
relationships) and client-side feature development (reliant on
low-friction DOM traversal and state change callbacks).
From the Documentation for
ARIA Elements
:ARIA Elements
ARIA Elements provide direct access to elements within (and without!) a Controller's scope based on their
[id]
attribute's value.They are conceptually similar to Stimulus Targets and Stimulus Outlets, but provide access regardless of where they occur in the document.
While a target is a specifically marked element within the scope of its own controller element, an ARIA element can be located anywhere on the page.
Definitions
Unlike Targets, support for ARIA Elements is built into all Controllers, and
doesn't require definition or additional configurations.
Out-of-the-box, Controllers provide Elements support for all ARIA ID reference
and ID reference list attributes that establish
[id]
-basedrelationships, including:
Properties
For each ARIA ID reference and ID reference list attribute, Stimulus adds three properties to your controller, where
[name]
corresponds to an attribute's name:has[Name]Element
Boolean
[id="${name}"]
[name]Element
Element
Element
whose[id]
value is included in the[name]
attribute's token or throws an exception if none are present[name]Elements
Array<Element>
Element
s whose[id]
values are included in the[name]
attribute's tokensKebab-case attribute names are transformed to camelCase and TitleCase according
to the following rules:
The casing rules for these names are outlined under § 10.1 Interface Mixin ARIAMixin of the Accessible Rich Internet Applications (WAI-ARIA) 1.3 Specification.
ARIA Element Callbacks
ARIA Element callbacks are specially named functions called by Stimulus to let you respond to whenever a referenced element is added or removed from the document.
To observe reference changes, define a method named
[name]ElementConnected()
or[name]ElementDisconnected()
.ARIA Elements are Assumed to be Present
When you access an ARIA Element property in a Controller, you assert that at least one corresponding ARIA Element is present. If the declaration is missing and no matching element is found Stimulus will throw an exception:
Optional ARIA Elements
If an ARIA Element is optional or you want to assert that at least one ARIA Element is present, you must first check the presence of the ARIA Element using the existential property:
Alternatively, looping over an empty Array of references would have the same
result: