RFC: The future of missing.js #120
Replies: 4 comments
-
Initial widgets to implementIn order to build a sufficiently robust framework, we should start with implementations of the following patterns:
|
Beta Was this translation helpful? Give feedback.
-
Managing stateThe following table summarizes the potential ARIA states a widget could assume. A few things to note:
How can we best provide authors the ability to monitor, change, and style widget state?Answer: Use ElementInternals to set roles, properties and default state and change state using
|
Beta Was this translation helpful? Give feedback.
-
AlternativesA list of similar (but not) libraries that may be helpful by ways of compare/contrast:
|
Beta Was this translation helpful? Give feedback.
-
|
When it comes time to finalize docs / demos, make sure to specify all the default ARIA properties set in ElementInternals, as well as supported ARIA states/properties. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
missing.js
The goal of missing.js is to provide a comprehensive collection of common UI widgets and behaviors that:
To that end, we are creating this discussion to:
Widget list
Below is a list of possible widgets we could implement:
ARIA APG Patterns (click to toggle)
<details name=foo><output role=alert>for alerts (<output>has implicitrole=statusand isdisplay: inlineby default, so the author would need to change that)<output>for toasts (the implicitrole=statusimpliesaria-live=politeandaria-atomic=true, same caveat with defaultdisplayvalue)<dialog role=alertdialog>(<dialog>has implicitrole=dialog)<nav>, 2) provide accessible name, 3) setaria-current=page<button><input type=checkbox><dialog><details><aside>,<footer>,<header>,<main>,<nav>,<section aria-label>,<form>, and<search><a><meter><input type=radio name=foo><input type=range><input type=checkbox role=switch><table>Non-APG Patterns (click to toggle)
internals.role = region,tabindex = 0,overflow: auto).titlebarin alerts, dialogs, etc)<article>where clicking anywhere on the article (that isn’t itself clickable) activates a certain link or button or other action.<input type=date|time|datetime-local>sufficient?<input type=color>sufficient?light-dark()(composite widget of two color pickers)<progress>sufficient?Guidelines
Components should mutate their child elements as little as possible. They should be able to initialize themselves when the children have already been mutated (i.e. if a live DOM tree is stringified and restored, such as during htmx history restoration).
Components should emit events liberally for interactions performed on them, so that their behavior can be hooked into.
Shadow DOM should only be used to set styles that are strictly required for functionality
display: inlineby default, (e.g. set:host { display: block; }for tabpanels).Common behaviors should be abstracted into composable mixins.
Accessibility guidelines must be strictly followed when available. If the component does not have explicit guidelines, careful consideration should be taken based on guidelines for similar components.
Implementation
Thanks to deniz, we have two great utility functions:
behavior()andtag(). The first one allows us to hook custom functionality into elements matching a given selector (e.g.role=menu), and the second one reduces a lot of boilerplate involved in custom elements.behavior()than atag()?behavior()needs to be re-initialized for dynamically created elements: this happens for free withtag()(however, it might be possible forbehavior()to be extended to cover this).tag()provides access to the ElementInternals API, requiring significantly less author markup.behavior()doesn't require dash-separated names and can be hooked directly into any selector, making it compatible with existing CSS libraries.tag()requires dash-separated names, making it incompatible with existing CSS libraries.<aria-foo>works well with APG patterns:<aria-tooltip>,<aria-carousel>,<aria-tree-view|grid>,<aria-window-splitter>, but maybe feels out of place for non-APG patterns:<aria-input-mask>/<aria-scroll-box>.<a-tablist>,<a-menubar>(maybe follow English grammar with<an-alert>), making non-APG patterns such as<an-input-mask>and<a-scroll-box>feel less out of place.<missing-menu-bar>,<missing-input-mask>Common behaviors
There are a few recurring behaviors utilized in accessible widgets. These should be developed in a composable way in order to make creation of compound widgets more efficient. Some of the behaviors are getting native implementations (such as invoker buttons and anchor positioning), but it'll be awhile before they're available across our support target.
Focus group: Add keyboard support for moving focus among a list or grid of focusable elements with a roving tabindex. (see: open-ui explainer)
Focus selector: Add support for selecting an element when it is focused. ARIA roles that require "selection follows focus" include
role=tree|listbox|tabHot keys: Add keyboard shortcuts to an element, e.g.
Escapeto close a menu, moving focus to the next item in a menu whose label begins with a given printable character, and other non-standard keyboard navigation (feeds).Invoker button: Polyfill for the
commandforandcommandattributes. Needed for menus and toolbars. (see: open-ui explainer)Anchor positioning: Polyfill for the upcoming CSS anchor positioning. Needed for menus, tooltips, and combobox.
Dynamic ID / ARIA linking / ARIA validating: many widgets require unique ids and linkage via
aria-labelledby/aria-describedbyetc. This could possibly automatically handle setting those attributes and/or logging errors to console when markup does not specify required ARIA links. See ARIA Naming Role GuidanceLight dismiss: "Closes" the component when the user clicks outside the element. What it means to “close” is defined by the child component.
Reorderable: Allow a component’s children to be reordered by clicking and dragging. Needs research to figure out if this is possible to implement generically, or needs to be implemented within specific components.
Next steps
<aria-foo>,<a|an-foo>,<missing-foo>Beta Was this translation helpful? Give feedback.
All reactions