Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Navigation Editor: Allow menu renaming #29012

Merged
merged 23 commits into from
Mar 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { __ } from '@wordpress/i18n';
/**
* Internal dependencies
*/
import useMenuLocations from './use-menu-locations';
import useMenuLocations from '../../hooks/use-menu-locations';

export default function ManageLocations() {
const menus = useSelect( ( select ) => select( 'core' ).getMenus(), [] );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import { InspectorControls } from '@wordpress/block-editor';
*/
import AutoAddPagesPanel from './auto-add-pages-panel';
import DeleteMenuPanel from './delete-menu-panel';
import { NameEditor } from '../name-editor';
import { PanelBody } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

export default function InspectorAdditions( { menuId, onDeleteMenu } ) {
const selectedBlock = useSelect(
Expand All @@ -22,8 +25,11 @@ export default function InspectorAdditions( { menuId, onDeleteMenu } ) {

return (
<InspectorControls>
<AutoAddPagesPanel menuId={ menuId } />
<DeleteMenuPanel onDeleteMenu={ onDeleteMenu } />
<PanelBody title={ __( 'Menu Settings' ) }>
<NameEditor />
<AutoAddPagesPanel menuId={ menuId } />
<DeleteMenuPanel onDeleteMenu={ onDeleteMenu } />
</PanelBody>
</InspectorControls>
);
}
113 changes: 67 additions & 46 deletions packages/edit-navigation/src/components/layout/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,19 @@ import {
BlockInspector,
__unstableUseBlockSelectionClearer as useBlockSelectionClearer,
} from '@wordpress/block-editor';
import { useMemo, useState } 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';
import {
IsMenuNameControlFocusedContext,
MenuIdContext,
useNavigationEditor,
useNavigationBlockEditor,
useMenuNotifications,
} from '../../hooks';
import ErrorBoundary from '../error-boundary';
import NavigationEditorShortcuts from './shortcuts';
import Header from '../header';
Expand All @@ -37,7 +42,9 @@ import { store as editNavigationStore } from '../../store';

export default function Layout( { blockEditorSettings } ) {
const canvasRef = useBlockSelectionClearer();

const [ isMenuNameControlFocused, setIsMenuNameControlFocused ] = useState(
false
);
const { saveNavigationPost } = useDispatch( editNavigationStore );
const savePost = () => saveNavigationPost( navigationPost );

Expand Down Expand Up @@ -74,51 +81,65 @@ export default function Layout( { blockEditorSettings } ) {
'has-block-inspector': isBlockEditorReady,
} ) }
>
<Header
isPending={ ! hasLoadedMenus }
menus={ menus }
selectedMenuId={ selectedMenuId }
onSelectMenu={ selectMenu }
navigationPost={ navigationPost }
/>
<MenuIdContext.Provider value={ selectedMenuId }>
<IsMenuNameControlFocusedContext.Provider
value={ useMemo(
() => [
isMenuNameControlFocused,
setIsMenuNameControlFocused,
],
[ isMenuNameControlFocused ]
) }
>
<Header
isPending={ ! hasLoadedMenus }
menus={ menus }
selectedMenuId={ selectedMenuId }
onSelectMenu={ selectMenu }
navigationPost={ navigationPost }
/>

{ ! hasFinishedInitialLoad && <Spinner /> }
{ ! hasFinishedInitialLoad && <Spinner /> }

{ hasFinishedInitialLoad && ! hasMenus && (
<EmptyState />
) }
{ hasFinishedInitialLoad && ! hasMenus && (
<EmptyState />
) }

{ isBlockEditorReady && (
<BlockEditorProvider
value={ blocks }
onInput={ onInput }
onChange={ onChange }
settings={ {
...blockEditorSettings,
templateLock: 'all',
} }
useSubRegistry={ false }
>
<BlockEditorKeyboardShortcuts />
<NavigationEditorShortcuts
saveBlocks={ savePost }
/>
<div
className="edit-navigation-layout__canvas"
ref={ canvasRef }
>
<Editor
isPending={ ! hasLoadedMenus }
blocks={ blocks }
/>
</div>
<InspectorAdditions
menuId={ selectedMenuId }
onDeleteMenu={ deleteMenu }
/>
<BlockInspector bubblesVirtually={ false } />
</BlockEditorProvider>
) }
{ isBlockEditorReady && (
<BlockEditorProvider
value={ blocks }
onInput={ onInput }
onChange={ onChange }
settings={ {
...blockEditorSettings,
templateLock: 'all',
} }
useSubRegistry={ false }
>
<BlockEditorKeyboardShortcuts />
<NavigationEditorShortcuts
saveBlocks={ savePost }
/>
<div
className="edit-navigation-layout__canvas"
ref={ canvasRef }
>
<Editor
isPending={ ! hasLoadedMenus }
blocks={ blocks }
/>
</div>
<InspectorAdditions
menuId={ selectedMenuId }
onDeleteMenu={ deleteMenu }
/>
<BlockInspector
bubblesVirtually={ false }
/>
</BlockEditorProvider>
) }
</IsMenuNameControlFocusedContext.Provider>
</MenuIdContext.Provider>
</div>

<Popover.Slot />
Expand Down
37 changes: 37 additions & 0 deletions packages/edit-navigation/src/components/name-display/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* WordPress dependencies
*/
import { ToolbarGroup, ToolbarButton } from '@wordpress/components';
import { BlockControls } from '@wordpress/block-editor';
/**
* Internal dependencies
*/
import {
useSelectedMenuData,
IsMenuNameControlFocusedContext,
} from '../../hooks';
import { useContext } from '@wordpress/element';

import { sprintf, __ } from '@wordpress/i18n';
export default function NameDisplay() {
const { menuName } = useSelectedMenuData();
const [ , setIsMenuNameEditFocused ] = useContext(
IsMenuNameControlFocusedContext
);
return (
<BlockControls>
<ToolbarGroup>
<ToolbarButton
aria-label={ sprintf(
// translators: %s: the name of a menu.
__( `Edit menu name: %s` ),
menuName
) }
onClick={ () => setIsMenuNameEditFocused( true ) }
>
{ menuName }
</ToolbarButton>
</ToolbarGroup>
</BlockControls>
);
}
44 changes: 44 additions & 0 deletions packages/edit-navigation/src/components/name-editor/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { useEffect, useRef, useContext } from '@wordpress/element';
/**
* Internal dependencies
*/
import { TextControl } from '@wordpress/components';
import {
IsMenuNameControlFocusedContext,
useMenuEntity,
useSelectedMenuData,
} from '../../hooks';

export function NameEditor() {
const [ isMenuNameEditFocused, setIsMenuNameEditFocused ] = useContext(
IsMenuNameControlFocusedContext
);

const { menuId } = useSelectedMenuData();
const { editMenuName, editedMenuName } = useMenuEntity( menuId );
const inputRef = useRef();
useEffect( () => {
if ( isMenuNameEditFocused ) inputRef.current.focus();
}, [ isMenuNameEditFocused ] );
return (
<>
<TextControl
ref={ inputRef }
help={ __(
'A short, descriptive name used to refer to this menu elsewhere.'
) }
label={ __( 'Name' ) }
onBlur={ () => setIsMenuNameEditFocused( false ) }
className="edit-navigation-name-editor__text-control"
value={ editedMenuName }
onChange={ ( value ) => {
editMenuName( value );
} }
/>
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.edit-navigation-name-editor__text-control {
.components-base-control {
border: none;
}
}
31 changes: 31 additions & 0 deletions packages/edit-navigation/src/filters/add-menu-name-editor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
import { addFilter } from '@wordpress/hooks';
import { createHigherOrderComponent } from '@wordpress/compose';
import NameDisplay from '../components/name-display';

const addMenuNameEditor = createHigherOrderComponent(
( BlockEdit ) => ( props ) => {
if ( props.name !== 'core/navigation' ) {
return <BlockEdit { ...props } />;
}
return (
<>
<BlockEdit { ...props } />
<NameDisplay />
</>
);
},
'withMenuName'
);

export default () =>
addFilter(
'editor.BlockEdit',
'core/edit-navigation/with-menu-name',
addMenuNameEditor
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* WordPress dependencies
*/
import { addFilter } from '@wordpress/hooks';
/**
* External dependencies
*/
import { set } from 'lodash';

function disableInsertingNonNavigationBlocks( settings, name ) {
if ( ! [ 'core/navigation', 'core/navigation-link' ].includes( name ) ) {
set( settings, [ 'supports', 'inserter' ], false );
}
return settings;
}

export default () =>
addFilter(
'blocks.registerBlockType',
'core/edit-navigation/disable-inserting-non-navigation-blocks',
disableInsertingNonNavigationBlocks
);
18 changes: 18 additions & 0 deletions packages/edit-navigation/src/filters/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Internal dependencies
*/
import addMenuNameEditor from './add-menu-name-editor';
import disableInsertingNonNavigationBlocks from './disable-inserting-non-navigation-blocks';
import removeEditUnsupportedFeatures from './remove-edit-unsupported-features';
import removeSettingsUnsupportedFeatures from './remove-settings-unsupported-features';

export const addFilters = (
shouldAddDisableInsertingNonNavigationBlocksFilter
) => {
addMenuNameEditor();
if ( shouldAddDisableInsertingNonNavigationBlocksFilter ) {
disableInsertingNonNavigationBlocks();
}
removeEditUnsupportedFeatures();
removeSettingsUnsupportedFeatures();
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* WordPress dependencies
*/
import { addFilter } from '@wordpress/hooks';
import { createHigherOrderComponent } from '@wordpress/compose';

const removeNavigationBlockEditUnsupportedFeatures = createHigherOrderComponent(
( BlockEdit ) => ( props ) => {
if ( props.name !== 'core/navigation' ) {
return <BlockEdit { ...props } />;
}

return (
<BlockEdit
{ ...props }
hasSubmenuIndicatorSetting={ false }
hasItemJustificationControls={ false }
hasListViewModal={ false }
/>
);
},
'removeNavigationBlockEditUnsupportedFeatures'
);

export default () =>
addFilter(
'editor.BlockEdit',
'core/edit-navigation/remove-navigation-block-edit-unsupported-features',
removeNavigationBlockEditUnsupportedFeatures
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* WordPress dependencies
*/
import { addFilter } from '@wordpress/hooks';

function removeNavigationBlockSettingsUnsupportedFeatures( settings, name ) {
if ( name !== 'core/navigation' ) {
return settings;
}

return {
...settings,
supports: {
customClassName: false,
html: false,
inserter: true,
},
// Remove any block variations.
variations: undefined,
};
}

export default () =>
addFilter(
'blocks.registerBlockType',
'core/edit-navigation/remove-navigation-block-settings-unsupported-features',
removeNavigationBlockSettingsUnsupportedFeatures
);
Loading