diff --git a/package-lock.json b/package-lock.json
index e62d7d72d62c61..af34547baca422 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -54571,6 +54571,7 @@
"@wordpress/data": "file:../../packages/data",
"@wordpress/editor": "file:../../packages/editor",
"@wordpress/element": "file:../../packages/element",
+ "@wordpress/global-styles-ui": "file:../../packages/global-styles-ui",
"@wordpress/html-entities": "file:../../packages/html-entities",
"@wordpress/i18n": "file:../../packages/i18n",
"@wordpress/icons": "file:../../packages/icons",
diff --git a/packages/editor/CHANGELOG.md b/packages/editor/CHANGELOG.md
index 4b278af7511ac5..46db2bbef77f06 100644
--- a/packages/editor/CHANGELOG.md
+++ b/packages/editor/CHANGELOG.md
@@ -9,6 +9,7 @@
### Bug Fixes
- `EditorInterface`: Apply the `showListViewByDefault` preference when the editor enters edit mode, so every editor built on the package honors it — including the extensible site editor, which previously ignored it. The logic moves here from `edit-post` and `edit-site`.
+- `StylesCanvas`: In preview mode, render edge to edge without the close button and Escape handler. There the canvas is the whole surface rather than a frame opened over an editing session, and whatever opened it owns closing it.
### Bug Fixes
diff --git a/packages/editor/src/components/styles-canvas/index.jsx b/packages/editor/src/components/styles-canvas/index.jsx
index 7dd6cee8fdc653..7df03c446cae29 100644
--- a/packages/editor/src/components/styles-canvas/index.jsx
+++ b/packages/editor/src/components/styles-canvas/index.jsx
@@ -1,3 +1,4 @@
+import clsx from 'clsx';
import { Button } from '@wordpress/components';
import { ESCAPE } from '@wordpress/keycodes';
import { __ } from '@wordpress/i18n';
@@ -35,8 +36,8 @@ export function getStylesCanvasTitle( path, showStylebook ) {
* @return {React.JSX.Element} The styles canvas or null if nothing to render.
*/
export default function StylesCanvas() {
- const { stylesPath, showStylebook, showListViewByDefault } = useSelect(
- ( select ) => {
+ const { stylesPath, showStylebook, showListViewByDefault, isPreviewMode } =
+ useSelect( ( select ) => {
const { getStylesPath, getShowStylebook } = unlock(
select( editorStore )
);
@@ -50,10 +51,10 @@ export default function StylesCanvas() {
stylesPath: getStylesPath(),
showStylebook: getShowStylebook(),
showListViewByDefault: _showListViewByDefault,
+ isPreviewMode:
+ select( editorStore ).getEditorSettings().isPreviewMode,
};
- },
- []
- );
+ }, [] );
const { resetStylesNavigation, setStylesPath } = unlock(
useDispatch( editorStore )
);
@@ -95,23 +96,31 @@ export default function StylesCanvas() {
}
};
+ // In preview mode (e.g. the styles route of the extensible site editor),
+ // the canvas is not opened over an editing session: whatever opened it
+ // owns closing it, so the close affordances would only desync that owner.
return (
-
+
- { /* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */ }
-
+ { ! isPreviewMode && (
+
+ ) }
{ content }
diff --git a/packages/editor/src/components/styles-canvas/style.scss b/packages/editor/src/components/styles-canvas/style.scss
index 16a30cd218f241..092259c5f92853 100644
--- a/packages/editor/src/components/styles-canvas/style.scss
+++ b/packages/editor/src/components/styles-canvas/style.scss
@@ -15,6 +15,12 @@
width: 100%;
height: 100%;
}
+
+ // In preview mode the canvas is the whole surface, not a frame opened
+ // over an editing session, so it renders edge to edge.
+ &.is-preview-mode {
+ padding: 0;
+ }
}
.editor-styles-canvas__section {
diff --git a/routes/styles/canvas.tsx b/routes/styles/canvas.tsx
index 4473a9a19c9344..a0765a22338770 100644
--- a/routes/styles/canvas.tsx
+++ b/routes/styles/canvas.tsx
@@ -4,10 +4,46 @@ import { useEditorAssets, useEditorSettings } from '@wordpress/lazy-editor';
import { Spinner } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';
+import { useGlobalStylesRevisions } from '@wordpress/global-styles-ui';
import { unlock } from '@wordpress/routes-lock-unlock';
const { StyleBookPreview } = unlock( editorPrivateApis );
+// Rendered instead of the plain style book while a revision is selected in
+// the revisions screen, so the style book previews that revision's styles
+// rather than the current ones. A separate component so the revisions (and
+// authors) are only fetched once a revision is actually selected.
+function RevisionStyleBookPreview( {
+ revisionId,
+ section,
+ onChangeSection,
+ settings,
+}: {
+ revisionId: string;
+ section: string;
+ onChangeSection: ( updatedSection: string ) => void;
+ settings: any;
+} ) {
+ const { revisions, isLoading } = useGlobalStylesRevisions();
+
+ if ( isLoading ) {
+ return null;
+ }
+
+ const selectedRevision = revisions.find(
+ ( revision: any ) => String( revision.id ) === revisionId
+ );
+
+ return (
+
+ );
+}
+
function Canvas() {
const { isReady: assetsReady } = useEditorAssets();
const navigate = useNavigate();
@@ -63,6 +99,18 @@ function Canvas() {
return ;
}
+ const revisionId = section.match( /^\/revisions\/(.+)$/ )?.[ 1 ];
+ if ( revisionId ) {
+ return (
+
+ );
+ }
+
return (
{
- const { getCurrentTheme, __experimentalGetCurrentGlobalStylesId } =
- select( coreStore ) as any;
+ const {
+ getCurrentTheme,
+ getEntityRecord,
+ __experimentalGetCurrentGlobalStylesId,
+ } = select( coreStore ) as any;
const themeNameRendered = isPreviewingTheme
? getCurrentTheme()?.name?.rendered
: undefined;
+ const _globalStylesId = __experimentalGetCurrentGlobalStylesId();
+ const globalStyles = _globalStylesId
+ ? getEntityRecord( 'root', 'globalStyles', _globalStylesId )
+ : undefined;
return {
- globalStylesId: __experimentalGetCurrentGlobalStylesId(),
+ globalStylesId: _globalStylesId,
+ hasRevisions:
+ !! globalStyles?._links?.[ 'version-history' ]?.[ 0 ]
+ ?.count,
themeName: themeNameRendered
? decodeEntities( themeNameRendered )
: undefined,
@@ -49,6 +62,21 @@ function Stage() {
} );
const section = ( search.section ?? '/' ) as string;
+ const areRevisionsOpened = section.startsWith( '/revisions' );
+
+ // The canvas on this route is the editor in preview mode, and its
+ // revisions preview is driven by the editor store's styles path rather
+ // than this route's `section` search param. Keep the store in sync while
+ // the revisions screen is open so selecting a revision previews it in
+ // the canvas.
+ const { setStylesPath } = unlock( useDispatch( editorStore ) );
+ useEffect( () => {
+ if ( ! areRevisionsOpened ) {
+ return;
+ }
+ setStylesPath( section );
+ return () => setStylesPath( '/' );
+ }, [ areRevisionsOpened, section, setStylesPath ] );
const [ isStyleBookOpened, setIsStyleBookOpened ] = useState(
search.preview === 'stylebook'
);
@@ -97,6 +125,24 @@ function Stage() {
} );
} }
/>
+