From d6ebc37c1bcc108ba7db17f4d96ca79df2635610 Mon Sep 17 00:00:00 2001 From: Clemence Kyara Date: Sun, 20 Oct 2024 09:22:49 +0300 Subject: [PATCH 1/5] Implement TreeView via mui-x --- .../components/HURUmap/TreeView/TreeView.js | 205 ++++++++++++++++++ .../HURUmap/TreeView/TreeView.snap.js | 70 ++++++ .../HURUmap/TreeView/TreeView.test.js | 37 ++++ .../src/components/HURUmap/TreeView/index.js | 91 +------- .../HURUmap/TreeView/index.stories.js | 16 -- .../components/HURUmap/TreeView/useStyles.js | 51 ----- 6 files changed, 313 insertions(+), 157 deletions(-) create mode 100644 apps/climatemappedafrica/src/components/HURUmap/TreeView/TreeView.js create mode 100644 apps/climatemappedafrica/src/components/HURUmap/TreeView/TreeView.snap.js create mode 100644 apps/climatemappedafrica/src/components/HURUmap/TreeView/TreeView.test.js delete mode 100644 apps/climatemappedafrica/src/components/HURUmap/TreeView/index.stories.js delete mode 100644 apps/climatemappedafrica/src/components/HURUmap/TreeView/useStyles.js diff --git a/apps/climatemappedafrica/src/components/HURUmap/TreeView/TreeView.js b/apps/climatemappedafrica/src/components/HURUmap/TreeView/TreeView.js new file mode 100644 index 000000000..99d05c5ca --- /dev/null +++ b/apps/climatemappedafrica/src/components/HURUmap/TreeView/TreeView.js @@ -0,0 +1,205 @@ +import { Box, SvgIcon } from "@mui/material"; +import { styled } from "@mui/material/styles"; +import { SimpleTreeView } from "@mui/x-tree-view/SimpleTreeView"; +import { + TreeItem2Checkbox, + TreeItem2Content, + TreeItem2GroupTransition, + TreeItem2IconContainer, + TreeItem2Label, + TreeItem2Root, +} from "@mui/x-tree-view/TreeItem2"; +import { TreeItem2Icon } from "@mui/x-tree-view/TreeItem2Icon"; +import { TreeItem2Provider } from "@mui/x-tree-view/TreeItem2Provider"; +import { useTreeItem2 } from "@mui/x-tree-view/useTreeItem2"; +import clsx from "clsx"; +import PropTypes from "prop-types"; +import React from "react"; + +import CheckIcon from "@/climatemappedafrica/assets/icons/checked.svg"; +import slugify from "@/climatemappedafrica/utils/slugify"; + +const CustomTreeItemContent = styled(TreeItem2Content)(({ theme }) => ({ + background: "inherit", + borderRadius: 0, + borderBottom: `1px solid transparent`, + borderRight: `2px solid transparent`, + padding: 0, + "&:hover": { + background: "inherit", + }, + "&.expanded": { + borderRadius: 0, + backgroundColor: theme.palette.background.default, + borderRight: `2px solid ${theme.palette.primary.main}`, + borderBottom: `1px solid ${theme.palette.grey.main}`, + }, +})); + +const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { + const { id, itemId, label, disabled, children, ...other } = props; + + const { + getRootProps, + getContentProps, + getIconContainerProps, + getCheckboxProps, + getLabelProps, + getGroupTransitionProps, + status, + } = useTreeItem2({ id, itemId, children, label, disabled, rootRef: ref }); + + return ( + + + + + ({ + ...theme.typography.caption, + height: 38, + display: "flex", + alignItems: "center", + justifyContent: "flex-end", + fontWeight: 500, + letterSpacing: 0.6, + ...(!children && { + fontWeight: 300, + paddingRight: 2.5, + }), + }), + })} + /> + + + + + {children && ( + + )} + + + ); +}); + +function CollapseIcon({ sx, ...props }) { + return ( + + ); +} + +function ExpandIcon({ sx, ...props }) { + return ( + ({ + fill: theme.palette.grey.main, + }), + ...(Array.isArray(sx) ? sx : [sx]), + ]} + /> + ); +} + +const TreeView = React.forwardRef(function TreeView(props, ref) { + const { items, onLabelClick, sx, ...others } = props; + + const handleItemClick = (e, itemId) => { + e.preventDefault(); + + if (onLabelClick) { + onLabelClick(itemId); + } + }; + if (!items?.length) { + return null; + } + return ( + ({ + textAlign: "right", + background: palette.background.paper, + }), + ...(Array.isArray(sx) ? sx : [sx]), + ]} + ref={ref} + > + + {items.map((item) => { + const itemId = slugify(item.title); + + return ( + + {item.children.map((child) => { + const childId = slugify(`${itemId}-${child.title}`); + + return ( + + ); + })} + + ); + })} + + + ); +}); + +TreeView.propTypes = { + items: PropTypes.arrayOf( + PropTypes.shape({ + title: PropTypes.string, + children: PropTypes.arrayOf( + PropTypes.shape({ + title: PropTypes.string, + }), + ), + }), + ), + onLabelClick: PropTypes.func, +}; + +export default TreeView; diff --git a/apps/climatemappedafrica/src/components/HURUmap/TreeView/TreeView.snap.js b/apps/climatemappedafrica/src/components/HURUmap/TreeView/TreeView.snap.js new file mode 100644 index 000000000..f6e69b5d4 --- /dev/null +++ b/apps/climatemappedafrica/src/components/HURUmap/TreeView/TreeView.snap.js @@ -0,0 +1,70 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` renders unchanged 1`] = ` +
+
+
    + + +
+
+
+`; diff --git a/apps/climatemappedafrica/src/components/HURUmap/TreeView/TreeView.test.js b/apps/climatemappedafrica/src/components/HURUmap/TreeView/TreeView.test.js new file mode 100644 index 000000000..0a73dab2a --- /dev/null +++ b/apps/climatemappedafrica/src/components/HURUmap/TreeView/TreeView.test.js @@ -0,0 +1,37 @@ +import { createRender } from "@commons-ui/testing-library"; +import React from "react"; + +import TreeView from "."; + +import theme from "@/climatemappedafrica/theme"; + +// eslint-disable-next-line testing-library/render-result-naming-convention +const render = createRender({ theme }); + +const defaultProps = { + items: [ + { + title: "Annual Temperature", + children: [ + { + title: "Annual Temperature", + }, + ], + }, + { + title: "Temperature Variation", + children: [ + { + title: "Decadal Temperature Variation", + }, + ], + }, + ], +}; + +describe("", () => { + it("renders unchanged", () => { + const { container } = render(); + expect(container).toMatchSnapshot(); + }); +}); diff --git a/apps/climatemappedafrica/src/components/HURUmap/TreeView/index.js b/apps/climatemappedafrica/src/components/HURUmap/TreeView/index.js index 503066580..3abcc494d 100644 --- a/apps/climatemappedafrica/src/components/HURUmap/TreeView/index.js +++ b/apps/climatemappedafrica/src/components/HURUmap/TreeView/index.js @@ -1,92 +1,3 @@ -import TreeItem from "@mui/lab/TreeItem"; -import MuiTreeView from "@mui/lab/TreeView"; -import { Typography } from "@mui/material"; -import clsx from "clsx"; -import PropTypes from "prop-types"; -import React, { useState } from "react"; - -import useStyles from "./useStyles"; - -import CheckIcon from "@/climatemappedafrica/assets/icons/checked.svg"; -import slugify from "@/climatemappedafrica/utils/slugify"; - -function TreeView({ items, onLabelClick, ...props }) { - const classes = useStyles(props); - const [expanded, setExpanded] = useState(); - - const handleLabelClick = (e) => { - e.preventDefault(); - const { id, expand } = e.target.dataset; - if (expand) { - setExpanded(id); - } - if (onLabelClick) { - onLabelClick(id); - } - }; - - if (!items?.length) { - return null; - } - return ( -
- - {items.map((item) => { - const itemId = slugify(item.title); - - return ( - - - {item.title} - - - - } - onLabelClick={handleLabelClick} - classes={{ - root: classes.tree, - expanded: classes.expanded, - label: classes.label, - }} - > - {item.children.map((child) => { - const childId = slugify(`${itemId}-${child.title}`); - - return ( - - {child.title} - - } - onLabelClick={handleLabelClick} - classes={{ - label: clsx(classes.label, classes.childLabel), - }} - /> - ); - })} - - ); - })} - -
- ); -} - -TreeView.propTypes = { - items: PropTypes.arrayOf( - PropTypes.shape({ - children: PropTypes.arrayOf(PropTypes.shape({})), - }), - ), - onLabelClick: PropTypes.func, -}; +import TreeView from "./TreeView"; export default TreeView; diff --git a/apps/climatemappedafrica/src/components/HURUmap/TreeView/index.stories.js b/apps/climatemappedafrica/src/components/HURUmap/TreeView/index.stories.js deleted file mode 100644 index 95b1232c9..000000000 --- a/apps/climatemappedafrica/src/components/HURUmap/TreeView/index.stories.js +++ /dev/null @@ -1,16 +0,0 @@ -import React from "react"; - -import TreeView from "@/climatemappedafrica/components/HURUmap/TreeView"; - -export default { - title: "Components/HURUmap/TreeView", - argTypes: {}, -}; - -function Template({ ...args }) { - return ; -} - -export const Default = Template.bind({}); - -Default.args = {}; diff --git a/apps/climatemappedafrica/src/components/HURUmap/TreeView/useStyles.js b/apps/climatemappedafrica/src/components/HURUmap/TreeView/useStyles.js deleted file mode 100644 index 358158f13..000000000 --- a/apps/climatemappedafrica/src/components/HURUmap/TreeView/useStyles.js +++ /dev/null @@ -1,51 +0,0 @@ -import makeStyles from "@mui/styles/makeStyles"; - -const useStyles = makeStyles(({ typography, palette }) => ({ - root: { - textAlign: "right", - background: palette.background.paper, - "& .MuiTreeItem-root.Mui-selected > .MuiTreeItem-content .MuiTreeItem-label": - { - backgroundColor: "unset", - }, - "& .MuiTreeItem-iconContainer": { - width: 0, - }, - }, - label: { - marginRight: typography.pxToRem(20), - height: typography.pxToRem(38), - display: "flex", - alignItems: "center", - justifyContent: "flex-end", - fontWeight: 500, - letterSpacing: 0.6, - }, - childLabel: { - fontWeight: 300, - }, - icon: { - marginLeft: typography.pxToRem(20), - fill: palette.grey.main, - width: typography.pxToRem(19), - }, - tree: {}, - expanded: { - "& .MuiCollapse-root": { - marginLeft: 0, - borderTop: `1px solid ${palette.grey.main}`, - borderBottom: `1px solid ${palette.grey.main}`, - }, - "&> .MuiTreeItem-content": { - borderRightColor: palette.primary.main, - borderRightWidth: typography.pxToRem(2), - borderRightStyle: "Solid", - backgroundColor: palette.background.default, - }, - "& $icon": { - fill: "#666666", - }, - }, -})); - -export default useStyles; From debd31f4fc7450d3e935b2a0b0b9e71526d7b88d Mon Sep 17 00:00:00 2001 From: Clemence Kyara Date: Sun, 20 Oct 2024 09:23:36 +0300 Subject: [PATCH 2/5] Switch to sx where applicable --- .../HURUmap/Panel/DesktopPanel/RichData.js | 14 ++++++++++---- .../HURUmap/Panel/DesktopPanel/useStyles.js | 10 ---------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/apps/climatemappedafrica/src/components/HURUmap/Panel/DesktopPanel/RichData.js b/apps/climatemappedafrica/src/components/HURUmap/Panel/DesktopPanel/RichData.js index df3330c20..15ea17c0c 100644 --- a/apps/climatemappedafrica/src/components/HURUmap/Panel/DesktopPanel/RichData.js +++ b/apps/climatemappedafrica/src/components/HURUmap/Panel/DesktopPanel/RichData.js @@ -1,13 +1,10 @@ import PropTypes from "prop-types"; import React, { useRef } from "react"; -import useStyles from "./useStyles"; - import Profile from "@/climatemappedafrica/components/HURUmap/Panel/Profile"; import TreeView from "@/climatemappedafrica/components/HURUmap/TreeView"; function RichData({ primaryProfile, ...props }) { - const classes = useStyles(props); const profileRef = useRef(); const handleLabelClick = (id) => { @@ -22,7 +19,16 @@ function RichData({ primaryProfile, ...props }) { ({ + width: `calc((100vw - ${theme.widths.values.lg}px)/2 + 79px)`, + minWidth: theme.typography.pxToRem(300), + paddingTop: theme.typography.pxToRem(76), + flexShrink: 0, + top: theme.typography.pxToRem(110), + bottom: 0, + position: "fixed", + left: 0, + })} /> Date: Sun, 20 Oct 2024 09:24:43 +0300 Subject: [PATCH 3/5] Use appropriate deps --- apps/climatemappedafrica/package.json | 2 +- pnpm-lock.yaml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/climatemappedafrica/package.json b/apps/climatemappedafrica/package.json index 4f2310186..308612472 100644 --- a/apps/climatemappedafrica/package.json +++ b/apps/climatemappedafrica/package.json @@ -41,10 +41,10 @@ "@emotion/styled": "catalog:", "@hurumap/core": "workspace:*", "@hurumap/next": "workspace:*", - "@mui/lab": "catalog:mui-styles", "@mui/material": "catalog:mui-styles", "@mui/styles": "catalog:mui-styles", "@mui/utils": "catalog:mui-styles", + "@mui/x-tree-view": "catalog:", "@next/env": "catalog:", "@payloadcms/bundler-webpack": "catalog:", "@payloadcms/db-mongodb": "catalog:", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b1c903e82..5fb2fa8d8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1064,9 +1064,6 @@ importers: '@hurumap/next': specifier: workspace:* version: link:../../packages/hurumap-next - '@mui/lab': - specifier: catalog:mui-styles - version: 5.0.0-alpha.173(@emotion/react@11.13.3(@types/react@18.3.10)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.10)(react@18.3.1))(@types/react@18.3.10)(react@18.3.1))(@mui/material@5.16.7(@emotion/react@11.13.3(@types/react@18.3.10)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.10)(react@18.3.1))(@types/react@18.3.10)(react@18.3.1))(@types/react@18.3.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/material': specifier: catalog:mui-styles version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.10)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.10)(react@18.3.1))(@types/react@18.3.10)(react@18.3.1))(@types/react@18.3.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -1076,6 +1073,9 @@ importers: '@mui/utils': specifier: catalog:mui-styles version: 5.16.6(@types/react@18.3.10)(react@18.3.1) + '@mui/x-tree-view': + specifier: 'catalog:' + version: 7.18.0(@emotion/react@11.13.3(@types/react@18.3.10)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.10)(react@18.3.1))(@types/react@18.3.10)(react@18.3.1))(@mui/material@5.16.7(@emotion/react@11.13.3(@types/react@18.3.10)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.10)(react@18.3.1))(@types/react@18.3.10)(react@18.3.1))(@types/react@18.3.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.16.7(@emotion/react@11.13.3(@types/react@18.3.10)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.10)(react@18.3.1))(@types/react@18.3.10)(react@18.3.1))(@types/react@18.3.10)(react@18.3.1))(@types/react@18.3.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@next/env': specifier: 'catalog:' version: 14.2.13 From 085c35a7599db32a769b1aba0ffa5a1b6595b2e1 Mon Sep 17 00:00:00 2001 From: Clemence Kyara Date: Mon, 21 Oct 2024 16:52:10 +0300 Subject: [PATCH 4/5] Fix hover --- .../src/components/HURUmap/TreeView/TreeView.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/apps/climatemappedafrica/src/components/HURUmap/TreeView/TreeView.js b/apps/climatemappedafrica/src/components/HURUmap/TreeView/TreeView.js index 99d05c5ca..5a8f16faf 100644 --- a/apps/climatemappedafrica/src/components/HURUmap/TreeView/TreeView.js +++ b/apps/climatemappedafrica/src/components/HURUmap/TreeView/TreeView.js @@ -1,5 +1,5 @@ import { Box, SvgIcon } from "@mui/material"; -import { styled } from "@mui/material/styles"; +import { alpha, styled } from "@mui/material/styles"; import { SimpleTreeView } from "@mui/x-tree-view/SimpleTreeView"; import { TreeItem2Checkbox, @@ -25,6 +25,7 @@ const CustomTreeItemContent = styled(TreeItem2Content)(({ theme }) => ({ borderBottom: `1px solid transparent`, borderRight: `2px solid transparent`, padding: 0, + paddingRight: theme.spacing(2.5), "&:hover": { background: "inherit", }, @@ -59,9 +60,14 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { selected: status.selected, focused: status.focused, }), - sx: { - ...(children && { paddingRight: 2.5 }), - }, + sx: (theme) => ({ + ...(!children && { + pr: 0, + "&: hover": { + background: alpha(theme.palette.common.black, 0.04), + }, + }), + }), })} > From 141768c899d48c88d6b54749f51bd6ca7e4c840c Mon Sep 17 00:00:00 2001 From: Clemence Kyara Date: Mon, 21 Oct 2024 16:55:02 +0300 Subject: [PATCH 5/5] Remove unnecessary borderRadius styling --- .../src/components/HURUmap/TreeView/TreeView.js | 1 - .../src/components/HURUmap/TreeView/TreeView.snap.js | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/climatemappedafrica/src/components/HURUmap/TreeView/TreeView.js b/apps/climatemappedafrica/src/components/HURUmap/TreeView/TreeView.js index 5a8f16faf..78e4e47d0 100644 --- a/apps/climatemappedafrica/src/components/HURUmap/TreeView/TreeView.js +++ b/apps/climatemappedafrica/src/components/HURUmap/TreeView/TreeView.js @@ -30,7 +30,6 @@ const CustomTreeItemContent = styled(TreeItem2Content)(({ theme }) => ({ background: "inherit", }, "&.expanded": { - borderRadius: 0, backgroundColor: theme.palette.background.default, borderRight: `2px solid ${theme.palette.primary.main}`, borderBottom: `1px solid ${theme.palette.grey.main}`, diff --git a/apps/climatemappedafrica/src/components/HURUmap/TreeView/TreeView.snap.js b/apps/climatemappedafrica/src/components/HURUmap/TreeView/TreeView.snap.js index f6e69b5d4..dee356bbe 100644 --- a/apps/climatemappedafrica/src/components/HURUmap/TreeView/TreeView.snap.js +++ b/apps/climatemappedafrica/src/components/HURUmap/TreeView/TreeView.snap.js @@ -20,7 +20,7 @@ exports[` renders unchanged 1`] = ` tabindex="0" >
renders unchanged 1`] = ` tabindex="-1" >