From a1d941e23033efc3a8a5147a67451bdbb03f188b Mon Sep 17 00:00:00 2001 From: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Date: Tue, 6 Jun 2023 14:06:40 +1000 Subject: [PATCH] Styles Screen: Add link to global styles revisions (#51149) * Styles Screen: Add link to global styles revisions * Add button label * Update packages/edit-site/src/components/global-styles/ui.js Co-authored-by: Ramon <ramonjd@users.noreply.github.com> * Small code quality improvements * Try sticking the navigation screen footer to the bottom of the screen at all times * Add as span to the HStack * Update border radius and left padding so that the button lines up * Remove classnames call * Add redirect for style book, too * Only redirect to root when opening the style book on the revisions screen * Use truthy check for editor canvas container when redirecting from the revisions screen. Co-authored-by: ramon <ramonjd@gmail.com> --------- Co-authored-by: Ramon <ramonjd@users.noreply.github.com> Co-authored-by: ramon <ramonjd@gmail.com> --- .../src/components/global-styles/ui.js | 28 ++++ .../index.js | 100 ++++++++++++-- .../style.scss | 15 ++ .../sidebar-navigation-screen-page/index.js | 2 +- .../sidebar-navigation-screen-page/style.scss | 6 + .../sidebar-navigation-screen/index.js | 128 +++++++++--------- .../sidebar-navigation-screen/style.scss | 13 ++ .../src/components/sidebar/style.scss | 3 + packages/edit-site/src/style.scss | 1 + 9 files changed, 222 insertions(+), 74 deletions(-) create mode 100644 packages/edit-site/src/components/sidebar-navigation-screen-global-styles/style.scss diff --git a/packages/edit-site/src/components/global-styles/ui.js b/packages/edit-site/src/components/global-styles/ui.js index f15fcff11aa560..953904e314928c 100644 --- a/packages/edit-site/src/components/global-styles/ui.js +++ b/packages/edit-site/src/components/global-styles/ui.js @@ -237,6 +237,33 @@ function GlobalStylesBlockLink() { }, [ selectedBlockClientId, selectedBlockName, blockHasGlobalStyles ] ); } +function GlobalStylesEditorCanvasContainerLink() { + const { goTo, location } = useNavigator(); + const editorCanvasContainerView = useSelect( + ( select ) => + unlock( select( editSiteStore ) ).getEditorCanvasContainerView(), + [] + ); + + // If the user switches the editor canvas container view, redirect + // to the appropriate screen. This effectively allows deep linking to the + // desired screens from outside the global styles navigation provider. + useEffect( () => { + if ( editorCanvasContainerView === 'global-styles-revisions' ) { + // Switching to the revisions container view should + // redirect to the revisions screen. + goTo( '/revisions' ); + } else if ( + !! editorCanvasContainerView && + location?.path === '/revisions' + ) { + // Switching to any container other than revisions should + // redirect from the revisions screen to the root global styles screen. + goTo( '/' ); + } + }, [ editorCanvasContainerView, location?.path, goTo ] ); +} + function GlobalStylesUI() { const blocks = getBlockTypes(); const editorCanvasContainerView = useSelect( @@ -326,6 +353,7 @@ function GlobalStylesUI() { <GlobalStylesActionMenu /> <GlobalStylesBlockLink /> + <GlobalStylesEditorCanvasContainerLink /> </NavigatorProvider> ); } diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js index 8e6f080e74a80a..926f8b8611af0d 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js @@ -2,12 +2,19 @@ * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { edit, seen } from '@wordpress/icons'; +import { backup, edit, seen } from '@wordpress/icons'; import { useSelect, useDispatch } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; -import { __experimentalNavigatorButton as NavigatorButton } from '@wordpress/components'; +import { + Icon, + __experimentalNavigatorButton as NavigatorButton, + __experimentalVStack as HStack, + __experimentalVStack as VStack, +} from '@wordpress/components'; import { useViewportMatch } from '@wordpress/compose'; import { BlockEditorProvider } from '@wordpress/block-editor'; +import { humanTimeDiff } from '@wordpress/date'; +import { useCallback } from '@wordpress/element'; /** * Internal dependencies @@ -19,6 +26,7 @@ import { store as editSiteStore } from '../../store'; import SidebarButton from '../sidebar-button'; import SidebarNavigationItem from '../sidebar-navigation-item'; import StyleBook from '../style-book'; +import useGlobalStylesRevisions from '../global-styles/screen-revisions/use-global-styles-revisions'; const noop = () => {}; @@ -74,13 +82,64 @@ function SidebarNavigationScreenGlobalStylesContent() { onChange={ noop } onInput={ noop } > - <div className="edit-site-sidebar-navigation-screen-global-styles__content"> - <StyleVariationsContainer /> - </div> + <StyleVariationsContainer /> </BlockEditorProvider> ); } +function SidebarNavigationScreenGlobalStylesFooter( { onClickRevisions } ) { + const { revisions, isLoading } = useGlobalStylesRevisions(); + const { revisionsCount } = useSelect( ( select ) => { + const { getEntityRecord, __experimentalGetCurrentGlobalStylesId } = + select( coreStore ); + + const globalStylesId = __experimentalGetCurrentGlobalStylesId(); + const globalStyles = globalStylesId + ? getEntityRecord( 'root', 'globalStyles', globalStylesId ) + : undefined; + + return { + revisionsCount: + globalStyles?._links?.[ 'version-history' ]?.[ 0 ]?.count ?? 0, + }; + }, [] ); + + const hasRevisions = revisionsCount >= 2; + const modified = revisions?.[ 0 ]?.modified; + + if ( ! hasRevisions || isLoading || ! modified ) { + return null; + } + + return ( + <VStack className="edit-site-sidebar-navigation-screen-global-styles__footer"> + <SidebarNavigationItem + className="edit-site-sidebar-navigation-screen-global-styles__revisions" + label={ __( 'Revisions' ) } + onClick={ onClickRevisions } + > + <HStack + as="span" + alignment="center" + spacing={ 5 } + direction="row" + justify="space-between" + > + <span className="edit-site-sidebar-navigation-screen-global-styles__revisions__label"> + { __( 'Last modified' ) } + </span> + <span> + <time dateTime={ modified }> + { humanTimeDiff( modified ) } + </time> + </span> + <Icon icon={ backup } style={ { fill: 'currentcolor' } } /> + </HStack> + </SidebarNavigationItem> + </VStack> + ); +} + export default function SidebarNavigationScreenGlobalStyles() { const { openGeneralSidebar } = useDispatch( editSiteStore ); const isMobileViewport = useViewportMatch( 'medium', '<' ); @@ -95,19 +154,31 @@ export default function SidebarNavigationScreenGlobalStyles() { [] ); - const openGlobalStyles = async () => - Promise.all( [ - setCanvasMode( 'edit' ), - openGeneralSidebar( 'edit-site/global-styles' ), - ] ); + const openGlobalStyles = useCallback( + async () => + Promise.all( [ + setCanvasMode( 'edit' ), + openGeneralSidebar( 'edit-site/global-styles' ), + ] ), + [ setCanvasMode, openGeneralSidebar ] + ); - const openStyleBook = async () => { + const openStyleBook = useCallback( async () => { await openGlobalStyles(); // Open the Style Book once the canvas mode is set to edit, // and the global styles sidebar is open. This ensures that // the Style Book is not prematurely closed. setEditorCanvasContainerView( 'style-book' ); - }; + }, [ openGlobalStyles, setEditorCanvasContainerView ] ); + + const openRevisions = useCallback( async () => { + await openGlobalStyles(); + // Open the global styles revisions once the canvas mode is set to edit, + // and the global styles sidebar is open. The global styles UI is responsible + // for redirecting to the revisions screen once the editor canvas container + // has been set to 'global-styles-revisions'. + setEditorCanvasContainerView( 'global-styles-revisions' ); + }, [ openGlobalStyles, setEditorCanvasContainerView ] ); return ( <> @@ -117,6 +188,11 @@ export default function SidebarNavigationScreenGlobalStyles() { 'Choose a different style combination for the theme styles.' ) } content={ <SidebarNavigationScreenGlobalStylesContent /> } + footer={ + <SidebarNavigationScreenGlobalStylesFooter + onClickRevisions={ openRevisions } + /> + } actions={ <> { ! isMobileViewport && ( diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/style.scss b/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/style.scss new file mode 100644 index 00000000000000..26ac157cb24bef --- /dev/null +++ b/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/style.scss @@ -0,0 +1,15 @@ +.edit-site-sidebar-navigation-screen-global-styles__footer { + padding-left: $grid-unit-15; +} + +.edit-site-sidebar-navigation-screen-global-styles__revisions { + border-radius: $radius-block-ui; + + &:not(:hover) { + color: $gray-200; + + .edit-site-sidebar-navigation-screen-global-styles__revisions__label { + color: $gray-600; + } + } +} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-page/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-page/index.js index 5e0c113b3544ad..176470b3576b84 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-page/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-page/index.js @@ -147,7 +147,7 @@ export default function SidebarNavigationScreenPage() { <HStack spacing={ 5 } alignment="left" - className="edit-site-sidebar-navigation-screen-page__details" + className="edit-site-sidebar-navigation-screen-page__details edit-site-sidebar-navigation-screen-page__footer" > <Text className="edit-site-sidebar-navigation-screen-page__details-label"> { __( 'Last modified' ) } diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-page/style.scss b/packages/edit-site/src/components/sidebar-navigation-screen-page/style.scss index 6ec9e565f9e8ff..c58e9f09392465 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-page/style.scss +++ b/packages/edit-site/src/components/sidebar-navigation-screen-page/style.scss @@ -61,6 +61,12 @@ } } +.edit-site-sidebar-navigation-screen-page__footer { + padding-top: $grid-unit-10; + padding-bottom: $grid-unit-10; + padding-left: $grid-unit-20; +} + .edit-site-sidebar-navigation-screen-page__details { .edit-site-sidebar-navigation-screen-page__details-label { color: $gray-600; diff --git a/packages/edit-site/src/components/sidebar-navigation-screen/index.js b/packages/edit-site/src/components/sidebar-navigation-screen/index.js index 67e22721e78f0b..026cbaba8e860f 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen/index.js @@ -42,74 +42,80 @@ export default function SidebarNavigationScreen( { const theme = getTheme( currentlyPreviewingTheme() ); return ( - <VStack spacing={ 0 }> - <HStack - spacing={ 4 } - alignment="flex-start" - className="edit-site-sidebar-navigation-screen__title-icon" + <> + <VStack + className="edit-site-sidebar-navigation-screen__main" + spacing={ 0 } + justify="flex-start" > - { ! isRoot ? ( - <NavigatorToParentButton - as={ SidebarButton } - icon={ isRTL() ? chevronRight : chevronLeft } - label={ __( 'Back' ) } - /> - ) : ( - <SidebarButton - icon={ isRTL() ? chevronRight : chevronLeft } - label={ - ! isPreviewingTheme() - ? __( 'Go back to the Dashboard' ) - : __( 'Go back to the theme showcase' ) - } - href={ - ! isPreviewingTheme() - ? dashboardLink || 'index.php' - : 'themes.php' - } - /> - ) } - <Heading - className="edit-site-sidebar-navigation-screen__title" - color={ 'white' } - level={ 2 } - size={ 20 } + <HStack + spacing={ 4 } + alignment="flex-start" + className="edit-site-sidebar-navigation-screen__title-icon" > - { ! isPreviewingTheme() - ? title - : sprintf( - 'Previewing %1$s: %2$s', - theme?.name?.rendered, - title - ) } - </Heading> - { actions && ( - <div className="edit-site-sidebar-navigation-screen__actions"> - { actions } - </div> + { ! isRoot ? ( + <NavigatorToParentButton + as={ SidebarButton } + icon={ isRTL() ? chevronRight : chevronLeft } + label={ __( 'Back' ) } + /> + ) : ( + <SidebarButton + icon={ isRTL() ? chevronRight : chevronLeft } + label={ + ! isPreviewingTheme() + ? __( 'Go back to the Dashboard' ) + : __( 'Go back to the theme showcase' ) + } + href={ + ! isPreviewingTheme() + ? dashboardLink || 'index.php' + : 'themes.php' + } + /> + ) } + <Heading + className="edit-site-sidebar-navigation-screen__title" + color={ 'white' } + level={ 2 } + size={ 20 } + > + { ! isPreviewingTheme() + ? title + : sprintf( + 'Previewing %1$s: %2$s', + theme?.name?.rendered, + title + ) } + </Heading> + { actions && ( + <div className="edit-site-sidebar-navigation-screen__actions"> + { actions } + </div> + ) } + </HStack> + { meta && ( + <> + <div className="edit-site-sidebar-navigation-screen__meta"> + { meta } + </div> + </> ) } - </HStack> - { meta && ( - <> - <div className="edit-site-sidebar-navigation-screen__meta"> - { meta } - </div> - </> - ) } - <nav className="edit-site-sidebar-navigation-screen__content"> - { description && ( - <p className="edit-site-sidebar-navigation-screen__description"> - { description } - </p> - ) } - { content } - </nav> + <nav className="edit-site-sidebar-navigation-screen__content"> + { description && ( + <p className="edit-site-sidebar-navigation-screen__description"> + { description } + </p> + ) } + { content } + </nav> + </VStack> { footer && ( - <footer className="edit-site-sidebar-navigation-screen__sticky-section"> + <footer className="edit-site-sidebar-navigation-screen__footer"> { footer } </footer> ) } - </VStack> + </> ); } diff --git a/packages/edit-site/src/components/sidebar-navigation-screen/style.scss b/packages/edit-site/src/components/sidebar-navigation-screen/style.scss index 111b2650e41256..713a3ca1449e65 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen/style.scss +++ b/packages/edit-site/src/components/sidebar-navigation-screen/style.scss @@ -5,6 +5,12 @@ position: relative; } +.edit-site-sidebar-navigation-screen__main { + // Ensure the sidebar is always at least as tall as the viewport. + // This allows the footer section to be sticky at the bottom of the viewport. + flex-grow: 1; +} + .edit-site-sidebar-navigation-screen__content { margin: 0 0 $grid-unit-20 0; color: $gray-400; @@ -86,3 +92,10 @@ margin: $grid-unit-40 $grid-unit-20; border-top: 1px solid $gray-800; } + +.edit-site-sidebar-navigation-screen__footer { + position: sticky; + bottom: 0; + background-color: $gray-900; + padding: $grid-unit-20 0; +} diff --git a/packages/edit-site/src/components/sidebar/style.scss b/packages/edit-site/src/components/sidebar/style.scss index 03d4410941167e..9a3644cc830d56 100644 --- a/packages/edit-site/src/components/sidebar/style.scss +++ b/packages/edit-site/src/components/sidebar/style.scss @@ -5,6 +5,9 @@ .components-navigator-screen { @include custom-scrollbars-on-hover(transparent, $gray-700); scrollbar-gutter: stable; + display: flex; + flex-direction: column; + height: 100%; } } diff --git a/packages/edit-site/src/style.scss b/packages/edit-site/src/style.scss index e31978cf0f45df..1004684c17cc2c 100644 --- a/packages/edit-site/src/style.scss +++ b/packages/edit-site/src/style.scss @@ -27,6 +27,7 @@ @import "./components/sidebar-button/style.scss"; @import "./components/sidebar-navigation-item/style.scss"; @import "./components/sidebar-navigation-screen/style.scss"; +@import "./components/sidebar-navigation-screen-global-styles/style.scss"; @import "./components/sidebar-navigation-screen-page/style.scss"; @import "./components/sidebar-navigation-screen-template/style.scss"; @import "./components/sidebar-navigation-screen-templates/style.scss";