/
githubmirror
/
material-ui
Обзор
Документация
Войти
/
githubmirror
/
material-ui
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
docs/data/material/getting-started/templates/dashboard/components/CustomizedTreeView.js
224 строки
6 KB
Albert Yu
[transitions] Custom `Transition` component (#48325)
07 май 2026, 18:29
Не верифицирован
07 май 2026, 18:29
485fb56
Код
Авторство
О чём код?
import * as React from 'react'; import PropTypes from 'prop-types'; import clsx from 'clsx'; import { animated, useSpring } from '@react-spring/web'; import Box from '@mui/material/Box'; import Card from '@mui/material/Card'; import CardContent from '@mui/material/CardContent'; import Collapse from '@mui/material/Collapse'; import Typography from '@mui/material/Typography'; import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; import { useTreeItem } from '@mui/x-tree-view/useTreeItem'; import { TreeItemContent, TreeItemIconContainer, TreeItemLabel, TreeItemRoot, } from '@mui/x-tree-view/TreeItem'; import { TreeItemIcon } from '@mui/x-tree-view/TreeItemIcon'; import { TreeItemProvider } from '@mui/x-tree-view/TreeItemProvider'; import { useTheme } from '@mui/material/styles'; const ITEMS = [ { id: '1', label: 'Website', children: [ { id: '1.1', label: 'Home', color: 'green' }, { id: '1.2', label: 'Pricing', color: 'green' }, { id: '1.3', label: 'About us', color: 'green' }, { id: '1.4', label: 'Blog', children: [ { id: '1.1.1', label: 'Announcements', color: 'blue' }, { id: '1.1.2', label: 'April lookahead', color: 'blue' }, { id: '1.1.3', label: "What's new", color: 'blue' }, { id: '1.1.4', label: 'Meet the team', color: 'blue' }, ], }, ], }, { id: '2', label: 'Store', children: [ { id: '2.1', label: 'All products', color: 'green' }, { id: '2.2', label: 'Categories', children: [ { id: '2.2.1', label: 'Gadgets', color: 'blue' }, { id: '2.2.2', label: 'Phones', color: 'blue' }, { id: '2.2.3', label: 'Wearables', color: 'blue' }, ], }, { id: '2.3', label: 'Bestsellers', color: 'green' }, { id: '2.4', label: 'Sales', color: 'green' }, ], }, { id: '4', label: 'Contact', color: 'blue' }, { id: '5', label: 'Help', color: 'blue' }, ]; function DotIcon({ color }) { return ( <Box sx={{ marginRight: 1, display: 'flex', alignItems: 'center' }}> <svg width={6} height={6}> <circle cx={3} cy={3} r={3} fill={color} /> </svg> </Box> ); } DotIcon.propTypes = { color: PropTypes.string.isRequired, }; const AnimatedCollapse = animated(Collapse); function TransitionComponent(props) { const style = useSpring({ to: { opacity: props.in ? 1 : 0, transform: `translate3d(0,${props.in ? 0 : 20}px,0)`, }, }); return <AnimatedCollapse style={style} {...props} />; } TransitionComponent.propTypes = { in: PropTypes.bool, }; function CustomLabel({ color, expandable, children, ...other }) { const theme = useTheme(); const colors = { blue: (theme.vars || theme).palette.primary.main, green: (theme.vars || theme).palette.success.main, }; const iconColor = color ? colors[color] : null; return ( <TreeItemLabel {...other} sx={{ display: 'flex', alignItems: 'center' }}> {iconColor && <DotIcon color={iconColor} />} <Typography className="labelText" variant="body2" sx={{ color: 'text.primary' }} > {children} </Typography> </TreeItemLabel> ); } CustomLabel.propTypes = { children: PropTypes.node, color: PropTypes.oneOf(['blue', 'green']), expandable: PropTypes.bool, }; const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { const { id, itemId, label, disabled, children, ...other } = props; const { getRootProps, getContentProps, getIconContainerProps, getLabelProps, getGroupTransitionProps, status, publicAPI, } = useTreeItem({ id, itemId, children, label, disabled, rootRef: ref }); const item = publicAPI.getItem(itemId); const color = item?.color; return ( <TreeItemProvider id={id} itemId={itemId}> <TreeItemRoot {...getRootProps(other)}> <TreeItemContent status={status} {...getContentProps({ className: clsx('content', { expanded: status.expanded, selected: status.selected, focused: status.focused, disabled: status.disabled, }), })} > {status.expandable && ( <TreeItemIconContainer {...getIconContainerProps()}> <TreeItemIcon status={status} /> </TreeItemIconContainer> )} <CustomLabel {...getLabelProps({ color })} /> </TreeItemContent> {children && ( <TransitionComponent {...getGroupTransitionProps({ className: 'groupTransition' })} /> )} </TreeItemRoot> </TreeItemProvider> ); }); CustomTreeItem.propTypes = { /** * The content of the component. */ children: PropTypes.node, /** * If `true`, the item is disabled. * @default false */ disabled: PropTypes.bool, /** * The id attribute of the item. If not provided, it will be generated. */ id: PropTypes.string, /** * The id of the item. * Must be unique. */ itemId: PropTypes.string.isRequired, /** * The label of the item. */ label: PropTypes.node, }; export default function CustomizedTreeView() { return ( <Card variant="outlined" sx={{ display: 'flex', flexDirection: 'column', gap: '8px', flexGrow: 1 }} > <CardContent> <Typography component="h2" variant="subtitle2"> Product tree </Typography> <RichTreeView items={ITEMS} aria-label="pages" multiSelect defaultExpandedItems={['1', '1.1']} defaultSelectedItems={['1.1', '1.1.1']} sx={{ m: '0 -8px', pb: '8px', height: 'fit-content', flexGrow: 1, overflowY: 'auto', }} slots={{ item: CustomTreeItem }} /> </CardContent> </Card> ); }