From f5c1fa607cfe27e7ea3010adadba34589a739847 Mon Sep 17 00:00:00 2001 From: noraleonte Date: Mon, 6 May 2024 17:41:47 +0300 Subject: [PATCH 1/8] wip --- docs/package.json | 8 +- docs/src/components/productX/TreeViewDemo.tsx | 288 ++++++++++++++++++ .../src/components/productX/XTreeViewDemo.tsx | 73 ++--- .../components/showcase/FolderTreeView.tsx | 59 ++-- pnpm-lock.yaml | 85 +++--- 5 files changed, 416 insertions(+), 97 deletions(-) create mode 100644 docs/src/components/productX/TreeViewDemo.tsx diff --git a/docs/package.json b/docs/package.json index ee69bb478f12c1..20295579777559 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-date-pickers": "7.3.2", + "@mui/x-date-pickers-pro": "7.3.2", "@mui/x-license-pro": "6.10.2", - "@mui/x-tree-view": "6.17.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/src/components/productX/TreeViewDemo.tsx b/docs/src/components/productX/TreeViewDemo.tsx new file mode 100644 index 00000000000000..dc3ea3ecb0fb84 --- /dev/null +++ b/docs/src/components/productX/TreeViewDemo.tsx @@ -0,0 +1,288 @@ +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 Collapse from '@mui/material/Collapse'; +import Typography from '@mui/material/Typography'; +import FolderRounded from '@mui/icons-material/FolderRounded'; +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'; + +type FileType = 'image' | 'pdf' | 'video' | 'folder'; + +type ExtendedTreeItemProps = { + fileType?: FileType; + id: string; + label: string; +}; + +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' }], + }, + ], + }, +]; + +function DotIcon() { + return ( + + ); +} +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}`]: { + marginLeft: theme.spacing(3.5), + }, +})) as unknown as typeof TreeItem2Root; + +const CustomTreeItemContent = styled(TreeItem2Content)(({ theme }) => ({ + borderRadius: theme.spacing(0.7), + marginBottom: theme.spacing(0.5), + marginTop: theme.spacing(0.5), + padding: theme.spacing(0.5), + paddingRight: theme.spacing(1), + [`& .${treeItemClasses.iconContainer}`]: { + marginRight: theme.spacing(2), + }, + [`&.Mui-expanded `]: { + // '&:not(.Mui-focused, .Mui-selected, .Mui-selected.Mui-focused) .labelIcon': { + // color: + // theme.palette.mode === 'light' ? theme.palette.primary.main : theme.palette.primary.dark, + // }, + '&::before': { + content: '""', + display: 'block', + position: 'absolute', + left: '16px', + top: '44px', + height: 'calc(100% - 48px)', + width: '1.5px', + backgroundColor: + theme.palette.mode === 'light' + ? (theme.vars || theme).palette.grey[100] + : (theme.vars || theme).palette.primaryDark[700], + }, + }, + // '&:hover': { + // backgroundColor: alpha(theme.palette.primary.main, 0.1), + // color: theme.palette.mode === 'light' ? theme.palette.primary.main : 'white', + // }, + // [`&.Mui-focused, &.Mui-selected, &.Mui-selected.Mui-focused`]: { + // backgroundColor: + // theme.palette.mode === 'light' ? theme.palette.primary.main : theme.palette.primary.dark, + // color: theme.palette.primary.contrastText, + // }, +})); + +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)`, + }, + }); + + return ; +} + +const StyledTreeItemLabelText = styled(Typography)({ + color: 'inherit', +}) as unknown as typeof Typography; + +interface CustomLabelProps { + children: React.ReactNode; + icon?: React.ElementType; + expandable?: boolean; +} + +function CustomLabel({ icon: Icon, expandable, children, ...other }: CustomLabelProps) { + return ( + + {Icon && ( + + )} + + {children} + {expandable && } + + ); +} + +const isExpandable = (reactChildren: React.ReactNode) => { + if (Array.isArray(reactChildren)) { + return reactChildren.length > 0 && reactChildren.some(isExpandable); + } + return Boolean(reactChildren); +}; + +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, +) { + 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) { + icon = FolderRounded; + } else if (item.fileType) { + icon = getIconFromFileType(item.fileType); + } + + return ( + + + + + + + + + + {children && } + + + ); +}); + +export default function TreeViewDemo() { + return ( + + ); +} diff --git a/docs/src/components/productX/XTreeViewDemo.tsx b/docs/src/components/productX/XTreeViewDemo.tsx index 7cf620c9935071..690553475af5ef 100644 --- a/docs/src/components/productX/XTreeViewDemo.tsx +++ b/docs/src/components/productX/XTreeViewDemo.tsx @@ -3,10 +3,10 @@ import clsx from 'clsx'; import { styled } from '@mui/material/styles'; import Box from '@mui/material/Box'; import Paper from '@mui/material/Paper'; -import { TreeView } from '@mui/x-tree-view/TreeView'; +import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; import { TreeItem as MuiTreeItem, - useTreeItem, + useTreeItemState, TreeItemProps, TreeItemContentProps, } from '@mui/x-tree-view/TreeItem'; @@ -19,6 +19,7 @@ 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 TreeViewDemo from './TreeViewDemo'; const CustomContent = React.forwardRef(function CustomContent( props: TreeItemContentProps & { lastNestedChild?: boolean }, @@ -29,7 +30,7 @@ const CustomContent = React.forwardRef(function CustomContent( classes, className, label, - nodeId, + itemId, icon: iconProp, expansionIcon, displayIcon, @@ -43,7 +44,7 @@ const CustomContent = React.forwardRef(function CustomContent( handleExpansion, handleSelection, preventSelection, - } = useTreeItem(nodeId); + } = useTreeItemState(itemId); const icon = iconProp || expansionIcon || displayIcon; @@ -113,7 +114,7 @@ const CustomContent = React.forwardRef(function CustomContent( zIndex: 1, '& svg': { fontSize: 18, - color: nodeId.startsWith('root') ? 'primary.main' : 'grey.600', + color: itemId.startsWith('root') ? 'primary.main' : 'grey.600', }, '&:not(.CustomContent-last)': { '& svg': { @@ -203,51 +204,51 @@ const code = ` defaultExpanded={['1', '1.1', '1.2', '2', '2.3']} sx={{ height: { xs: 260, sm: 460 }, overflowY: 'auto', p: 1 }} > - - + + - + - + - + @@ -255,7 +256,7 @@ const code = ` `; -export default function XDateRangeDemo() { +export default function XTreeViewDemo() { return ( @@ -265,67 +266,69 @@ 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..02bc490ace87ee 100644 --- a/docs/src/components/showcase/FolderTreeView.tsx +++ b/docs/src/components/showcase/FolderTreeView.tsx @@ -4,10 +4,10 @@ import * as React from 'react'; import clsx from 'clsx'; import { styled } from '@mui/material/styles'; import Box from '@mui/material/Box'; -import { TreeView } from '@mui/x-tree-view/TreeView'; +import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; import { TreeItem, - useTreeItem, + useTreeItemState, TreeItemProps, TreeItemContentProps, } from '@mui/x-tree-view/TreeItem'; @@ -25,7 +25,7 @@ const CustomContent = React.forwardRef(function CustomContent( classes, className, label, - nodeId, + itemId, icon: iconProp, expansionIcon, displayIcon, @@ -39,7 +39,7 @@ const CustomContent = React.forwardRef(function CustomContent( handleExpansion, handleSelection, preventSelection, - } = useTreeItem(nodeId); + } = useTreeItemState(itemId); const icon = iconProp || expansionIcon || displayIcon; @@ -86,7 +86,7 @@ const CustomContent = React.forwardRef(function CustomContent( )} @@ -128,7 +128,7 @@ const StyledTreeItem = styled(TreeItem)(({ theme }) => [ content: '""', display: 'block', position: 'absolute', - left: -14, + left: -5, height: '100%', width: 1.5, backgroundColor: (theme.vars || theme).palette.grey[200], @@ -163,48 +163,61 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem( ) { return ; }); +function CustomEndIcon() { + return
; +} + +function CustomExpandIcon() { + return ; +} + +function CustomCollapseIcon() { + return ; +} export default function FolderTreeView() { return ( - } - defaultExpandIcon={} - defaultEndIcon={
} + defaultExpandedItems={['1', '2', '5', '7']} + slots={{ + endIcon: CustomEndIcon, + expandIcon: CustomExpandIcon, + collapseIcon: CustomCollapseIcon, + }} sx={{ p: 1, overflowY: 'auto' }} > - - - - - + + + + + - + - + - + ); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5e76405cba4cd9..72ebabc3883adc 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) + 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-pro': specifier: 6.10.2 version: 6.10.2(@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 @@ -5733,14 +5733,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: @@ -5752,13 +5751,16 @@ packages: '@babel/runtime': 7.24.4 '@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 @@ -5869,14 +5871,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 @@ -5909,12 +5910,12 @@ packages: '@babel/runtime': 7.24.4 '@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 @@ -5926,14 +5927,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 @@ -5966,9 +5966,9 @@ packages: '@babel/runtime': 7.24.4 '@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 @@ -6008,23 +6008,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.4 '@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 @@ -6061,7 +6060,6 @@ packages: /@next/env@14.2.3: resolution: {integrity: sha512-W7fd7IbkfmeeY2gXrzJYDx8D2lWKbVoTIj1o1ScPHNzvp30s1AuoEFSdr39bC5sjxJaxTtq3OTCZboNp0lNWHA==} - dev: false /@next/eslint-plugin-next@14.2.3: resolution: {integrity: sha512-L3oDricIIjgj1AVnRdRor21gI7mShlSwU/1ZGHmqM3LzHhXXhdkrfeNY5zif25Bi5Dd7fiJHsbhoZCHfXYvlAw==} @@ -11019,6 +11017,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 @@ -11323,6 +11328,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'} @@ -19236,6 +19247,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.4)(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. From 7602360f496021fbe9a09819252066f81f6f54b8 Mon Sep 17 00:00:00 2001 From: noraleonte Date: Mon, 6 May 2024 19:42:13 +0300 Subject: [PATCH 2/8] update treeview demos --- docs/src/components/productX/TreeViewDemo.tsx | 288 ---------- .../src/components/productX/XTreeViewDemo.tsx | 533 ++++++++---------- .../components/showcase/FolderTreeView.tsx | 391 +++++++------ 3 files changed, 471 insertions(+), 741 deletions(-) delete mode 100644 docs/src/components/productX/TreeViewDemo.tsx diff --git a/docs/src/components/productX/TreeViewDemo.tsx b/docs/src/components/productX/TreeViewDemo.tsx deleted file mode 100644 index dc3ea3ecb0fb84..00000000000000 --- a/docs/src/components/productX/TreeViewDemo.tsx +++ /dev/null @@ -1,288 +0,0 @@ -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 Collapse from '@mui/material/Collapse'; -import Typography from '@mui/material/Typography'; -import FolderRounded from '@mui/icons-material/FolderRounded'; -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'; - -type FileType = 'image' | 'pdf' | 'video' | 'folder'; - -type ExtendedTreeItemProps = { - fileType?: FileType; - id: string; - label: string; -}; - -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' }], - }, - ], - }, -]; - -function DotIcon() { - return ( - - ); -} -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}`]: { - marginLeft: theme.spacing(3.5), - }, -})) as unknown as typeof TreeItem2Root; - -const CustomTreeItemContent = styled(TreeItem2Content)(({ theme }) => ({ - borderRadius: theme.spacing(0.7), - marginBottom: theme.spacing(0.5), - marginTop: theme.spacing(0.5), - padding: theme.spacing(0.5), - paddingRight: theme.spacing(1), - [`& .${treeItemClasses.iconContainer}`]: { - marginRight: theme.spacing(2), - }, - [`&.Mui-expanded `]: { - // '&:not(.Mui-focused, .Mui-selected, .Mui-selected.Mui-focused) .labelIcon': { - // color: - // theme.palette.mode === 'light' ? theme.palette.primary.main : theme.palette.primary.dark, - // }, - '&::before': { - content: '""', - display: 'block', - position: 'absolute', - left: '16px', - top: '44px', - height: 'calc(100% - 48px)', - width: '1.5px', - backgroundColor: - theme.palette.mode === 'light' - ? (theme.vars || theme).palette.grey[100] - : (theme.vars || theme).palette.primaryDark[700], - }, - }, - // '&:hover': { - // backgroundColor: alpha(theme.palette.primary.main, 0.1), - // color: theme.palette.mode === 'light' ? theme.palette.primary.main : 'white', - // }, - // [`&.Mui-focused, &.Mui-selected, &.Mui-selected.Mui-focused`]: { - // backgroundColor: - // theme.palette.mode === 'light' ? theme.palette.primary.main : theme.palette.primary.dark, - // color: theme.palette.primary.contrastText, - // }, -})); - -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)`, - }, - }); - - return ; -} - -const StyledTreeItemLabelText = styled(Typography)({ - color: 'inherit', -}) as unknown as typeof Typography; - -interface CustomLabelProps { - children: React.ReactNode; - icon?: React.ElementType; - expandable?: boolean; -} - -function CustomLabel({ icon: Icon, expandable, children, ...other }: CustomLabelProps) { - return ( - - {Icon && ( - - )} - - {children} - {expandable && } - - ); -} - -const isExpandable = (reactChildren: React.ReactNode) => { - if (Array.isArray(reactChildren)) { - return reactChildren.length > 0 && reactChildren.some(isExpandable); - } - return Boolean(reactChildren); -}; - -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, -) { - 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) { - icon = FolderRounded; - } else if (item.fileType) { - icon = getIconFromFileType(item.fileType); - } - - return ( - - - - - - - - - - {children && } - - - ); -}); - -export default function TreeViewDemo() { - return ( - - ); -} diff --git a/docs/src/components/productX/XTreeViewDemo.tsx b/docs/src/components/productX/XTreeViewDemo.tsx index 690553475af5ef..a6edec4eebeba0 100644 --- a/docs/src/components/productX/XTreeViewDemo.tsx +++ b/docs/src/components/productX/XTreeViewDemo.tsx @@ -1,260 +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 { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; -import { - TreeItem as MuiTreeItem, - useTreeItemState, - 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 TreeViewDemo from './TreeViewDemo'; +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, - itemId, - icon: iconProp, - expansionIcon, - displayIcon, - } = props; +type FileType = 'image' | 'pdf' | 'video' | 'folder'; - const { - disabled, - expanded, - selected, - focused, - handleExpansion, - handleSelection, - preventSelection, - } = useTreeItemState(itemId); +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' }], + }, + ], + }, +]; + +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}`]: { + marginLeft: theme.spacing(3.5), + }, +})) as unknown as typeof TreeItem2Root; - const handleMouseDown = (event: React.MouseEvent) => { - preventSelection(event); - }; +const CustomTreeItemContent = styled(TreeItem2Content)(({ theme }) => ({ + borderRadius: theme.spacing(0.7), + marginBottom: theme.spacing(0.5), + marginTop: theme.spacing(0.5), + padding: theme.spacing(0.5), + [`& .${treeItemClasses.iconContainer}`]: { + marginRight: theme.spacing(1), + }, + '&.Mui-expanded&::before': { + content: '""', + display: 'block', + position: 'absolute', + left: '16px', + top: '44px', + height: 'calc(100% - 48px)', + width: '1.5px', + backgroundColor: + theme.palette.mode === 'light' + ? (theme.vars || theme).palette.grey[100] + : (theme.vars || theme).palette.primaryDark[700], + }, +})); - const handleExpansionClick = (event: React.MouseEvent) => { - handleExpansion(event); - handleSelection(event); - }; +const AnimatedCollapse = animated(Collapse); - const handleSelectionClick = (event: React.MouseEvent) => { - handleSelection(event); - }; +function TransitionComponent(props: TransitionProps) { + const style = useSpring({ + to: { + opacity: props.in ? 1 : 0, + transform: `translate3d(0,${props.in ? 0 : 20}px,0)`, + }, + }); - 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 ( - - ); - }; + 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.grey[600], + })} + 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 XTreeViewDemo() { return ( @@ -272,63 +286,14 @@ export default function XTreeViewDemo() { }), })} > - {/* - - - - - - - - - - - - - - - - - - - */} - + diff --git a/docs/src/components/showcase/FolderTreeView.tsx b/docs/src/components/showcase/FolderTreeView.tsx index 02bc490ace87ee..2eb26d016794be 100644 --- a/docs/src/components/showcase/FolderTreeView.tsx +++ b/docs/src/components/showcase/FolderTreeView.tsx @@ -2,166 +2,248 @@ /* 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 { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; -import { - TreeItem, - useTreeItemState, - 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, - itemId, - icon: iconProp, - expansionIcon, - displayIcon, - } = props; +type ExtendedTreeItemProps = { + id: string; + label: string; + color?: 'primary' | 'default'; +}; - const { - disabled, - expanded, - selected, - focused, - handleExpansion, - handleSelection, - preventSelection, - } = useTreeItemState(itemId); +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 ( + + ); +} + +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.7), + marginBottom: theme.spacing(0.5), + marginTop: theme.spacing(0.5), + padding: theme.spacing(0.5), + [`& .${treeItemClasses.iconContainer}`]: { + marginRight: theme.spacing(1), + }, - const icon = iconProp || expansionIcon || displayIcon; + '&.Mui-expanded&::before': { + content: '""', + display: 'block', + position: 'absolute', + left: '16px', + top: '44px', + height: 'calc(100% - 48px)', + width: '1.5px', + backgroundColor: + theme.palette.mode === 'light' + ? (theme.vars || theme).palette.grey[100] + : (theme.vars || theme).palette.primaryDark[700], + }, +})); - const handleMouseDown = (event: React.MouseEvent) => { - preventSelection(event); - }; +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: -5, - 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); + + return ( + + + + {' '} + {expandable && ( + + + + )} + + {children && }{' '} + + + ); }); function CustomEndIcon() { return
; @@ -175,49 +257,20 @@ function CustomCollapseIcon() { return ; } -export default function FolderTreeView() { +export default function TreeViewDemo() { return ( - - - - - - - - - - - - - - - - - + /> ); } From 97e4414f3c00546ed2150d601fec70f4bb8f10b0 Mon Sep 17 00:00:00 2001 From: Nora <72460825+noraleonte@users.noreply.github.com> Date: Tue, 7 May 2024 11:13:15 +0300 Subject: [PATCH 3/8] Apply suggestions from code review - Danilo & Lukas Co-authored-by: Lukas Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Signed-off-by: Nora <72460825+noraleonte@users.noreply.github.com> --- docs/package.json | 1 - .../src/components/productX/XTreeViewDemo.tsx | 24 ++++++++----------- .../components/showcase/FolderTreeView.tsx | 15 ++++-------- 3 files changed, 15 insertions(+), 25 deletions(-) diff --git a/docs/package.json b/docs/package.json index 20295579777559..f5f77fbfdaa720 100644 --- a/docs/package.json +++ b/docs/package.json @@ -50,7 +50,6 @@ "@mui/x-data-grid-pro": "7.3.1", "@mui/x-date-pickers": "7.3.2", "@mui/x-date-pickers-pro": "7.3.2", - "@mui/x-license-pro": "6.10.2", "@mui/x-tree-view": "7.3.1", "@popperjs/core": "^2.11.8", "@react-spring/web": "^9.7.3", diff --git a/docs/src/components/productX/XTreeViewDemo.tsx b/docs/src/components/productX/XTreeViewDemo.tsx index a6edec4eebeba0..6505687214cd5c 100644 --- a/docs/src/components/productX/XTreeViewDemo.tsx +++ b/docs/src/components/productX/XTreeViewDemo.tsx @@ -101,20 +101,16 @@ const StyledTreeItemRoot = styled(TreeItem2Root)(({ theme }) => ({ })) as unknown as typeof TreeItem2Root; const CustomTreeItemContent = styled(TreeItem2Content)(({ theme }) => ({ - borderRadius: theme.spacing(0.7), - marginBottom: theme.spacing(0.5), - marginTop: theme.spacing(0.5), - padding: theme.spacing(0.5), - [`& .${treeItemClasses.iconContainer}`]: { - marginRight: theme.spacing(1), - }, + borderRadius: theme.spacing(0.5), + marginBottom: theme.spacing(0.2), + marginTop: theme.spacing(0.2), '&.Mui-expanded&::before': { content: '""', display: 'block', position: 'absolute', left: '16px', - top: '44px', - height: 'calc(100% - 48px)', + top: '40px', + height: 'calc(100% - 50px)', width: '1.5px', backgroundColor: theme.palette.mode === 'light' @@ -168,7 +164,7 @@ function CustomLabel({ icon: Icon, expandable, children, ...other }: CustomLabel fontWeight: expandable ? theme.typography.fontWeightMedium : theme.typography.fontWeightRegular, - color: expandable ? theme.palette.text.primary : theme.palette.grey[600], + color: expandable ? theme.palette.text.primary : theme.palette.text.secondary, })} variant="body2" > @@ -263,8 +259,8 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem( const code = ` ({ })) as unknown as typeof TreeItem2Root; const CustomTreeItemContent = styled(TreeItem2Content)(({ theme }) => ({ - borderRadius: theme.spacing(0.7), - marginBottom: theme.spacing(0.5), - marginTop: theme.spacing(0.5), - padding: theme.spacing(0.5), + borderRadius: theme.spacing(0.5), [`& .${treeItemClasses.iconContainer}`]: { marginRight: theme.spacing(1), }, @@ -113,9 +108,9 @@ const CustomTreeItemContent = styled(TreeItem2Content)(({ theme }) => ({ content: '""', display: 'block', position: 'absolute', - left: '16px', - top: '44px', - height: 'calc(100% - 48px)', + left: '15px', + top: '40px', + height: 'calc(100% - 50px)', width: '1.5px', backgroundColor: theme.palette.mode === 'light' From c9e72a30039d1b4b610b7aabc2116b49a917b53a Mon Sep 17 00:00:00 2001 From: noraleonte Date: Tue, 7 May 2024 11:22:21 +0300 Subject: [PATCH 4/8] tidy up horizontal spacing --- docs/src/components/showcase/FolderTreeView.tsx | 13 +++++-------- pnpm-lock.yaml | 16 ---------------- 2 files changed, 5 insertions(+), 24 deletions(-) diff --git a/docs/src/components/showcase/FolderTreeView.tsx b/docs/src/components/showcase/FolderTreeView.tsx index 1471f0957616aa..cb2506d93635e5 100644 --- a/docs/src/components/showcase/FolderTreeView.tsx +++ b/docs/src/components/showcase/FolderTreeView.tsx @@ -77,7 +77,7 @@ function DotIcon() { borderRadius: '50%', bgcolor: 'warning.main', zIndex: 1, - mx: 1, + mr: 1, }} /> ); @@ -100,17 +100,14 @@ const StyledTreeItemRoot = styled(TreeItem2Root)(({ theme }) => ({ const CustomTreeItemContent = styled(TreeItem2Content)(({ theme }) => ({ borderRadius: theme.spacing(0.5), - [`& .${treeItemClasses.iconContainer}`]: { - marginRight: theme.spacing(1), - }, '&.Mui-expanded&::before': { content: '""', display: 'block', position: 'absolute', left: '15px', - top: '40px', - height: 'calc(100% - 50px)', + top: '28px', + height: 'calc(100% - 28px)', width: '1.5px', backgroundColor: theme.palette.mode === 'light' @@ -228,7 +225,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem( expandable, color: item?.color === 'primary' ? 'primary.main' : 'grey.600', })} - />{' '} + /> {expandable && ( @@ -259,7 +256,7 @@ export default function TreeViewDemo() { aria-label="file explorer" defaultExpandedItems={['1', '1.1', '1.2', '1.2.2']} defaultSelectedItems="1.1" - sx={{ height: 'fit-content', flexGrow: 1, overflowY: 'auto', p: 1 }} + sx={{ height: 'fit-content', flexGrow: 1, p: 1 }} slots={{ item: CustomTreeItem, endIcon: CustomEndIcon, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 72ebabc3883adc..deed14a8799556 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -667,9 +667,6 @@ importers: '@mui/x-date-pickers-pro': 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-pro': - specifier: 6.10.2 - version: 6.10.2(@types/react@18.2.55)(react@18.2.0) '@mui/x-tree-view': 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) @@ -5982,19 +5979,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.4 - '@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'} From acc240bd87d9b5986209c50ef70a1964609ac706 Mon Sep 17 00:00:00 2001 From: noraleonte Date: Tue, 7 May 2024 11:32:42 +0300 Subject: [PATCH 5/8] tidy up demo spacing --- docs/src/components/productX/XTreeViewDemo.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/src/components/productX/XTreeViewDemo.tsx b/docs/src/components/productX/XTreeViewDemo.tsx index 6505687214cd5c..23b34d381c4def 100644 --- a/docs/src/components/productX/XTreeViewDemo.tsx +++ b/docs/src/components/productX/XTreeViewDemo.tsx @@ -104,13 +104,14 @@ 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: '40px', - height: 'calc(100% - 50px)', + top: '30px', + height: 'calc(100% - 32px)', width: '1.5px', backgroundColor: theme.palette.mode === 'light' @@ -126,6 +127,7 @@ function TransitionComponent(props: TransitionProps) { to: { opacity: props.in ? 1 : 0, transform: `translate3d(0,${props.in ? 0 : 20}px,0)`, + paddingLeft: 24, }, }); @@ -262,7 +264,7 @@ const code = ` aria-label="File explorer" defaultExpandedItems={['1', '1.1', '1.2', '2']} defaultSelectedItems="1.1" - sx={{ height: 'fit-content', flexGrow: 1, overflowY: 'auto' }} + sx={{ height: 'fit-content', flexGrow: 1 }} slots={{ item: CustomTreeItem }} />`; @@ -287,7 +289,7 @@ export default function XTreeViewDemo() { aria-label="File explorer" defaultExpandedItems={['1', '1.1', '1.2', '2']} defaultSelectedItems="1.1" - sx={{ height: 'fit-content', flexGrow: 1, overflowY: 'auto' }} + sx={{ height: 'fit-content', flexGrow: 1 }} slots={{ item: CustomTreeItem }} /> From 4ec5797a42bd7d537fd4d46e169973bafb5d33ba Mon Sep 17 00:00:00 2001 From: noraleonte Date: Tue, 7 May 2024 14:32:57 +0300 Subject: [PATCH 6/8] fix linting --- .../default-theme-viewer/JoyDefaultTheme.js | 4 +- .../default-theme/DefaultTheme.js | 4 +- .../components/showcase/FolderTreeView.tsx | 2 - docs/src/modules/components/ThemeViewer.tsx | 45 ++++++++++--------- 4 files changed, 29 insertions(+), 26 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/src/components/showcase/FolderTreeView.tsx b/docs/src/components/showcase/FolderTreeView.tsx index cb2506d93635e5..806c63a0f388f5 100644 --- a/docs/src/components/showcase/FolderTreeView.tsx +++ b/docs/src/components/showcase/FolderTreeView.tsx @@ -1,5 +1,3 @@ -/* 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'; 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 ( ); })} - + ); } From f0b6996f1b0f4572e9c6ce0d2903b3abf30e5096 Mon Sep 17 00:00:00 2001 From: noraleonte Date: Tue, 7 May 2024 16:12:34 +0300 Subject: [PATCH 7/8] date range demo --- docs/src/components/productX/XDateRangeDemo.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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), }; From fc694e6b4d897ee6c73a2e9b5a8274524f757270 Mon Sep 17 00:00:00 2001 From: noraleonte Date: Thu, 9 May 2024 14:43:22 +0300 Subject: [PATCH 8/8] add x-license --- docs/package.json | 1 + docs/pages/_app.js | 2 +- pnpm-lock.yaml | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 376caacbb7647e..03cf7b78245cbc 100644 --- a/docs/package.json +++ b/docs/package.json @@ -50,6 +50,7 @@ "@mui/x-data-grid-pro": "7.3.1", "@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", 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/pnpm-lock.yaml b/pnpm-lock.yaml index 03c03e6b214e09..fdcb9245f17c06 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -667,6 +667,9 @@ importers: '@mui/x-date-pickers-pro': 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: 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)