diff --git a/packages/block-editor/src/components/block-toolbar/style.scss b/packages/block-editor/src/components/block-toolbar/style.scss index 0b49c9299212f..eef1678e2dfab 100644 --- a/packages/block-editor/src/components/block-toolbar/style.scss +++ b/packages/block-editor/src/components/block-toolbar/style.scss @@ -252,6 +252,16 @@ flex-shrink: 1; } + @include break-medium() { + .block-editor-block-contextual-toolbar.is-fixed { + .components-toolbar, + .components-toolbar-group { + flex-shrink: 0; + } + } + } + + .block-editor-rich-text__inline-format-toolbar-group { .components-button + .components-button { margin-left: 6px; 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 9667cb21d99b7..455ea6e569277 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,7 +7,12 @@ import classnames from 'classnames'; * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { useEffect, useRef, useState } from '@wordpress/element'; +import { + useLayoutEffect, + useEffect, + useRef, + useState, +} from '@wordpress/element'; import { hasBlockSupport, store as blocksStore } from '@wordpress/blocks'; import { useSelect } from '@wordpress/data'; import { @@ -78,6 +83,77 @@ function BlockContextualToolbar( { focusOnMount, isFixed, ...props } ) { setIsCollapsed( false ); }, [ selectedBlockClientId ] ); + const isLargerThanTabletViewport = useViewportMatch( 'large', '>=' ); + const isFullscreen = + document.body.classList.contains( 'is-fullscreen-mode' ); + + useLayoutEffect( () => { + // don't do anything if not fixed toolbar + if ( ! isFixed || ! blockType ) { + return; + } + + const blockToolbar = document.querySelector( + '.block-editor-block-contextual-toolbar' + ); + + if ( ! blockToolbar ) { + 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 + const pinnedItems = document.querySelector( + '.edit-post-header__settings' + ); + + // 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 ) + 10 // 10 is the pinned items padding + : 0; + const leftHeaderWidth = computedLeftHeaderStyle + ? parseFloat( computedLeftHeaderStyle.width ) + : 0; + + // set the new witdth of the toolbar + blockToolbar.style.width = `calc(100% - ${ + leftHeaderWidth + + pinnedItemsWidth + + marginLeft + + ( 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/block-editor/src/components/block-tools/style.scss b/packages/block-editor/src/components/block-tools/style.scss index 828e1ebe9b348..6a987929dffb7 100644 --- a/packages/block-editor/src/components/block-tools/style.scss +++ b/packages/block-editor/src/components/block-tools/style.scss @@ -110,6 +110,12 @@ z-index: z-index(".block-editor-block-popover"); display: block; width: 100%; + overflow: hidden; + + .block-editor-block-toolbar { + overflow: auto; + overflow-y: hidden; + } border: none; border-bottom: $border-width solid $gray-200; @@ -133,14 +139,14 @@ // 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() { &.is-fixed { - // leave room for block inserter, undo and redo, list view - margin-left: $grid-unit-80 * 3 - 2 * $grid-unit + $grid-unit-05; + margin-left: $toolbar-margin; // position on top of interface header position: fixed; - top: $admin-bar-height + $grid-unit - $border-width; + top: $admin-bar-height; // Don't fill up when empty min-height: initial; // remove the border @@ -148,18 +154,32 @@ // 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; + &.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: $grid-unit - $border-width; + + top: 0; + &.is-collapsed { width: initial; } + + &:empty { + width: initial; + } } & > .block-editor-block-toolbar.is-showing-movers { @@ -245,7 +265,7 @@ .show-icon-labels & { - margin-left: $grid-unit-80 + 2 * $grid-unit; // inserter and margin ; + margin-left: $grid-unit-80 + 2 * $grid-unit; // inserter and margin .is-fullscreen-mode & { margin-left: $grid-unit * 18; // site hub, inserter and margin @@ -318,7 +338,12 @@ // except for the inserter on the left @include break-medium() { &.is-fixed { - width: 100%; + width: calc(100% - #{$toolbar-margin}); + + .show-icon-labels & { + width: calc(100% + 40px - #{$toolbar-margin}); //there are no undo, redo and list view buttons + } + } } @@ -328,6 +353,9 @@ @include break-large() { &.is-fixed { width: auto; + .show-icon-labels & { + width: auto; //there are no undo, redo and list view buttons + } } .is-fullscreen-mode &.is-fixed { // in full screen mode we need to account for