@unicity/design-system
Version:
A comprehensive React component library built on Material-UI with advanced theming capabilities including neumorphism design support
129 lines • 6.99 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import React from 'react';
import { Drawer as MuiDrawer, Box, List, ListItem, ListItemButton, ListItemIcon, ListItemText, IconButton, Divider, Collapse, useTheme, useMediaQuery, } from '@mui/material';
import { ChevronLeft, ChevronRight, ExpandLess, ExpandMore, } from '@mui/icons-material';
import { styled } from '@mui/material/styles';
const DRAWER_WIDTH = 280;
const MINI_DRAWER_WIDTH = 72;
const StyledDrawer = styled(MuiDrawer, {
shouldForwardProp: (prop) => prop !== 'styleVariant',
})(({ theme, styleVariant = 'default' }) => ({
width: styleVariant === 'mini' ? MINI_DRAWER_WIDTH : DRAWER_WIDTH,
flexShrink: 0,
whiteSpace: 'nowrap',
boxSizing: 'border-box',
'& .MuiDrawer-paper': {
width: styleVariant === 'mini' ? MINI_DRAWER_WIDTH : DRAWER_WIDTH,
transition: theme.transitions.create(['width'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen,
}),
overflowX: 'hidden',
...(styleVariant === 'mini' && {
width: MINI_DRAWER_WIDTH,
'& .MuiListItemText-root': {
opacity: 0,
},
'& .MuiListItemIcon-root': {
minWidth: 0,
mr: 'auto',
justifyContent: 'center',
},
}),
...(styleVariant === 'rail' && {
'&:hover': {
width: DRAWER_WIDTH,
'& .MuiListItemText-root': {
opacity: 1,
},
'& .MuiListItemIcon-root': {
minWidth: 56,
mr: 3,
},
},
'& .MuiListItemText-root': {
opacity: 0,
},
'& .MuiListItemIcon-root': {
minWidth: 0,
mr: 'auto',
justifyContent: 'center',
},
}),
},
}));
const DrawerHeader = styled(Box)(({ theme }) => ({
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-end',
padding: theme.spacing(0, 1),
...theme.mixins.toolbar,
}));
const StyledListItemButton = styled(ListItemButton)(({ theme, level = 0, selected = false }) => ({
paddingLeft: theme.spacing(2 + level * 2),
borderRadius: theme.shape.borderRadius,
margin: theme.spacing(0.25, 1),
...(selected && {
backgroundColor: theme.palette.primary.main + '15',
color: theme.palette.primary.main,
'& .MuiListItemIcon-root': {
color: theme.palette.primary.main,
},
'&:hover': {
backgroundColor: theme.palette.primary.main + '20',
},
}),
}));
const renderDrawerItem = (item, level = 0, onItemClick, styleVariant) => {
const [expanded, setExpanded] = React.useState(item.defaultExpanded || false);
const hasChildren = item.children && item.children.length > 0;
const handleClick = () => {
if (hasChildren) {
setExpanded(!expanded);
}
else {
item.onClick?.();
onItemClick?.(item);
}
};
return (_jsxs(React.Fragment, { children: [_jsx(ListItem, { disablePadding: true, sx: { display: 'block' }, children: _jsxs(StyledListItemButton, { level: level, selected: item.selected, disabled: item.disabled, onClick: handleClick, children: [item.icon && (_jsx(ListItemIcon, { sx: {
minWidth: 56,
mr: styleVariant === 'mini' || styleVariant === 'rail' ? 'auto' : 3,
justifyContent: styleVariant === 'mini' || styleVariant === 'rail' ? 'center' : 'flex-start',
}, children: item.icon })), _jsx(ListItemText, { primary: item.label, sx: {
opacity: styleVariant === 'mini' ? 0 : 1,
transition: 'opacity 0.2s',
} }), hasChildren && (_jsx(Box, { sx: { opacity: styleVariant === 'mini' ? 0 : 1 }, children: expanded ? _jsx(ExpandLess, {}) : _jsx(ExpandMore, {}) })), item.badge && (_jsx(Box, { sx: {
bgcolor: 'error.main',
color: 'error.contrastText',
borderRadius: '50%',
minWidth: 20,
height: 20,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: '0.75rem',
fontWeight: 'bold',
ml: 1,
opacity: styleVariant === 'mini' ? 0 : 1,
}, children: item.badge }))] }) }), hasChildren && (_jsx(Collapse, { in: expanded, timeout: "auto", unmountOnExit: true, children: _jsx(List, { component: "div", disablePadding: true, children: item.children.map((child) => renderDrawerItem(child, level + 1, onItemClick, styleVariant)) }) })), item.divider && _jsx(Divider, { sx: { my: 1 } })] }, item.id));
};
export const Drawer = ({ open, onClose, onToggle, variant = 'temporary', styleVariant = 'default', anchor = 'left', items, header, footer, showCloseButton = true, width = DRAWER_WIDTH, autoCloseMobile = true, onItemClick, ...props }) => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
const handleItemClick = (item) => {
onItemClick?.(item);
if (autoCloseMobile && isMobile && variant === 'temporary') {
onClose?.();
}
};
const drawerContent = (_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', height: '100%' }, children: [(header || showCloseButton) && (_jsxs(DrawerHeader, { children: [header && (_jsx(Box, { sx: { flex: 1, display: 'flex', alignItems: 'center' }, children: header })), showCloseButton && onClose && (_jsx(IconButton, { onClick: onClose, children: anchor === 'right' ? _jsx(ChevronRight, {}) : _jsx(ChevronLeft, {}) }))] })), (header || showCloseButton) && _jsx(Divider, {}), _jsx(Box, { sx: { flex: 1, overflow: 'auto' }, children: _jsx(List, { children: items.map((item) => renderDrawerItem(item, 0, handleItemClick, styleVariant)) }) }), footer && (_jsxs(_Fragment, { children: [_jsx(Divider, {}), _jsx(Box, { sx: { p: 2 }, children: footer })] }))] }));
return (_jsx(StyledDrawer, { variant: variant, styleVariant: styleVariant, open: open, onClose: onClose, anchor: anchor, ...props, sx: {
width: open ? width : (styleVariant === 'mini' ? MINI_DRAWER_WIDTH : 0),
'& .MuiDrawer-paper': {
width: styleVariant === 'mini' ? MINI_DRAWER_WIDTH : width,
},
...props.sx,
}, children: drawerContent }));
};
//# sourceMappingURL=Drawer.js.map