Repository navigation
UI: Remove speak functionality from Notice primitive #82701
Description
What problem does this address?
Related: #80706
Currently, the Notice component implementation in @wordpress/ui includes built-in functionality to use @wordpress/a11y's speak utility to announce the content of the notice.
This is problematic in a few ways:
- The
@wordpress/uipackage is a set of low-level UI primitives that are intended to be used in a variety of use-cases, and there may be cases where a UI should contain a notice that is not a dynamic message that needs to be announced to screen readers (e.g. notices which are statically present at page load). Dynamic notices are a common use-case and should continue to be handled with sensible defaults, but this should happen at a higher level of abstraction. - The current default implementation of the spoken message is naive and often produces an undesirable result. As explored in UI: Update Notice spoken message default to plaintext title and description #80706, the current behavior announces the entire HTML contents of the notice banner, including any actions that it contains. So the spoken message for the default Notice Storybook story would be "Notice Title Description text with details about this notification. Primary button Secondary button Link". The lack of any punctuation to abbreviate the spoken content and the inclusion of all details (e.g. actions) may make the announcement difficult to understand.
Related guidance:
The most important thing to know about the alert role is that it's for content that is dynamically displayed, not for content that appears on page load. [...] For example, if a page loads with multiple visible alerts scattered throughout, the alert role should not be used, as the messages were not dynamically triggered.
https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Roles/alert_role
What is your proposed solution?
Move the built-in speak functionality from the Notice component to a level of abstraction appropriate for the expected interaction of dynamic notice content, e.g. the editor notices region as mentioned in #80706 (comment) .
Needs decision: This cannot be implemented until settling on a proposed direction for where the live announcements should happen.
Activity
joedolson commentedon Sep 9, 2026
This will probably also need an audit of every usage of the Notice component to ensure that notices are spoken appropriately when needed.
But I agree that this naive implementation is flawed: the messages should be explicitly defined, so that they contain all the relevant content and punctuation to be understandable. There are also specific cases where a notice should not be announced - if focus is moved to the notice, then it should not also be announced. I'm not sure whether there are examples of that use case, but it would probably be better to allow for it.
See #9442, #15708, etc.
aduth commentedon Sep 9, 2026
It's worth noting that while the issue is directed at the
@wordpress/uicomponent, the specific implementation details were presumably inherited from the@wordpress/componentsimplementation that has the same behavior. I raise this to clarify a few points:@wordpress/uiimplementation@wordpress/componentsinherently lives at a higher level of abstraction and this may be more appropriate there than it is in@wordpress/ui(see Design System: Support for admin redesign #71196 and design system introduction documentation for more of the context around this)@wordpress/componentsimplementation, but as there's a desire to start adopting the new implementation (example), we should plan to account for this in whatever new usage is introducedsimison commentedon Sep 10, 2026
What if we removed the behaviour that automatically announces and uses the description, but left the API in place? It would then become a documented convenience feature which folks can opt into by just providing
spokenMessage.politenesscould then continue to get set automatically depending on Noticeintent.Not sure if there's value in having the API instead of just allowing consumers to define
role="alert"etc though.ciampo commentedon Sep 10, 2026
To me, there's a wider conversation to have about whether "plain" (ie not tied to Gutenberg/WordPress app) UI components should announce updates to assistive technology.
I believe the answer should be "yes" (TBD if opt-in or opt-out).
Separately, but as important, we should make sure that components performing the announcement do it in the same way, and with a consistent APIs. We currently have:
speak()internal utility vs internal base-ui implementationaduth commentedon Sep 10, 2026
For another related parallel to BaseUI, it appears that the implementation of
Toast.Viewportis somewhat similar to ideas I've tossed around in the original issue and in #80706: It's the container element that handles announcements of new content, where each new spoken message is derived from the plaintext title and description. The idea of deriving plaintext content from the individual feedback component is similar to what I was exploring in #80706. And a container component is similar to what we have with@wordpress/noticescomponents. Taking this approach could help avoid some of the issues of working with an explicitspokenMessage.With an explicit
spokenMessage, there's a challenge in whether it's required or not, particularly in context of this issue in highlighting that not all notices should have spoken announcements:spokenMessage={ false }to support notices without accompanying spoken message.aduth commentedon Sep 14, 2026
Here's a proposal:
NoticeNotice.Listcomponent provides both visual layout and to a live region container for notice announcement content.@wordpress/uiNoticeListin@wordpress/components, it is compositional: children areNotice.Root, not anoticesprop@wordpress/noticesimplementation can switch fromNoticeListtoNotice.Listinternally and handle data store interactionsNotice.Listrenders its own live region container whose content is populated by context-registered title and description of descendent notices, something of a hybrid between BaseUI'sToast.Viewportand UI: Update Notice spoken message default to plaintext title and description #80706useAnnouncementhook orLiveRegioninternal abstraction. We may not need this for an initial implementation.ciampo commentedon Sep 14, 2026
Keeping announcement behavior in
@wordpress/uithrough composition makes sense to me.Notice.Listseems like a reasonable place for it.In any case, I'd still like to stay close to Base UI's approach where possible. Reusing Toast directly may require overriding too much of its interaction model, since our notices also cover persistent banners and inline messages. A first-party implementation seems reasonable for that broader scope. We'd need to maintain it and keep it aligned with Base UI's approach in order to offer a consistent experience for the
@wordpress/uipackage.We should also verify our own use cases with screen readers, especially initial content, dynamically added notices, and announcements while focus is inside the list. Base UI's toast behavior is useful guidance, but those cases may need different decisions for notices.
And we definitely need to discuss / decide exactly what to do around snackbards, since that sounds like an almost perfect fit for the base ui
Toastcomponent?ciampo commentedon Oct 16, 2026
This issue is technically addressed by #82737; should we repurpose it to official include remaining
Notice.Listwork, or close it and create a new issue?aduth commentedon Oct 16, 2026
Yes, a new issue makes sense. I'll create one.
aduth commentedon Oct 16, 2026
Follow-up issue at #84941