From 93e25916268e33832e78a10e3b822c25f6902a56 Mon Sep 17 00:00:00 2001 From: Nora <72460825+noraleonte@users.noreply.github.com> Date: Thu, 9 May 2024 15:00:53 +0300 Subject: [PATCH] [website] Update MUI X deps and migrate TreeView demos to v7 API (#42149) Signed-off-by: Nora <72460825+noraleonte@users.noreply.github.com> Co-authored-by: Lukas Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> --- .../default-theme-viewer/JoyDefaultTheme.js | 4 +- .../default-theme/DefaultTheme.js | 4 +- docs/package.json | 10 +- docs/pages/_app.js | 2 +- .../components/productX/XDateRangeDemo.tsx | 4 +- .../src/components/productX/XTreeViewDemo.tsx | 532 ++++++++---------- .../components/showcase/FolderTreeView.tsx | 404 +++++++------ docs/src/modules/components/ThemeViewer.tsx | 45 +- pnpm-lock.yaml | 103 ++-- 9 files changed, 569 insertions(+), 539 deletions(-) diff --git a/docs/data/joy/customization/default-theme-viewer/JoyDefaultTheme.js b/docs/data/joy/customization/default-theme-viewer/JoyDefaultTheme.js index 7b83d51ed7c326..dbbabfb2304d3e 100644 --- a/docs/data/joy/customization/default-theme-viewer/JoyDefaultTheme.js +++ b/docs/data/joy/customization/default-theme-viewer/JoyDefaultTheme.js @@ -3,7 +3,7 @@ import { extendTheme } from '@mui/joy/styles'; import Box from '@mui/joy/Box'; import { ThemeProvider, createTheme } from '@mui/material/styles'; import ThemeViewer, { - useNodeIdsLazy, + useItemIdsLazy, } from 'docs/src/modules/components/ThemeViewer'; const defaultTheme = extendTheme(); @@ -39,7 +39,7 @@ export default function JoyDefaultTheme() { }, []); const data = defaultTheme; - const allNodeIds = useNodeIdsLazy(data); + const allNodeIds = useItemIdsLazy(data); React.useDebugValue(allNodeIds); return ( diff --git a/docs/data/material/customization/default-theme/DefaultTheme.js b/docs/data/material/customization/default-theme/DefaultTheme.js index 11d2dd6a76b8ca..582213931f24e1 100644 --- a/docs/data/material/customization/default-theme/DefaultTheme.js +++ b/docs/data/material/customization/default-theme/DefaultTheme.js @@ -6,7 +6,7 @@ import FormControlLabel from '@mui/material/FormControlLabel'; import Switch from '@mui/material/Switch'; import { useTranslate } from '@mui/docs/i18n'; import ThemeViewer, { - useNodeIdsLazy, + useItemIdsLazy, } from 'docs/src/modules/components/ThemeViewer'; import { blue, grey } from '@mui/docs/branding'; @@ -104,7 +104,7 @@ function DefaultTheme() { }); }, [darkTheme]); - const allNodeIds = useNodeIdsLazy(data); + const allNodeIds = useItemIdsLazy(data); React.useDebugValue(allNodeIds); React.useEffect(() => { if (checked) { diff --git a/docs/package.json b/docs/package.json index ae8a0a0098b33c..03cf7b78245cbc 100644 --- a/docs/package.json +++ b/docs/package.json @@ -43,15 +43,15 @@ "@mui/system": "workspace:^", "@mui/types": "workspace:^", "@mui/utils": "workspace:^", - "@mui/x-charts": "6.19.8", + "@mui/x-charts": "7.3.2", "@mui/x-data-grid": "7.3.1", "@mui/x-data-grid-generator": "7.3.1", "@mui/x-data-grid-premium": "7.3.1", "@mui/x-data-grid-pro": "7.3.1", - "@mui/x-date-pickers": "6.19.9", - "@mui/x-date-pickers-pro": "6.19.9", - "@mui/x-license-pro": "6.10.2", - "@mui/x-tree-view": "6.17.0", + "@mui/x-date-pickers": "7.3.2", + "@mui/x-date-pickers-pro": "7.3.2", + "@mui/x-license": "7.2.0", + "@mui/x-tree-view": "7.3.1", "@popperjs/core": "^2.11.8", "@react-spring/web": "^9.7.3", "autoprefixer": "^10.4.19", diff --git a/docs/pages/_app.js b/docs/pages/_app.js index 7ba45523219f4e..b17a4b54351526 100644 --- a/docs/pages/_app.js +++ b/docs/pages/_app.js @@ -5,7 +5,7 @@ import { loadCSS } from 'fg-loadcss/src/loadCSS'; import NextHead from 'next/head'; import PropTypes from 'prop-types'; import { useRouter } from 'next/router'; -import { LicenseInfo } from '@mui/x-data-grid-pro'; +import { LicenseInfo } from '@mui/x-license'; import materialPkgJson from 'packages/mui-material/package.json'; import joyPkgJson from 'packages/mui-joy/package.json'; import systemPkgJson from 'packages/mui-system/package.json'; diff --git a/docs/src/components/productX/XDateRangeDemo.tsx b/docs/src/components/productX/XDateRangeDemo.tsx index 679a2b824c2ff3..1acc8b4ea99527 100644 --- a/docs/src/components/productX/XDateRangeDemo.tsx +++ b/docs/src/components/productX/XDateRangeDemo.tsx @@ -19,7 +19,7 @@ const endDate = new Date(); endDate.setDate(endDate.getDate() + 28); function CustomRangeShortcuts(props: PickersShortcutsProps>) { - const { items, onChange, isValid } = props; + const { items, onChange, isValid, changeImportance = 'accept' } = props; if (items == null || items.length === 0) { return null; @@ -31,7 +31,7 @@ function CustomRangeShortcuts(props: PickersShortcutsProps>) { return { label: item.label, onClick: () => { - onChange(newValue); + onChange(newValue, changeImportance, item); }, disabled: !isValid(newValue), }; diff --git a/docs/src/components/productX/XTreeViewDemo.tsx b/docs/src/components/productX/XTreeViewDemo.tsx index 7cf620c9935071..23b34d381c4def 100644 --- a/docs/src/components/productX/XTreeViewDemo.tsx +++ b/docs/src/components/productX/XTreeViewDemo.tsx @@ -1,261 +1,274 @@ import * as React from 'react'; import clsx from 'clsx'; +import { animated, useSpring } from '@react-spring/web'; import { styled } from '@mui/material/styles'; +import { TransitionProps } from '@mui/material/transitions'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; +import Frame from 'docs/src/components/action/Frame'; import Box from '@mui/material/Box'; -import Paper from '@mui/material/Paper'; -import { TreeView } from '@mui/x-tree-view/TreeView'; -import { - TreeItem as MuiTreeItem, - useTreeItem, - TreeItemProps, - TreeItemContentProps, -} from '@mui/x-tree-view/TreeItem'; +import Collapse from '@mui/material/Collapse'; import Typography from '@mui/material/Typography'; +import Paper from '@mui/material/Paper'; import FolderRounded from '@mui/icons-material/FolderRounded'; import FolderOpenRounded from '@mui/icons-material/FolderOpenRounded'; -import PhotoOutlined from '@mui/icons-material/PhotoOutlined'; -import PictureAsPdfOutlined from '@mui/icons-material/PictureAsPdfOutlined'; -import VideocamOutlined from '@mui/icons-material/VideocamOutlined'; -import FourKOutlined from '@mui/icons-material/FourKOutlined'; -import { HighlightedCode } from '@mui/docs/HighlightedCode'; -import Frame from 'docs/src/components/action/Frame'; +import ImageIcon from '@mui/icons-material/Image'; +import PictureAsPdfIcon from '@mui/icons-material/PictureAsPdf'; +import VideoCameraBackIcon from '@mui/icons-material/VideoCameraBack'; +import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; +import { treeItemClasses } from '@mui/x-tree-view/TreeItem'; +import { + unstable_useTreeItem2 as useTreeItem2, + UseTreeItem2Parameters, +} from '@mui/x-tree-view/useTreeItem2'; +import { + TreeItem2Content, + 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 { TreeViewBaseItem } from '@mui/x-tree-view/models'; -const CustomContent = React.forwardRef(function CustomContent( - props: TreeItemContentProps & { lastNestedChild?: boolean }, - ref, -) { - const { - lastNestedChild, - classes, - className, - label, - nodeId, - icon: iconProp, - expansionIcon, - displayIcon, - } = props; +type FileType = 'image' | 'pdf' | 'video' | 'folder'; - const { - disabled, - expanded, - selected, - focused, - handleExpansion, - handleSelection, - preventSelection, - } = useTreeItem(nodeId); +type ExtendedTreeItemProps = { + fileType?: FileType; + id: string; + label: string; +}; - const icon = iconProp || expansionIcon || displayIcon; +const ITEMS: TreeViewBaseItem[] = [ + { + id: '1', + label: 'Drive', + children: [ + { + id: '1.1', + label: 'Backup', + children: [ + { id: '1.1.1', label: 'Jan 2023.pdf', fileType: 'pdf' }, + { id: '1.1.2', label: 'Feb 2023.pdf', fileType: 'pdf' }, + { id: '1.1.3', label: 'Mar 2023.pdf', fileType: 'pdf' }, + ], + }, + { + id: '1.2', + label: 'Photos', + children: [ + { id: '1.2.1', label: 'family.jpeg', fileType: 'image' }, + { id: '1.2.2', label: 'my_dog.png', fileType: 'image' }, + ], + }, + ], + }, + { + id: '2', + label: 'Favorites', + children: [ + { + id: '2.1', + label: 'MUI_retreat_photo.jpg', + fileType: 'image', + }, + { + id: '2.2', + label: 'v7_secrets.mkv', + fileType: 'video', + }, + { + id: '2.3', + label: 'Other pictures', + children: [{ id: '2.3.1', label: 'my_avatar.jpeg', fileType: 'image' }], + }, + ], + }, +]; - const handleMouseDown = (event: React.MouseEvent) => { - preventSelection(event); - }; +declare module 'react' { + interface CSSProperties { + '--tree-view-color'?: string; + '--tree-view-bg-color'?: string; + } +} - const handleExpansionClick = (event: React.MouseEvent) => { - handleExpansion(event); - handleSelection(event); - }; +const StyledTreeItemRoot = styled(TreeItem2Root)(({ theme }) => ({ + color: theme.palette.mode === 'light' ? theme.palette.grey[800] : theme.palette.grey[400], + position: 'relative', + [`& .${treeItemClasses.groupTransition}`]: { + marginLeft: theme.spacing(3.5), + }, +})) as unknown as typeof TreeItem2Root; - const handleSelectionClick = (event: React.MouseEvent) => { - handleSelection(event); - }; +const CustomTreeItemContent = styled(TreeItem2Content)(({ theme }) => ({ + borderRadius: theme.spacing(0.5), + marginBottom: theme.spacing(0.2), + marginTop: theme.spacing(0.2), + padding: `${theme.spacing(0.3)} ${theme.spacing(0.5)}`, + '&.Mui-expanded&::before': { + content: '""', + display: 'block', + position: 'absolute', + left: '16px', + top: '30px', + height: 'calc(100% - 32px)', + width: '1.5px', + backgroundColor: + theme.palette.mode === 'light' + ? (theme.vars || theme).palette.grey[100] + : (theme.vars || theme).palette.primaryDark[700], + }, +})); - const renderExtension = () => { - if (typeof label !== 'string') { - return label; - } - const extension = (label || '').split('.').slice(-1)[0]; - if (extension.match(/(jpg|jpeg|png)/)) { - return ; - } - if (extension === 'pdf') { - return ; - } - if (extension === 'mp4') { - return ; - } - if (extension === 'mkv') { - return ; - } - return ( - - ); - }; +const AnimatedCollapse = animated(Collapse); + +function TransitionComponent(props: TransitionProps) { + const style = useSpring({ + to: { + opacity: props.in ? 1 : 0, + transform: `translate3d(0,${props.in ? 0 : 20}px,0)`, + paddingLeft: 24, + }, + }); + + return ; +} +interface CustomLabelProps { + children: React.ReactNode; + icon?: React.ElementType; + expandable?: boolean; +} + +function CustomLabel({ icon: Icon, expandable, children, ...other }: CustomLabelProps) { return ( - /* @ts-ignore -- Key event is handled by the TreeView */ - } + - {icon} - {lastNestedChild && renderExtension()} - {!lastNestedChild && (expanded ? : )} + {Icon && ( + ({ + mr: 1, + fontSize: '1rem', + color: expandable ? theme.palette.primary.main : theme.palette.grey[600], + })} + /> + )} + ({ + fontWeight: expandable + ? theme.typography.fontWeightMedium + : theme.typography.fontWeightRegular, + color: expandable ? theme.palette.text.primary : theme.palette.text.secondary, + })} + variant="body2" > - {label} + {children} - + ); -}); +} -const StyledTreeItem = styled(MuiTreeItem)(({ theme }) => [ - { - paddingTop: 5, - '& .MuiTreeItem-content .MuiTreeItem-label': { - paddingLeft: theme.spacing(0.75), - }, - '& .MuiTreeItem-root': { - position: 'relative', - '&::before': { - content: '""', - display: 'block', - position: 'absolute', - left: -14, - height: '100%', - width: 1.5, - backgroundColor: (theme.vars || theme).palette.grey[100], - }, - }, - '& .MuiTreeItem-content': { - padding: theme.spacing('2px', 0.5), - }, - '& .MuiTreeItem-group': { - marginLeft: 0, - paddingLeft: theme.spacing(3), - }, - }, - theme.applyDarkStyles({ - '& .MuiTreeItem-root': { - '&::before': { - backgroundColor: (theme.vars || theme).palette.primaryDark[700], - }, - }, - '& .MuiTreeItem-group': { - '& .MuiTreeItem-content': { - '&::before': { - backgroundColor: (theme.vars || theme).palette.primaryDark[500], - }, - }, - }, - }), -]); +const isExpandable = (reactChildren: React.ReactNode) => { + if (Array.isArray(reactChildren)) { + return reactChildren.length > 0 && reactChildren.some(isExpandable); + } + return Boolean(reactChildren); +}; -const TreeItem = React.forwardRef(function TreeItem( - props: TreeItemProps & { - ContentProps?: { lastNestedChild?: boolean }; - }, +const getIconFromFileType = (fileType: FileType) => { + switch (fileType) { + case 'image': + return ImageIcon; + case 'pdf': + return PictureAsPdfIcon; + case 'video': + return VideoCameraBackIcon; + case 'folder': + return FolderRounded; + default: + return FolderRounded; + } +}; + +interface CustomTreeItemProps + extends Omit, + Omit, 'onFocus'> {} + +const CustomTreeItem = React.forwardRef(function CustomTreeItem( + props: CustomTreeItemProps, ref: React.Ref, ) { - return ; + const { id, itemId, label, disabled, children, ...other } = props; + + const { + getRootProps, + getContentProps, + getIconContainerProps, + getLabelProps, + getGroupTransitionProps, + status, + publicAPI, + } = useTreeItem2({ id, itemId, children, label, disabled, rootRef: ref }); + + const item = publicAPI.getItem(itemId); + const expandable = isExpandable(children); + let icon; + if (expandable) { + if (status.expanded) { + icon = FolderOpenRounded; + } else { + icon = FolderRounded; + } + } else if (item.fileType) { + icon = getIconFromFileType(item.fileType); + } + + return ( + + + + {expandable && ( + + + + )} + + + + {children && } + + + ); }); const code = ` - - - - - - - - - - - - - - - - - - - -`; +`; -export default function XDateRangeDemo() { +export default function XTreeViewDemo() { return ( @@ -265,67 +278,20 @@ export default function XDateRangeDemo() { maxWidth: '100%', bgcolor: '#FFF', borderRadius: '8px', + padding: 2, ...theme.applyDarkStyles({ bgcolor: 'primaryDark.900', }), })} > - - - - - - - - - - - - - - - - - - - - + diff --git a/docs/src/components/showcase/FolderTreeView.tsx b/docs/src/components/showcase/FolderTreeView.tsx index b5db11f3404cbe..806c63a0f388f5 100644 --- a/docs/src/components/showcase/FolderTreeView.tsx +++ b/docs/src/components/showcase/FolderTreeView.tsx @@ -1,210 +1,266 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ import * as React from 'react'; import clsx from 'clsx'; +import { animated, useSpring } from '@react-spring/web'; import { styled } from '@mui/material/styles'; +import { TransitionProps } from '@mui/material/transitions'; import Box from '@mui/material/Box'; -import { TreeView } from '@mui/x-tree-view/TreeView'; -import { - TreeItem, - useTreeItem, - TreeItemProps, - TreeItemContentProps, -} from '@mui/x-tree-view/TreeItem'; +import Collapse from '@mui/material/Collapse'; import Typography from '@mui/material/Typography'; import KeyboardArrowDownRounded from '@mui/icons-material/KeyboardArrowDownRounded'; import KeyboardArrowUpRounded from '@mui/icons-material/KeyboardArrowUpRounded'; import FolderRounded from '@mui/icons-material/FolderRounded'; +import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; +import { treeItemClasses } from '@mui/x-tree-view/TreeItem'; +import { + unstable_useTreeItem2 as useTreeItem2, + UseTreeItem2Parameters, +} from '@mui/x-tree-view/useTreeItem2'; +import { + TreeItem2Content, + 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 { TreeViewBaseItem } from '@mui/x-tree-view/models'; -const CustomContent = React.forwardRef(function CustomContent( - props: TreeItemContentProps & { lastNestedChild?: boolean }, - ref, -) { - const { - lastNestedChild, - classes, - className, - label, - nodeId, - icon: iconProp, - expansionIcon, - displayIcon, - } = props; +type ExtendedTreeItemProps = { + id: string; + label: string; + color?: 'primary' | 'default'; +}; - const { - disabled, - expanded, - selected, - focused, - handleExpansion, - handleSelection, - preventSelection, - } = useTreeItem(nodeId); +const ITEMS: TreeViewBaseItem[] = [ + { + id: '1', + label: 'src', + color: 'primary', + children: [ + { + id: '1.1', + label: 'components', + children: [ + { id: '1.1.1', label: 'Button.tsx' }, + { id: '1.1.2', label: 'Drawer.tsx' }, + { id: '1.1.3', label: 'Navbar.tsx' }, + { id: '1.1.4', label: 'TreeView.tsx' }, + ], + }, + { + id: '1.2', + label: 'blocks', + children: [ + { id: '1.2.1', label: 'SignupPage.tsx' }, + { + id: '1.2.2', + label: 'PricingTable', + children: [ + { id: '1.2.2.1', label: 'PaymentOptions.tsx' }, + { id: '1.2.2.2', label: 'EarlyBirdDiscount.tsx' }, + ], + }, + ], + }, + ], + }, +]; + +function DotIcon() { + return ( + + ); +} - const icon = iconProp || expansionIcon || displayIcon; +declare module 'react' { + interface CSSProperties { + '--tree-view-color'?: string; + '--tree-view-bg-color'?: string; + } +} + +const StyledTreeItemRoot = styled(TreeItem2Root)(({ theme }) => ({ + color: theme.palette.mode === 'light' ? theme.palette.grey[800] : theme.palette.grey[400], + position: 'relative', + [`& .${treeItemClasses.groupTransition}`]: { + paddingLeft: theme.spacing(0.5), + }, +})) as unknown as typeof TreeItem2Root; + +const CustomTreeItemContent = styled(TreeItem2Content)(({ theme }) => ({ + borderRadius: theme.spacing(0.5), - const handleMouseDown = (event: React.MouseEvent) => { - preventSelection(event); - }; + '&.Mui-expanded&::before': { + content: '""', + display: 'block', + position: 'absolute', + left: '15px', + top: '28px', + height: 'calc(100% - 28px)', + width: '1.5px', + backgroundColor: + theme.palette.mode === 'light' + ? (theme.vars || theme).palette.grey[100] + : (theme.vars || theme).palette.primaryDark[700], + }, +})); + +const AnimatedCollapse = animated(Collapse); - const handleExpansionClick = (event: React.MouseEvent) => { - handleExpansion(event); - }; +function TransitionComponent(props: TransitionProps) { + const style = useSpring({ + to: { + opacity: props.in ? 1 : 0, + transform: `translate3d(0,${props.in ? 0 : 20}px,0)`, + paddingLeft: 24, + }, + }); - const handleSelectionClick = (event: React.MouseEvent) => { - handleSelection(event); - }; + return ; +} +interface CustomLabelProps { + children: React.ReactNode; + expandable?: boolean; + color: string; +} + +function CustomLabel({ color, expandable, children, ...other }: CustomLabelProps) { + let Icon; + if (expandable) { + Icon = FolderRounded; + } else { + Icon = DotIcon; + } return ( -
} + - {lastNestedChild ? ( + {Icon && ( - ) : ( - )} + ({ + fontWeight: expandable + ? theme.typography.fontWeightMedium + : theme.typography.fontWeightRegular, + })} + variant="body2" > - {label} + {children} - {icon} -
+ ); -}); +} -const StyledTreeItem = styled(TreeItem)(({ theme }) => [ - { - '& .MuiTreeItem-content': { - border: 'none', - backgroundColor: 'transparent', - borderRadius: 5, - padding: theme.spacing(0.5), - textAlign: 'left', - position: 'relative', - zIndex: 1, - }, - '& .MuiTreeItem-content .MuiTreeItem-label': { - paddingLeft: theme.spacing(1), - }, - '& .MuiTreeItem-root': { - position: 'relative', - '&::before': { - content: '""', - display: 'block', - position: 'absolute', - left: -14, - height: '100%', - width: 1.5, - backgroundColor: (theme.vars || theme).palette.grey[200], - }, - }, - '& .MuiTreeItem-group': { - marginLeft: 0, - paddingLeft: theme.spacing(3), - }, - }, - theme.applyDarkStyles({ - '& .MuiTreeItem-root': { - '&::before': { - backgroundColor: (theme.vars || theme).palette.primaryDark[600], - }, - }, - '& .MuiTreeItem-group': { - '& .MuiTreeItem-content': { - '&::before': { - backgroundColor: (theme.vars || theme).palette.primaryDark[600], - }, - }, - }, - }), -]); +const isExpandable = (reactChildren: React.ReactNode): boolean => { + if (Array.isArray(reactChildren)) { + return reactChildren.length > 0 && reactChildren.some(isExpandable); + } + return Boolean(reactChildren); +}; + +interface CustomTreeItemProps + extends Omit, + Omit, 'onFocus'> {} const CustomTreeItem = React.forwardRef(function CustomTreeItem( - props: TreeItemProps & { - ContentProps?: { lastNestedChild?: boolean }; - }, + props: CustomTreeItemProps, ref: React.Ref, ) { - return ; -}); + const { id, itemId, label, disabled, children, ...other } = props; + + const { + getRootProps, + getContentProps, + getIconContainerProps, + getLabelProps, + getGroupTransitionProps, + status, + publicAPI, + } = useTreeItem2({ id, itemId, children, label, disabled, rootRef: ref }); + + const item = publicAPI.getItem(itemId); + const expandable = isExpandable(children); -export default function FolderTreeView() { return ( - } - defaultExpandIcon={} - defaultEndIcon={
} - sx={{ p: 1, overflowY: 'auto' }} - > - - - - - - - - - + + + - - - - - - - + {expandable && ( + + + + )} + + {children && }{' '} + + + ); +}); +function CustomEndIcon() { + return
; +} + +function CustomExpandIcon() { + return ; +} + +function CustomCollapseIcon() { + return ; +} + +export default function TreeViewDemo() { + return ( + ); } diff --git a/docs/src/modules/components/ThemeViewer.tsx b/docs/src/modules/components/ThemeViewer.tsx index 60ddb10417cd1f..f9f4a07d22fe54 100644 --- a/docs/src/modules/components/ThemeViewer.tsx +++ b/docs/src/modules/components/ThemeViewer.tsx @@ -4,7 +4,7 @@ import { styled, alpha, lighten } from '@mui/material/styles'; import Box from '@mui/material/Box'; import ExpandIcon from '@mui/icons-material/ExpandMore'; import CollapseIcon from '@mui/icons-material/ChevronRight'; -import { TreeView } from '@mui/x-tree-view/TreeView'; +import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; import { TreeItem as MuiTreeItem, treeItemClasses } from '@mui/x-tree-view/TreeItem'; import { blue, blueDark } from '@mui/docs/branding'; @@ -96,6 +96,10 @@ function ObjectEntryLabel(props: { objectKey: string; objectValue: any }) { ); } +function CustomEndIcon() { + return
; +} + const TreeItem = styled(MuiTreeItem)(({ theme }) => ({ [`& .${treeItemClasses.content}`]: { padding: 4, @@ -116,9 +120,9 @@ const TreeItem = styled(MuiTreeItem)(({ theme }) => ({ }, })); -function ObjectEntry(props: { nodeId: string; objectKey: string; objectValue: any }) { - const { nodeId, objectKey, objectValue } = props; - const keyPrefix = nodeId; +function ObjectEntry(props: { itemId: string; objectKey: string; objectValue: any }) { + const { itemId, objectKey, objectValue } = props; + const keyPrefix = itemId; let children = null; if ( @@ -132,7 +136,7 @@ function ObjectEntry(props: { nodeId: string; objectKey: string; objectValue: an return ( @@ -142,7 +146,7 @@ function ObjectEntry(props: { nodeId: string; objectKey: string; objectValue: an return ( } > {children} @@ -150,11 +154,11 @@ function ObjectEntry(props: { nodeId: string; objectKey: string; objectValue: an ); } -function computeNodeIds(object: Record, prefix: string) { +function computeItemIds(object: Record, prefix: string) { if ((object !== null && typeof object === 'object') || typeof object === 'function') { const ids: Array = []; Object.keys(object).forEach((key) => { - ids.push(`${prefix}${key}`, ...computeNodeIds(object[key], `${prefix}${key}.`)); + ids.push(`${prefix}${key}`, ...computeItemIds(object[key], `${prefix}${key}.`)); }); return ids; @@ -162,16 +166,16 @@ function computeNodeIds(object: Record, prefix: string) { return []; } -export function useNodeIdsLazy(object: Record) { - const [allNodeIds, setAllNodeIds] = React.useState>([]); +export function useItemIdsLazy(object: Record) { + const [allItemIds, setAllItemIds] = React.useState>([]); // technically we want to compute them lazily until we need them (expand all) // yielding is good enough. technically we want to schedule the computation // with low pri and upgrade the priority later React.useEffect(() => { - setAllNodeIds(computeNodeIds(object, '')); + setAllItemIds(computeItemIds(object, '')); }, [object]); - return allNodeIds; + return allItemIds; } const keyPrefix = '$ROOT'; @@ -193,14 +197,15 @@ export default function ThemeViewer({ ); // for default* to take effect we need to remount const key = React.useMemo(() => defaultExpanded.join(''), [defaultExpanded]); - return ( - } - defaultEndIcon={
} - defaultExpanded={defaultExpanded} - defaultExpandIcon={} + slots={{ + expandIcon: ExpandIcon, + collapseIcon: CollapseIcon, + endIcon: CustomEndIcon, + }} + defaultExpandedItems={defaultExpanded} {...other} sx={{ color: '#FFF', @@ -214,12 +219,12 @@ export default function ThemeViewer({ return ( ); })} - + ); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 084e87b971836e..fdcb9245f17c06 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -647,8 +647,8 @@ importers: specifier: workspace:^ version: link:../packages/mui-utils/build '@mui/x-charts': - specifier: 6.19.8 - version: 6.19.8(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + specifier: 7.3.2 + version: 7.3.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@mui/material@packages+mui-material+build)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@mui/x-data-grid': specifier: 7.3.1 version: 7.3.1(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@mui/material@packages+mui-material+build)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) @@ -662,17 +662,17 @@ importers: specifier: 7.3.1 version: 7.3.1(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@mui/material@packages+mui-material+build)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@mui/x-date-pickers': - specifier: 6.19.9 - version: 6.19.9(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.55)(date-fns-jalali@2.21.3-1)(date-fns@2.30.0)(react-dom@18.2.0)(react@18.2.0) + specifier: 7.3.2 + version: 7.3.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@mui/material@packages+mui-material+build)(@types/react@18.2.55)(date-fns-jalali@2.21.3-1)(date-fns@2.30.0)(react-dom@18.2.0)(react@18.2.0) '@mui/x-date-pickers-pro': - specifier: 6.19.9 - version: 6.19.9(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.55)(date-fns-jalali@2.21.3-1)(date-fns@2.30.0)(react-dom@18.2.0)(react@18.2.0) - '@mui/x-license-pro': - specifier: 6.10.2 - version: 6.10.2(@types/react@18.2.55)(react@18.2.0) + specifier: 7.3.2 + version: 7.3.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@mui/material@packages+mui-material+build)(@types/react@18.2.55)(date-fns-jalali@2.21.3-1)(date-fns@2.30.0)(react-dom@18.2.0)(react@18.2.0) + '@mui/x-license': + specifier: 7.2.0 + version: 7.2.0(@types/react@18.2.55)(react@18.2.0) '@mui/x-tree-view': - specifier: 6.17.0 - version: 6.17.0(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + specifier: 7.3.1 + version: 7.3.1(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@mui/material@packages+mui-material+build)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@popperjs/core': specifier: ^2.11.8 version: 2.11.8 @@ -5725,14 +5725,13 @@ packages: react: 18.2.0 react-is: 18.2.0 - /@mui/x-charts@6.19.8(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-cjwsCJrUPDlMytJHBV+g3gDoSRURiphjclZs8sRnkZ+h4QbHn24K5QkK4bxEj7aCkO2HVJmDE0aqYEg4BnWCOA==} + /@mui/x-charts@7.3.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@mui/material@packages+mui-material+build)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-620eMe83R0RDZk0S7ExYFRM2yZLlEOyIZmP5zwwVujZg54OC1fwLsk0tiaFaVZQOBKmeFOtyltDNPxr9e6itJQ==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.9.0 '@emotion/styled': ^11.8.1 - '@mui/material': ^5.4.1 - '@mui/system': ^5.4.1 + '@mui/material': ^5.15.14 react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 peerDependenciesMeta: @@ -5744,13 +5743,16 @@ packages: '@babel/runtime': 7.24.5 '@emotion/react': 11.11.4(@types/react@18.2.55)(react@18.2.0) '@emotion/styled': 11.11.5(@emotion/react@11.11.4)(@types/react@18.2.55)(react@18.2.0) - '@mui/base': 5.0.0-beta.30(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@mui/base': 5.0.0-beta.40(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@mui/material': link:packages/mui-material/build - '@mui/system': link:packages/mui-system/build + '@mui/system': 5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@types/react@18.2.55)(react@18.2.0) + '@mui/utils': 5.15.14(@types/react@18.2.55)(react@18.2.0) '@react-spring/rafz': 9.7.3 '@react-spring/web': 9.7.3(react-dom@18.2.0)(react@18.2.0) clsx: 2.1.1 d3-color: 3.1.0 + d3-delaunay: 6.0.4 + d3-interpolate: 3.0.1 d3-scale: 4.0.2 d3-shape: 3.2.0 prop-types: 15.8.1 @@ -5861,14 +5863,13 @@ packages: - '@types/react' dev: false - /@mui/x-date-pickers-pro@6.19.9(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.55)(date-fns-jalali@2.21.3-1)(date-fns@2.30.0)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-0EmWiRoZUc3ZGin3EdJaYNuCS5PA45KHEc9HkCmkT6sAnPeXMVpXrl8TFJvJxFVV6Vp7IYV8RZHC5gSZcfIrfQ==} + /@mui/x-date-pickers-pro@7.3.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@mui/material@packages+mui-material+build)(@types/react@18.2.55)(date-fns-jalali@2.21.3-1)(date-fns@2.30.0)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-ZmEzWp9ujB+7K1+oz5kIbcXOEI1iKZXQv9NZOBa8knQpqjTnETU5fGHmcyHnfXgf2rZS4bhMseKjtOOeUIYkMA==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.9.0 '@emotion/styled': ^11.8.1 - '@mui/material': ^5.8.6 - '@mui/system': ^5.8.0 + '@mui/material': ^5.15.14 date-fns: ^2.25.0 || ^3.2.0 date-fns-jalali: ^2.13.0-0 dayjs: ^1.10.7 @@ -5901,12 +5902,12 @@ packages: '@babel/runtime': 7.24.5 '@emotion/react': 11.11.4(@types/react@18.2.55)(react@18.2.0) '@emotion/styled': 11.11.5(@emotion/react@11.11.4)(@types/react@18.2.55)(react@18.2.0) - '@mui/base': 5.0.0-beta.30(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@mui/base': 5.0.0-beta.40(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@mui/material': link:packages/mui-material/build - '@mui/system': link:packages/mui-system/build + '@mui/system': 5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@types/react@18.2.55)(react@18.2.0) '@mui/utils': 5.15.14(@types/react@18.2.55)(react@18.2.0) - '@mui/x-date-pickers': 6.19.9(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.55)(date-fns-jalali@2.21.3-1)(date-fns@2.30.0)(react-dom@18.2.0)(react@18.2.0) - '@mui/x-license-pro': 6.10.2(@types/react@18.2.55)(react@18.2.0) + '@mui/x-date-pickers': 7.3.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@mui/material@packages+mui-material+build)(@types/react@18.2.55)(date-fns-jalali@2.21.3-1)(date-fns@2.30.0)(react-dom@18.2.0)(react@18.2.0) + '@mui/x-license': 7.2.0(@types/react@18.2.55)(react@18.2.0) clsx: 2.1.1 date-fns: 2.30.0 date-fns-jalali: 2.21.3-1 @@ -5918,14 +5919,13 @@ packages: - '@types/react' dev: false - /@mui/x-date-pickers@6.19.9(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.55)(date-fns-jalali@2.21.3-1)(date-fns@2.30.0)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-B2m4Fv/fOme5qmV6zuE3QnWQSvj3zKtI2OvikPz5prpiCcIxqpeytkQ7VfrWH3/Aqd5yhG1Yr4IgbqG0ymIXGg==} + /@mui/x-date-pickers@7.3.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@mui/material@packages+mui-material+build)(@types/react@18.2.55)(date-fns-jalali@2.21.3-1)(date-fns@2.30.0)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-i7JaDs1eXSZWyJihfszUHVV0t/C2HvtdMv5tHwv3E3enMx5Hup1vkJ64vZAH2fgGrTHQH8mjxvVsmI6jhDXIUg==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.9.0 '@emotion/styled': ^11.8.1 - '@mui/material': ^5.8.6 - '@mui/system': ^5.8.0 + '@mui/material': ^5.15.14 date-fns: ^2.25.0 || ^3.2.0 date-fns-jalali: ^2.13.0-0 dayjs: ^1.10.7 @@ -5958,9 +5958,9 @@ packages: '@babel/runtime': 7.24.5 '@emotion/react': 11.11.4(@types/react@18.2.55)(react@18.2.0) '@emotion/styled': 11.11.5(@emotion/react@11.11.4)(@types/react@18.2.55)(react@18.2.0) - '@mui/base': 5.0.0-beta.30(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@mui/base': 5.0.0-beta.40(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@mui/material': link:packages/mui-material/build - '@mui/system': link:packages/mui-system/build + '@mui/system': 5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@types/react@18.2.55)(react@18.2.0) '@mui/utils': 5.15.14(@types/react@18.2.55)(react@18.2.0) '@types/react-transition-group': 4.4.10 clsx: 2.1.1 @@ -5974,19 +5974,6 @@ packages: - '@types/react' dev: false - /@mui/x-license-pro@6.10.2(@types/react@18.2.55)(react@18.2.0): - resolution: {integrity: sha512-Baw3shilU+eHgU+QYKNPFUKvfS5rSyNJ98pQx02E0gKA22hWp/XAt88K1qUfUMPlkPpvg/uci6gviQSSLZkuKw==} - engines: {node: '>=14.0.0'} - peerDependencies: - react: ^17.0.0 || ^18.0.0 - dependencies: - '@babel/runtime': 7.24.5 - '@mui/utils': 5.15.14(@types/react@18.2.55)(react@18.2.0) - react: 18.2.0 - transitivePeerDependencies: - - '@types/react' - dev: false - /@mui/x-license@7.2.0(@types/react@18.2.55)(react@18.2.0): resolution: {integrity: sha512-z9mqsfNPVFqjfxcPgz15o29Vb3FupSImwpMd5CFjZqNasJu3ptLpKxbIUnTtJMUicRdhsVfm3d93Z5XQkq1JuQ==} engines: {node: '>=14.0.0'} @@ -6000,23 +5987,22 @@ packages: - '@types/react' dev: false - /@mui/x-tree-view@6.17.0(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-09dc2D+Rjg2z8KOaxbUXyPi0aw7fm2jurEtV8Xw48xJ00joLWd5QJm1/v4CarEvaiyhTQzHImNqdgeJW8ZQB6g==} + /@mui/x-tree-view@7.3.1(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@mui/material@packages+mui-material+build)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-sGVj1+0F4B7TpAsq1xwKN/9kLO0Px/ZH/Vr3vANOc+VKg/vFtHjZCCzmh9PEZun/vZNOGpMWXccDEZqUi3QjYA==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.9.0 '@emotion/styled': ^11.8.1 - '@mui/material': ^5.8.6 - '@mui/system': ^5.8.0 + '@mui/material': ^5.15.14 react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 dependencies: '@babel/runtime': 7.24.5 '@emotion/react': 11.11.4(@types/react@18.2.55)(react@18.2.0) '@emotion/styled': 11.11.5(@emotion/react@11.11.4)(@types/react@18.2.55)(react@18.2.0) - '@mui/base': 5.0.0-beta.30(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@mui/base': 5.0.0-beta.40(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@mui/material': link:packages/mui-material/build - '@mui/system': link:packages/mui-system/build + '@mui/system': 5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@types/react@18.2.55)(react@18.2.0) '@mui/utils': 5.15.14(@types/react@18.2.55)(react@18.2.0) '@types/react-transition-group': 4.4.10 clsx: 2.1.1 @@ -10993,6 +10979,13 @@ packages: engines: {node: '>=12'} dev: false + /d3-delaunay@6.0.4: + resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} + engines: {node: '>=12'} + dependencies: + delaunator: 5.0.1 + dev: false + /d3-format@2.0.0: resolution: {integrity: sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA==} dev: false @@ -11297,6 +11290,12 @@ packages: has-property-descriptors: 1.0.2 object-keys: 1.1.1 + /delaunator@5.0.1: + resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==} + dependencies: + robust-predicates: 3.0.2 + dev: false + /delay@5.0.0: resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} engines: {node: '>=10'} @@ -19210,6 +19209,10 @@ packages: dependencies: glob: 10.3.10 + /robust-predicates@3.0.2: + resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} + dev: false + /rollup-plugin-babel@4.4.0(@babel/core@7.24.5)(rollup@3.29.4): resolution: {integrity: sha512-Lek/TYp1+7g7I+uMfJnnSJ7YWoD58ajo6Oarhlex7lvUce+RCKRuGRSgztDO3/MF/PuGKmUL5iTHKf208UNszw==} deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-babel.