Repository navigation
UI: Remove automatic Notice announcements - #82737
Conversation
🤖 PR meta 🤖📦 Bundle sizeSize Change: -564 B (-0.01%) Total Size: 8.22 MB 📦 View Changed
⚡ PerformanceShow the resultsClient side metrics exclude the server response time. front-end-block-theme
front-end-classic-theme
media-processing
media-upload
post-editor
site-editor
|
|
To me it would make sense to add Storybook documentation or note with |
Rename the per-notice stamp from `id` to `noticeId`. It is a sequence number rather than an identity, and `id` would have become a real DOM attribute the day `Notice.Root` is handed rest props. Say why only the toast announces, and drop the comparison with `Notice.Root`'s own announcement: WordPress/gutenberg#82737 proposes removing that, so the comparison would describe a mechanism a reader cannot reach. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lo29yrft9KqShYK3p1wQe6
* Protect notices: back the notice component with the @wordpress/ui Notice The hand-rolled chassis — an icon switch, a message div and a dismiss button over a dark banner — becomes `Notice.Root` with a `Notice.Description` and a `Notice.CloseIcon`. The public props are unchanged, so all three call sites keep working: `type` picks the intent, `message` fills the description, `dismissable` draws the close control, and `duration` keeps its own timeout. `type="warning"` now reaches an intent of its own. The old switch had no case for it, so the fix-threat modal's inactive-extension warning fell through to the info icon over the default chassis. Only the floating toast passes a `spokenMessage`. It appears without a focus change and no call site wraps it in a live region; the other two sit inside a modal that is announced when it opens. The stylesheet keeps the floating placement, the info notice's bottom margin and the stacking context, and loses everything that painted the old chassis. `container-type: normal` is new: `Notice.Root` sets `container-type: inline-size`, and a size-contained child reports no width to the shrink-to-fit fixed box, which collapsed the toast to 26px. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: keep the notice silent and its dismiss label The Protect e2e suite failed on both counts, and both are this PR's doing. `spokenMessage` defaulted the toast into `speak()`, which copies the message into `#a11y-speak-polite` — so `getByText( 'Changes saved' )` matched two nodes and Playwright's strict mode rejected it. The legacy notice never announced and no call site sits in a live region, so this restores that. Announcing a toast is a real improvement, but it belongs in its own change, applied consistently. `Notice.CloseIcon`'s default label is "Dismiss", which renamed the control the suite clicks. The existing translated string is passed through instead, so the accessible name users already have survives the chassis swap. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: let the toast announce, and follow the three review notes `speak()` keeps its own live region, so whether a call site sits in one was never the right test — the reason the previous commit gave was wrong. The toast reports an async result with no focus change, which is what `speak()` is for, so it announces again; the two modal notices stay quiet, since their dialog is read when it opens. That is what broke the e2e suite: `speak()` copies the message into `#a11y-speak-polite`, so `getByText( 'Changes saved' )` matches twice. Verified in a browser that the notice is the earlier of the two, and scoped the assertion to it. Also: capitalise the changelog entry after its prefix and drop the repeated word, and add `warning` to the component README's list of types, which this change makes a real intent. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: never hand a JSX message to the announcer `Notice.Root` renders `spokenMessage` to a string during its own render. When the message holds a component with hooks — every error notice interpolates a `Link` — that component's hooks land in `Notice.Root`'s hook list, and the `useEffect` on the next line reads a mismatched slot and throws. React then unmounts the whole Protect dashboard, so any failed request blanked the page. `safeRenderToString`'s try/catch does not help: the throw comes from the hook after it. Only a plain string is announced now, which covers the saved and saving toasts. Announcing errors needs a spoken string carried alongside the JSX; that is worth doing separately. The same trap is recorded in `packages/newsletter/_inc/subscribers/components/modals/add-subscribers-modal.tsx`. Two follow-ups from the same review: the e2e assertion is scoped to the app root, because `speak()` leaves its text in the live region after the notice goes and the helper runs seven times; and `NoticeState.type` gains `warning`, which the component and README already offer. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: bundle the two packages the close control pulls in `Notice.CloseIcon` reaches `@wordpress/theme` and `@wordpress/private-apis` through `IconButton` and its tooltip, so the build started externalising them to the `wp-theme` and `wp-private-apis` script handles. Protect registers no shim for those, and WordPress refuses to enqueue a bundle with an unmet dependency — the admin page would render empty wherever core does not supply them. They are bundled instead, which is what the Jetpack plugin's own admin bundles do for the same reason. Verified by rebuilding: both handles are gone from `build/index.asset.php`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: correct a comment the e2e scoping outdated The Firewall block still said the "Changes saved" assertion stays page-scoped on purpose. It does not any more. The changelog entry becomes `minor`, matching the same migration for the Jetpack plugin in #52015: every Protect notice is restyled, one turns amber, and the toasts start announcing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: announce error notices to screen readers The announcement was derived from the message, and only a plain string was ever handed to `Notice.Root` — anything else corrupts its hook order. `showErrorNotice` always builds JSX, because it interpolates a support link, so failed saves stayed silent while "Changes saved." did not. Carry the announcement in the notice state instead: `showErrorNotice` sets `spokenMessage` from the plain string it already receives, and the component prefers it over the message. It still resolves to null rather than undefined, so `Notice.Root` never falls back to rendering children. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: speak the whole error, and speak it every time The announcement dropped the "Please try again or contact support." sentence because it only exists with interpolation tags. Stripping the tags off the translated string gives the plain sentence at no translation cost, so the announcement now carries what the notice says. Each notice also gets an identity, and the toast is keyed on it. Without that a repeat of the same error re-renders with identical props, the announcing effect never re-runs, and the second failure is silent. `use-fixers-query` is the path that reaches it: its polling error fires the same message with no other notice in between. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: re-announce without stealing focus Keying the toast on the notice id remounted it, which destroyed the node focus was in: a keyboard user reading the error, with focus on its support link or dismiss button, lost focus to the body when the next notice arrived. In an accessibility change that is not a fair trade. The announcement now varies instead of the element. A repeat alternates a trailing non-breaking space — the same device `@wordpress/a11y` uses for this — so the announcing effect re-runs while the element stays mounted. Two identical errors in a row take consecutive ids, so the parity always flips between them; anything that arrives in between announces on its own text. Two more from the same review: the provider stamps the id, so no future writer can forget it and silently break the repeat, and the tag strip no longer names `supportLink`, so renaming the tag cannot silently stop it working. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: announce per notice, not per distinct message The parity nonce was wrong. `Notice.Root` announces when the value it is handed changes, so the previous revision alternated a trailing space keyed on the notice id — but the id advances once per stored notice while the announcement happens once per committed render. Any event that stores an even number of notices in one commit leaves the parity where it was, and the repeat is silent again. `use-fixers-query` is exactly that shape: one instance per threat row plus the modals, all sharing a query, all raising the same error in one commit. So the announcement moves here, keyed on the notice, and `Notice.Root` is handed `null` unconditionally — it never renders a message to a string now, which is what the crash came from. `speak()` handles an identical repeat itself. Two more from the same review: the id is stamped outside the state updater, and the component README documents `spokenMessage` and `id`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: tie the dismiss timer to the notice as well `duration` keyed its timer on the message, so a second identical success inherited whatever was left of the first one's 7.5 seconds instead of starting again. The notice's id is what says "this is a different notice", and the announcement already uses it. Also from review: the mid-render rationale is stated once, on the prop that carries it, and the new dependency is filed in alphabetical order. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: drop a comment's claim of a nonexistent dialog The comment above `spokenMessage` said the modal notices are read when their dialog opens. Protect has no dialog: `components/modal/index.jsx` renders a plain `<div>` with no `role="dialog"`, no `aria-modal` and no focus move into the window, so nothing reads those notices. Keep the half that is true and load-bearing -- why the prop takes strings only -- and drop the rest. Also cut the `requestMap` comment in the plugin's webpack config to the live constraint. The mechanism is already spelled out in three other configs, and a fourth copy drifts. The code is unchanged. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: keep the joint-bundling constraint on the requestMap The pair has to be bundled together: `@wordpress/theme` opts in and calls `lock()` at module scope, and `@wordpress/private-apis` keeps its consent map per module instance. Bundle one and externalize the other and the two maps diverge, which surfaces at runtime as "Cannot unlock an object that was not locked before" or a duplicate opt-in, with nothing pointing back at the build config. The full account lives in #48173. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: point at the requestMap rationale instead of restating it Three other webpack configs already carry this reasoning in full. A fourth copy is the one outcome that guarantees they drift, so this leaves the constraint and the reference and nothing else. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: name the tag the spoken message strips CodeQL reads a `<[^>]+>` strip as HTML sanitization and files it high severity (js/incomplete-multi-character-sanitization). Nothing here reaches innerHTML — the result goes to `speak()`, which writes textContent — but the generic form buys nothing over naming the one placeholder the string actually carries, and `createInterpolateElement` breaks just as loudly if that name ever changes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: answer the review on the announcement Rename the per-notice stamp from `id` to `noticeId`. It is a sequence number rather than an identity, and `id` would have become a real DOM attribute the day `Notice.Root` is handed rest props. Say why only the toast announces, and drop the comparison with `Notice.Root`'s own announcement: WordPress/gutenberg#82737 proposes removing that, so the comparison would describe a mechanism a reader cannot reach. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lo29yrft9KqShYK3p1wQe6 * Protect notices: announce a failing fixers poll once per streak Every failed poll produces a new Error object, so keying the effect on it re-announced the same message assertively every five seconds for as long as the poll kept failing. Key on `isError` instead: one announcement per streak, and another only once a success has come in between. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lo29yrft9KqShYK3p1wQe6 --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: Douglas <douglas.henri@automattic.com>
* Protect notices: back the notice component with the @wordpress/ui Notice The hand-rolled chassis — an icon switch, a message div and a dismiss button over a dark banner — becomes `Notice.Root` with a `Notice.Description` and a `Notice.CloseIcon`. The public props are unchanged, so all three call sites keep working: `type` picks the intent, `message` fills the description, `dismissable` draws the close control, and `duration` keeps its own timeout. `type="warning"` now reaches an intent of its own. The old switch had no case for it, so the fix-threat modal's inactive-extension warning fell through to the info icon over the default chassis. Only the floating toast passes a `spokenMessage`. It appears without a focus change and no call site wraps it in a live region; the other two sit inside a modal that is announced when it opens. The stylesheet keeps the floating placement, the info notice's bottom margin and the stacking context, and loses everything that painted the old chassis. `container-type: normal` is new: `Notice.Root` sets `container-type: inline-size`, and a size-contained child reports no width to the shrink-to-fit fixed box, which collapsed the toast to 26px. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: keep the notice silent and its dismiss label The Protect e2e suite failed on both counts, and both are this PR's doing. `spokenMessage` defaulted the toast into `speak()`, which copies the message into `#a11y-speak-polite` — so `getByText( 'Changes saved' )` matched two nodes and Playwright's strict mode rejected it. The legacy notice never announced and no call site sits in a live region, so this restores that. Announcing a toast is a real improvement, but it belongs in its own change, applied consistently. `Notice.CloseIcon`'s default label is "Dismiss", which renamed the control the suite clicks. The existing translated string is passed through instead, so the accessible name users already have survives the chassis swap. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: let the toast announce, and follow the three review notes `speak()` keeps its own live region, so whether a call site sits in one was never the right test — the reason the previous commit gave was wrong. The toast reports an async result with no focus change, which is what `speak()` is for, so it announces again; the two modal notices stay quiet, since their dialog is read when it opens. That is what broke the e2e suite: `speak()` copies the message into `#a11y-speak-polite`, so `getByText( 'Changes saved' )` matches twice. Verified in a browser that the notice is the earlier of the two, and scoped the assertion to it. Also: capitalise the changelog entry after its prefix and drop the repeated word, and add `warning` to the component README's list of types, which this change makes a real intent. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: never hand a JSX message to the announcer `Notice.Root` renders `spokenMessage` to a string during its own render. When the message holds a component with hooks — every error notice interpolates a `Link` — that component's hooks land in `Notice.Root`'s hook list, and the `useEffect` on the next line reads a mismatched slot and throws. React then unmounts the whole Protect dashboard, so any failed request blanked the page. `safeRenderToString`'s try/catch does not help: the throw comes from the hook after it. Only a plain string is announced now, which covers the saved and saving toasts. Announcing errors needs a spoken string carried alongside the JSX; that is worth doing separately. The same trap is recorded in `packages/newsletter/_inc/subscribers/components/modals/add-subscribers-modal.tsx`. Two follow-ups from the same review: the e2e assertion is scoped to the app root, because `speak()` leaves its text in the live region after the notice goes and the helper runs seven times; and `NoticeState.type` gains `warning`, which the component and README already offer. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: bundle the two packages the close control pulls in `Notice.CloseIcon` reaches `@wordpress/theme` and `@wordpress/private-apis` through `IconButton` and its tooltip, so the build started externalising them to the `wp-theme` and `wp-private-apis` script handles. Protect registers no shim for those, and WordPress refuses to enqueue a bundle with an unmet dependency — the admin page would render empty wherever core does not supply them. They are bundled instead, which is what the Jetpack plugin's own admin bundles do for the same reason. Verified by rebuilding: both handles are gone from `build/index.asset.php`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: correct a comment the e2e scoping outdated The Firewall block still said the "Changes saved" assertion stays page-scoped on purpose. It does not any more. The changelog entry becomes `minor`, matching the same migration for the Jetpack plugin in #52015: every Protect notice is restyled, one turns amber, and the toasts start announcing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: announce error notices to screen readers The announcement was derived from the message, and only a plain string was ever handed to `Notice.Root` — anything else corrupts its hook order. `showErrorNotice` always builds JSX, because it interpolates a support link, so failed saves stayed silent while "Changes saved." did not. Carry the announcement in the notice state instead: `showErrorNotice` sets `spokenMessage` from the plain string it already receives, and the component prefers it over the message. It still resolves to null rather than undefined, so `Notice.Root` never falls back to rendering children. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: speak the whole error, and speak it every time The announcement dropped the "Please try again or contact support." sentence because it only exists with interpolation tags. Stripping the tags off the translated string gives the plain sentence at no translation cost, so the announcement now carries what the notice says. Each notice also gets an identity, and the toast is keyed on it. Without that a repeat of the same error re-renders with identical props, the announcing effect never re-runs, and the second failure is silent. `use-fixers-query` is the path that reaches it: its polling error fires the same message with no other notice in between. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: re-announce without stealing focus Keying the toast on the notice id remounted it, which destroyed the node focus was in: a keyboard user reading the error, with focus on its support link or dismiss button, lost focus to the body when the next notice arrived. In an accessibility change that is not a fair trade. The announcement now varies instead of the element. A repeat alternates a trailing non-breaking space — the same device `@wordpress/a11y` uses for this — so the announcing effect re-runs while the element stays mounted. Two identical errors in a row take consecutive ids, so the parity always flips between them; anything that arrives in between announces on its own text. Two more from the same review: the provider stamps the id, so no future writer can forget it and silently break the repeat, and the tag strip no longer names `supportLink`, so renaming the tag cannot silently stop it working. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: announce per notice, not per distinct message The parity nonce was wrong. `Notice.Root` announces when the value it is handed changes, so the previous revision alternated a trailing space keyed on the notice id — but the id advances once per stored notice while the announcement happens once per committed render. Any event that stores an even number of notices in one commit leaves the parity where it was, and the repeat is silent again. `use-fixers-query` is exactly that shape: one instance per threat row plus the modals, all sharing a query, all raising the same error in one commit. So the announcement moves here, keyed on the notice, and `Notice.Root` is handed `null` unconditionally — it never renders a message to a string now, which is what the crash came from. `speak()` handles an identical repeat itself. Two more from the same review: the id is stamped outside the state updater, and the component README documents `spokenMessage` and `id`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: tie the dismiss timer to the notice as well `duration` keyed its timer on the message, so a second identical success inherited whatever was left of the first one's 7.5 seconds instead of starting again. The notice's id is what says "this is a different notice", and the announcement already uses it. Also from review: the mid-render rationale is stated once, on the prop that carries it, and the new dependency is filed in alphabetical order. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: drop a comment's claim of a nonexistent dialog The comment above `spokenMessage` said the modal notices are read when their dialog opens. Protect has no dialog: `components/modal/index.jsx` renders a plain `<div>` with no `role="dialog"`, no `aria-modal` and no focus move into the window, so nothing reads those notices. Keep the half that is true and load-bearing -- why the prop takes strings only -- and drop the rest. Also cut the `requestMap` comment in the plugin's webpack config to the live constraint. The mechanism is already spelled out in three other configs, and a fourth copy drifts. The code is unchanged. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: keep the joint-bundling constraint on the requestMap The pair has to be bundled together: `@wordpress/theme` opts in and calls `lock()` at module scope, and `@wordpress/private-apis` keeps its consent map per module instance. Bundle one and externalize the other and the two maps diverge, which surfaces at runtime as "Cannot unlock an object that was not locked before" or a duplicate opt-in, with nothing pointing back at the build config. The full account lives in #48173. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: point at the requestMap rationale instead of restating it Three other webpack configs already carry this reasoning in full. A fourth copy is the one outcome that guarantees they drift, so this leaves the constraint and the reference and nothing else. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: name the tag the spoken message strips CodeQL reads a `<[^>]+>` strip as HTML sanitization and files it high severity (js/incomplete-multi-character-sanitization). Nothing here reaches innerHTML — the result goes to `speak()`, which writes textContent — but the generic form buys nothing over naming the one placeholder the string actually carries, and `createInterpolateElement` breaks just as loudly if that name ever changes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: answer the review on the announcement Rename the per-notice stamp from `id` to `noticeId`. It is a sequence number rather than an identity, and `id` would have become a real DOM attribute the day `Notice.Root` is handed rest props. Say why only the toast announces, and drop the comparison with `Notice.Root`'s own announcement: WordPress/gutenberg#82737 proposes removing that, so the comparison would describe a mechanism a reader cannot reach. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lo29yrft9KqShYK3p1wQe6 * Protect notices: announce a failing fixers poll once per streak Every failed poll produces a new Error object, so keying the effect on it re-announced the same message assertively every five seconds for as long as the poll kept failing. Key on `isError` instead: one announcement per streak, and another only once a success has come in between. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lo29yrft9KqShYK3p1wQe6 --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: Douglas <douglas.henri@automattic.com> Committed via a GitHub action: https://github.com/Automattic/jetpack/actions/runs/34654909076 Upstream-Ref: Automattic/jetpack@d121e06
* Protect notices: back the notice component with the @wordpress/ui Notice The hand-rolled chassis — an icon switch, a message div and a dismiss button over a dark banner — becomes `Notice.Root` with a `Notice.Description` and a `Notice.CloseIcon`. The public props are unchanged, so all three call sites keep working: `type` picks the intent, `message` fills the description, `dismissable` draws the close control, and `duration` keeps its own timeout. `type="warning"` now reaches an intent of its own. The old switch had no case for it, so the fix-threat modal's inactive-extension warning fell through to the info icon over the default chassis. Only the floating toast passes a `spokenMessage`. It appears without a focus change and no call site wraps it in a live region; the other two sit inside a modal that is announced when it opens. The stylesheet keeps the floating placement, the info notice's bottom margin and the stacking context, and loses everything that painted the old chassis. `container-type: normal` is new: `Notice.Root` sets `container-type: inline-size`, and a size-contained child reports no width to the shrink-to-fit fixed box, which collapsed the toast to 26px. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: keep the notice silent and its dismiss label The Protect e2e suite failed on both counts, and both are this PR's doing. `spokenMessage` defaulted the toast into `speak()`, which copies the message into `#a11y-speak-polite` — so `getByText( 'Changes saved' )` matched two nodes and Playwright's strict mode rejected it. The legacy notice never announced and no call site sits in a live region, so this restores that. Announcing a toast is a real improvement, but it belongs in its own change, applied consistently. `Notice.CloseIcon`'s default label is "Dismiss", which renamed the control the suite clicks. The existing translated string is passed through instead, so the accessible name users already have survives the chassis swap. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: let the toast announce, and follow the three review notes `speak()` keeps its own live region, so whether a call site sits in one was never the right test — the reason the previous commit gave was wrong. The toast reports an async result with no focus change, which is what `speak()` is for, so it announces again; the two modal notices stay quiet, since their dialog is read when it opens. That is what broke the e2e suite: `speak()` copies the message into `#a11y-speak-polite`, so `getByText( 'Changes saved' )` matches twice. Verified in a browser that the notice is the earlier of the two, and scoped the assertion to it. Also: capitalise the changelog entry after its prefix and drop the repeated word, and add `warning` to the component README's list of types, which this change makes a real intent. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: never hand a JSX message to the announcer `Notice.Root` renders `spokenMessage` to a string during its own render. When the message holds a component with hooks — every error notice interpolates a `Link` — that component's hooks land in `Notice.Root`'s hook list, and the `useEffect` on the next line reads a mismatched slot and throws. React then unmounts the whole Protect dashboard, so any failed request blanked the page. `safeRenderToString`'s try/catch does not help: the throw comes from the hook after it. Only a plain string is announced now, which covers the saved and saving toasts. Announcing errors needs a spoken string carried alongside the JSX; that is worth doing separately. The same trap is recorded in `packages/newsletter/_inc/subscribers/components/modals/add-subscribers-modal.tsx`. Two follow-ups from the same review: the e2e assertion is scoped to the app root, because `speak()` leaves its text in the live region after the notice goes and the helper runs seven times; and `NoticeState.type` gains `warning`, which the component and README already offer. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: bundle the two packages the close control pulls in `Notice.CloseIcon` reaches `@wordpress/theme` and `@wordpress/private-apis` through `IconButton` and its tooltip, so the build started externalising them to the `wp-theme` and `wp-private-apis` script handles. Protect registers no shim for those, and WordPress refuses to enqueue a bundle with an unmet dependency — the admin page would render empty wherever core does not supply them. They are bundled instead, which is what the Jetpack plugin's own admin bundles do for the same reason. Verified by rebuilding: both handles are gone from `build/index.asset.php`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: correct a comment the e2e scoping outdated The Firewall block still said the "Changes saved" assertion stays page-scoped on purpose. It does not any more. The changelog entry becomes `minor`, matching the same migration for the Jetpack plugin in #52015: every Protect notice is restyled, one turns amber, and the toasts start announcing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: announce error notices to screen readers The announcement was derived from the message, and only a plain string was ever handed to `Notice.Root` — anything else corrupts its hook order. `showErrorNotice` always builds JSX, because it interpolates a support link, so failed saves stayed silent while "Changes saved." did not. Carry the announcement in the notice state instead: `showErrorNotice` sets `spokenMessage` from the plain string it already receives, and the component prefers it over the message. It still resolves to null rather than undefined, so `Notice.Root` never falls back to rendering children. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: speak the whole error, and speak it every time The announcement dropped the "Please try again or contact support." sentence because it only exists with interpolation tags. Stripping the tags off the translated string gives the plain sentence at no translation cost, so the announcement now carries what the notice says. Each notice also gets an identity, and the toast is keyed on it. Without that a repeat of the same error re-renders with identical props, the announcing effect never re-runs, and the second failure is silent. `use-fixers-query` is the path that reaches it: its polling error fires the same message with no other notice in between. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: re-announce without stealing focus Keying the toast on the notice id remounted it, which destroyed the node focus was in: a keyboard user reading the error, with focus on its support link or dismiss button, lost focus to the body when the next notice arrived. In an accessibility change that is not a fair trade. The announcement now varies instead of the element. A repeat alternates a trailing non-breaking space — the same device `@wordpress/a11y` uses for this — so the announcing effect re-runs while the element stays mounted. Two identical errors in a row take consecutive ids, so the parity always flips between them; anything that arrives in between announces on its own text. Two more from the same review: the provider stamps the id, so no future writer can forget it and silently break the repeat, and the tag strip no longer names `supportLink`, so renaming the tag cannot silently stop it working. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: announce per notice, not per distinct message The parity nonce was wrong. `Notice.Root` announces when the value it is handed changes, so the previous revision alternated a trailing space keyed on the notice id — but the id advances once per stored notice while the announcement happens once per committed render. Any event that stores an even number of notices in one commit leaves the parity where it was, and the repeat is silent again. `use-fixers-query` is exactly that shape: one instance per threat row plus the modals, all sharing a query, all raising the same error in one commit. So the announcement moves here, keyed on the notice, and `Notice.Root` is handed `null` unconditionally — it never renders a message to a string now, which is what the crash came from. `speak()` handles an identical repeat itself. Two more from the same review: the id is stamped outside the state updater, and the component README documents `spokenMessage` and `id`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: tie the dismiss timer to the notice as well `duration` keyed its timer on the message, so a second identical success inherited whatever was left of the first one's 7.5 seconds instead of starting again. The notice's id is what says "this is a different notice", and the announcement already uses it. Also from review: the mid-render rationale is stated once, on the prop that carries it, and the new dependency is filed in alphabetical order. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: drop a comment's claim of a nonexistent dialog The comment above `spokenMessage` said the modal notices are read when their dialog opens. Protect has no dialog: `components/modal/index.jsx` renders a plain `<div>` with no `role="dialog"`, no `aria-modal` and no focus move into the window, so nothing reads those notices. Keep the half that is true and load-bearing -- why the prop takes strings only -- and drop the rest. Also cut the `requestMap` comment in the plugin's webpack config to the live constraint. The mechanism is already spelled out in three other configs, and a fourth copy drifts. The code is unchanged. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: keep the joint-bundling constraint on the requestMap The pair has to be bundled together: `@wordpress/theme` opts in and calls `lock()` at module scope, and `@wordpress/private-apis` keeps its consent map per module instance. Bundle one and externalize the other and the two maps diverge, which surfaces at runtime as "Cannot unlock an object that was not locked before" or a duplicate opt-in, with nothing pointing back at the build config. The full account lives in #48173. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: point at the requestMap rationale instead of restating it Three other webpack configs already carry this reasoning in full. A fourth copy is the one outcome that guarantees they drift, so this leaves the constraint and the reference and nothing else. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: name the tag the spoken message strips CodeQL reads a `<[^>]+>` strip as HTML sanitization and files it high severity (js/incomplete-multi-character-sanitization). Nothing here reaches innerHTML — the result goes to `speak()`, which writes textContent — but the generic form buys nothing over naming the one placeholder the string actually carries, and `createInterpolateElement` breaks just as loudly if that name ever changes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWVs5oUDimen1FeGJhJAkx * Protect notices: answer the review on the announcement Rename the per-notice stamp from `id` to `noticeId`. It is a sequence number rather than an identity, and `id` would have become a real DOM attribute the day `Notice.Root` is handed rest props. Say why only the toast announces, and drop the comparison with `Notice.Root`'s own announcement: WordPress/gutenberg#82737 proposes removing that, so the comparison would describe a mechanism a reader cannot reach. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lo29yrft9KqShYK3p1wQe6 * Protect notices: announce a failing fixers poll once per streak Every failed poll produces a new Error object, so keying the effect on it re-announced the same message assertively every five seconds for as long as the poll kept failing. Key on `isError` instead: one announcement per streak, and another only once a success has come in between. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lo29yrft9KqShYK3p1wQe6 --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: Douglas <douglas.henri@automattic.com> Committed via a GitHub action: https://github.com/Automattic/jetpack/actions/runs/34654909076 Upstream-Ref: Automattic/jetpack@d121e06
a839c12 to
1de9984
Compare
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
@simison I added Storybook migration guidance with static, |
mirka
left a comment
There was a problem hiding this comment.
I'm getting conflicting information about the reliability of role="alert".
Do not try to dynamically add/generate an element with
role="alert"that is already populated with the alert message you want announced - this generally does not lead to an announcement, as it is not a content change. (MDN)
Dynamically rendered alerts are automatically announced by most screen readers (APG)
Browser support seems acceptable, according to this page.
Which leads me to the question of what our "suggested pattern" is going to be. role="alert" with the content pre-populated might be fine in terms of browser/SR support, but only for when the notice is serious enough to be an alert. The widget-frame one, for example, is questionable in that regard to me. And of course many other usages are not even going to be suitable for role="alert", and then we can't just put aria-live="polite" on a pre-populated Notice element and be done with it. I'm starting to wonder if our suggested pattern should actually be based on speak(). Perhaps especially, since we'll likely want to announce the Notice.Title as well. Thoughts?
e7864bd to
684d482
Compare
@mirka this could be probably the best solution, at least for now, while we decide exactly what behavior should be implemented by For now, I updated examples and error boundaries to use |
mirka
left a comment
There was a problem hiding this comment.
Just for posterity, I want to explicit note that routes/connectors-home/stage.tsx also has a wp-ui Notice instance, but was determined not suitable for an announcement.
| } | ||
|
|
||
| componentDidCatch( error, errorInfo ) { | ||
| speak( |
There was a problem hiding this comment.
This is a third translated string that restates Title + Description. Can we hoist those __() calls and speak( `${ title }. ${ description }` ) to prevent drift and unnecessary translations? Same for the other files.
There was a problem hiding this comment.
Good point. I updated all three error boundaries to reuse the translated title and description for the announcement.
|
Hey 👋 I wanted to give you a heads-up since this pull request is affected by recent validation changes for changelog files. #83043 adds additional validation for changelog files. You'll note that this pull request is currently failing a "Required changes from trunk" check. What you'll need to do: You will need to either rebase or merge the latest code from |
b2e91f1 to
d01ac37
Compare
|
I'd strongly recommend sticking to just a single route for spoken notifications, so that any later changes to the mechanism can be modified globally.
|
* UI: Remove automatic Notice announcements * UI: Add Notice announcement changelog * Packages: Add Notice consumer changelogs * UI: Strengthen Notice announcement regression * Notice: Document announcements and test message-only alerts * Notice: Remove redundant announcement tests * Notice: Let consumers announce errors explicitly * Widget Dashboard: Add a11y TypeScript project references * Packages: Move Notice changelogs to Unreleased * Notice: Reuse translated error text for announcements --- Co-authored-by: ciampo <mciampini@git.wordpress.org> Co-authored-by: mirka <0mirka00@git.wordpress.org> Co-authored-by: simison <simison@git.wordpress.org> Co-authored-by: aduth <aduth@git.wordpress.org>
This updates the pinned commit hash of the Gutenberg repository from 954fe7f9e04631c41aec4552acd627a7203a2aad to 7b95ee96b54de2e35886971ccf7eb449c324c830 (version 24.2.0). A full list of changes included in this commit can be found on GitHub: WordPress/gutenberg@954fe7f...7b95ee9 - useServerSideRender: parse messages from caught errors (WordPress/gutenberg#83365) - Docs: Fix published Vitest migration-guide links (WordPress/gutenberg#83449) - Fix: Whitespace changes are not shown in the Resolve Block diff. (WordPress/gutenberg#82397) - Editor: Use SearchableSelect for the post author field (WordPress/gutenberg#83323) - Docs: Note that block attributes and global styles values are untrusted at render time (WordPress/gutenberg#83473) - RichText: Remove dead exports and consolidate deprecations (WordPress/gutenberg#83461) - Inserter: Manage roving tab index to skip re-rendering every item (WordPress/gutenberg#83437) - SearchableSelectControl: Add to @wordpress/ui (WordPress/gutenberg#80979) - Try: Bolder "B" icon (WordPress/gutenberg#83321) - Ignore composer vendor files from top-level gitignore. (WordPress/gutenberg#22283) - Tests: Add floating notes e2e coverage (WordPress/gutenberg#83477) - Block Editor: Check the inserter's fallback containers unmemoized (WordPress/gutenberg#83446) - Packages: Update Ariakit to 0.4.40 (WordPress/gutenberg#83278) - Tests: Enforce per-call Vitest console expectations (WordPress/gutenberg#83095) - Theme: Fix virtual modules, root styles, and seed validation (WordPress/gutenberg#83355) - DataViews: Fix README to describe sort() as receiving field values, not items (WordPress/gutenberg#83483) - Combobox: Label popup dialogs in stories (WordPress/gutenberg#83476) - Block editor: Isolate mutable test fixtures (WordPress/gutenberg#83098) - Blocks: Isolate registration state in tests (WordPress/gutenberg#83099) - UI: Remove automatic Notice announcements (WordPress/gutenberg#82737) - Text: Migrate Emotion styles to an SCSS Module (WordPress/gutenberg#82573) - Block library: Isolate order-sensitive test interactions (WordPress/gutenberg#83101) - Format Library: unify FormatEditProps to one type, move private types (WordPress/gutenberg#83487) - UI: Announce selected chips in SearchableChipSelect (WordPress/gutenberg#82863) - Card: Migrate from Emotion to SCSS modules (WordPress/gutenberg#82577) - Components: Deprecate the private Menu API (WordPress/gutenberg#82947) - CustomGradientPicker: Migrate control wrappers to an SCSS module (WordPress/gutenberg#82576) - Components: Isolate order-sensitive UI tests (WordPress/gutenberg#83103) - Tests: Isolate mutable configuration fixtures (WordPress/gutenberg#83104) - Core data: Finish deferred selection updates in RTC test (WordPress/gutenberg#83366) - Block editor: Wait for final keyboard link suggestions (WordPress/gutenberg#83489) - Data: Assert and silence resolution error in useSuspenseSelect test (WordPress/gutenberg#83491) - Tests: Isolate deprecation warning state (WordPress/gutenberg#83107) - UI: Align selection popup checkmarks with the first label line (WordPress/gutenberg#82942) - Tests: Resolve Browser Mode commands against the live iframe (WordPress/gutenberg#83495) - Ensure position type is a string (WordPress/gutenberg#83500) - MediaUpload: Fix console error when reopening Gallery media library (WordPress/gutenberg#76749) - Refactor stylelint config detection in lint-style.js (WordPress/gutenberg#79280) - Docs: Recommend UI Tabs for switching views (WordPress/gutenberg#83516) - Popover: Close non-modal popovers on iframe interaction (WordPress/gutenberg#83509) - Typography: List only the weights inside a variable font's range (WordPress/gutenberg#83128) - Style book: Add link to example text. (WordPress/gutenberg#83448) - Tests: Add Vitest Browser Mode failure artifacts (WordPress/gutenberg#83093) - Theme: Make JavaScript token fallback transforms syntax-aware (WordPress/gutenberg#83356) - Editor: Fix new posts being published with the `auto-draft` slug (WordPress/gutenberg#83518) - Editor: Gather the View group of the Options menu into submenus (WordPress/gutenberg#82976) - Tests: Fix PostCSS browser-externalized warnings in Vitest (WordPress/gutenberg#83091) - Tests: Shuffle test cases in CI (WordPress/gutenberg#83111) - Update Styles > Blocks description. (WordPress/gutenberg#83515) - Columns: Remove the column count slider (WordPress/gutenberg#83262) - BorderControl: Remove `%` from the border width units (WordPress/gutenberg#83492) - Fields: Fix AuthorView for users who can't edit users (WordPress/gutenberg#83498) - Update and add justify icons. (WordPress/gutenberg#83519) - RichText: Refactor useMarkPersistent, fix StrictMode mount mark (WordPress/gutenberg#83463) - Theme: Improve accessibility, API documentation, and compatibility checks (WordPress/gutenberg#83358) - Theme: Preserve global token references in Lightning CSS (WordPress/gutenberg#83359) - Tests: Migrate internal linting to Vitest and remove unused Jest dependencies (WordPress/gutenberg#83502) - Improve specificity of lightbox button selector (WordPress/gutenberg#70800) - TextControl: Use design system colors when disabled (WordPress/gutenberg#83307) - Fix: Image lightbox: overlay becomes unusable (can't close) when it isn't a direct child of `<body>` (WordPress/gutenberg#83480) - Notes: Extract note selection sync into useNoteSelection hook (WordPress/gutenberg#83528) - Block Parser: Document `\WP_Block_Parser::$stack` as a list (WordPress/gutenberg#82695) - CollapsibleCard: Scope the header focus ring to its own trigger (WordPress/gutenberg#81314) - Fix broken links in docs (WordPress/gutenberg#83545) - Icons: Use assertEqualHTML() in icons registry tests (WordPress/gutenberg#83544) - Editor: Merge adjacent revision inline diffs (WordPress/gutenberg#80579) - Date: Ignore trailing format backslash instead of printing undefined (WordPress/gutenberg#81528) - Block Supports: Add background-clip block support infrastructure (WordPress/gutenberg#77141) - Block Editor: Fix translator comments for block count announcements (WordPress/gutenberg#83555) - Paste: replace non-breaking spaces at the edges of text with regular spaces (WordPress/gutenberg#83464) - Media Editor: Fix pan drag flooding undo history after wheel zoom (WordPress/gutenberg#83558) - Rich text: fix iOS double tap selection, preventing focus capture under editable host (WordPress/gutenberg#81042) - Block editor: migrate state-control badges to UI Badge (WordPress/gutenberg#82608) - Gallery: Add Order By controls for static gallery, consolidate controls in settings sidebar (WordPress/gutenberg#83438) - Media editor: show an error when saving attachment details fails (WordPress/gutenberg#83560) - Position controls: Fix useSelect warning for selected state viewports (WordPress/gutenberg#83570) - Inserter: Use design system focus ring for previews (WordPress/gutenberg#83126) - Image: Fix lightbox using thumbnail aspect ratio instead of original image ratio (WordPress/gutenberg#79058) - Docs: Clarify @wordpress/ui icon color requirements (WordPress/gutenberg#83564) - docker compose -T if stdin is not a tty (WordPress/gutenberg#78374) - Storybook: Add new contributing page. (WordPress/gutenberg#83345) - Widget Primitives: Avoid Vite warnings for runtime widget modules (WordPress/gutenberg#83602) - Build: Update Vite to 8.3.1 and simplify Storybook tooling (WordPress/gutenberg#83569) - doc(wp-env) Change core branch from trunk to master in doc (WordPress/gutenberg#83566) - wp-build: Remove the unused boot, private-apis, and route optional peer dependencies (WordPress/gutenberg#83601) - CI: Check CHANGELOG presence for published tooling and config packages (WordPress/gutenberg#83577) - Tests: Enforce Vitest assertion coverage (WordPress/gutenberg#83572) - Icons: Update heading level icons for optical balance (WordPress/gutenberg#83268) - ESLint: Add allowUseWithCaution option to use-recommended-components (WordPress/gutenberg#83536) - Notes: Refactor floating board measurement (WordPress/gutenberg#83485) - Inserter: Stop re-rendering the block list on block selection change (WordPress/gutenberg#83284) - Paste: Give each pasted data-URI image unique filename to avoid upload collisions. (WordPress/gutenberg#79480) - Changelog validator: ignore markdown & configs d46223 (WordPress/gutenberg#83618) - Font Library: Use UI Menu for collection actions (WordPress/gutenberg#82965) - Storybook: Show prop descriptions in Canvas controls (WordPress/gutenberg#83581) - test: Link upstream warning fixes in config (WordPress/gutenberg#83632) - Storybook: Use one block-editor store module (WordPress/gutenberg#83636) - Tests: Use strict assertions synced from Core changeset 63934. (WordPress/gutenberg#83619) - Math: Store cell alignment in the MathML and polyfill alignment and overlines in Chromium (WordPress/gutenberg#83164) - Storybook: Reuse PostCSS browser resolver in smoke tests (WordPress/gutenberg#83635) - Editor: Use UI Menu for template options (WordPress/gutenberg#82964) - RTC: Add a EntitySyncManager interface in core-data (WordPress/gutenberg#83410) - Term Count: Add margin support (WordPress/gutenberg#83608) - Archives: Add minimum height support (WordPress/gutenberg#83573) - Media Editor: Stop the crop pixel snap from recording undo history (WordPress/gutenberg#83571) - Term Name: Add margin support (WordPress/gutenberg#83606) - Post Author Biography: Add text indent support (WordPress/gutenberg#83614) - Code: Add minimum width and height support (WordPress/gutenberg#83574) - Details: Add minimum width support (WordPress/gutenberg#83576) - Post Content: Add minimum width support (WordPress/gutenberg#83575) - Post Excerpt: Add minimum width and height support (WordPress/gutenberg#83578) - Post Title: Add minimum width and height support (WordPress/gutenberg#83600) - Footnotes: Add minimum width and height support (WordPress/gutenberg#83579) - Storybook: Place Notice announcements under Components (WordPress/gutenberg#83617) - InputControl: Darken the field border on hover (WordPress/gutenberg#83306) - npm: Switch from legacy-peer-deps to strict-peer-deps (WordPress/gutenberg#81029) - Term Name: Add minimum width and height support (WordPress/gutenberg#83599) - Columns: Allow dropping a column at the outer edges (WordPress/gutenberg#83274) - E2E: Pin the site title in the Interactivity API router specs and give the E2E Storybook build more heap. (WordPress/gutenberg#83474) - Heading: Add minimum width and height support (WordPress/gutenberg#83580) - Login/out: Add minimum width and height support (WordPress/gutenberg#83583) - Verse: Add minimum width support (WordPress/gutenberg#83609) - Video, Cover: Don't autoplay in the editor when reduced motion is preferred (WordPress/gutenberg#83337) - Media & Text: Lower the specificity of the content padding (WordPress/gutenberg#83563) - Pagination: Add padding, margin, and block gap support (WordPress/gutenberg#83743) - Fix peer dependency conflicts left in the lockfile (WordPress/gutenberg#83754) - Comments Pagination: Add padding, margin, and block gap support (WordPress/gutenberg#83744) - Term Count: Add minimum width and height support (WordPress/gutenberg#83596) - Read More: Add border style support (WordPress/gutenberg#83735) - Cover: Don't autoplay embedded background videos when reduced motion is preferred (WordPress/gutenberg#83452) - No Results: Add minimum width and height support (WordPress/gutenberg#83584) - RichText: Rename utils.jsx to utils.js (WordPress/gutenberg#83758) - Quote: Add minimum width support (WordPress/gutenberg#83592) - Upgrade typescript-eslint to v8.70.1 (WordPress/gutenberg#83760) - Tabs: Add minimum width support (WordPress/gutenberg#83595) - Site Tagline: Add minimum width and height support (WordPress/gutenberg#83589) - Heading: Add text indent support (WordPress/gutenberg#83615) - Site Title: Add minimum width and height support (WordPress/gutenberg#83593) - Home Link: Add padding and margin support (WordPress/gutenberg#83607) - Preformatted: Add minimum width and height support (WordPress/gutenberg#83587) - Include E2E Storybook sources in docgen (WordPress/gutenberg#83634) - Extensible Site Editor: Pass custom block categories to the blocks store (WordPress/gutenberg#83762) - Packages: Declare missing peer dependencies and check them in CI (WordPress/gutenberg#83765) - Post Terms: Add minimum width and height support (WordPress/gutenberg#83586) - Group, Cover: Track drop zone element in state (WordPress/gutenberg#83756) - Global Styles: Add pseudo-state controls for Navigation Link (WordPress/gutenberg#83451) - storybook: Register playground core blocks once (WordPress/gutenberg#83637) - Document Outline: Show the design system focus ring instead of legacy box-shadow (WordPress/gutenberg#83755) - storybook: Update BlockPopover fixture to API version 3 (WordPress/gutenberg#83642) - Add typing to iAPI's getConfig() (WordPress/gutenberg#71692) - Components: deprecate Badge (WordPress/gutenberg#82379) - Block Editor: Fix style / nested attribute overwrite during multi-selection (WordPress/gutenberg#80070) - Notes: Restrict menu actions for resolution notes and resolved threads (WordPress/gutenberg#73243) - UI: Add change actions to form primitive stories (WordPress/gutenberg#83591) - Icons: Support keyword-based search in the icons registry (WordPress/gutenberg#82367) - Avatar: Explain that avatars use the Gravatar service (WordPress/gutenberg#83567) - UI: Add item labels and descriptions to remaining popups (WordPress/gutenberg#83493) - PaletteEdit: Stop changing the slug when renaming a preset (WordPress/gutenberg#83750) - Storybook: Fix missing block styles in BlockCanvas playground stories (WordPress/gutenberg#81070) - Tests: Enforce Vitest callback, promise, and title rules (WordPress/gutenberg#83620) - ItemGroup: Use design system focus ring (WordPress/gutenberg#83764) - Keep the legacy CheckboxControl visually consistent across viewports (WordPress/gutenberg#83612) - Media editor: Use UI Menu for crop aspect ratio (WordPress/gutenberg#82968) - Use strict assertions in override script tests (WordPress/gutenberg#83782) - Home Link: Add minimum width and height support (WordPress/gutenberg#83582) - Tab Panels: Add minimum height support (WordPress/gutenberg#83594) - Post Time to Read: Add minimum width and height support (WordPress/gutenberg#83598) - Term Description: Add minimum width and height support (WordPress/gutenberg#83597) - UI: Keep InputLayout chrome at md on small viewports (WordPress/gutenberg#82764) - Math: Add minimum width and height support (WordPress/gutenberg#83585) - Tests: Bump undici in the AI development test lockfile (WordPress/gutenberg#83799) - Bump brace-expansion in /test/ai-development (WordPress/gutenberg#83807) - Bump js-yaml and promptfoo in /test/ai-development (WordPress/gutenberg#83797) - Bump fast-uri from 3.1.7 to 3.1.8 (WordPress/gutenberg#83829) - Update AI Development package versions after npm audit (WordPress/gutenberg#83830) - Notes: Add show and hide options for floating notes (WordPress/gutenberg#83768) - Add separators to item popup components (WordPress/gutenberg#83776) - Components: Align RadioControl colors with UI Radio (WordPress/gutenberg#83270) - E2E: Mock Openverse in image drag-and-drop inserter test (WordPress/gutenberg#83842) - FormToggle: Match Switch colors across states (WordPress/gutenberg#83773) - Bump `@react-spring/web` from 9.4.5 to 10.1.2 (WordPress/gutenberg#83796) - ColorPalette: Show design system focus ring on custom color button (WordPress/gutenberg#83841) - Docs: Remove CheckboxControl heading from InspectorControls example (WordPress/gutenberg#83844) - Base Styles: Default the admin theme color to Blueberry (WordPress/gutenberg#83749) - Menu: Guard against nesting Group and RadioGroup (WordPress/gutenberg#83792) - Template Part: Fall back to rendering a template part from the theme file if the db version is unavailable (WordPress/gutenberg#83809) - Tests: Reset deprecation history in shared Vitest setup (WordPress/gutenberg#83849) - Menu: Disable triggers instead of roots in consumers (WordPress/gutenberg#83791) - Playlist: Replace the waveform player patch with its no-autoinit entry (WordPress/gutenberg#83132) - Update UI Spinner appearance and add a color prop (WordPress/gutenberg#83775) - UI: Align component names with their semantics (WordPress/gutenberg#83789) - Checkbox: Prevent rounded themes from making checkboxes circular (WordPress/gutenberg#83526) - Storybook: Update manifest snapshot for Spinner color prop (WordPress/gutenberg#83856) - Button: Only open the link popover on explicit user action (WordPress/gutenberg#30166) - Gallery Lightbox: Prevent image click from closing the dialog when navigation is enabled (WordPress/gutenberg#78898) - UI: Recommend Checkbox family components (WordPress/gutenberg#83771) - RadioControl: Keep a 16px visual with a larger hit target (WordPress/gutenberg#83840) - Table: replace deprecated word-break with overflow-wrap: anywhere (WordPress/gutenberg#82480) - Tag Cloud: Update styles and add `!important` (WordPress/gutenberg#70224) - Correctly document the `blockName` property as being nullable (WordPress/gutenberg#70900) - Add inertValue helper and use it for setting inert attribute (WordPress/gutenberg#83871) - Enable editableRoot for the list item block for multi-selection on mobile (WordPress/gutenberg#82816) - Verify localized data retention in override script test (WordPress/gutenberg#83845) - Tests: Bump ibm-cloud-sdk-core in the AI development test lockfile (WordPress/gutenberg#83887) - UI: Recommend Notice component (WordPress/gutenberg#82685) - Fix: MediaUpload `gallery` prop ignores `allowedTypes` (WordPress/gutenberg#78257) - Media editor: Add a session boundary above the cropper (WordPress/gutenberg#83550) - DataViews: Measure the container as the data view mounts to avoid a single column flash (WordPress/gutenberg#83752) - Pullquote: Add minimum width support (WordPress/gutenberg#83588) - Media editor: Remove initial state seeding from the session (WordPress/gutenberg#83893) - UI: Add e2e Storybook popup item layout fixtures (WordPress/gutenberg#83488) - Storybook: Give CI job a distinct name (WordPress/gutenberg#83869) - Coding standards: Skip anonymous class methods in block library function name sniff (WordPress/gutenberg#83900) - Pagination: Add border support (WordPress/gutenberg#83745) - PR meta: Move the props list into the shared comment (WordPress/gutenberg#82302) - Comments Pagination: Add border support (WordPress/gutenberg#83746) - Scripts: Resolve default configs without hoisted dependencies (WordPress/gutenberg#83902) - Image: Fix invalid CSS url() value in circle-mask style (WordPress/gutenberg#82333) - Query Total: Add minimum width and height support (WordPress/gutenberg#83590) - Scripts: Treat files passed after --fix as file arguments (WordPress/gutenberg#83521) - Editor: Remove icon for 'Export' more menu item (WordPress/gutenberg#83901) - Dashboard Widgets: let a mounted widget declare actions at runtime (WordPress/gutenberg#83877) - Framework: Switch from hoisted to isolated dependencies (WordPress/gutenberg#83847) - Test: Run Vitest type graph validation in process (WordPress/gutenberg#83851) - Remove use-memo-one usage (missing React 19 compat) (WordPress/gutenberg#83952) - Fix Post Featured Image crash when isLink is enabled (WordPress/gutenberg#81584) - Experiment: restyle classic wp-admin controls from design system tokens (WordPress/gutenberg#82425) - Tests: Lint JavaScript Vitest mock imports (WordPress/gutenberg#83783) - Build: Remove patch-package (WordPress/gutenberg#83982) - Docs: Update deprecation testing guidance for shared reset (WordPress/gutenberg#83989) - DataViews: list hideable fields alphabetically in the view config (WordPress/gutenberg#83947) - Core Data: Rank link suggestions by type, and stop discarding merged results (WordPress/gutenberg#83407) - Add new react-inert-value package with inertValue helper (WordPress/gutenberg#83987) - Connectors: Keep a stored API key read-only when it can't be verified (WordPress/gutenberg#83889) - Navigation: Search every entity type from the link UI (WordPress/gutenberg#83408) - Tests: Cover translation setup in override script tests (WordPress/gutenberg#83886) - Build: Update Vite to 8.3.2 and remove the PostCSS browser resolver (WordPress/gutenberg#83992) - Update readme title to match block name (WordPress/gutenberg#83999) - RTC: Fix undo breaking for non-synced entities (WordPress/gutenberg#83888) - CI: Cover the AI development lockfile with Dependabot instead of npm audit (WordPress/gutenberg#83997) - Latest Posts: Add minimum width and height support (WordPress/gutenberg#83905) - Avatar: Add shadow support (WordPress/gutenberg#83929) - Tab List: Add shadow support (WordPress/gutenberg#83922) - Buttons: Add minimum width and height support (WordPress/gutenberg#83894) - Social Icons: Add shadow support (WordPress/gutenberg#83920) - Columns: Add minimum width and height support (WordPress/gutenberg#83895) - Gallery: Add shadow support (WordPress/gutenberg#83919) - File: Add shadow support (WordPress/gutenberg#83918) - Page List: Add minimum width and height support (WordPress/gutenberg#83908) - Build Tooling: Read npm v12 pack --json output (WordPress/gutenberg#84011) - Accordion Heading: Add line height support (WordPress/gutenberg#83958) - Paragraph: Add shadow support (WordPress/gutenberg#83926) - Media & Text: Add minimum width and height support (WordPress/gutenberg#83906) - Tests: Patch basic-ftp in AI development dependencies (WordPress/gutenberg#84000) - Env, E2E: Update dependencies that ran native install scripts (WordPress/gutenberg#84012) - Tests: Update Vitest to 5.0.3 and Storybook to 10.6.1 (WordPress/gutenberg#83996) - Search: Add padding support (WordPress/gutenberg#83984) - Block editor: Honour background skip serialization in the editor (WordPress/gutenberg#83943) - Framework: Declare React types in the workspaces that use them (WordPress/gutenberg#84013) - Fit text: Size each block instance in a loop independently (WordPress/gutenberg#83985) - FocalPointPicker: end a drag released over the editor canvas (WordPress/gutenberg#83348) - Tests: Cover Menu scroll lock and LinkControl protocols in browsers (WordPress/gutenberg#83991) - List: Add shadow support (WordPress/gutenberg#83923) - UI: Add Progress with custom color support (WordPress/gutenberg#83781) - ESLint: Allow non-module stylesheet imports in unit tests (WordPress/gutenberg#84019) - Canvas loader: Use UI Progress and pass color via the indicator prop (WordPress/gutenberg#83860) - Menu: Align group labels and separators with indented item labels. (WordPress/gutenberg#83993) - react-inert-value: add missing types/react peer dep (WordPress/gutenberg#84024) - Docs: Refine design system agent guidance (WordPress/gutenberg#84007) - Navigation: List allowed blocks in the link UI search results + add transformSuggestions to Link Control (WordPress/gutenberg#83652) - Sync: Remove exposed wp.sync package (WordPress/gutenberg#81999) - Style: Update color to use CSS variable in edit-site (WordPress/gutenberg#79002) - Popover: drop the will-change hint once the popover stops moving (WordPress/gutenberg#77359) - MediaEdit: Show a checkerboard background behind image previews (WordPress/gutenberg#83846) - Quote: Add button colour support (WordPress/gutenberg#83983) - Media & Text: Add duotone support (WordPress/gutenberg#83981) - Gallery: Add duotone support (WordPress/gutenberg#83978) - Interactivity API Router: Add reactive navigation lifecycle and initiator API (WordPress/gutenberg#83280) - Notes: Move floating notes into a canvas margin (WordPress/gutenberg#83786) - Verse: Add text columns and indent support (WordPress/gutenberg#83962) - Notes: Scroll floating notes with the canvas (WordPress/gutenberg#83852) - Notes: Add Undo to deleted note snackbar (WordPress/gutenberg#83988) - Framework: Move @typescript/native from the root to the workspaces that use it (WordPress/gutenberg#84027) - Repair invalid peer dependencies in the lockfile (WordPress/gutenberg#84062) - Term Template: Add minimum width and height support (WordPress/gutenberg#83914) - Fix check type declarations (WordPress/gutenberg#84070) - Media: track the original attachment id for edited images (WordPress/gutenberg#81803) - Post Comments Form: Add font family support (WordPress/gutenberg#83967) - Media Utils: Add `MediaEdit` as a private API (WordPress/gutenberg#84046) - Build Tools: Fix flaky ESM package types test timeout (WordPress/gutenberg#84068) - Embed: Add padding support (WordPress/gutenberg#83963) - Interactivity API: Add a data-wp-html directive (WordPress/gutenberg#83092) - Typography and "block-default icon polish. (WordPress/gutenberg#84073) - Release Tooling: Read the npm v12 JSON output shapes (WordPress/gutenberg#84075) - Menu: Align submenu labels and highlight open parents (WordPress/gutenberg#84031) - Props Bot: Skip bare reviews that duplicate their review comment runs (WordPress/gutenberg#84076) - Dataviews: use inertValue in CompositeGrid (WordPress/gutenberg#84072) - UI: Add Meter (WordPress/gutenberg#83855) - Media & Text: Add shadow support (WordPress/gutenberg#83976) - Media editor: restore original image in modal (WordPress/gutenberg#81805) - List: Add background image, size, and gradient support (WordPress/gutenberg#83935) - List Item: Add background image, size, and gradient support (WordPress/gutenberg#83936) - Block Editor: Fix 'Manage allowed blocks' not shown when its the only 'Advanced' control (WordPress/gutenberg#84067) - Design System: Clarify tooltip labeling and UI review guidance (WordPress/gutenberg#83898) - Gallery: Add minimum width and height support (WordPress/gutenberg#83897) - File: Add minimum width and height support (WordPress/gutenberg#83896) - Media: Return 0 from the edit root lookup when there is no edit root (WordPress/gutenberg#84096) - Read More: Add minimum width and height support (WordPress/gutenberg#83912) - UI: Recommend Radio family components (WordPress/gutenberg#83872) - Latest Comments: Add minimum width and height support (WordPress/gutenberg#83904) - chore: Use v24 in .nvmrc (WordPress/gutenberg#84061) - Embed: Add minimum width and height support (WordPress/gutenberg#83903) - Post Comments Form: Add minimum width and height support (WordPress/gutenberg#83910) - Post Featured Image: Add border style support (WordPress/gutenberg#83956) - Buttons: Add shadow support (WordPress/gutenberg#83916) - Poetry: Add fit text support (WordPress/gutenberg#83980) - Video: Add duotone support (WordPress/gutenberg#83979) - Notes: Keep anchor writes out of undo history (WordPress/gutenberg#84079) - ProgressBar: Use WPDS color tokens (WordPress/gutenberg#83779) - REST API: Add action-trash link to posts and comments (WordPress/gutenberg#84045) - RSS: Add minimum width and height support (WordPress/gutenberg#83913) - Notes: Reset paragraph top margin in floating notes (WordPress/gutenberg#84101) - Global Styles: Fix popover position in Styles screen (WordPress/gutenberg#84048) - Block Switcher: Show design system focus ring on pattern previews (WordPress/gutenberg#83933) - MediaEdit: Use design system focus ring (WordPress/gutenberg#83854) - Notes: Delete permanently when the trash is disabled (WordPress/gutenberg#84102) - Release: Rewrite SVN publication scripts in Node.js (WordPress/gutenberg#84034) - ContentEditableControl: Keep a disabled field focusable (WordPress/gutenberg#84083) - States: Scope per-instance rules to the block's root element (WordPress/gutenberg#83986) - List Item: Add shadow support (WordPress/gutenberg#83925) - DataViews: Truncate filter chips instead of wrapping them (WordPress/gutenberg#83879) - Experiments: Turn the React 19 experiment on by default (WordPress/gutenberg#83784) - Notes: Extract NoteReply and lift AddNote gating (WordPress/gutenberg#84106) - Interactivity API: Remove expired deprecated behaviors (WordPress/gutenberg#84098) - Breadcrumbs: Fix typo in aria label translation context (WordPress/gutenberg#84112) - ESLint: Allow generated test titles (WordPress/gutenberg#83995) - Icons: Add keywords to icon manifest (WordPress/gutenberg#83884) - Tooltip: Control the hover delay cancellation test clock (WordPress/gutenberg#84113) - VS Code: Add managed workspace config (WordPress/gutenberg#84025) - Breadcrumb: fix getMeasurementRender for React 19 (WordPress/gutenberg#84069) - Notes: Fix flaky thread scroll e2e test (WordPress/gutenberg#84118) - Detect the database client in the unit test debug step. (WordPress/gutenberg#84089) - UI: Preserve Autocomplete item type inference (WordPress/gutenberg#84095) - UI: Recommend Switch family components (WordPress/gutenberg#84097) - Env: Add an option to choose the MariaDB version (WordPress/gutenberg#83751) - UI: Preserve Combobox source item generics (WordPress/gutenberg#84094) - Menu: Tighten spacing, use 16px prefix icons, and cap width at 320px (WordPress/gutenberg#84028) - Notes: Preserve unsent note and reply drafts (WordPress/gutenberg#84110) - Theme: Add integration test coverage for seed colors in artifacts (WordPress/gutenberg#81161) - Progress: Migrate remaining ProgressBar usages and recommend UI Progress (WordPress/gutenberg#84021) - Components: Fix polymorphism typings leaking `as` prop (WordPress/gutenberg#82704) - Media & Text: Add background image, size, and gradient support (WordPress/gutenberg#83927) - Experiments: Use a mock plugin slug that no WordPress build ships in the unrelated-plugin test (WordPress/gutenberg#84133) - Button: Add background image, size, and gradient support (WordPress/gutenberg#83950) - Tests: Isolate Ajv per test in wp-env schema tests to avoid order dependence (WordPress/gutenberg#84139) - Storybook: Read icon keywords from the manifest (WordPress/gutenberg#84127) - SandBox: Fix embed previews that require a referrer in Safari (WordPress/gutenberg#84014) - Notes: Restore child notes trashed along with their parent note (WordPress/gutenberg#84100) - Style states: fix exception when there's no selected block (WordPress/gutenberg#84140) - Chore: Use v24.20 in `.nvmrc` config file. (WordPress/gutenberg#84138) - Security: Opt in to the npm v12 supply-chain defaults (WordPress/gutenberg#82689) - Docs: Describe isolated dependencies for agents and contributors (WordPress/gutenberg#84141) - Upgrade code and types to React 19 (WordPress/gutenberg#83941) - Latest Comments: Add border support (WordPress/gutenberg#84148) - Add prettier, eslint and stylelint to the root package.json (WordPress/gutenberg#84017) - FontSizePicker: Migrate Emotion styles to SCSS Modules (WordPress/gutenberg#84126) - Fields API: Add the server-side registry and REST route (WordPress/gutenberg#84078) - Block bindings: add support to `icon` attribute of `core/icon` (WordPress/gutenberg#80730) - VisuallyHidden: Move hiding styles outside CSS cascade layers (WordPress/gutenberg#84114) - Theme: Generate complete border token modes for Figma testing (WordPress/gutenberg#84035) - Developer tools: Simplify editor setup and add Zed settings (WordPress/gutenberg#84143) - Consolidate wp-admin container radiuses onto the design system scale (WordPress/gutenberg#82427) - CustomGradientPicker: Extend control point targets to the bar height (WordPress/gutenberg#84124) - Notes: Draw the canvas divider from body so it uses the theme text color (WordPress/gutenberg#84158) - Icons: Experiment with proportional stroke scaling (WordPress/gutenberg#84081) - Global Styles: Ignore theme.json values of unexpected types (WordPress/gutenberg#84523) - React 19 codemod: apply defaultProps when rendering a memo component (WordPress/gutenberg#84568) - React 19: add new incompatible plugins (WordPress/gutenberg#84607) - Tests: Fix HTML comparison tests (WordPress/gutenberg#84294) - Tests: Fix list item unsafe markup test on older WordPress versions (WordPress/gutenberg#84302) - Experiments: don't invalidate saved option with a legacy key (WordPress/gutenberg#84619) - Tests: Scope Classic block media checkbox locator (WordPress/gutenberg#84524) Props mamaduka. See #66340 git-svn-id: https://develop.svn.wordpress.org/trunk@64587 602fd350-edb4-49c9-b593-d223f7449a82
This updates the pinned commit hash of the Gutenberg repository from 954fe7f9e04631c41aec4552acd627a7203a2aad to 7b95ee96b54de2e35886971ccf7eb449c324c830 (version 24.2.0). A full list of changes included in this commit can be found on GitHub: WordPress/gutenberg@954fe7f...7b95ee9 - useServerSideRender: parse messages from caught errors (WordPress/gutenberg#83365) - Docs: Fix published Vitest migration-guide links (WordPress/gutenberg#83449) - Fix: Whitespace changes are not shown in the Resolve Block diff. (WordPress/gutenberg#82397) - Editor: Use SearchableSelect for the post author field (WordPress/gutenberg#83323) - Docs: Note that block attributes and global styles values are untrusted at render time (WordPress/gutenberg#83473) - RichText: Remove dead exports and consolidate deprecations (WordPress/gutenberg#83461) - Inserter: Manage roving tab index to skip re-rendering every item (WordPress/gutenberg#83437) - SearchableSelectControl: Add to @wordpress/ui (WordPress/gutenberg#80979) - Try: Bolder "B" icon (WordPress/gutenberg#83321) - Ignore composer vendor files from top-level gitignore. (WordPress/gutenberg#22283) - Tests: Add floating notes e2e coverage (WordPress/gutenberg#83477) - Block Editor: Check the inserter's fallback containers unmemoized (WordPress/gutenberg#83446) - Packages: Update Ariakit to 0.4.40 (WordPress/gutenberg#83278) - Tests: Enforce per-call Vitest console expectations (WordPress/gutenberg#83095) - Theme: Fix virtual modules, root styles, and seed validation (WordPress/gutenberg#83355) - DataViews: Fix README to describe sort() as receiving field values, not items (WordPress/gutenberg#83483) - Combobox: Label popup dialogs in stories (WordPress/gutenberg#83476) - Block editor: Isolate mutable test fixtures (WordPress/gutenberg#83098) - Blocks: Isolate registration state in tests (WordPress/gutenberg#83099) - UI: Remove automatic Notice announcements (WordPress/gutenberg#82737) - Text: Migrate Emotion styles to an SCSS Module (WordPress/gutenberg#82573) - Block library: Isolate order-sensitive test interactions (WordPress/gutenberg#83101) - Format Library: unify FormatEditProps to one type, move private types (WordPress/gutenberg#83487) - UI: Announce selected chips in SearchableChipSelect (WordPress/gutenberg#82863) - Card: Migrate from Emotion to SCSS modules (WordPress/gutenberg#82577) - Components: Deprecate the private Menu API (WordPress/gutenberg#82947) - CustomGradientPicker: Migrate control wrappers to an SCSS module (WordPress/gutenberg#82576) - Components: Isolate order-sensitive UI tests (WordPress/gutenberg#83103) - Tests: Isolate mutable configuration fixtures (WordPress/gutenberg#83104) - Core data: Finish deferred selection updates in RTC test (WordPress/gutenberg#83366) - Block editor: Wait for final keyboard link suggestions (WordPress/gutenberg#83489) - Data: Assert and silence resolution error in useSuspenseSelect test (WordPress/gutenberg#83491) - Tests: Isolate deprecation warning state (WordPress/gutenberg#83107) - UI: Align selection popup checkmarks with the first label line (WordPress/gutenberg#82942) - Tests: Resolve Browser Mode commands against the live iframe (WordPress/gutenberg#83495) - Ensure position type is a string (WordPress/gutenberg#83500) - MediaUpload: Fix console error when reopening Gallery media library (WordPress/gutenberg#76749) - Refactor stylelint config detection in lint-style.js (WordPress/gutenberg#79280) - Docs: Recommend UI Tabs for switching views (WordPress/gutenberg#83516) - Popover: Close non-modal popovers on iframe interaction (WordPress/gutenberg#83509) - Typography: List only the weights inside a variable font's range (WordPress/gutenberg#83128) - Style book: Add link to example text. (WordPress/gutenberg#83448) - Tests: Add Vitest Browser Mode failure artifacts (WordPress/gutenberg#83093) - Theme: Make JavaScript token fallback transforms syntax-aware (WordPress/gutenberg#83356) - Editor: Fix new posts being published with the `auto-draft` slug (WordPress/gutenberg#83518) - Editor: Gather the View group of the Options menu into submenus (WordPress/gutenberg#82976) - Tests: Fix PostCSS browser-externalized warnings in Vitest (WordPress/gutenberg#83091) - Tests: Shuffle test cases in CI (WordPress/gutenberg#83111) - Update Styles > Blocks description. (WordPress/gutenberg#83515) - Columns: Remove the column count slider (WordPress/gutenberg#83262) - BorderControl: Remove `%` from the border width units (WordPress/gutenberg#83492) - Fields: Fix AuthorView for users who can't edit users (WordPress/gutenberg#83498) - Update and add justify icons. (WordPress/gutenberg#83519) - RichText: Refactor useMarkPersistent, fix StrictMode mount mark (WordPress/gutenberg#83463) - Theme: Improve accessibility, API documentation, and compatibility checks (WordPress/gutenberg#83358) - Theme: Preserve global token references in Lightning CSS (WordPress/gutenberg#83359) - Tests: Migrate internal linting to Vitest and remove unused Jest dependencies (WordPress/gutenberg#83502) - Improve specificity of lightbox button selector (WordPress/gutenberg#70800) - TextControl: Use design system colors when disabled (WordPress/gutenberg#83307) - Fix: Image lightbox: overlay becomes unusable (can't close) when it isn't a direct child of `<body>` (WordPress/gutenberg#83480) - Notes: Extract note selection sync into useNoteSelection hook (WordPress/gutenberg#83528) - Block Parser: Document `\WP_Block_Parser::$stack` as a list (WordPress/gutenberg#82695) - CollapsibleCard: Scope the header focus ring to its own trigger (WordPress/gutenberg#81314) - Fix broken links in docs (WordPress/gutenberg#83545) - Icons: Use assertEqualHTML() in icons registry tests (WordPress/gutenberg#83544) - Editor: Merge adjacent revision inline diffs (WordPress/gutenberg#80579) - Date: Ignore trailing format backslash instead of printing undefined (WordPress/gutenberg#81528) - Block Supports: Add background-clip block support infrastructure (WordPress/gutenberg#77141) - Block Editor: Fix translator comments for block count announcements (WordPress/gutenberg#83555) - Paste: replace non-breaking spaces at the edges of text with regular spaces (WordPress/gutenberg#83464) - Media Editor: Fix pan drag flooding undo history after wheel zoom (WordPress/gutenberg#83558) - Rich text: fix iOS double tap selection, preventing focus capture under editable host (WordPress/gutenberg#81042) - Block editor: migrate state-control badges to UI Badge (WordPress/gutenberg#82608) - Gallery: Add Order By controls for static gallery, consolidate controls in settings sidebar (WordPress/gutenberg#83438) - Media editor: show an error when saving attachment details fails (WordPress/gutenberg#83560) - Position controls: Fix useSelect warning for selected state viewports (WordPress/gutenberg#83570) - Inserter: Use design system focus ring for previews (WordPress/gutenberg#83126) - Image: Fix lightbox using thumbnail aspect ratio instead of original image ratio (WordPress/gutenberg#79058) - Docs: Clarify @wordpress/ui icon color requirements (WordPress/gutenberg#83564) - docker compose -T if stdin is not a tty (WordPress/gutenberg#78374) - Storybook: Add new contributing page. (WordPress/gutenberg#83345) - Widget Primitives: Avoid Vite warnings for runtime widget modules (WordPress/gutenberg#83602) - Build: Update Vite to 8.3.1 and simplify Storybook tooling (WordPress/gutenberg#83569) - doc(wp-env) Change core branch from trunk to master in doc (WordPress/gutenberg#83566) - wp-build: Remove the unused boot, private-apis, and route optional peer dependencies (WordPress/gutenberg#83601) - CI: Check CHANGELOG presence for published tooling and config packages (WordPress/gutenberg#83577) - Tests: Enforce Vitest assertion coverage (WordPress/gutenberg#83572) - Icons: Update heading level icons for optical balance (WordPress/gutenberg#83268) - ESLint: Add allowUseWithCaution option to use-recommended-components (WordPress/gutenberg#83536) - Notes: Refactor floating board measurement (WordPress/gutenberg#83485) - Inserter: Stop re-rendering the block list on block selection change (WordPress/gutenberg#83284) - Paste: Give each pasted data-URI image unique filename to avoid upload collisions. (WordPress/gutenberg#79480) - Changelog validator: ignore markdown & configs d46223 (WordPress/gutenberg#83618) - Font Library: Use UI Menu for collection actions (WordPress/gutenberg#82965) - Storybook: Show prop descriptions in Canvas controls (WordPress/gutenberg#83581) - test: Link upstream warning fixes in config (WordPress/gutenberg#83632) - Storybook: Use one block-editor store module (WordPress/gutenberg#83636) - Tests: Use strict assertions synced from Core changeset 63934. (WordPress/gutenberg#83619) - Math: Store cell alignment in the MathML and polyfill alignment and overlines in Chromium (WordPress/gutenberg#83164) - Storybook: Reuse PostCSS browser resolver in smoke tests (WordPress/gutenberg#83635) - Editor: Use UI Menu for template options (WordPress/gutenberg#82964) - RTC: Add a EntitySyncManager interface in core-data (WordPress/gutenberg#83410) - Term Count: Add margin support (WordPress/gutenberg#83608) - Archives: Add minimum height support (WordPress/gutenberg#83573) - Media Editor: Stop the crop pixel snap from recording undo history (WordPress/gutenberg#83571) - Term Name: Add margin support (WordPress/gutenberg#83606) - Post Author Biography: Add text indent support (WordPress/gutenberg#83614) - Code: Add minimum width and height support (WordPress/gutenberg#83574) - Details: Add minimum width support (WordPress/gutenberg#83576) - Post Content: Add minimum width support (WordPress/gutenberg#83575) - Post Excerpt: Add minimum width and height support (WordPress/gutenberg#83578) - Post Title: Add minimum width and height support (WordPress/gutenberg#83600) - Footnotes: Add minimum width and height support (WordPress/gutenberg#83579) - Storybook: Place Notice announcements under Components (WordPress/gutenberg#83617) - InputControl: Darken the field border on hover (WordPress/gutenberg#83306) - npm: Switch from legacy-peer-deps to strict-peer-deps (WordPress/gutenberg#81029) - Term Name: Add minimum width and height support (WordPress/gutenberg#83599) - Columns: Allow dropping a column at the outer edges (WordPress/gutenberg#83274) - E2E: Pin the site title in the Interactivity API router specs and give the E2E Storybook build more heap. (WordPress/gutenberg#83474) - Heading: Add minimum width and height support (WordPress/gutenberg#83580) - Login/out: Add minimum width and height support (WordPress/gutenberg#83583) - Verse: Add minimum width support (WordPress/gutenberg#83609) - Video, Cover: Don't autoplay in the editor when reduced motion is preferred (WordPress/gutenberg#83337) - Media & Text: Lower the specificity of the content padding (WordPress/gutenberg#83563) - Pagination: Add padding, margin, and block gap support (WordPress/gutenberg#83743) - Fix peer dependency conflicts left in the lockfile (WordPress/gutenberg#83754) - Comments Pagination: Add padding, margin, and block gap support (WordPress/gutenberg#83744) - Term Count: Add minimum width and height support (WordPress/gutenberg#83596) - Read More: Add border style support (WordPress/gutenberg#83735) - Cover: Don't autoplay embedded background videos when reduced motion is preferred (WordPress/gutenberg#83452) - No Results: Add minimum width and height support (WordPress/gutenberg#83584) - RichText: Rename utils.jsx to utils.js (WordPress/gutenberg#83758) - Quote: Add minimum width support (WordPress/gutenberg#83592) - Upgrade typescript-eslint to v8.70.1 (WordPress/gutenberg#83760) - Tabs: Add minimum width support (WordPress/gutenberg#83595) - Site Tagline: Add minimum width and height support (WordPress/gutenberg#83589) - Heading: Add text indent support (WordPress/gutenberg#83615) - Site Title: Add minimum width and height support (WordPress/gutenberg#83593) - Home Link: Add padding and margin support (WordPress/gutenberg#83607) - Preformatted: Add minimum width and height support (WordPress/gutenberg#83587) - Include E2E Storybook sources in docgen (WordPress/gutenberg#83634) - Extensible Site Editor: Pass custom block categories to the blocks store (WordPress/gutenberg#83762) - Packages: Declare missing peer dependencies and check them in CI (WordPress/gutenberg#83765) - Post Terms: Add minimum width and height support (WordPress/gutenberg#83586) - Group, Cover: Track drop zone element in state (WordPress/gutenberg#83756) - Global Styles: Add pseudo-state controls for Navigation Link (WordPress/gutenberg#83451) - storybook: Register playground core blocks once (WordPress/gutenberg#83637) - Document Outline: Show the design system focus ring instead of legacy box-shadow (WordPress/gutenberg#83755) - storybook: Update BlockPopover fixture to API version 3 (WordPress/gutenberg#83642) - Add typing to iAPI's getConfig() (WordPress/gutenberg#71692) - Components: deprecate Badge (WordPress/gutenberg#82379) - Block Editor: Fix style / nested attribute overwrite during multi-selection (WordPress/gutenberg#80070) - Notes: Restrict menu actions for resolution notes and resolved threads (WordPress/gutenberg#73243) - UI: Add change actions to form primitive stories (WordPress/gutenberg#83591) - Icons: Support keyword-based search in the icons registry (WordPress/gutenberg#82367) - Avatar: Explain that avatars use the Gravatar service (WordPress/gutenberg#83567) - UI: Add item labels and descriptions to remaining popups (WordPress/gutenberg#83493) - PaletteEdit: Stop changing the slug when renaming a preset (WordPress/gutenberg#83750) - Storybook: Fix missing block styles in BlockCanvas playground stories (WordPress/gutenberg#81070) - Tests: Enforce Vitest callback, promise, and title rules (WordPress/gutenberg#83620) - ItemGroup: Use design system focus ring (WordPress/gutenberg#83764) - Keep the legacy CheckboxControl visually consistent across viewports (WordPress/gutenberg#83612) - Media editor: Use UI Menu for crop aspect ratio (WordPress/gutenberg#82968) - Use strict assertions in override script tests (WordPress/gutenberg#83782) - Home Link: Add minimum width and height support (WordPress/gutenberg#83582) - Tab Panels: Add minimum height support (WordPress/gutenberg#83594) - Post Time to Read: Add minimum width and height support (WordPress/gutenberg#83598) - Term Description: Add minimum width and height support (WordPress/gutenberg#83597) - UI: Keep InputLayout chrome at md on small viewports (WordPress/gutenberg#82764) - Math: Add minimum width and height support (WordPress/gutenberg#83585) - Tests: Bump undici in the AI development test lockfile (WordPress/gutenberg#83799) - Bump brace-expansion in /test/ai-development (WordPress/gutenberg#83807) - Bump js-yaml and promptfoo in /test/ai-development (WordPress/gutenberg#83797) - Bump fast-uri from 3.1.7 to 3.1.8 (WordPress/gutenberg#83829) - Update AI Development package versions after npm audit (WordPress/gutenberg#83830) - Notes: Add show and hide options for floating notes (WordPress/gutenberg#83768) - Add separators to item popup components (WordPress/gutenberg#83776) - Components: Align RadioControl colors with UI Radio (WordPress/gutenberg#83270) - E2E: Mock Openverse in image drag-and-drop inserter test (WordPress/gutenberg#83842) - FormToggle: Match Switch colors across states (WordPress/gutenberg#83773) - Bump `@react-spring/web` from 9.4.5 to 10.1.2 (WordPress/gutenberg#83796) - ColorPalette: Show design system focus ring on custom color button (WordPress/gutenberg#83841) - Docs: Remove CheckboxControl heading from InspectorControls example (WordPress/gutenberg#83844) - Base Styles: Default the admin theme color to Blueberry (WordPress/gutenberg#83749) - Menu: Guard against nesting Group and RadioGroup (WordPress/gutenberg#83792) - Template Part: Fall back to rendering a template part from the theme file if the db version is unavailable (WordPress/gutenberg#83809) - Tests: Reset deprecation history in shared Vitest setup (WordPress/gutenberg#83849) - Menu: Disable triggers instead of roots in consumers (WordPress/gutenberg#83791) - Playlist: Replace the waveform player patch with its no-autoinit entry (WordPress/gutenberg#83132) - Update UI Spinner appearance and add a color prop (WordPress/gutenberg#83775) - UI: Align component names with their semantics (WordPress/gutenberg#83789) - Checkbox: Prevent rounded themes from making checkboxes circular (WordPress/gutenberg#83526) - Storybook: Update manifest snapshot for Spinner color prop (WordPress/gutenberg#83856) - Button: Only open the link popover on explicit user action (WordPress/gutenberg#30166) - Gallery Lightbox: Prevent image click from closing the dialog when navigation is enabled (WordPress/gutenberg#78898) - UI: Recommend Checkbox family components (WordPress/gutenberg#83771) - RadioControl: Keep a 16px visual with a larger hit target (WordPress/gutenberg#83840) - Table: replace deprecated word-break with overflow-wrap: anywhere (WordPress/gutenberg#82480) - Tag Cloud: Update styles and add `!important` (WordPress/gutenberg#70224) - Correctly document the `blockName` property as being nullable (WordPress/gutenberg#70900) - Add inertValue helper and use it for setting inert attribute (WordPress/gutenberg#83871) - Enable editableRoot for the list item block for multi-selection on mobile (WordPress/gutenberg#82816) - Verify localized data retention in override script test (WordPress/gutenberg#83845) - Tests: Bump ibm-cloud-sdk-core in the AI development test lockfile (WordPress/gutenberg#83887) - UI: Recommend Notice component (WordPress/gutenberg#82685) - Fix: MediaUpload `gallery` prop ignores `allowedTypes` (WordPress/gutenberg#78257) - Media editor: Add a session boundary above the cropper (WordPress/gutenberg#83550) - DataViews: Measure the container as the data view mounts to avoid a single column flash (WordPress/gutenberg#83752) - Pullquote: Add minimum width support (WordPress/gutenberg#83588) - Media editor: Remove initial state seeding from the session (WordPress/gutenberg#83893) - UI: Add e2e Storybook popup item layout fixtures (WordPress/gutenberg#83488) - Storybook: Give CI job a distinct name (WordPress/gutenberg#83869) - Coding standards: Skip anonymous class methods in block library function name sniff (WordPress/gutenberg#83900) - Pagination: Add border support (WordPress/gutenberg#83745) - PR meta: Move the props list into the shared comment (WordPress/gutenberg#82302) - Comments Pagination: Add border support (WordPress/gutenberg#83746) - Scripts: Resolve default configs without hoisted dependencies (WordPress/gutenberg#83902) - Image: Fix invalid CSS url() value in circle-mask style (WordPress/gutenberg#82333) - Query Total: Add minimum width and height support (WordPress/gutenberg#83590) - Scripts: Treat files passed after --fix as file arguments (WordPress/gutenberg#83521) - Editor: Remove icon for 'Export' more menu item (WordPress/gutenberg#83901) - Dashboard Widgets: let a mounted widget declare actions at runtime (WordPress/gutenberg#83877) - Framework: Switch from hoisted to isolated dependencies (WordPress/gutenberg#83847) - Test: Run Vitest type graph validation in process (WordPress/gutenberg#83851) - Remove use-memo-one usage (missing React 19 compat) (WordPress/gutenberg#83952) - Fix Post Featured Image crash when isLink is enabled (WordPress/gutenberg#81584) - Experiment: restyle classic wp-admin controls from design system tokens (WordPress/gutenberg#82425) - Tests: Lint JavaScript Vitest mock imports (WordPress/gutenberg#83783) - Build: Remove patch-package (WordPress/gutenberg#83982) - Docs: Update deprecation testing guidance for shared reset (WordPress/gutenberg#83989) - DataViews: list hideable fields alphabetically in the view config (WordPress/gutenberg#83947) - Core Data: Rank link suggestions by type, and stop discarding merged results (WordPress/gutenberg#83407) - Add new react-inert-value package with inertValue helper (WordPress/gutenberg#83987) - Connectors: Keep a stored API key read-only when it can't be verified (WordPress/gutenberg#83889) - Navigation: Search every entity type from the link UI (WordPress/gutenberg#83408) - Tests: Cover translation setup in override script tests (WordPress/gutenberg#83886) - Build: Update Vite to 8.3.2 and remove the PostCSS browser resolver (WordPress/gutenberg#83992) - Update readme title to match block name (WordPress/gutenberg#83999) - RTC: Fix undo breaking for non-synced entities (WordPress/gutenberg#83888) - CI: Cover the AI development lockfile with Dependabot instead of npm audit (WordPress/gutenberg#83997) - Latest Posts: Add minimum width and height support (WordPress/gutenberg#83905) - Avatar: Add shadow support (WordPress/gutenberg#83929) - Tab List: Add shadow support (WordPress/gutenberg#83922) - Buttons: Add minimum width and height support (WordPress/gutenberg#83894) - Social Icons: Add shadow support (WordPress/gutenberg#83920) - Columns: Add minimum width and height support (WordPress/gutenberg#83895) - Gallery: Add shadow support (WordPress/gutenberg#83919) - File: Add shadow support (WordPress/gutenberg#83918) - Page List: Add minimum width and height support (WordPress/gutenberg#83908) - Build Tooling: Read npm v12 pack --json output (WordPress/gutenberg#84011) - Accordion Heading: Add line height support (WordPress/gutenberg#83958) - Paragraph: Add shadow support (WordPress/gutenberg#83926) - Media & Text: Add minimum width and height support (WordPress/gutenberg#83906) - Tests: Patch basic-ftp in AI development dependencies (WordPress/gutenberg#84000) - Env, E2E: Update dependencies that ran native install scripts (WordPress/gutenberg#84012) - Tests: Update Vitest to 5.0.3 and Storybook to 10.6.1 (WordPress/gutenberg#83996) - Search: Add padding support (WordPress/gutenberg#83984) - Block editor: Honour background skip serialization in the editor (WordPress/gutenberg#83943) - Framework: Declare React types in the workspaces that use them (WordPress/gutenberg#84013) - Fit text: Size each block instance in a loop independently (WordPress/gutenberg#83985) - FocalPointPicker: end a drag released over the editor canvas (WordPress/gutenberg#83348) - Tests: Cover Menu scroll lock and LinkControl protocols in browsers (WordPress/gutenberg#83991) - List: Add shadow support (WordPress/gutenberg#83923) - UI: Add Progress with custom color support (WordPress/gutenberg#83781) - ESLint: Allow non-module stylesheet imports in unit tests (WordPress/gutenberg#84019) - Canvas loader: Use UI Progress and pass color via the indicator prop (WordPress/gutenberg#83860) - Menu: Align group labels and separators with indented item labels. (WordPress/gutenberg#83993) - react-inert-value: add missing types/react peer dep (WordPress/gutenberg#84024) - Docs: Refine design system agent guidance (WordPress/gutenberg#84007) - Navigation: List allowed blocks in the link UI search results + add transformSuggestions to Link Control (WordPress/gutenberg#83652) - Sync: Remove exposed wp.sync package (WordPress/gutenberg#81999) - Style: Update color to use CSS variable in edit-site (WordPress/gutenberg#79002) - Popover: drop the will-change hint once the popover stops moving (WordPress/gutenberg#77359) - MediaEdit: Show a checkerboard background behind image previews (WordPress/gutenberg#83846) - Quote: Add button colour support (WordPress/gutenberg#83983) - Media & Text: Add duotone support (WordPress/gutenberg#83981) - Gallery: Add duotone support (WordPress/gutenberg#83978) - Interactivity API Router: Add reactive navigation lifecycle and initiator API (WordPress/gutenberg#83280) - Notes: Move floating notes into a canvas margin (WordPress/gutenberg#83786) - Verse: Add text columns and indent support (WordPress/gutenberg#83962) - Notes: Scroll floating notes with the canvas (WordPress/gutenberg#83852) - Notes: Add Undo to deleted note snackbar (WordPress/gutenberg#83988) - Framework: Move @typescript/native from the root to the workspaces that use it (WordPress/gutenberg#84027) - Repair invalid peer dependencies in the lockfile (WordPress/gutenberg#84062) - Term Template: Add minimum width and height support (WordPress/gutenberg#83914) - Fix check type declarations (WordPress/gutenberg#84070) - Media: track the original attachment id for edited images (WordPress/gutenberg#81803) - Post Comments Form: Add font family support (WordPress/gutenberg#83967) - Media Utils: Add `MediaEdit` as a private API (WordPress/gutenberg#84046) - Build Tools: Fix flaky ESM package types test timeout (WordPress/gutenberg#84068) - Embed: Add padding support (WordPress/gutenberg#83963) - Interactivity API: Add a data-wp-html directive (WordPress/gutenberg#83092) - Typography and "block-default icon polish. (WordPress/gutenberg#84073) - Release Tooling: Read the npm v12 JSON output shapes (WordPress/gutenberg#84075) - Menu: Align submenu labels and highlight open parents (WordPress/gutenberg#84031) - Props Bot: Skip bare reviews that duplicate their review comment runs (WordPress/gutenberg#84076) - Dataviews: use inertValue in CompositeGrid (WordPress/gutenberg#84072) - UI: Add Meter (WordPress/gutenberg#83855) - Media & Text: Add shadow support (WordPress/gutenberg#83976) - Media editor: restore original image in modal (WordPress/gutenberg#81805) - List: Add background image, size, and gradient support (WordPress/gutenberg#83935) - List Item: Add background image, size, and gradient support (WordPress/gutenberg#83936) - Block Editor: Fix 'Manage allowed blocks' not shown when its the only 'Advanced' control (WordPress/gutenberg#84067) - Design System: Clarify tooltip labeling and UI review guidance (WordPress/gutenberg#83898) - Gallery: Add minimum width and height support (WordPress/gutenberg#83897) - File: Add minimum width and height support (WordPress/gutenberg#83896) - Media: Return 0 from the edit root lookup when there is no edit root (WordPress/gutenberg#84096) - Read More: Add minimum width and height support (WordPress/gutenberg#83912) - UI: Recommend Radio family components (WordPress/gutenberg#83872) - Latest Comments: Add minimum width and height support (WordPress/gutenberg#83904) - chore: Use v24 in .nvmrc (WordPress/gutenberg#84061) - Embed: Add minimum width and height support (WordPress/gutenberg#83903) - Post Comments Form: Add minimum width and height support (WordPress/gutenberg#83910) - Post Featured Image: Add border style support (WordPress/gutenberg#83956) - Buttons: Add shadow support (WordPress/gutenberg#83916) - Poetry: Add fit text support (WordPress/gutenberg#83980) - Video: Add duotone support (WordPress/gutenberg#83979) - Notes: Keep anchor writes out of undo history (WordPress/gutenberg#84079) - ProgressBar: Use WPDS color tokens (WordPress/gutenberg#83779) - REST API: Add action-trash link to posts and comments (WordPress/gutenberg#84045) - RSS: Add minimum width and height support (WordPress/gutenberg#83913) - Notes: Reset paragraph top margin in floating notes (WordPress/gutenberg#84101) - Global Styles: Fix popover position in Styles screen (WordPress/gutenberg#84048) - Block Switcher: Show design system focus ring on pattern previews (WordPress/gutenberg#83933) - MediaEdit: Use design system focus ring (WordPress/gutenberg#83854) - Notes: Delete permanently when the trash is disabled (WordPress/gutenberg#84102) - Release: Rewrite SVN publication scripts in Node.js (WordPress/gutenberg#84034) - ContentEditableControl: Keep a disabled field focusable (WordPress/gutenberg#84083) - States: Scope per-instance rules to the block's root element (WordPress/gutenberg#83986) - List Item: Add shadow support (WordPress/gutenberg#83925) - DataViews: Truncate filter chips instead of wrapping them (WordPress/gutenberg#83879) - Experiments: Turn the React 19 experiment on by default (WordPress/gutenberg#83784) - Notes: Extract NoteReply and lift AddNote gating (WordPress/gutenberg#84106) - Interactivity API: Remove expired deprecated behaviors (WordPress/gutenberg#84098) - Breadcrumbs: Fix typo in aria label translation context (WordPress/gutenberg#84112) - ESLint: Allow generated test titles (WordPress/gutenberg#83995) - Icons: Add keywords to icon manifest (WordPress/gutenberg#83884) - Tooltip: Control the hover delay cancellation test clock (WordPress/gutenberg#84113) - VS Code: Add managed workspace config (WordPress/gutenberg#84025) - Breadcrumb: fix getMeasurementRender for React 19 (WordPress/gutenberg#84069) - Notes: Fix flaky thread scroll e2e test (WordPress/gutenberg#84118) - Detect the database client in the unit test debug step. (WordPress/gutenberg#84089) - UI: Preserve Autocomplete item type inference (WordPress/gutenberg#84095) - UI: Recommend Switch family components (WordPress/gutenberg#84097) - Env: Add an option to choose the MariaDB version (WordPress/gutenberg#83751) - UI: Preserve Combobox source item generics (WordPress/gutenberg#84094) - Menu: Tighten spacing, use 16px prefix icons, and cap width at 320px (WordPress/gutenberg#84028) - Notes: Preserve unsent note and reply drafts (WordPress/gutenberg#84110) - Theme: Add integration test coverage for seed colors in artifacts (WordPress/gutenberg#81161) - Progress: Migrate remaining ProgressBar usages and recommend UI Progress (WordPress/gutenberg#84021) - Components: Fix polymorphism typings leaking `as` prop (WordPress/gutenberg#82704) - Media & Text: Add background image, size, and gradient support (WordPress/gutenberg#83927) - Experiments: Use a mock plugin slug that no WordPress build ships in the unrelated-plugin test (WordPress/gutenberg#84133) - Button: Add background image, size, and gradient support (WordPress/gutenberg#83950) - Tests: Isolate Ajv per test in wp-env schema tests to avoid order dependence (WordPress/gutenberg#84139) - Storybook: Read icon keywords from the manifest (WordPress/gutenberg#84127) - SandBox: Fix embed previews that require a referrer in Safari (WordPress/gutenberg#84014) - Notes: Restore child notes trashed along with their parent note (WordPress/gutenberg#84100) - Style states: fix exception when there's no selected block (WordPress/gutenberg#84140) - Chore: Use v24.20 in `.nvmrc` config file. (WordPress/gutenberg#84138) - Security: Opt in to the npm v12 supply-chain defaults (WordPress/gutenberg#82689) - Docs: Describe isolated dependencies for agents and contributors (WordPress/gutenberg#84141) - Upgrade code and types to React 19 (WordPress/gutenberg#83941) - Latest Comments: Add border support (WordPress/gutenberg#84148) - Add prettier, eslint and stylelint to the root package.json (WordPress/gutenberg#84017) - FontSizePicker: Migrate Emotion styles to SCSS Modules (WordPress/gutenberg#84126) - Fields API: Add the server-side registry and REST route (WordPress/gutenberg#84078) - Block bindings: add support to `icon` attribute of `core/icon` (WordPress/gutenberg#80730) - VisuallyHidden: Move hiding styles outside CSS cascade layers (WordPress/gutenberg#84114) - Theme: Generate complete border token modes for Figma testing (WordPress/gutenberg#84035) - Developer tools: Simplify editor setup and add Zed settings (WordPress/gutenberg#84143) - Consolidate wp-admin container radiuses onto the design system scale (WordPress/gutenberg#82427) - CustomGradientPicker: Extend control point targets to the bar height (WordPress/gutenberg#84124) - Notes: Draw the canvas divider from body so it uses the theme text color (WordPress/gutenberg#84158) - Icons: Experiment with proportional stroke scaling (WordPress/gutenberg#84081) - Global Styles: Ignore theme.json values of unexpected types (WordPress/gutenberg#84523) - React 19 codemod: apply defaultProps when rendering a memo component (WordPress/gutenberg#84568) - React 19: add new incompatible plugins (WordPress/gutenberg#84607) - Tests: Fix HTML comparison tests (WordPress/gutenberg#84294) - Tests: Fix list item unsafe markup test on older WordPress versions (WordPress/gutenberg#84302) - Experiments: don't invalidate saved option with a legacy key (WordPress/gutenberg#84619) - Tests: Scope Classic block media checkbox locator (WordPress/gutenberg#84524) Props mamaduka. See #66340 Built from https://develop.svn.wordpress.org/trunk@64587 git-svn-id: http://core.svn.wordpress.org/trunk@63737 1a063a9b-81f0-0310-95a4-ce76da25c4cd
See #82701
What?
Remove automatic announcements and the
spokenMessageandpolitenessprops from@wordpress/uiNotice.Why?
Static notices should not announce themselves. Applications need to choose the announcement's text, timing, and urgency without including action labels.
How?
Consumers call
speak()when an update needs an announcement. Editor crashes announce the title and description assertively. A single dashboard widget failure uses a polite announcement. The visible notices have no live-region roles, avoiding duplicate announcements.Storybook includes migration guidance and interactive examples. It recommends consumer-owned
speak()calls and explains how to use an already mounted live region as an alternative.This is a breaking API change. The legacy
@wordpress/componentsNoticeis unchanged. The compositionalNotice.Listproposal in #82701 remains separate work.Testing Instructions
@wordpress/a11ylive regions should receive announcements; the visible notices should have norole="alert"orrole="status".Testing Instructions for Keyboard
Use Tab and Enter to run the examples. After either save action, focus should stay on its button. Tab should reach Try again or Dismiss.
Use of AI Tools
Codex was used to investigate, implement, verify, and draft this change.