diff --git a/packages/components/src/navigation/index.js b/packages/components/src/navigation/index.js index bf5199edc2cb9e..c33850d51f4518 100644 --- a/packages/components/src/navigation/index.js +++ b/packages/components/src/navigation/index.js @@ -1,74 +1,47 @@ /** * WordPress dependencies */ -import { useState } from '@wordpress/element'; -import { Icon, arrowLeft } from '@wordpress/icons'; +import { useEffect, useState } from '@wordpress/element'; -/** - * Internal dependencies - */ -import Button from '../button'; -import Text from '../text'; -import Item from './item'; +const Navigation = ( { activeItemId, children, data, rootTitle } ) => { + const [ activeLevel, setActiveLevel ] = useState( 'root' ); + + const mapItemData = ( items ) => { + return items.map( ( item ) => { + const itemChildren = data.filter( ( i ) => i.parent === item.id ); + return { + ...item, + children: itemChildren, + parent: item.parent || 'root', + isActive: item.id === activeItemId, + hasChildren: itemChildren.length > 0, + }; + } ); + }; + const items = [ { id: 'root', title: rootTitle }, ...mapItemData( data ) ]; -const Navigation = ( { data, initial } ) => { - const initialActive = data.find( ( item ) => item.slug === initial ); - const [ active, setActive ] = useState( initialActive ); - const parent = data.find( ( item ) => item.slug === active.parent ); - const items = data.filter( ( item ) => item.parent === active.parent ); + const activeItem = items.find( ( item ) => item.id === activeItemId ); + const level = items.find( ( item ) => item.id === activeLevel ); + const levelItems = items.filter( ( item ) => item.parent === level.id ); + const parentLevel = + level.id === 'root' + ? null + : items.find( ( item ) => item.id === level.parent ); - const goBack = () => { - if ( ! parent.parent ) { - // We are at top level, will need to handle this case. - return; - } - const parentalSiblings = data.filter( - ( item ) => item.parent === parent.parent - ); - if ( parentalSiblings.length ) { - setActive( parentalSiblings[ 0 ] ); + useEffect( () => { + if ( activeItem ) { + setActiveLevel( activeItem.parent ); } - }; + }, [] ); return (
- -
- { parent.title } -
-
- { items.map( ( item ) => - item.menu !== 'secondary' ? ( - - ) : null - ) } -
-
- { items.map( ( item ) => - item.menu === 'secondary' ? ( - - ) : null - ) } -
+ { children( { + level, + levelItems, + parentLevel, + setActiveLevel, + } ) }
); }; diff --git a/packages/components/src/navigation/item.js b/packages/components/src/navigation/item.js deleted file mode 100644 index b3453dbbf99793..00000000000000 --- a/packages/components/src/navigation/item.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; - -/** - * WordPress dependencies - */ -import { Icon, chevronRight } from '@wordpress/icons'; - -/** - * Internal dependencies - */ -import Button from '../button'; -import Text from '../text'; - -const Item = ( { data, item, setActive, isActive } ) => { - const children = data.filter( ( d ) => d.parent === item.slug ); - const onSelect = () => { - const next = children.length ? children[ 0 ] : item; - setActive( next ); - }; - const classes = classnames( 'components-navigation__menu-item', { - 'is-active': isActive, - } ); - return ( - - ); -}; - -export default Item; diff --git a/packages/components/src/navigation/menu-item.js b/packages/components/src/navigation/menu-item.js new file mode 100644 index 00000000000000..d665b778d52582 --- /dev/null +++ b/packages/components/src/navigation/menu-item.js @@ -0,0 +1,51 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; + +/** + * WordPress dependencies + */ +import { Icon, chevronRight } from '@wordpress/icons'; + +/** + * Internal dependencies + */ +import Button from '../button'; +import Text from '../text'; + +const NavigationMenuItem = ( props ) => { + const { + children, + hasChildren, + id, + isActive, + onClick, + setActiveLevel, + title, + } = props; + const classes = classnames( 'components-navigation__menu-item', { + 'is-active': isActive, + } ); + + const handleClick = () => { + if ( children.length ) { + setActiveLevel( id ); + return; + } + onClick( props ); + }; + + return ( +
  • + +
  • + ); +}; + +export default NavigationMenuItem; diff --git a/packages/components/src/navigation/menu.js b/packages/components/src/navigation/menu.js new file mode 100644 index 00000000000000..d5a62018f9a5f2 --- /dev/null +++ b/packages/components/src/navigation/menu.js @@ -0,0 +1,5 @@ +const NavigationMenu = ( { children } ) => { + return ; +}; + +export default NavigationMenu; diff --git a/packages/components/src/navigation/stories/index.js b/packages/components/src/navigation/stories/index.js index ede16f3046136f..c18d0a6e7e2e73 100644 --- a/packages/components/src/navigation/stories/index.js +++ b/packages/components/src/navigation/stories/index.js @@ -1,7 +1,15 @@ +/** + * WordPress dependencies + */ +import { Button } from '@wordpress/components'; +import { useState } from '@wordpress/element'; + /** * Internal dependencies */ import Navigation from '../'; +import NavigationMenu from '../menu'; +import NavigationMenuItem from '../menu-item'; export default { title: 'Components/Navigation', @@ -9,80 +17,68 @@ export default { }; const data = [ - { title: 'WooCommerce', slug: 'root', back: 'Dashboard' }, - { title: 'Home', slug: 'home', parent: 'root', menu: 'primary' }, - { - title: 'Analytics', - slug: 'analytics', - parent: 'root', - back: 'WooCommerce Home', - menu: 'primary', - }, - { - title: 'Orders', - slug: 'orders', - parent: 'root', - back: 'WooCommerce Home', - menu: 'primary', - }, - { - title: 'Overview', - slug: 'overview', - parent: 'analytics', - }, { - title: 'Products report', - slug: 'products', - parent: 'analytics', + title: 'Item 1', + id: 'item-1', }, { - title: 'All orders', - slug: 'all_orders', - parent: 'orders', + title: 'Item 2', + id: 'item-2', }, { - title: 'Payouts', - slug: 'payouts', - parent: 'orders', + title: 'Category', + id: 'item-3', }, { - title: 'Settings', - slug: 'settings', - parent: 'root', - back: 'WooCommerce Home', - menu: 'secondary', + title: 'Child 1', + id: 'child-1', + parent: 'item-3', }, { - title: 'Extensions', - slug: 'extensions', - parent: 'root', - back: 'WooCommerce Home', - menu: 'secondary', - }, - { - title: 'General', - slug: 'general', - parent: 'settings', - }, - { - title: 'Tax', - slug: 'tax', - parent: 'settings', - }, - { - title: 'My extensions', - slug: 'my_extensions', - parent: 'extensions', - }, - { - title: 'Marketplace', - slug: 'marketplace', - parent: 'extensions', + title: 'Child 2', + id: 'child-2', + parent: 'item-3', }, ]; function Example() { - return ; + const [ active, setActive ] = useState( 'item-1' ); + + return ( + + { ( { level, levelItems, parentLevel, setActiveLevel } ) => { + return ( + <> + { parentLevel && ( + + ) } +

    { level.title }

    + + { levelItems.map( ( item ) => { + return ( + + setActive( selected.id ) + } + setActiveLevel={ setActiveLevel } + /> + ); + } ) } + + + ); + } } +
    + ); } export const _default = () => { diff --git a/packages/components/src/navigation/style.scss b/packages/components/src/navigation/style.scss index 1c90f0573f0439..df9ff20ed4f74e 100644 --- a/packages/components/src/navigation/style.scss +++ b/packages/components/src/navigation/style.scss @@ -11,13 +11,9 @@ margin-bottom: 40px; } -.components-navigation__menu-items { +.components-navigation__menu { display: flex; flex-direction: column; - - &.is-secondary { - margin-top: 24px; - } } .components-navigation__menu-item {