From 920598e488891219d39647b345a64928c4e0f9ae Mon Sep 17 00:00:00 2001 From: Mitchell Austin Date: Mon, 22 Jul 2024 07:24:14 -0700 Subject: [PATCH] Editor: Improve Header layout (#62636) * Revise header for resilient centering * Better match existing responsiveness * Fix naming typo * Remove padding from header center to make just a bit more room * Revise style to add space before collapsible block toolbar * Account for potential lack of a back button * Post editor: Leave out the back button instead of hiding it * Hide post preview button at less than small breakpoint * Try keeping the Document Bar visible at less than mobile breakpoints * Revert change to display of post preview button * Revise mobile display of Document Bar * Revert conditional rendering changes * Remove has-back-button class name * Remove has-center class name Co-authored-by: stokesman Co-authored-by: jeryj Co-authored-by: Mamaduka Co-authored-by: youknowriad Co-authored-by: jasmussen Co-authored-by: jameskoster Co-authored-by: richtabor --- .../back-button/fullscreen-mode-close.js | 14 +-- .../src/components/back-button/style.scss | 4 - .../edit-post/src/components/layout/index.js | 9 +- .../collapsible-block-toolbar/index.js | 4 +- .../collapsible-block-toolbar/style.scss | 3 - .../src/components/document-bar/style.scss | 6 +- .../src/components/document-tools/style.scss | 8 +- .../src/components/header/back-button.js | 12 +-- .../editor/src/components/header/index.js | 51 +++++------ .../editor/src/components/header/style.scss | 85 ++++++++++++++----- 10 files changed, 113 insertions(+), 83 deletions(-) diff --git a/packages/edit-post/src/components/back-button/fullscreen-mode-close.js b/packages/edit-post/src/components/back-button/fullscreen-mode-close.js index 59694de16cb925..02eaceb3a35e50 100644 --- a/packages/edit-post/src/components/back-button/fullscreen-mode-close.js +++ b/packages/edit-post/src/components/back-button/fullscreen-mode-close.js @@ -19,23 +19,16 @@ import { store as editorStore } from '@wordpress/editor'; import { store as coreStore } from '@wordpress/core-data'; import { useReducedMotion } from '@wordpress/compose'; -/** - * Internal dependencies - */ -import { store as editPostStore } from '../../store'; - function FullscreenModeClose( { showTooltip, icon, href, initialPost } ) { - const { isActive, isRequestingSiteIcon, postType, siteIconUrl } = useSelect( + const { isRequestingSiteIcon, postType, siteIconUrl } = useSelect( ( select ) => { const { getCurrentPostType } = select( editorStore ); - const { isFeatureActive } = select( editPostStore ); const { getEntityRecord, getPostType, isResolving } = select( coreStore ); const siteData = getEntityRecord( 'root', '__unstableBase', undefined ) || {}; const _postType = initialPost?.type || getCurrentPostType(); return { - isActive: isFeatureActive( 'fullscreenMode' ), isRequestingSiteIcon: isResolving( 'getEntityRecord', [ 'root', '__unstableBase', @@ -50,7 +43,7 @@ function FullscreenModeClose( { showTooltip, icon, href, initialPost } ) { const disableMotion = useReducedMotion(); - if ( ! isActive || ! postType ) { + if ( ! postType ) { return null; } @@ -83,8 +76,7 @@ function FullscreenModeClose( { showTooltip, icon, href, initialPost } ) { buttonIcon = ; } - const classes = clsx( { - 'edit-post-fullscreen-mode-close': true, + const classes = clsx( 'edit-post-fullscreen-mode-close', { 'has-icon': siteIconUrl, } ); diff --git a/packages/edit-post/src/components/back-button/style.scss b/packages/edit-post/src/components/back-button/style.scss index d6455c707fb1d9..8ffae89e31e054 100644 --- a/packages/edit-post/src/components/back-button/style.scss +++ b/packages/edit-post/src/components/back-button/style.scss @@ -2,10 +2,6 @@ // They need to be updated in both places. .edit-post-fullscreen-mode-close.components-button { - // Do not show the toolbar icon on small screens, - // when Fullscreen Mode is not an option in the "More" menu. - display: none; - @include break-medium() { display: flex; align-items: center; diff --git a/packages/edit-post/src/components/layout/index.js b/packages/edit-post/src/components/layout/index.js index b6ab4629b9e213..9266cbbb10a557 100644 --- a/packages/edit-post/src/components/layout/index.js +++ b/packages/edit-post/src/components/layout/index.js @@ -37,6 +37,7 @@ import { addQueryArgs } from '@wordpress/url'; import { decodeEntities } from '@wordpress/html-entities'; import { store as coreStore } from '@wordpress/core-data'; import { SlotFillProvider } from '@wordpress/components'; +import { useViewportMatch } from '@wordpress/compose'; /** * Internal dependencies @@ -327,6 +328,12 @@ function Layout( { id: initialPostId, }; }, [ initialPostType, initialPostId ] ); + + const backButton = + useViewportMatch( 'medium' ) && isFullscreenActive ? ( + + ) : null; + return ( @@ -373,7 +380,7 @@ function Layout( { - + { backButton } diff --git a/packages/editor/src/components/collapsible-block-toolbar/index.js b/packages/editor/src/components/collapsible-block-toolbar/index.js index 87d9b6473d8b61..cafbfecb72516c 100644 --- a/packages/editor/src/components/collapsible-block-toolbar/index.js +++ b/packages/editor/src/components/collapsible-block-toolbar/index.js @@ -24,7 +24,7 @@ import { unlock } from '../../lock-unlock'; const { useHasBlockToolbar } = unlock( blockEditorPrivateApis ); -function CollapsableBlockToolbar( { isCollapsed, onToggle } ) { +export default function CollapsibleBlockToolbar( { isCollapsed, onToggle } ) { const { blockSelectionStart } = useSelect( ( select ) => { return { blockSelectionStart: @@ -73,5 +73,3 @@ function CollapsableBlockToolbar( { isCollapsed, onToggle } ) { ); } - -export default CollapsableBlockToolbar; diff --git a/packages/editor/src/components/collapsible-block-toolbar/style.scss b/packages/editor/src/components/collapsible-block-toolbar/style.scss index 18fdc556681449..f559e1a055cdcd 100644 --- a/packages/editor/src/components/collapsible-block-toolbar/style.scss +++ b/packages/editor/src/components/collapsible-block-toolbar/style.scss @@ -77,6 +77,3 @@ } } -.editor-collapsible-block-toolbar__toggle { - margin-left: 2px; // Allow focus ring to be fully visible -} diff --git a/packages/editor/src/components/document-bar/style.scss b/packages/editor/src/components/document-bar/style.scss index 7e51605ad30280..dedf05bc8e7d4f 100644 --- a/packages/editor/src/components/document-bar/style.scss +++ b/packages/editor/src/components/document-bar/style.scss @@ -10,7 +10,7 @@ min-width: 0; background: $gray-100; border-radius: $grid-unit-05; - width: min(100%, 416px); + width: min(100%, 450px); &:hover { background-color: $gray-200; @@ -25,10 +25,6 @@ background: $gray-200; } } - - @include break-large() { - width: min(100%, 450px); - } } .editor-document-bar__command { diff --git a/packages/editor/src/components/document-tools/style.scss b/packages/editor/src/components/document-tools/style.scss index 36c643bbaa027e..a1abfd5abd7aef 100644 --- a/packages/editor/src/components/document-tools/style.scss +++ b/packages/editor/src/components/document-tools/style.scss @@ -65,12 +65,12 @@ .editor-document-tools__left { display: inline-flex; align-items: center; - padding-left: $grid-unit-20; gap: $grid-unit-10; - // Some plugins add buttons here despite best practices. - // Push them a bit rightwards to fit the top toolbar. - margin-right: $grid-unit-10; + // Some plugins add buttons here despite best practices — accommodate them with a gap. + &:not(:last-child) { + margin-inline-end: $grid-unit-10; + } } .editor-document-tools .editor-document-tools__left > .editor-document-tools__inserter-toggle.has-icon { diff --git a/packages/editor/src/components/header/back-button.js b/packages/editor/src/components/header/back-button.js index 3ac689c8415264..a3d682f92970ed 100644 --- a/packages/editor/src/components/header/back-button.js +++ b/packages/editor/src/components/header/back-button.js @@ -9,16 +9,16 @@ import { // Keeping an old name for backward compatibility. const slotName = '__experimentalMainDashboardButton'; +export const useHasBackButton = () => { + const fills = useSlotFills( slotName ); + return Boolean( fills && fills.length ); +}; + const { Fill, Slot } = createSlotFill( slotName ); const BackButton = Fill; -const BackButtonSlot = ( { children } ) => { +const BackButtonSlot = () => { const fills = useSlotFills( slotName ); - const hasFills = Boolean( fills && fills.length ); - - if ( ! hasFills ) { - return children; - } return ( - - - + { hasBackButton && ( + + + + ) } - { hasTopToolbar && ( - ) } -
+ { hasCenter && ( + -
-
+ + ) } .editor-header__center) { + grid-template: auto / $header-height min-content 1fr min-content $header-height; + @include break-medium { + grid-template: auto / $header-height minmax(min-content, 1fr) 2fr minmax(min-content, 1fr) $header-height; + } + } + @include break-mobile { + gap: $grid-unit-20; + } 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; @@ -15,19 +25,32 @@ } .editor-header__toolbar { + grid-column: 1 / 3; + // When there is no back button or the viewport is <= mobile the margin keeps the content off + // the starting edge. + > :first-child { + margin-inline: $grid-unit-20 0; + } + + // This is the typical case, the back button takes up the first column. + .editor-header__back-button + & { + grid-column: 2 / 3; + + @include break-mobile { + // Clears the margin; at this breakpoint the parent’s `gap` takes its place. + > :first-child { + margin-inline: 0; + } + } + } 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; + // Make narrowing to less than content width possible. Block toolbar will hide overflow and allow scrolling on fixed toolbar. + min-width: 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); + // Clip the box while leaving room for focus rings. + clip-path: inset(-2px); + @include break-mobile { + clip-path: none; } .table-of-contents { @@ -37,20 +60,35 @@ display: block; } } + + // Add a gap before the block toolbar or its toggle button when collapsed. + .editor-collapsible-block-toolbar { + margin-inline: $grid-unit 0; + + &.is-collapsed ~ .editor-collapsible-block-toolbar__toggle { + margin-inline: $grid-unit 0; + } + } } .editor-header__center { - flex-grow: 1; + grid-column: 3 / 4; display: flex; 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 + align-items: center; + // To enable shrinking and truncating of child text, apply an explicit min-width. min-width: 0; - - &.is-collapsed { - display: none; + // Clip the box while leaving room for focus rings. + clip-path: inset(-2px); + // At less than mobile the header’s `gap` is zero so margins are added to create a smaller + // gap around the center’s contents. + @media (max-width: #{$break-mobile - 1}) { + > :first-child { + margin-inline-start: $grid-unit; + } + > :last-child { + margin-inline-end: $grid-unit; + } } } @@ -59,6 +97,11 @@ */ .editor-header__settings { + grid-column: 3 / -1; + .editor-header:has(> .editor-header__center) & { + grid-column: 4 / -1; + } + justify-self: end; display: inline-flex; align-items: center; flex-wrap: nowrap;