Widget Dashboard: measure the header fit and document the chrome - #80423
Conversation
Carry declared actions from widget.json to the client through the build manifest, the widget-modules REST endpoint, and the useWidgetTypes merge.
Render a widget type's declared actions as a More dropdown of links in the normal-mode toolbar.
Cover the actions field in the widget-primitives README and CHANGELOG, and across the four pipeline stages in the architecture doc.
Give the demo widget types help notes and a goal-progress actions example so the story exercises both surfaces.
…ard-toolbar-behavior
identity width and trailing sections are measured, not assumed
introduction, dashboard anatomy, and widget chrome
settings trigger reserves via useReserveHeaderSpace; drop reservedSize
free the name for the attributes section component
parallel with widget-actions; rename component and sub-files
the file holds the fit contexts, not just sizing
show the settings icon button, not a fields dropdown
drop a duplicate line, correct the fit sentence, fix italics
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
|
Size Change: 0 B Total Size: 7.74 MB |
…ard-toolbar-behavior
…ard-toolbar-behavior
chihsuan
left a comment
There was a problem hiding this comment.
Thanks for working on this! One thing I’m unsure about is using the identity’s current width.
I also found a couple of small story/docs mismatches.
| type: 'text', | ||
| elements: GOAL_TARGETS, | ||
| relevance: 'high', | ||
| }, |
There was a problem hiding this comment.
Was removing target intentional? The Help text, comments, story description, and example data still describe two fields, but only metric remains editable.
There was a problem hiding this comment.
It was intentional. I want to show a widget instance with a single inline Field. Updating the docs.
| * side). Part of the header budget in both header variants, with and | ||
| * without identity. | ||
| */ | ||
| export const WIDGET_TOOLBAR_CHIP_RESERVE = 8; |
There was a problem hiding this comment.
Small optional thought: Is it possible to measure the toolbar padding too? Keeping 8 in JS could drift from the CSS token later.
There was a problem hiding this comment.
You were right, as usual 👍, and the drift is reproducible.
Set the chip to padding: 16px, leave the constant at 8, and keep the inline fields inline past the point where they fit, so they overflow the tile.
The constant is gone 🧹. The chip reports its own horizontal frame as the difference between the two boxes the resize entry already carries:
const border = entry.borderBoxSize?.[ 0 ]?.inlineSize ?? 0;
const content = entry.contentBoxSize?.[ 0 ]?.inlineSize ?? 0;
registerReserved( id, Math.max( 0, border - content ) );|
|
||
| ### Fitting the row | ||
|
|
||
| Each section renders inline when the row has room, and folds into a compact form when it does not. |
There was a problem hiding this comment.
Tiny wording mismatch: only Attributes folds. Identity shrinks and Actions stays compact. Maybe we can update this sentence to match the SVG below?
| ? headerWidth - | ||
| WIDGET_TOOLBAR_CHIP_RESERVE - | ||
| ( hasIdentity ? WIDGET_HEADER_IDENTITY_RESERVE : 0 ) | ||
| ( hasIdentity ? identityReserve : 0 ) - |
There was a problem hiding this comment.
I wonder if this should reserve the identity’s minimum width instead. Once the controls collapse, the identity grows into the free space, so the header may keep thinking there isn’t enough room to expand them again. That would also match the docs’ “identity floor” wording.
There was a problem hiding this comment.
Sorry, Chi, I don't follow you :-(
What do you mean? Did you notice any erratic behavior or something we should try to address?
There was a problem hiding this comment.
Sorry, let me do more local tests first. 🙏
There was a problem hiding this comment.
Thanks, just tested locally again. No issues found.
…ard-toolbar-behavior
the identity row is one line tall; a long title wrapped out of it
identity absorbs the row's squeeze, so its measured width tracked the presentation the budget decides
only the attributes fold; the absolute measurer the chip anchored is gone
the two thresholds are symmetric; the reserve changed policy, not correctness
the chip reports the gap between its border and content boxes, so the stylesheet owns the value
matches how the chip reports itself; padding on a section would go uncounted
the header measures the identity as it stands; it reserves no floor
…ard-toolbar-behavior
|
Flaky tests detected in bf9099e. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/29810935086
|

What?
Fix the tile header so the inline attribute controls collapse into a dropdown at the right point.
The fit is measured from the actual header row rather than fixed reserves, so a help note in the identity or the actions menu beside the controls no longer skews the budget. Fixes #80398.
Truncate the header title with an ellipsis instead of letting it wrap out of the single-line row.
Add Storybook docs for the dashboard: Introduction, Anatomy, and Widget Chrome.
The last one covers the header's sections and how the fit adapts.
Rename the attribute section for a vocabulary parallel to
widget-actions(see the note on renaming below).Why?
The previous fit reconstructed the header from constants: a fixed 128px identity reserve plus a partial toolbar measurement. Anything the math did not know skewed the result.
A help tooltip lives inside the identity but was not in the constant, so
availableSizewas overestimated, causing the controls to overflow instead of collapsing.The "More" menu actions sit beside the controls, and their width was not reduced either. The help case reproduces on trunk; both reproduce on this branch. #80398.
The chrome also had no shared documentation. The header's section model and its fit behavior lived only in the code.
How?
The header measures its own identity cluster (width plus the gap before the toolbar) and publishes
availableSize.Trailing sections register their footprint through
useReserveHeaderSpace, and the header subtracts them.The collapsible controls compare their natural width against what remains. No composite constants: whatever sits in the row is measured, so a new section counts on its own.
The toolbar chip reports its own padding and border the same way, as the difference between the border box and the content box the resize entry already carries. Observing the border box is what makes a padding change notify, since it leaves the content box untouched. No length in the budget is written twice.
One reserve path. Identity is measured by the header; every other section, the actions menu, and the settings trigger report up.
useInlineFitreduces tonatural > availableSize.The docs are
.md+.mdxstory pages with hand-drawn SVGs, matching thewidget-primitivespattern.Testing
The stories exercise the fit directly:
The high-relevance controls stay in line while they fit, then fold into the dropdown, and the actions menu keeps its place.
Screen.Recording.2026-07-20.at.2.14.15.PM.mov
Open Widget Dashboard / Playground / Long Title and shrink the canvas.
The title truncates with an ellipsis instead of wrapping out of the header row.
Open Widget Dashboard / Introduction · Anatomy · Widget Chrome to review the docs.
In a real dashboard:
gutenberg-dashboard-widgetsexperiment.Screen.Recording.2026-07-17.at.5.19.40.PM.mov
Documentation is a work in progress
These three pages are a first pass. We keep improving them: more of the chrome, the customize mode, and the remaining sections still deserve their own coverage.
A note on renaming
This PR carries a sizable rename pass, in favor of code quality and a coherent, parallel section vocabulary:
widget-attribute-controls→widget-attributes(WidgetAttributes), withattributes-dropdownanduse-inline-fitinside.widget-header-size.ts→widget-header-fit.ts, which holds the fit contexts.WidgetAttributes→WidgetAttributeValues, freeing the name for the section.All via
git mv, so history is preserved, and none of it changes behavior. CSS class names and the reserved IDs were left as-is to limit churn; more naming cleanup may follow.