Dashboard: add widget inserter modal#78033
Conversation
Mounts a Dialog-based inserter inside `WidgetDashboard`, opened by the "Add widgets" button in `Actions`. Picks types via `DataViewsPicker` with live previews, supports multi-select, and appends new instances through `onLayoutChange`.
|
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.95 MB ℹ️ View Unchanged
|
|
Flaky tests detected in d81439a. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/25502958861
|
Write logical border shorthands directly so cssnano's longhand merge doesn't emit a `border` reset after the logical widths.
|
|
||
| return ( | ||
| <Dialog.Root open={ inserterOpen } onOpenChange={ setInserterOpen }> | ||
| <Dialog.Popup size="large"> |
There was a problem hiding this comment.
I'm not sure whether it's wp-build or how we are composing the UI layout.
I'll take a look since it affects the grid's UX as well. My hunch is that we are rendering the stage in an iFrame, as you highlighted when testing the Grid stories in the main doc page.
| border-block-end: 12px solid var(--wpds-color-fg-interactive-brand); | ||
| border-inline-start: 12px solid transparent; |
There was a problem hiding this comment.
Were these changes related/needed here? Just didn't see elaborated in PR description.
There was a problem hiding this comment.
Yes, forgot to mention it. The resize element isn't shown. I'll dive into it.
simison
left a comment
There was a problem hiding this comment.
Works as a starting point; we'll probably want to use view.groupBy or a sidebar to organise widgets by category or plugin later on.
Modal vs sidebar might be a good UX exploration later, too.
👍
I didn't consider this. Do we know if the new admin UI defines a space to fill with a sidebar? |
0f31ab8 to
178276f
Compare
There's a drawer component, and some pre-existing things around the editor + WP Build supports "inspector" sidebar.
I'd say let's merge this and explore alternatives too; it might be helpful to have something that doesn't obscure the view to the existing widgets on the dashboard as much and allows directly dragging to the right location upon insertion. But more spacious full screen modal also has its benefits. |
…ard-inserter # Conflicts: # routes/dashboard/stage.tsx # routes/dashboard/widget-dashboard/widget-dashboard.tsx






What?
Adds a modal-based widget inserter to the dashboard rendering engine.
The inserter is mounted automatically inside
WidgetDashboard; it stays hidden until the "Add widgets" button in<WidgetDashboard.Actions />is clicked.Selection results are converted to
DashboardWidgetinstances and appended tolayoutviaonLayoutChange.Part of #77616 #77626
Why?
The dashboard rendering engine had no way to add widget instances. The compound shipped editing toggles via
Actions, but the "Add widgets" trigger was a TODO that logged to the console.How?
Insertercomponent:Dialog.Root(controlled) withDialog.Popupcontaining the picker. Always mounted insideWidgetDashboard; rendered only while the UI context'sinserterOpenflag istrue.WidgetPickercomponent:DataViewsPickerwith apickerGridview, fields fortitle+ livepreview+ searchablename, and aSelectaction withsupportsBulk: true. Each preview live-renders the type'sexample.attributesthroughWidgetRender.WidgetDashboardUIProvidercontext: tracks transient UI state (inserterOpen,setInserterOpen) so any compound (today: the trigger inActions) can open or close the modal.<WidgetDashboard.Actions />now wires the "Add widgets" button tosetInserterOpen( true ).createDashboardWidget( widgetType )(defaulting attributes to the type'sexample.attributes) and appended to the layout.routes/dashboard/stage.tsx) starts with an empty layout +<WidgetDashboard.NoWidgetsState />so the inserter flow is exercised on first load.Testing
npm start, open the Dashboard.Customize, thenAdd widgets.Select. The widget appears on the dashboard, the modal closes.Select. All selected widgets are appended in a singleonLayoutChange.Esc(or click the close icon) to dismiss without selecting; layout is unchanged.npm run test:unit -- routes/dashboard/widget-dashboard/testruns green (20 tests; 5 are new for the inserter).Screen.Recording.2026-05-06.at.1.18.34.PM.mov