diff --git a/packages/e2e-tests/specs/experiments/navigation-editor.test.js b/packages/e2e-tests/specs/experiments/navigation-editor.test.js index 0002e78a12e1e..db7a560055f1a 100644 --- a/packages/e2e-tests/specs/experiments/navigation-editor.test.js +++ b/packages/e2e-tests/specs/experiments/navigation-editor.test.js @@ -126,7 +126,7 @@ describe( 'Navigation editor', () => { await visitNavigationEditor(); // Wait for the header to show that no menus are available. - await page.waitForXPath( '//h2[contains(., "No menus available")]', { + await page.waitForXPath( '//h3[.="Create your first menu"]', { visible: true, } ); @@ -139,21 +139,12 @@ describe( 'Navigation editor', () => { ...getMenuItemMocks( { GET: [] } ), ] ); - // Add a new menu. - const [ addNewButton ] = await page.$x( - '//button[contains(., "Add new")]' - ); - await addNewButton.click(); - await page.keyboard.type( 'Main Menu' ); const createMenuButton = await page.waitForXPath( '//button[contains(., "Create menu")]' ); await createMenuButton.click(); - // Close the dropdown. - await page.keyboard.press( 'Escape' ); - // A snackbar will appear when menu creation has completed. await page.waitForXPath( '//div[contains(., "Menu created")]' ); diff --git a/packages/edit-navigation/src/components/header/add-menu-form.js b/packages/edit-navigation/src/components/add-menu/index.js similarity index 72% rename from packages/edit-navigation/src/components/header/add-menu-form.js rename to packages/edit-navigation/src/components/add-menu/index.js index d46aa886ea427..a2170721ce7f6 100644 --- a/packages/edit-navigation/src/components/header/add-menu-form.js +++ b/packages/edit-navigation/src/components/add-menu/index.js @@ -2,7 +2,7 @@ * External dependencies */ import { some } from 'lodash'; - +import classnames from 'classnames'; /** * WordPress dependencies */ @@ -15,13 +15,10 @@ import { store as noticesStore } from '@wordpress/notices'; const menuNameMatches = ( menuName ) => ( menu ) => menu.name.toLowerCase() === menuName.toLowerCase(); -export default function AddMenuForm( { menus, onCreate } ) { +export default function AddMenu( { className, menus, onCreate } ) { const [ menuName, setMenuName ] = useState( '' ); - const { createErrorNotice, createInfoNotice } = useDispatch( noticesStore ); - const [ isCreatingMenu, setIsCreatingMenu ] = useState( false ); - const { saveMenu } = useDispatch( 'core' ); const createMenu = async ( event ) => { @@ -51,29 +48,43 @@ export default function AddMenuForm( { menus, onCreate } ) { type: 'snackbar', isDismissible: true, } ); - onCreate( menu.id ); + if ( onCreate ) { + onCreate( menu.id ); + } } setIsCreatingMenu( false ); }; + const hasMenus = menus?.length; + + const titleText = hasMenus + ? __( 'Create a new menu' ) + : __( 'Create your first menu' ); + + const helpText = hasMenus + ? __( 'A short descriptive name for your menu.' ) + : __( 'A short descriptive name for your first menu.' ); + return (
+

{ titleText }

- ) } - renderContent={ () => ( - - ) } - /> + ( + + ) } + renderContent={ () => ( + + ) } + /> - ( - - ) } - renderContent={ () => } - /> + ( + + ) } + renderContent={ () => } + /> - + - - + + + ) } ); } diff --git a/packages/edit-navigation/src/components/header/style.scss b/packages/edit-navigation/src/components/header/style.scss index 035e4133fc1c7..e6495ff532dea 100644 --- a/packages/edit-navigation/src/components/header/style.scss +++ b/packages/edit-navigation/src/components/header/style.scss @@ -25,6 +25,6 @@ display: flex; } -.edit-navigation-header__add-menu-form { +.edit-navigation-header__add-menu { min-width: 220px; } diff --git a/packages/edit-navigation/src/components/layout/empty-state.js b/packages/edit-navigation/src/components/layout/empty-state.js new file mode 100644 index 0000000000000..fd0d9b114bc81 --- /dev/null +++ b/packages/edit-navigation/src/components/layout/empty-state.js @@ -0,0 +1,19 @@ +/** + * WordPress dependencies + */ +import { Card, CardBody } from '@wordpress/components'; + +/** + * Internal dependencies + */ +import AddMenu from '../add-menu'; + +export default function EmptyState() { + return ( + + + + + + ); +} diff --git a/packages/edit-navigation/src/components/layout/index.js b/packages/edit-navigation/src/components/layout/index.js index db7883831a4ea..c773a79cfddf0 100644 --- a/packages/edit-navigation/src/components/layout/index.js +++ b/packages/edit-navigation/src/components/layout/index.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; + /** * WordPress dependencies */ @@ -5,6 +10,7 @@ import { DropZoneProvider, Popover, SlotFillProvider, + Spinner, } from '@wordpress/components'; import { useDispatch } from '@wordpress/data'; import { @@ -18,6 +24,7 @@ import { useRef } from '@wordpress/element'; /** * Internal dependencies */ +import EmptyState from './empty-state'; import useNavigationEditor from './use-navigation-editor'; import useNavigationBlockEditor from './use-navigation-block-editor'; import useMenuNotifications from './use-menu-notifications'; @@ -38,11 +45,12 @@ export default function Layout( { blockEditorSettings } ) { const { menus, + hasLoadedMenus, + hasFinishedInitialLoad, selectedMenuId, navigationPost, selectMenu, deleteMenu, - hasLoadedMenus, } = useNavigationEditor(); const [ blocks, onInput, onChange ] = useNavigationBlockEditor( @@ -51,6 +59,9 @@ export default function Layout( { blockEditorSettings } ) { useMenuNotifications( selectedMenuId ); + const hasMenus = !! menus?.length; + const isBlockEditorReady = !! ( hasMenus && navigationPost ); + return ( @@ -60,7 +71,11 @@ export default function Layout( { blockEditorSettings } ) { -
+
- - - -
} + + { hasFinishedInitialLoad && ! hasMenus && ( + + ) } + + { isBlockEditorReady && ( + - + -
- -
- - +
+ +
+ + + + ) }
diff --git a/packages/edit-navigation/src/components/layout/style.scss b/packages/edit-navigation/src/components/layout/style.scss index 2b69625bc6467..1138a64ef15e7 100644 --- a/packages/edit-navigation/src/components/layout/style.scss +++ b/packages/edit-navigation/src/components/layout/style.scss @@ -22,11 +22,17 @@ } .edit-navigation-layout { - margin-right: $sidebar-width; + &.has-block-inspector { + margin-right: $sidebar-width; + } + + > .components-spinner { + margin: $navigation-editor-spacing-top auto 0; + } .edit-navigation-layout__canvas { // Provide space for the floating block toolbar. - padding-top: $grid-unit-40 * 3; + padding-top: $navigation-editor-spacing-top; // Ensure the entire layout is full-height, the background // of the editing canvas needs to be full-height for block @@ -34,3 +40,10 @@ flex-grow: 1; } } + +.edit-navigation-empty-state { + width: $navigation-editor-width; + margin-top: $navigation-editor-spacing-top; + margin-left: auto; + margin-right: auto; +} diff --git a/packages/edit-navigation/src/components/layout/use-navigation-editor.js b/packages/edit-navigation/src/components/layout/use-navigation-editor.js index 2606d7a2cb3e6..e6439e804062b 100644 --- a/packages/edit-navigation/src/components/layout/use-navigation-editor.js +++ b/packages/edit-navigation/src/components/layout/use-navigation-editor.js @@ -10,6 +10,9 @@ import { useState, useEffect } from '@wordpress/element'; import { store as editNavigationStore } from '../../store'; export default function useNavigationEditor() { + const [ hasFinishedInitialLoad, setHasFinishedInitialLoad ] = useState( + false + ); const { menus, hasLoadedMenus } = useSelect( ( select ) => { const selectors = select( 'core' ); const params = { per_page: -1 }; @@ -21,6 +24,12 @@ export default function useNavigationEditor() { }; }, [] ); + useEffect( () => { + if ( hasLoadedMenus ) { + setHasFinishedInitialLoad( true ); + } + }, [ hasLoadedMenus ] ); + const [ selectedMenuId, setSelectedMenuId ] = useState( null ); useEffect( () => { @@ -30,10 +39,14 @@ export default function useNavigationEditor() { }, [ selectedMenuId, menus ] ); const navigationPost = useSelect( - ( select ) => - select( editNavigationStore ).getNavigationPostForMenu( + ( select ) => { + if ( ! selectedMenuId ) { + return; + } + return select( editNavigationStore ).getNavigationPostForMenu( selectedMenuId - ), + ); + }, [ selectedMenuId ] ); @@ -54,10 +67,11 @@ export default function useNavigationEditor() { return { menus, + hasLoadedMenus, + hasFinishedInitialLoad, selectedMenuId, navigationPost, selectMenu, deleteMenu, - hasLoadedMenus, }; } diff --git a/packages/edit-navigation/src/style.scss b/packages/edit-navigation/src/style.scss index b3309df35db84..170cbcefe5513 100644 --- a/packages/edit-navigation/src/style.scss +++ b/packages/edit-navigation/src/style.scss @@ -1,9 +1,13 @@ +$navigation-editor-width: 420px; +$navigation-editor-spacing-top: $grid-unit-40 * 2; + *, *::before, *::after { box-sizing: border-box; } +@import "./components/add-menu/style.scss"; @import "./components/editor/style.scss"; @import "./components/error-boundary/style.scss"; @import "./components/header/style.scss";