DataViews: Migrate modals from @wordpress/components Modal to @wordpress/ui Dialog#76837
Draft
DataViews: Migrate modals from @wordpress/components Modal to @wordpress/ui Dialog#76837
Conversation
…ess/ui Dialog Replace all usages of `@wordpress/components` `Modal` in `@wordpress/dataviews` with `@wordpress/ui` `Dialog` compound components. Key changes: - Migrate `ActionModal` to use `Dialog.Root`, `Dialog.Popup`, `Dialog.Header`, `Dialog.Title`, `Dialog.CloseIcon`, and `VisuallyHidden` for hidden headers. - Migrate `ModalContent` (DataForm panel) to use Dialog with `Dialog.Footer` for Cancel/Apply buttons. - Expose `initialFocus` and `finalFocus` props on `@wordpress/ui` `Dialog.Popup`. - Add `event.stopPropagation()` to Escape key handler in `@wordpress/compose` `useDialog` to prevent bubbling to parent Base UI overlays. - Set `--wp-ui-dialog-z-index` via SCSS `z-index()` function for backwards compatibility with existing overlay z-index hierarchy. - Add `'stretch'` and `'full'` to `modalSize` type; deprecate `'fill'`. - Add `modalSize: 'small'` to duplicate-template-part and duplicate-pattern actions, replacing CSS-based width overrides. - Remove CSS overrides targeting `.components-modal__frame` and `[role="document"]` in `@wordpress/edit-site`. - Remove `.dataforms-layouts-panel__modal-footer` margin-top rule. - Update `WithModal` story to use Dialog. Made-with: Cursor
50a77c2 to
a8b8a61
Compare
|
Size Change: +181 kB (+2.36%) Total Size: 7.87 MB
ℹ️ View Unchanged
|
|
Flaky tests detected in a8b8a61. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/23601513716
|
This was referenced Mar 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Dependencies
Requires
stopPropagation()to Escape handler #76861What?
Migrate all usages of
@wordpress/componentsModalin the@wordpress/dataviewspackage to@wordpress/uiDialogcompound components.See #76487 for the original assessment.
Why?
The
@wordpress/uiDialogcomponent is the recommended replacement for@wordpress/componentsModal. Migrating@wordpress/dataviewsincrementally validates the newDialogAPI in a real-world consumer and moves the ecosystem towards the new design system.How?
Core migrations
ActionModal(dataviews-item-actions/index.tsx): Replaced<Modal>with<Dialog.Root>+<Dialog.Popup>+<Dialog.Header>/<Dialog.Title>/<Dialog.CloseIcon>. WhenhideModalHeaderis set, the title is wrapped in<VisuallyHidden>for accessibility.ModalContent(dataform-layouts/panel/modal.tsx): Replaced<Modal>with Dialog compound components. The footer now uses<Dialog.Footer>instead of a custom<Stack>with<Spacer>.Focus management
The old
Modalcomponent'sfocusOnMountprop is mapped to Base UI'sinitialFocusprop onDialog.Popup:focusOnMountvalueinitialFocusmappingtrue(default) /'firstElement'true— Base UI default (first tabbable element in popup)falsefalse— no focus movement'firstContentElement'contentRef) for the first tabbable element, skipping the dialog header'firstInputElement'input/select/textarea, falling back to first tabbableThe content rendered by
<action.RenderModal>and the DataForm fields are wrapped in a<div ref={contentRef}>so the callbacks can scope their search to just the content below the header.For
ModalContent(panel modal), the previoususeFocusOnMount('firstInputElement')hook is replaced with aninitialFocuscallback that queries the content ref for the first input element, fully integrating with Base UI's focus management instead of using a hybrid approach.Supporting changes
@wordpress/uiDialog.Popup: ExposedinitialFocusandfinalFocusprops (forwarded from Base UI'sDialogPopup) for custom focus management.@wordpress/composeuseDialog: Addedevent.stopPropagation()to the Escape key handler to prevent legacy Popover escape events from bubbling up and dismissing parent Base UI dialogs..dataviews-action-modal { z-index }rule with:root { --wp-ui-dialog-z-index }using the existing SCSSz-index()function, maintaining backwards compatibility with the overlay hierarchy.modalSizetype: Added'stretch'and'full'values; deprecated'fill'(mapped to'stretch'at runtime with a console warning)..components-modal__framemax-width override for duplicate-template-part and[role="document"]width override for duplicate-pattern from@wordpress/edit-site. Replaced with declarativemodalSize: 'small'on the action definitions in@wordpress/fields..dataforms-layouts-panel__modal-footer { margin-top }rule, relying onDialog.Footerdefault spacing.WithModalstory indataviews-pickerto use Dialog instead of Modal, removing inline<style>targeting.components-modal__*classes.Files changed
@wordpress/uidialog/types.ts,dialog/popup.tsxinitialFocus/finalFocus@wordpress/composeuse-dialog/index.tsstopPropagation()on Escape@wordpress/dataviewsdataviews-item-actions/index.tsxActionModal@wordpress/dataviewsdataviews-item-actions/style.scss--wp-ui-dialog-z-index@wordpress/dataviewsdataform-layouts/panel/modal.tsxModalContent@wordpress/dataviewsdataform-layouts/panel/style.scss@wordpress/dataviewstypes/dataviews.tsmodalSizeunion@wordpress/dataviewsdataviews-picker/stories/index.story.tsx@wordpress/edit-sitepage-patterns/style.scss@wordpress/fieldsduplicate-template-part.tsx,duplicate-pattern.tsxmodalSize: 'small'Testing Instructions
smallsize).Testing Instructions for Keyboard
firstContentElementactions, focus should land on the first tabbable element in the content area, skipping the header).TODO / Follow-ups
ConfirmDialogcomponent to@wordpress/ui(wrapping Base UIAlertDialog) in a separate PR (UI: Add AlertDialog primitive #76847). Once available, updateActionModalto use it for actions withhideModalHeader(destructive confirmations) to get properAlertDialogsemantics (no outside-click/Escape dismiss).routes/post-list/quick-edit-modal.tsx) to aDrawercomponent in a separate PR.@base-ui/reactare present (e.g., a plugin ships its own copy), nested overlay stacking may break due to separatePortalContextinstances. This is a known cross-bundle limitation to monitor.Use of AI Tools
Cursor + Claude Opus 4.6