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: Implement redesign of Navigation Editor #25178

Merged
merged 34 commits into from
Sep 11, 2020
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
53f11de
Navigation: Implement redesign of Navigation Editor
noisysocks Sep 9, 2020
7ba8452
Navigation: Typo: @wordpress/i18n -> @wordpress/element
noisysocks Sep 10, 2020
7efa781
Navigation: Inline call to setSelectedBlockId
noisysocks Sep 10, 2020
7f59c24
Navigation: Add selectBlock as a useEffect dependency
noisysocks Sep 10, 2020
96db71a
Navigation: Don't call setMenuLocationsByName when component is not m…
noisysocks Sep 10, 2020
3f1eaf6
Navigation: Remove unnecessary useCallback()
noisysocks Sep 10, 2020
22750a8
Navigation: Show Toolbar when there are no menus
noisysocks Sep 10, 2020
18341e8
Return stable references from useMenuLocations()
noisysocks Sep 10, 2020
5888c7a
Navigation: Fix createStubPost() setting blocks = [ undefined ]
noisysocks Sep 10, 2020
79026cf
Navigation: Use NavigableToolbar
noisysocks Sep 10, 2020
86440fa
Navigation: Split toolbar into two lines on mobile
noisysocks Sep 10, 2020
cd405b7
Changing the order of the list view and visual view so the list view …
shaunandrews Sep 10, 2020
a758ad2
Adding a title to the top of the List View.
shaunandrews Sep 10, 2020
90c2b58
Moving the add-menu-form from the toolbar into the header.
shaunandrews Sep 10, 2020
143df0b
Moving the props for the add form from the toolbar to the header.
shaunandrews Sep 10, 2020
f5cdbbb
A general refactor of the CSS, moving the add menu around, and genera…
shaunandrews Sep 10, 2020
c19c449
Navigation: Use <label> for dropdown instead of <p>
noisysocks Sep 11, 2020
93f5efa
Navigation: Remove Cancel buton from AddMenuForm
noisysocks Sep 11, 2020
62211f0
Navigation: 24px -> -unit-30
noisysocks Sep 11, 2020
6e5df7d
Navigation: Remove isAddingMenu state
noisysocks Sep 11, 2020
4a7da3f
Navigation: Simplify Add Menu Form
noisysocks Sep 11, 2020
08980a2
Navigation: Remove menu location from label for now
noisysocks Sep 11, 2020
bdc1cdc
Navigation: Center spinner in Add Menu Form
noisysocks Sep 11, 2020
1b668fb
Navigation: Improve mobile styling
noisysocks Sep 11, 2020
74d6a8b
Navigation: Minor cleanup
noisysocks Sep 11, 2020
f4e9bb9
Navigation: Use className instead of h3
noisysocks Sep 11, 2020
a094256
Navigation: Use em for font-size
noisysocks Sep 11, 2020
417ee55
Navigation: Remove Spinner from header
noisysocks Sep 11, 2020
bf6aefa
Navigation: Use $default-line-height
noisysocks Sep 11, 2020
6125e6f
Navigation: Use className for h1
noisysocks Sep 11, 2020
80215a7
Navigation: Remove unnecessary flexbox styling
noisysocks Sep 11, 2020
5d06320
Navigation: VisualView -> BlockView
noisysocks Sep 11, 2020
d02bcb8
Navigation: Use deps in useSelect()
noisysocks Sep 11, 2020
3ba5109
Navigation: Remove CSS re-ordering of block inspector, for now
noisysocks Sep 11, 2020
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
2 changes: 2 additions & 0 deletions packages/components/src/select-control/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ function SelectControl(
options = [],
size = 'default',
value: valueProp,
labelPosition,
...props
},
ref
Expand Down Expand Up @@ -100,6 +101,7 @@ function SelectControl(
<Icon icon={ chevronDown } size={ 18 } />
</DownArrowWrapper>
}
labelPosition={ labelPosition }
>
<Select
{ ...props }
Expand Down

This file was deleted.

This file was deleted.

14 changes: 14 additions & 0 deletions packages/edit-navigation/src/components/editor/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Internal dependencies
*/
import ListView from './list-view';
import VisualView from './visual-view';
noisysocks marked this conversation as resolved.
Show resolved Hide resolved

export default function Editor( { isPending, blocks } ) {
return (
<div className="edit-navigation-editor">
<VisualView isPending={ isPending } />
<ListView isPending={ isPending } blocks={ blocks } />
</div>
);
}
32 changes: 32 additions & 0 deletions packages/edit-navigation/src/components/editor/list-view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { useState } from '@wordpress/element';
import { Spinner } from '@wordpress/components';
import { __experimentalBlockNavigationTree } from '@wordpress/block-editor';

export default function ListView( { isPending, blocks } ) {
const [ selectedBlockId, setSelectedBlockId ] = useState(
blocks[ 0 ]?.clientId
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens when blocks changes?

For example, it changes from [1, 2, 3] to [4, 5, 6]. selectedBlockId is now out of sync, should we care about this at all?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be honest I'm not even sure why we're using local state instead of select( 'core/block-editor' ).getSelectedBlockClientId(). Maybe @talldan knows?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was already this way in master, so I've made a note to come back to this later.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this was @adamziel's change, #22705 should be the issue relating to the code.

);

return (
<div className="edit-navigation-editor__list-view">
<h3>{ __( 'List view' ) }</h3>
{ isPending ? (
<Spinner />
) : (
<__experimentalBlockNavigationTree
blocks={ blocks }
selectedBlockClientId={ selectedBlockId }
selectBlock={ setSelectedBlockId }
__experimentalFeatures
showNestedBlocks
showAppender
showBlockMovers
/>
) }
</div>
);
}
39 changes: 39 additions & 0 deletions packages/edit-navigation/src/components/editor/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
.edit-navigation-editor {
margin: $grid-unit-20;

@include break-medium() {
align-items: flex-start;
display: flex;
}
}

.edit-navigation-editor__list-view {
padding-left: $grid-unit-20;
margin-left: $grid-unit-20;
border-left: 1px solid $gray-200;

@include break-medium() {
width: 300px;
}

h3 {
noisysocks marked this conversation as resolved.
Show resolved Hide resolved
font-size: 15px;
noisysocks marked this conversation as resolved.
Show resolved Hide resolved
margin: 0;
}

.components-spinner {
display: block;
margin: 100px auto;
}
}

.edit-navigation-editor__visual-view {
@include break-medium() {
flex-grow: 1;
}

.components-spinner {
display: block;
margin: 10px auto;
}
}
38 changes: 38 additions & 0 deletions packages/edit-navigation/src/components/editor/visual-view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* WordPress dependencies
*/
import { useSelect, useDispatch } from '@wordpress/data';
import { useEffect } from '@wordpress/element';
import { WritingFlow, ObserveTyping, BlockList } from '@wordpress/block-editor';
import { Spinner } from '@wordpress/components';

export default function VisualView( { isPending } ) {
const rootClientId = useSelect(
( select ) => select( 'core/block-editor' ).getBlocks()[ 0 ]?.clientId
noisysocks marked this conversation as resolved.
Show resolved Hide resolved
);

const { selectBlock } = useDispatch( 'core/block-editor' );

// Select the root Navigation block when it becomes available.
useEffect( () => {
if ( rootClientId ) {
selectBlock( rootClientId );
}
}, [ rootClientId, selectBlock ] );

return (
<div className="edit-navigation-editor__visual-view">
{ isPending ? (
<Spinner />
) : (
<div className="editor-styles-wrapper">
<WritingFlow>
<ObserveTyping>
<BlockList />
</ObserveTyping>
</WritingFlow>
</div>
) }
</div>
);
}
90 changes: 90 additions & 0 deletions packages/edit-navigation/src/components/header/add-menu-form.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/**
* External dependencies
*/
import { some } from 'lodash';

/**
* WordPress dependencies
*/
import { useState } from '@wordpress/element';
import { useDispatch } from '@wordpress/data';
import { TextControl, Button } from '@wordpress/components';
import { __, sprintf } from '@wordpress/i18n';

const menuNameMatches = ( menuName ) => ( menu ) =>
menu.name.toLowerCase() === menuName.toLowerCase();

export default function AddMenuForm( { menus, onCreate } ) {
const [ menuName, setMenuName ] = useState( '' );

const { createErrorNotice, createInfoNotice } = useDispatch(
'core/notices'
);

const [ isCreatingMenu, setIsCreatingMenu ] = useState( false );

const { saveMenu } = useDispatch( 'core' );

const createMenu = async ( event ) => {
event.preventDefault();

if ( ! menuName.length ) {
return;
}

if ( some( menus, menuNameMatches( menuName ) ) ) {
const message = sprintf(
// translators: %s: the name of a menu.
__(
'The menu name %s conflicts with another menu name. Please try another.'
),
menuName
);
createErrorNotice( message, { id: 'edit-navigation-error' } );
return;
}

setIsCreatingMenu( true );

const menu = await saveMenu( { name: menuName } );
if ( menu ) {
createInfoNotice( __( 'Menu created' ), {
type: 'snackbar',
isDismissible: true,
} );
onCreate( menu.id );
}

setIsCreatingMenu( false );
};

return (
<form
className="edit-navigation-header__add-menu-form"
onSubmit={ createMenu }
>
<TextControl
className="edit-navigation-header__add-menu-name-field"
// Disable reason: The name field should receive focus when
// component mounts.
// eslint-disable-next-line jsx-a11y/no-autofocus
autoFocus
label={ __( 'New menu name' ) }
placeholder={ __( 'New menu name' ) }
hideLabelFromVision
value={ menuName }
onChange={ setMenuName }
/>

<Button
className="edit-navigation-header__add-menu-create-button"
type="submit"
isPrimary
disabled={ ! menuName.length }
isBusy={ isCreatingMenu }
>
{ __( 'Create menu' ) }
</Button>
</form>
);
}
96 changes: 96 additions & 0 deletions packages/edit-navigation/src/components/header/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import {
Spinner,
Button,
SelectControl,
Dropdown,
} from '@wordpress/components';

/**
* Internal dependencies
*/
import ManageLocations from './manage-locations';
import AddMenuForm from './add-menu-form';

export default function Header( {
menus,
selectedMenuId,
onSelectMenu,
onCancelAddingMenu,
} ) {
return (
<div className="edit-navigation-header">
<h1>{ __( 'Navigation' ) }</h1>

<div className="edit-navigation-header__actions">
{ menus ? (
<div className="edit-navigation-header__current-menu">
<SelectControl
className="edit-navigation-toolbar__menu-select"
label={ __( 'Currently editing' ) }
disabled={ ! menus.length }
value={ selectedMenuId ?? 0 }
options={
menus.length
? menus.map( ( menu ) => ( {
value: menu.id,
label: menu.name + ' (Primary)', //Just a reminder to show the menu location, if set.
noisysocks marked this conversation as resolved.
Show resolved Hide resolved
} ) )
: [
{
value: 0,
label: __(
'— Select navigation —'
),
},
]
}
onChange={ onSelectMenu }
/>
</div>
) : (
<Spinner />
noisysocks marked this conversation as resolved.
Show resolved Hide resolved
) }

<Dropdown
contentClassName="edit-navigation-header__add-new-form"
position="bottom center"
renderToggle={ ( { isOpen, onToggle } ) => (
<Button
isTertiary
aria-expanded={ isOpen }
onClick={ onToggle }
>
{ __( 'Add new' ) }
</Button>
) }
renderContent={ () => (
<AddMenuForm
menus={ menus }
onCancel={ onCancelAddingMenu }
noisysocks marked this conversation as resolved.
Show resolved Hide resolved
onCreate={ onSelectMenu }
/>
) }
/>

<Dropdown
contentClassName="edit-navigation-header__manage-locations"
position="bottom center"
renderToggle={ ( { isOpen, onToggle } ) => (
<Button
isTertiary
aria-expanded={ isOpen }
onClick={ onToggle }
>
{ __( 'Manage locations' ) }
</Button>
) }
renderContent={ () => <ManageLocations /> }
/>
</div>
</div>
);
}
Loading