Skip to content

Widget Dashboard: measure the header fit and document the chrome - #80423

Merged
retrofox merged 42 commits into
trunkfrom
update/widget-dashboard-toolbar-behavior
Jul 21, 2026
Merged

Widget Dashboard: measure the header fit and document the chrome#80423
retrofox merged 42 commits into
trunkfrom
update/widget-dashboard-toolbar-behavior

Conversation

@retrofox

@retrofox retrofox commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

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 availableSize was 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. useInlineFit reduces to natural > availableSize.

The docs are .md + .mdx story pages with hand-drawn SVGs, matching the widget-primitives pattern.

Testing

The stories exercise the fit directly:

npm run storybook:dev
  1. Open Widget Dashboard / Playground and shrink the canvas.
    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
  1. Open Widget Dashboard / Playground / Long Title and shrink the canvas.
    The title truncates with an ellipsis instead of wrapping out of the header row.

  2. Open Widget Dashboard / Introduction · Anatomy · Widget Chrome to review the docs.

In a real dashboard:

  1. Enable the gutenberg-dashboard-widgets experiment.
  2. Add the Hello Dolly widget and resize its tile.
  3. The header adapts the same way; with a help note present, it now collapses at the right point instead of overflowing.
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-controlswidget-attributes (WidgetAttributes), with attributes-dropdown and use-inline-fit inside.
  • widget-header-size.tswidget-header-fit.ts, which holds the fit contexts.
  • the value type WidgetAttributesWidgetAttributeValues, 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.

retrofox added 26 commits July 16, 2026 15:55
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.
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
@retrofox retrofox self-assigned this Jul 17, 2026
@github-actions

github-actions Bot commented Jul 17, 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: retrofox <retrofox@git.wordpress.org>
Co-authored-by: chihsuan <chihsuan@git.wordpress.org>

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

@retrofox
retrofox requested review from chihsuan and simison July 17, 2026 16:10
@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown

Size Change: 0 B

Total Size: 7.74 MB

compressed-size-action

@chihsuan chihsuan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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',
},

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Was removing target intentional? The Help text, comments, story description, and example data still describe two fields, but only metric remains editable.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Small optional thought: Is it possible to measure the toolbar padding too? Keeping 8 in JS could drift from the CSS token later.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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 ) -

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sorry, Chi, I don't follow you :-(

What do you mean? Did you notice any erratic behavior or something we should try to address?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Sorry, let me do more local tests first. 🙏

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I've slightly changed how the title behaves when the viewport width is stretched.

Now, it applies ellipsis, avoiding more than one line for the title. So maybe the issue you described was affected by this new behavior.

image

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks, just tested locally again. No issues found.

retrofox added 12 commits July 20, 2026 10:25
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
@chihsuan
chihsuan self-requested a review July 21, 2026 05:50

@chihsuan chihsuan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM! nice work. 🚢

@github-actions

Copy link
Copy Markdown

Flaky tests detected in bf9099e.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/29810935086
📝 Reported issues:

@retrofox
retrofox merged commit 11fbad9 into trunk Jul 21, 2026
58 of 59 checks passed
@retrofox
retrofox deleted the update/widget-dashboard-toolbar-behavior branch July 21, 2026 08:54
@github-actions github-actions Bot added this to the Gutenberg 23.7 milestone Jul 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Widget Dashboard: inline attribute controls overflow the header when the widget declares a help note

2 participants