diff --git a/lib/init.php b/lib/init.php index c2fcd430c2ac47..e28d0b5c49ec0a 100644 --- a/lib/init.php +++ b/lib/init.php @@ -106,6 +106,14 @@ function gutenberg_site_editor_menu() { 'gutenberg-edit-site', 'gutenberg_edit_site_page' ); + + add_theme_page( + __( 'Styles', 'gutenberg' ), + __( 'Styles', 'gutenberg' ), + 'edit_theme_options', + 'gutenberg-edit-site&styles=open', + 'gutenberg_edit_site_page' + ); } } add_action( 'admin_menu', 'gutenberg_site_editor_menu', 9 ); diff --git a/packages/base-styles/_z-index.scss b/packages/base-styles/_z-index.scss index 0444afc675e040..d9651201a3873e 100644 --- a/packages/base-styles/_z-index.scss +++ b/packages/base-styles/_z-index.scss @@ -115,6 +115,8 @@ $z-layers: ( // Show the navigation toggle above the skeleton header ".edit-site-navigation-toggle": 31, + // Show the navigation link above the skeleton header + ".edit-site-navigation-link": 31, // Show the FSE template previews above the editor and any open block toolbars ".edit-site-navigation-panel__preview": 32, diff --git a/packages/e2e-tests/specs/experiments/document-settings.test.js b/packages/e2e-tests/specs/experiments/document-settings.test.js index 62d239b45d348a..c3a13c75abb102 100644 --- a/packages/e2e-tests/specs/experiments/document-settings.test.js +++ b/packages/e2e-tests/specs/experiments/document-settings.test.js @@ -6,7 +6,7 @@ import { trashAllPosts, activateTheme } from '@wordpress/e2e-test-utils'; /** * Internal dependencies */ -import { navigationPanel, siteEditor } from '../../experimental-features'; +import { siteEditor } from '../../experimental-features'; async function getDocumentSettingsTitle() { const titleElement = await page.waitForSelector( @@ -41,10 +41,10 @@ describe( 'Document Settings', () => { describe( 'when a template is selected from the navigation sidebar', () => { it( 'should display the selected templates name in the document header', async () => { // Navigate to a template - await navigationPanel.open(); - await navigationPanel.backToRoot(); - await navigationPanel.navigate( 'Templates' ); - await navigationPanel.clickItemByText( 'Index' ); + await siteEditor.visit( { + postId: 'tt1-blocks//index', + postType: 'wp_template', + } ); // Evaluate the document settings title const actual = await getDocumentSettingsTitle(); @@ -77,10 +77,10 @@ describe( 'Document Settings', () => { describe( 'when a template part is selected from the navigation sidebar', () => { it( "should display the selected template part's name in the document header", async () => { // Navigate to a template part - await navigationPanel.open(); - await navigationPanel.backToRoot(); - await navigationPanel.navigate( [ 'Template Parts', 'headers' ] ); - await navigationPanel.clickItemByText( 'header' ); + await siteEditor.visit( { + postId: 'tt1-blocks//header', + postType: 'wp_template_part', + } ); // Evaluate the document settings title const actual = await getDocumentSettingsTitle(); diff --git a/packages/e2e-tests/specs/experiments/multi-entity-editing.test.js b/packages/e2e-tests/specs/experiments/multi-entity-editing.test.js index 1afb1e0660f058..c2090e340f39cf 100644 --- a/packages/e2e-tests/specs/experiments/multi-entity-editing.test.js +++ b/packages/e2e-tests/specs/experiments/multi-entity-editing.test.js @@ -148,9 +148,12 @@ describe( 'Multi-entity editor states', () => { expect( await openEntitySavePanel() ).toBe( false ); } ); - it( 'should not dirty an entity by switching to it in the template dropdown', async () => { - await siteEditor.visit(); - await clickTemplateItem( [ 'Template Parts', 'headers' ], 'header' ); + // Skip reason: This should be rewritten to use other methods to switching to different templates. + it.skip( 'should not dirty an entity by switching to it in the template dropdown', async () => { + await siteEditor.visit( { + postId: 'tt1-blocks//header', + postType: 'wp_template_part', + } ); await page.waitForFunction( () => Array.from( window.frames ).find( ( { name } ) => name === 'editor-canvas' diff --git a/packages/e2e-tests/specs/experiments/multi-entity-saving.test.js b/packages/e2e-tests/specs/experiments/multi-entity-saving.test.js index e2b9d135d31498..fd73d280166e14 100644 --- a/packages/e2e-tests/specs/experiments/multi-entity-saving.test.js +++ b/packages/e2e-tests/specs/experiments/multi-entity-saving.test.js @@ -14,7 +14,7 @@ import { /** * Internal dependencies */ -import { navigationPanel, siteEditor } from '../../experimental-features'; +import { siteEditor } from '../../experimental-features'; describe( 'Multi-entity save flow', () => { // Selectors - usable between Post/Site editors. @@ -240,13 +240,10 @@ describe( 'Multi-entity save flow', () => { it( 'Save flow should work as expected', async () => { // Navigate to site editor. - await siteEditor.visit(); - - // Ensure we are on 'index' template. - await navigationPanel.open(); - await navigationPanel.backToRoot(); - await navigationPanel.navigate( 'Templates' ); - await navigationPanel.clickItemByText( 'Index' ); + await siteEditor.visit( { + postId: 'tt1-blocks//index', + postType: 'wp_template', + } ); // Select the header template part via list view. await page.click( '.edit-site-header-toolbar__list-view-toggle' ); diff --git a/packages/e2e-tests/specs/experiments/settings-sidebar.test.js b/packages/e2e-tests/specs/experiments/settings-sidebar.test.js index 9b51ec3d56195f..be3e44fce32b47 100644 --- a/packages/e2e-tests/specs/experiments/settings-sidebar.test.js +++ b/packages/e2e-tests/specs/experiments/settings-sidebar.test.js @@ -12,7 +12,7 @@ import { /** * Internal dependencies */ -import { navigationPanel, siteEditor } from '../../experimental-features'; +import { siteEditor } from '../../experimental-features'; async function toggleSidebar() { await page.click( @@ -68,10 +68,10 @@ describe( 'Settings sidebar', () => { await toggleSidebar(); const templateCardBeforeNavigation = await getTemplateCard(); - await navigationPanel.open(); - await navigationPanel.backToRoot(); - await navigationPanel.navigate( 'Templates' ); - await navigationPanel.clickItemByText( '404' ); + await siteEditor.visit( { + postId: 'tt1-blocks//404', + postType: 'wp_template', + } ); const templateCardAfterNavigation = await getTemplateCard(); expect( templateCardBeforeNavigation ).toMatchObject( { diff --git a/packages/e2e-tests/specs/experiments/template-part.test.js b/packages/e2e-tests/specs/experiments/template-part.test.js index 80c5e9a1bfdb2c..ddec6e7d362018 100644 --- a/packages/e2e-tests/specs/experiments/template-part.test.js +++ b/packages/e2e-tests/specs/experiments/template-part.test.js @@ -16,7 +16,7 @@ import { /** * Internal dependencies */ -import { navigationPanel, siteEditor } from '../../experimental-features'; +import { siteEditor } from '../../experimental-features'; const templatePartNameInput = '.edit-site-template-part-converter__modal .components-text-control__input'; @@ -40,10 +40,10 @@ describe( 'Template Part', () => { async function navigateToHeader() { // Switch to editing the header template part. - await navigationPanel.open(); - await navigationPanel.backToRoot(); - await navigationPanel.navigate( [ 'Template Parts', 'headers' ] ); - await navigationPanel.clickItemByText( 'header' ); + await siteEditor.visit( { + postId: 'tt1-blocks//header', + postType: 'wp_template_part', + } ); } async function updateHeader( content ) { @@ -61,10 +61,10 @@ describe( 'Template Part', () => { ); // Switch back to the Index template. - await navigationPanel.open(); - await navigationPanel.backToRoot(); - await navigationPanel.navigate( 'Templates' ); - await navigationPanel.clickItemByText( 'Index' ); + await siteEditor.visit( { + postId: 'tt1-blocks//index', + postType: 'wp_template', + } ); } async function triggerEllipsisMenuItem( textPrompt ) { diff --git a/packages/edit-site/src/components/editor/index.js b/packages/edit-site/src/components/editor/index.js index bedc7a94844ca1..796f3ac135a877 100644 --- a/packages/edit-site/src/components/editor/index.js +++ b/packages/edit-site/src/components/editor/index.js @@ -35,7 +35,6 @@ import Header from '../header'; import { SidebarComplementaryAreaFills } from '../sidebar'; import BlockEditor from '../block-editor'; import KeyboardShortcuts from '../keyboard-shortcuts'; -import NavigationSidebar from '../navigation-sidebar'; import URLQueryController from '../url-query-controller'; import InserterSidebar from '../secondary-sidebar/inserter-sidebar'; import ListViewSidebar from '../secondary-sidebar/list-view-sidebar'; @@ -46,7 +45,6 @@ import { GlobalStylesProvider } from '../global-styles/global-styles-provider'; const interfaceLabels = { secondarySidebar: __( 'Block Library' ), - drawer: __( 'Navigation Sidebar' ), }; function Editor( { initialSettings, onError } ) { @@ -103,6 +101,7 @@ function Editor( { initialSettings, onError } ) { const { setPage, setIsInserterOpened, updateSettings } = useDispatch( editSiteStore ); + const { enableComplementaryArea } = useDispatch( interfaceStore ); useEffect( () => { updateSettings( initialSettings ); }, [] ); @@ -160,6 +159,19 @@ function Editor( { initialSettings, onError } ) { } }, [ isNavigationOpen ] ); + useEffect( + function openGlobalStylesOnLoad() { + const searchParams = new URLSearchParams( window.location.search ); + if ( searchParams.get( 'styles' ) === 'open' ) { + enableComplementaryArea( + 'core/edit-site', + 'edit-site/global-styles' + ); + } + }, + [ enableComplementaryArea ] + ); + // Don't render the Editor until the settings are set and loaded const isReady = settings?.siteUrl && @@ -200,7 +212,6 @@ function Editor( { initialSettings, onError } ) { } secondarySidebar={ secondarySidebar() } sidebar={ sidebarIsOpened && ( diff --git a/packages/edit-site/src/components/header/index.js b/packages/edit-site/src/components/header/index.js index 5845036f5a443a..06a71f74fd76c8 100644 --- a/packages/edit-site/src/components/header/index.js +++ b/packages/edit-site/src/components/header/index.js @@ -19,6 +19,7 @@ import { store as coreStore } from '@wordpress/core-data'; /** * Internal dependencies */ +import NavigationLink from './navigation-link'; import MoreMenu from './more-menu'; import SaveButton from '../save-button'; import UndoButton from './undo-redo/undo'; @@ -105,6 +106,8 @@ export default function Header( { return (
+ +
+ + ); +} + +export default NavigationLink; diff --git a/packages/edit-site/src/components/header/navigation-link/style.scss b/packages/edit-site/src/components/header/navigation-link/style.scss new file mode 100644 index 00000000000000..adc3298fbc1f5b --- /dev/null +++ b/packages/edit-site/src/components/header/navigation-link/style.scss @@ -0,0 +1,69 @@ +// Developer notes: these rules are duplicated for the post editor. +// They need to be updated in both places. + +.edit-site-navigation-link { + align-items: center; + background: $gray-900; + border-radius: 0; + display: flex; + position: absolute; + top: 0; + left: 0; + z-index: z-index(".edit-site-navigation-link"); + height: $header-height; + width: $header-height; +} + +.edit-site-navigation-link__button { + align-items: center; + background: $gray-900; + border-radius: 0; + color: $white; + height: $header-height + $border-width; + width: $header-height; + z-index: 1; + margin-bottom: - $border-width; + + &.has-icon { + min-width: $header-height; + + &:hover, + &:active, + &:focus { + color: $white; + } + + &:focus { + box-shadow: none; + } + + &::before { + transition: box-shadow 0.1s ease; + @include reduce-motion("transition"); + content: ""; + display: block; + position: absolute; + top: 9px; + right: 9px; + bottom: 9px; + left: 9px; + border-radius: $radius-block-ui + $border-width + $border-width; + box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) $gray-900; + } + + // Hover color. + &:hover::before { + box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) $gray-700; + } + + // Lightened spot color focus. + &:focus::before { + box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) rgba($white, 0.1), inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); + } + } +} + +.edit-site-navigation-link__site-icon { + width: $button-size; + border-radius: $radius-block-ui; +} diff --git a/packages/edit-site/src/components/template-details/index.js b/packages/edit-site/src/components/template-details/index.js index 8256e058bd63ab..70a37e107defee 100644 --- a/packages/edit-site/src/components/template-details/index.js +++ b/packages/edit-site/src/components/template-details/index.js @@ -12,6 +12,7 @@ import { } from '@wordpress/components'; import { useDispatch, useSelect } from '@wordpress/data'; import { store as editorStore } from '@wordpress/editor'; +import { addQueryArgs } from '@wordpress/url'; /** * Internal dependencies @@ -30,9 +31,7 @@ export default function TemplateDetails( { template, onClose } ) { select( editorStore ).__experimentalGetTemplateInfo( template ), [] ); - const { openNavigationPanelToMenu, revertTemplate } = useDispatch( - editSiteStore - ); + const { revertTemplate } = useDispatch( editSiteStore ); const templateSubMenu = useMemo( () => { if ( template?.type === 'wp_template' ) { @@ -48,11 +47,6 @@ export default function TemplateDetails( { template, onClose } ) { return null; } - const showTemplateInSidebar = () => { - onClose(); - openNavigationPanelToMenu( templateSubMenu.menu ); - }; - const revert = () => { revertTemplate( template ); onClose(); @@ -96,14 +90,10 @@ export default function TemplateDetails( { template, onClose } ) {