From 00ef7ba101f7c1a0ca649c60df57249bde570991 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 6 Oct 2025 14:32:14 +0100 Subject: [PATCH 1/2] Extract Page and NavigableRegion components to an admin-ui package --- docs/manifest.json | 6 + docs/private-apis.md | 1 - package-lock.json | 22 +++ packages/admin-ui/CHANGELOG.md | 3 + packages/admin-ui/README.md | 33 +++++ packages/admin-ui/package.json | 39 ++++++ packages/admin-ui/src/index.ts | 2 + .../src/navigable-region/index.tsx} | 21 ++- packages/admin-ui/src/page/header.tsx | 52 +++++++ packages/admin-ui/src/page/index.tsx | 55 ++++++++ packages/admin-ui/src/page/style.scss | 43 ++++++ packages/admin-ui/src/style.scss | 1 + packages/admin-ui/tsconfig.json | 5 + packages/base-styles/_z-index.scss | 2 - .../lib/util.js | 1 + packages/edit-post/package.json | 1 + .../edit-post/src/components/layout/index.js | 3 +- packages/edit-post/src/style.scss | 1 + packages/edit-site/package.json | 1 + .../edit-site/src/components/layout/index.js | 3 +- .../src/components/page-patterns/actions.js | 54 ++++++++ .../src/components/page-patterns/header.js | 128 ------------------ .../src/components/page-patterns/index.js | 71 ++++++++-- .../src/components/page-templates/index.js | 3 +- .../edit-site/src/components/page/header.js | 44 ------ .../edit-site/src/components/page/index.js | 43 ------ .../edit-site/src/components/page/style.scss | 56 -------- .../src/components/post-edit/index.js | 2 +- .../src/components/post-edit/style.scss | 2 +- .../src/components/post-list/index.js | 3 +- .../src/components/save-panel/index.js | 4 +- .../sidebar-global-styles-wrapper/index.js | 38 +++--- .../sidebar-global-styles-wrapper/style.scss | 12 +- packages/edit-site/src/posts.scss | 2 +- packages/edit-site/src/style.scss | 2 +- packages/edit-site/tsconfig.json | 1 + packages/interface/package.json | 1 + packages/interface/src/components/index.js | 1 - .../components/interface-skeleton/index.js | 6 +- .../src/components/navigable-region/README.md | 36 ----- packages/interface/src/style.scss | 1 + tools/webpack/packages.js | 1 + tsconfig.json | 1 + 43 files changed, 431 insertions(+), 376 deletions(-) create mode 100644 packages/admin-ui/CHANGELOG.md create mode 100644 packages/admin-ui/README.md create mode 100644 packages/admin-ui/package.json create mode 100644 packages/admin-ui/src/index.ts rename packages/{interface/src/components/navigable-region/index.js => admin-ui/src/navigable-region/index.tsx} (52%) create mode 100644 packages/admin-ui/src/page/header.tsx create mode 100644 packages/admin-ui/src/page/index.tsx create mode 100644 packages/admin-ui/src/page/style.scss create mode 100644 packages/admin-ui/src/style.scss create mode 100644 packages/admin-ui/tsconfig.json create mode 100644 packages/edit-site/src/components/page-patterns/actions.js delete mode 100644 packages/edit-site/src/components/page-patterns/header.js delete mode 100644 packages/edit-site/src/components/page/header.js delete mode 100644 packages/edit-site/src/components/page/index.js delete mode 100644 packages/edit-site/src/components/page/style.scss delete mode 100644 packages/interface/src/components/navigable-region/README.md diff --git a/docs/manifest.json b/docs/manifest.json index 6ced1abb1f7109..13edeced421af8 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -1427,6 +1427,12 @@ "markdown_source": "../packages/a11y/README.md", "parent": "packages" }, + { + "title": "@wordpress/admin-ui", + "slug": "packages-admin-ui", + "markdown_source": "../packages/admin-ui/README.md", + "parent": "packages" + }, { "title": "@wordpress/annotations", "slug": "packages-annotations", diff --git a/docs/private-apis.md b/docs/private-apis.md index d8610405dbaf69..31699f64da7f83 100644 --- a/docs/private-apis.md +++ b/docs/private-apis.md @@ -293,7 +293,6 @@ Private exports: - `ComplementaryAreaMoreMenuItem` - `FullscreenMode` - `InterfaceSkeleton` -- `NavigableRegion` - `PinnedItems` ### `core/editor` store diff --git a/package-lock.json b/package-lock.json index 3beb1679fb2262..b87391d0b71a19 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15755,6 +15755,10 @@ "resolved": "packages/a11y", "link": true }, + "node_modules/@wordpress/admin-ui": { + "resolved": "packages/admin-ui", + "link": true + }, "node_modules/@wordpress/annotations": { "resolved": "packages/annotations", "link": true @@ -48780,6 +48784,21 @@ "npm": ">=8.19.2" } }, + "packages/admin-ui": { + "name": "@wordpress/admin-ui", + "version": "1.0.0", + "license": "GPL-2.0-or-later", + "dependencies": { + "@babel/runtime": "7.25.7", + "@wordpress/components": "file:../components", + "@wordpress/element": "file:../element", + "clsx": "^2.1.1" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, "packages/annotations": { "name": "@wordpress/annotations", "version": "3.32.0", @@ -50607,6 +50626,7 @@ "dependencies": { "@babel/runtime": "7.25.7", "@wordpress/a11y": "file:../a11y", + "@wordpress/admin-ui": "file:../admin-ui", "@wordpress/api-fetch": "file:../api-fetch", "@wordpress/block-editor": "file:../block-editor", "@wordpress/block-library": "file:../block-library", @@ -50654,6 +50674,7 @@ "@babel/runtime": "7.25.7", "@react-spring/web": "^9.4.5", "@wordpress/a11y": "file:../a11y", + "@wordpress/admin-ui": "file:../admin-ui", "@wordpress/api-fetch": "file:../api-fetch", "@wordpress/blob": "file:../blob", "@wordpress/block-editor": "file:../block-editor", @@ -51102,6 +51123,7 @@ "dependencies": { "@babel/runtime": "7.25.7", "@wordpress/a11y": "file:../a11y", + "@wordpress/admin-ui": "file:../admin-ui", "@wordpress/components": "file:../components", "@wordpress/compose": "file:../compose", "@wordpress/data": "file:../data", diff --git a/packages/admin-ui/CHANGELOG.md b/packages/admin-ui/CHANGELOG.md new file mode 100644 index 00000000000000..6ed52df1077824 --- /dev/null +++ b/packages/admin-ui/CHANGELOG.md @@ -0,0 +1,3 @@ + + +## Unreleased diff --git a/packages/admin-ui/README.md b/packages/admin-ui/README.md new file mode 100644 index 00000000000000..8bac974786a86a --- /dev/null +++ b/packages/admin-ui/README.md @@ -0,0 +1,33 @@ +# Admin UI + +Generic components to be used to build the Admin UI. + +## Installation + +Install the module + +```bash +npm install @wordpress/admin-ui --save +``` + +## API + + + +### NavigableRegion + +Undocumented declaration. + +### Page + +Undocumented declaration. + + + +## Contributing to this package + +This is an individual package that's part of the Gutenberg project. The project is organized as a monorepo. It's made up of multiple self-contained software packages, each with a specific purpose. The packages in this monorepo are published to [npm](https://www.npmjs.com/) and used by [WordPress](https://make.wordpress.org/core/) as well as other software projects. + +To find out more about contributing to this package or Gutenberg as a whole, please read the project's main [contributor guide](https://github.com/WordPress/gutenberg/tree/HEAD/CONTRIBUTING.md). + +

Code is Poetry.

diff --git a/packages/admin-ui/package.json b/packages/admin-ui/package.json new file mode 100644 index 00000000000000..efd98a94ba8482 --- /dev/null +++ b/packages/admin-ui/package.json @@ -0,0 +1,39 @@ +{ + "name": "@wordpress/admin-ui", + "version": "1.0.0", + "description": "Generic components to be used in the Admin UI.", + "author": "The WordPress Contributors", + "license": "GPL-2.0-or-later", + "keywords": [ + "wordpress", + "admin", + "ui" + ], + "homepage": "https://github.com/WordPress/gutenberg/tree/HEAD/packages/admin-ui/README.md", + "repository": { + "type": "git", + "url": "https://github.com/WordPress/gutenberg.git", + "directory": "packages/admin-ui" + }, + "bugs": { + "url": "https://github.com/WordPress/gutenberg/issues" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "main": "build/index.js", + "module": "build-module/index.js", + "react-native": "src/index", + "types": "build-types", + "sideEffects": false, + "dependencies": { + "@babel/runtime": "7.25.7", + "@wordpress/components": "file:../components", + "@wordpress/element": "file:../element", + "clsx": "^2.1.1" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/admin-ui/src/index.ts b/packages/admin-ui/src/index.ts new file mode 100644 index 00000000000000..1f44d5a1548830 --- /dev/null +++ b/packages/admin-ui/src/index.ts @@ -0,0 +1,2 @@ +export { default as NavigableRegion } from './navigable-region'; +export { default as Page } from './page'; diff --git a/packages/interface/src/components/navigable-region/index.js b/packages/admin-ui/src/navigable-region/index.tsx similarity index 52% rename from packages/interface/src/components/navigable-region/index.js rename to packages/admin-ui/src/navigable-region/index.tsx index 50b98d49070d43..b6aff02a36ee57 100644 --- a/packages/interface/src/components/navigable-region/index.js +++ b/packages/admin-ui/src/navigable-region/index.tsx @@ -1,19 +1,31 @@ +/** + * External dependencies + */ +import clsx from 'clsx'; + /** * WordPress dependencies */ import { forwardRef } from '@wordpress/element'; /** - * External dependencies + * Type definitions */ -import clsx from 'clsx'; +type NavigableRegionProps = { + children: React.ReactNode; + className?: string; + ariaLabel: string; + as?: React.ElementType; + [ key: string ]: any; +}; -const NavigableRegion = forwardRef( +// This is a copy of the private `NavigableRegion` component from the '@wordpress/editor' private APIs. +const NavigableRegion = forwardRef< HTMLElement, NavigableRegionProps >( ( { children, className, ariaLabel, as: Tag = 'div', ...props }, ref ) => { return ( + + + { title && ( + + { title } + + ) } + { breadcrumbs } + { badges } + + + { actions } + + + { subTitle && ( +

{ subTitle }

+ ) } + + ); +} diff --git a/packages/admin-ui/src/page/index.tsx b/packages/admin-ui/src/page/index.tsx new file mode 100644 index 00000000000000..44806a769e9466 --- /dev/null +++ b/packages/admin-ui/src/page/index.tsx @@ -0,0 +1,55 @@ +/** + * External dependencies + */ +import clsx from 'clsx'; + +/** + * Internal dependencies + */ +import Header from './header'; +import NavigableRegion from '../navigable-region'; + +function Page( { + breadcrumbs, + badges, + title, + subTitle, + children, + className, + actions, + hasPadding = true, +}: { + breadcrumbs?: React.ReactNode; + badges?: React.ReactNode; + title?: React.ReactNode; + subTitle?: React.ReactNode; + children: React.ReactNode; + className?: string; + actions?: React.ReactNode; + hasPadding?: boolean; +} ) { + const classes = clsx( 'admin-ui-page', className ); + + return ( + + { ( title || breadcrumbs || badges ) && ( +
+ ) } +
+ { children } +
+ + ); +} + +export default Page; diff --git a/packages/admin-ui/src/page/style.scss b/packages/admin-ui/src/page/style.scss new file mode 100644 index 00000000000000..aaff6fe6842d6d --- /dev/null +++ b/packages/admin-ui/src/page/style.scss @@ -0,0 +1,43 @@ +.admin-ui-page { + height: 100%; + background: $white; + color: $gray-800; + container: admin-ui-page / inline-size; + + @media not (prefers-reduced-motion) { + transition: width ease-out 0.2s; + } +} + +.admin-ui-page__header { + padding: $grid-unit-20 $grid-unit-60; + border-bottom: 1px solid $gray-100; + background: $white; + position: sticky; + top: 0; + + @container (max-width: 430px) { + padding: $grid-unit-20 $grid-unit-30; + } +} + +.admin-ui-page__header-subtitle { + padding-block-end: $grid-unit-10; + color: $gray-700; + @include body-medium(); + margin: 0; +} + +.admin-ui-page__content { + flex-grow: 1; + overflow: auto; + display: flex; + flex-direction: column; + + &.has-padding { + padding: $grid-unit-20 $grid-unit * 2.5; + @container (max-width: 430px) { + padding: $grid-unit-20 $grid-unit-30; + } + } +} diff --git a/packages/admin-ui/src/style.scss b/packages/admin-ui/src/style.scss new file mode 100644 index 00000000000000..77ea351a30f7eb --- /dev/null +++ b/packages/admin-ui/src/style.scss @@ -0,0 +1 @@ +@import "./page/style.scss"; diff --git a/packages/admin-ui/tsconfig.json b/packages/admin-ui/tsconfig.json new file mode 100644 index 00000000000000..a2d5f9b4fceb21 --- /dev/null +++ b/packages/admin-ui/tsconfig.json @@ -0,0 +1,5 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig.json", + "extends": "../../tsconfig.base.json", + "references": [ { "path": "../components" }, { "path": "../element" } ] +} diff --git a/packages/base-styles/_z-index.scss b/packages/base-styles/_z-index.scss index 28f6f1465e6322..d06f7b5b5a1ff0 100644 --- a/packages/base-styles/_z-index.scss +++ b/packages/base-styles/_z-index.scss @@ -192,8 +192,6 @@ $z-layers: ( ".customize-widgets__block-toolbar": 7, // Site editor layout - ".edit-site-page-header": 2, - ".edit-site-page-content": 1, ".edit-site-templates__dataviews-list-pagination": 2, ".edit-site-layout__canvas-container": 2, ".edit-site-layout__sidebar": 1, diff --git a/packages/dependency-extraction-webpack-plugin/lib/util.js b/packages/dependency-extraction-webpack-plugin/lib/util.js index f04bbbded3bcf0..37385bd76d4890 100644 --- a/packages/dependency-extraction-webpack-plugin/lib/util.js +++ b/packages/dependency-extraction-webpack-plugin/lib/util.js @@ -4,6 +4,7 @@ const WORDPRESS_NAMESPACE = '@wordpress/'; // This list must be kept in sync with the same list in tools/webpack/packages.js // !! const BUNDLED_PACKAGES = [ + '@wordpress/admin-ui', '@wordpress/dataviews', '@wordpress/dataviews/wp', '@wordpress/icons', diff --git a/packages/edit-post/package.json b/packages/edit-post/package.json index 218495a39aa1f0..811902962e21fd 100644 --- a/packages/edit-post/package.json +++ b/packages/edit-post/package.json @@ -30,6 +30,7 @@ "dependencies": { "@babel/runtime": "7.25.7", "@wordpress/a11y": "file:../a11y", + "@wordpress/admin-ui": "file:../admin-ui", "@wordpress/api-fetch": "file:../api-fetch", "@wordpress/block-editor": "file:../block-editor", "@wordpress/block-library": "file:../block-library", diff --git a/packages/edit-post/src/components/layout/index.js b/packages/edit-post/src/components/layout/index.js index 748246b2f432f6..2944386f827fad 100644 --- a/packages/edit-post/src/components/layout/index.js +++ b/packages/edit-post/src/components/layout/index.js @@ -6,6 +6,7 @@ import clsx from 'clsx'; /** * WordPress dependencies */ +import { NavigableRegion } from '@wordpress/admin-ui'; import { AutosaveMonitor, LocalAutosaveMonitor, @@ -76,7 +77,7 @@ import { useMetaBoxInitialization } from '../meta-boxes/use-meta-box-initializat const { getLayoutStyles } = unlock( blockEditorPrivateApis ); const { useCommandContext } = unlock( commandsPrivateApis ); -const { Editor, FullscreenMode, NavigableRegion } = unlock( editorPrivateApis ); +const { Editor, FullscreenMode } = unlock( editorPrivateApis ); const { BlockKeyboardShortcuts } = unlock( blockLibraryPrivateApis ); const DESIGN_POST_TYPES = [ 'wp_template', diff --git a/packages/edit-post/src/style.scss b/packages/edit-post/src/style.scss index bd8c97de9fc558..85f081062dcb16 100644 --- a/packages/edit-post/src/style.scss +++ b/packages/edit-post/src/style.scss @@ -1,3 +1,4 @@ +@import "../../admin-ui/src/style.scss"; @import "./components/back-button/style.scss"; @import "./components/layout/style.scss"; @import "./components/meta-boxes/meta-boxes-area/style.scss"; diff --git a/packages/edit-site/package.json b/packages/edit-site/package.json index 6ba1fc0241f469..1a30716b3c4954 100644 --- a/packages/edit-site/package.json +++ b/packages/edit-site/package.json @@ -31,6 +31,7 @@ "@babel/runtime": "7.25.7", "@react-spring/web": "^9.4.5", "@wordpress/a11y": "file:../a11y", + "@wordpress/admin-ui": "file:../admin-ui", "@wordpress/api-fetch": "file:../api-fetch", "@wordpress/blob": "file:../blob", "@wordpress/block-editor": "file:../block-editor", diff --git a/packages/edit-site/src/components/layout/index.js b/packages/edit-site/src/components/layout/index.js index 1959bfadeecf4f..6acb5a2dfddf48 100644 --- a/packages/edit-site/src/components/layout/index.js +++ b/packages/edit-site/src/components/layout/index.js @@ -6,6 +6,7 @@ import clsx from 'clsx'; /** * WordPress dependencies */ +import { NavigableRegion } from '@wordpress/admin-ui'; import { __unstableMotion as motion, __unstableAnimatePresence as AnimatePresence, @@ -47,7 +48,7 @@ import SaveHub from '../save-hub'; import SavePanel from '../save-panel'; const { useGlobalStyle } = unlock( blockEditorPrivateApis ); -const { NavigableRegion, GlobalStylesProvider } = unlock( editorPrivateApis ); +const { GlobalStylesProvider } = unlock( editorPrivateApis ); const { useLocation } = unlock( routerPrivateApis ); const ANIMATION_DURATION = 0.3; diff --git a/packages/edit-site/src/components/page-patterns/actions.js b/packages/edit-site/src/components/page-patterns/actions.js new file mode 100644 index 00000000000000..bc167ead776c86 --- /dev/null +++ b/packages/edit-site/src/components/page-patterns/actions.js @@ -0,0 +1,54 @@ +/** + * WordPress dependencies + */ +import { DropdownMenu, MenuGroup } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; +import { moreVertical } from '@wordpress/icons'; + +/** + * Internal dependencies + */ +import AddNewPattern from '../add-new-pattern'; +import RenameCategoryMenuItem from './rename-category-menu-item'; +import DeleteCategoryMenuItem from './delete-category-menu-item'; +import usePatternCategories from '../sidebar-navigation-screen-patterns/use-pattern-categories'; +import { PATTERN_TYPES } from '../../utils/constants'; + +export default function PatternsActions( { categoryId, type } ) { + const { patternCategories } = usePatternCategories(); + let patternCategory; + if ( type === PATTERN_TYPES.user && !! categoryId ) { + patternCategory = patternCategories.find( + ( category ) => category.name === categoryId + ); + } + + return ( + <> + + { !! patternCategory?.id && ( + + { ( { onClose } ) => ( + + + + + ) } + + ) } + + ); +} diff --git a/packages/edit-site/src/components/page-patterns/header.js b/packages/edit-site/src/components/page-patterns/header.js deleted file mode 100644 index 17848d8a6c24bf..00000000000000 --- a/packages/edit-site/src/components/page-patterns/header.js +++ /dev/null @@ -1,128 +0,0 @@ -/** - * WordPress dependencies - */ -import { - DropdownMenu, - MenuGroup, - __experimentalHStack as HStack, - __experimentalHeading as Heading, - __experimentalText as Text, - __experimentalVStack as VStack, - Button, -} from '@wordpress/components'; -import { store as coreStore } from '@wordpress/core-data'; -import { useSelect } from '@wordpress/data'; -import { __, sprintf } from '@wordpress/i18n'; -import { moreVertical } from '@wordpress/icons'; - -/** - * Internal dependencies - */ -import AddNewPattern from '../add-new-pattern'; -import RenameCategoryMenuItem from './rename-category-menu-item'; -import DeleteCategoryMenuItem from './delete-category-menu-item'; -import usePatternCategories from '../sidebar-navigation-screen-patterns/use-pattern-categories'; -import { TEMPLATE_PART_POST_TYPE, PATTERN_TYPES } from '../../utils/constants'; - -export default function PatternsHeader( { - categoryId, - type, - titleId, - descriptionId, - isModifiedView = false, - resetView = () => {}, -} ) { - const { patternCategories } = usePatternCategories(); - const templatePartAreas = useSelect( - ( select ) => - select( coreStore ).getCurrentTheme() - ?.default_template_part_areas || [], - [] - ); - - let title, description, patternCategory; - if ( type === TEMPLATE_PART_POST_TYPE ) { - const templatePartArea = templatePartAreas.find( - ( area ) => area.area === categoryId - ); - title = templatePartArea?.label || __( 'All Template Parts' ); - description = - templatePartArea?.description || - __( 'Includes every template part defined for any area.' ); - } else if ( type === PATTERN_TYPES.user && !! categoryId ) { - patternCategory = patternCategories.find( - ( category ) => category.name === categoryId - ); - title = patternCategory?.label; - description = patternCategory?.description; - } - - if ( ! title ) { - return null; - } - - return ( - - - - { title } - - - { isModifiedView && ( - - ) } - - { !! patternCategory?.id && ( - - { ( { onClose } ) => ( - - - - - ) } - - ) } - - - { description ? ( - - { description } - - ) : null } - - ); -} diff --git a/packages/edit-site/src/components/page-patterns/index.js b/packages/edit-site/src/components/page-patterns/index.js index 8c3c3c62e7ae76..a644ec950f2c5d 100644 --- a/packages/edit-site/src/components/page-patterns/index.js +++ b/packages/edit-site/src/components/page-patterns/index.js @@ -1,19 +1,20 @@ /** * WordPress dependencies */ +import { Page } from '@wordpress/admin-ui'; import { __ } from '@wordpress/i18n'; -import { useMemo, useId } from '@wordpress/element'; +import { useMemo } from '@wordpress/element'; import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor'; import { DataViews, filterSortAndPaginate } from '@wordpress/dataviews'; -import { useEntityRecords } from '@wordpress/core-data'; +import { useEntityRecords, store as coreStore } from '@wordpress/core-data'; import { privateApis as editorPrivateApis } from '@wordpress/editor'; import { privateApis as routerPrivateApis } from '@wordpress/router'; import { useView } from '@wordpress/views'; +import { useSelect } from '@wordpress/data'; /** * Internal dependencies */ -import Page from '../page'; import { LAYOUT_GRID, LAYOUT_TABLE, @@ -24,7 +25,7 @@ import { import usePatternSettings from './use-pattern-settings'; import { unlock } from '../../lock-unlock'; import usePatterns, { useAugmentPatternsWithPermissions } from './use-patterns'; -import PatternsHeader from './header'; +import PatternsActions from './actions'; import { useEditPostAction } from '../dataviews-actions'; import { patternStatusField, @@ -32,6 +33,8 @@ import { templatePartAuthorField, } from './fields'; import { addQueryArgs } from '@wordpress/url'; +import usePatternCategories from '../sidebar-navigation-screen-patterns/use-pattern-categories'; +import { Button } from '@wordpress/components'; const { ExperimentalBlockEditorProvider } = unlock( blockEditorPrivateApis ); const { usePostActions, patternTitleField } = unlock( editorPrivateApis ); @@ -64,6 +67,34 @@ const DEFAULT_VIEW = { ...defaultLayouts[ LAYOUT_GRID ], }; +function usePagePatternsHeader( type, categoryId ) { + const { patternCategories } = usePatternCategories(); + const templatePartAreas = useSelect( + ( select ) => + select( coreStore ).getCurrentTheme() + ?.default_template_part_areas || [], + [] + ); + let title, description, patternCategory; + if ( type === TEMPLATE_PART_POST_TYPE ) { + const templatePartArea = templatePartAreas.find( + ( area ) => area.area === categoryId + ); + title = templatePartArea?.label || __( 'All Template Parts' ); + description = + templatePartArea?.description || + __( 'Includes every template part defined for any area.' ); + } else if ( type === PATTERN_TYPES.user && !! categoryId ) { + patternCategory = patternCategories.find( + ( category ) => category.name === categoryId + ); + title = patternCategory?.label; + description = patternCategory?.description; + } + + return { title, description }; +} + export default function DataviewsPatterns() { const { path, query } = useLocation(); const { postType = 'wp_block', categoryId: categoryIdFromURL } = query; @@ -158,26 +189,36 @@ export default function DataviewsPatterns() { } return [ editAction, ...patternActions ].filter( Boolean ); }, [ editAction, postType, templatePartActions, patternActions ] ); - const id = useId(); const settings = usePatternSettings(); + const { title, description } = usePagePatternsHeader( + postType, + categoryId + ); + // Wrap everything in a block editor provider. // This ensures 'styles' that are needed for the previews are synced // from the site editor store to the block editor store. return ( + { isModified && ( + + ) } + + + } + hasPadding={ false } > - } + hasPadding={ false } > - - - { title } - - - { actions } - - - { subTitle && ( - - { subTitle } - - ) } - - ); -} diff --git a/packages/edit-site/src/components/page/index.js b/packages/edit-site/src/components/page/index.js deleted file mode 100644 index 6609abb8f52449..00000000000000 --- a/packages/edit-site/src/components/page/index.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * External dependencies - */ -import clsx from 'clsx'; - -/** - * WordPress dependencies - */ -import { privateApis as editorPrivateApis } from '@wordpress/editor'; - -/** - * Internal dependencies - */ -import Header from './header'; -import { unlock } from '../../lock-unlock'; - -const { NavigableRegion } = unlock( editorPrivateApis ); - -export default function Page( { - title, - subTitle, - actions, - children, - className, - hideTitleFromUI = false, -} ) { - const classes = clsx( 'edit-site-page', className ); - - return ( - -
- { ! hideTitleFromUI && title && ( -
- ) } - { children } -
-
- ); -} diff --git a/packages/edit-site/src/components/page/style.scss b/packages/edit-site/src/components/page/style.scss deleted file mode 100644 index f2ffbff5067fab..00000000000000 --- a/packages/edit-site/src/components/page/style.scss +++ /dev/null @@ -1,56 +0,0 @@ -.edit-site-page { - color: $gray-800; - background: $white; - height: 100%; - /* stylelint-disable-next-line property-no-unknown -- '@container' not globally permitted */ - container: edit-site-page / inline-size; - - @media not (prefers-reduced-motion) { - transition: width ease-out 0.2s; - } -} - -.edit-site-page-header { - padding: $grid-unit-20 $grid-unit-60; - border-bottom: 1px solid $gray-100; - background: $white; - position: sticky; - top: 0; - z-index: z-index(".edit-site-page-header"); - - @media not (prefers-reduced-motion) { - transition: padding ease-out 0.1s; - } - - .components-heading { - color: $gray-900; - } - - .edit-site-page-header__page-title { - min-height: $grid-unit-50; - - .components-heading { - flex-grow: 1; - flex-basis: 0; - white-space: nowrap; - } - } - - .edit-site-page-header__sub-title { - margin-bottom: $grid-unit-10; - } -} - -@container (max-width: 430px) { - .edit-site-page-header { - padding: $grid-unit-20 $grid-unit-30; - } -} - -.edit-site-page-content { - height: 100%; - display: flex; - flex-flow: column; - position: relative; - z-index: z-index(".edit-site-page-content"); -} diff --git a/packages/edit-site/src/components/post-edit/index.js b/packages/edit-site/src/components/post-edit/index.js index d956e83eb7118e..bd34a925a32772 100644 --- a/packages/edit-site/src/components/post-edit/index.js +++ b/packages/edit-site/src/components/post-edit/index.js @@ -6,6 +6,7 @@ import clsx from 'clsx'; /** * WordPress dependencies */ +import { Page } from '@wordpress/admin-ui'; import { __ } from '@wordpress/i18n'; import { DataForm } from '@wordpress/dataviews'; import { useDispatch, useSelect } from '@wordpress/data'; @@ -17,7 +18,6 @@ import { privateApis as editorPrivateApis } from '@wordpress/editor'; /** * Internal dependencies */ -import Page from '../page'; import { unlock } from '../../lock-unlock'; import usePatternSettings from '../page-patterns/use-pattern-settings'; import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor'; diff --git a/packages/edit-site/src/components/post-edit/style.scss b/packages/edit-site/src/components/post-edit/style.scss index 5688d83df00c5f..ce4f75f3a08b18 100644 --- a/packages/edit-site/src/components/post-edit/style.scss +++ b/packages/edit-site/src/components/post-edit/style.scss @@ -1,7 +1,7 @@ .edit-site-post-edit { padding: $grid-unit-30; - &.is-empty .edit-site-page-content { + &.is-empty .admin-ui-page__content { display: flex; align-items: center; justify-content: center; diff --git a/packages/edit-site/src/components/post-list/index.js b/packages/edit-site/src/components/post-list/index.js index e19d4d88f3056e..09e9cf0cb6badd 100644 --- a/packages/edit-site/src/components/post-list/index.js +++ b/packages/edit-site/src/components/post-list/index.js @@ -1,6 +1,7 @@ /** * WordPress dependencies */ +import { Page } from '@wordpress/admin-ui'; import { Button } from '@wordpress/components'; import { store as coreStore, @@ -19,7 +20,6 @@ import { addQueryArgs } from '@wordpress/url'; /** * Internal dependencies */ -import Page from '../page'; import { useDefaultViews, defaultLayouts, @@ -295,6 +295,7 @@ export default function PostList( { postType } ) { ) } + hasPadding={ false } > - - ) : null - } - className="edit-site-styles" - title={ __( 'Styles' ) } - > - - - + + ) : null + } + className="edit-site-styles" + title={ __( 'Styles' ) } + hasPadding={ false } + > + + ); } diff --git a/packages/edit-site/src/components/sidebar-global-styles-wrapper/style.scss b/packages/edit-site/src/components/sidebar-global-styles-wrapper/style.scss index 0fa4e158fe7f10..908fecba0c57f5 100644 --- a/packages/edit-site/src/components/sidebar-global-styles-wrapper/style.scss +++ b/packages/edit-site/src/components/sidebar-global-styles-wrapper/style.scss @@ -1,4 +1,4 @@ -.edit-site-styles .edit-site-page-content { +.edit-site-styles .admin-ui-page__content { .edit-site-global-styles-screen-root { box-shadow: none; & > div > hr { @@ -21,21 +21,13 @@ outline: none; } } - .edit-site-page-header { - padding-left: $grid-unit-60; - padding-right: $grid-unit-60; - @container (max-width: 430px) { - padding-left: $grid-unit-30; - padding-right: $grid-unit-30; - } - } .edit-site-sidebar-button { color: $gray-900; } } .show-icon-labels { - .edit-site-styles .edit-site-page-content { + .edit-site-styles .admin-ui-page__content { .edit-site-page-header__actions { .components-button.has-icon { width: auto; diff --git a/packages/edit-site/src/posts.scss b/packages/edit-site/src/posts.scss index ec04c9cddf25b8..df8d765aaea50c 100644 --- a/packages/edit-site/src/posts.scss +++ b/packages/edit-site/src/posts.scss @@ -1,6 +1,6 @@ +@import "../../admin-ui/src/style.scss"; @import "../../dataviews/src/style.scss"; @import "./components/layout/style.scss"; -@import "./components/page/style.scss"; @import "./components/save-hub/style.scss"; @import "./components/save-panel/style.scss"; @import "./components/sidebar/style.scss"; diff --git a/packages/edit-site/src/style.scss b/packages/edit-site/src/style.scss index 9f98c2c172e091..f1cbfb6064ec3c 100644 --- a/packages/edit-site/src/style.scss +++ b/packages/edit-site/src/style.scss @@ -1,3 +1,4 @@ +@import "../../admin-ui/src/style.scss"; @import "../../dataviews/src/style.scss"; @import "../../fields/src/style.scss"; @import "./components/add-new-template/style.scss"; @@ -6,7 +7,6 @@ @import "./components/global-styles/style.scss"; @import "./components/global-styles/screen-revisions/style.scss"; @import "./components/global-styles-sidebar/style.scss"; -@import "./components/page/style.scss"; @import "./components/page-patterns/style.scss"; @import "./components/page-templates/style.scss"; @import "./components/editor/style.scss"; diff --git a/packages/edit-site/tsconfig.json b/packages/edit-site/tsconfig.json index d4861201588503..d88842449f1de1 100644 --- a/packages/edit-site/tsconfig.json +++ b/packages/edit-site/tsconfig.json @@ -3,6 +3,7 @@ "extends": "../../tsconfig.base.json", "references": [ { "path": "../a11y" }, + { "path": "../admin-ui" }, { "path": "../api-fetch" }, { "path": "../autop" }, { "path": "../blob" }, diff --git a/packages/interface/package.json b/packages/interface/package.json index b1d0e8bbc02ad1..ba2cc22d84ec18 100644 --- a/packages/interface/package.json +++ b/packages/interface/package.json @@ -35,6 +35,7 @@ "dependencies": { "@babel/runtime": "7.25.7", "@wordpress/a11y": "file:../a11y", + "@wordpress/admin-ui": "file:../admin-ui", "@wordpress/components": "file:../components", "@wordpress/compose": "file:../compose", "@wordpress/data": "file:../data", diff --git a/packages/interface/src/components/index.js b/packages/interface/src/components/index.js index a96d3304db7c5a..971b42522ae3c4 100644 --- a/packages/interface/src/components/index.js +++ b/packages/interface/src/components/index.js @@ -4,4 +4,3 @@ export { default as FullscreenMode } from './fullscreen-mode'; export { default as InterfaceSkeleton } from './interface-skeleton'; export { default as PinnedItems } from './pinned-items'; export { default as ActionItem } from './action-item'; -export { default as NavigableRegion } from './navigable-region'; diff --git a/packages/interface/src/components/interface-skeleton/index.js b/packages/interface/src/components/interface-skeleton/index.js index 2417cc909d1698..296bad324866c0 100644 --- a/packages/interface/src/components/interface-skeleton/index.js +++ b/packages/interface/src/components/interface-skeleton/index.js @@ -6,6 +6,7 @@ import clsx from 'clsx'; /** * WordPress dependencies */ +import { NavigableRegion } from '@wordpress/admin-ui'; import { forwardRef, useEffect } from '@wordpress/element'; import { __unstableMotion as motion, @@ -18,11 +19,6 @@ import { useResizeObserver, } from '@wordpress/compose'; -/** - * Internal dependencies - */ -import NavigableRegion from '../navigable-region'; - const ANIMATION_DURATION = 0.25; const commonTransition = { type: 'tween', diff --git a/packages/interface/src/components/navigable-region/README.md b/packages/interface/src/components/navigable-region/README.md deleted file mode 100644 index 5a931475443b19..00000000000000 --- a/packages/interface/src/components/navigable-region/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# NavigableRegion - -`NavigableRegion` renders an ARIA landmark region that's meant to be used together with the `useNavigateRegions` component from the `@wordpress/components` package. The ARIA landmark is a `div` element with a `role="region"` attribute and an `aria-label` attribute. It's made focusable by the means of a `tabindex="-1"` attribute so that `useNavigateRegions` can set focus on it and allow keyboard navigation through the regions in the editor. - -It also renders a child `div` element that is responsible to set a negative `z-index` stack level, to make sure the focus style is always visible, regardless of other elements that may cut-off the focus style outline otherwise. - -## Props - -### children - -The component that should be rendered as content. - -- Type: React Element -- Required: Yes - -### className - -The CSS class that will be added to the classes of the wrapper div. - -- Type: `String` -- Required: No - -### ariaLabel - -A meaningful name for the ARIA landmark region. - -- Type: `String` -- Required: Yes - -### as - -The component used as the root of the region. Defaults to a `div` element. - -- Type: `Component` -- Required: no -- Default: `div` diff --git a/packages/interface/src/style.scss b/packages/interface/src/style.scss index d7f1e35e6e6616..123c8aeefa398f 100644 --- a/packages/interface/src/style.scss +++ b/packages/interface/src/style.scss @@ -1,3 +1,4 @@ +@import "../../admin-ui/src/style.scss"; @import "./components/complementary-area-header/style.scss"; @import "./components/complementary-area/style.scss"; @import "./components/fullscreen-mode/style.scss"; diff --git a/tools/webpack/packages.js b/tools/webpack/packages.js index 82f8d8910a2757..5bcfc6c9c8735e 100644 --- a/tools/webpack/packages.js +++ b/tools/webpack/packages.js @@ -35,6 +35,7 @@ const WORDPRESS_NAMESPACE = '@wordpress/'; // This list must be kept in sync with the matching list in packages/dependency-extraction-webpack-plugin/lib/util.js // !! const BUNDLED_PACKAGES = [ + '@wordpress/admin-ui', '@wordpress/dataviews', '@wordpress/dataviews/wp', '@wordpress/icons', diff --git a/tsconfig.json b/tsconfig.json index 250fd832670e5a..04dfba109fa825 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,6 +3,7 @@ "references": [ { "path": "bin" }, { "path": "packages/a11y" }, + { "path": "packages/admin-ui" }, { "path": "packages/api-fetch" }, { "path": "packages/autop" }, { "path": "packages/blob" }, From 92cb0f16de09f786004c52d55135d2f64d00edcc Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 7 Oct 2025 14:03:53 +0100 Subject: [PATCH 2/2] Fix e2e tests --- test/e2e/specs/editor/various/pattern-overrides.spec.js | 2 +- test/e2e/specs/site-editor/patterns.spec.js | 2 +- test/e2e/specs/site-editor/site-editor-url-navigation.spec.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/e2e/specs/editor/various/pattern-overrides.spec.js b/test/e2e/specs/editor/various/pattern-overrides.spec.js index 8744ce93511aac..7bd52336074c24 100644 --- a/test/e2e/specs/editor/various/pattern-overrides.spec.js +++ b/test/e2e/specs/editor/various/pattern-overrides.spec.js @@ -43,7 +43,7 @@ test.describe( 'Pattern Overrides', () => { await admin.visitSiteEditor( { postType: 'wp_block' } ); await page - .getByRole( 'region', { name: 'Patterns content' } ) + .getByRole( 'region', { name: 'All patterns' } ) .getByRole( 'button', { name: 'add pattern' } ) .click(); diff --git a/test/e2e/specs/site-editor/patterns.spec.js b/test/e2e/specs/site-editor/patterns.spec.js index dcb5d8c413877c..adbb6fd8912f29 100644 --- a/test/e2e/specs/site-editor/patterns.spec.js +++ b/test/e2e/specs/site-editor/patterns.spec.js @@ -199,7 +199,7 @@ class Patterns { this.#page = page; this.content = this.#page.getByRole( 'region', { - name: 'Patterns content', + name: 'All patterns', } ); this.navigation = this.#page.getByRole( 'region', { name: 'Navigation', diff --git a/test/e2e/specs/site-editor/site-editor-url-navigation.spec.js b/test/e2e/specs/site-editor/site-editor-url-navigation.spec.js index df6408ce24e75f..4707ed4dfd8a02 100644 --- a/test/e2e/specs/site-editor/site-editor-url-navigation.spec.js +++ b/test/e2e/specs/site-editor/site-editor-url-navigation.spec.js @@ -79,7 +79,7 @@ test.describe( 'Site editor url navigation', () => { await navigation.getByRole( 'button', { name: 'General' } ).click(); await page .getByRole( 'region', { - name: 'Patterns content', + name: 'General', } ) .getByText( 'header', { exact: true } ) .click();