diff --git a/packages/e2e-test-utils/src/ensure-sidebar-opened.js b/packages/e2e-test-utils/src/ensure-sidebar-opened.js index 5ea99c629c15ef..c78084b4f4e933 100644 --- a/packages/e2e-test-utils/src/ensure-sidebar-opened.js +++ b/packages/e2e-test-utils/src/ensure-sidebar-opened.js @@ -5,10 +5,9 @@ */ export async function ensureSidebarOpened() { const toggleSidebarButton = await page.$( - '.edit-post-header__settings [aria-label="Settings"][aria-expanded="false"],' + + '.editor-header__settings [aria-label="Settings"][aria-expanded="false"],' + '.edit-site-header__actions [aria-label="Settings"][aria-expanded="false"],' + - '.edit-widgets-header__actions [aria-label="Settings"][aria-expanded="false"],' + - '.edit-site-header-edit-mode__actions [aria-label="Settings"][aria-expanded="false"]' + '.edit-widgets-header__actions [aria-label="Settings"][aria-expanded="false"]' ); if ( toggleSidebarButton ) { diff --git a/packages/e2e-test-utils/src/inserter.js b/packages/e2e-test-utils/src/inserter.js index cf5d7c48c9dfdd..5beab3c6205b6e 100644 --- a/packages/e2e-test-utils/src/inserter.js +++ b/packages/e2e-test-utils/src/inserter.js @@ -53,7 +53,8 @@ async function isGlobalInserterOpen() { '.edit-site-header [aria-label="Toggle block inserter"].is-pressed,' + '.edit-widgets-header [aria-label="Toggle block inserter"].is-pressed,' + '.edit-widgets-header [aria-label="Add block"].is-pressed,' + - '.edit-site-header-edit-mode__inserter-toggle.is-pressed' + '.edit-site-header-edit-mode__inserter-toggle.is-pressed,' + + '.editor-header [aria-label="Toggle block inserter"].is-pressed' ); } ); } diff --git a/packages/e2e-test-utils/src/site-editor.js b/packages/e2e-test-utils/src/site-editor.js index 4f6cf1773134fb..98ba34f7db4f51 100644 --- a/packages/e2e-test-utils/src/site-editor.js +++ b/packages/e2e-test-utils/src/site-editor.js @@ -97,9 +97,7 @@ export async function visitSiteEditor( query, skipWelcomeGuide = true ) { * Toggles the global styles sidebar (opens it if closed and closes it if open). */ export async function toggleGlobalStyles() { - await page.click( - '.edit-site-header-edit-mode__actions button[aria-label="Styles"]' - ); + await page.click( '.editor-header__settings button[aria-label="Styles"]' ); } /** diff --git a/packages/edit-post/src/components/header/index.js b/packages/edit-post/src/components/header/index.js index ff21478307754a..311279292d8f6a 100644 --- a/packages/edit-post/src/components/header/index.js +++ b/packages/edit-post/src/components/header/index.js @@ -1,23 +1,9 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; - /** * WordPress dependencies */ -import { - DocumentBar, - PostSavedState, - PostPreviewButton, - store as editorStore, - privateApis as editorPrivateApis, -} from '@wordpress/editor'; +import { privateApis as editorPrivateApis } from '@wordpress/editor'; import { useSelect } from '@wordpress/data'; -import { useViewportMatch } from '@wordpress/compose'; import { __unstableMotion as motion } from '@wordpress/components'; -import { store as preferencesStore } from '@wordpress/preferences'; -import { useState } from '@wordpress/element'; /** * Internal dependencies @@ -28,21 +14,7 @@ import MainDashboardButton from './main-dashboard-button'; import { store as editPostStore } from '../../store'; import { unlock } from '../../lock-unlock'; -const { - CollapsableBlockToolbar, - DocumentTools, - PostViewLink, - PreviewDropdown, - PinnedItems, - MoreMenu, - PostPublishButtonOrToggle, -} = unlock( editorPrivateApis ); - -const slideY = { - hidden: { y: '-50px' }, - distractionFreeInactive: { y: 0 }, - hover: { y: 0, transition: { type: 'tween', delay: 0.2 } }, -}; +const { Header: EditorHeader } = unlock( editorPrivateApis ); const slideX = { hidden: { x: '-100%' }, @@ -51,39 +23,17 @@ const slideX = { }; function Header( { setEntitiesSavedStatesCallback, initialPost } ) { - const isWideViewport = useViewportMatch( 'large' ); - const isLargeViewport = useViewportMatch( 'medium' ); - const { - isTextEditor, - hasActiveMetaboxes, - isPublishSidebarOpened, - showIconLabels, - hasHistory, - hasFixedToolbar, - } = useSelect( ( select ) => { - const { get: getPreference } = select( preferencesStore ); - const { getEditorMode } = select( editorStore ); - + const { hasActiveMetaboxes } = useSelect( ( select ) => { return { - isTextEditor: getEditorMode() === 'text', hasActiveMetaboxes: select( editPostStore ).hasMetaBoxes(), - hasHistory: - !! select( editorStore ).getEditorSettings() - .onNavigateToPreviousEntityRecord, - isPublishSidebarOpened: - select( editorStore ).isPublishSidebarOpened(), - showIconLabels: getPreference( 'core', 'showIconLabels' ), - hasFixedToolbar: getPreference( 'core', 'fixedToolbar' ), }; }, [] ); - const hasTopToolbar = isLargeViewport && hasFixedToolbar; - - const [ isBlockToolsCollapsed, setIsBlockToolsCollapsed ] = - useState( true ); - return ( -
+ - - - { hasTopToolbar && ( - - ) } -
- { hasHistory && } -
-
- - { ! isPublishSidebarOpened && ( - // This button isn't completely hidden by the publish sidebar. - // We can't hide the whole toolbar when the publish sidebar is open because - // we want to prevent mounting/unmounting the PostPublishButtonOrToggle DOM node. - // We track that DOM node to return focus to the PostPublishButtonOrToggle - // when the publish sidebar has been closed. - - ) } - - - - - { ( isWideViewport || ! showIconLabels ) && ( - - ) } - - - -
+ + ); } diff --git a/packages/edit-post/src/components/header/style.scss b/packages/edit-post/src/components/header/style.scss index 93c1461774cbd0..3620f3c99176a7 100644 --- a/packages/edit-post/src/components/header/style.scss +++ b/packages/edit-post/src/components/header/style.scss @@ -1,251 +1,16 @@ -.edit-post-header { - height: $header-height; - background: $white; - display: flex; - flex-wrap: wrap; - align-items: center; - // The header should never be wider than the viewport, or buttons might be hidden. Especially relevant at high zoom levels. Related to https://core.trac.wordpress.org/ticket/47603#ticket. - max-width: 100vw; - justify-content: space-between; - - // Make toolbar sticky on larger breakpoints - @include break-zoomed-in { - flex-wrap: nowrap; - } -} - -.edit-post-header__toolbar { - display: flex; - // Allow this area to shrink to fit the toolbar buttons. - flex-shrink: 8; - // Take up the space of the toolbar so it can be justified to the left side of the toolbar. - flex-grow: 3; - // Hide the overflow so flex will limit its width. Block toolbar will allow scrolling on fixed toolbar. - overflow: hidden; - // Leave enough room for the focus ring to show. - padding: 2px 0; - align-items: center; - // Allow focus ring to be fully visible on furthest right button. - @include break-medium() { - padding-right: var(--wp-admin-border-width-focus); - } - - .table-of-contents { - display: none; - - @include break-small() { - display: block; - } - } -} - -.edit-post-header__center { - flex-grow: 1; - display: flex; - justify-content: center; - - &.is-collapsed { - display: none; - } -} - /** - * Buttons on the right side + * Fullscreen mode button. */ - -.edit-post-header__settings { - display: inline-flex; - align-items: center; - flex-wrap: nowrap; - padding-right: $grid-unit-05; - - @include break-small () { - padding-right: $grid-unit-10; - } - - gap: $grid-unit-10; -} - -/** - * Show icon labels. - */ - -.show-icon-labels.interface-pinned-items, -.show-icon-labels .edit-post-header, -.edit-post-header__dropdown { - .components-button.has-icon { - width: auto; - - // Hide the button icons when labels are set to display... - svg { - display: none; - } - // ... and display labels. - &::after { - content: attr(aria-label); - } - &[aria-disabled="true"] { - background-color: transparent; - } - } - .is-tertiary { - &:active { - box-shadow: 0 0 0 1.5px var(--wp-admin-theme-color); - background-color: transparent; - } - } - // Exception for drodpdown toggle buttons. +.show-icon-labels .editor-header { // Exception for the fullscreen mode button. - .edit-post-fullscreen-mode-close.has-icon, - .components-button.has-icon.button-toggle { - svg { - display: block; - } - &::after { - content: none; - } - } // Undo the width override for fullscreen mode button. .edit-post-fullscreen-mode-close.has-icon { width: $header-height; - } - // Don't hide MenuItemsChoice check icons - .components-menu-items-choice .components-menu-items__item-icon.components-menu-items__item-icon { - display: block; - } - .editor-document-tools__inserter-toggle.editor-document-tools__inserter-toggle, - .interface-pinned-items .components-button { - padding-left: $grid-unit; - padding-right: $grid-unit; - - @include break-small { - padding-left: $grid-unit-15; - padding-right: $grid-unit-15; + svg { + display: block; } - } - - .editor-post-save-draft.editor-post-save-draft, - .editor-post-saved-state.editor-post-saved-state { &::after { content: none; } } } - -.show-icon-labels { - .edit-post-header__toolbar .block-editor-block-mover { - // Modified group borders. - border-left: none; - - &::before { - content: ""; - width: $border-width; - height: $grid-unit-30; - background-color: $gray-300; - margin-top: $grid-unit-05; - margin-left: $grid-unit; - } - - // Modified block movers horizontal separator. - .block-editor-block-mover__move-button-container { - &::before { - width: calc(100% - #{$grid-unit-30}); - background: $gray-300; - left: calc(50% + 1px); - } - } - } -} - -.edit-post-header__dropdown { - .components-menu-item__button.components-menu-item__button, - .components-button.editor-history__undo, - .components-button.editor-history__redo, - .table-of-contents .components-button, - .components-button.block-editor-list-view { - margin: 0; - padding: 6px 6px 6px $grid-unit-50; - width: 14.625rem; - text-align: left; - justify-content: flex-start; - } -} - -.show-icon-labels.interface-pinned-items { - padding: 6px $grid-unit-15 $grid-unit-15; - margin-top: 0; - margin-bottom: 0; - margin-left: -$grid-unit-15; - margin-right: -$grid-unit-15; - border-bottom: 1px solid $gray-400; - display: block; - - > .components-button.has-icon { - margin: 0; - padding: 6px 6px 6px $grid-unit; - width: 14.625rem; - justify-content: flex-start; - - &[aria-expanded="true"] svg { - display: block; - max-width: $grid-unit-30; - } - &[aria-expanded="false"] { - padding-left: $grid-unit-50; - } - svg { - margin-right: 8px; - } - } -} - -.edit-post-header__post-preview-button { - @include break-small { - display: none; - } -} - -.is-distraction-free { - .interface-interface-skeleton__header { - border-bottom: none; - } - - .edit-post-header { - background-color: $white; - border-bottom: 1px solid #e0e0e0; - position: absolute; - width: 100%; - - - // hide some parts - & > .edit-post-header__settings > .edit-post-header__post-preview-button { - visibility: hidden; - } - - & > .edit-post-header__toolbar .editor-document-tools__document-overview-toggle, - & > .edit-post-header__settings > .editor-preview-dropdown, - & > .edit-post-header__settings > .interface-pinned-items { - display: none; - } - - } - - // We need ! important because we override inline styles - // set by the motion component. - .interface-interface-skeleton__header:focus-within { - opacity: 1 !important; - div { - transform: translateX(0) translateZ(0) !important; - } - - } - - .components-editor-notices__dismissible { - position: absolute; - z-index: 35; - } -} - -.components-popover.more-menu-dropdown__content { - z-index: z-index(".components-popover.more-menu__content"); -} diff --git a/packages/edit-post/src/style.scss b/packages/edit-post/src/style.scss index d780f4257f25ab..f477bef7bbffd3 100644 --- a/packages/edit-post/src/style.scss +++ b/packages/edit-post/src/style.scss @@ -39,7 +39,7 @@ body.js.block-editor-page { } // Target the editor UI excluding the visual editor contents, metaboxes and custom fields areas. -.edit-post-header, +.editor-header, .edit-post-text-editor, .editor-sidebar, .editor-post-publish-panel { diff --git a/packages/edit-site/src/components/header-edit-mode/document-tools/index.js b/packages/edit-site/src/components/header-edit-mode/document-tools/index.js deleted file mode 100644 index cd7720a1a34f97..00000000000000 --- a/packages/edit-site/src/components/header-edit-mode/document-tools/index.js +++ /dev/null @@ -1,68 +0,0 @@ -/** - * WordPress dependencies - */ -import { useViewportMatch } from '@wordpress/compose'; -import { store as blockEditorStore } from '@wordpress/block-editor'; -import { useSelect, useDispatch } from '@wordpress/data'; -import { __ } from '@wordpress/i18n'; -import { chevronUpDown } from '@wordpress/icons'; -import { Button, ToolbarItem } from '@wordpress/components'; -import { - store as editorStore, - privateApis as editorPrivateApis, -} from '@wordpress/editor'; - -/** - * Internal dependencies - */ -import { unlock } from '../../../lock-unlock'; - -const { DocumentTools: EditorDocumentTools } = unlock( editorPrivateApis ); - -export default function DocumentTools( { - blockEditorMode, - hasFixedToolbar, - isDistractionFree, -} ) { - const { isVisualMode } = useSelect( ( select ) => { - const { getEditorMode } = select( editorStore ); - - return { - isVisualMode: getEditorMode() === 'visual', - }; - }, [] ); - const { __unstableSetEditorMode } = useDispatch( blockEditorStore ); - const { setDeviceType } = useDispatch( editorStore ); - const isLargeViewport = useViewportMatch( 'medium' ); - const isZoomedOutViewExperimentEnabled = - window?.__experimentalEnableZoomedOutView && isVisualMode; - const isZoomedOutView = blockEditorMode === 'zoom-out'; - - return ( - - { isZoomedOutViewExperimentEnabled && - isLargeViewport && - ! isDistractionFree && - ! hasFixedToolbar && ( - { - setDeviceType( 'Desktop' ); - __unstableSetEditorMode( - isZoomedOutView ? 'edit' : 'zoom-out' - ); - } } - size="compact" - /> - ) } - - ); -} diff --git a/packages/edit-site/src/components/header-edit-mode/index.js b/packages/edit-site/src/components/header-edit-mode/index.js index 486c6e0e1046c9..0ef8cbfae3b2cc 100644 --- a/packages/edit-site/src/components/header-edit-mode/index.js +++ b/packages/edit-site/src/components/header-edit-mode/index.js @@ -1,190 +1,31 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; - /** * WordPress dependencies */ -import { useViewportMatch, useReducedMotion } from '@wordpress/compose'; -import { store as blockEditorStore } from '@wordpress/block-editor'; -import { useSelect } from '@wordpress/data'; -import { useState } from '@wordpress/element'; -import { __unstableMotion as motion } from '@wordpress/components'; -import { store as preferencesStore } from '@wordpress/preferences'; -import { - DocumentBar, - PostSavedState, - store as editorStore, - privateApis as editorPrivateApis, -} from '@wordpress/editor'; +import { privateApis as editorPrivateApis } from '@wordpress/editor'; /** * Internal dependencies */ -import SiteEditorMoreMenuItems from './more-menu'; -import SaveButton from '../save-button'; -import DocumentTools from './document-tools'; -import { store as editSiteStore } from '../../store'; -import { - getEditorCanvasContainerTitle, - useHasEditorCanvasContainer, -} from '../editor-canvas-container'; +import SiteEditorMoreMenu from './more-menu'; import { unlock } from '../../lock-unlock'; -import { FOCUSABLE_ENTITIES } from '../../utils/constants'; +import SaveButton from '../save-button'; import { isPreviewingTheme } from '../../utils/is-previewing-theme'; -const { - CollapsableBlockToolbar, - MoreMenu, - PostViewLink, - PreviewDropdown, - PinnedItems, - PostPublishButtonOrToggle, -} = unlock( editorPrivateApis ); - -export default function HeaderEditMode( { setEntitiesSavedStatesCallback } ) { - const { - templateType, - isDistractionFree, - blockEditorMode, - showIconLabels, - editorCanvasView, - isFixedToolbar, - isPublishSidebarOpened, - } = useSelect( ( select ) => { - const { getEditedPostType } = select( editSiteStore ); - const { __unstableGetEditorMode } = select( blockEditorStore ); - const { get: getPreference } = select( preferencesStore ); - const { getDeviceType } = select( editorStore ); - - return { - deviceType: getDeviceType(), - templateType: getEditedPostType(), - blockEditorMode: __unstableGetEditorMode(), - showIconLabels: getPreference( 'core', 'showIconLabels' ), - editorCanvasView: unlock( - select( editSiteStore ) - ).getEditorCanvasContainerView(), - isDistractionFree: getPreference( 'core', 'distractionFree' ), - isFixedToolbar: getPreference( 'core', 'fixedToolbar' ), - isPublishSidebarOpened: - select( editorStore ).isPublishSidebarOpened(), - }; - }, [] ); - - const isLargeViewport = useViewportMatch( 'medium' ); - const showTopToolbar = - isLargeViewport && isFixedToolbar && blockEditorMode !== 'zoom-out'; - const disableMotion = useReducedMotion(); - - const hasDefaultEditorCanvasView = ! useHasEditorCanvasContainer(); - - const isFocusMode = FOCUSABLE_ENTITIES.includes( templateType ); - - const isZoomedOutView = blockEditorMode === 'zoom-out'; - - const [ isBlockToolsCollapsed, setIsBlockToolsCollapsed ] = - useState( true ); - - const toolbarVariants = { - isDistractionFree: { y: '-50px' }, - isDistractionFreeHovering: { y: 0 }, - view: { y: 0 }, - edit: { y: 0 }, - }; - - const toolbarTransition = { - type: 'tween', - duration: disableMotion ? 0 : 0.2, - ease: 'easeOut', - }; +const { Header: EditorHeader } = unlock( editorPrivateApis ); +function Header( { setEntitiesSavedStatesCallback } ) { const _isPreviewingTheme = isPreviewingTheme(); + return ( -
+ } > - { hasDefaultEditorCanvasView && ( - - - { showTopToolbar && ( - - ) } - - ) } - - { ! isDistractionFree && ( -
- { ! hasDefaultEditorCanvasView ? ( - getEditorCanvasContainerTitle( editorCanvasView ) - ) : ( - - ) } -
- ) } - -
- - { isLargeViewport && ( -
- -
- ) } - - { - // TODO: For now we conditionally render the Save/Publish buttons based on - // some specific site editor extra handling. Examples are when we're previewing - // a theme, handling of global styles changes or when we're in 'view' mode, - // which opens the save panel in a Modal. - } - { ! _isPreviewingTheme && ! isPublishSidebarOpened && ( - // This button isn't completely hidden by the publish sidebar. - // We can't hide the whole toolbar when the publish sidebar is open because - // we want to prevent mounting/unmounting the PostPublishButtonOrToggle DOM node. - // We track that DOM node to return focus to the PostPublishButtonOrToggle - // when the publish sidebar has been closed. - - ) } - { ! _isPreviewingTheme && ( - - ) } - { _isPreviewingTheme && } - { ! isDistractionFree && } - - -
-
-
+ + ); } + +export default Header; diff --git a/packages/edit-site/src/components/header-edit-mode/style.scss b/packages/edit-site/src/components/header-edit-mode/style.scss index 5963a1c8151410..69b1e9dff38492 100644 --- a/packages/edit-site/src/components/header-edit-mode/style.scss +++ b/packages/edit-site/src/components/header-edit-mode/style.scss @@ -1,201 +1,3 @@ -.edit-site-header-edit-mode { - height: $header-height; - align-items: center; - background-color: $white; - color: $gray-900; - display: flex; - box-sizing: border-box; - width: 100%; - justify-content: space-between; - border-bottom: $border-width solid $gray-200; +.editor-header { padding-left: $header-height; - - // When top toolbar is engaged and should expand fully. - &.show-block-toolbar { - - .edit-site-header-edit-mode__start, - .edit-site-header-edit-mode__end { - flex-basis: auto; - } - - .edit-site-header-edit-mode__center { - display: none; - } - } - - .edit-site-header-edit-mode__start { - display: flex; - border: none; - align-items: center; - flex-grow: 1; - flex-shrink: 2; - // Take up the full height of the header so the border focus - // is visible on toolbar buttons. - height: 100%; - // Allow focus ring to be fully visible on furthest right button. - @include break-medium() { - padding-right: var(--wp-admin-border-width-focus); - // Account for the site hub, which is 60x60px. - flex-basis: calc(37.5% - 60px); - // We need this to be overflow hidden so the block toolbar can - // overflow scroll. If the overflow is visible, flexbox allows - // the toolbar to grow outside of the allowed container space. - overflow: hidden; - } - } - - .edit-site-header-edit-mode__end { - display: flex; - justify-content: flex-end; - height: 100%; - flex-grow: 1; - flex-shrink: 1; - - @include break-medium() { - flex-basis: 37.5%; - } - } - - .edit-site-header-edit-mode__center { - align-items: center; - display: flex; - flex-basis: 100%; - flex-grow: 1; - flex-shrink: 2; - height: 100%; - justify-content: center; - - // Flex items will, by default, refuse to shrink below a minimum - // intrinsic width. In order to shrink this flexbox item, and - // subsequently truncate child text, we set an explicit min-width. - // See https://dev.w3.org/csswg/css-flexbox/#min-size-auto - min-width: 0; - - @include break-medium() { - flex-basis: 25%; - } - } - -} - -.edit-site-header-edit-mode__toolbar { - align-items: center; - display: flex; - gap: $grid-unit-10; - padding-left: $grid-unit-20; - - @include break-medium() { - padding-left: $grid-unit-50 * 0.5; - } - - @include break-wide() { - padding-right: $grid-unit-10; - } - - .edit-site-header-edit-mode__inserter-toggle { - svg { - transition: transform cubic-bezier(0.165, 0.84, 0.44, 1) 0.2s; - @include reduce-motion("transition"); - } - - &.is-pressed { - svg { - transform: rotate(45deg); - } - } - } -} - -/** - * Buttons on the right side - */ - -.edit-site-header-edit-mode__actions { - display: inline-flex; - align-items: center; - flex-wrap: nowrap; - // Ensure actions do not press against .edit-site-header-edit-mode__center. - padding-left: $grid-unit-10; - padding-right: $grid-unit-10; - gap: $grid-unit-10; -} - -.edit-site-header-edit-mode__preview-options { - opacity: 1; - transition: opacity 0.3s; - - &.is-zoomed-out { - opacity: 0; - } -} - -// Button text label styles - -.edit-site-header-edit-mode.show-icon-labels { - .components-button.has-icon { - width: auto; - - // Hide the button icons when labels are set to display... - svg { - display: none; - } - // ... and display labels. - &::after { - content: attr(aria-label); - } - &[aria-disabled="true"] { - background-color: transparent; - } - } - .is-tertiary { - &:active { - box-shadow: 0 0 0 1.5px var(--wp-admin-theme-color); - background-color: transparent; - } - } - // Some margins and padding have to be adjusted so the buttons can still fit on smaller screens. - .edit-site-save-button__button { - padding-left: 6px; - padding-right: 6px; - } - - // The template details toggle has a custom label, different from its aria-label, so we don't want to display both. - .edit-site-document-actions__get-info.edit-site-document-actions__get-info.edit-site-document-actions__get-info { - &::after { - content: none; - } - } - - .edit-site-header-edit-mode__inserter-toggle.edit-site-header-edit-mode__inserter-toggle, - .edit-site-document-actions__get-info.edit-site-document-actions__get-info.edit-site-document-actions__get-info { - height: 36px; - padding: 0 $grid-unit-10; - } - - .block-editor-block-mover { - // Modified group borders. - border-left: none; - - &::before { - content: ""; - width: $border-width; - height: $grid-unit-30; - background-color: $gray-300; - margin-top: $grid-unit-05; - margin-left: $grid-unit; - } - - // Modified block movers horizontal separator. - .block-editor-block-mover__move-button-container { - &::before { - width: calc(100% - #{$grid-unit-30}); - background: $gray-300; - left: calc(50% + 1px); - } - } - } -} - -.components-popover.more-menu-dropdown__content { - z-index: z-index(".components-popover.more-menu__content"); } diff --git a/packages/editor/src/components/document-tools/index.js b/packages/editor/src/components/document-tools/index.js index 13359cd61a8f1a..d2023e3de1b242 100644 --- a/packages/editor/src/components/document-tools/index.js +++ b/packages/editor/src/components/document-tools/index.js @@ -15,7 +15,7 @@ import { store as blockEditorStore, } from '@wordpress/block-editor'; import { Button, ToolbarItem } from '@wordpress/components'; -import { listView, plus } from '@wordpress/icons'; +import { listView, plus, chevronUpDown } from '@wordpress/icons'; import { useRef, useCallback } from '@wordpress/element'; import { store as keyboardShortcutsStore } from '@wordpress/keyboard-shortcuts'; import { store as preferencesStore } from '@wordpress/preferences'; @@ -35,13 +35,13 @@ const preventDefault = ( event ) => { function DocumentTools( { className, disableBlockTools = false, - children, // This is a temporary prop until the list view is fully unified between post and site editors. listViewLabel = __( 'Document Overview' ), } ) { const inserterButton = useRef(); - const { setIsInserterOpened, setIsListViewOpened } = + const { setIsInserterOpened, setIsListViewOpened, setDeviceType } = useDispatch( editorStore ); + const { __unstableSetEditorMode } = useDispatch( blockEditorStore ); const { isDistractionFree, isInserterOpened, @@ -50,13 +50,15 @@ function DocumentTools( { listViewToggleRef, hasFixedToolbar, showIconLabels, + isVisualMode, + isZoomedOutView, } = useSelect( ( select ) => { const { getSettings } = select( blockEditorStore ); const { get } = select( preferencesStore ); - const { isListViewOpened, getListViewToggleRef } = unlock( - select( editorStore ) - ); + const { isListViewOpened, getListViewToggleRef, getEditorMode } = + unlock( select( editorStore ) ); const { getShortcutRepresentation } = select( keyboardShortcutsStore ); + const { __unstableGetEditorMode } = select( blockEditorStore ); return { isInserterOpened: select( editorStore ).isInserterOpened(), @@ -68,11 +70,15 @@ function DocumentTools( { hasFixedToolbar: getSettings().hasFixedToolbar, showIconLabels: get( 'core', 'showIconLabels' ), isDistractionFree: get( 'core', 'distractionFree' ), + isVisualMode: getEditorMode() === 'visual', + isZoomedOutView: __unstableGetEditorMode() === 'zoom-out', }; }, [] ); const isLargeViewport = useViewportMatch( 'medium' ); const isWideViewport = useViewportMatch( 'wide' ); + const isZoomedOutViewExperimentEnabled = + window?.__experimentalEnableZoomedOutView && isVisualMode; /* translators: accessibility text for the editor toolbar */ const toolbarAriaLabel = __( 'Document tools' ); @@ -179,7 +185,27 @@ function DocumentTools( { ) } ) } - { children } + + { isZoomedOutViewExperimentEnabled && + isLargeViewport && + ! isDistractionFree && + ! hasFixedToolbar && ( + { + setDeviceType( 'Desktop' ); + __unstableSetEditorMode( + isZoomedOutView ? 'edit' : 'zoom-out' + ); + } } + size="compact" + /> + ) } ); diff --git a/packages/editor/src/components/header/index.js b/packages/editor/src/components/header/index.js new file mode 100644 index 00000000000000..ee4ed480862a7a --- /dev/null +++ b/packages/editor/src/components/header/index.js @@ -0,0 +1,131 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; + +/** + * WordPress dependencies + */ +import { useSelect } from '@wordpress/data'; +import { useViewportMatch } from '@wordpress/compose'; +import { __unstableMotion as motion } from '@wordpress/components'; +import { store as preferencesStore } from '@wordpress/preferences'; +import { useState } from '@wordpress/element'; +import { PinnedItems } from '@wordpress/interface'; + +/** + * Internal dependencies + */ +import CollapsableBlockToolbar from '../collapsible-block-toolbar'; +import DocumentBar from '../document-bar'; +import DocumentTools from '../document-tools'; +import PostPreviewButton from '../post-preview-button'; +import PostSavedState from '../post-saved-state'; +import PostViewLink from '../post-view-link'; +import PreviewDropdown from '../preview-dropdown'; +import MoreMenu from '../more-menu'; +import PostPublishButtonOrToggle from '../post-publish-button/post-publish-button-or-toggle'; + +import { store as editorStore } from '../../store'; + +const slideY = { + hidden: { y: '-50px' }, + distractionFreeInactive: { y: 0 }, + hover: { y: 0, transition: { type: 'tween', delay: 0.2 } }, +}; + +function Header( { + customSaveButton, + forceIsDirty, + setEntitiesSavedStatesCallback, + children, +} ) { + const isWideViewport = useViewportMatch( 'large' ); + const isLargeViewport = useViewportMatch( 'medium' ); + const { + isTextEditor, + isPublishSidebarOpened, + showIconLabels, + hasFixedToolbar, + } = useSelect( ( select ) => { + const { get: getPreference } = select( preferencesStore ); + const { getEditorMode } = select( editorStore ); + + return { + isTextEditor: getEditorMode() === 'text', + isPublishSidebarOpened: + select( editorStore ).isPublishSidebarOpened(), + showIconLabels: getPreference( 'core', 'showIconLabels' ), + hasFixedToolbar: getPreference( 'core', 'fixedToolbar' ), + }; + }, [] ); + + const hasTopToolbar = isLargeViewport && hasFixedToolbar; + + const [ isBlockToolsCollapsed, setIsBlockToolsCollapsed ] = + useState( true ); + + // The edit-post-header classname is only kept for backward compatibilty + // as some plugins might be relying on its presence. + return ( +
+ { children } + + + { hasTopToolbar && ( + + ) } +
+ +
+
+ + { ! customSaveButton && ! isPublishSidebarOpened && ( + // This button isn't completely hidden by the publish sidebar. + // We can't hide the whole toolbar when the publish sidebar is open because + // we want to prevent mounting/unmounting the PostPublishButtonOrToggle DOM node. + // We track that DOM node to return focus to the PostPublishButtonOrToggle + // when the publish sidebar has been closed. + + ) } + + + + { ! customSaveButton && ( + + ) } + { customSaveButton } + { ( isWideViewport || ! showIconLabels ) && ( + + ) } + + +
+ ); +} + +export default Header; diff --git a/packages/editor/src/components/header/style.scss b/packages/editor/src/components/header/style.scss new file mode 100644 index 00000000000000..3040362a7bd575 --- /dev/null +++ b/packages/editor/src/components/header/style.scss @@ -0,0 +1,231 @@ +.editor-header { + height: $header-height; + background: $white; + display: flex; + flex-wrap: wrap; + align-items: center; + // The header should never be wider than the viewport, or buttons might be hidden. Especially relevant at high zoom levels. Related to https://core.trac.wordpress.org/ticket/47603#ticket. + max-width: 100vw; + justify-content: space-between; + + // Make toolbar sticky on larger breakpoints + @include break-zoomed-in { + flex-wrap: nowrap; + } +} + +.editor-header__toolbar { + display: flex; + // Allow this area to shrink to fit the toolbar buttons. + flex-shrink: 8; + // Take up the space of the toolbar so it can be justified to the left side of the toolbar. + flex-grow: 3; + // Hide the overflow so flex will limit its width. Block toolbar will allow scrolling on fixed toolbar. + overflow: hidden; + // Leave enough room for the focus ring to show. + padding: 2px 0; + align-items: center; + // Allow focus ring to be fully visible on furthest right button. + @include break-medium() { + padding-right: var(--wp-admin-border-width-focus); + } + + .table-of-contents { + display: none; + + @include break-small() { + display: block; + } + } +} + +.editor-header__center { + flex-grow: 1; + display: flex; + justify-content: center; + + &.is-collapsed { + display: none; + } +} + +/** + * Buttons on the right side + */ + +.editor-header__settings { + display: inline-flex; + align-items: center; + flex-wrap: nowrap; + padding-right: $grid-unit-05; + + @include break-small () { + padding-right: $grid-unit-10; + } + + gap: $grid-unit-10; +} + +/** + * Show icon labels. + */ + +.show-icon-labels.interface-pinned-items, +.show-icon-labels .editor-header { + .components-button.has-icon { + width: auto; + + // Hide the button icons when labels are set to display... + svg { + display: none; + } + // ... and display labels. + &::after { + content: attr(aria-label); + } + &[aria-disabled="true"] { + background-color: transparent; + } + } + .is-tertiary { + &:active { + box-shadow: 0 0 0 1.5px var(--wp-admin-theme-color); + background-color: transparent; + } + } + // Exception for drodpdown toggle buttons. + .components-button.has-icon.button-toggle { + svg { + display: block; + } + &::after { + content: none; + } + } + + // Don't hide MenuItemsChoice check icons + .components-menu-items-choice .components-menu-items__item-icon.components-menu-items__item-icon { + display: block; + } + .editor-document-tools__inserter-toggle.editor-document-tools__inserter-toggle, + .interface-pinned-items .components-button { + padding-left: $grid-unit; + padding-right: $grid-unit; + + @include break-small { + padding-left: $grid-unit-15; + padding-right: $grid-unit-15; + } + } + + .editor-post-save-draft.editor-post-save-draft, + .editor-post-saved-state.editor-post-saved-state { + &::after { + content: none; + } + } +} + +.show-icon-labels { + .editor-header__toolbar .block-editor-block-mover { + // Modified group borders. + border-left: none; + + &::before { + content: ""; + width: $border-width; + height: $grid-unit-30; + background-color: $gray-300; + margin-top: $grid-unit-05; + margin-left: $grid-unit; + } + + // Modified block movers horizontal separator. + .block-editor-block-mover__move-button-container { + &::before { + width: calc(100% - #{$grid-unit-30}); + background: $gray-300; + left: calc(50% + 1px); + } + } + } +} + +.show-icon-labels.interface-pinned-items { + padding: 6px $grid-unit-15 $grid-unit-15; + margin-top: 0; + margin-bottom: 0; + margin-left: -$grid-unit-15; + margin-right: -$grid-unit-15; + border-bottom: 1px solid $gray-400; + display: block; + + > .components-button.has-icon { + margin: 0; + padding: 6px 6px 6px $grid-unit; + width: 14.625rem; + justify-content: flex-start; + + &[aria-expanded="true"] svg { + display: block; + max-width: $grid-unit-30; + } + &[aria-expanded="false"] { + padding-left: $grid-unit-50; + } + svg { + margin-right: 8px; + } + } +} + +.editor-header__post-preview-button { + @include break-small { + display: none; + } +} + +.is-distraction-free { + .interface-interface-skeleton__header { + border-bottom: none; + } + + .editor-header { + background-color: $white; + border-bottom: 1px solid #e0e0e0; + position: absolute; + width: 100%; + + + // hide some parts + & > .edit-post-header__settings > .edit-post-header__post-preview-button { + visibility: hidden; + } + + & > .editor-header__toolbar .editor-document-tools__document-overview-toggle, + & > .editor-header__settings > .editor-preview-dropdown, + & > .editor-header__settings > .interface-pinned-items { + display: none; + } + + } + + // We need ! important because we override inline styles + // set by the motion component. + .interface-interface-skeleton__header:focus-within { + opacity: 1 !important; + div { + transform: translateX(0) translateZ(0) !important; + } + + } + + .components-editor-notices__dismissible { + position: absolute; + z-index: 35; + } +} + +.components-popover.more-menu-dropdown__content { + z-index: z-index(".components-popover.more-menu__content"); +} diff --git a/packages/editor/src/private-apis.js b/packages/editor/src/private-apis.js index f73fef22bf5173..dbdb791d12759b 100644 --- a/packages/editor/src/private-apis.js +++ b/packages/editor/src/private-apis.js @@ -6,22 +6,18 @@ import * as interfaceApis from '@wordpress/interface'; /** * Internal dependencies */ -import CollapsableBlockToolbar from './components/collapsible-block-toolbar'; import EditorCanvas from './components/editor-canvas'; import { ExperimentalEditorProvider } from './components/provider'; import { lock } from './lock-unlock'; import { EntitiesSavedStatesExtensible } from './components/entities-saved-states'; import useAutoSwitchEditorSidebars from './components/provider/use-auto-switch-editor-sidebars'; import useBlockEditorSettings from './components/provider/use-block-editor-settings'; -import DocumentTools from './components/document-tools'; +import Header from './components/header'; import InserterSidebar from './components/inserter-sidebar'; import ListViewSidebar from './components/list-view-sidebar'; -import MoreMenu from './components/more-menu'; import PatternOverridesPanel from './components/pattern-overrides-panel'; import PluginPostExcerpt from './components/post-excerpt/plugin'; import PostPanelRow from './components/post-panel-row'; -import PostViewLink from './components/post-view-link'; -import PreviewDropdown from './components/preview-dropdown'; import PreferencesModal from './components/preferences-modal'; import PostActions from './components/post-actions'; import { usePostActions } from './components/post-actions/actions'; @@ -30,27 +26,22 @@ import PostStatus from './components/post-status'; import ToolsMoreMenuGroup from './components/more-menu/tools-more-menu-group'; import ViewMoreMenuGroup from './components/more-menu/view-more-menu-group'; import { PrivatePostExcerptPanel } from './components/post-excerpt/panel'; -import PostPublishButtonOrToggle from './components/post-publish-button/post-publish-button-or-toggle'; import SavePublishPanels from './components/save-publish-panels'; const { store: interfaceStore, ...remainingInterfaceApis } = interfaceApis; export const privateApis = {}; lock( privateApis, { - CollapsableBlockToolbar, - DocumentTools, EditorCanvas, ExperimentalEditorProvider, EntitiesSavedStatesExtensible, + Header, InserterSidebar, ListViewSidebar, - MoreMenu, PatternOverridesPanel, PluginPostExcerpt, PostActions, PostPanelRow, - PostViewLink, - PreviewDropdown, PreferencesModal, usePostActions, PostCardPanel, @@ -58,7 +49,6 @@ lock( privateApis, { ToolsMoreMenuGroup, ViewMoreMenuGroup, PrivatePostExcerptPanel, - PostPublishButtonOrToggle, SavePublishPanels, // This is a temporary private API while we're updating the site editor to use EditorProvider. diff --git a/packages/editor/src/style.scss b/packages/editor/src/style.scss index 93944188be8f83..f6920f61c8be0d 100644 --- a/packages/editor/src/style.scss +++ b/packages/editor/src/style.scss @@ -9,6 +9,7 @@ @import "./components/editor-notices/style.scss"; @import "./components/entities-saved-states/style.scss"; @import "./components/error-boundary/style.scss"; +@import "./components/header/style.scss"; @import "./components/inserter-sidebar/style.scss"; @import "./components/keyboard-shortcut-help-modal/style.scss"; @import "./components/list-view-sidebar/style.scss";