Skip to content

Widget Dashboard: preserve widget chrome flex layout - #80570

Merged
chihsuan merged 3 commits into
WordPress:trunkfrom
dognose24:codex/widget-dashboard-css-reset-hardening
Jul 31, 2026
Merged

chihsuan merged 3 commits into
WordPress:trunkfrom
dognose24:codex/widget-dashboard-css-reset-hardening

Conversation

@dognose24

@dognose24 dognose24 commented Jul 22, 2026 •

Copy link
Copy Markdown
Contributor

Why

On a production WordPress site, the hosting platform concatenates a legacy admin-wide stylesheet into every wp-admin page (it's platform-level CSS, not something a plugin or theme on the site enqueues), and it ships an unscoped HTML5 display reset — article, aside, …, section, summary { display: block; } — unlayered. The Card styles live inside @layer wp-ui.components, and unlayered rules beat layered ones regardless of specificity, so the widget chrome's <section> computed display: block. The chrome's content area then lost its flex height constraint (flex: 1 / min-height: 0 are inert without a flex parent, while its height: 100% still applies in block flow), quietly overflowed the tile, and the tile's overflow: clip cut off the bottom of every widget — e.g. a chart's x-axis labels.

Any host page can carry such CSS (wp-admin loads arbitrary plugin, theme, and platform styles), so the dashboard should not depend on a layered rule for its structural layout.

What

  • Restate the widget chrome's structural flex-column layout on its own module class (widget-chrome.module.css). No Card.Root styles are modified.
  • The module CSS ships unlayered, so within the unlayered tier normal specificity applies and the class rule beats element-selector resets — no !important needed.
  • The chrome's children already rely on this invariant (flex: 1 + min-height: 0 on the content assume a column flex parent), so in a clean host this is a visual no-op; the change only makes the existing contract self-contained.
  • Document the hardening in the package changelog.

Test plan

  1. Open any Widget Dashboard story with a rendered widget tile.
  2. In DevTools, inject an unlayered reset: document.head.insertAdjacentHTML('beforeend', '<style>section{display:block}</style>').
  3. Before this patch: the chrome <section> computes display: block and the widget body overflows the tile (bottom clipped, e.g. chart x-axis labels).
  4. With this patch: computed styles remain display: flex; flex-direction: column and the layout is unaffected.
  5. Without the injected reset, confirm tiles render identically to trunk (visual no-op).

@github-actions github-actions Bot added the First-time Contributor Pull request opened by a first-time contributor to Gutenberg repository label Jul 22, 2026
@github-actions

Copy link
Copy Markdown

👋 Thanks for your first Pull Request and for helping build the future of Gutenberg and WordPress, @dognose24! In case you missed it, we'd love to have you join us in our Slack community.

If you want to learn more about WordPress development in general, check out the Core Handbook full of helpful information.

@dognose24 dognose24 changed the title Widget Dashboard: Preserve widget chrome flex layout Widget Dashboard: preserve widget chrome flex layout Jul 22, 2026
@dognose24
dognose24 marked this pull request as ready for review July 22, 2026 13:45
@dognose24
dognose24 requested a review from retrofox as a code owner July 22, 2026 13:45
@github-actions

github-actions Bot commented Jul 22, 2026 •

Copy link
Copy Markdown

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 props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: dognose24 <dognose24@git.wordpress.org>
Co-authored-by: retrofox <retrofox@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@retrofox

Copy link
Copy Markdown
Contributor

Thanks, Dognose, for this PR. I'm not entirely sure what the motivation for this PR is. Could you provide clearer testing instructions? It touches the regular Card.Root component styles.

@dognose24

dognose24 commented Jul 23, 2026 •

Copy link
Copy Markdown
Contributor Author

@retrofox Thanks for taking a look, and fair — the description buried the motivation. Context:

We hit this in production on a WordPress site: its wp-admin loads a legacy admin-wide stylesheet that ships an unscoped HTML5 display reset — article, aside, …, section, summary { display: block; } — unlayered. The Card styles live inside @layer wp-ui.components, and unlayered rules win over layered ones regardless of specificity, so the widget chrome's <section> fell back to display: block. The content area then lost its flex height constraint, overflowed the tile, and the tile's overflow: clip cut off the bottom of every widget — e.g. a chart's x-axis labels.

Here's the Styles panel on the affected site — the Card's display: flex struck through inside @layer wp-ui.components while the unlayered reset wins (note the chrome's own module rules carry no layer, and their border-radius even beats the Card's — which is exactly why this fix works):

截圖 2026-07-23 晚上9 15 06

To be clear, the PR doesn't touch Card.Root's styles — it only restates the chrome's structural layout on its own module class (widget-chrome.module.css). The module CSS ships unlayered, so within the unlayered tier normal specificity applies and the class rule beats the element reset — confirmed empirically by adding display: flex to the chrome's module rule in DevTools on the affected site, which restores the layout. The chrome's children already rely on this invariant (flex: 1 + min-height: 0 on the content only make sense with a column flex parent), so in a clean host this is a visual no-op.

Clearer test plan:

  1. Open any Widget Dashboard story with a rendered tile.
  2. In DevTools, inject an unlayered reset: document.head.insertAdjacentHTML('beforeend', '<style>section{display:block}</style>').
  3. Before this patch: the chrome section computes display: block and the widget body overflows the tile (bottom clipped). With this patch: computed styles stay display: flex; flex-direction: column and the layout is unaffected.

Could you also add the [Type] Enhancement label? I don't have permission. Thanks!

@retrofox

Copy link
Copy Markdown
Contributor

Thanks for the follow-up, @dognose24.

You're right that the patch leaves Card.Root untouched, and the cascade reasoning checks out: the Card styles are layered, the dashboard's module CSS is not, so the module class wins over the host reset. .tile in widgets.module.css already restates the Card's border-radius the same way.

One change before merge. WidgetPreviewChrome renders the same Card.Root render={ <section /> } around the same WidgetFrame, so the picker previews break identically. Could you restate display: flex; flex-direction: column on .card in widget-preview-chrome.module.css too?

Out of curiosity, which stylesheet ships the reset? No core wp-admin stylesheet carries one, so it looks like a plugin or theme. Worth naming it in the description.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@dognose24

Copy link
Copy Markdown
Contributor Author

Done — .card in widget-preview-chrome.module.css now restates display: flex; flex-direction: column as well, and the changelog entry covers both chromes.

On the reset source: it's not core, and not a plugin or theme on the site either — the site's hosting platform concatenates a legacy admin-wide stylesheet into wp-admin, and its opening rules include the classic HTML5-Boilerplate-era article, aside, … section, summary { display: block; } reset, unscoped and unlayered. I've updated the description accordingly. Being platform-level CSS outside any plugin author's control, it reinforces keeping the chrome's structural layout self-contained.

Mind adding a [Type] Bug label when you get a chance? The two failing checks are just the label requirement.

@retrofox retrofox left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, Dognose. LGTM 👍

@retrofox retrofox added [Type] Enhancement A suggestion for improvement. [Package] Widget Dashboard /packages/widget-dashboard labels Jul 30, 2026
@chihsuan
chihsuan merged commit d36ca77 into WordPress:trunk Jul 31, 2026
66 checks passed
@github-actions github-actions Bot added this to the Gutenberg 23.8 milestone Jul 31, 2026
chihsuan added a commit to Automattic/jetpack that referenced this pull request Sep 2, 2026
Both stages carried their own copy of the same scaffold: a `.page`, a
`.scrollArea`, a `.content` band and a `.widgets` block that was byte-identical
down to its TODO. `DetailPageShell` / `DetailPageLayout` / `DetailPageSection`
now own that structure, following `ReportPageShell` / `ReportPageLayout` next
door, so the stages hand over their header slots, their date controls and their
widget content and nothing else.

The layout lives in `widgets-toolkit` beside `report-page` rather than under
`routes/`: wp-build treats every directory in `routes/` as a route to build, so
a shared folder there would be discovered as one.

`.widgets` folds into the section: `--wp-grid-gap` is inherited and the Card
rules are descendant selectors, so moving them one level out matches the same
elements without an extra wrapper around the grid.

Two differences the copies had drifted into, both invisible in the default
theme, are settled. The header's `padding-block` converges on 40px, written as
`--wpds-dimension-gap-3xl`, which the video page's comment records as the
design's breathing room. Post detail reaches the same 40px only once its tab
bar stops adding a bottom margin on top of it: #50540 zeroed that margin for
exactly this reason and #50562 restored it for a two-row header that no longer
exists, so 16px + 32px becomes 40px and the two pages finally agree. And the
shared `.content` end padding was a bare 24px restating
`--wpds-dimension-padding-2xl`.

`postHeaderSlots` and `videoHeaderSlots` each declared their own copy of the
slot shape; both now return `DetailPageHeaderSlots`, which the layout derives
from `SectionHeaderProps` so a required `title` and `busy` stay required.

`DetailPageTabs` re-exports the tab root beside the panel, so a detail route
reaches both through one package specifier — the constraint `report-page-tabs`
already documents. `DetailPageTabPanelProps` is declared and exported with its
`TabId` generic rather than leaving consumers to import the underlying UI type.

Drops the `display: flex` widget-chrome workaround: `@wordpress/widget-dashboard`
0.5.0, the version pinned here, ships the upstream fix
(WordPress/gutenberg#80570) in `.widget-chrome` itself.

The suites assert the classes the gutters, the grid gap and the Card padding
hang off, with a local style mock — which keeps them out of the shared no-mocks
group, per `tests/groups/README.md`.

WOOA7S-1949

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W4VNbKvETw12J6L1nCzixU
chihsuan added a commit to Automattic/jetpack that referenced this pull request Sep 2, 2026
Both stages carried their own copy of the same scaffold: a `.page`, a
`.scrollArea`, a `.content` band and a `.widgets` block that was byte-identical
down to its TODO. `DetailPageShell` / `DetailPageLayout` / `DetailPageSection`
now own that structure, following `ReportPageShell` / `ReportPageLayout` next
door, so the stages hand over their header slots, their date controls and their
widget content and nothing else.

The layout lives in `widgets-toolkit` beside `report-page` rather than under
`routes/`: wp-build treats every directory in `routes/` as a route to build, so
a shared folder there would be discovered as one.

`.widgets` folds into the section: `--wp-grid-gap` is inherited and the Card
rules are descendant selectors, so moving them one level out matches the same
elements without an extra wrapper around the grid.

Two differences the copies had drifted into, both invisible in the default
theme, are settled. The header's `padding-block` converges on 40px, written as
`--wpds-dimension-gap-3xl`, which the video page's comment records as the
design's breathing room. Post detail reaches the same 40px only once its tab
bar stops adding a bottom margin on top of it: #50540 zeroed that margin for
exactly this reason and #50562 restored it for a two-row header that no longer
exists, so 16px + 32px becomes 40px and the two pages finally agree. And the
shared `.content` end padding was a bare 24px restating
`--wpds-dimension-padding-2xl`.

`postHeaderSlots` and `videoHeaderSlots` each declared their own copy of the
slot shape; both now return `DetailPageHeaderSlots`, which the layout derives
from `SectionHeaderProps` so a required `title` and `busy` stay required.

`DetailPageTabs` re-exports the tab root beside the panel, so a detail route
reaches both through one package specifier — the constraint `report-page-tabs`
already documents. `DetailPageTabPanelProps` is declared and exported with its
`TabId` generic rather than leaving consumers to import the underlying UI type.

Drops the `display: flex` widget-chrome workaround: `@wordpress/widget-dashboard`
0.5.0, the version pinned here, ships the upstream fix
(WordPress/gutenberg#80570) in `.widget-chrome` itself.

The suites assert the classes the gutters, the grid gap and the Card padding
hang off, with a local style mock — which keeps them out of the shared no-mocks
group, per `tests/groups/README.md`.

WOOA7S-1949

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W4VNbKvETw12J6L1nCzixU
chihsuan added a commit to Automattic/jetpack that referenced this pull request Sep 3, 2026
…etail stages (#51877)

* refactor: share one page layout between the post and video detail stages

Both stages carried their own copy of the same scaffold: a `.page`, a
`.scrollArea`, a `.content` band and a `.widgets` block that was byte-identical
down to its TODO. `DetailPageShell` / `DetailPageLayout` / `DetailPageSection`
now own that structure, following `ReportPageShell` / `ReportPageLayout` next
door, so the stages hand over their header slots, their date controls and their
widget content and nothing else.

The layout lives in `widgets-toolkit` beside `report-page` rather than under
`routes/`: wp-build treats every directory in `routes/` as a route to build, so
a shared folder there would be discovered as one.

`.widgets` folds into the section: `--wp-grid-gap` is inherited and the Card
rules are descendant selectors, so moving them one level out matches the same
elements without an extra wrapper around the grid.

Two differences the copies had drifted into, both invisible in the default
theme, are settled. The header's `padding-block` converges on 40px, written as
`--wpds-dimension-gap-3xl`, which the video page's comment records as the
design's breathing room. Post detail reaches the same 40px only once its tab
bar stops adding a bottom margin on top of it: #50540 zeroed that margin for
exactly this reason and #50562 restored it for a two-row header that no longer
exists, so 16px + 32px becomes 40px and the two pages finally agree. And the
shared `.content` end padding was a bare 24px restating
`--wpds-dimension-padding-2xl`.

`postHeaderSlots` and `videoHeaderSlots` each declared their own copy of the
slot shape; both now return `DetailPageHeaderSlots`, which the layout derives
from `SectionHeaderProps` so a required `title` and `busy` stay required.

`DetailPageTabs` re-exports the tab root beside the panel, so a detail route
reaches both through one package specifier — the constraint `report-page-tabs`
already documents. `DetailPageTabPanelProps` is declared and exported with its
`TabId` generic rather than leaving consumers to import the underlying UI type.

Drops the `display: flex` widget-chrome workaround: `@wordpress/widget-dashboard`
0.5.0, the version pinned here, ships the upstream fix
(WordPress/gutenberg#80570) in `.widget-chrome` itself.

The suites assert the classes the gutters, the grid gap and the Card padding
hang off, with a local style mock — which keeps them out of the shared no-mocks
group, per `tests/groups/README.md`.

WOOA7S-1949

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W4VNbKvETw12J6L1nCzixU

* change: settle the three review notes on the shared detail page layout

The post tab bar's `margin-block-end: 0` lands on the same element as
`SectionTabs`' own rule, both single-class, so it only won because the
toolkit's stylesheet is emitted first. Doubling the selector makes it win
outright, and an import reorder can no longer move the header spacing.

`DetailPageTabs` and `DetailPageTabPanel` move into `detail-page-tabs.tsx`,
matching `report-page-tabs` next door. The layout no longer imports
`SectionTabPanel`, so `video-detail/stage.test.tsx` drops the mock it carried
for a page with no tabs — a mock the suite already passed without.

`DetailPageShell`'s test mock swallowed `...pageProps`, leaving the one thing
the component does beyond `clsx` unasserted. The mock now captures the rest
props and the test checks `visual` and `breadcrumbs` reach `Page`; removing the
spread fails it.

WOOA7S-1949

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LouhrnbjGjdAK2BZqC2M7s

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
chihsuan added a commit to Automattic/jetpack that referenced this pull request Sep 3, 2026
…es (#51875)

* feat: use SectionHeader on the post and video detail pages

The detail pages hand-rolled a third header beside the dashboard's and the
report pages': a flex row with its own wrap rules, plus a 440px constant
reserved for the date panel and a ref feeding it `containerElement`.

SectionHeader gains the two parameters those pages needed and nothing else
had — a `visual` slot and a `subTitle` — plus a `headingLevel`, since a
detail page's title is its `h1`. Naming and the decorative contract on the
visual follow `@wordpress/admin-ui`'s own page header, which the same files
already render.

The slot owns the visual's box, so both summary cards stop restating the
72px square and its radius. That also settles a latent difference between
them: the post thumbnail hard-coded `8px` where the video poster read
`--wpds-border-radius-lg`, which is 8px in the default theme and 0 in the
zero-radius one.

The pages keep the panel's responsive step-down through the header's
container query, so the external measurement retires with the migration.

On video detail, a failed or missing video now leaves the header with its
date controls alone and states the reason below it, where the widgets would
have been: an error is not something the shared header should know about.

WOOA7S-1949

* fix: give the detail-page header a heading in every summary state

From review of the SectionHeader migration.

* `title` goes back to a required prop. Optional, it let a page render a
  header with no heading at all, which is what the video stage did in its
  loading, error and not-found states: it spread `{}` into the header and
  the page lost its `h1`. Required, the spread is a type error.
* `videoHeaderSlots` now owns every summary state, so the video page keeps
  its `h1`, its visual box and its date controls throughout: a skeleton
  while the summary resolves (matching the post page, WOOA7S-2059), and a
  named state when it fails. The notice below the header is unchanged.
* `postHeaderSlots` names an untitled or failed post rather than dropping
  the heading, and restores the `aria-busy` the summary card carried.
* Both slot factories and `performanceSentence` take the package's own
  `DateRange` instead of three inline spellings of it, two of which the
  real type could not be assigned to. `HeaderSlots` is now one exported
  `Pick` of the header's props rather than a hand-copy in each file.
* `.withVisual` no longer widens the gap between the title and the
  controls, so the stacking breakpoint constant matches the width the row
  actually needs.
* Cover the untitled and failed paths, the video slots (which had no test
  of their own), the date helpers' guards, and the stage wiring the mocks
  were hiding; run the header's date helpers under test-tz.

* chore: keep the header date helpers out of the cross-timezone run

The fixture publishes at 08:00, so neither timezone test-tz runs shifts
its day. The entry would suggest coverage it does not give.

* Premium Analytics: share one page layout between the post and video detail stages (#51877)

* refactor: share one page layout between the post and video detail stages

Both stages carried their own copy of the same scaffold: a `.page`, a
`.scrollArea`, a `.content` band and a `.widgets` block that was byte-identical
down to its TODO. `DetailPageShell` / `DetailPageLayout` / `DetailPageSection`
now own that structure, following `ReportPageShell` / `ReportPageLayout` next
door, so the stages hand over their header slots, their date controls and their
widget content and nothing else.

The layout lives in `widgets-toolkit` beside `report-page` rather than under
`routes/`: wp-build treats every directory in `routes/` as a route to build, so
a shared folder there would be discovered as one.

`.widgets` folds into the section: `--wp-grid-gap` is inherited and the Card
rules are descendant selectors, so moving them one level out matches the same
elements without an extra wrapper around the grid.

Two differences the copies had drifted into, both invisible in the default
theme, are settled. The header's `padding-block` converges on 40px, written as
`--wpds-dimension-gap-3xl`, which the video page's comment records as the
design's breathing room. Post detail reaches the same 40px only once its tab
bar stops adding a bottom margin on top of it: #50540 zeroed that margin for
exactly this reason and #50562 restored it for a two-row header that no longer
exists, so 16px + 32px becomes 40px and the two pages finally agree. And the
shared `.content` end padding was a bare 24px restating
`--wpds-dimension-padding-2xl`.

`postHeaderSlots` and `videoHeaderSlots` each declared their own copy of the
slot shape; both now return `DetailPageHeaderSlots`, which the layout derives
from `SectionHeaderProps` so a required `title` and `busy` stay required.

`DetailPageTabs` re-exports the tab root beside the panel, so a detail route
reaches both through one package specifier — the constraint `report-page-tabs`
already documents. `DetailPageTabPanelProps` is declared and exported with its
`TabId` generic rather than leaving consumers to import the underlying UI type.

Drops the `display: flex` widget-chrome workaround: `@wordpress/widget-dashboard`
0.5.0, the version pinned here, ships the upstream fix
(WordPress/gutenberg#80570) in `.widget-chrome` itself.

The suites assert the classes the gutters, the grid gap and the Card padding
hang off, with a local style mock — which keeps them out of the shared no-mocks
group, per `tests/groups/README.md`.

WOOA7S-1949

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W4VNbKvETw12J6L1nCzixU

* change: settle the three review notes on the shared detail page layout

The post tab bar's `margin-block-end: 0` lands on the same element as
`SectionTabs`' own rule, both single-class, so it only won because the
toolkit's stylesheet is emitted first. Doubling the selector makes it win
outright, and an import reorder can no longer move the header spacing.

`DetailPageTabs` and `DetailPageTabPanel` move into `detail-page-tabs.tsx`,
matching `report-page-tabs` next door. The layout no longer imports
`SectionTabPanel`, so `video-detail/stage.test.tsx` drops the mock it carried
for a page with no tabs — a mock the suite already passed without.

`DetailPageShell`'s test mock swallowed `...pageProps`, leaving the one thing
the component does beyond `clsx` unasserted. The mock now captures the rest
props and the test checks `visual` and `breadcrumbs` reach `Page`; removing the
spread fails it.

WOOA7S-1949

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LouhrnbjGjdAK2BZqC2M7s

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
matticbot pushed a commit to Automattic/jetpack-mu-wpcom-plugin that referenced this pull request Sep 3, 2026
…es (#51875)

* feat: use SectionHeader on the post and video detail pages

The detail pages hand-rolled a third header beside the dashboard's and the
report pages': a flex row with its own wrap rules, plus a 440px constant
reserved for the date panel and a ref feeding it `containerElement`.

SectionHeader gains the two parameters those pages needed and nothing else
had — a `visual` slot and a `subTitle` — plus a `headingLevel`, since a
detail page's title is its `h1`. Naming and the decorative contract on the
visual follow `@wordpress/admin-ui`'s own page header, which the same files
already render.

The slot owns the visual's box, so both summary cards stop restating the
72px square and its radius. That also settles a latent difference between
them: the post thumbnail hard-coded `8px` where the video poster read
`--wpds-border-radius-lg`, which is 8px in the default theme and 0 in the
zero-radius one.

The pages keep the panel's responsive step-down through the header's
container query, so the external measurement retires with the migration.

On video detail, a failed or missing video now leaves the header with its
date controls alone and states the reason below it, where the widgets would
have been: an error is not something the shared header should know about.

WOOA7S-1949

* fix: give the detail-page header a heading in every summary state

From review of the SectionHeader migration.

* `title` goes back to a required prop. Optional, it let a page render a
  header with no heading at all, which is what the video stage did in its
  loading, error and not-found states: it spread `{}` into the header and
  the page lost its `h1`. Required, the spread is a type error.
* `videoHeaderSlots` now owns every summary state, so the video page keeps
  its `h1`, its visual box and its date controls throughout: a skeleton
  while the summary resolves (matching the post page, WOOA7S-2059), and a
  named state when it fails. The notice below the header is unchanged.
* `postHeaderSlots` names an untitled or failed post rather than dropping
  the heading, and restores the `aria-busy` the summary card carried.
* Both slot factories and `performanceSentence` take the package's own
  `DateRange` instead of three inline spellings of it, two of which the
  real type could not be assigned to. `HeaderSlots` is now one exported
  `Pick` of the header's props rather than a hand-copy in each file.
* `.withVisual` no longer widens the gap between the title and the
  controls, so the stacking breakpoint constant matches the width the row
  actually needs.
* Cover the untitled and failed paths, the video slots (which had no test
  of their own), the date helpers' guards, and the stage wiring the mocks
  were hiding; run the header's date helpers under test-tz.

* chore: keep the header date helpers out of the cross-timezone run

The fixture publishes at 08:00, so neither timezone test-tz runs shifts
its day. The entry would suggest coverage it does not give.

* Premium Analytics: share one page layout between the post and video detail stages (#51877)

* refactor: share one page layout between the post and video detail stages

Both stages carried their own copy of the same scaffold: a `.page`, a
`.scrollArea`, a `.content` band and a `.widgets` block that was byte-identical
down to its TODO. `DetailPageShell` / `DetailPageLayout` / `DetailPageSection`
now own that structure, following `ReportPageShell` / `ReportPageLayout` next
door, so the stages hand over their header slots, their date controls and their
widget content and nothing else.

The layout lives in `widgets-toolkit` beside `report-page` rather than under
`routes/`: wp-build treats every directory in `routes/` as a route to build, so
a shared folder there would be discovered as one.

`.widgets` folds into the section: `--wp-grid-gap` is inherited and the Card
rules are descendant selectors, so moving them one level out matches the same
elements without an extra wrapper around the grid.

Two differences the copies had drifted into, both invisible in the default
theme, are settled. The header's `padding-block` converges on 40px, written as
`--wpds-dimension-gap-3xl`, which the video page's comment records as the
design's breathing room. Post detail reaches the same 40px only once its tab
bar stops adding a bottom margin on top of it: #50540 zeroed that margin for
exactly this reason and #50562 restored it for a two-row header that no longer
exists, so 16px + 32px becomes 40px and the two pages finally agree. And the
shared `.content` end padding was a bare 24px restating
`--wpds-dimension-padding-2xl`.

`postHeaderSlots` and `videoHeaderSlots` each declared their own copy of the
slot shape; both now return `DetailPageHeaderSlots`, which the layout derives
from `SectionHeaderProps` so a required `title` and `busy` stay required.

`DetailPageTabs` re-exports the tab root beside the panel, so a detail route
reaches both through one package specifier — the constraint `report-page-tabs`
already documents. `DetailPageTabPanelProps` is declared and exported with its
`TabId` generic rather than leaving consumers to import the underlying UI type.

Drops the `display: flex` widget-chrome workaround: `@wordpress/widget-dashboard`
0.5.0, the version pinned here, ships the upstream fix
(WordPress/gutenberg#80570) in `.widget-chrome` itself.

The suites assert the classes the gutters, the grid gap and the Card padding
hang off, with a local style mock — which keeps them out of the shared no-mocks
group, per `tests/groups/README.md`.

WOOA7S-1949

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W4VNbKvETw12J6L1nCzixU

* change: settle the three review notes on the shared detail page layout

The post tab bar's `margin-block-end: 0` lands on the same element as
`SectionTabs`' own rule, both single-class, so it only won because the
toolkit's stylesheet is emitted first. Doubling the selector makes it win
outright, and an import reorder can no longer move the header spacing.

`DetailPageTabs` and `DetailPageTabPanel` move into `detail-page-tabs.tsx`,
matching `report-page-tabs` next door. The layout no longer imports
`SectionTabPanel`, so `video-detail/stage.test.tsx` drops the mock it carried
for a page with no tabs — a mock the suite already passed without.

`DetailPageShell`'s test mock swallowed `...pageProps`, leaving the one thing
the component does beyond `clsx` unasserted. The mock now captures the rest
props and the test checks `visual` and `breadcrumbs` reach `Page`; removing the
spread fails it.

WOOA7S-1949

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LouhrnbjGjdAK2BZqC2M7s

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

Committed via a GitHub action: https://github.com/Automattic/jetpack/actions/runs/33715644341

Upstream-Ref: Automattic/jetpack@df431e9
matticbot pushed a commit to Automattic/jetpack-production that referenced this pull request Sep 3, 2026
…es (#51875)

* feat: use SectionHeader on the post and video detail pages

The detail pages hand-rolled a third header beside the dashboard's and the
report pages': a flex row with its own wrap rules, plus a 440px constant
reserved for the date panel and a ref feeding it `containerElement`.

SectionHeader gains the two parameters those pages needed and nothing else
had — a `visual` slot and a `subTitle` — plus a `headingLevel`, since a
detail page's title is its `h1`. Naming and the decorative contract on the
visual follow `@wordpress/admin-ui`'s own page header, which the same files
already render.

The slot owns the visual's box, so both summary cards stop restating the
72px square and its radius. That also settles a latent difference between
them: the post thumbnail hard-coded `8px` where the video poster read
`--wpds-border-radius-lg`, which is 8px in the default theme and 0 in the
zero-radius one.

The pages keep the panel's responsive step-down through the header's
container query, so the external measurement retires with the migration.

On video detail, a failed or missing video now leaves the header with its
date controls alone and states the reason below it, where the widgets would
have been: an error is not something the shared header should know about.

WOOA7S-1949

* fix: give the detail-page header a heading in every summary state

From review of the SectionHeader migration.

* `title` goes back to a required prop. Optional, it let a page render a
  header with no heading at all, which is what the video stage did in its
  loading, error and not-found states: it spread `{}` into the header and
  the page lost its `h1`. Required, the spread is a type error.
* `videoHeaderSlots` now owns every summary state, so the video page keeps
  its `h1`, its visual box and its date controls throughout: a skeleton
  while the summary resolves (matching the post page, WOOA7S-2059), and a
  named state when it fails. The notice below the header is unchanged.
* `postHeaderSlots` names an untitled or failed post rather than dropping
  the heading, and restores the `aria-busy` the summary card carried.
* Both slot factories and `performanceSentence` take the package's own
  `DateRange` instead of three inline spellings of it, two of which the
  real type could not be assigned to. `HeaderSlots` is now one exported
  `Pick` of the header's props rather than a hand-copy in each file.
* `.withVisual` no longer widens the gap between the title and the
  controls, so the stacking breakpoint constant matches the width the row
  actually needs.
* Cover the untitled and failed paths, the video slots (which had no test
  of their own), the date helpers' guards, and the stage wiring the mocks
  were hiding; run the header's date helpers under test-tz.

* chore: keep the header date helpers out of the cross-timezone run

The fixture publishes at 08:00, so neither timezone test-tz runs shifts
its day. The entry would suggest coverage it does not give.

* Premium Analytics: share one page layout between the post and video detail stages (#51877)

* refactor: share one page layout between the post and video detail stages

Both stages carried their own copy of the same scaffold: a `.page`, a
`.scrollArea`, a `.content` band and a `.widgets` block that was byte-identical
down to its TODO. `DetailPageShell` / `DetailPageLayout` / `DetailPageSection`
now own that structure, following `ReportPageShell` / `ReportPageLayout` next
door, so the stages hand over their header slots, their date controls and their
widget content and nothing else.

The layout lives in `widgets-toolkit` beside `report-page` rather than under
`routes/`: wp-build treats every directory in `routes/` as a route to build, so
a shared folder there would be discovered as one.

`.widgets` folds into the section: `--wp-grid-gap` is inherited and the Card
rules are descendant selectors, so moving them one level out matches the same
elements without an extra wrapper around the grid.

Two differences the copies had drifted into, both invisible in the default
theme, are settled. The header's `padding-block` converges on 40px, written as
`--wpds-dimension-gap-3xl`, which the video page's comment records as the
design's breathing room. Post detail reaches the same 40px only once its tab
bar stops adding a bottom margin on top of it: #50540 zeroed that margin for
exactly this reason and #50562 restored it for a two-row header that no longer
exists, so 16px + 32px becomes 40px and the two pages finally agree. And the
shared `.content` end padding was a bare 24px restating
`--wpds-dimension-padding-2xl`.

`postHeaderSlots` and `videoHeaderSlots` each declared their own copy of the
slot shape; both now return `DetailPageHeaderSlots`, which the layout derives
from `SectionHeaderProps` so a required `title` and `busy` stay required.

`DetailPageTabs` re-exports the tab root beside the panel, so a detail route
reaches both through one package specifier — the constraint `report-page-tabs`
already documents. `DetailPageTabPanelProps` is declared and exported with its
`TabId` generic rather than leaving consumers to import the underlying UI type.

Drops the `display: flex` widget-chrome workaround: `@wordpress/widget-dashboard`
0.5.0, the version pinned here, ships the upstream fix
(WordPress/gutenberg#80570) in `.widget-chrome` itself.

The suites assert the classes the gutters, the grid gap and the Card padding
hang off, with a local style mock — which keeps them out of the shared no-mocks
group, per `tests/groups/README.md`.

WOOA7S-1949

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W4VNbKvETw12J6L1nCzixU

* change: settle the three review notes on the shared detail page layout

The post tab bar's `margin-block-end: 0` lands on the same element as
`SectionTabs`' own rule, both single-class, so it only won because the
toolkit's stylesheet is emitted first. Doubling the selector makes it win
outright, and an import reorder can no longer move the header spacing.

`DetailPageTabs` and `DetailPageTabPanel` move into `detail-page-tabs.tsx`,
matching `report-page-tabs` next door. The layout no longer imports
`SectionTabPanel`, so `video-detail/stage.test.tsx` drops the mock it carried
for a page with no tabs — a mock the suite already passed without.

`DetailPageShell`'s test mock swallowed `...pageProps`, leaving the one thing
the component does beyond `clsx` unasserted. The mock now captures the rest
props and the test checks `visual` and `breadcrumbs` reach `Page`; removing the
spread fails it.

WOOA7S-1949

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LouhrnbjGjdAK2BZqC2M7s

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

Committed via a GitHub action: https://github.com/Automattic/jetpack/actions/runs/33715644341

Upstream-Ref: Automattic/jetpack@df431e9
matticbot pushed a commit to Automattic/jetpack-storybook that referenced this pull request Sep 3, 2026
…es (#51875)

* feat: use SectionHeader on the post and video detail pages

The detail pages hand-rolled a third header beside the dashboard's and the
report pages': a flex row with its own wrap rules, plus a 440px constant
reserved for the date panel and a ref feeding it `containerElement`.

SectionHeader gains the two parameters those pages needed and nothing else
had — a `visual` slot and a `subTitle` — plus a `headingLevel`, since a
detail page's title is its `h1`. Naming and the decorative contract on the
visual follow `@wordpress/admin-ui`'s own page header, which the same files
already render.

The slot owns the visual's box, so both summary cards stop restating the
72px square and its radius. That also settles a latent difference between
them: the post thumbnail hard-coded `8px` where the video poster read
`--wpds-border-radius-lg`, which is 8px in the default theme and 0 in the
zero-radius one.

The pages keep the panel's responsive step-down through the header's
container query, so the external measurement retires with the migration.

On video detail, a failed or missing video now leaves the header with its
date controls alone and states the reason below it, where the widgets would
have been: an error is not something the shared header should know about.

WOOA7S-1949

* fix: give the detail-page header a heading in every summary state

From review of the SectionHeader migration.

* `title` goes back to a required prop. Optional, it let a page render a
  header with no heading at all, which is what the video stage did in its
  loading, error and not-found states: it spread `{}` into the header and
  the page lost its `h1`. Required, the spread is a type error.
* `videoHeaderSlots` now owns every summary state, so the video page keeps
  its `h1`, its visual box and its date controls throughout: a skeleton
  while the summary resolves (matching the post page, WOOA7S-2059), and a
  named state when it fails. The notice below the header is unchanged.
* `postHeaderSlots` names an untitled or failed post rather than dropping
  the heading, and restores the `aria-busy` the summary card carried.
* Both slot factories and `performanceSentence` take the package's own
  `DateRange` instead of three inline spellings of it, two of which the
  real type could not be assigned to. `HeaderSlots` is now one exported
  `Pick` of the header's props rather than a hand-copy in each file.
* `.withVisual` no longer widens the gap between the title and the
  controls, so the stacking breakpoint constant matches the width the row
  actually needs.
* Cover the untitled and failed paths, the video slots (which had no test
  of their own), the date helpers' guards, and the stage wiring the mocks
  were hiding; run the header's date helpers under test-tz.

* chore: keep the header date helpers out of the cross-timezone run

The fixture publishes at 08:00, so neither timezone test-tz runs shifts
its day. The entry would suggest coverage it does not give.

* Premium Analytics: share one page layout between the post and video detail stages (#51877)

* refactor: share one page layout between the post and video detail stages

Both stages carried their own copy of the same scaffold: a `.page`, a
`.scrollArea`, a `.content` band and a `.widgets` block that was byte-identical
down to its TODO. `DetailPageShell` / `DetailPageLayout` / `DetailPageSection`
now own that structure, following `ReportPageShell` / `ReportPageLayout` next
door, so the stages hand over their header slots, their date controls and their
widget content and nothing else.

The layout lives in `widgets-toolkit` beside `report-page` rather than under
`routes/`: wp-build treats every directory in `routes/` as a route to build, so
a shared folder there would be discovered as one.

`.widgets` folds into the section: `--wp-grid-gap` is inherited and the Card
rules are descendant selectors, so moving them one level out matches the same
elements without an extra wrapper around the grid.

Two differences the copies had drifted into, both invisible in the default
theme, are settled. The header's `padding-block` converges on 40px, written as
`--wpds-dimension-gap-3xl`, which the video page's comment records as the
design's breathing room. Post detail reaches the same 40px only once its tab
bar stops adding a bottom margin on top of it: #50540 zeroed that margin for
exactly this reason and #50562 restored it for a two-row header that no longer
exists, so 16px + 32px becomes 40px and the two pages finally agree. And the
shared `.content` end padding was a bare 24px restating
`--wpds-dimension-padding-2xl`.

`postHeaderSlots` and `videoHeaderSlots` each declared their own copy of the
slot shape; both now return `DetailPageHeaderSlots`, which the layout derives
from `SectionHeaderProps` so a required `title` and `busy` stay required.

`DetailPageTabs` re-exports the tab root beside the panel, so a detail route
reaches both through one package specifier — the constraint `report-page-tabs`
already documents. `DetailPageTabPanelProps` is declared and exported with its
`TabId` generic rather than leaving consumers to import the underlying UI type.

Drops the `display: flex` widget-chrome workaround: `@wordpress/widget-dashboard`
0.5.0, the version pinned here, ships the upstream fix
(WordPress/gutenberg#80570) in `.widget-chrome` itself.

The suites assert the classes the gutters, the grid gap and the Card padding
hang off, with a local style mock — which keeps them out of the shared no-mocks
group, per `tests/groups/README.md`.

WOOA7S-1949

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W4VNbKvETw12J6L1nCzixU

* change: settle the three review notes on the shared detail page layout

The post tab bar's `margin-block-end: 0` lands on the same element as
`SectionTabs`' own rule, both single-class, so it only won because the
toolkit's stylesheet is emitted first. Doubling the selector makes it win
outright, and an import reorder can no longer move the header spacing.

`DetailPageTabs` and `DetailPageTabPanel` move into `detail-page-tabs.tsx`,
matching `report-page-tabs` next door. The layout no longer imports
`SectionTabPanel`, so `video-detail/stage.test.tsx` drops the mock it carried
for a page with no tabs — a mock the suite already passed without.

`DetailPageShell`'s test mock swallowed `...pageProps`, leaving the one thing
the component does beyond `clsx` unasserted. The mock now captures the rest
props and the test checks `visual` and `breadcrumbs` reach `Page`; removing the
spread fails it.

WOOA7S-1949

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LouhrnbjGjdAK2BZqC2M7s

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

Committed via a GitHub action: https://github.com/Automattic/jetpack/actions/runs/33715644341

Upstream-Ref: Automattic/jetpack@df431e9
matticbot pushed a commit to Automattic/jetpack-premium-analytics that referenced this pull request Sep 3, 2026
…es (#51875)

* feat: use SectionHeader on the post and video detail pages

The detail pages hand-rolled a third header beside the dashboard's and the
report pages': a flex row with its own wrap rules, plus a 440px constant
reserved for the date panel and a ref feeding it `containerElement`.

SectionHeader gains the two parameters those pages needed and nothing else
had — a `visual` slot and a `subTitle` — plus a `headingLevel`, since a
detail page's title is its `h1`. Naming and the decorative contract on the
visual follow `@wordpress/admin-ui`'s own page header, which the same files
already render.

The slot owns the visual's box, so both summary cards stop restating the
72px square and its radius. That also settles a latent difference between
them: the post thumbnail hard-coded `8px` where the video poster read
`--wpds-border-radius-lg`, which is 8px in the default theme and 0 in the
zero-radius one.

The pages keep the panel's responsive step-down through the header's
container query, so the external measurement retires with the migration.

On video detail, a failed or missing video now leaves the header with its
date controls alone and states the reason below it, where the widgets would
have been: an error is not something the shared header should know about.

WOOA7S-1949

* fix: give the detail-page header a heading in every summary state

From review of the SectionHeader migration.

* `title` goes back to a required prop. Optional, it let a page render a
  header with no heading at all, which is what the video stage did in its
  loading, error and not-found states: it spread `{}` into the header and
  the page lost its `h1`. Required, the spread is a type error.
* `videoHeaderSlots` now owns every summary state, so the video page keeps
  its `h1`, its visual box and its date controls throughout: a skeleton
  while the summary resolves (matching the post page, WOOA7S-2059), and a
  named state when it fails. The notice below the header is unchanged.
* `postHeaderSlots` names an untitled or failed post rather than dropping
  the heading, and restores the `aria-busy` the summary card carried.
* Both slot factories and `performanceSentence` take the package's own
  `DateRange` instead of three inline spellings of it, two of which the
  real type could not be assigned to. `HeaderSlots` is now one exported
  `Pick` of the header's props rather than a hand-copy in each file.
* `.withVisual` no longer widens the gap between the title and the
  controls, so the stacking breakpoint constant matches the width the row
  actually needs.
* Cover the untitled and failed paths, the video slots (which had no test
  of their own), the date helpers' guards, and the stage wiring the mocks
  were hiding; run the header's date helpers under test-tz.

* chore: keep the header date helpers out of the cross-timezone run

The fixture publishes at 08:00, so neither timezone test-tz runs shifts
its day. The entry would suggest coverage it does not give.

* Premium Analytics: share one page layout between the post and video detail stages (#51877)

* refactor: share one page layout between the post and video detail stages

Both stages carried their own copy of the same scaffold: a `.page`, a
`.scrollArea`, a `.content` band and a `.widgets` block that was byte-identical
down to its TODO. `DetailPageShell` / `DetailPageLayout` / `DetailPageSection`
now own that structure, following `ReportPageShell` / `ReportPageLayout` next
door, so the stages hand over their header slots, their date controls and their
widget content and nothing else.

The layout lives in `widgets-toolkit` beside `report-page` rather than under
`routes/`: wp-build treats every directory in `routes/` as a route to build, so
a shared folder there would be discovered as one.

`.widgets` folds into the section: `--wp-grid-gap` is inherited and the Card
rules are descendant selectors, so moving them one level out matches the same
elements without an extra wrapper around the grid.

Two differences the copies had drifted into, both invisible in the default
theme, are settled. The header's `padding-block` converges on 40px, written as
`--wpds-dimension-gap-3xl`, which the video page's comment records as the
design's breathing room. Post detail reaches the same 40px only once its tab
bar stops adding a bottom margin on top of it: #50540 zeroed that margin for
exactly this reason and #50562 restored it for a two-row header that no longer
exists, so 16px + 32px becomes 40px and the two pages finally agree. And the
shared `.content` end padding was a bare 24px restating
`--wpds-dimension-padding-2xl`.

`postHeaderSlots` and `videoHeaderSlots` each declared their own copy of the
slot shape; both now return `DetailPageHeaderSlots`, which the layout derives
from `SectionHeaderProps` so a required `title` and `busy` stay required.

`DetailPageTabs` re-exports the tab root beside the panel, so a detail route
reaches both through one package specifier — the constraint `report-page-tabs`
already documents. `DetailPageTabPanelProps` is declared and exported with its
`TabId` generic rather than leaving consumers to import the underlying UI type.

Drops the `display: flex` widget-chrome workaround: `@wordpress/widget-dashboard`
0.5.0, the version pinned here, ships the upstream fix
(WordPress/gutenberg#80570) in `.widget-chrome` itself.

The suites assert the classes the gutters, the grid gap and the Card padding
hang off, with a local style mock — which keeps them out of the shared no-mocks
group, per `tests/groups/README.md`.

WOOA7S-1949

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W4VNbKvETw12J6L1nCzixU

* change: settle the three review notes on the shared detail page layout

The post tab bar's `margin-block-end: 0` lands on the same element as
`SectionTabs`' own rule, both single-class, so it only won because the
toolkit's stylesheet is emitted first. Doubling the selector makes it win
outright, and an import reorder can no longer move the header spacing.

`DetailPageTabs` and `DetailPageTabPanel` move into `detail-page-tabs.tsx`,
matching `report-page-tabs` next door. The layout no longer imports
`SectionTabPanel`, so `video-detail/stage.test.tsx` drops the mock it carried
for a page with no tabs — a mock the suite already passed without.

`DetailPageShell`'s test mock swallowed `...pageProps`, leaving the one thing
the component does beyond `clsx` unasserted. The mock now captures the rest
props and the test checks `visual` and `breadcrumbs` reach `Page`; removing the
spread fails it.

WOOA7S-1949

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LouhrnbjGjdAK2BZqC2M7s

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

Committed via a GitHub action: https://github.com/Automattic/jetpack/actions/runs/33715644341

Upstream-Ref: Automattic/jetpack@df431e9
matticbot pushed a commit to Automattic/wpcom-site-helper that referenced this pull request Sep 3, 2026
…es (#51875)

* feat: use SectionHeader on the post and video detail pages

The detail pages hand-rolled a third header beside the dashboard's and the
report pages': a flex row with its own wrap rules, plus a 440px constant
reserved for the date panel and a ref feeding it `containerElement`.

SectionHeader gains the two parameters those pages needed and nothing else
had — a `visual` slot and a `subTitle` — plus a `headingLevel`, since a
detail page's title is its `h1`. Naming and the decorative contract on the
visual follow `@wordpress/admin-ui`'s own page header, which the same files
already render.

The slot owns the visual's box, so both summary cards stop restating the
72px square and its radius. That also settles a latent difference between
them: the post thumbnail hard-coded `8px` where the video poster read
`--wpds-border-radius-lg`, which is 8px in the default theme and 0 in the
zero-radius one.

The pages keep the panel's responsive step-down through the header's
container query, so the external measurement retires with the migration.

On video detail, a failed or missing video now leaves the header with its
date controls alone and states the reason below it, where the widgets would
have been: an error is not something the shared header should know about.

WOOA7S-1949

* fix: give the detail-page header a heading in every summary state

From review of the SectionHeader migration.

* `title` goes back to a required prop. Optional, it let a page render a
  header with no heading at all, which is what the video stage did in its
  loading, error and not-found states: it spread `{}` into the header and
  the page lost its `h1`. Required, the spread is a type error.
* `videoHeaderSlots` now owns every summary state, so the video page keeps
  its `h1`, its visual box and its date controls throughout: a skeleton
  while the summary resolves (matching the post page, WOOA7S-2059), and a
  named state when it fails. The notice below the header is unchanged.
* `postHeaderSlots` names an untitled or failed post rather than dropping
  the heading, and restores the `aria-busy` the summary card carried.
* Both slot factories and `performanceSentence` take the package's own
  `DateRange` instead of three inline spellings of it, two of which the
  real type could not be assigned to. `HeaderSlots` is now one exported
  `Pick` of the header's props rather than a hand-copy in each file.
* `.withVisual` no longer widens the gap between the title and the
  controls, so the stacking breakpoint constant matches the width the row
  actually needs.
* Cover the untitled and failed paths, the video slots (which had no test
  of their own), the date helpers' guards, and the stage wiring the mocks
  were hiding; run the header's date helpers under test-tz.

* chore: keep the header date helpers out of the cross-timezone run

The fixture publishes at 08:00, so neither timezone test-tz runs shifts
its day. The entry would suggest coverage it does not give.

* Premium Analytics: share one page layout between the post and video detail stages (#51877)

* refactor: share one page layout between the post and video detail stages

Both stages carried their own copy of the same scaffold: a `.page`, a
`.scrollArea`, a `.content` band and a `.widgets` block that was byte-identical
down to its TODO. `DetailPageShell` / `DetailPageLayout` / `DetailPageSection`
now own that structure, following `ReportPageShell` / `ReportPageLayout` next
door, so the stages hand over their header slots, their date controls and their
widget content and nothing else.

The layout lives in `widgets-toolkit` beside `report-page` rather than under
`routes/`: wp-build treats every directory in `routes/` as a route to build, so
a shared folder there would be discovered as one.

`.widgets` folds into the section: `--wp-grid-gap` is inherited and the Card
rules are descendant selectors, so moving them one level out matches the same
elements without an extra wrapper around the grid.

Two differences the copies had drifted into, both invisible in the default
theme, are settled. The header's `padding-block` converges on 40px, written as
`--wpds-dimension-gap-3xl`, which the video page's comment records as the
design's breathing room. Post detail reaches the same 40px only once its tab
bar stops adding a bottom margin on top of it: #50540 zeroed that margin for
exactly this reason and #50562 restored it for a two-row header that no longer
exists, so 16px + 32px becomes 40px and the two pages finally agree. And the
shared `.content` end padding was a bare 24px restating
`--wpds-dimension-padding-2xl`.

`postHeaderSlots` and `videoHeaderSlots` each declared their own copy of the
slot shape; both now return `DetailPageHeaderSlots`, which the layout derives
from `SectionHeaderProps` so a required `title` and `busy` stay required.

`DetailPageTabs` re-exports the tab root beside the panel, so a detail route
reaches both through one package specifier — the constraint `report-page-tabs`
already documents. `DetailPageTabPanelProps` is declared and exported with its
`TabId` generic rather than leaving consumers to import the underlying UI type.

Drops the `display: flex` widget-chrome workaround: `@wordpress/widget-dashboard`
0.5.0, the version pinned here, ships the upstream fix
(WordPress/gutenberg#80570) in `.widget-chrome` itself.

The suites assert the classes the gutters, the grid gap and the Card padding
hang off, with a local style mock — which keeps them out of the shared no-mocks
group, per `tests/groups/README.md`.

WOOA7S-1949

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W4VNbKvETw12J6L1nCzixU

* change: settle the three review notes on the shared detail page layout

The post tab bar's `margin-block-end: 0` lands on the same element as
`SectionTabs`' own rule, both single-class, so it only won because the
toolkit's stylesheet is emitted first. Doubling the selector makes it win
outright, and an import reorder can no longer move the header spacing.

`DetailPageTabs` and `DetailPageTabPanel` move into `detail-page-tabs.tsx`,
matching `report-page-tabs` next door. The layout no longer imports
`SectionTabPanel`, so `video-detail/stage.test.tsx` drops the mock it carried
for a page with no tabs — a mock the suite already passed without.

`DetailPageShell`'s test mock swallowed `...pageProps`, leaving the one thing
the component does beyond `clsx` unasserted. The mock now captures the rest
props and the test checks `visual` and `breadcrumbs` reach `Page`; removing the
spread fails it.

WOOA7S-1949

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LouhrnbjGjdAK2BZqC2M7s

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

Committed via a GitHub action: https://github.com/Automattic/jetpack/actions/runs/33715644341

Upstream-Ref: Automattic/jetpack@df431e9
wporg-sync pushed a commit to WordPress/wordpress-develop that referenced this pull request Sep 8, 2026
This updates the pinned commit hash of the Gutenberg repository from `5a0417990a9404cc2562cdd35e3054cb0d3e546e` (version `23.7.0`) to `ae8b34d78e1abc6d1c866fdc00080a1452de82ad` (version `23.8.0`).

A full list of changes included in this commit can be found on GitHub: https://github.com/WordPress/gutenberg/compare/v23.7.0..v23.8.0.

- Fix: New route-based admin pages are empty when no JS (WordPress/gutenberg#80628)
- Report flaky tests: declare @types/node (WordPress/gutenberg#80838)
- Storybook e2e: add small, compact and icon examples to button matrix (WordPress/gutenberg#80793)
- ESLint: Drop @eslint/compat fixup for jest-dom and testing-library (WordPress/gutenberg#80842)
- Storybook: Use SelectControl in Motion tokens story (WordPress/gutenberg#80790)
- Writing flow: forward delete an empty paragraph without breaking apart the next block (WordPress/gutenberg#80813)
- ToggleControl: Add "With Visual" Storybook story (WordPress/gutenberg#80803)
- Bump the github-actions group across 1 directory with 5 updates (WordPress/gutenberg#80684)
- Update Ariakit packages (WordPress/gutenberg#80765)
- Components: Update Floating UI to 2.1.9 (WordPress/gutenberg#80761)
- Improve pre-flight npm access checks (WordPress/gutenberg#80334)
- Ensure static checks can run for private mirrors (WordPress/gutenberg#80817)
- Components: Update react-day-picker to 9.14.0 (WordPress/gutenberg#80792)
- Testing: Remove the jest-puppeteer-axe package (WordPress/gutenberg#80775)
- Tools: Use native agent skill discovery (WordPress/gutenberg#80811)
- Table of Contents: Replace "Convert to static list" with confirmed "Detach" action (WordPress/gutenberg#80844)
- Page List: Rename the Edit action to Detach and confirm it in a dialog (WordPress/gutenberg#80847)
- URLInput: Simplify keyboard handling and fix arrow keys with a text selection (WordPress/gutenberg#80780)
- Upload Media: Fail the item when the /finalize request fails (WordPress/gutenberg#80725)
- Jest preset: support self-referencing via exports (WordPress/gutenberg#80837)
- Fix template `modified` and `date` return value for file templates (WordPress/gutenberg#80733)
- Element: Make the package importable in React 19 (WordPress/gutenberg#80053)
- Add CheckboxControl with-visual Storybook story. (WordPress/gutenberg#80849)
- UI: Add Combobox.InputGroup primitive (WordPress/gutenberg#80869)
- Block Editor: Clear the moving animation's z-index when it finishes (WordPress/gutenberg#80824)
- SearchableChipSelect: Add form primitive to @wordpress/ui (WordPress/gutenberg#80779)
- Playlist: Add track icon (WordPress/gutenberg#80959)
- Flaky tests: fix router navigate latest HTML (WordPress/gutenberg#80178)
- Components: Update polymorphism types to allow all attributes when specifying `as` (WordPress/gutenberg#80705)
- Block JSON schema & PHP-only blocks: Add `autoRegister` support (WordPress/gutenberg#80173)
- Boot: Adjust specificity of the image reset styles so components can size their own images (WordPress/gutenberg#80845)
- Components: Opt-in ConfirmDialog for auto-documentation (WordPress/gutenberg#80866)
- RichText: don't apply input transform when there's no onReplace (WordPress/gutenberg#80978)
- Quote: Ensure paragraph placeholder appears after deleting nested blocks (WordPress/gutenberg#77151)
- Block editor: make the Group action wrap blocks with a group transform (WordPress/gutenberg#80891)
- Copy: preserve the block when its entire text is selected (WordPress/gutenberg#80994)
- Add opt-out for block style state controls (WordPress/gutenberg#80956)
- Upgrade Playwright to v1.62 (WordPress/gutenberg#81001)
- List View: Speed up opening by removing a forced style recalculation (WordPress/gutenberg#80929)
- Widget Dashboard: preserve widget chrome flex layout (WordPress/gutenberg#80570)
- Widget Primitives: document actions as verbs, not links (WordPress/gutenberg#80974)
- Core Data: add missing @wordpress/base-styles dependency (WordPress/gutenberg#81012)
- Ignore node_modules in schema integration test globs (WordPress/gutenberg#81013)
- RichText: fix paste handler crash when pasting files (WordPress/gutenberg#81010)
- Docs: Add VS Code setup guidance (WordPress/gutenberg#77913)
- Perf Tests: Merge selection event windows instead of summing durations (WordPress/gutenberg#81002)
- Storybook: move smoke-test deps into the storybook workspace (WordPress/gutenberg#81017)
- Unit Tests: Reorganise the jest config file. (WordPress/gutenberg#80940)
- Performance Tests: Ignore the locally generated artifacts directory (WordPress/gutenberg#81024)
- Editor: Remove sidebar tabs focus sync effect (WordPress/gutenberg#81020)
- Widgets: carry a declarative `icon` through the widget pipeline (WordPress/gutenberg#80969)
- RTC: Remove excess autosave notices (when not useful) (WordPress/gutenberg#80539)
- UI: Use focus styles from base-styles (WordPress/gutenberg#80635)
- Automated Testing: Add Storybook component documentation regression testing (WordPress/gutenberg#80655)
- Pass Playlist controls to track blocks (WordPress/gutenberg#80368)
- Components: Deprecate Surface (WordPress/gutenberg#80943)
- Tabs: Support Home and End keys for keyboard navigation (WordPress/gutenberg#80912)
- Fix typos in code `comments` and `JSDoc` (WordPress/gutenberg#81045)
- Interface: Remove incorrect aria-expanded from pin-to-toolbar button (WordPress/gutenberg#79874)
- List View: Speed up opening by removing a second render pass (WordPress/gutenberg#80935)
- Docs: Use `gutenberg` instead of `Gutenberg` in package name (WordPress/gutenberg#81051)
- Fix ESLint warnings for 'navigateRegionsProps' spread (WordPress/gutenberg#81052)
- Tests: Replace page-level selectors with locators in e2e specs (WordPress/gutenberg#81053)
- RTC: Disable custom autosave controller when RTC is disabled (WordPress/gutenberg#80769)
- Background: Fix the legacy gradient UI where a gradient cannot be selected (WordPress/gutenberg#81056)
- Rename blockStatesEnabled setting to blockStatesEditingEnabled (WordPress/gutenberg#81058)
- Background: Fix the legacy gradient UI where a gradient cannot be selected - Add missing change log (WordPress/gutenberg#81060)
- Declare missing prettier and stylelint workspace dependencies (WordPress/gutenberg#81065)
- Notes: Display shortcut for form action buttons (WordPress/gutenberg#81064)
- View config: lowercase dynamic filter names (WordPress/gutenberg#81068)
- CI: cache the system packages Playwright dowloads for WebKit (WordPress/gutenberg#80846)
- List View: Collapse off-window placeholder rows into a single spacer row (WordPress/gutenberg#80953)
- devops: balance Playwright shards by duration (WordPress/gutenberg#79479)
- Views: honor developer-defined view config overrides (WordPress/gutenberg#80832)
- Components: Migrate ItemGroup to SCSS module (WordPress/gutenberg#80797)
- Test: Add Vitest migration routing guardrails (WordPress/gutenberg#81036)
- Visual revisions: Add a code diff view inside the editor (WordPress/gutenberg#80314)
- Bump actions/labeler from 6.1.0 to 7.0.0 in /.github/workflows (WordPress/gutenberg#80966)
- Visual revisions: add shareable urls (WordPress/gutenberg#79934)
- Fix e2e tests that break when shard rebalancing changes their neighbors (WordPress/gutenberg#81117)
- Query: guard non-scalar queryId to avoid fatal in enhanced pagination (WordPress/gutenberg#80724)
- Replace deprecated useResizeObserver for useScaleCanvas (WordPress/gutenberg#67508)
- CI: Add job timeouts to E2E, static checks, bundle size, and create block (WordPress/gutenberg#80801)
- Allow organization or repository variable to dictate the Actions runner (WordPress/gutenberg#81087)
- List View: Only subscribe to the block subtree for rows that can show images (WordPress/gutenberg#81076)
- Editor: Migrate settings sidebar to Tabs from @wordpress/ui (WordPress/gutenberg#81054)
- Notes: Email users mentioned in a note (WordPress/gutenberg#79606)
- List View: Narrow the dependants of the memoized List View tree (WordPress/gutenberg#81129)
- List View: Pass only minimal required data to sub-tree branches (WordPress/gutenberg#81111)
- DataViews: Add `time` field type and control (WordPress/gutenberg#80830)
- Post Author Biography: Fix horizontal overflow with long unbroken text (WordPress/gutenberg#81018)
- Link Control: Restore the preview title underline (WordPress/gutenberg#81083)
- Views: Add React to the package's dev dependencies (WordPress/gutenberg#81139)
- feat: Add target param in proxy (WordPress/gutenberg#81141)
- Fix: flaky revisions pagination e2e cross-page diff assertion (WordPress/gutenberg#81119)
- Button: Suppress UA focus ring when focused and pressed (WordPress/gutenberg#81113)
- View config: add reference docs (WordPress/gutenberg#81149)
- Editor: Fix document tools button focus ring (WordPress/gutenberg#81115)
- List View: Replace expand/collapse callbacks with reducer dispatch (WordPress/gutenberg#81138)
- CI: resolve Playwright through the workspace that declares it (WordPress/gutenberg#81137)
- CI: build once and reuse the build across e2e tests shards (WordPress/gutenberg#81031)
- Fix: Tabs block: Start with empty tab labels with placeholders (WordPress/gutenberg#81009)
- Interface: Increase footer breadcrumb height to prevent focus ring clipping (WordPress/gutenberg#81145)
- Editor: clarify autosave failure notice (WordPress/gutenberg#76470)
- Theme: Omit color properties when neither provided nor inherited (WordPress/gutenberg#80600)
- Post editor: Add ThemeProvider for admin color schemes (WordPress/gutenberg#81112)
- Core Data: saveDirtyEntities: improve messaging of server errors (WordPress/gutenberg#81151)
- Global Styles: kebab-case preset slugs when converting references to custom properties (WordPress/gutenberg#80583)
- Revise CODEOWNERS for package ownership (removing nerrad) (WordPress/gutenberg#81175)
- Build: Wrap script bundles in an IIFE to contain 'use strict' (WordPress/gutenberg#79792)
- Media: Improve the HEIC upload error and keep any upload errors up until dismissed (WordPress/gutenberg#81130)
- Block Supports: Guard against non-string attribute values to avoid fatal errors (WordPress/gutenberg#80501)
- Video: Hide settings for the GIF variation (WordPress/gutenberg#81142)
- Video: clarify the Video variation description (WordPress/gutenberg#81181)
- Media Editor: Render sidebar tabs via ComplementaryArea's render prop (WordPress/gutenberg#81133)
- Bump docker/login-action (WordPress/gutenberg#80962)
- Bump actions/setup-node from 6.4.0 to 7.0.0 in /.github/setup-node (WordPress/gutenberg#80963)
- fix(admin-ui): reset the wp-admin li margin that misaligns Breadcrumbs (WordPress/gutenberg#81134)
- Bump astral-sh/setup-uv from 8.3.2 to 9.0.0 in /.github/workflows (WordPress/gutenberg#80964)
- Fix/79643 rtc awareness mixed block selection (WordPress/gutenberg#79836)
- Agents: Add a defensive data design skill and route to the copy guide (WordPress/gutenberg#81131)
- ESLint: Ban `@ts-ignore` in favour of `@ts-expect-error` (WordPress/gutenberg#81148)
- Types: Replace remaining `@ts-expect-error` suppressions with proper typing (WordPress/gutenberg#81200)
- Button: turn on the width setting by default in theme.json (WordPress/gutenberg#81196)
- Notes: fix the mention notification email composition (WordPress/gutenberg#81187)
- Edit Widgets: Fix header toolbar button focus ring (WordPress/gutenberg#81176)
- List View: Reduce per-row store subscriptions (WordPress/gutenberg#81136)
- Customizer widgets: Add ThemeProvider for admin color schemes (WordPress/gutenberg#81174)
- Blocks: Declare the `@types/react-is` devDependency (WordPress/gutenberg#81203)
- Widgets editor: Add ThemeProvider for admin color schemes (WordPress/gutenberg#81173)
- PanelColorSettings: Restore the missing space below the panel header (WordPress/gutenberg#81155)
- Remove the editableRoot opt-in from the paragraph block (WordPress/gutenberg#81184)
- Media Attached to: Fix issue with the popover unexpectedly flipping, tweak wording (WordPress/gutenberg#81206)
- Components: Add allowForms prop to SandBox component (WordPress/gutenberg#76471)
- Ensure device preview is always accurate when window is zoomed in (WordPress/gutenberg#81193)
- DataViews: Pass only eligible items to a bulk action callback (WordPress/gutenberg#81198)
- DataViews: Make grid and table item preview aspect ratio configurable (WordPress/gutenberg#79329)
- Block Editor: Return false from isBlockSelected when there is no client ID (WordPress/gutenberg#81212)
- Blocks: Update hpq to 1.4.0 and drop the ts-expect-error suppressions (WordPress/gutenberg#81199)
- DataViews: Fix the between `date` filter losing a manually typed date on blur (WordPress/gutenberg#81150)
- Block Editor: Fix Select all freezing on large posts (WordPress/gutenberg#81210)
- List View: Split the context and drop dead props to cut re-renders on expand and collapse (WordPress/gutenberg#81159)
- Docs: Fix broken Figma links on the design resources page. (WordPress/gutenberg#81166)
- Blocks: Support static block templates in block type settings (WordPress/gutenberg#80027)
- AGENTS: Update development tips section (WordPress/gutenberg#81224)
- URLInput: Skip search requests while an IME composition is in progress (WordPress/gutenberg#80602)
- Components: Deprecate Animate (WordPress/gutenberg#80931)
- Fix: Trunk e2e failures caused by the navigation spec leaving plain permalinks (WordPress/gutenberg#81238)
- Use p elements for callout alerts in components docs (WordPress/gutenberg#81234)
- Storybook: Enable design system theme tool globally (WordPress/gutenberg#81116)
- Media: Cover client-side big image scaling and orphaned files (WordPress/gutenberg#81061)
- Footnotes: guard against invalid post meta values (WordPress/gutenberg#81201)
- Block editor: unify what a new sibling block inherits (WordPress/gutenberg#81250)
- Global Styles: Remove unused duplicate font family preview utilities (WordPress/gutenberg#81194)
- Docs: explain how the theme.json schema fixtures work (WordPress/gutenberg#81263)
- theme.json schema: fix block pseudo-classes and custom states (WordPress/gutenberg#81209)
- List View: Migrate label wrapper to UI Stack and drop Badge from the anchor (WordPress/gutenberg#81266)
- Docs: Remove dependency group import guidance (WordPress/gutenberg#81245)
- ESLint: Define dependency import rules (WordPress/gutenberg#81246)
- Flaky tests: Report as a PR comment only, stop creating issues (WordPress/gutenberg#81218)
- Dashboard Widgets: remove the Hello Dolly download action (WordPress/gutenberg#81272)
- Block Directory: Make downloadable block item labels translatable. (WordPress/gutenberg#81237)
- Icons: move the inline image icon into the library (WordPress/gutenberg#81271)
- Update phpcs, wpcs dependencies (WordPress/gutenberg#81279)
- fix: add optional chaining for empty reusable block (WordPress/gutenberg#81165) (WordPress/gutenberg#81177)
- DataViews: Inline the kebabCase utility from components (WordPress/gutenberg#81284)
- Navigation: Complete the DocBlocks for the responsive container and overlay style helpers (WordPress/gutenberg#80622)
- Style states: fix state deselection when selecting the already selected block (WordPress/gutenberg#81277)
- Fix missing return value in force_filtered_html_on_import footnotes filter (WordPress/gutenberg#81293)
- Packages: Recover July 29 npm release metadata (WordPress/gutenberg#81303)
- Global styles: render element styles set only inside a breakpoint (WordPress/gutenberg#81265)
- Style states: Fix phantom pseudo element style output (WordPress/gutenberg#81291)
- Docs: remove breakpoint-only element style example from global styles guide (WordPress/gutenberg#81308)
- Render viewport state element styles in the editor (WordPress/gutenberg#81307)
- theme.json schema: responsive states belong to blocks (WordPress/gutenberg#81253)
- theme.json schema: allow responsive states on block style variations (WordPress/gutenberg#81309)
- Block Inspector: Disable the 'Edit original' button when the entity ID is missing (WordPress/gutenberg#81288)
- Site Editor: Decode HTML entities in Identity fields (WordPress/gutenberg#81269)
- Document editEntityRecord's options.isCached param (WordPress/gutenberg#81318)
- Theme: Colocate plugin tests with implementations (WordPress/gutenberg#81247)
- Block Editor: Bail out of hasSelectedInnerBlock when there is no clientId (WordPress/gutenberg#81315)
- ESLint: Replace strict config with bulk suppressions (WordPress/gutenberg#81248)
- Block Library: Document security patch releases (WordPress/gutenberg#81295)
- ESLint: Remove legacy import suppressions (WordPress/gutenberg#81338)
- Components: Migrate Spinner styles from Emotion to SCSS module (WordPress/gutenberg#80511)
- DataViews: Use the public `@wordpress/ui` Badge instead of the private one (WordPress/gutenberg#81236)
- Pert Tests: Avoid inflating interaction metrics with startTracing (WordPress/gutenberg#81264)
- Block Editor: Simplify InspectorControlsFill rendering logic (WordPress/gutenberg#81286)
- Keycodes: Make `withIgnoreIMEEvents` a public API (WordPress/gutenberg#81343)
- Docs: Fix broken links to the removed JavaScript build setup guide. (WordPress/gutenberg#81232)
- Markdownlint: disable the MD033 (no-inline-html) rule project-wide (WordPress/gutenberg#81213)
- Docs: Fix typo in block file structure guide (WordPress/gutenberg#81348)
- Playlist: Normalize Waveform Player configuration handling (WordPress/gutenberg#81342)
- Site editor: fix unreadable sidebar hover color (WordPress/gutenberg#81317)
- Global Styles: Migrate font size presets to the shared preset layer (WordPress/gutenberg#79811)
- Block Editor: Convert useBlockVisibility hook to TypeScript (WordPress/gutenberg#80390)
- Scope breakpoint media queries to screen so printing does not look like a resize (WordPress/gutenberg#81367)
- New `kebab-case` package: extract utility and migrate private API calls (WordPress/gutenberg#81294)
- Remove content types experiment (WordPress/gutenberg#81340)
- Editor: Keep the canvas height stable while resizing the canvas (WordPress/gutenberg#81163)
- Dashboard Widgets: add icon and relevance to the widget action envelope (WordPress/gutenberg#81275)
- Playlist: Improve audio conversion and track selection (WordPress/gutenberg#80926)
- Try: Set post navigation link icon to next. (WordPress/gutenberg#81384)
- UI: Derive Base UI direction from WordPress i18n (WordPress/gutenberg#80399)
- DataViews:  Fix `array` field type validation for empty values (WordPress/gutenberg#81378)
- Bump github/codeql-action/upload-sarif (WordPress/gutenberg#81287)
- Bump actions/stale from 10.4.0 to 11.0.0 in /.github/workflows (WordPress/gutenberg#81219)
- Monitor all setup-related composite Actions. (WordPress/gutenberg#81192)
- IconButton: Improve keyboard shortcut accessibility (WordPress/gutenberg#80402)
- Interface: Stop the secondary sidebar animating into place on page load (WordPress/gutenberg#81362)
- Fix: flaky list view paste block styles e2e test (WordPress/gutenberg#81229)
- Docs: Add error message guidance. (WordPress/gutenberg#81143)
- wp-build: Render the no-JS fallback in the generated page templates (WordPress/gutenberg#81365)
- Changed Build Process Link and remove unused tags (WordPress/gutenberg#81360)
- Scripts: Prevent a UTF-8 BOM in the middle of extracted CSS (WordPress/gutenberg#81383)
- Global Styles: Migrate shadows presets to use the preset management layer. (WordPress/gutenberg#79812)
- Global Styles: report border, shadow, outline, filter and dimension changes (WordPress/gutenberg#81407)
- Dashboard Widgets: split action icons into wire and resolved forms (WordPress/gutenberg#81381)
- Block Editor: Fix Escape from the block toolbar and stop redundant last focus dispatches (WordPress/gutenberg#81319)
- Block Mover: Add the keyboard shortcut to the buttons' spoken description (WordPress/gutenberg#81380)
- Format Library: Remove unused CSS rule (WordPress/gutenberg#77831)
- Core Data: Fix post staying dirty after saving edited post meta with RTC enabled (WordPress/gutenberg#81392)
- Widget Dashboard: host-tunable tile spacing via public custom properties (WordPress/gutenberg#81352)
- DataForm: Fix hidden fields validation (WordPress/gutenberg#81377)
- Tools: Make agent setup a workspace (WordPress/gutenberg#81418)
- Test: Add private Vitest config and migrate a pilot test (WordPress/gutenberg#81037)
- Interface: Let CSS own the ComplementaryArea width and use AnimatePresence custom for exit (WordPress/gutenberg#81363)
- Notes: Fix text wrapping for long usernames in collaboration sidebar (WordPress/gutenberg#81406)
- DataViews: vendor `ValidatedSelectControl` (WordPress/gutenberg#81391)
- UI: Add `Calendar` and `RangeCalendar`, moved from `components` private APIs (WordPress/gutenberg#81337)
- Feature: Tabs block: consider using the tab title in the Document Overview instead of a generic "Tab" label (WordPress/gutenberg#81427)
- fix: order site identity changes predictably (WordPress/gutenberg#81283)
- Docs: Fix broken link to the Node.js debugging guide. (WordPress/gutenberg#81398)
- Navigation Overlay Close: Inherit typography and color from the overlay (WordPress/gutenberg#80751)
- Fix: Regression: Tabs block: Start with empty tab labels with placeholders (WordPress/gutenberg#81429)
- components/Menu: Restore Modal focus return when menu items close (WordPress/gutenberg#81164)
- DataViews: Move the rich text control into the editor package (WordPress/gutenberg#81430)
- Components: Remove ValidatedTextControl private API (WordPress/gutenberg#80680)
- Cover: Avoid passing null as the featured image size (WordPress/gutenberg#81444)
- DataViews: vendor `ValidatedNumberControl` (WordPress/gutenberg#81433)
- DataViews: vendor ValidatedCheckboxControl (WordPress/gutenberg#81435)
- DataViews: vendor ValidatedRadioControl (WordPress/gutenberg#81434)
- UI: Upgrade React DayPicker to version 10 (WordPress/gutenberg#81439)
- Block editor: render a real default block in place of the default appender (WordPress/gutenberg#81231)
- Spacing Sizes Control: Make the control label translatable independently of the input aria label. (WordPress/gutenberg#81240)
- Writing flow: stop the caret on containers that do not merge with the text flow (WordPress/gutenberg#81456)
- Remove an unmodified wrapper when all its inner blocks are removed (WordPress/gutenberg#42503)
- Normalize block gap values in layout (WordPress/gutenberg#81460)
- Docs: Add Block Actions Readme (WordPress/gutenberg#69408)
- Block editor: disclose the nested block count of a multi selection (WordPress/gutenberg#80745)
- Fix: flaky autosave shareable URL revisions e2e test. (WordPress/gutenberg#81455)
- Fix empty list block with anchor persisting after backspace deletion (WordPress/gutenberg#77000)
- Docs: Add Block List Readme (WordPress/gutenberg#69432)
- Docs: Add Block Lock Readme (WordPress/gutenberg#69434)
- Backport core fixes for finalize route (WordPress/gutenberg#81465)
- ESLint: Rename root eslint.config.cjs to eslint.config.mjs (WordPress/gutenberg#81468)
- Update 23.8 release branch  (WordPress/gutenberg#81486)
- RTC: Couple RTC and polling provider as an opt-in experiment (WordPress/gutenberg#80658)
- Align collaboration migration version markers with the 23.8.0 release (WordPress/gutenberg#81789)

Fixes #66066.

git-svn-id: https://develop.svn.wordpress.org/trunk@63534 602fd350-edb4-49c9-b593-d223f7449a82
wporg-sync pushed a commit to WordPress/WordPress that referenced this pull request Sep 8, 2026
This updates the pinned commit hash of the Gutenberg repository from `5a0417990a9404cc2562cdd35e3054cb0d3e546e` (version `23.7.0`) to `ae8b34d78e1abc6d1c866fdc00080a1452de82ad` (version `23.8.0`).

A full list of changes included in this commit can be found on GitHub: https://github.com/WordPress/gutenberg/compare/v23.7.0..v23.8.0.

- Fix: New route-based admin pages are empty when no JS (WordPress/gutenberg#80628)
- Report flaky tests: declare @types/node (WordPress/gutenberg#80838)
- Storybook e2e: add small, compact and icon examples to button matrix (WordPress/gutenberg#80793)
- ESLint: Drop @eslint/compat fixup for jest-dom and testing-library (WordPress/gutenberg#80842)
- Storybook: Use SelectControl in Motion tokens story (WordPress/gutenberg#80790)
- Writing flow: forward delete an empty paragraph without breaking apart the next block (WordPress/gutenberg#80813)
- ToggleControl: Add "With Visual" Storybook story (WordPress/gutenberg#80803)
- Bump the github-actions group across 1 directory with 5 updates (WordPress/gutenberg#80684)
- Update Ariakit packages (WordPress/gutenberg#80765)
- Components: Update Floating UI to 2.1.9 (WordPress/gutenberg#80761)
- Improve pre-flight npm access checks (WordPress/gutenberg#80334)
- Ensure static checks can run for private mirrors (WordPress/gutenberg#80817)
- Components: Update react-day-picker to 9.14.0 (WordPress/gutenberg#80792)
- Testing: Remove the jest-puppeteer-axe package (WordPress/gutenberg#80775)
- Tools: Use native agent skill discovery (WordPress/gutenberg#80811)
- Table of Contents: Replace "Convert to static list" with confirmed "Detach" action (WordPress/gutenberg#80844)
- Page List: Rename the Edit action to Detach and confirm it in a dialog (WordPress/gutenberg#80847)
- URLInput: Simplify keyboard handling and fix arrow keys with a text selection (WordPress/gutenberg#80780)
- Upload Media: Fail the item when the /finalize request fails (WordPress/gutenberg#80725)
- Jest preset: support self-referencing via exports (WordPress/gutenberg#80837)
- Fix template `modified` and `date` return value for file templates (WordPress/gutenberg#80733)
- Element: Make the package importable in React 19 (WordPress/gutenberg#80053)
- Add CheckboxControl with-visual Storybook story. (WordPress/gutenberg#80849)
- UI: Add Combobox.InputGroup primitive (WordPress/gutenberg#80869)
- Block Editor: Clear the moving animation's z-index when it finishes (WordPress/gutenberg#80824)
- SearchableChipSelect: Add form primitive to @wordpress/ui (WordPress/gutenberg#80779)
- Playlist: Add track icon (WordPress/gutenberg#80959)
- Flaky tests: fix router navigate latest HTML (WordPress/gutenberg#80178)
- Components: Update polymorphism types to allow all attributes when specifying `as` (WordPress/gutenberg#80705)
- Block JSON schema & PHP-only blocks: Add `autoRegister` support (WordPress/gutenberg#80173)
- Boot: Adjust specificity of the image reset styles so components can size their own images (WordPress/gutenberg#80845)
- Components: Opt-in ConfirmDialog for auto-documentation (WordPress/gutenberg#80866)
- RichText: don't apply input transform when there's no onReplace (WordPress/gutenberg#80978)
- Quote: Ensure paragraph placeholder appears after deleting nested blocks (WordPress/gutenberg#77151)
- Block editor: make the Group action wrap blocks with a group transform (WordPress/gutenberg#80891)
- Copy: preserve the block when its entire text is selected (WordPress/gutenberg#80994)
- Add opt-out for block style state controls (WordPress/gutenberg#80956)
- Upgrade Playwright to v1.62 (WordPress/gutenberg#81001)
- List View: Speed up opening by removing a forced style recalculation (WordPress/gutenberg#80929)
- Widget Dashboard: preserve widget chrome flex layout (WordPress/gutenberg#80570)
- Widget Primitives: document actions as verbs, not links (WordPress/gutenberg#80974)
- Core Data: add missing @wordpress/base-styles dependency (WordPress/gutenberg#81012)
- Ignore node_modules in schema integration test globs (WordPress/gutenberg#81013)
- RichText: fix paste handler crash when pasting files (WordPress/gutenberg#81010)
- Docs: Add VS Code setup guidance (WordPress/gutenberg#77913)
- Perf Tests: Merge selection event windows instead of summing durations (WordPress/gutenberg#81002)
- Storybook: move smoke-test deps into the storybook workspace (WordPress/gutenberg#81017)
- Unit Tests: Reorganise the jest config file. (WordPress/gutenberg#80940)
- Performance Tests: Ignore the locally generated artifacts directory (WordPress/gutenberg#81024)
- Editor: Remove sidebar tabs focus sync effect (WordPress/gutenberg#81020)
- Widgets: carry a declarative `icon` through the widget pipeline (WordPress/gutenberg#80969)
- RTC: Remove excess autosave notices (when not useful) (WordPress/gutenberg#80539)
- UI: Use focus styles from base-styles (WordPress/gutenberg#80635)
- Automated Testing: Add Storybook component documentation regression testing (WordPress/gutenberg#80655)
- Pass Playlist controls to track blocks (WordPress/gutenberg#80368)
- Components: Deprecate Surface (WordPress/gutenberg#80943)
- Tabs: Support Home and End keys for keyboard navigation (WordPress/gutenberg#80912)
- Fix typos in code `comments` and `JSDoc` (WordPress/gutenberg#81045)
- Interface: Remove incorrect aria-expanded from pin-to-toolbar button (WordPress/gutenberg#79874)
- List View: Speed up opening by removing a second render pass (WordPress/gutenberg#80935)
- Docs: Use `gutenberg` instead of `Gutenberg` in package name (WordPress/gutenberg#81051)
- Fix ESLint warnings for 'navigateRegionsProps' spread (WordPress/gutenberg#81052)
- Tests: Replace page-level selectors with locators in e2e specs (WordPress/gutenberg#81053)
- RTC: Disable custom autosave controller when RTC is disabled (WordPress/gutenberg#80769)
- Background: Fix the legacy gradient UI where a gradient cannot be selected (WordPress/gutenberg#81056)
- Rename blockStatesEnabled setting to blockStatesEditingEnabled (WordPress/gutenberg#81058)
- Background: Fix the legacy gradient UI where a gradient cannot be selected - Add missing change log (WordPress/gutenberg#81060)
- Declare missing prettier and stylelint workspace dependencies (WordPress/gutenberg#81065)
- Notes: Display shortcut for form action buttons (WordPress/gutenberg#81064)
- View config: lowercase dynamic filter names (WordPress/gutenberg#81068)
- CI: cache the system packages Playwright dowloads for WebKit (WordPress/gutenberg#80846)
- List View: Collapse off-window placeholder rows into a single spacer row (WordPress/gutenberg#80953)
- devops: balance Playwright shards by duration (WordPress/gutenberg#79479)
- Views: honor developer-defined view config overrides (WordPress/gutenberg#80832)
- Components: Migrate ItemGroup to SCSS module (WordPress/gutenberg#80797)
- Test: Add Vitest migration routing guardrails (WordPress/gutenberg#81036)
- Visual revisions: Add a code diff view inside the editor (WordPress/gutenberg#80314)
- Bump actions/labeler from 6.1.0 to 7.0.0 in /.github/workflows (WordPress/gutenberg#80966)
- Visual revisions: add shareable urls (WordPress/gutenberg#79934)
- Fix e2e tests that break when shard rebalancing changes their neighbors (WordPress/gutenberg#81117)
- Query: guard non-scalar queryId to avoid fatal in enhanced pagination (WordPress/gutenberg#80724)
- Replace deprecated useResizeObserver for useScaleCanvas (WordPress/gutenberg#67508)
- CI: Add job timeouts to E2E, static checks, bundle size, and create block (WordPress/gutenberg#80801)
- Allow organization or repository variable to dictate the Actions runner (WordPress/gutenberg#81087)
- List View: Only subscribe to the block subtree for rows that can show images (WordPress/gutenberg#81076)
- Editor: Migrate settings sidebar to Tabs from @wordpress/ui (WordPress/gutenberg#81054)
- Notes: Email users mentioned in a note (WordPress/gutenberg#79606)
- List View: Narrow the dependants of the memoized List View tree (WordPress/gutenberg#81129)
- List View: Pass only minimal required data to sub-tree branches (WordPress/gutenberg#81111)
- DataViews: Add `time` field type and control (WordPress/gutenberg#80830)
- Post Author Biography: Fix horizontal overflow with long unbroken text (WordPress/gutenberg#81018)
- Link Control: Restore the preview title underline (WordPress/gutenberg#81083)
- Views: Add React to the package's dev dependencies (WordPress/gutenberg#81139)
- feat: Add target param in proxy (WordPress/gutenberg#81141)
- Fix: flaky revisions pagination e2e cross-page diff assertion (WordPress/gutenberg#81119)
- Button: Suppress UA focus ring when focused and pressed (WordPress/gutenberg#81113)
- View config: add reference docs (WordPress/gutenberg#81149)
- Editor: Fix document tools button focus ring (WordPress/gutenberg#81115)
- List View: Replace expand/collapse callbacks with reducer dispatch (WordPress/gutenberg#81138)
- CI: resolve Playwright through the workspace that declares it (WordPress/gutenberg#81137)
- CI: build once and reuse the build across e2e tests shards (WordPress/gutenberg#81031)
- Fix: Tabs block: Start with empty tab labels with placeholders (WordPress/gutenberg#81009)
- Interface: Increase footer breadcrumb height to prevent focus ring clipping (WordPress/gutenberg#81145)
- Editor: clarify autosave failure notice (WordPress/gutenberg#76470)
- Theme: Omit color properties when neither provided nor inherited (WordPress/gutenberg#80600)
- Post editor: Add ThemeProvider for admin color schemes (WordPress/gutenberg#81112)
- Core Data: saveDirtyEntities: improve messaging of server errors (WordPress/gutenberg#81151)
- Global Styles: kebab-case preset slugs when converting references to custom properties (WordPress/gutenberg#80583)
- Revise CODEOWNERS for package ownership (removing nerrad) (WordPress/gutenberg#81175)
- Build: Wrap script bundles in an IIFE to contain 'use strict' (WordPress/gutenberg#79792)
- Media: Improve the HEIC upload error and keep any upload errors up until dismissed (WordPress/gutenberg#81130)
- Block Supports: Guard against non-string attribute values to avoid fatal errors (WordPress/gutenberg#80501)
- Video: Hide settings for the GIF variation (WordPress/gutenberg#81142)
- Video: clarify the Video variation description (WordPress/gutenberg#81181)
- Media Editor: Render sidebar tabs via ComplementaryArea's render prop (WordPress/gutenberg#81133)
- Bump docker/login-action (WordPress/gutenberg#80962)
- Bump actions/setup-node from 6.4.0 to 7.0.0 in /.github/setup-node (WordPress/gutenberg#80963)
- fix(admin-ui): reset the wp-admin li margin that misaligns Breadcrumbs (WordPress/gutenberg#81134)
- Bump astral-sh/setup-uv from 8.3.2 to 9.0.0 in /.github/workflows (WordPress/gutenberg#80964)
- Fix/79643 rtc awareness mixed block selection (WordPress/gutenberg#79836)
- Agents: Add a defensive data design skill and route to the copy guide (WordPress/gutenberg#81131)
- ESLint: Ban `@ts-ignore` in favour of `@ts-expect-error` (WordPress/gutenberg#81148)
- Types: Replace remaining `@ts-expect-error` suppressions with proper typing (WordPress/gutenberg#81200)
- Button: turn on the width setting by default in theme.json (WordPress/gutenberg#81196)
- Notes: fix the mention notification email composition (WordPress/gutenberg#81187)
- Edit Widgets: Fix header toolbar button focus ring (WordPress/gutenberg#81176)
- List View: Reduce per-row store subscriptions (WordPress/gutenberg#81136)
- Customizer widgets: Add ThemeProvider for admin color schemes (WordPress/gutenberg#81174)
- Blocks: Declare the `@types/react-is` devDependency (WordPress/gutenberg#81203)
- Widgets editor: Add ThemeProvider for admin color schemes (WordPress/gutenberg#81173)
- PanelColorSettings: Restore the missing space below the panel header (WordPress/gutenberg#81155)
- Remove the editableRoot opt-in from the paragraph block (WordPress/gutenberg#81184)
- Media Attached to: Fix issue with the popover unexpectedly flipping, tweak wording (WordPress/gutenberg#81206)
- Components: Add allowForms prop to SandBox component (WordPress/gutenberg#76471)
- Ensure device preview is always accurate when window is zoomed in (WordPress/gutenberg#81193)
- DataViews: Pass only eligible items to a bulk action callback (WordPress/gutenberg#81198)
- DataViews: Make grid and table item preview aspect ratio configurable (WordPress/gutenberg#79329)
- Block Editor: Return false from isBlockSelected when there is no client ID (WordPress/gutenberg#81212)
- Blocks: Update hpq to 1.4.0 and drop the ts-expect-error suppressions (WordPress/gutenberg#81199)
- DataViews: Fix the between `date` filter losing a manually typed date on blur (WordPress/gutenberg#81150)
- Block Editor: Fix Select all freezing on large posts (WordPress/gutenberg#81210)
- List View: Split the context and drop dead props to cut re-renders on expand and collapse (WordPress/gutenberg#81159)
- Docs: Fix broken Figma links on the design resources page. (WordPress/gutenberg#81166)
- Blocks: Support static block templates in block type settings (WordPress/gutenberg#80027)
- AGENTS: Update development tips section (WordPress/gutenberg#81224)
- URLInput: Skip search requests while an IME composition is in progress (WordPress/gutenberg#80602)
- Components: Deprecate Animate (WordPress/gutenberg#80931)
- Fix: Trunk e2e failures caused by the navigation spec leaving plain permalinks (WordPress/gutenberg#81238)
- Use p elements for callout alerts in components docs (WordPress/gutenberg#81234)
- Storybook: Enable design system theme tool globally (WordPress/gutenberg#81116)
- Media: Cover client-side big image scaling and orphaned files (WordPress/gutenberg#81061)
- Footnotes: guard against invalid post meta values (WordPress/gutenberg#81201)
- Block editor: unify what a new sibling block inherits (WordPress/gutenberg#81250)
- Global Styles: Remove unused duplicate font family preview utilities (WordPress/gutenberg#81194)
- Docs: explain how the theme.json schema fixtures work (WordPress/gutenberg#81263)
- theme.json schema: fix block pseudo-classes and custom states (WordPress/gutenberg#81209)
- List View: Migrate label wrapper to UI Stack and drop Badge from the anchor (WordPress/gutenberg#81266)
- Docs: Remove dependency group import guidance (WordPress/gutenberg#81245)
- ESLint: Define dependency import rules (WordPress/gutenberg#81246)
- Flaky tests: Report as a PR comment only, stop creating issues (WordPress/gutenberg#81218)
- Dashboard Widgets: remove the Hello Dolly download action (WordPress/gutenberg#81272)
- Block Directory: Make downloadable block item labels translatable. (WordPress/gutenberg#81237)
- Icons: move the inline image icon into the library (WordPress/gutenberg#81271)
- Update phpcs, wpcs dependencies (WordPress/gutenberg#81279)
- fix: add optional chaining for empty reusable block (WordPress/gutenberg#81165) (WordPress/gutenberg#81177)
- DataViews: Inline the kebabCase utility from components (WordPress/gutenberg#81284)
- Navigation: Complete the DocBlocks for the responsive container and overlay style helpers (WordPress/gutenberg#80622)
- Style states: fix state deselection when selecting the already selected block (WordPress/gutenberg#81277)
- Fix missing return value in force_filtered_html_on_import footnotes filter (WordPress/gutenberg#81293)
- Packages: Recover July 29 npm release metadata (WordPress/gutenberg#81303)
- Global styles: render element styles set only inside a breakpoint (WordPress/gutenberg#81265)
- Style states: Fix phantom pseudo element style output (WordPress/gutenberg#81291)
- Docs: remove breakpoint-only element style example from global styles guide (WordPress/gutenberg#81308)
- Render viewport state element styles in the editor (WordPress/gutenberg#81307)
- theme.json schema: responsive states belong to blocks (WordPress/gutenberg#81253)
- theme.json schema: allow responsive states on block style variations (WordPress/gutenberg#81309)
- Block Inspector: Disable the 'Edit original' button when the entity ID is missing (WordPress/gutenberg#81288)
- Site Editor: Decode HTML entities in Identity fields (WordPress/gutenberg#81269)
- Document editEntityRecord's options.isCached param (WordPress/gutenberg#81318)
- Theme: Colocate plugin tests with implementations (WordPress/gutenberg#81247)
- Block Editor: Bail out of hasSelectedInnerBlock when there is no clientId (WordPress/gutenberg#81315)
- ESLint: Replace strict config with bulk suppressions (WordPress/gutenberg#81248)
- Block Library: Document security patch releases (WordPress/gutenberg#81295)
- ESLint: Remove legacy import suppressions (WordPress/gutenberg#81338)
- Components: Migrate Spinner styles from Emotion to SCSS module (WordPress/gutenberg#80511)
- DataViews: Use the public `@wordpress/ui` Badge instead of the private one (WordPress/gutenberg#81236)
- Pert Tests: Avoid inflating interaction metrics with startTracing (WordPress/gutenberg#81264)
- Block Editor: Simplify InspectorControlsFill rendering logic (WordPress/gutenberg#81286)
- Keycodes: Make `withIgnoreIMEEvents` a public API (WordPress/gutenberg#81343)
- Docs: Fix broken links to the removed JavaScript build setup guide. (WordPress/gutenberg#81232)
- Markdownlint: disable the MD033 (no-inline-html) rule project-wide (WordPress/gutenberg#81213)
- Docs: Fix typo in block file structure guide (WordPress/gutenberg#81348)
- Playlist: Normalize Waveform Player configuration handling (WordPress/gutenberg#81342)
- Site editor: fix unreadable sidebar hover color (WordPress/gutenberg#81317)
- Global Styles: Migrate font size presets to the shared preset layer (WordPress/gutenberg#79811)
- Block Editor: Convert useBlockVisibility hook to TypeScript (WordPress/gutenberg#80390)
- Scope breakpoint media queries to screen so printing does not look like a resize (WordPress/gutenberg#81367)
- New `kebab-case` package: extract utility and migrate private API calls (WordPress/gutenberg#81294)
- Remove content types experiment (WordPress/gutenberg#81340)
- Editor: Keep the canvas height stable while resizing the canvas (WordPress/gutenberg#81163)
- Dashboard Widgets: add icon and relevance to the widget action envelope (WordPress/gutenberg#81275)
- Playlist: Improve audio conversion and track selection (WordPress/gutenberg#80926)
- Try: Set post navigation link icon to next. (WordPress/gutenberg#81384)
- UI: Derive Base UI direction from WordPress i18n (WordPress/gutenberg#80399)
- DataViews:  Fix `array` field type validation for empty values (WordPress/gutenberg#81378)
- Bump github/codeql-action/upload-sarif (WordPress/gutenberg#81287)
- Bump actions/stale from 10.4.0 to 11.0.0 in /.github/workflows (WordPress/gutenberg#81219)
- Monitor all setup-related composite Actions. (WordPress/gutenberg#81192)
- IconButton: Improve keyboard shortcut accessibility (WordPress/gutenberg#80402)
- Interface: Stop the secondary sidebar animating into place on page load (WordPress/gutenberg#81362)
- Fix: flaky list view paste block styles e2e test (WordPress/gutenberg#81229)
- Docs: Add error message guidance. (WordPress/gutenberg#81143)
- wp-build: Render the no-JS fallback in the generated page templates (WordPress/gutenberg#81365)
- Changed Build Process Link and remove unused tags (WordPress/gutenberg#81360)
- Scripts: Prevent a UTF-8 BOM in the middle of extracted CSS (WordPress/gutenberg#81383)
- Global Styles: Migrate shadows presets to use the preset management layer. (WordPress/gutenberg#79812)
- Global Styles: report border, shadow, outline, filter and dimension changes (WordPress/gutenberg#81407)
- Dashboard Widgets: split action icons into wire and resolved forms (WordPress/gutenberg#81381)
- Block Editor: Fix Escape from the block toolbar and stop redundant last focus dispatches (WordPress/gutenberg#81319)
- Block Mover: Add the keyboard shortcut to the buttons' spoken description (WordPress/gutenberg#81380)
- Format Library: Remove unused CSS rule (WordPress/gutenberg#77831)
- Core Data: Fix post staying dirty after saving edited post meta with RTC enabled (WordPress/gutenberg#81392)
- Widget Dashboard: host-tunable tile spacing via public custom properties (WordPress/gutenberg#81352)
- DataForm: Fix hidden fields validation (WordPress/gutenberg#81377)
- Tools: Make agent setup a workspace (WordPress/gutenberg#81418)
- Test: Add private Vitest config and migrate a pilot test (WordPress/gutenberg#81037)
- Interface: Let CSS own the ComplementaryArea width and use AnimatePresence custom for exit (WordPress/gutenberg#81363)
- Notes: Fix text wrapping for long usernames in collaboration sidebar (WordPress/gutenberg#81406)
- DataViews: vendor `ValidatedSelectControl` (WordPress/gutenberg#81391)
- UI: Add `Calendar` and `RangeCalendar`, moved from `components` private APIs (WordPress/gutenberg#81337)
- Feature: Tabs block: consider using the tab title in the Document Overview instead of a generic "Tab" label (WordPress/gutenberg#81427)
- fix: order site identity changes predictably (WordPress/gutenberg#81283)
- Docs: Fix broken link to the Node.js debugging guide. (WordPress/gutenberg#81398)
- Navigation Overlay Close: Inherit typography and color from the overlay (WordPress/gutenberg#80751)
- Fix: Regression: Tabs block: Start with empty tab labels with placeholders (WordPress/gutenberg#81429)
- components/Menu: Restore Modal focus return when menu items close (WordPress/gutenberg#81164)
- DataViews: Move the rich text control into the editor package (WordPress/gutenberg#81430)
- Components: Remove ValidatedTextControl private API (WordPress/gutenberg#80680)
- Cover: Avoid passing null as the featured image size (WordPress/gutenberg#81444)
- DataViews: vendor `ValidatedNumberControl` (WordPress/gutenberg#81433)
- DataViews: vendor ValidatedCheckboxControl (WordPress/gutenberg#81435)
- DataViews: vendor ValidatedRadioControl (WordPress/gutenberg#81434)
- UI: Upgrade React DayPicker to version 10 (WordPress/gutenberg#81439)
- Block editor: render a real default block in place of the default appender (WordPress/gutenberg#81231)
- Spacing Sizes Control: Make the control label translatable independently of the input aria label. (WordPress/gutenberg#81240)
- Writing flow: stop the caret on containers that do not merge with the text flow (WordPress/gutenberg#81456)
- Remove an unmodified wrapper when all its inner blocks are removed (WordPress/gutenberg#42503)
- Normalize block gap values in layout (WordPress/gutenberg#81460)
- Docs: Add Block Actions Readme (WordPress/gutenberg#69408)
- Block editor: disclose the nested block count of a multi selection (WordPress/gutenberg#80745)
- Fix: flaky autosave shareable URL revisions e2e test. (WordPress/gutenberg#81455)
- Fix empty list block with anchor persisting after backspace deletion (WordPress/gutenberg#77000)
- Docs: Add Block List Readme (WordPress/gutenberg#69432)
- Docs: Add Block Lock Readme (WordPress/gutenberg#69434)
- Backport core fixes for finalize route (WordPress/gutenberg#81465)
- ESLint: Rename root eslint.config.cjs to eslint.config.mjs (WordPress/gutenberg#81468)
- Update 23.8 release branch  (WordPress/gutenberg#81486)
- RTC: Couple RTC and polling provider as an opt-in experiment (WordPress/gutenberg#80658)
- Align collaboration migration version markers with the 23.8.0 release (WordPress/gutenberg#81789)

Fixes #66066.
Built from https://develop.svn.wordpress.org/trunk@63534


git-svn-id: http://core.svn.wordpress.org/trunk@62710 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

First-time Contributor Pull request opened by a first-time contributor to Gutenberg repository [Package] Widget Dashboard /packages/widget-dashboard [Type] Enhancement A suggestion for improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants