From 2c813ae6b52ee921e957fcdc8cff8d59f311773f Mon Sep 17 00:00:00 2001 From: Jerry Jones Date: Wed, 1 Nov 2023 12:50:10 -0500 Subject: [PATCH 01/20] Add selected block tools slot to edit post header --- .../components/header/header-toolbar/index.js | 6 +-- .../edit-post/src/components/header/index.js | 39 +++++++++++++------ 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/packages/edit-post/src/components/header/header-toolbar/index.js b/packages/edit-post/src/components/header/header-toolbar/index.js index b86e66af7a849..9c650f8660da1 100644 --- a/packages/edit-post/src/components/header/header-toolbar/index.js +++ b/packages/edit-post/src/components/header/header-toolbar/index.js @@ -19,7 +19,6 @@ import { Button, ToolbarItem } from '@wordpress/components'; import { listView, plus } from '@wordpress/icons'; import { useRef, useCallback } from '@wordpress/element'; import { store as keyboardShortcutsStore } from '@wordpress/keyboard-shortcuts'; -import { store as preferencesStore } from '@wordpress/preferences'; /** * Internal dependencies @@ -33,7 +32,7 @@ const preventDefault = ( event ) => { event.preventDefault(); }; -function HeaderToolbar( { setListViewToggleElement } ) { +function HeaderToolbar( { hasFixedToolbar, setListViewToggleElement } ) { const inserterButton = useRef(); const { setIsInserterOpened, setIsListViewOpened } = useDispatch( editPostStore ); @@ -44,7 +43,6 @@ function HeaderToolbar( { setListViewToggleElement } ) { showIconLabels, isListViewOpen, listViewShortcut, - hasFixedToolbar, } = useSelect( ( select ) => { const { hasInserterItems, getBlockRootClientId, getBlockSelectionEnd } = select( blockEditorStore ); @@ -52,7 +50,6 @@ function HeaderToolbar( { setListViewToggleElement } ) { const { getEditorMode, isFeatureActive, isListViewOpened } = select( editPostStore ); const { getShortcutRepresentation } = select( keyboardShortcutsStore ); - const { get: getPreference } = select( preferencesStore ); return { // This setting (richEditingEnabled) should not live in the block editor's setting. @@ -69,7 +66,6 @@ function HeaderToolbar( { setListViewToggleElement } ) { listViewShortcut: getShortcutRepresentation( 'core/edit-post/toggle-list-view' ), - hasFixedToolbar: getPreference( 'core/edit-post', 'fixedToolbar' ), }; }, [] ); diff --git a/packages/edit-post/src/components/header/index.js b/packages/edit-post/src/components/header/index.js index 2e0d470818fec..130b8ec8b0ccb 100644 --- a/packages/edit-post/src/components/header/index.js +++ b/packages/edit-post/src/components/header/index.js @@ -5,7 +5,8 @@ import { PostSavedState, PostPreviewButton } from '@wordpress/editor'; import { useSelect } from '@wordpress/data'; import { PinnedItems } from '@wordpress/interface'; import { useViewportMatch } from '@wordpress/compose'; -import { __unstableMotion as motion } from '@wordpress/components'; +import { __unstableMotion as motion, Slot } from '@wordpress/components'; +import { store as preferencesStore } from '@wordpress/preferences'; /** * Internal dependencies @@ -37,17 +38,23 @@ function Header( { setListViewToggleElement, } ) { const isLargeViewport = useViewportMatch( 'large' ); - const { hasActiveMetaboxes, isPublishSidebarOpened, showIconLabels } = - useSelect( - ( select ) => ( { - hasActiveMetaboxes: select( editPostStore ).hasMetaBoxes(), - isPublishSidebarOpened: - select( editPostStore ).isPublishSidebarOpened(), - showIconLabels: - select( editPostStore ).isFeatureActive( 'showIconLabels' ), - } ), - [] - ); + const { + hasActiveMetaboxes, + hasFixedToolbar, + isPublishSidebarOpened, + showIconLabels, + } = useSelect( ( select ) => { + const { get: getPreference } = select( preferencesStore ); + + return { + hasActiveMetaboxes: select( editPostStore ).hasMetaBoxes(), + isPublishSidebarOpened: + select( editPostStore ).isPublishSidebarOpened(), + hasFixedToolbar: getPreference( 'core/edit-post', 'fixedToolbar' ), + showIconLabels: + select( editPostStore ).isFeatureActive( 'showIconLabels' ), + }; + }, [] ); return (
@@ -65,8 +72,16 @@ function Header( { className="edit-post-header__toolbar" > + { hasFixedToolbar && ( + + ) }
From 45e18889ba4e712eb4955e38da9a65b60d49f31e Mon Sep 17 00:00:00 2001 From: Jerry Jones Date: Wed, 1 Nov 2023 12:58:11 -0500 Subject: [PATCH 02/20] Add selected block tools slot to site editor header --- .../header-edit-mode/document-tools/index.js | 53 ++++++++----------- .../src/components/header-edit-mode/index.js | 13 +++++ 2 files changed, 35 insertions(+), 31 deletions(-) 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 index e68d7d0a570f8..cb75ed3c9ab15 100644 --- 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 @@ -14,7 +14,6 @@ import { _x, __ } from '@wordpress/i18n'; import { listView, plus, chevronUpDown } from '@wordpress/icons'; import { Button, ToolbarItem } from '@wordpress/components'; import { store as keyboardShortcutsStore } from '@wordpress/keyboard-shortcuts'; -import { store as preferencesStore } from '@wordpress/preferences'; /** * Internal dependencies @@ -32,42 +31,34 @@ const preventDefault = ( event ) => { export default function DocumentTools( { blockEditorMode, + hasFixedToolbar, isDistractionFree, showIconLabels, setListViewToggleElement, } ) { const inserterButton = useRef(); - const { - isInserterOpen, - isListViewOpen, - listViewShortcut, - isVisualMode, - hasFixedToolbar, - } = useSelect( ( select ) => { - const { - __experimentalGetPreviewDeviceType, - isInserterOpened, - isListViewOpened, - getEditorMode, - } = select( editSiteStore ); - const { getShortcutRepresentation } = select( keyboardShortcutsStore ); - - const { get: getPreference } = select( preferencesStore ); + const { isInserterOpen, isListViewOpen, listViewShortcut, isVisualMode } = + useSelect( ( select ) => { + const { + __experimentalGetPreviewDeviceType, + isInserterOpened, + isListViewOpened, + getEditorMode, + } = select( editSiteStore ); + const { getShortcutRepresentation } = select( + keyboardShortcutsStore + ); - return { - deviceType: __experimentalGetPreviewDeviceType(), - isInserterOpen: isInserterOpened(), - isListViewOpen: isListViewOpened(), - listViewShortcut: getShortcutRepresentation( - 'core/edit-site/toggle-list-view' - ), - isVisualMode: getEditorMode() === 'visual', - hasFixedToolbar: getPreference( - editSiteStore.name, - 'fixedToolbar' - ), - }; - }, [] ); + return { + deviceType: __experimentalGetPreviewDeviceType(), + isInserterOpen: isInserterOpened(), + isListViewOpen: isListViewOpened(), + listViewShortcut: getShortcutRepresentation( + 'core/edit-site/toggle-list-view' + ), + isVisualMode: getEditorMode() === 'visual', + }; + }, [] ); const { __experimentalSetPreviewDeviceType: setPreviewDeviceType, 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 50955950a3312..1559583c0e791 100644 --- a/packages/edit-site/src/components/header-edit-mode/index.js +++ b/packages/edit-site/src/components/header-edit-mode/index.js @@ -20,6 +20,7 @@ import { __unstableMotion as motion, MenuGroup, MenuItem, + Slot, VisuallyHidden, } from '@wordpress/components'; import { store as preferencesStore } from '@wordpress/preferences'; @@ -48,6 +49,7 @@ export default function HeaderEditMode( { setListViewToggleElement } ) { homeUrl, showIconLabels, editorCanvasView, + hasFixedToolbar, } = useSelect( ( select ) => { const { __experimentalGetPreviewDeviceType, getEditedPostType } = select( editSiteStore ); @@ -73,6 +75,10 @@ export default function HeaderEditMode( { setListViewToggleElement } ) { editorCanvasView: unlock( select( editSiteStore ) ).getEditorCanvasContainerView(), + hasFixedToolbar: getPreference( + editSiteStore.name, + 'fixedToolbar' + ), isDistractionFree: getPreference( editSiteStore.name, 'distractionFree' @@ -120,6 +126,13 @@ export default function HeaderEditMode( { setListViewToggleElement } ) { showIconLabels={ showIconLabels } setListViewToggleElement={ setListViewToggleElement } /> + { hasFixedToolbar && ( + + ) } ) } From 8b0cd57b7c6bfe421b7e6a3bcfb4a134b06082aa Mon Sep 17 00:00:00 2001 From: Jerry Jones Date: Wed, 1 Nov 2023 13:55:52 -0500 Subject: [PATCH 03/20] Add selected tools slot to widget header --- .../src/components/header/index.js | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/edit-widgets/src/components/header/index.js b/packages/edit-widgets/src/components/header/index.js index 29afc1eba59b8..acbefe28f3ebf 100644 --- a/packages/edit-widgets/src/components/header/index.js +++ b/packages/edit-widgets/src/components/header/index.js @@ -1,10 +1,12 @@ /** * WordPress dependencies */ +import { useSelect } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; -import { VisuallyHidden } from '@wordpress/components'; +import { Slot, VisuallyHidden } from '@wordpress/components'; import { PinnedItems } from '@wordpress/interface'; import { useViewportMatch } from '@wordpress/compose'; +import { store as preferencesStore } from '@wordpress/preferences'; /** * Internal dependencies @@ -15,6 +17,15 @@ import MoreMenu from '../more-menu'; function Header( { setListViewToggleElement } ) { const isMediumViewport = useViewportMatch( 'medium' ); + const { hasFixedToolbar } = useSelect( + ( select ) => ( { + hasFixedToolbar: !! select( preferencesStore ).get( + 'core/edit-widgets', + 'fixedToolbar' + ), + } ), + [] + ); return ( <> @@ -36,6 +47,13 @@ function Header( { setListViewToggleElement } ) { + { hasFixedToolbar && ( + + ) }
From 0d580ba6e7b8245f3616bc0937d85114508f02c8 Mon Sep 17 00:00:00 2001 From: Jerry Jones Date: Wed, 1 Nov 2023 14:09:08 -0500 Subject: [PATCH 04/20] Add contextual toolbar as fill when top toolbar option is on --- .../src/components/block-tools/index.js | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/packages/block-editor/src/components/block-tools/index.js b/packages/block-editor/src/components/block-tools/index.js index 696299689d185..b546003fc8253 100644 --- a/packages/block-editor/src/components/block-tools/index.js +++ b/packages/block-editor/src/components/block-tools/index.js @@ -3,7 +3,11 @@ */ import { useSelect, useDispatch } from '@wordpress/data'; import { useViewportMatch } from '@wordpress/compose'; -import { Popover } from '@wordpress/components'; +import { + Fill, + __experimentalUseSlot as useSlot, + Popover, +} from '@wordpress/components'; import { __unstableUseShortcutEventMatch as useShortcutEventMatch } from '@wordpress/keyboard-shortcuts'; import { useRef } from '@wordpress/element'; import { isUnmodifiedDefaultBlock } from '@wordpress/blocks'; @@ -90,6 +94,8 @@ export default function BlockTools( { const selectedBlockToolsRef = useRef( null ); + const blockToolsSlot = useSlot( '__experimentalSelectedBlockTools' ); + function onKeyDown( event ) { if ( event.defaultPrevented ) return; @@ -173,14 +179,22 @@ export default function BlockTools( { __unstableContentRef={ __unstableContentRef } /> ) } + { /* If there is no slot available, such as in the standalone block editor, render within the editor */ } { ! isZoomOutMode && - ( hasFixedToolbar || ! isLargeViewport ) && ( + ( hasFixedToolbar || ! isLargeViewport ) && + ( blockToolsSlot?.ref?.current ? ( + + + + ) : ( - ) } - + ) ) } { showEmptyBlockSideInserter && ( Date: Tue, 19 Sep 2023 15:23:10 -0500 Subject: [PATCH 05/20] Remove absolute positioned block tool hacks --- .../block-tools/block-contextual-toolbar.js | 90 +---------------- packages/customize-widgets/src/style.scss | 31 ------ .../src/components/header/style.scss | 14 +++ .../src/components/layout/style.scss | 11 --- .../src/components/visual-editor/style.scss | 89 ----------------- .../src/components/block-editor/style.scss | 87 ---------------- .../components/header-edit-mode/style.scss | 15 +++ .../src/components/layout/style.scss | 17 ---- .../src/components/layout/style.scss | 12 --- .../style.scss | 98 ------------------- 10 files changed, 30 insertions(+), 434 deletions(-) diff --git a/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js b/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js index deac140f412ca..d015330768827 100644 --- a/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js +++ b/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js @@ -7,13 +7,7 @@ import classnames from 'classnames'; * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { - forwardRef, - useLayoutEffect, - useEffect, - useRef, - useState, -} from '@wordpress/element'; +import { forwardRef, useEffect, useRef, useState } from '@wordpress/element'; import { hasBlockSupport, store as blocksStore } from '@wordpress/blocks'; import { useSelect } from '@wordpress/data'; import { @@ -86,88 +80,6 @@ function UnforwardedBlockContextualToolbar( setIsCollapsed( false ); }, [ selectedBlockClientId ] ); - const isLargerThanTabletViewport = useViewportMatch( 'large', '>=' ); - const isFullscreen = - document.body.classList.contains( 'is-fullscreen-mode' ); - - /** - * The following code is a workaround to fix the width of the toolbar - * it should be removed when the toolbar will be rendered inline - * FIXME: remove this layout effect when the toolbar is no longer - * absolutely positioned - */ - useLayoutEffect( () => { - // don't do anything if not fixed toolbar - if ( ! isFixed ) { - return; - } - - const blockToolbar = document.querySelector( - '.block-editor-block-contextual-toolbar' - ); - - if ( ! blockToolbar ) { - return; - } - - if ( ! blockType ) { - blockToolbar.style.width = 'initial'; - return; - } - - if ( ! isLargerThanTabletViewport ) { - // set the width of the toolbar to auto - blockToolbar.style = {}; - return; - } - - if ( isCollapsed ) { - // set the width of the toolbar to auto - blockToolbar.style.width = 'auto'; - return; - } - - // get the width of the pinned items in the post editor or widget editor - const pinnedItems = document.querySelector( - '.edit-post-header__settings, .edit-widgets-header__actions' - ); - // get the width of the left header in the site editor - const leftHeader = document.querySelector( - '.edit-site-header-edit-mode__end' - ); - - const computedToolbarStyle = window.getComputedStyle( blockToolbar ); - const computedPinnedItemsStyle = pinnedItems - ? window.getComputedStyle( pinnedItems ) - : false; - const computedLeftHeaderStyle = leftHeader - ? window.getComputedStyle( leftHeader ) - : false; - - const marginLeft = parseFloat( computedToolbarStyle.marginLeft ); - const pinnedItemsWidth = computedPinnedItemsStyle - ? parseFloat( computedPinnedItemsStyle.width ) - : 0; - const leftHeaderWidth = computedLeftHeaderStyle - ? parseFloat( computedLeftHeaderStyle.width ) - : 0; - - // set the new witdth of the toolbar - blockToolbar.style.width = `calc(100% - ${ - leftHeaderWidth + - pinnedItemsWidth + - marginLeft + - ( pinnedItems || leftHeader ? 2 : 0 ) + // Prevents button focus border from being cut off - ( isFullscreen ? 0 : 160 ) // the width of the admin sidebar expanded - }px)`; - }, [ - isFixed, - isLargerThanTabletViewport, - isCollapsed, - isFullscreen, - blockType, - ] ); - const isToolbarEnabled = blockType && hasBlockSupport( blockType, '__experimentalToolbar', true ); diff --git a/packages/customize-widgets/src/style.scss b/packages/customize-widgets/src/style.scss index bd6d16b89c7fa..3bf341c34c0eb 100644 --- a/packages/customize-widgets/src/style.scss +++ b/packages/customize-widgets/src/style.scss @@ -17,34 +17,3 @@ .customize-widgets-popover { @include reset; } - -/** - Fixed bloock toolbar overrides. We can't detect each editor instance - in the styles of the block editor component so we need to override - the fixed styles here because the breakpoint css does not fire in the - customizer's left panel. -*/ -.block-editor-block-contextual-toolbar { - &.is-fixed { - position: sticky; - top: 0; - left: 0; - z-index: z-index(".block-editor-block-list__insertion-point"); - width: calc(100% + 2 * 12px); //12px is the padding of customizer sidebar content - - overflow-y: hidden; - - border: none; - border-bottom: $border-width solid $gray-200; - border-radius: 0; - - .block-editor-block-toolbar .components-toolbar-group, - .block-editor-block-toolbar .components-toolbar { - border-right-color: $gray-200; - } - - &.is-collapsed { - margin-left: -12px; //12px is the padding of customizer sidebar content - } - } -} diff --git a/packages/edit-post/src/components/header/style.scss b/packages/edit-post/src/components/header/style.scss index d83745196576f..42448ebef4012 100644 --- a/packages/edit-post/src/components/header/style.scss +++ b/packages/edit-post/src/components/header/style.scss @@ -42,6 +42,20 @@ display: block; } } + + .block-editor-block-contextual-toolbar.is-fixed { + position: fixed; + top: $admin-bar-height-big + $header-height + 1px; // +1px to avoid overlap with the header border + left: 0; + width: 100%; + + @include break-medium() { + width: auto; + position: static; + // remove the border + border: none; + } + } } .edit-post-header__center { diff --git a/packages/edit-post/src/components/layout/style.scss b/packages/edit-post/src/components/layout/style.scss index 5e8cdb4fb76e1..229ab58a4e14b 100644 --- a/packages/edit-post/src/components/layout/style.scss +++ b/packages/edit-post/src/components/layout/style.scss @@ -99,14 +99,3 @@ .edit-post-layout .entities-saved-states__panel-header { height: $header-height + $border-width; } - -.edit-post-layout.has-fixed-toolbar { - // making the header be lower than the content - // so the fixed toolbar can be positioned on top of it - // but only on desktop - @include break-medium() { - .interface-interface-skeleton__header:not(:focus-within) { - z-index: 19; - } - } -} diff --git a/packages/edit-post/src/components/visual-editor/style.scss b/packages/edit-post/src/components/visual-editor/style.scss index 40043958fcaad..fa61cc9889cf9 100644 --- a/packages/edit-post/src/components/visual-editor/style.scss +++ b/packages/edit-post/src/components/visual-editor/style.scss @@ -67,92 +67,3 @@ // See also https://www.w3.org/TR/CSS22/visudet.html#the-height-property flex-grow: 1; } - -// Fixed contextual toolbar -@include editor-left(".edit-post-visual-editor .block-editor-block-contextual-toolbar.is-fixed"); - -.edit-post-visual-editor .block-editor-block-contextual-toolbar.is-fixed { - position: sticky; - top: 0; - z-index: z-index(".block-editor-block-popover"); - display: block; - width: 100%; - - // on desktop and tablet viewports the toolbar is fixed - // on top of interface header - $toolbar-margin: $grid-unit-80 * 3 - 2 * $grid-unit + $grid-unit-05; - - @include break-medium() { - // leave room for block inserter, undo and redo, list view - margin-left: $toolbar-margin; - // position on top of interface header - position: fixed; - top: $admin-bar-height; - // Don't fill up when empty - min-height: initial; - // remove the border - border-bottom: none; - // has to be flex for collapse button to fit - display: flex; - - // Mimic the height of the parent, vertically align center, and provide a max-height. - height: $header-height; - align-items: center; - - - // on tablet viewports the toolbar is fixed - // on top of interface header and covers the whole header - // except for the inserter on the left - width: calc(100% - #{$toolbar-margin}); - - &.is-collapsed { - width: initial; - } - - &:empty { - width: initial; - } - - .is-fullscreen-mode & { - // leave room for block inserter, undo and redo, list view - // and some margin left - margin-left: $grid-unit-80 * 4 - 2 * $grid-unit; - - top: 0; - - &.is-collapsed { - width: initial; - } - - &:empty { - width: initial; - } - } - - .show-icon-labels & { - width: calc(100% + 40px - #{$toolbar-margin}); //there are no undo, redo and list view buttons - margin-left: $grid-unit-80 + 2 * $grid-unit; // inserter and margin - - .is-fullscreen-mode & { - margin-left: $grid-unit * 18; // site hub, inserter and margin - } - } - } - - // on desktop viewports the toolbar is fixed - // on top of interface header and leaves room - // for the block inserter the publish button - @include break-large() { - width: auto; - .show-icon-labels & { - width: auto; //there are no undo, redo and list view buttons - } - - .is-fullscreen-mode & { - // in full screen mode we need to account for - // the combined with of the tools at the right of the header and the margin left - // of the toolbar which includes four buttons - width: calc(100% - 280px - #{4 * $grid-unit-80}); - } - } -} diff --git a/packages/edit-site/src/components/block-editor/style.scss b/packages/edit-site/src/components/block-editor/style.scss index ad058b2dd7be9..b110b1c274e77 100644 --- a/packages/edit-site/src/components/block-editor/style.scss +++ b/packages/edit-site/src/components/block-editor/style.scss @@ -172,90 +172,3 @@ box-shadow: inset 0 0 0 2px var(--wp-admin-theme-color); } } - -// Fixed contextual toolbar -@include editor-left(".edit-site-visual-editor .block-editor-block-contextual-toolbar.is-fixed"); - -.edit-site-visual-editor .block-editor-block-contextual-toolbar.is-fixed { - position: sticky; - top: 0; - z-index: z-index(".block-editor-block-popover"); - display: block; - width: 100%; - - // on desktop and tablet viewports the toolbar is fixed - // on top of interface header - $toolbar-margin: $grid-unit-80 * 3 - 2 * $grid-unit + $grid-unit-05; - - @include break-medium() { - // leave room for block inserter, undo and redo, list view - margin-left: $toolbar-margin; - // position on top of interface header - position: fixed; - top: $admin-bar-height; - // Don't fill up when empty - min-height: initial; - // has to be flex for collapse button to fit - display: flex; - - // Mimic the height of the parent, vertically align center, and provide a max-height. - height: $header-height; - align-items: center; - - - // on tablet viewports the toolbar is fixed - // on top of interface header and covers the whole header - // except for the inserter on the left - width: calc(100% - #{$toolbar-margin}); - - &.is-collapsed { - width: initial; - } - - &:empty { - width: initial; - } - - .is-fullscreen-mode & { - // leave room for block inserter, undo and redo, list view - // and some margin left - margin-left: $grid-unit-80 * 4 - 2 * $grid-unit; - - top: 0; - - &.is-collapsed { - width: initial; - } - - &:empty { - width: initial; - } - } - - .show-icon-labels & { - margin-left: $grid-unit-80 + 2 * $grid-unit; // inserter and margin - width: calc(100% + 40px - #{$toolbar-margin}); //there are no undo, redo and list view buttons - - .is-fullscreen-mode & { - margin-left: $grid-unit * 18; // site hub, inserter and margin - } - } - } - - // on desktop viewports the toolbar is fixed - // on top of interface header and leaves room - // for the block inserter the publish button - @include break-large() { - width: auto; - .show-icon-labels & { - width: auto; //there are no undo, redo and list view buttons - } - - .is-fullscreen-mode & { - // in full screen mode we need to account for - // the combined with of the tools at the right of the header and the margin left - // of the toolbar which includes four buttons - width: calc(100% - 280px - #{4 * $grid-unit-80}); - } - } -} 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 26b1716a28b86..0f1dc76f50e75 100644 --- a/packages/edit-site/src/components/header-edit-mode/style.scss +++ b/packages/edit-site/src/components/header-edit-mode/style.scss @@ -70,6 +70,21 @@ $header-toolbar-min-width: 335px; } } +.edit-site-header-edit-mode .block-editor-block-contextual-toolbar.is-fixed { + position: fixed; + top: $header-height; // +1px to avoid overlap with the header border + left: 0; + width: 100%; + + @include break-medium() { + width: auto; + position: relative; + top: 0; + // remove the border + border: none; + } +} + /** * Buttons on the right side */ diff --git a/packages/edit-site/src/components/layout/style.scss b/packages/edit-site/src/components/layout/style.scss index 088217776b4d2..3bea97862b1c4 100644 --- a/packages/edit-site/src/components/layout/style.scss +++ b/packages/edit-site/src/components/layout/style.scss @@ -254,23 +254,6 @@ } } -.edit-site-layout.has-fixed-toolbar { - // making the header be lower than the content - // so the fixed toolbar can be positioned on top of it - // but only on desktop - @include break-medium() { - .edit-site-layout__canvas-container { - z-index: 5; - } - .edit-site-site-hub { - z-index: 4; - } - .edit-site-layout__header:focus-within { - z-index: 3; - } - } -} - .is-edit-mode.is-distraction-free { .edit-site-layout__header-container { diff --git a/packages/edit-widgets/src/components/layout/style.scss b/packages/edit-widgets/src/components/layout/style.scss index fe1edbae23295..1aed3d3eefc86 100644 --- a/packages/edit-widgets/src/components/layout/style.scss +++ b/packages/edit-widgets/src/components/layout/style.scss @@ -22,15 +22,3 @@ height: 100%; } } - -.blocks-widgets-container { - // making the header be lower than the content - // so the fixed toolbar can be positioned on top of it - // but only on desktop - @include break-medium() { - .interface-interface-skeleton__header:not(:focus-within) { - z-index: 19; - } - } - -} diff --git a/packages/edit-widgets/src/components/widget-areas-block-editor-content/style.scss b/packages/edit-widgets/src/components/widget-areas-block-editor-content/style.scss index 062214ef147bf..35493cad130cf 100644 --- a/packages/edit-widgets/src/components/widget-areas-block-editor-content/style.scss +++ b/packages/edit-widgets/src/components/widget-areas-block-editor-content/style.scss @@ -34,101 +34,3 @@ } } } - -// Fixed contextual toolbar -@include editor-left(".edit-widgets-block-editor .block-editor-block-contextual-toolbar.is-fixed"); - - -.edit-widgets-block-editor .block-editor-block-contextual-toolbar.is-fixed { - position: sticky; - top: 0; - z-index: z-index(".block-editor-block-popover"); - display: block; - width: 100%; - - // on desktop and tablet viewports the toolbar is fixed - // on top of interface header - $toolbar-margin: $grid-unit-80 * 3 - 2 * $grid-unit + $grid-unit-05; - - @include break-medium() { - // leave room for block inserter, undo and redo, list view - margin-left: $toolbar-margin; - // position on top of interface header - position: fixed; - top: $admin-bar-height; - // Don't fill up when empty - min-height: initial; - // remove the border - border-bottom: none; - // has to be flex for collapse button to fit - display: flex; - - // Mimic the height of the parent, vertically align center, and provide a max-height. - height: $header-height; - align-items: center; - - - // on tablet viewports the toolbar is fixed - // on top of interface header and covers the whole header - // except for the inserter on the left - width: calc(100% - #{$toolbar-margin}); - - &.is-collapsed { - width: initial; - } - - &:empty { - width: initial; - } - - .is-fullscreen-mode & { - // leave room for block inserter, undo and redo, list view - // and some margin left - margin-left: $grid-unit-80 * 4 - 2 * $grid-unit; - - top: 0; - - &.is-collapsed { - width: initial; - } - - &:empty { - width: initial; - } - } - - .show-icon-labels & { - margin-left: $grid-unit-80 + 2 * $grid-unit; // inserter and margin - width: calc(100% + 40px - #{$toolbar-margin}); //there are no undo, redo and list view buttons - - .is-fullscreen-mode & { - margin-left: $grid-unit * 18; // site hub, inserter and margin - } - } - - .blocks-widgets-container & { - margin-left: $grid-unit-80 * 2.4; - - &.is-collapsed { - margin-left: $grid-unit-80 * 4.2; - } - } - } - - // on desktop viewports the toolbar is fixed - // on top of interface header and leaves room - // for the block inserter the publish button - @include break-large() { - width: auto; - .show-icon-labels & { - width: auto; //there are no undo, redo and list view buttons - } - - .is-fullscreen-mode & { - // in full screen mode we need to account for - // the combined with of the tools at the right of the header and the margin left - // of the toolbar which includes four buttons - width: calc(100% - 280px - #{4 * $grid-unit-80}); - } - } -} From d63459979cf706a985120f2ce4eea7e2ae68e00c Mon Sep 17 00:00:00 2001 From: Jerry Jones Date: Wed, 1 Nov 2023 14:18:12 -0500 Subject: [PATCH 06/20] Move inline rich popover into header if top toolbar slot is available --- .../src/components/block-tools/index.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/block-tools/index.js b/packages/block-editor/src/components/block-tools/index.js index b546003fc8253..de4ada16a7dd4 100644 --- a/packages/block-editor/src/components/block-tools/index.js +++ b/packages/block-editor/src/components/block-tools/index.js @@ -212,7 +212,20 @@ export default function BlockTools( { ) } { /* Used for the inline rich text toolbar. */ } - + { /* If there is no slot available, such as in the standalone block editor, render within the editor */ } + { blockToolsSlot?.ref?.current ? ( + + + + ) : ( + + ) } { children } { /* Used for inline rich text popovers. */ } Date: Thu, 2 Nov 2023 15:22:14 -0500 Subject: [PATCH 07/20] isBlockToolsCollapsed state and styles for edit site header Move isCollapsed state from the block-contextual-toolbar into the site editor header, as it is only needed and related to the site editor header. This is not a state the block toolbar needs to know about. Co-authored-by: Andrei Draganescu --- .../block-tools/block-contextual-toolbar.js | 118 ++++++------------ .../header-edit-mode/document-tools/index.js | 2 +- .../src/components/header-edit-mode/index.js | 73 +++++++++-- .../components/header-edit-mode/style.scss | 21 +++- 4 files changed, 120 insertions(+), 94 deletions(-) diff --git a/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js b/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js index d015330768827..988bb3589f0b1 100644 --- a/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js +++ b/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js @@ -7,16 +7,9 @@ import classnames from 'classnames'; * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { forwardRef, useEffect, useRef, useState } from '@wordpress/element'; +import { forwardRef } from '@wordpress/element'; import { hasBlockSupport, store as blocksStore } from '@wordpress/blocks'; import { useSelect } from '@wordpress/data'; -import { - ToolbarItem, - ToolbarButton, - ToolbarGroup, -} from '@wordpress/components'; -import { next, previous } from '@wordpress/icons'; -import { useViewportMatch } from '@wordpress/compose'; /** * Internal dependencies @@ -30,55 +23,41 @@ function UnforwardedBlockContextualToolbar( { focusOnMount, isFixed, ...props }, ref ) { - // When the toolbar is fixed it can be collapsed - const [ isCollapsed, setIsCollapsed ] = useState( false ); - const toolbarButtonRef = useRef(); + const { blockType, blockEditingMode, hasParents, showParentSelector } = + useSelect( ( select ) => { + const { + getBlockName, + getBlockParents, + getSelectedBlockClientIds, + getBlockEditingMode, + } = select( blockEditorStore ); + const { getBlockType } = select( blocksStore ); + const selectedBlockClientIds = getSelectedBlockClientIds(); + const _selectedBlockClientId = selectedBlockClientIds[ 0 ]; + const parents = getBlockParents( _selectedBlockClientId ); + const firstParentClientId = parents[ parents.length - 1 ]; + const parentBlockName = getBlockName( firstParentClientId ); + const parentBlockType = getBlockType( parentBlockName ); - const isLargeViewport = useViewportMatch( 'medium' ); - const { - blockType, - blockEditingMode, - hasParents, - showParentSelector, - selectedBlockClientId, - } = useSelect( ( select ) => { - const { - getBlockName, - getBlockParents, - getSelectedBlockClientIds, - getBlockEditingMode, - } = select( blockEditorStore ); - const { getBlockType } = select( blocksStore ); - const selectedBlockClientIds = getSelectedBlockClientIds(); - const _selectedBlockClientId = selectedBlockClientIds[ 0 ]; - const parents = getBlockParents( _selectedBlockClientId ); - const firstParentClientId = parents[ parents.length - 1 ]; - const parentBlockName = getBlockName( firstParentClientId ); - const parentBlockType = getBlockType( parentBlockName ); - - return { - selectedBlockClientId: _selectedBlockClientId, - blockType: - _selectedBlockClientId && - getBlockType( getBlockName( _selectedBlockClientId ) ), - blockEditingMode: getBlockEditingMode( _selectedBlockClientId ), - hasParents: parents.length, - showParentSelector: - parentBlockType && - getBlockEditingMode( firstParentClientId ) === 'default' && - hasBlockSupport( - parentBlockType, - '__experimentalParentSelector', - true - ) && - selectedBlockClientIds.length <= 1 && - getBlockEditingMode( _selectedBlockClientId ) === 'default', - }; - }, [] ); - - useEffect( () => { - setIsCollapsed( false ); - }, [ selectedBlockClientId ] ); + return { + selectedBlockClientId: _selectedBlockClientId, + blockType: + _selectedBlockClientId && + getBlockType( getBlockName( _selectedBlockClientId ) ), + blockEditingMode: getBlockEditingMode( _selectedBlockClientId ), + hasParents: parents.length, + showParentSelector: + parentBlockType && + getBlockEditingMode( firstParentClientId ) === 'default' && + hasBlockSupport( + parentBlockType, + '__experimentalParentSelector', + true + ) && + selectedBlockClientIds.length <= 1 && + getBlockEditingMode( _selectedBlockClientId ) === 'default', + }; + }, [] ); const isToolbarEnabled = blockType && @@ -95,7 +74,6 @@ function UnforwardedBlockContextualToolbar( const classes = classnames( 'block-editor-block-contextual-toolbar', { 'has-parent': hasParents && showParentSelector, 'is-fixed': isFixed, - 'is-collapsed': isCollapsed, } ); return ( @@ -109,31 +87,7 @@ function UnforwardedBlockContextualToolbar( variant={ isFixed ? 'unstyled' : undefined } { ...props } > - { ! isCollapsed && } - { isFixed && isLargeViewport && blockType && ( - - { - setIsCollapsed( ( collapsed ) => ! collapsed ); - toolbarButtonRef.current.focus(); - } } - label={ - isCollapsed - ? __( 'Show block tools' ) - : __( 'Hide block tools' ) - } - /> - - ) } + ); } 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 index cb75ed3c9ab15..dda761c983d31 100644 --- 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 @@ -111,7 +111,7 @@ export default function DocumentTools( { return ( 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 1559583c0e791..c35f1f1ddd681 100644 --- a/packages/edit-site/src/components/header-edit-mode/index.js +++ b/packages/edit-site/src/components/header-edit-mode/index.js @@ -6,17 +6,19 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { useReducedMotion } from '@wordpress/compose'; +import { useViewportMatch, useReducedMotion } from '@wordpress/compose'; import { store as coreStore } from '@wordpress/core-data'; import { __experimentalPreviewOptions as PreviewOptions, store as blockEditorStore, } from '@wordpress/block-editor'; import { useSelect, useDispatch } from '@wordpress/data'; +import { useEffect, useState } from '@wordpress/element'; import { PinnedItems } from '@wordpress/interface'; import { __ } from '@wordpress/i18n'; -import { external } from '@wordpress/icons'; +import { external, next, previous } from '@wordpress/icons'; import { + Button, __unstableMotion as motion, MenuGroup, MenuItem, @@ -46,6 +48,7 @@ export default function HeaderEditMode( { setListViewToggleElement } ) { templateType, isDistractionFree, blockEditorMode, + blockSelectionStart, homeUrl, showIconLabels, editorCanvasView, @@ -53,7 +56,8 @@ export default function HeaderEditMode( { setListViewToggleElement } ) { } = useSelect( ( select ) => { const { __experimentalGetPreviewDeviceType, getEditedPostType } = select( editSiteStore ); - const { __unstableGetEditorMode } = select( blockEditorStore ); + const { getBlockSelectionStart, __unstableGetEditorMode } = + select( blockEditorStore ); const postType = getEditedPostType(); @@ -67,6 +71,7 @@ export default function HeaderEditMode( { setListViewToggleElement } ) { deviceType: __experimentalGetPreviewDeviceType(), templateType: postType, blockEditorMode: __unstableGetEditorMode(), + blockSelectionStart: getBlockSelectionStart(), homeUrl: getUnstableBase()?.home, showIconLabels: getPreference( editSiteStore.name, @@ -86,6 +91,8 @@ export default function HeaderEditMode( { setListViewToggleElement } ) { }; }, [] ); + const isLargeViewport = useViewportMatch( 'medium' ); + const { __experimentalSetPreviewDeviceType: setPreviewDeviceType } = useDispatch( editSiteStore ); const disableMotion = useReducedMotion(); @@ -96,6 +103,18 @@ export default function HeaderEditMode( { setListViewToggleElement } ) { const isZoomedOutView = blockEditorMode === 'zoom-out'; + const [ isBlockToolsCollapsed, setIsBlockToolsCollapsed ] = + useState( true ); + + const hasBlockSelected = !! blockSelectionStart; + + useEffect( () => { + // If we have a new block selection, show the block tools + if ( blockSelectionStart ) { + setIsBlockToolsCollapsed( false ); + } + }, [ blockSelectionStart ] ); + const toolbarVariants = { isDistractionFree: { y: '-50px' }, isDistractionFreeHovering: { y: 0 }, @@ -117,6 +136,7 @@ export default function HeaderEditMode( { setListViewToggleElement } ) { > { hasDefaultEditorCanvasView && ( @@ -127,17 +147,52 @@ export default function HeaderEditMode( { setListViewToggleElement } ) { setListViewToggleElement={ setListViewToggleElement } /> { hasFixedToolbar && ( - + <> + + { isLargeViewport && hasBlockSelected && ( +
From 238f4e5da10456bd89bd5f34162c627cb54baa6d Mon Sep 17 00:00:00 2001 From: Jerry Jones Date: Thu, 9 Nov 2023 11:28:14 -0600 Subject: [PATCH 15/20] Check for isZoomOutMode for site editor header --- packages/edit-site/src/components/header-edit-mode/index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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 9ec0121cf7258..782c8f8548e73 100644 --- a/packages/edit-site/src/components/header-edit-mode/index.js +++ b/packages/edit-site/src/components/header-edit-mode/index.js @@ -54,6 +54,7 @@ export default function HeaderEditMode( { setListViewToggleElement } ) { showIconLabels, editorCanvasView, hasFixedToolbar, + isZoomOutMode, } = useSelect( ( select ) => { const { __experimentalGetPreviewDeviceType, getEditedPostType } = select( editSiteStore ); @@ -89,10 +90,12 @@ export default function HeaderEditMode( { setListViewToggleElement } ) { editSiteStore.name, 'distractionFree' ), + isZoomOutMode: __unstableGetEditorMode() === 'zoom-out', }; }, [] ); const isLargeViewport = useViewportMatch( 'large' ); + const isTopToolbar = ! isZoomOutMode && hasFixedToolbar && isLargeViewport; const blockToolbarRef = useRef(); const { __experimentalSetPreviewDeviceType: setPreviewDeviceType } = @@ -148,7 +151,7 @@ export default function HeaderEditMode( { setListViewToggleElement } ) { showIconLabels={ showIconLabels } setListViewToggleElement={ setListViewToggleElement } /> - { hasFixedToolbar && isLargeViewport && ( + { isTopToolbar && ( <>
Date: Thu, 9 Nov 2023 15:27:10 -0600 Subject: [PATCH 16/20] Fix edit post edit template header layout Adds the collapse button and styles for collapsing the block tools and hiding the center area. --- .../src/components/block-tools/style.scss | 10 --- .../header/document-actions/index.js | 11 +-- .../edit-post/src/components/header/index.js | 74 +++++++++++++++++-- .../src/components/header/style.scss | 13 ++++ 4 files changed, 84 insertions(+), 24 deletions(-) diff --git a/packages/block-editor/src/components/block-tools/style.scss b/packages/block-editor/src/components/block-tools/style.scss index 2cb2edaf1a9c7..07f22bb4946ea 100644 --- a/packages/block-editor/src/components/block-tools/style.scss +++ b/packages/block-editor/src/components/block-tools/style.scss @@ -118,16 +118,6 @@ } } - // Add a scrim to the right of the collapsed button. - &.is-collapsed::after { - content: ""; - position: absolute; - left: 100%; - width: $grid-unit-60; - height: 100%; - background: linear-gradient(to right, $white, transparent); - } - @include break-medium() { &.is-fixed { & > .block-editor-block-toolbar { diff --git a/packages/edit-post/src/components/header/document-actions/index.js b/packages/edit-post/src/components/header/document-actions/index.js index 52df978e2cd5b..105b31e3122ac 100644 --- a/packages/edit-post/src/components/header/document-actions/index.js +++ b/packages/edit-post/src/components/header/document-actions/index.js @@ -20,21 +20,18 @@ import { displayShortcut } from '@wordpress/keycodes'; import { store as editPostStore } from '../../../store'; function DocumentActions() { - const { template, isEditing } = useSelect( ( select ) => { - const { isEditingTemplate, getEditedPostTemplate } = - select( editPostStore ); - const _isEditing = isEditingTemplate(); + const { template } = useSelect( ( select ) => { + const { getEditedPostTemplate } = select( editPostStore ); return { - template: _isEditing ? getEditedPostTemplate() : null, - isEditing: _isEditing, + template: getEditedPostTemplate(), }; }, [] ); const { clearSelectedBlock } = useDispatch( blockEditorStore ); const { setIsEditingTemplate } = useDispatch( editPostStore ); const { open: openCommandCenter } = useDispatch( commandsStore ); - if ( ! isEditing || ! template ) { + if ( ! template ) { return null; } diff --git a/packages/edit-post/src/components/header/index.js b/packages/edit-post/src/components/header/index.js index cb555b2e9f05c..1ff9c3e1dd37c 100644 --- a/packages/edit-post/src/components/header/index.js +++ b/packages/edit-post/src/components/header/index.js @@ -1,14 +1,27 @@ /** - * WordPress dependencies + * External dependencies */ +import classnames from 'classnames'; -import { BlockContextualToolbar } from '@wordpress/block-editor'; +/** + * WordPress dependencies + */ +import { + BlockContextualToolbar, + store as blockEditorStore, +} from '@wordpress/block-editor'; import { PostSavedState, PostPreviewButton } from '@wordpress/editor'; -import { useRef } from '@wordpress/element'; +import { useEffect, useRef, useState } from '@wordpress/element'; import { useSelect } from '@wordpress/data'; +import { __ } from '@wordpress/i18n'; +import { next, previous } from '@wordpress/icons'; import { PinnedItems } from '@wordpress/interface'; import { useViewportMatch } from '@wordpress/compose'; -import { __unstableMotion as motion, Popover } from '@wordpress/components'; +import { + Button, + __unstableMotion as motion, + Popover, +} from '@wordpress/components'; import { store as preferencesStore } from '@wordpress/preferences'; /** @@ -43,15 +56,20 @@ function Header( { const isLargeViewport = useViewportMatch( 'large' ); const blockToolbarRef = useRef(); const { + blockSelectionStart, hasActiveMetaboxes, hasFixedToolbar, + isEditingTemplate, isPublishSidebarOpened, showIconLabels, } = useSelect( ( select ) => { const { get: getPreference } = select( preferencesStore ); return { + blockSelectionStart: + select( blockEditorStore ).getBlockSelectionStart(), hasActiveMetaboxes: select( editPostStore ).hasMetaBoxes(), + isEditingTemplate: select( editPostStore ).isEditingTemplate(), isPublishSidebarOpened: select( editPostStore ).isPublishSidebarOpened(), hasFixedToolbar: getPreference( 'core/edit-post', 'fixedToolbar' ), @@ -60,6 +78,18 @@ function Header( { }; }, [] ); + const [ isBlockToolsCollapsed, setIsBlockToolsCollapsed ] = + useState( true ); + + const hasBlockSelected = !! blockSelectionStart; + + useEffect( () => { + // If we have a new block selection, show the block tools + if ( blockSelectionStart ) { + setIsBlockToolsCollapsed( false ); + } + }, [ blockSelectionStart ] ); + return (
@@ -81,17 +111,47 @@ function Header( { /> { hasFixedToolbar && isLargeViewport && ( <> -
+
+ { isEditingTemplate && hasBlockSelected && ( +