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 {