From 54b20280d1d73ef04d2c773d474a42daa188ca03 Mon Sep 17 00:00:00 2001 From: HAKIZIMANA Franck Date: Mon, 25 Nov 2019 11:16:28 +0200 Subject: [PATCH 1/8] feat: Add nested accordion menu --- src/components/NestedAccordionMenu/Menu.js | 32 ++++++ .../NestedAccordionMenu/MenuItem.js | 102 ++++++++++++++++++ src/components/NestedAccordionMenu/index.js | 8 ++ .../NestedAccordionMenu/index.stories.js | 70 ++++++++++++ src/index.js | 2 + 5 files changed, 214 insertions(+) create mode 100644 src/components/NestedAccordionMenu/Menu.js create mode 100644 src/components/NestedAccordionMenu/MenuItem.js create mode 100644 src/components/NestedAccordionMenu/index.js create mode 100644 src/components/NestedAccordionMenu/index.stories.js diff --git a/src/components/NestedAccordionMenu/Menu.js b/src/components/NestedAccordionMenu/Menu.js new file mode 100644 index 0000000..c72de53 --- /dev/null +++ b/src/components/NestedAccordionMenu/Menu.js @@ -0,0 +1,32 @@ +import React, { Fragment } from "react"; +import List from "@material-ui/core/List"; +import MenuItem from "./MenuItem"; +import { makeStyles } from "@material-ui/core/styles"; +const useStyles = makeStyles(theme => ({ + sidebar: { + width: "100%", + backgroundColor: theme.palette.background.paper, + }, +})); +function Menu({ items, depthStep, depth, expanded, fontsize }) { + const classes = useStyles(); + return ( +
+ + {items && + items.map((menuItem, index) => ( + + + + ))} + +
+ ); +} + +export default Menu; diff --git a/src/components/NestedAccordionMenu/MenuItem.js b/src/components/NestedAccordionMenu/MenuItem.js new file mode 100644 index 0000000..696d1d6 --- /dev/null +++ b/src/components/NestedAccordionMenu/MenuItem.js @@ -0,0 +1,102 @@ +import React, { Fragment, useState } from "react"; +import List from "@material-ui/core/List"; +import ListItem from "@material-ui/core/ListItem"; +import ExpandMoreIcon from "@material-ui/icons/ExpandMore"; +import ExpandLessIcon from "@material-ui/icons/ExpandLess"; +import Collapse from "@material-ui/core/Collapse"; +import ListItemIcon from "@material-ui/core/ListItemIcon"; +import ListItemText from "@material-ui/core/ListItemText"; +import { makeStyles } from "@material-ui/core/styles"; +const useStyles = makeStyles(theme => ({ + sidebarItem: { + display: "flex", + justifyContent: "space-between", + alignItems: "center", + }, + sidebarItemContent: { + whiteSpace: "nowrap", + textOverflow: "ellipsis", + overflow: "hidden", + display: "flex", + alignItems: "center", + width: "100%", + }, + collapse: { + background: "#f4f1f1", + }, +})); +function MenuItem({ depthStep = 10, depth = 0, expanded, item, ...rest }) { + const classes = useStyles(); + const [collapsed, setCollapsed] = useState(true); + const { route, name, items, Icon } = item; + + function toggleCollapse() { + setCollapsed(prevValue => !prevValue); + } + + function onClick(e) { + if (Array.isArray(items)) { + toggleCollapse(); + } + if (onClickProp) { + onClickProp(e, item); + } + } + + let expandIcon; + + if (Array.isArray(items) && items.length) { + expandIcon = !collapsed ? ( + + ) : ( + + ); + } + + return ( + + +
+ + {Icon && } + + +
+ {expandIcon} +
+ + {Array.isArray(items) ? ( + + {items && + items.map((subItem, index) => ( + + + + ))} + + ) : null} + +
+ ); +} + +export default MenuItem; diff --git a/src/components/NestedAccordionMenu/index.js b/src/components/NestedAccordionMenu/index.js new file mode 100644 index 0000000..1e3b0d8 --- /dev/null +++ b/src/components/NestedAccordionMenu/index.js @@ -0,0 +1,8 @@ +import React from "react"; +import List from "@material-ui/core/List"; +import { makeStyles } from "@material-ui/core/styles"; +import Menu from "./Menu"; + +export default function NestedList(props) { + return ; +} diff --git a/src/components/NestedAccordionMenu/index.stories.js b/src/components/NestedAccordionMenu/index.stories.js new file mode 100644 index 0000000..b7cf04a --- /dev/null +++ b/src/components/NestedAccordionMenu/index.stories.js @@ -0,0 +1,70 @@ +import React from "react"; +import theme from "../../theme"; +import { NestedAccordionMenu } from "../../index"; +import { storiesOf } from "@storybook/react"; +import { withKnobs, boolean } from "@storybook/addon-knobs"; +import { jsxDecorator } from "storybook-addon-jsx"; +import { muiTheme } from "storybook-addon-material-ui"; +import ListIcon from "@material-ui/icons/List"; +import ScheduleIcon from "@material-ui/icons/Schedule"; +import SettingsIcon from "@material-ui/icons/Settings"; +import ShuffleIcon from "@material-ui/icons/Shuffle"; +import InboxIcon from "@material-ui/icons/Inbox"; +import { makeStyles } from "@material-ui/core/styles"; + +const stories = storiesOf("Nested Accordion Menu", NestedAccordionMenu); +function onClick(e, item) {} + +// Add the `withKnobs` decorator to add knobs support to your stories. +// You can also configure `withKnobs` as a global decorator. +stories + .addDecorator(withKnobs) + .addDecorator(jsxDecorator) + .addDecorator(muiTheme([theme])); + +const subItems = [ + { + name: "Sub Journal one", + Icon: InboxIcon, + }, + { + name: "Sub Journal two", + Icon: InboxIcon, + }, +]; +const nestedItems = [ + { + name: "Journal", + Icon: ListIcon, + items: subItems, + }, + { name: "Schedulers", Icon: ScheduleIcon, route: "project/5/schedulers" }, + { name: "General", Icon: SettingsIcon, route: "project/5/schedulers" }, + { + name: "Org. Units", + Icon: ShuffleIcon, + route: "project/5/organisationunits", + }, + { name: "Org. Unit Groups", Icon: ShuffleIcon, route: "" }, + { name: "Category Options", Icon: ShuffleIcon, route: "" }, + { name: "Categories", Icon: ShuffleIcon, route: "" }, + { name: "Category Cobos", Icon: ShuffleIcon, route: "" }, + { name: "Data Elements", Icon: ShuffleIcon, route: "" }, + { name: "Data Element Groups", Icon: ShuffleIcon, route: "" }, + { name: "Data Sets", Icon: ShuffleIcon, route: "" }, +]; + +const itemsCoreModules = [ + { + name: "CordaidSIS to HIVDR", + items: nestedItems, + Icon: InboxIcon, + }, + { + name: "SNIS REPLICA to HIVDR", + items: nestedItems, + Icon: InboxIcon, + }, +]; +// Knobs for React props +stories.add("Default", () => ); diff --git a/src/index.js b/src/index.js index 6eea5ac..2179fc0 100644 --- a/src/index.js +++ b/src/index.js @@ -11,6 +11,7 @@ import InfoBoxComponent from "./components/InfoBox"; import KeyNumberBlockComponent from "./components/KeyNumberBlock"; import ProgressButtonComponent from "./components/ProgressButton"; import TransferListComponent from "./components/TransferList"; +import NestedAccordionMenuComponent from "./components/NestedAccordionMenu"; export const BluesquareLogo = BluesquareLogoComponent; export const D2dLogo = D2dLogoComponent; @@ -25,3 +26,4 @@ export const InfoBox = InfoBoxComponent; export const KeyNumberBlock = KeyNumberBlockComponent; export const ProgressButton = ProgressButtonComponent; export const TransferList = TransferListComponent; +export const NestedAccordionMenu = NestedAccordionMenuComponent; From ba4f476905f4bd9b6aa0e93959cb0b85289eaa3d Mon Sep 17 00:00:00 2001 From: HAKIZIMANA Franck Date: Tue, 26 Nov 2019 09:10:38 +0200 Subject: [PATCH 2/8] feat: Add nested accordion menu --- src/components/NestedAccordionMenu/Menu.js | 32 ------------------ .../{MenuItem.js => MenuItems/index.js} | 33 +++---------------- .../NestedAccordionMenu/MenuItems/styles.js | 20 +++++++++++ src/components/NestedAccordionMenu/index.js | 30 ++++++++++++++--- .../NestedAccordionMenu/index.stories.js | 8 ++++- 5 files changed, 57 insertions(+), 66 deletions(-) delete mode 100644 src/components/NestedAccordionMenu/Menu.js rename src/components/NestedAccordionMenu/{MenuItem.js => MenuItems/index.js} (71%) create mode 100644 src/components/NestedAccordionMenu/MenuItems/styles.js diff --git a/src/components/NestedAccordionMenu/Menu.js b/src/components/NestedAccordionMenu/Menu.js deleted file mode 100644 index c72de53..0000000 --- a/src/components/NestedAccordionMenu/Menu.js +++ /dev/null @@ -1,32 +0,0 @@ -import React, { Fragment } from "react"; -import List from "@material-ui/core/List"; -import MenuItem from "./MenuItem"; -import { makeStyles } from "@material-ui/core/styles"; -const useStyles = makeStyles(theme => ({ - sidebar: { - width: "100%", - backgroundColor: theme.palette.background.paper, - }, -})); -function Menu({ items, depthStep, depth, expanded, fontsize }) { - const classes = useStyles(); - return ( -
- - {items && - items.map((menuItem, index) => ( - - - - ))} - -
- ); -} - -export default Menu; diff --git a/src/components/NestedAccordionMenu/MenuItem.js b/src/components/NestedAccordionMenu/MenuItems/index.js similarity index 71% rename from src/components/NestedAccordionMenu/MenuItem.js rename to src/components/NestedAccordionMenu/MenuItems/index.js index 696d1d6..13b9f5b 100644 --- a/src/components/NestedAccordionMenu/MenuItem.js +++ b/src/components/NestedAccordionMenu/MenuItems/index.js @@ -6,26 +6,8 @@ import ExpandLessIcon from "@material-ui/icons/ExpandLess"; import Collapse from "@material-ui/core/Collapse"; import ListItemIcon from "@material-ui/core/ListItemIcon"; import ListItemText from "@material-ui/core/ListItemText"; -import { makeStyles } from "@material-ui/core/styles"; -const useStyles = makeStyles(theme => ({ - sidebarItem: { - display: "flex", - justifyContent: "space-between", - alignItems: "center", - }, - sidebarItemContent: { - whiteSpace: "nowrap", - textOverflow: "ellipsis", - overflow: "hidden", - display: "flex", - alignItems: "center", - width: "100%", - }, - collapse: { - background: "#f4f1f1", - }, -})); -function MenuItem({ depthStep = 10, depth = 0, expanded, item, ...rest }) { +import useStyles from "./styles"; +function MenuItem({ depth = 0, expanded, item, ...rest }) { const classes = useStyles(); const [collapsed, setCollapsed] = useState(true); const { route, name, items, Icon } = item; @@ -38,9 +20,6 @@ function MenuItem({ depthStep = 10, depth = 0, expanded, item, ...rest }) { if (Array.isArray(items)) { toggleCollapse(); } - if (onClickProp) { - onClickProp(e, item); - } } let expandIcon; @@ -64,7 +43,7 @@ function MenuItem({ depthStep = 10, depth = 0, expanded, item, ...rest }) { to={route} >
@@ -85,11 +64,7 @@ function MenuItem({ depthStep = 10, depth = 0, expanded, item, ...rest }) { {items && items.map((subItem, index) => ( - + ))} diff --git a/src/components/NestedAccordionMenu/MenuItems/styles.js b/src/components/NestedAccordionMenu/MenuItems/styles.js new file mode 100644 index 0000000..f377dea --- /dev/null +++ b/src/components/NestedAccordionMenu/MenuItems/styles.js @@ -0,0 +1,20 @@ +import { makeStyles } from "@material-ui/styles"; + +export default makeStyles(theme => ({ + sidebarItem: { + display: "flex", + justifyContent: "space-between", + alignItems: "center", + }, + sidebarItemContent: { + whiteSpace: "nowrap", + textOverflow: "ellipsis", + overflow: "hidden", + display: "flex", + alignItems: "center", + width: "100%", + }, + collapse: { + background: "#bdbcbb", + }, +})); diff --git a/src/components/NestedAccordionMenu/index.js b/src/components/NestedAccordionMenu/index.js index 1e3b0d8..cc60790 100644 --- a/src/components/NestedAccordionMenu/index.js +++ b/src/components/NestedAccordionMenu/index.js @@ -1,8 +1,30 @@ import React from "react"; import List from "@material-ui/core/List"; +import MenuItem from "./MenuItems"; import { makeStyles } from "@material-ui/core/styles"; -import Menu from "./Menu"; - -export default function NestedList(props) { - return ; +const useStyles = makeStyles(theme => ({ + sidebar: { + width: "100%", + backgroundColor: theme.palette.background.paper, + }, +})); +function Menu({ items, depth, expanded, fontsize }) { + const classes = useStyles(); + return ( +
+ + {items && + items.map((menuItem, index) => ( + + ))} + +
+ ); } + +export default Menu; diff --git a/src/components/NestedAccordionMenu/index.stories.js b/src/components/NestedAccordionMenu/index.stories.js index b7cf04a..9b52893 100644 --- a/src/components/NestedAccordionMenu/index.stories.js +++ b/src/components/NestedAccordionMenu/index.stories.js @@ -51,7 +51,7 @@ const nestedItems = [ { name: "Category Cobos", Icon: ShuffleIcon, route: "" }, { name: "Data Elements", Icon: ShuffleIcon, route: "" }, { name: "Data Element Groups", Icon: ShuffleIcon, route: "" }, - { name: "Data Sets", Icon: ShuffleIcon, route: "" }, + { name: "Data Sets", route: "" }, ]; const itemsCoreModules = [ @@ -65,6 +65,12 @@ const itemsCoreModules = [ items: nestedItems, Icon: InboxIcon, }, + , + { + name: "DRC PROJECT", + Icon: InboxIcon, + route: "project/5/schedulers", + }, ]; // Knobs for React props stories.add("Default", () => ); From 5b1c2bb27cbb9ebb9cc747e1713219c63b23d203 Mon Sep 17 00:00:00 2001 From: HAKIZIMANA Franck Date: Tue, 26 Nov 2019 10:35:43 +0200 Subject: [PATCH 3/8] feat: Add nested accordion menu --- src/components/NestedAccordionMenu/MenuItems/index.js | 7 ++----- src/components/NestedAccordionMenu/MenuItems/styles.js | 5 +++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/components/NestedAccordionMenu/MenuItems/index.js b/src/components/NestedAccordionMenu/MenuItems/index.js index 13b9f5b..2e11242 100644 --- a/src/components/NestedAccordionMenu/MenuItems/index.js +++ b/src/components/NestedAccordionMenu/MenuItems/index.js @@ -8,7 +8,7 @@ import ListItemIcon from "@material-ui/core/ListItemIcon"; import ListItemText from "@material-ui/core/ListItemText"; import useStyles from "./styles"; function MenuItem({ depth = 0, expanded, item, ...rest }) { - const classes = useStyles(); + const classes = useStyles({ depth: depth }); const [collapsed, setCollapsed] = useState(true); const { route, name, items, Icon } = item; @@ -42,10 +42,7 @@ function MenuItem({ depth = 0, expanded, item, ...rest }) { {...rest} to={route} > -
+
{Icon && } diff --git a/src/components/NestedAccordionMenu/MenuItems/styles.js b/src/components/NestedAccordionMenu/MenuItems/styles.js index f377dea..df93ab6 100644 --- a/src/components/NestedAccordionMenu/MenuItems/styles.js +++ b/src/components/NestedAccordionMenu/MenuItems/styles.js @@ -6,14 +6,15 @@ export default makeStyles(theme => ({ justifyContent: "space-between", alignItems: "center", }, - sidebarItemContent: { + sidebarItemContent: props => ({ whiteSpace: "nowrap", textOverflow: "ellipsis", overflow: "hidden", display: "flex", alignItems: "center", width: "100%", - }, + paddingLeft: props.depth * 10, + }), collapse: { background: "#bdbcbb", }, From a2299236abb0d2e381838a2a5e3eb7546a848ee2 Mon Sep 17 00:00:00 2001 From: HAKIZIMANA Franck Date: Tue, 26 Nov 2019 10:39:49 +0200 Subject: [PATCH 4/8] feat: Add nested accordion menu --- src/components/NestedAccordionMenu/index.js | 24 ++++++++++----------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/components/NestedAccordionMenu/index.js b/src/components/NestedAccordionMenu/index.js index cc60790..c023db0 100644 --- a/src/components/NestedAccordionMenu/index.js +++ b/src/components/NestedAccordionMenu/index.js @@ -11,19 +11,17 @@ const useStyles = makeStyles(theme => ({ function Menu({ items, depth, expanded, fontsize }) { const classes = useStyles(); return ( -
- - {items && - items.map((menuItem, index) => ( - - ))} - -
+ + {items && + items.map((menuItem, index) => ( + + ))} + ); } From fb8c99dec5c7467c995cde4bbd091258f6f585d3 Mon Sep 17 00:00:00 2001 From: HAKIZIMANA Franck Date: Wed, 27 Nov 2019 11:23:00 +0200 Subject: [PATCH 5/8] feat: Add nested accordion menu --- .../NestedAccordionMenu/MenuItems/index.js | 62 +++++++++++++------ .../NestedAccordionMenu/MenuItems/styles.js | 8 ++- src/components/NestedAccordionMenu/index.js | 3 +- .../NestedAccordionMenu/index.stories.js | 38 ++++++++---- 4 files changed, 78 insertions(+), 33 deletions(-) diff --git a/src/components/NestedAccordionMenu/MenuItems/index.js b/src/components/NestedAccordionMenu/MenuItems/index.js index 2e11242..b204748 100644 --- a/src/components/NestedAccordionMenu/MenuItems/index.js +++ b/src/components/NestedAccordionMenu/MenuItems/index.js @@ -7,11 +7,13 @@ import Collapse from "@material-ui/core/Collapse"; import ListItemIcon from "@material-ui/core/ListItemIcon"; import ListItemText from "@material-ui/core/ListItemText"; import useStyles from "./styles"; -function MenuItem({ depth = 0, expanded, item, ...rest }) { +function MenuItem({ depth = 0, expanded, item, currentPath, ...rest }) { const classes = useStyles({ depth: depth }); const [collapsed, setCollapsed] = useState(true); + const [highlightcolor, setHighlightcolor] = useState(false); const { route, name, items, Icon } = item; - + const mainroute = rest.mainroute; + let highlightclass = "itemNohighlighted"; function toggleCollapse() { setCollapsed(prevValue => !prevValue); } @@ -20,6 +22,17 @@ function MenuItem({ depth = 0, expanded, item, ...rest }) { if (Array.isArray(items)) { toggleCollapse(); } + + if (currentPath === routeVal(mainroute, route)) { + if (!highlightcolor) { + setHighlightcolor(prevValue => !prevValue); + } + } else { + setHighlightcolor(prevValue => prevValue); + } + } + function routeVal(mainroute, route) { + return mainroute ? mainroute + route : route; } let expandIcon; @@ -31,25 +44,31 @@ function MenuItem({ depth = 0, expanded, item, ...rest }) { ); } - + highlightclass = highlightcolor ? "itemhighlighted" : "itemNohighlighted"; return ( - -
- - {Icon && } - - -
- {expandIcon} -
+ +
+ + {Icon && } + + +
+ {expandIcon} +
+
( - + ))} diff --git a/src/components/NestedAccordionMenu/MenuItems/styles.js b/src/components/NestedAccordionMenu/MenuItems/styles.js index df93ab6..bdb7995 100644 --- a/src/components/NestedAccordionMenu/MenuItems/styles.js +++ b/src/components/NestedAccordionMenu/MenuItems/styles.js @@ -16,6 +16,12 @@ export default makeStyles(theme => ({ paddingLeft: props.depth * 10, }), collapse: { - background: "#bdbcbb", + background: "#dcdbdc", + }, + itemhighlighted: { + color: "red", + }, + itemNohighlighted: { + color: "black", }, })); diff --git a/src/components/NestedAccordionMenu/index.js b/src/components/NestedAccordionMenu/index.js index c023db0..f74b813 100644 --- a/src/components/NestedAccordionMenu/index.js +++ b/src/components/NestedAccordionMenu/index.js @@ -8,7 +8,7 @@ const useStyles = makeStyles(theme => ({ backgroundColor: theme.palette.background.paper, }, })); -function Menu({ items, depth, expanded, fontsize }) { +function Menu({ items, depth, expanded, currentPath, fontsize }) { const classes = useStyles(); return ( @@ -19,6 +19,7 @@ function Menu({ items, depth, expanded, fontsize }) { depth={depth} expanded={expanded} item={menuItem} + currentPath={currentPath} /> ))} diff --git a/src/components/NestedAccordionMenu/index.stories.js b/src/components/NestedAccordionMenu/index.stories.js index 9b52893..4fa9e7e 100644 --- a/src/components/NestedAccordionMenu/index.stories.js +++ b/src/components/NestedAccordionMenu/index.stories.js @@ -26,10 +26,12 @@ const subItems = [ { name: "Sub Journal one", Icon: InboxIcon, + route: "/sub_journal_one", }, { name: "Sub Journal two", Icon: InboxIcon, + route: "/sub_journal_one", }, ]; const nestedItems = [ @@ -37,21 +39,26 @@ const nestedItems = [ name: "Journal", Icon: ListIcon, items: subItems, + route: "/journal", }, - { name: "Schedulers", Icon: ScheduleIcon, route: "project/5/schedulers" }, - { name: "General", Icon: SettingsIcon, route: "project/5/schedulers" }, + { name: "Schedulers", Icon: ScheduleIcon, route: "/schedulers" }, + { name: "General", Icon: SettingsIcon, route: "/General" }, { name: "Org. Units", Icon: ShuffleIcon, - route: "project/5/organisationunits", + route: "/organisationunits", }, - { name: "Org. Unit Groups", Icon: ShuffleIcon, route: "" }, - { name: "Category Options", Icon: ShuffleIcon, route: "" }, - { name: "Categories", Icon: ShuffleIcon, route: "" }, - { name: "Category Cobos", Icon: ShuffleIcon, route: "" }, - { name: "Data Elements", Icon: ShuffleIcon, route: "" }, - { name: "Data Element Groups", Icon: ShuffleIcon, route: "" }, - { name: "Data Sets", route: "" }, + { name: "Org. Unit Groups", Icon: ShuffleIcon, route: "/org_unit_groups" }, + { name: "Category Options", Icon: ShuffleIcon, route: "/category_options" }, + { name: "Categories", Icon: ShuffleIcon, route: "/categories" }, + { name: "Category Cobos", Icon: ShuffleIcon, route: "/category_combos" }, + { name: "Data Elements", Icon: ShuffleIcon, route: "/data_elements" }, + { + name: "Data Element Groups", + Icon: ShuffleIcon, + route: "/data_element_groups", + }, + { name: "Data Sets", route: "/data_sets" }, ]; const itemsCoreModules = [ @@ -59,18 +66,25 @@ const itemsCoreModules = [ name: "CordaidSIS to HIVDR", items: nestedItems, Icon: InboxIcon, + route: "project/5", }, { name: "SNIS REPLICA to HIVDR", items: nestedItems, Icon: InboxIcon, + route: "project/6", }, , { name: "DRC PROJECT", Icon: InboxIcon, - route: "project/5/schedulers", + route: "project/7", }, ]; // Knobs for React props -stories.add("Default", () => ); +stories.add("Default", () => ( + +)); From e34d37f30a9648c10d2fd71f31442b7e5f540780 Mon Sep 17 00:00:00 2001 From: HAKIZIMANA Franck Date: Wed, 27 Nov 2019 11:53:16 +0200 Subject: [PATCH 6/8] avoid dependent url instead use independent url for each nested menu --- src/components/NestedAccordionMenu/MenuItems/index.js | 9 ++------- src/components/NestedAccordionMenu/index.stories.js | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/components/NestedAccordionMenu/MenuItems/index.js b/src/components/NestedAccordionMenu/MenuItems/index.js index b204748..71511fe 100644 --- a/src/components/NestedAccordionMenu/MenuItems/index.js +++ b/src/components/NestedAccordionMenu/MenuItems/index.js @@ -12,7 +12,6 @@ function MenuItem({ depth = 0, expanded, item, currentPath, ...rest }) { const [collapsed, setCollapsed] = useState(true); const [highlightcolor, setHighlightcolor] = useState(false); const { route, name, items, Icon } = item; - const mainroute = rest.mainroute; let highlightclass = "itemNohighlighted"; function toggleCollapse() { setCollapsed(prevValue => !prevValue); @@ -23,7 +22,7 @@ function MenuItem({ depth = 0, expanded, item, currentPath, ...rest }) { toggleCollapse(); } - if (currentPath === routeVal(mainroute, route)) { + if (currentPath === route) { if (!highlightcolor) { setHighlightcolor(prevValue => !prevValue); } @@ -31,9 +30,6 @@ function MenuItem({ depth = 0, expanded, item, currentPath, ...rest }) { setHighlightcolor(prevValue => prevValue); } } - function routeVal(mainroute, route) { - return mainroute ? mainroute + route : route; - } let expandIcon; @@ -58,7 +54,7 @@ function MenuItem({ depth = 0, expanded, item, currentPath, ...rest }) { button dense {...rest} - to={routeVal(rest.mainroute, route)} + to={route} >
@@ -83,7 +79,6 @@ function MenuItem({ depth = 0, expanded, item, currentPath, ...rest }) { diff --git a/src/components/NestedAccordionMenu/index.stories.js b/src/components/NestedAccordionMenu/index.stories.js index 4fa9e7e..5232340 100644 --- a/src/components/NestedAccordionMenu/index.stories.js +++ b/src/components/NestedAccordionMenu/index.stories.js @@ -26,7 +26,7 @@ const subItems = [ { name: "Sub Journal one", Icon: InboxIcon, - route: "/sub_journal_one", + route: "project/6/journal/sub_journal_one", }, { name: "Sub Journal two", From 29746e97b714129a70b62c24e47d06977071b792 Mon Sep 17 00:00:00 2001 From: HAKIZIMANA Franck Date: Wed, 27 Nov 2019 13:31:43 +0200 Subject: [PATCH 7/8] remove unused variable --- src/components/NestedAccordionMenu/MenuItems/index.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/NestedAccordionMenu/MenuItems/index.js b/src/components/NestedAccordionMenu/MenuItems/index.js index 71511fe..95ad248 100644 --- a/src/components/NestedAccordionMenu/MenuItems/index.js +++ b/src/components/NestedAccordionMenu/MenuItems/index.js @@ -12,7 +12,6 @@ function MenuItem({ depth = 0, expanded, item, currentPath, ...rest }) { const [collapsed, setCollapsed] = useState(true); const [highlightcolor, setHighlightcolor] = useState(false); const { route, name, items, Icon } = item; - let highlightclass = "itemNohighlighted"; function toggleCollapse() { setCollapsed(prevValue => !prevValue); } @@ -40,7 +39,6 @@ function MenuItem({ depth = 0, expanded, item, currentPath, ...rest }) { ); } - highlightclass = highlightcolor ? "itemhighlighted" : "itemNohighlighted"; return (
Date: Thu, 28 Nov 2019 10:25:46 +0200 Subject: [PATCH 8/8] highlight an active menu and its parents --- .../NestedAccordionMenu/MenuItems/index.js | 96 ++++++++++--------- .../NestedAccordionMenu/MenuItems/styles.js | 12 +-- src/components/NestedAccordionMenu/index.js | 13 +-- .../NestedAccordionMenu/index.stories.js | 69 +++++++++---- 4 files changed, 111 insertions(+), 79 deletions(-) diff --git a/src/components/NestedAccordionMenu/MenuItems/index.js b/src/components/NestedAccordionMenu/MenuItems/index.js index 95ad248..0f7c382 100644 --- a/src/components/NestedAccordionMenu/MenuItems/index.js +++ b/src/components/NestedAccordionMenu/MenuItems/index.js @@ -6,80 +6,84 @@ import ExpandLessIcon from "@material-ui/icons/ExpandLess"; import Collapse from "@material-ui/core/Collapse"; import ListItemIcon from "@material-ui/core/ListItemIcon"; import ListItemText from "@material-ui/core/ListItemText"; +import classNames from "classnames"; import useStyles from "./styles"; -function MenuItem({ depth = 0, expanded, item, currentPath, ...rest }) { +function MenuItem(props) { + const { to, name, items, Icon, depth, expanded, currentPath } = props; const classes = useStyles({ depth: depth }); const [collapsed, setCollapsed] = useState(true); - const [highlightcolor, setHighlightcolor] = useState(false); - const { route, name, items, Icon } = item; + const hasSubItems = Array.isArray(items); function toggleCollapse() { setCollapsed(prevValue => !prevValue); } - function onClick(e) { - if (Array.isArray(items)) { - toggleCollapse(); - } - - if (currentPath === route) { - if (!highlightcolor) { - setHighlightcolor(prevValue => !prevValue); + let found = false; + function isChildrenActive(subItems) { + subItems.forEach(element => { + if (element.to === currentPath) { + found = true; + } + if (element.items) { + isChildrenActive(element.items); } - } else { - setHighlightcolor(prevValue => prevValue); - } + }); + return found; } + const active = to === currentPath && !hasSubItems; + const itemsTofilt = items; + const activeSubParent = items && isChildrenActive(items); let expandIcon; - if (Array.isArray(items) && items.length) { + if (hasSubItems && items.length) { expandIcon = !collapsed ? ( ) : ( ); } + const LinkComponent = props.link; return ( -
- -
- - {Icon && } - - -
- {expandIcon} -
-
+
+ + {Icon && } + + +
+ {expandIcon} + - {Array.isArray(items) ? ( - + {hasSubItems ? ( + {items && items.map((subItem, index) => ( - - - + ))} ) : null} @@ -87,5 +91,5 @@ function MenuItem({ depth = 0, expanded, item, currentPath, ...rest }) {
); } - +MenuItem.defaultProps = { depth: 0 }; export default MenuItem; diff --git a/src/components/NestedAccordionMenu/MenuItems/styles.js b/src/components/NestedAccordionMenu/MenuItems/styles.js index bdb7995..65543c7 100644 --- a/src/components/NestedAccordionMenu/MenuItems/styles.js +++ b/src/components/NestedAccordionMenu/MenuItems/styles.js @@ -13,15 +13,15 @@ export default makeStyles(theme => ({ display: "flex", alignItems: "center", width: "100%", - paddingLeft: props.depth * 10, + paddingLeft: props.depth * theme.spacing(4), }), collapse: { - background: "#dcdbdc", + background: "#f7f7f7", }, - itemhighlighted: { - color: "red", + activeColor: { + color: theme.palette.primary.main, }, - itemNohighlighted: { - color: "black", + activeBackground: { + background: "#efefef", }, })); diff --git a/src/components/NestedAccordionMenu/index.js b/src/components/NestedAccordionMenu/index.js index f74b813..199d9c4 100644 --- a/src/components/NestedAccordionMenu/index.js +++ b/src/components/NestedAccordionMenu/index.js @@ -8,19 +8,14 @@ const useStyles = makeStyles(theme => ({ backgroundColor: theme.palette.background.paper, }, })); -function Menu({ items, depth, expanded, currentPath, fontsize }) { + +function Menu({ items, ...rest }) { const classes = useStyles(); return ( - + {items && items.map((menuItem, index) => ( - + ))} ); diff --git a/src/components/NestedAccordionMenu/index.stories.js b/src/components/NestedAccordionMenu/index.stories.js index 5232340..b5aaf8e 100644 --- a/src/components/NestedAccordionMenu/index.stories.js +++ b/src/components/NestedAccordionMenu/index.stories.js @@ -21,17 +21,24 @@ stories .addDecorator(withKnobs) .addDecorator(jsxDecorator) .addDecorator(muiTheme([theme])); - +function Link(props) { + const { to, children, ...rest } = props; + return ( + + {children} + + ); +} const subItems = [ { name: "Sub Journal one", Icon: InboxIcon, - route: "project/6/journal/sub_journal_one", + to: "project/6/journal/sub_journal_one", }, { name: "Sub Journal two", Icon: InboxIcon, - route: "/sub_journal_one", + to: "/sub_journal_one", }, ]; const nestedItems = [ @@ -39,26 +46,46 @@ const nestedItems = [ name: "Journal", Icon: ListIcon, items: subItems, - route: "/journal", }, - { name: "Schedulers", Icon: ScheduleIcon, route: "/schedulers" }, - { name: "General", Icon: SettingsIcon, route: "/General" }, + { name: "Schedulers", Icon: ScheduleIcon, to: "/schedulers" }, + { name: "General", Icon: SettingsIcon, to: "/General" }, { name: "Org. Units", Icon: ShuffleIcon, - route: "/organisationunits", + to: "/organisationunits", }, - { name: "Org. Unit Groups", Icon: ShuffleIcon, route: "/org_unit_groups" }, - { name: "Category Options", Icon: ShuffleIcon, route: "/category_options" }, - { name: "Categories", Icon: ShuffleIcon, route: "/categories" }, - { name: "Category Cobos", Icon: ShuffleIcon, route: "/category_combos" }, - { name: "Data Elements", Icon: ShuffleIcon, route: "/data_elements" }, + { name: "Org. Unit Groups", Icon: ShuffleIcon, to: "/org_unit_groups" }, + { name: "Category Options", Icon: ShuffleIcon, to: "/category_options" }, + { name: "Categories", Icon: ShuffleIcon, to: "/categories" }, + { name: "Category Cobos", Icon: ShuffleIcon, to: "/category_combos" }, + { name: "Data Elements", Icon: ShuffleIcon, to: "/data_elements" }, { name: "Data Element Groups", Icon: ShuffleIcon, - route: "/data_element_groups", + to: "/data_element_groups", }, - { name: "Data Sets", route: "/data_sets" }, + { name: "Data Sets", to: "/data_sets" }, +]; + +const nestedItemsSecond = [ + { name: "Schedulers", Icon: ScheduleIcon, to: "/schedulers" }, + { name: "General", Icon: SettingsIcon, to: "/General" }, + { + name: "Org. Units", + Icon: ShuffleIcon, + to: "/organisationunits", + }, + { name: "Org. Unit Groups", Icon: ShuffleIcon, to: "/org_unit_groups" }, + { name: "Category Options", Icon: ShuffleIcon, to: "/category_options" }, + { name: "Categories", Icon: ShuffleIcon, to: "/categories" }, + { name: "Category Cobos", Icon: ShuffleIcon, to: "/category_combos" }, + { name: "Data Elements", Icon: ShuffleIcon, to: "/data_elements" }, + { + name: "Data Element Groups", + Icon: ShuffleIcon, + to: "/data_element_groups", + }, + { name: "Data Sets", to: "/data_sets" }, ]; const itemsCoreModules = [ @@ -66,25 +93,31 @@ const itemsCoreModules = [ name: "CordaidSIS to HIVDR", items: nestedItems, Icon: InboxIcon, - route: "project/5", }, { name: "SNIS REPLICA to HIVDR", items: nestedItems, Icon: InboxIcon, - route: "project/6", }, - , + { name: "DRC PROJECT", Icon: InboxIcon, - route: "project/7", + to: "project/6/journal/sub_journal_one", + }, + { + name: "SNIS REPLICA to HIVDR II", + items: nestedItemsSecond, + Icon: InboxIcon, }, ]; + // Knobs for React props + stories.add("Default", () => ( ));