Repository navigation
Admin UI: Add Navigation component and Page navigation slot - #79746
Conversation
Semantic section navigation (links + aria-current); router-agnostic via the render prop, mirroring Breadcrumbs.
Renders the `navigation` node in the header, below the title and subtitle; adds Page stories.
|
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. |
|
Size Change: +3.19 kB (+0.04%) Total Size: 7.72 MB 📦 View Changed
|
The component passes `search` as a reducer function; the mock now resolves it to build the href.
|
@retrofox let's coordinate before jumping into implementation:
cc @WordPress/gutenberg-components |
Moving PR to draft. |
|
I think we could find a path forward here for some incremental improvements to avoid the current situation where consumers are forced to use tabs even when not appropriate to do so. The broader ambition for navigation support for Page involves several related dependent navigation components and an expansive API to cover submenus and other aspects explored in #77628 and #76709. This is going to take a lot of work. But, if we adopt a configuration-based API for specifying navigation, as considered in #76709 (comment), I think we could implement a subset of supports with a simple internal component implementation as a short-term solution. Based on what's implemented here, if we can keep this to (1) label, (2) URL, and (3) selected state, that should be both relatively simple to implement and mostly future-compatible to the more expansive NavigationMenu component (#79154). With this, I'd expect:
As far as what the API looks like, I think you already have most of it with what you proposed with the Navigation component, but instead surfacing <Page
navigation={ [
{ label: 'Overview', href: '/overview', selected: true },
{ label: 'Products', href: '/products' },
] }
/>A couple differences:
|
|
Potentially, rather than a |
|
Thanks, @aduth. This direction works well for us, and we'll adopt it. Quick summary of what we'll implement, plus two questions:
Two things to confirm: 1. Shape of the prop. Since <Page
navigation={ {
items: [ { label: 'Overview', href: '/overview' }, … ],
selected: '/overview',
} }
/>This keeps Happy to go with the flat 2. Client-side navigation. With plain anchors, in-app navigation triggers a full reload. To preserve client-side routing without coupling the package to |
navigation becomes a `{ items, selected }` object; the navigation component is now internal (not exported) and no longer depends on @wordpress/route (plain anchors).
|
Flaky tests detected in fe1b0a7. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/29410438933
|
louwie17
left a comment
There was a problem hiding this comment.
Thanks for moving this forward @retrofox, and I like the middle ground of having a navigation config first. I just left some small comments, but otherwise happy where this is going!
Keyboard focus moves through the links with a visible focus ring.
I don't see any focus ring when using my keyboard. Seems like the Link component does not provide this.
| item.href === selected | ||
| ? 'page' | ||
| : undefined |
There was a problem hiding this comment.
Do we want to limit this to a single item, in the case where multiple items with the same href are added? Or do we not care about this and expect them to be unique?
There was a problem hiding this comment.
Do we want to limit this to a single item, in the case where multiple items with the same
hrefare added? Or do we not care about this and expect them to be unique?
I think it's a good point on both accounts; that we should neither want duplicate aria-current="page" but that it's also reasonable to expect that someone should pass unique values. I'm not sure it's worth the added complexity to try to preempt.
If we were, then maybe it could be done as part of the same validation happening above for non-empty href, to make sure that each href is distinct.
There was a problem hiding this comment.
We enforce uniqueness now: the dev-only validation throws on a duplicate href, right next to the missing-href check, the spot you pointed out for it.
@ciampo asked for the same guard in a separate thread. Regarding the added complexity: it's a few development-only lines, production pays nothing, and it guarantees a single aria-current="page".
Allow an empty `href` (valid target for the current page) in the dev validation, and key items by `href` instead of the array index.
Keep the navigation entry under the current Unreleased section (trunk released 2.5.0).
8976abb to
355ef86
Compare
aduth
left a comment
There was a problem hiding this comment.
I pushed a few changes I noticed while going through review.
Of note:
- Storybook link capture wasn't working for me in testing, which should be fixed now in 3c7066e.
- Added regression test coverage for scenarios which were flagged in earlier reviews and improved.
- Updated the styling to appear a bit more how I'd expect from the original specs in #76709. I don't know that we ever concretely landed on the visual style here, and in particular around whether to use an underline for the active item. This was noted in the original pull request description and in @ciampo 's initial tech spec in #79154 (comment), and I can see the intent in not wanting to confuse the semantics of links and tabs. We may find ourselves iterating on this design though.
Visual comparison before and after touch-ups in 88b5f92, largely around removing excess space, particularly default header padding when the navigation is present:
| Before | After |
|---|---|
![]() |
![]() |
Otherwise this looks good to me as a first iteration 👍 @louwie17 had submitted a blocking review and I also note that his status is "Busy" and that he may be away, so my inclination is to dismiss the review and address any follow-up comments in subsequent iterations.
Do you expect that the component would change the API surface of these changes, which would be something that might be worth settling, and otherwise non-blocking. Regarding urgency, I'll defer to @retrofox , but I am aware of several instances where consumers have been resorting to inappropriate Tabs usage over the lack of a navigation menu support. |
|
There may be some API changes, but it's early to say. At the same time, I expect that applying the specs proposed in #77628 will result in breaking changes anyway, so maybe there's no point in waiting? |
Requested changes have been addressed, and a colleague has mentioned that he will be unavailable to review for an extended time.
That's my instinct as well. For example, there's already some inconsistencies being introduced here (for the better) around link customization, where Page's breadcrumb still hard-codes |
| /** | ||
| * Overrides for the elements the navigation renders. | ||
| */ | ||
| components?: NavigationComponents; |
There was a problem hiding this comment.
Question (cc @aduth ): should components.link be on Page instead, for a higher-level API, more on the line of the bigger refactor proposed?
There was a problem hiding this comment.
Likely yes, and in fact my initial proposal in #77040 included exactly that ("<Page components={ { link: Link } } />").
There was a problem hiding this comment.
I've updated this in 4cfaf48 so that components is a top-level prop of Page. This switches back to the linkComponent semantics for Navigation itself, but since it's a private component it shouldn't matter much and I think we won't need as much of the 'bucket' approach for the sub-components where it's more clear and precise what we'll want to control.
| * | ||
| * @default 'a' | ||
| */ | ||
| link?: ComponentType< AnchorHTMLAttributes< HTMLAnchorElement > >; |
There was a problem hiding this comment.
With AnchorHTMLAttributes< HTMLAnchorElement >, the href prop/attribute is optional, but NavigationItem always requires it. This will also cause TS errors later, if we need to write adapters (ie for the wordpress/route link) such as:
type RouteLinkProps = {
href: string;
children: React.ReactNode;
className?: string;
};
const RouteLink = ( { href, ...props }: RouteLinkProps ) => (
<Link to={ href } { ...props } />
);The current test and story hide this problem by typing their fake anchor with the same optional-href AnchorHTMLAttributes type. We should probably mark href on link's props as required, update stories and tests
There was a problem hiding this comment.
With
AnchorHTMLAttributes< HTMLAnchorElement >, thehrefprop/attribute is optional, butNavigationItemalways requires it.
This is a good catch, and it was a little tricky to navigate, between how exactly to make it required (e.g. Pick-ing the props we're actually passing vs. Omit-ing and & intersecting with the override) as well as semantics around render in the underlying Link component. The end result is 38ffb1f:
- Opted for
Omit-and-&-intersect, since we had already documented through props "It receives standard anchor attributes [...] them to the element it renders" - Passing
hrefon therenderelement (both default and overridden) because otherwise the typings would assume that what's passed toLinkComponentcould have omithrefbecause the underlyingLinkprimitive builds its prop types based on anchor props
There was a problem hiding this comment.
I believe Page.navigation is still typed as the complete internal NavigationProps, so TypeScript advertises navigation.linkComponent and navigation.className as supported public configuration?
Header then spreads the object and unconditionally overwrites both values. A consumer can therefore pass valid-looking props that silently do nothing. This also leaves a second apparent link-customization path after the supported one moved to Page.components.link.
I guess one approach here is to split this into a public data-only config (items, currentHref, ariaLabel) and internal renderer props (linkComponent, className), and type Page.navigation with only the public config? That preserves the minimal configuration API discussed in #76709/#77628 and prevents internal markup concerns from becoming part of the Page contract.
There was a problem hiding this comment.
I believe
Page.navigationis still typed as the complete internalNavigationProps, so TypeScript advertisesnavigation.linkComponentandnavigation.classNameas supported public configuration?
Good call 👍 I split the internal and public-facing types in 6937f88.
| * | ||
| * @default 'a' | ||
| */ | ||
| link?: ElementType< NavigationLinkProps >; |
There was a problem hiding this comment.
This type would allow something like
<Page components={{ link: 'span' }}>
The public override does not need to accept intrinsic strings because the native <a> is already the default. What about using ComponentType<NavigationLinkProps> instead? Internally, Navigation can use linkComponent ?? 'a'.
There was a problem hiding this comment.
Hm, right, I had done this intentionally in 4259798 as a way to line up the typings so that linkComponent could destructure, but it sounds like the previous approach is probably better to avoid exposing other element tag names as invalid. I'll just revert.
| const link = useCallback( | ||
| ( { href, children, ...props }: NavigationLinkProps ) => ( | ||
| <a | ||
| { ...props } | ||
| href={ href } | ||
| onClick={ ( event ) => { | ||
| event.preventDefault(); | ||
| setCurrentHref( href ); | ||
| } } | ||
| > | ||
| { children } | ||
| </a> | ||
| ), | ||
| [] | ||
| ); |
There was a problem hiding this comment.
It looks like the router adapter can create two current links for nested URLs.
For example, at /products/settings:
- TanStack Router (which powers
@wordpress/route) also marks/productsas active by default Pagemarks/products/settingsfromcurrentHref- Both links then get
aria-current="page"and the current-item styling.
We should make sure that the @wordpress/route adapter uses activeOptions={{ exact: true }} (and document it).
Ideally, we should also test the real adapter with nested URLs and assert that only one link is current.
There was a problem hiding this comment.
Hmm, I'm not really sure how to proceed here. TanStack Router is going to apply aria-current to nested links regardless of what we do here. If that's a problem, then we need to solve that at the root, or it's something that any consumer for @wordpress/route will need to think about. I guess I don't really see this as a Page problem. Sure, we add aria-current and that overlaps with what Tanstack is doing, but even if we didn't do that, the problem you describe still exists.
I was initially going to add a test here, but I feel like this is such a concern of the integration itself that it's more appropriate to belong where the integration itself happens. And with #77040, I'd like to move away from @wordpress/admin-ui being entangled with the router.
Where are you suggesting that this documentation should live?
There was a problem hiding this comment.
Maybe we can start with a Storybook example where we show how to work around it, as of today.
But I agree that this is something to be solved separately
ciampo
left a comment
There was a problem hiding this comment.
All my feedback is addressed 🚀
One minor nit: the PR description still shows an old code snippet where the custom components are nested under navigation.components.
But otherwise, no additional feedback on my end!
…-navigation # Conflicts: # packages/admin-ui/CHANGELOG.md
* Admin UI: Add Navigation component
Semantic section navigation (links + aria-current); router-agnostic via the render prop, mirroring Breadcrumbs.
* Admin UI: Add navigation slot to Page
Renders the `navigation` node in the header, below the title and subtitle; adds Page stories.
* Admin UI: Fix Navigation test search mock
The component passes `search` as a reducer function; the mock now resolves it to build the href.
* Admin UI: Switch Page navigation to a config API
navigation becomes a `{ items, selected }` object; the navigation component is now internal (not exported) and no longer depends on @wordpress/route (plain anchors).
* Admin UI: Fix Page navigation item href handling
Allow an empty `href` (valid target for the current page) in the dev validation, and key items by `href` instead of the array index.
* Admin UI: Add 2.5.0 heading to the changelog
Keep the navigation entry under the current Unreleased section (trunk released 2.5.0).
* replace Link with LinkButton
* clean colors
* Admin UI: rename selected prop to currentHref
Align the Navigation prop name with the aria-current attribute.
* Admin UI: validate unique navigation hrefs in dev
Prevent more than one item from receiving aria-current=page.
* Admin UI: make navigation aria-label configurable
Default to Sections and drop the generic Secondary navigation label.
* Admin UI: accept a readonly navigation items array
Lets stable configuration data and as const arrays pass without a cast.
* Admin UI: destructure Navigation props in the signature
Follows the conventional destructuring used across the package.
* Admin UI: render navigation items with Link
Link now carries the focus ring and is allowlisted, so the LinkButton workaround and its eslint-disable are no longer needed.
* Admin UI: restore current-item styling and target size
Bring back the muted resting and emphasized current-item treatment, enforce a 44px pointer target, and flatten the class selectors.
* Admin UI: add Page navigation integration tests
Cover header rendering, aria-current, and the empty-items case.
* Admin UI: drop import grouping comments
* Admin UI: guard empty navigation in Page header
* Admin UI: add explicit list role to navigation
* Admin UI: inline the navigation aria-label default
* Admin UI: keep navigation focus ring visible
* Admin UI: complete the navigation target size
* Admin UI: space header navigation with margin
* Admin UI: link the changelog entry to the PR
* Admin UI: add navigation components.link support
* Page: Fix Navigation intercepted link handling
* Page: Improve test coverage for scenarios flagged in review
* Admin UI: Improve styling alignment for Page navigation to spec
* Admin UI: Flatten DOM by applying className to Navigation
* Admin UI: Simplify Navigation LinkComponent forwarding
* Admin UI: Treat href as consistently present
* Admin UI: Surface components prop to top-level Page component
* Admin UI: Update Link types to accommodate intrinsic `'a'` element
* Revert "Admin UI: Update Link types to accommodate intrinsic `'a'` element"
This reverts commit 4259798.
* Admin UI: Split public and internal props for Navigation
---------
Co-authored-by: Andrew Duthie <andrew.duthie@automattic.com>
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



What?
Adds a
navigationprop toPage(@wordpress/admin-ui) for link-based navigation between the sections of a screen, rendered in the page header.The navigation is configuration-based and rendered by a small internal component (not exported): consumers pass a list of links, the current one, and optionally a custom link component. Each item is a semantic
<a>inside a<nav>, with the current one marked viaaria-current="page".Related discussions: #79154, #76709, #77040.
Why?
Several admin screens need to switch between sections/views from the page header.
Today consumers reach for
Tabs, but theTabs(ARIAtablist) pattern is for toggling panels of content within a single view, not for navigating between locations/URLs. Using it for navigation is semantically inappropriate and loses proper link behavior (history, deep-linking, open-in-new-tab,aria-current). This is the problem described in #79154.This is a minimal, semantically correct step consumers can adopt now, while the more general
NavigationMenudiscussed in #79154 (built on Base UI, in@wordpress/ui) is designed and built.How?
Pageaccepts anavigationobject with the list ofitems(label+href) and thehrefof the current one:Implementation notes:
<nav><ul><li><a>, not atablist; the item matchingcurrentHrefgetsaria-current="page". The list keeps an explicitrole="list"so Safari announces it as a list despitelist-style: none.Link(variant="unstyled") from@wordpress/ui, which carries the design-system keyboard focus ring. The scroll container reserves room for the ring so overflow clipping never cuts it off.navlandmark label defaults to "Sections" and is configurable throughariaLabel. The default avoids the word "navigation", per the APG landmark guidance.@wordpress/route(per Admin UI: Decouple Page component from@wordpress/route#77040): plain anchors by default, no router dependency in the package. Client-side routing integrates through the top-levelcomponentsprop onPage;components.linkreceives standard<a>attributes, withhrefrequired:navigationis a public data-only config (items,currentHref,ariaLabel); renderer concerns (linkComponent,className) stay internal to the privateNavigationcomponent.Items meet the 44x44px target size (WCAG 2.5.5 Target Size, Enhanced). The current item takes a stronger foreground tone and heavier weight (design system interactive tokens), with no underline indicator.
Dev-only validation throws on a missing or duplicate
href, so exactly one item can carryaria-current="page".Lives in the sticky header, so it inherits the header's scroll behavior. On overflow, it scrolls horizontally rather than wrapping.
The navigation component is internal, configured only through
<Page navigation>, and future-compatible with the eventualNavigationMenu.Testing Instructions
Storybook:
Open
Admin UI / Page(WithNavigation,WithInteractiveNavigation,WithNavigationAndActions, andFullHeader) and verify:aria-current="page"(check the DOM / an a11y tool).WithInteractiveNavigation, clicking a link moves the current item without a page reload (customcomponents.link).Unit tests:
Out of scope (follow-ups)
@wordpress/uiNavigationMenu(Design System: Add a dedicated Navigation component #79154) and migrating existingTabs-as-navigation usages, plus lint guidance.Types of changes
New feature (non-breaking). Adds a new optional
Pageprop; existing usage is unaffected.