Repository navigation
UI: add ControlWithError component - #81574
Conversation
|
There are some commits that don't belong to this branch and are part of trunk. They're listed here because this PR started on a newer trunk version than the base had (spinner branch): the reason for that is that I wanted to work with all the recent vendored PRs for DataViews (e.g., togglecontrol). This will self-fix itself when the base branch is updated to latest trunk. |
9334b5a to
56cd3b0
Compare
This was the wrong trade-off: it prevented us from reviewing code changes here. So I rebased this onto the base. I'll get the latest trunk commits when the base is merged/updated. |
| @@ -0,0 +1,2 @@ | |||
| export { ControlWithError } from './control-with-error'; | |||
| export { ValidityIndicator } from './validity-indicator'; | |||
There was a problem hiding this comment.
There are cases that are not well served by ControlWithError today. One such a case is DataForm date operator, which comes with a range control (from-to inputs, not a single one):
If we wrapped every single control by ControlWithError we'd get error message on each individual control, but we actually want this to act as a single coordinated control (single error message).
There was a problem hiding this comment.
we'd get error message on each individual control
The first approach I would try is using a ValidatedInputControl for each date field, but by default get the errors to mark the first field. Most errors can be marked on the first field, even if it's technically an error for both fields combined, e.g. "End date is earlier than start date", "Please fill in this field" (when both fields are empty), etc. In the screenshot's case where it's clearly the second field that should get the error, then you mark the second field. If that's a problem visual-wise, then I think you could maybe just mark the first field for all errors, even if it's like "Please fill in the end date". As long as we have an appropriate fieldset grouping or something.
Would that work, or are there other cases?
I think you generally do need to mark (semantics + focus) exactly one element for any given error. Otherwise we'd have accessibility complications. Let me know if you have any other ideas.
| return ( | ||
| <div className="components-validated-control__wrapper-with-error-delegate"> | ||
| <ControlWithError | ||
| className="components-validated-control" |
There was a problem hiding this comment.
ControlWithError handles the messaging and also the styles of that message (red/green based on invalid/valid state). However, the consumer needs to also set other styles (e.g., border to red in invalid state) based on the data-validity-visible data attribute, etc.
This is a necessary first step, but it is also too low-level and requires tight coordination with how this works. We need to have the validated controls in UI to make this seamless to consumers.
There was a problem hiding this comment.
I'll also look into some ways to make custom composition easier.
| const ValidatedInputControl = forwardRef< | ||
| HTMLInputElement, | ||
| ValidatedInputControlProps | ||
| >( function ValidatedInputControl( | ||
| { required, markWhenOptional, customValidity, ...restProps }, | ||
| forwardedRef | ||
| ) { | ||
| const validityTargetRef = useRef< HTMLInputElement >( null ); | ||
| const mergedRefs = useMergeRefs( [ forwardedRef, validityTargetRef ] ); | ||
|
|
||
| return ( | ||
| <ControlWithError | ||
| required={ required } | ||
| markWhenOptional={ markWhenOptional } | ||
| customValidity={ customValidity } | ||
| getValidityTarget={ () => validityTargetRef.current } | ||
| > | ||
| <InputControl ref={ mergedRefs } { ...restProps } /> | ||
| </ControlWithError> | ||
| ); | ||
| } ); |
There was a problem hiding this comment.
This should be replaced by the actual validated control that uses ControWithError in follow-ups.
There was a problem hiding this comment.
Switched to a more generic fixture for purity instead (026550c). This would also check that we're not implicitly relying on Base UI behaviors.
| import { ValidatedRangeControl } from '../components'; | ||
|
|
||
| describe( 'ValidatedRangeControl', () => { | ||
| it( 'should accessibly label the internal slider and spin button', () => { |
There was a problem hiding this comment.
This has been moved from the ControWithError test verbatim.
There was a problem hiding this comment.
This was actually a regression test for a bug fix in ControlWithError itself, and since ValidatedRangeControl can plausibly be removed altogether at some point, I moved this test back (as a more generic version) to the ControlWithError suite (e86579d).
| @@ -503,33 +541,6 @@ describe( 'ControlWithError', () => { | |||
| } ); | |||
| } ); | |||
|
|
|||
| describe( 'ValidatedRangeControl', () => { | |||
There was a problem hiding this comment.
Moved to the own control's test suite.
|
I've tested these changes across UI, DataViews, and Components packages (validated controls) and it's working as expected. |
The changelog CI check requires each entry to link to the PR that introduces it; the entries previously linked only the tracking issue. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The Storybook manifest check requires every manifest-tagged component to carry a JSDoc description, and the committed snapshot to include the new ControlWithError and ValidityIndicator entries. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… control The error message was only re-read from the DOM in effects and on `invalid` events, so with an uncontrolled child control (which does not re-render on typing) a reported constraint violation stayed on screen after the user had resolved it. Re-read the validity when an `input` event bubbles up from the control, keeping the async `validating` indicator untouched, as the invalid handler already does. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Match the DataForm validated controls: when a control inside InputLayout is :invalid and ControlWithError has marked its validity as visible (data-validity-visible), paint the border with the interactive error stroke token, deepening on hover. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
56e2364 to
f19010a
Compare
|
Flaky tests detected in f19010a. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/32366112047 Should save the changes in
|
The focus ring on InputLayout is painted by the unlayered global-css defense rule, whose outline variable hardcoded the neutral focus token. Honor the --focus-color hook there (as the base-styles outset-ring mixin already does) and set it to the interactive error stroke while an invalid control's validity is visible, so the ring matches the border. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Regenerates the committed manifest snapshot, which picks up the new ValidatedInputControl entry. The ControlWithError and ValidityIndicator entries (and the ValidityIndicator JSDoc) now land with the earlier PR in this stack (#81574). Part of #81230 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
mirka
left a comment
There was a problem hiding this comment.
Looks good! Thanks for the move, thoughtfully executed. I went ahead and made some tweaks.
Since it seems you'll be away tomorrow, in the interest of time I'll look into the uncontrolled mode thing and see if it's something we can punt for this PR.
| @@ -0,0 +1,2 @@ | |||
| export { ControlWithError } from './control-with-error'; | |||
| export { ValidityIndicator } from './validity-indicator'; | |||
There was a problem hiding this comment.
we'd get error message on each individual control
The first approach I would try is using a ValidatedInputControl for each date field, but by default get the errors to mark the first field. Most errors can be marked on the first field, even if it's technically an error for both fields combined, e.g. "End date is earlier than start date", "Please fill in this field" (when both fields are empty), etc. In the screenshot's case where it's clearly the second field that should get the error, then you mark the second field. If that's a problem visual-wise, then I think you could maybe just mark the first field for all errors, even if it's like "Please fill in the end date". As long as we have an appropriate fieldset grouping or something.
Would that work, or are there other cases?
I think you generally do need to mark (semantics + focus) exactly one element for any given error. Otherwise we'd have accessibility complications. Let me know if you have any other ideas.
| import { ValidatedRangeControl } from '../components'; | ||
|
|
||
| describe( 'ValidatedRangeControl', () => { | ||
| it( 'should accessibly label the internal slider and spin button', () => { |
There was a problem hiding this comment.
This was actually a regression test for a bug fix in ControlWithError itself, and since ValidatedRangeControl can plausibly be removed altogether at some point, I moved this test back (as a more generic version) to the ControlWithError suite (e86579d).
| const ValidatedInputControl = forwardRef< | ||
| HTMLInputElement, | ||
| ValidatedInputControlProps | ||
| >( function ValidatedInputControl( | ||
| { required, markWhenOptional, customValidity, ...restProps }, | ||
| forwardedRef | ||
| ) { | ||
| const validityTargetRef = useRef< HTMLInputElement >( null ); | ||
| const mergedRefs = useMergeRefs( [ forwardedRef, validityTargetRef ] ); | ||
|
|
||
| return ( | ||
| <ControlWithError | ||
| required={ required } | ||
| markWhenOptional={ markWhenOptional } | ||
| customValidity={ customValidity } | ||
| getValidityTarget={ () => validityTargetRef.current } | ||
| > | ||
| <InputControl ref={ mergedRefs } { ...restProps } /> | ||
| </ControlWithError> | ||
| ); | ||
| } ); |
There was a problem hiding this comment.
Switched to a more generic fixture for purity instead (026550c). This would also check that we're not implicitly relying on Base UI behaviors.
| return ( | ||
| <div className="components-validated-control__wrapper-with-error-delegate"> | ||
| <ControlWithError | ||
| className="components-validated-control" |
There was a problem hiding this comment.
I'll also look into some ways to make custom composition easier.
| // Keep the message in sync while the user edits the control. Editing does | ||
| // not necessarily re-render this component (e.g. when the child control is | ||
| // uncontrolled), so the validity must be re-read from the DOM when an | ||
| // `input` event bubbles up from the control. | ||
| const onInput = () => { | ||
| // While async validation is pending, keep its indicator instead of | ||
| // showing a message its result may supersede. | ||
| if ( customValidity?.type !== 'validating' ) { | ||
| setErrorMessage( getValidityTarget()?.validationMessage ); | ||
| } | ||
| }; | ||
|
|
There was a problem hiding this comment.
Was this newly added in this PR? Can it be punted to a separate PR so we can discuss/review/test without blocking this migration PR? Or is it actually a blocker to the migration?
I think I understand what this is trying to solve, but some initial concerns with the approach:
ControlWithErrorisn't just forinputs.- The validated components are documented to only support controlled usage at the moment. This is just because we didn't have time to test uncontrolled use cases, but that also means that uncontrolled use cases are really not tested at all yet. So it's unclear whether this particular approach is sufficient to now fully support uncontrolled mode, or if there are bad interactions that are still unaccounted for.
If this is a real blocker, we can merge and follow up later, but if not, I think it'd be safer to remove for now. (Also consider using controlled mode if possible.)
There was a problem hiding this comment.
As far as I could tell, this was never on trunk and is not used in any production instances, so I'll go ahead and remove it for now (d596cc9).
| /* | ||
| * `data-validity-visible` is set by `ControlWithError` once the | ||
| * control's validation state should be reported to the user. | ||
| */ | ||
| &:has(:invalid[data-validity-visible]) { | ||
| /* Read by the shared focus-ring mixin, so the ring matches the border. */ | ||
| --focus-color: var(--wpds-color-stroke-interactive-error); | ||
|
|
||
| border-color: var(--wpds-color-stroke-interactive-error); | ||
|
|
||
| &:hover { | ||
| border-color: var(--wpds-color-stroke-interactive-error-active); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
This is temporary — I plan on changing the styling architecture so that this is less fragile. Maybe ControlWithError adds a data-has-visible-error data attribute to the underlying control component directly (not the raw validity target element), and the controls components are responsible for styling themselves based on that.
Regenerates the committed manifest snapshot, which picks up the new ValidatedInputControl entry. The ControlWithError and ValidityIndicator entries (and the ValidityIndicator JSDoc) now land with the earlier PR in this stack (#81574). Part of #81230 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* UI: Add ValidatedInputControl component Wraps the existing InputControl in ControlWithError, following the same composition used by the validated form controls in @wordpress/components and @wordpress/dataviews, with stories and unit tests. Part of #81230 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * DataViews: Use ValidatedInputControl from @wordpress/ui Replaces the ValidatedInputControl unlocked from the @wordpress/components private APIs in the text, email, telephone, url, password, color, datetime, and time controls. Prefixes and suffixes move from the components InputControl wrappers to InputLayout.Slot from @wordpress/ui. The DataForm test harness now applies edits back to the data prop, the way real consumers do: the new input is strictly controlled, so typed characters only accumulate when the value is fed back. Part of #81230 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Block editor: Compose URLInput validation with ControlWithError Replaces the ValidatedInputControl unlocked from the @wordpress/components private APIs with an inline composition of ControlWithError from @wordpress/ui around the same components InputControl, preserving the rendered DOM and behavior. Part of #81230 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Format library: Compose math input validation with ControlWithError Replaces the ValidatedInputControl unlocked from the @wordpress/components private APIs with an inline composition of ControlWithError from @wordpress/ui around the same components InputControl, preserving the rendered DOM and behavior. Part of #81230 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Components: Remove ValidatedInputControl All consumers now use ValidatedInputControl from @wordpress/ui, or compose ControlWithError from @wordpress/ui directly. The validated form controls overview docs now use ValidatedTextareaControl, which remains in this package, as their exemplar. Part of #81230 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * UI: Add ValidatedInputControl to the Storybook manifest snapshot Regenerates the committed manifest snapshot, which picks up the new ValidatedInputControl entry. The ControlWithError and ValidityIndicator entries (and the ValidityIndicator JSDoc) now land with the earlier PR in this stack (#81574). Part of #81230 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Format library: Use ValidatedInputControl from @wordpress/ui in the math popover Replaces the inline composition of ControlWithError around the components InputControl with ValidatedInputControl from @wordpress/ui, adopting the design-system input. Validation behavior is unchanged (same ControlWithError contract); the field renders with the new InputLayout styling and, unlike the components version, shows no red border in the invalid state — the inline message is the only signal, matching the DataViews controls. Part of #81230 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Fix ControlWithError import path in ValidatedInputControl * Move ValidatedInputControl into with-validation folder * Extract shared formDecorator for validation stories * Remove ValidatedInputControl from Storybook manifest * Add shared ValidatedControlProps for with-validation controls * Move validated form controls overview to @wordpress/ui. Add a stub page in components that links to the new docs. * Tweak overview * Remove WithDescriptionReplacement overview story. * Deprecate ValidatedInputControl private API instead of removing it. * Restore ValidatedInputControl ordering in private APIs and changelog. * Restore ValidatedInputControl export order in index. * Revert URLInput validation migration. * Fix changelog links. * Expect ValidatedInputControl deprecation in URL validation tests. * Move deprecation test helper into fixtures folder. --------- Co-authored-by: oandregal <oandregal@git.wordpress.org> Co-authored-by: mirka <0mirka00@git.wordpress.org>
| @@ -1,2 +1 @@ | |||
| export * from './components'; | |||
| export * from './control-with-error'; | |||
There was a problem hiding this comment.
@mirka wouldn't this cause issues if a consumer uses a DataViews version that depends on the ControlWithError or ValidityIndicator components exposed via the wp.components.privateApis global?
There was a problem hiding this comment.
I got the impression that we shouldn't remove these private APIs but rather deprecate them and keep them for 2 major WordPress versions (related).
There was a problem hiding this comment.
Actually, scratch that. I just double-checked plus checked history and they had never been exported via the private APIs.
This updates the pinned commit hash of the Gutenberg repository from `ae8b34d78e1abc6d1c866fdc00080a1452de82ad ` (version `23.8.0`) to `658c8cbe89db5d90279051d3bb816ca210fe4646` (version `23.9.0`). A full list of changes included in this commit can be found on GitHub: https://github.com/WordPress/gutenberg/compare/v23.8.0..v23.9.0. - Env: Update git to latest commit when `--update` passed (WordPress/gutenberg#81447) - InputControl: Vertically center date and time input values in Safari (WordPress/gutenberg#81361) - DataViews: vendor `ValidatedComboboxControl` (WordPress/gutenberg#81449) - Icon: Fix margin being applied twice in the editor (WordPress/gutenberg#81292) - Docs: Add Background image control Readme (WordPress/gutenberg#69409) - Dimensions: Fix aspect ratio and scale controls not reflecting external updates (WordPress/gutenberg#80747) - DataViews: vendor `ValidatedFormTokenField` (WordPress/gutenberg#81451) - Docs: Fix dead link in the dynamic blocks tutorial (WordPress/gutenberg#81399) - DataViews: vendor `ValidatedToggleGroupControl` (WordPress/gutenberg#81450) - Update 23.8 release changes on trunk (WordPress/gutenberg#81485) - Adds README for inspector-controls-tabs component (WordPress/gutenberg#69072) - BlockEditVisuallyButton: Update Developer Documentation (WordPress/gutenberg#68987) - Storybook: Upgrade Vite to 8 (WordPress/gutenberg#81494) - Packages: Move unreleased changelog entries out of the 23.8 published versions (WordPress/gutenberg#81502) - Theme: Avoid root-level relational selectors (WordPress/gutenberg#81457) - Theme: Move changelog entry to unreleased (WordPress/gutenberg#81508) - Admin UI: Add Navigation component and Page navigation slot (WordPress/gutenberg#79746) - Editor: Correctly mark ToolsMoreMenuGroup as a private SlotFill (WordPress/gutenberg#81503) - Fix: Term Description block skips display filters inside Terms Query. (WordPress/gutenberg#81290) - DataForm: Fix the datetime control sending two updates per calendar interaction (WordPress/gutenberg#81440) - Editor: Stop `:has()` selectors recalculating the whole document on every block selection (WordPress/gutenberg#81471) - Fix: getQueryArgs discards everything after the second = in a query argument value (WordPress/gutenberg#81066) - DOM: treat a caret at a soft line wrap as an ambiguous position in Firefox (WordPress/gutenberg#81003) - In-between indicator: make symmetric (WordPress/gutenberg#68074) - Fix: Delete key on empty heading transforms following paragraph into heading (WordPress/gutenberg#78779) - Media editor: keep initial modal focus on the dialog frame (WordPress/gutenberg#81541) - Writing flow: select next block on Enter key (WordPress/gutenberg#63484) - Media Editor Route Experiment: Override media edit links to point to the new experimental media editor (WordPress/gutenberg#81559) - DataViews: vendor `ValidatedToggleControl` (WordPress/gutenberg#81492) - Release: Improve changelog categorization (WordPress/gutenberg#81475) - Docs: Add Block Editing Mode Readme. (WordPress/gutenberg#69411) - Editor: Use PluginSidebar in GlobalStylesSidebar (WordPress/gutenberg#81570) - Docs: Fix broken links to the Block API reference guides. (WordPress/gutenberg#81571) - Adds JSdoc for `column` and `columns` block's edit.js (WordPress/gutenberg#68873) - Adds JSdoc for `audio` block's edit.js (WordPress/gutenberg#68865) - Refactor: Convert `createColorHOC` to functional component (WordPress/gutenberg#70408) - Adds JSdoc for `avatar` block's edit.js (WordPress/gutenberg#68867) - Editor: Speed up the hierarchical term selector for large taxonomies (WordPress/gutenberg#81376) - Extensible Site Editor: Preview the site on Home for classic themes (WordPress/gutenberg#81578) - TypeScript: Add typecheck script and split root tsconfig into build and dev solutions (WordPress/gutenberg#81499) - Packages: Split blob, grid, interactivity, and theme tsconfigs (WordPress/gutenberg#81509) - Vitest: Resolve @flakiness/vitest reporter to an absolute path (WordPress/gutenberg#81582) - Update waveform player dependency patch (WordPress/gutenberg#81454) - Dashboard Widgets: promote high-relevance actions into a chrome footer (WordPress/gutenberg#81556) - Extensible Site Editor: Gate theme screens on theme support (WordPress/gutenberg#81581) - Editor: Register the editor keyboard shortcuts from the provider (WordPress/gutenberg#81580) - Base styles: Streamline focus ring override (WordPress/gutenberg#81242) - Components: Align legacy form control focus rings with WPDS (WordPress/gutenberg#80417) - Base Styles: Align `input-control` mixin to design system (WordPress/gutenberg#81357) - Add Gutenberg version details for WordPress 7.1 (WordPress/gutenberg#81600) - Fix viewport state values set by grid resizer (WordPress/gutenberg#81601) - Block editor: add an inserter to the parent selector (WordPress/gutenberg#81532) - url: clamp the truncated file name slice in filterURLForDisplay (WordPress/gutenberg#81529) - Fix parent inserter alignment with text labels enabled (WordPress/gutenberg#81608) - URL: Stop normalizePath throwing on a malformed percent sequence (WordPress/gutenberg#81086) - Extensible Site Editor: Add the Identity route (WordPress/gutenberg#81576) - ComboboxControl: narrow `onChange` callback type to `string` | `null` (WordPress/gutenberg#81568) - Storybook: Add Story for URLPopup component (WordPress/gutenberg#68449) - Extensible Site Editor: Show only the style book on Styles for classic themes (WordPress/gutenberg#81579) - Global Styles: Expose additional elements in Typography and Colors (WordPress/gutenberg#80852) - Storybook: Add Story for BlockPopover (WordPress/gutenberg#68681) - Block Editor: Never spotlight blocks in a preview (WordPress/gutenberg#81615) - Boot: Let the editor canvas navigate between entity records (WordPress/gutenberg#81590) - Block API: Declare block keyboard shortcuts on variations and transforms (WordPress/gutenberg#81588) - Storybook: Add Story for InnerBlocks (WordPress/gutenberg#68651) - Boot: Translate the canvas click-to-edit label (WordPress/gutenberg#81620) - Perf: Report the first block selection as its own metric (WordPress/gutenberg#81616) - Boot: Contain a surface failure to that surface (WordPress/gutenberg#81622) - Boot: Warn before leaving with unsaved changes (WordPress/gutenberg#81625) - Env: Fall back to cached docker images when the registry is unreachable (WordPress/gutenberg#81631) - Editor: Refactor 'ErrorBoundary' to use the new recommended components (WordPress/gutenberg#81638) - Fix playlist track toolbar insertion (WordPress/gutenberg#81639) - Playlist Track: Show upload spinner inline (WordPress/gutenberg#81445) - Admin UI: Fix the primary color of the Fresh admin color scheme (WordPress/gutenberg#81618) - Inner Blocks: Fix bug that caused alignment controls to show in Image blocks within a Gallery (WordPress/gutenberg#81606) - Layout block supports: cast numeric grid attributes before use (WordPress/gutenberg#81560) - Make Back button grid column flexible. (WordPress/gutenberg#81701) - List View: Make focus on mount opt in (WordPress/gutenberg#81659) - Lazy Editor: Render the editor preferences modal (WordPress/gutenberg#81630) - Edit Site Init: Seed the editor preferences the editor expects (WordPress/gutenberg#81628) - Boot: Do not offer to edit a trashed entity (WordPress/gutenberg#81632) - Block API: Address review feedback on block keyboard shortcuts (WordPress/gutenberg#81621) - Editor: Simplify List View sidebar shortcut handling (WordPress/gutenberg#81693) - RichText: Use the current record when handling Enter (WordPress/gutenberg#81696) - Boot: Sync the editor's device preview with the URL (WordPress/gutenberg#81617) - Stop saving Table of Contents output (WordPress/gutenberg#80404) - Lazy Editor: Keep the theme's editor styles on the canvas (WordPress/gutenberg#81747) - List View: Fix flaky global shortcut test and re-enable it (WordPress/gutenberg#81690) - Boot: Preview the site where the canvas has nothing to open (WordPress/gutenberg#81749) - Docs: Require site editor features to land in the extensible site editor too (WordPress/gutenberg#81752) - Build Tools: Stop watcher process trees on shutdown (WordPress/gutenberg#81504) - Update Terrazzo packages to 2.5.0 (WordPress/gutenberg#81082) - Site Editor: Use inverted ThemeProvider seed for portaled UI (WordPress/gutenberg#81653) - Components: Migrate DropdownContentWrapper to SCSS module (WordPress/gutenberg#81522) - Playlist: Add aria-label to prevent placeholder as label (WordPress/gutenberg#81654) - UI: Collapse item-popup item sizing to default and small (WordPress/gutenberg#81354) - Add `__unstable_wp_sync_storage` filter for pluggable storage backends (WordPress/gutenberg#81697) - Bump github/codeql-action/upload-sarif (WordPress/gutenberg#81436) - Feat: support block spacing (WordPress/gutenberg#79689) - Enable axial gap for Group and restrict to flex and grid layouts. (WordPress/gutenberg#81476) - Packages: Split tsconfigs for utility and mid-size packages (WordPress/gutenberg#81514) - Media Editor Route: Make the route look like it's part of the media menu in the left-hand sidebar (WordPress/gutenberg#81565) - Global Styles: filter and indicate blocks that have custom styles (WordPress/gutenberg#81373) - Prevent white screen crash during undo operations when Media Modal is open (WordPress/gutenberg#79898) - Fix clipped focus outlines in the media editor Details sidebar (WordPress/gutenberg#81703) - Fix: URL: normalizePath drops the rest of the query after a second "?" (WordPress/gutenberg#81612) - Block Editor: Add translator context to pseudo-state labels (WordPress/gutenberg#81770) - Global styles: Register <label> as element (WordPress/gutenberg#81160) - Site editor: update template section description. (WordPress/gutenberg#81613) - Fix: Accordion: Anchored hash inside the accordion throws the malformed URL console error (WordPress/gutenberg#81780) - BoxControl: update the opposite side when ALT is held on the left or right input (WordPress/gutenberg#81530) - Tabs: Give tab IDs their own counter so numbering starts at 1 and never skips (WordPress/gutenberg#81781) - Modal: Stop Escape key propagation on dismiss (WordPress/gutenberg#81785) - RTC: Couple RTC and polling provider as an opt-in experiment (WordPress/gutenberg#80658) - ui/Card: Use the default neutral border (WordPress/gutenberg#81746) - Update playlist track placeholder to match aria label (WordPress/gutenberg#81762) - Notes: keep the note actions menu in view for long display names (WordPress/gutenberg#81414) - Fix DataViews list layout color token usage (WordPress/gutenberg#81074) - UI: Add Spinner component (WordPress/gutenberg#81358) - Fields: Export the package stylesheet (WordPress/gutenberg#81769) - Fix the failing e2e test (WordPress/gutenberg#81739) - RTC: Add fallback identities when user profiles are unavailable (WordPress/gutenberg#81408) - Align collaboration migration version markers with the 23.8.0 release (WordPress/gutenberg#81789) - Dashboard: add a Site Health detail page as the dashboard's second route (WordPress/gutenberg#81729) - Dashboard Widgets: resolve widget types without a metadata module (WordPress/gutenberg#81738) - Theme: Improve color ramp contrast safeguards (WordPress/gutenberg#81185) - More block: clarify description about excerpt vs full content (WordPress/gutenberg#80619) - Schemas: Document what the theme.json schema checks (WordPress/gutenberg#81773) - Components, DataViews, Editor, UI: Split tsconfigs into build and dev projects (WordPress/gutenberg#81515) - Command Palette: Allow commands to override the category icon (WordPress/gutenberg#81787) - Fix Broken Links in Package file (WordPress/gutenberg#81700) - Notes: Stop forcing capitalization of user names (WordPress/gutenberg#81788) - Media Editor Route: Add undo/redo and save/cancel actions to the header (WordPress/gutenberg#81563) - Fix: Post Editor: Canvas animates from the left when switching mobile/tablet preview to desktop (WordPress/gutenberg#81484) - Build Package: Use Core's boot module when a plugin has none (WordPress/gutenberg#81761) - Docs: Fix broken link to the Document-Isolation-Policy explainer. (WordPress/gutenberg#81790) - Tests: Make PHPUnit tests independent of test config flags and theme root (WordPress/gutenberg#79159) - Editor: Debounce term filtering and announce results once (WordPress/gutenberg#81422) - Packages: Split story package tsconfigs into build and dev projects (WordPress/gutenberg#81516) - Packages: Complete the tsconfig build and dev project split (WordPress/gutenberg#81517) - TypeScript: Require the typecheck run for type checking in CI (WordPress/gutenberg#81518) - Block Editor: Remove leftover files (WordPress/gutenberg#81793) - Rename the media editor toolbar button to 'Edit image' (WordPress/gutenberg#81705) - Playlist: Remove block toolbar sharing between parent and child blocks (WordPress/gutenberg#81432) - Components: Fix Storybook accessibility issues in stories (WordPress/gutenberg#81777) - Fields: migrate last remaining JS file to TS (WordPress/gutenberg#81808) - Menu: Add UI component (WordPress/gutenberg#79560) - Patterns explorer: Refactor the category sidebar to use Tabs (WordPress/gutenberg#81807) - add context to change "revisions code diff" (WordPress/gutenberg#81820) - Add command: View post (WordPress/gutenberg#66720) - Fix: Post Editor: 403 on /wp/v2/settings at boot for users without manage_options cap (WordPress/gutenberg#81813) - UI: Add initial agents guidance mapping to contributing guidelines (WordPress/gutenberg#81400) - UI: Mark Input-related components as recommended (WordPress/gutenberg#81658) - Post Template: Fix mover arrows and labels for blocks inside the grid view (WordPress/gutenberg#81120) - Docs: Fix broken link to the getEntityRecords selector reference. (WordPress/gutenberg#81791) - Quick Inserter: Standardize the design of the Browse all button (WordPress/gutenberg#81827) - UI: Add TextareaControl component (WordPress/gutenberg#81359) - Docs: Narrow the tsconfig split guidance to the standard layout (WordPress/gutenberg#81828) - Storybook: Fix production build warnings (WordPress/gutenberg#81758) - Components: migrate ResizableBox to SCSS module- WordPress/gutenberg#80720 (WordPress/gutenberg#81792) - Bump astral-sh/setup-uv from 9.0.0 to 10.0.0 in /.github/workflows (WordPress/gutenberg#81823) - Global Styles: Keep storing shadow presets as CSS variables when custom presets exist (WordPress/gutenberg#81346) - Docs: Fix broken skip ahead anchor on the custom block editor guide. (WordPress/gutenberg#81835) - Fix MediaPlaceholder drag eligibility (WordPress/gutenberg#81431) - Updated Aria Landmark Example URL (WordPress/gutenberg#81832) - TypeScript: Put route projects under the typecheck run (WordPress/gutenberg#81829) - Add missing dependency to media-editor route (WordPress/gutenberg#81845) - Add transform to Row for Columns block (WordPress/gutenberg#81802) - Editor: Remove FlexItem usage from NoteCard (WordPress/gutenberg#81851) - UI: Expose keyboard shortcut presentation utilities (WordPress/gutenberg#81826) - Theme: Add color warning diagnostics workbench (WordPress/gutenberg#81817) - Editor: Surface debugging details in the ErrorBoundary (WordPress/gutenberg#81642) - Update save & submit docs (WordPress/gutenberg#81077) - Boot: Migrate styles to CSS Modules (WordPress/gutenberg#81756) - Build: Emit TypeScript declarations with --noCheck (WordPress/gutenberg#81839) - Core Data: Validate the parsed-blocks cache against registered block types (WordPress/gutenberg#81809) - Dependencies: Dedupe, update adm-zip, nx (WordPress/gutenberg#81870) - Core Data: Allow keyless entities to be addressed without a record ID (WordPress/gutenberg#81857) - UI: Mark Autocomplete, Field, and Fieldset as recommended (WordPress/gutenberg#80636) - Editor: Announce publish date changes to screen readers (WordPress/gutenberg#81629) - Storybook: Fix default background color for Example Application theme story (WordPress/gutenberg#81765) - Fix/79641 rtc cursor hidden details block v2 (WordPress/gutenberg#81322) - UI: add ControlWithError component (WordPress/gutenberg#81574) - Global Styles: Group shadow editor rows as items (WordPress/gutenberg#81871) - Storybook: Handle production module load failures (WordPress/gutenberg#81867) - Pattern: Disable visibility support (WordPress/gutenberg#81866) - Design System: Add portable agent skills (WordPress/gutenberg#80597) - Global Styles: Allow editing duotone palettes (WordPress/gutenberg#81605) - Color Palette panel: Remove empty whitespace when there are no theme colors (WordPress/gutenberg#81894) - Try caching gutenberg_get_global_styles (WordPress/gutenberg#81889) - Refactor parameter type hints and clean comments (WordPress/gutenberg#81898) - Preserve layout and style attributes on Column transform (WordPress/gutenberg#81855) - Global Styles: Close the revisions screen on the first back click (WordPress/gutenberg#81897) - Editor: Set the width an entity opens at from the editor provider (WordPress/gutenberg#81750) - Pre-publish panel: Remove the headings that repeat the panel title (WordPress/gutenberg#81806) - Components: migrate ComboboxControl to SCSS module (WordPress/gutenberg#80471) - UI: Update Base UI to 1.7.0 (WordPress/gutenberg#81390) - Update Ariakit packages (0.4.35 => 0.4.37) (WordPress/gutenberg#81080) - chore: Update the combobox SCSS to have a breaking changes log (WordPress/gutenberg#81923) - Use `WCTextareaControl` alias for legacy TextareaControl imports (WordPress/gutenberg#81834) - Components: Improve text detection for button icon-with-text (WordPress/gutenberg#81521) - Font Library: Fix the preview weight for variable fonts (WordPress/gutenberg#81748) - Editor: Migrate hierarchical term selector to @wordpress/ui (WordPress/gutenberg#81848) - Validation: update dependency-audit to 0.4.6 and ignore dataviews ./wp bundle (WordPress/gutenberg#81928) - SearchableChipSelect: Add grouped items support (WordPress/gutenberg#80989) - Use `WCInputControl` alias for legacy InputControl imports (WordPress/gutenberg#81830) - Storybook: Upgrade to 10.5 (WordPress/gutenberg#80692) - Documentation: Update coding guidelines to recommend TypeScript (WordPress/gutenberg#81763) - Font library: Add skeleton loader for the font preview images (WordPress/gutenberg#81047) - Build Scripts: Force tsc --pretty so CI reports the project behind global diagnostics (WordPress/gutenberg#81937) - Update is-plain-object to 5.1.0 (WordPress/gutenberg#81926) - DataViews: Sync the displayed calendar month with external value changes (WordPress/gutenberg#81635) - DataForm: Make the panel layout edit button the real field trigger (WordPress/gutenberg#80689) - Dependency updates Aug 2026 (2) (WordPress/gutenberg#81906) - Playlist: Add bulk track metadata editing (WordPress/gutenberg#81441) - Automated Testing: Change Storybook default a11y test to error on failure (WordPress/gutenberg#81597) - Playlist Track: Improve track upload error flows (WordPress/gutenberg#81878) - Block Library: Fix failing test in playlist block (WordPress/gutenberg#81950) - Block editor: Move isElementVisible changelog entry to Unreleased (WordPress/gutenberg#81953: shail-mehta <shailu25@git.wordpress.org> Co-authored-by: Mamaduka <mamaduka@git.wordpress.org> - DataViews: Fix date and datetime controls selecting the adjacent day (WordPress/gutenberg#81498) - UI: Accept locale codes in Calendar components (WordPress/gutenberg#81814) - List: Add Align Support (WordPress/gutenberg#68002) - TypeScript: Bring the remaining route projects under the typecheck run (WordPress/gutenberg#81847) - Components: migrate GradientPicker, ColorPalette to SCSS module (WordPress/gutenberg#80473) - Docs: Align @PARAM tag columns in test/ docblocks (WordPress/gutenberg#81905) - Hide layout panel when no controls are available (WordPress/gutenberg#81968) - UI: Add ValidatedInputControl component (WordPress/gutenberg#81627) - Components: migrate StyledLabel to SCSS module (WordPress/gutenberg#80001) - fix: Button rtl loader issue (WordPress/gutenberg#81901) - Theme: Update Terrazzo packages to 2.7.1 (WordPress/gutenberg#81978) - CollapsibleCard: Support multiple header descriptions (WordPress/gutenberg#81227) - DataViews: use `Menu` from `@wordpress/ui` (WordPress/gutenberg#81783) - DataViews: Localize the date/datetime calendars from the site locale and direction (WordPress/gutenberg#81592) - Replace the Storybook test runner with the Vitest integration (WordPress/gutenberg#81918) - Block Editor: Don't close inserter panel when inline quick inserter opens (WordPress/gutenberg#76241) - Updated broken links in document files (WordPress/gutenberg#81961) - Boot: Mount the registered plugins (WordPress/gutenberg#81754) - Extensible Site Editor: Add a theme preview page with global styles editing (WordPress/gutenberg#81954) - Block Styles: Refactor the variation UI to use ui/Button (WordPress/gutenberg#81833) - Styles Route: Reference the api-fetch and html-entities projects (WordPress/gutenberg#81989) - Fix: Line Break Tags Added to Scripts and Styles (WordPress/gutenberg#77542) - Fix: skip empty block markup in navigation to prevent split UL elements (WordPress/gutenberg#78793) - Pattern List: Import a pattern from JSON (WordPress/gutenberg#81919) - UI: Add tooltips to Calendar and RangeCalendar navigation buttons (WordPress/gutenberg#81983) - UI: Add `ValidatedTextArea` control (WordPress/gutenberg#81984) - Fix: Responsive styles: When enabled and a font-size is setting, the corresponding CSS variable remains undefined (WordPress/gutenberg#81854) - Components: Migrate `TextareaControl` to SCSS module (WordPress/gutenberg#81353) - UI: Set Calendar text direction automatically (WordPress/gutenberg#81982) - Theme: Rename ThemeProvider wrapper CSS class from root to wrapper (WordPress/gutenberg#81996) - Editor: Offer the theme export from both site editors (WordPress/gutenberg#81992) - Fix: Stop stripping spaces inside inline HTML elements on paste (WordPress/gutenberg#76696) - DataViews: Add a lint rule preventing private API imports (WordPress/gutenberg#81478) - Components: Migrate ProgressBar styles from Emotion to SCSS module (WordPress/gutenberg#80512) - RTC: Disable syncing for unpersistable post types (WordPress/gutenberg#81946) - Boot: Restore centered snackbar notices (WordPress/gutenberg#81995) - BorderControl, BorderBoxControl: Migrate styles to CSS Modules (WordPress/gutenberg#80437) - Duotone Picker: Stop the duotone bar offering to move its control points (WordPress/gutenberg#81850) - DataViews: Add an aspect ratio toggle for grid layouts (WordPress/gutenberg#81604) - Remove `fixable` on `i18n-no-flanking-whitespace` (WordPress/gutenberg#70279) - Dynamic Gallery block: Skip transforms that expect inner blocks, e.g. Image and Grid transforms (WordPress/gutenberg#82009) - Accordion Heading: Route theme.json spacing to the toggle button (WordPress/gutenberg#81976) - Element: Serialize memo-wrapped components instead of an empty string (WordPress/gutenberg#81986) - Style: Update color to use CSS variable in global-styles-ui (WordPress/gutenberg#79053) - Dashboard Widgets: let the host decide which component renders an action link (WordPress/gutenberg#81740) - Tabs: make inactive panel content findable in page (WordPress/gutenberg#81743) - Border Panel: Fix incorrect panel label (WordPress/gutenberg#78830) - Components: Migrate ZStack styles from Emotion to SCSS module (WordPress/gutenberg#80514) - Storybook: Add missing @types/jest devDependency (WordPress/gutenberg#82017) - TypeScript: Drop redundant undefined casts for keyless entity record IDs (WordPress/gutenberg#82018) - Editor: Fix start page/template modal footer overflow (WordPress/gutenberg#82021) - Storybook: Keep Vitest story scanning independent of the Vite root (WordPress/gutenberg#82020) - Test: Port shared Vitest test environment (WordPress/gutenberg#81038) - Query No Results: Add Border & Spacing Support (WordPress/gutenberg#64601) - RadioControl: allow individual options to be disabled (WordPress/gutenberg#82026) - Components: Migrate `BoxControl` to SCSS module (WordPress/gutenberg#80715) - SearchableChipSelectControl: Add form control to @wordpress/ui (WordPress/gutenberg#80980) - UI: Move controlled prop guidance to contributing docs (WordPress/gutenberg#82044) - Components: Migrate Scrollable to SCSS module (WordPress/gutenberg#80694) - UI: Fix accessibility issues in form primitives and their stories (WordPress/gutenberg#81853) - UI: Align Calendar styling with WPDS tokens (WordPress/gutenberg#81438) - Calendar: Support custom root roles (WordPress/gutenberg#81443) - E2E Tests: Use str_starts_with()/str_contains() in hide-user-rest-routes plugin (WordPress/gutenberg#82030) - Site editor v2: Fix block error with navigation-edit route (WordPress/gutenberg#82051) - ActionItem: Move the more menu deduplication out of the Slot (WordPress/gutenberg#81507) - DataViews: Fix invisible sticky Actions column divider (WordPress/gutenberg#82055) - Quick draft: replace Button+Link with LinkButton (WordPress/gutenberg#82031) - Lint: Prevent private API imports in all bundled packages (WordPress/gutenberg#82015) - PaletteEdit: Expose palette swatches as command buttons (WordPress/gutenberg#82023) - Test: Add Vitest React, Emotion compilation, console, and snapshot parity (WordPress/gutenberg#81039) - remove dead class reference in quick-draft (WordPress/gutenberg#82064) - `InputControl`: Hide the value-like placeholder Safari renders in empty date and time inputs in `ui` and `components` packages (WordPress/gutenberg#81991) - Site editor v2: Fix template part list pagination and sorting (WordPress/gutenberg#82054) - Build: Fix ESM declaration resolution (WordPress/gutenberg#82022) - Core Data: Stop storing NaN pagination totals for unpaginated endpoints (WordPress/gutenberg#82059) - Dashboard widgets & Grid: use kebab-case for CSS selectors (WordPress/gutenberg#82053) - CI: Skip the package CHANGELOG check when only the CHANGELOG changed (WordPress/gutenberg#82069) - Menu: Close non-modal menus on iframe interaction (WordPress/gutenberg#81952) - Packages: Recover August 26 npm release metadata (WordPress/gutenberg#82086) - Private APIs: Add back '@wordpress/dataviews' to the allowed core modules (WordPress/gutenberg#82221) Fixes #66067. git-svn-id: https://develop.svn.wordpress.org/trunk@63535 602fd350-edb4-49c9-b593-d223f7449a82
This updates the pinned commit hash of the Gutenberg repository from `ae8b34d78e1abc6d1c866fdc00080a1452de82ad ` (version `23.8.0`) to `658c8cbe89db5d90279051d3bb816ca210fe4646` (version `23.9.0`). A full list of changes included in this commit can be found on GitHub: https://github.com/WordPress/gutenberg/compare/v23.8.0..v23.9.0. - Env: Update git to latest commit when `--update` passed (WordPress/gutenberg#81447) - InputControl: Vertically center date and time input values in Safari (WordPress/gutenberg#81361) - DataViews: vendor `ValidatedComboboxControl` (WordPress/gutenberg#81449) - Icon: Fix margin being applied twice in the editor (WordPress/gutenberg#81292) - Docs: Add Background image control Readme (WordPress/gutenberg#69409) - Dimensions: Fix aspect ratio and scale controls not reflecting external updates (WordPress/gutenberg#80747) - DataViews: vendor `ValidatedFormTokenField` (WordPress/gutenberg#81451) - Docs: Fix dead link in the dynamic blocks tutorial (WordPress/gutenberg#81399) - DataViews: vendor `ValidatedToggleGroupControl` (WordPress/gutenberg#81450) - Update 23.8 release changes on trunk (WordPress/gutenberg#81485) - Adds README for inspector-controls-tabs component (WordPress/gutenberg#69072) - BlockEditVisuallyButton: Update Developer Documentation (WordPress/gutenberg#68987) - Storybook: Upgrade Vite to 8 (WordPress/gutenberg#81494) - Packages: Move unreleased changelog entries out of the 23.8 published versions (WordPress/gutenberg#81502) - Theme: Avoid root-level relational selectors (WordPress/gutenberg#81457) - Theme: Move changelog entry to unreleased (WordPress/gutenberg#81508) - Admin UI: Add Navigation component and Page navigation slot (WordPress/gutenberg#79746) - Editor: Correctly mark ToolsMoreMenuGroup as a private SlotFill (WordPress/gutenberg#81503) - Fix: Term Description block skips display filters inside Terms Query. (WordPress/gutenberg#81290) - DataForm: Fix the datetime control sending two updates per calendar interaction (WordPress/gutenberg#81440) - Editor: Stop `:has()` selectors recalculating the whole document on every block selection (WordPress/gutenberg#81471) - Fix: getQueryArgs discards everything after the second = in a query argument value (WordPress/gutenberg#81066) - DOM: treat a caret at a soft line wrap as an ambiguous position in Firefox (WordPress/gutenberg#81003) - In-between indicator: make symmetric (WordPress/gutenberg#68074) - Fix: Delete key on empty heading transforms following paragraph into heading (WordPress/gutenberg#78779) - Media editor: keep initial modal focus on the dialog frame (WordPress/gutenberg#81541) - Writing flow: select next block on Enter key (WordPress/gutenberg#63484) - Media Editor Route Experiment: Override media edit links to point to the new experimental media editor (WordPress/gutenberg#81559) - DataViews: vendor `ValidatedToggleControl` (WordPress/gutenberg#81492) - Release: Improve changelog categorization (WordPress/gutenberg#81475) - Docs: Add Block Editing Mode Readme. (WordPress/gutenberg#69411) - Editor: Use PluginSidebar in GlobalStylesSidebar (WordPress/gutenberg#81570) - Docs: Fix broken links to the Block API reference guides. (WordPress/gutenberg#81571) - Adds JSdoc for `column` and `columns` block's edit.js (WordPress/gutenberg#68873) - Adds JSdoc for `audio` block's edit.js (WordPress/gutenberg#68865) - Refactor: Convert `createColorHOC` to functional component (WordPress/gutenberg#70408) - Adds JSdoc for `avatar` block's edit.js (WordPress/gutenberg#68867) - Editor: Speed up the hierarchical term selector for large taxonomies (WordPress/gutenberg#81376) - Extensible Site Editor: Preview the site on Home for classic themes (WordPress/gutenberg#81578) - TypeScript: Add typecheck script and split root tsconfig into build and dev solutions (WordPress/gutenberg#81499) - Packages: Split blob, grid, interactivity, and theme tsconfigs (WordPress/gutenberg#81509) - Vitest: Resolve @flakiness/vitest reporter to an absolute path (WordPress/gutenberg#81582) - Update waveform player dependency patch (WordPress/gutenberg#81454) - Dashboard Widgets: promote high-relevance actions into a chrome footer (WordPress/gutenberg#81556) - Extensible Site Editor: Gate theme screens on theme support (WordPress/gutenberg#81581) - Editor: Register the editor keyboard shortcuts from the provider (WordPress/gutenberg#81580) - Base styles: Streamline focus ring override (WordPress/gutenberg#81242) - Components: Align legacy form control focus rings with WPDS (WordPress/gutenberg#80417) - Base Styles: Align `input-control` mixin to design system (WordPress/gutenberg#81357) - Add Gutenberg version details for WordPress 7.1 (WordPress/gutenberg#81600) - Fix viewport state values set by grid resizer (WordPress/gutenberg#81601) - Block editor: add an inserter to the parent selector (WordPress/gutenberg#81532) - url: clamp the truncated file name slice in filterURLForDisplay (WordPress/gutenberg#81529) - Fix parent inserter alignment with text labels enabled (WordPress/gutenberg#81608) - URL: Stop normalizePath throwing on a malformed percent sequence (WordPress/gutenberg#81086) - Extensible Site Editor: Add the Identity route (WordPress/gutenberg#81576) - ComboboxControl: narrow `onChange` callback type to `string` | `null` (WordPress/gutenberg#81568) - Storybook: Add Story for URLPopup component (WordPress/gutenberg#68449) - Extensible Site Editor: Show only the style book on Styles for classic themes (WordPress/gutenberg#81579) - Global Styles: Expose additional elements in Typography and Colors (WordPress/gutenberg#80852) - Storybook: Add Story for BlockPopover (WordPress/gutenberg#68681) - Block Editor: Never spotlight blocks in a preview (WordPress/gutenberg#81615) - Boot: Let the editor canvas navigate between entity records (WordPress/gutenberg#81590) - Block API: Declare block keyboard shortcuts on variations and transforms (WordPress/gutenberg#81588) - Storybook: Add Story for InnerBlocks (WordPress/gutenberg#68651) - Boot: Translate the canvas click-to-edit label (WordPress/gutenberg#81620) - Perf: Report the first block selection as its own metric (WordPress/gutenberg#81616) - Boot: Contain a surface failure to that surface (WordPress/gutenberg#81622) - Boot: Warn before leaving with unsaved changes (WordPress/gutenberg#81625) - Env: Fall back to cached docker images when the registry is unreachable (WordPress/gutenberg#81631) - Editor: Refactor 'ErrorBoundary' to use the new recommended components (WordPress/gutenberg#81638) - Fix playlist track toolbar insertion (WordPress/gutenberg#81639) - Playlist Track: Show upload spinner inline (WordPress/gutenberg#81445) - Admin UI: Fix the primary color of the Fresh admin color scheme (WordPress/gutenberg#81618) - Inner Blocks: Fix bug that caused alignment controls to show in Image blocks within a Gallery (WordPress/gutenberg#81606) - Layout block supports: cast numeric grid attributes before use (WordPress/gutenberg#81560) - Make Back button grid column flexible. (WordPress/gutenberg#81701) - List View: Make focus on mount opt in (WordPress/gutenberg#81659) - Lazy Editor: Render the editor preferences modal (WordPress/gutenberg#81630) - Edit Site Init: Seed the editor preferences the editor expects (WordPress/gutenberg#81628) - Boot: Do not offer to edit a trashed entity (WordPress/gutenberg#81632) - Block API: Address review feedback on block keyboard shortcuts (WordPress/gutenberg#81621) - Editor: Simplify List View sidebar shortcut handling (WordPress/gutenberg#81693) - RichText: Use the current record when handling Enter (WordPress/gutenberg#81696) - Boot: Sync the editor's device preview with the URL (WordPress/gutenberg#81617) - Stop saving Table of Contents output (WordPress/gutenberg#80404) - Lazy Editor: Keep the theme's editor styles on the canvas (WordPress/gutenberg#81747) - List View: Fix flaky global shortcut test and re-enable it (WordPress/gutenberg#81690) - Boot: Preview the site where the canvas has nothing to open (WordPress/gutenberg#81749) - Docs: Require site editor features to land in the extensible site editor too (WordPress/gutenberg#81752) - Build Tools: Stop watcher process trees on shutdown (WordPress/gutenberg#81504) - Update Terrazzo packages to 2.5.0 (WordPress/gutenberg#81082) - Site Editor: Use inverted ThemeProvider seed for portaled UI (WordPress/gutenberg#81653) - Components: Migrate DropdownContentWrapper to SCSS module (WordPress/gutenberg#81522) - Playlist: Add aria-label to prevent placeholder as label (WordPress/gutenberg#81654) - UI: Collapse item-popup item sizing to default and small (WordPress/gutenberg#81354) - Add `__unstable_wp_sync_storage` filter for pluggable storage backends (WordPress/gutenberg#81697) - Bump github/codeql-action/upload-sarif (WordPress/gutenberg#81436) - Feat: support block spacing (WordPress/gutenberg#79689) - Enable axial gap for Group and restrict to flex and grid layouts. (WordPress/gutenberg#81476) - Packages: Split tsconfigs for utility and mid-size packages (WordPress/gutenberg#81514) - Media Editor Route: Make the route look like it's part of the media menu in the left-hand sidebar (WordPress/gutenberg#81565) - Global Styles: filter and indicate blocks that have custom styles (WordPress/gutenberg#81373) - Prevent white screen crash during undo operations when Media Modal is open (WordPress/gutenberg#79898) - Fix clipped focus outlines in the media editor Details sidebar (WordPress/gutenberg#81703) - Fix: URL: normalizePath drops the rest of the query after a second "?" (WordPress/gutenberg#81612) - Block Editor: Add translator context to pseudo-state labels (WordPress/gutenberg#81770) - Global styles: Register <label> as element (WordPress/gutenberg#81160) - Site editor: update template section description. (WordPress/gutenberg#81613) - Fix: Accordion: Anchored hash inside the accordion throws the malformed URL console error (WordPress/gutenberg#81780) - BoxControl: update the opposite side when ALT is held on the left or right input (WordPress/gutenberg#81530) - Tabs: Give tab IDs their own counter so numbering starts at 1 and never skips (WordPress/gutenberg#81781) - Modal: Stop Escape key propagation on dismiss (WordPress/gutenberg#81785) - RTC: Couple RTC and polling provider as an opt-in experiment (WordPress/gutenberg#80658) - ui/Card: Use the default neutral border (WordPress/gutenberg#81746) - Update playlist track placeholder to match aria label (WordPress/gutenberg#81762) - Notes: keep the note actions menu in view for long display names (WordPress/gutenberg#81414) - Fix DataViews list layout color token usage (WordPress/gutenberg#81074) - UI: Add Spinner component (WordPress/gutenberg#81358) - Fields: Export the package stylesheet (WordPress/gutenberg#81769) - Fix the failing e2e test (WordPress/gutenberg#81739) - RTC: Add fallback identities when user profiles are unavailable (WordPress/gutenberg#81408) - Align collaboration migration version markers with the 23.8.0 release (WordPress/gutenberg#81789) - Dashboard: add a Site Health detail page as the dashboard's second route (WordPress/gutenberg#81729) - Dashboard Widgets: resolve widget types without a metadata module (WordPress/gutenberg#81738) - Theme: Improve color ramp contrast safeguards (WordPress/gutenberg#81185) - More block: clarify description about excerpt vs full content (WordPress/gutenberg#80619) - Schemas: Document what the theme.json schema checks (WordPress/gutenberg#81773) - Components, DataViews, Editor, UI: Split tsconfigs into build and dev projects (WordPress/gutenberg#81515) - Command Palette: Allow commands to override the category icon (WordPress/gutenberg#81787) - Fix Broken Links in Package file (WordPress/gutenberg#81700) - Notes: Stop forcing capitalization of user names (WordPress/gutenberg#81788) - Media Editor Route: Add undo/redo and save/cancel actions to the header (WordPress/gutenberg#81563) - Fix: Post Editor: Canvas animates from the left when switching mobile/tablet preview to desktop (WordPress/gutenberg#81484) - Build Package: Use Core's boot module when a plugin has none (WordPress/gutenberg#81761) - Docs: Fix broken link to the Document-Isolation-Policy explainer. (WordPress/gutenberg#81790) - Tests: Make PHPUnit tests independent of test config flags and theme root (WordPress/gutenberg#79159) - Editor: Debounce term filtering and announce results once (WordPress/gutenberg#81422) - Packages: Split story package tsconfigs into build and dev projects (WordPress/gutenberg#81516) - Packages: Complete the tsconfig build and dev project split (WordPress/gutenberg#81517) - TypeScript: Require the typecheck run for type checking in CI (WordPress/gutenberg#81518) - Block Editor: Remove leftover files (WordPress/gutenberg#81793) - Rename the media editor toolbar button to 'Edit image' (WordPress/gutenberg#81705) - Playlist: Remove block toolbar sharing between parent and child blocks (WordPress/gutenberg#81432) - Components: Fix Storybook accessibility issues in stories (WordPress/gutenberg#81777) - Fields: migrate last remaining JS file to TS (WordPress/gutenberg#81808) - Menu: Add UI component (WordPress/gutenberg#79560) - Patterns explorer: Refactor the category sidebar to use Tabs (WordPress/gutenberg#81807) - add context to change "revisions code diff" (WordPress/gutenberg#81820) - Add command: View post (WordPress/gutenberg#66720) - Fix: Post Editor: 403 on /wp/v2/settings at boot for users without manage_options cap (WordPress/gutenberg#81813) - UI: Add initial agents guidance mapping to contributing guidelines (WordPress/gutenberg#81400) - UI: Mark Input-related components as recommended (WordPress/gutenberg#81658) - Post Template: Fix mover arrows and labels for blocks inside the grid view (WordPress/gutenberg#81120) - Docs: Fix broken link to the getEntityRecords selector reference. (WordPress/gutenberg#81791) - Quick Inserter: Standardize the design of the Browse all button (WordPress/gutenberg#81827) - UI: Add TextareaControl component (WordPress/gutenberg#81359) - Docs: Narrow the tsconfig split guidance to the standard layout (WordPress/gutenberg#81828) - Storybook: Fix production build warnings (WordPress/gutenberg#81758) - Components: migrate ResizableBox to SCSS module- WordPress/gutenberg#80720 (WordPress/gutenberg#81792) - Bump astral-sh/setup-uv from 9.0.0 to 10.0.0 in /.github/workflows (WordPress/gutenberg#81823) - Global Styles: Keep storing shadow presets as CSS variables when custom presets exist (WordPress/gutenberg#81346) - Docs: Fix broken skip ahead anchor on the custom block editor guide. (WordPress/gutenberg#81835) - Fix MediaPlaceholder drag eligibility (WordPress/gutenberg#81431) - Updated Aria Landmark Example URL (WordPress/gutenberg#81832) - TypeScript: Put route projects under the typecheck run (WordPress/gutenberg#81829) - Add missing dependency to media-editor route (WordPress/gutenberg#81845) - Add transform to Row for Columns block (WordPress/gutenberg#81802) - Editor: Remove FlexItem usage from NoteCard (WordPress/gutenberg#81851) - UI: Expose keyboard shortcut presentation utilities (WordPress/gutenberg#81826) - Theme: Add color warning diagnostics workbench (WordPress/gutenberg#81817) - Editor: Surface debugging details in the ErrorBoundary (WordPress/gutenberg#81642) - Update save & submit docs (WordPress/gutenberg#81077) - Boot: Migrate styles to CSS Modules (WordPress/gutenberg#81756) - Build: Emit TypeScript declarations with --noCheck (WordPress/gutenberg#81839) - Core Data: Validate the parsed-blocks cache against registered block types (WordPress/gutenberg#81809) - Dependencies: Dedupe, update adm-zip, nx (WordPress/gutenberg#81870) - Core Data: Allow keyless entities to be addressed without a record ID (WordPress/gutenberg#81857) - UI: Mark Autocomplete, Field, and Fieldset as recommended (WordPress/gutenberg#80636) - Editor: Announce publish date changes to screen readers (WordPress/gutenberg#81629) - Storybook: Fix default background color for Example Application theme story (WordPress/gutenberg#81765) - Fix/79641 rtc cursor hidden details block v2 (WordPress/gutenberg#81322) - UI: add ControlWithError component (WordPress/gutenberg#81574) - Global Styles: Group shadow editor rows as items (WordPress/gutenberg#81871) - Storybook: Handle production module load failures (WordPress/gutenberg#81867) - Pattern: Disable visibility support (WordPress/gutenberg#81866) - Design System: Add portable agent skills (WordPress/gutenberg#80597) - Global Styles: Allow editing duotone palettes (WordPress/gutenberg#81605) - Color Palette panel: Remove empty whitespace when there are no theme colors (WordPress/gutenberg#81894) - Try caching gutenberg_get_global_styles (WordPress/gutenberg#81889) - Refactor parameter type hints and clean comments (WordPress/gutenberg#81898) - Preserve layout and style attributes on Column transform (WordPress/gutenberg#81855) - Global Styles: Close the revisions screen on the first back click (WordPress/gutenberg#81897) - Editor: Set the width an entity opens at from the editor provider (WordPress/gutenberg#81750) - Pre-publish panel: Remove the headings that repeat the panel title (WordPress/gutenberg#81806) - Components: migrate ComboboxControl to SCSS module (WordPress/gutenberg#80471) - UI: Update Base UI to 1.7.0 (WordPress/gutenberg#81390) - Update Ariakit packages (0.4.35 => 0.4.37) (WordPress/gutenberg#81080) - chore: Update the combobox SCSS to have a breaking changes log (WordPress/gutenberg#81923) - Use `WCTextareaControl` alias for legacy TextareaControl imports (WordPress/gutenberg#81834) - Components: Improve text detection for button icon-with-text (WordPress/gutenberg#81521) - Font Library: Fix the preview weight for variable fonts (WordPress/gutenberg#81748) - Editor: Migrate hierarchical term selector to @wordpress/ui (WordPress/gutenberg#81848) - Validation: update dependency-audit to 0.4.6 and ignore dataviews ./wp bundle (WordPress/gutenberg#81928) - SearchableChipSelect: Add grouped items support (WordPress/gutenberg#80989) - Use `WCInputControl` alias for legacy InputControl imports (WordPress/gutenberg#81830) - Storybook: Upgrade to 10.5 (WordPress/gutenberg#80692) - Documentation: Update coding guidelines to recommend TypeScript (WordPress/gutenberg#81763) - Font library: Add skeleton loader for the font preview images (WordPress/gutenberg#81047) - Build Scripts: Force tsc --pretty so CI reports the project behind global diagnostics (WordPress/gutenberg#81937) - Update is-plain-object to 5.1.0 (WordPress/gutenberg#81926) - DataViews: Sync the displayed calendar month with external value changes (WordPress/gutenberg#81635) - DataForm: Make the panel layout edit button the real field trigger (WordPress/gutenberg#80689) - Dependency updates Aug 2026 (2) (WordPress/gutenberg#81906) - Playlist: Add bulk track metadata editing (WordPress/gutenberg#81441) - Automated Testing: Change Storybook default a11y test to error on failure (WordPress/gutenberg#81597) - Playlist Track: Improve track upload error flows (WordPress/gutenberg#81878) - Block Library: Fix failing test in playlist block (WordPress/gutenberg#81950) - Block editor: Move isElementVisible changelog entry to Unreleased (WordPress/gutenberg#81953: shail-mehta <shailu25@git.wordpress.org> Co-authored-by: Mamaduka <mamaduka@git.wordpress.org> - DataViews: Fix date and datetime controls selecting the adjacent day (WordPress/gutenberg#81498) - UI: Accept locale codes in Calendar components (WordPress/gutenberg#81814) - List: Add Align Support (WordPress/gutenberg#68002) - TypeScript: Bring the remaining route projects under the typecheck run (WordPress/gutenberg#81847) - Components: migrate GradientPicker, ColorPalette to SCSS module (WordPress/gutenberg#80473) - Docs: Align @PARAM tag columns in test/ docblocks (WordPress/gutenberg#81905) - Hide layout panel when no controls are available (WordPress/gutenberg#81968) - UI: Add ValidatedInputControl component (WordPress/gutenberg#81627) - Components: migrate StyledLabel to SCSS module (WordPress/gutenberg#80001) - fix: Button rtl loader issue (WordPress/gutenberg#81901) - Theme: Update Terrazzo packages to 2.7.1 (WordPress/gutenberg#81978) - CollapsibleCard: Support multiple header descriptions (WordPress/gutenberg#81227) - DataViews: use `Menu` from `@wordpress/ui` (WordPress/gutenberg#81783) - DataViews: Localize the date/datetime calendars from the site locale and direction (WordPress/gutenberg#81592) - Replace the Storybook test runner with the Vitest integration (WordPress/gutenberg#81918) - Block Editor: Don't close inserter panel when inline quick inserter opens (WordPress/gutenberg#76241) - Updated broken links in document files (WordPress/gutenberg#81961) - Boot: Mount the registered plugins (WordPress/gutenberg#81754) - Extensible Site Editor: Add a theme preview page with global styles editing (WordPress/gutenberg#81954) - Block Styles: Refactor the variation UI to use ui/Button (WordPress/gutenberg#81833) - Styles Route: Reference the api-fetch and html-entities projects (WordPress/gutenberg#81989) - Fix: Line Break Tags Added to Scripts and Styles (WordPress/gutenberg#77542) - Fix: skip empty block markup in navigation to prevent split UL elements (WordPress/gutenberg#78793) - Pattern List: Import a pattern from JSON (WordPress/gutenberg#81919) - UI: Add tooltips to Calendar and RangeCalendar navigation buttons (WordPress/gutenberg#81983) - UI: Add `ValidatedTextArea` control (WordPress/gutenberg#81984) - Fix: Responsive styles: When enabled and a font-size is setting, the corresponding CSS variable remains undefined (WordPress/gutenberg#81854) - Components: Migrate `TextareaControl` to SCSS module (WordPress/gutenberg#81353) - UI: Set Calendar text direction automatically (WordPress/gutenberg#81982) - Theme: Rename ThemeProvider wrapper CSS class from root to wrapper (WordPress/gutenberg#81996) - Editor: Offer the theme export from both site editors (WordPress/gutenberg#81992) - Fix: Stop stripping spaces inside inline HTML elements on paste (WordPress/gutenberg#76696) - DataViews: Add a lint rule preventing private API imports (WordPress/gutenberg#81478) - Components: Migrate ProgressBar styles from Emotion to SCSS module (WordPress/gutenberg#80512) - RTC: Disable syncing for unpersistable post types (WordPress/gutenberg#81946) - Boot: Restore centered snackbar notices (WordPress/gutenberg#81995) - BorderControl, BorderBoxControl: Migrate styles to CSS Modules (WordPress/gutenberg#80437) - Duotone Picker: Stop the duotone bar offering to move its control points (WordPress/gutenberg#81850) - DataViews: Add an aspect ratio toggle for grid layouts (WordPress/gutenberg#81604) - Remove `fixable` on `i18n-no-flanking-whitespace` (WordPress/gutenberg#70279) - Dynamic Gallery block: Skip transforms that expect inner blocks, e.g. Image and Grid transforms (WordPress/gutenberg#82009) - Accordion Heading: Route theme.json spacing to the toggle button (WordPress/gutenberg#81976) - Element: Serialize memo-wrapped components instead of an empty string (WordPress/gutenberg#81986) - Style: Update color to use CSS variable in global-styles-ui (WordPress/gutenberg#79053) - Dashboard Widgets: let the host decide which component renders an action link (WordPress/gutenberg#81740) - Tabs: make inactive panel content findable in page (WordPress/gutenberg#81743) - Border Panel: Fix incorrect panel label (WordPress/gutenberg#78830) - Components: Migrate ZStack styles from Emotion to SCSS module (WordPress/gutenberg#80514) - Storybook: Add missing @types/jest devDependency (WordPress/gutenberg#82017) - TypeScript: Drop redundant undefined casts for keyless entity record IDs (WordPress/gutenberg#82018) - Editor: Fix start page/template modal footer overflow (WordPress/gutenberg#82021) - Storybook: Keep Vitest story scanning independent of the Vite root (WordPress/gutenberg#82020) - Test: Port shared Vitest test environment (WordPress/gutenberg#81038) - Query No Results: Add Border & Spacing Support (WordPress/gutenberg#64601) - RadioControl: allow individual options to be disabled (WordPress/gutenberg#82026) - Components: Migrate `BoxControl` to SCSS module (WordPress/gutenberg#80715) - SearchableChipSelectControl: Add form control to @wordpress/ui (WordPress/gutenberg#80980) - UI: Move controlled prop guidance to contributing docs (WordPress/gutenberg#82044) - Components: Migrate Scrollable to SCSS module (WordPress/gutenberg#80694) - UI: Fix accessibility issues in form primitives and their stories (WordPress/gutenberg#81853) - UI: Align Calendar styling with WPDS tokens (WordPress/gutenberg#81438) - Calendar: Support custom root roles (WordPress/gutenberg#81443) - E2E Tests: Use str_starts_with()/str_contains() in hide-user-rest-routes plugin (WordPress/gutenberg#82030) - Site editor v2: Fix block error with navigation-edit route (WordPress/gutenberg#82051) - ActionItem: Move the more menu deduplication out of the Slot (WordPress/gutenberg#81507) - DataViews: Fix invisible sticky Actions column divider (WordPress/gutenberg#82055) - Quick draft: replace Button+Link with LinkButton (WordPress/gutenberg#82031) - Lint: Prevent private API imports in all bundled packages (WordPress/gutenberg#82015) - PaletteEdit: Expose palette swatches as command buttons (WordPress/gutenberg#82023) - Test: Add Vitest React, Emotion compilation, console, and snapshot parity (WordPress/gutenberg#81039) - remove dead class reference in quick-draft (WordPress/gutenberg#82064) - `InputControl`: Hide the value-like placeholder Safari renders in empty date and time inputs in `ui` and `components` packages (WordPress/gutenberg#81991) - Site editor v2: Fix template part list pagination and sorting (WordPress/gutenberg#82054) - Build: Fix ESM declaration resolution (WordPress/gutenberg#82022) - Core Data: Stop storing NaN pagination totals for unpaginated endpoints (WordPress/gutenberg#82059) - Dashboard widgets & Grid: use kebab-case for CSS selectors (WordPress/gutenberg#82053) - CI: Skip the package CHANGELOG check when only the CHANGELOG changed (WordPress/gutenberg#82069) - Menu: Close non-modal menus on iframe interaction (WordPress/gutenberg#81952) - Packages: Recover August 26 npm release metadata (WordPress/gutenberg#82086) - Private APIs: Add back '@wordpress/dataviews' to the allowed core modules (WordPress/gutenberg#82221) Fixes #66067. Built from https://develop.svn.wordpress.org/trunk@63535 git-svn-id: http://core.svn.wordpress.org/trunk@62711 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Part of #81230
Note
Built on top of #81358 (
Spinner), which should land first.What?
Moves
ControlWithError(and its internalValidityIndicator) to@wordpress/ui, and replaces the copies in@wordpress/componentsand@wordpress/dataviewswith the new component.Why?
See #81230.
How?
The component is ported as-is behavior-wise, adapted to the
@wordpress/uiconventions: CSS modules on WPDS design tokens withwp-uicascade layers,renderprop support viauseRender/mergeProps, uiIcon+Spinnerfor the validity indicator, and wp-admin global CSS defense. The wrapper no longer hardcodes a package class — consumers pass their legacy class instead, so the existing:has()-based invalid styles keep working:Testing Instructions
npm run test:unit -- packages/ui/src/control-with-error packages/components/src/validated-form-controls packages/dataviews/src/components/validated-form-controlsnpm run storybook:dev), check the new stories underDesign System > Components > Form > ControlWithError, plus the existingComponents > Selection & Input > Validated Form Controls > OverviewandDataViews > DataForm > Validationstories: submitting with empty required fields shows inline errors and red borders, exactly as on trunk.Testing Instructions for Keyboard
Tab into a required field in the stories above, tab out to blur it, and press Enter on the Submit button: the error message is announced (associated via
aria-describedby), and focus moves to the first invalid control on submit.Use of AI Tools
Authored with Claude Code (Claude Fable 5), including the port, consumer updates, and test migration; reviewed and verified by the author.