UNPKG

@unicity/design-system

Version:

A comprehensive React component library built on Material-UI with advanced theming capabilities including neumorphism design support

108 lines 5.43 kB
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; import React from 'react'; import { Menu as MuiMenu, MenuItem, MenuList, ListItemIcon, ListItemText, Divider, IconButton, Paper, ClickAwayListener, Popper, Grow, Fade, } from '@mui/material'; import { MoreVert } from '@mui/icons-material'; import { styled } from '@mui/material/styles'; const StyledMenu = styled(MuiMenu)(({ theme }) => ({ '& .MuiPaper-root': { borderRadius: `calc(${theme.shape.borderRadius}px * 1.5)`, marginTop: theme.spacing(1), minWidth: 180, boxShadow: theme.shadows[8], '& .MuiMenuItem-root': { padding: theme.spacing(1, 2), borderRadius: theme.shape.borderRadius, margin: theme.spacing(0.25, 1), '&:hover': { backgroundColor: theme.palette.action.hover, }, '&.Mui-disabled': { opacity: 0.5, }, '& .MuiListItemIcon-root': { minWidth: 36, color: theme.palette.text.secondary, }, '& .MuiListItemText-primary': { fontSize: theme.typography.body2.fontSize, }, '& .MuiListItemText-secondary': { fontSize: theme.typography.caption.fontSize, }, }, }, })); const ContextMenuContainer = styled(Paper)(({ theme }) => ({ borderRadius: `calc(${theme.shape.borderRadius}px * 1.5)`, minWidth: 180, boxShadow: theme.shadows[8], backgroundColor: theme.palette.background.paper, border: `1px solid ${theme.palette.divider}`, })); const renderMenuItem = (item, index, onClose, showIconsColumn = false) => { if (item.divider) { return _jsx(Divider, { sx: { my: 0.5 } }, `divider-${index}`); } const handleClick = () => { item.onClick?.(); onClose(); }; return (_jsxs(MenuItem, { onClick: handleClick, disabled: item.disabled, sx: { ...(item.color && item.color !== 'default' && { color: `${item.color}.main`, '& .MuiListItemIcon-root': { color: `${item.color}.main`, }, }), }, children: [(item.icon || showIconsColumn) && (_jsx(ListItemIcon, { children: item.icon })), _jsx(ListItemText, { primary: item.label, secondary: item.secondary })] }, item.id)); }; export const Menu = ({ items, open, anchorEl, onClose, variant = 'dropdown', animation = 'fade', showIconsColumn = false, maxHeight = 300, ...props }) => { const TransitionComponent = animation === 'grow' ? Grow : Fade; if (variant === 'context') { return (_jsx(Popper, { open: open, anchorEl: anchorEl, placement: "bottom-start", transition: true, disablePortal: true, children: ({ TransitionProps }) => (_jsx(TransitionComponent, { ...TransitionProps, children: _jsx(ContextMenuContainer, { children: _jsx(ClickAwayListener, { onClickAway: onClose, children: _jsx(MenuList, { autoFocusItem: open, sx: { py: 1, maxHeight, overflowY: 'auto' }, children: items.map((item, index) => renderMenuItem(item, index, onClose, showIconsColumn)) }) }) }) })) })); } return (_jsx(StyledMenu, { open: open, anchorEl: anchorEl, onClose: onClose, TransitionComponent: TransitionComponent, ...props, PaperProps: { ...props.PaperProps, sx: { maxHeight, overflowY: 'auto', ...props.PaperProps?.sx, }, }, children: items.map((item, index) => renderMenuItem(item, index, onClose, showIconsColumn)) })); }; export const ContextMenu = ({ items, children, disabled = false, animation = 'fade', }) => { const [contextMenu, setContextMenu] = React.useState(null); const handleContextMenu = (event) => { if (disabled) return; event.preventDefault(); setContextMenu(contextMenu === null ? { mouseX: event.clientX + 2, mouseY: event.clientY - 6, } : null); }; const handleClose = () => { setContextMenu(null); }; return (_jsxs(_Fragment, { children: [_jsx("div", { onContextMenu: handleContextMenu, style: { cursor: disabled ? 'default' : 'context-menu' }, children: children }), _jsx(Menu, { open: contextMenu !== null, onClose: handleClose, variant: "context", animation: animation, anchorReference: "anchorPosition", anchorPosition: contextMenu !== null ? { top: contextMenu.mouseY, left: contextMenu.mouseX } : undefined, items: items })] })); }; export const MenuButton = ({ items, children, variant = 'icon', size = 'medium', disabled = false, buttonProps = {}, }) => { const [anchorEl, setAnchorEl] = React.useState(null); const open = Boolean(anchorEl); const handleClick = (event) => { setAnchorEl(event.currentTarget); }; const handleClose = () => { setAnchorEl(null); }; if (variant === 'icon') { return (_jsxs(_Fragment, { children: [_jsx(IconButton, { onClick: handleClick, size: size, disabled: disabled, ...buttonProps, children: children || _jsx(MoreVert, {}) }), _jsx(Menu, { items: items, open: open, anchorEl: anchorEl, onClose: handleClose })] })); } // For other variants, you could implement Button component here return null; }; //# sourceMappingURL=Menu.js.map