@unicity/design-system
Version:
A comprehensive React component library built on Material-UI with advanced theming capabilities including neumorphism design support
109 lines • 7.25 kB
JavaScript
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import React from 'react';
import { AppBar as MuiAppBar, Toolbar, IconButton, Typography, Box, InputBase, Badge, Menu, MenuItem, Avatar, Breadcrumbs, Link, useTheme, useMediaQuery, } from '@mui/material';
import { Menu as MenuIcon, Search, Notifications, ArrowBack, } from '@mui/icons-material';
import { styled, alpha } from '@mui/material/styles';
const StyledAppBar = styled(MuiAppBar)(({ theme, variant = 'default', transparent = false }) => ({
...(variant === 'dense' && {
minHeight: 48,
'& .MuiToolbar-root': {
minHeight: 48,
paddingTop: 0,
paddingBottom: 0,
},
}),
...(variant === 'prominent' && {
minHeight: 80,
'& .MuiToolbar-root': {
minHeight: 80,
},
}),
...(transparent && {
backgroundColor: 'transparent',
backgroundImage: 'none',
boxShadow: 'none',
borderBottom: `1px solid ${alpha(theme.palette.divider, 0.12)}`,
}),
}));
const SearchContainer = styled('div')(({ theme }) => ({
position: 'relative',
borderRadius: theme.shape.borderRadius,
backgroundColor: alpha(theme.palette.common.white, 0.15),
'&:hover': {
backgroundColor: alpha(theme.palette.common.white, 0.25),
},
marginLeft: 0,
width: '100%',
[theme.breakpoints.up('sm')]: {
marginLeft: theme.spacing(1),
width: 'auto',
},
}));
const SearchIconWrapper = styled('div')(({ theme }) => ({
padding: theme.spacing(0, 2),
height: '100%',
position: 'absolute',
pointerEvents: 'none',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}));
const StyledInputBase = styled(InputBase)(({ theme }) => ({
color: 'inherit',
'& .MuiInputBase-input': {
padding: theme.spacing(1, 1, 1, 0),
paddingLeft: `calc(1em + ${theme.spacing(4)})`,
transition: theme.transitions.create('width'),
width: '100%',
[theme.breakpoints.up('sm')]: {
width: '12ch',
'&:focus': {
width: '20ch',
},
},
},
}));
export const AppBar = ({ title, subtitle, variant = 'default', showSearch = false, searchPlaceholder = 'Search...', searchValue = '', onSearchChange, showMenuButton = false, onMenuClick, showBackButton = false, onBackClick, user, userMenuActions = [], notificationCount = 0, onNotificationClick, breadcrumbs = [], actions = [], transparent = false, leftContent, rightContent, ...props }) => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
const [userMenuAnchor, setUserMenuAnchor] = React.useState(null);
const handleUserMenuOpen = (event) => {
setUserMenuAnchor(event.currentTarget);
};
const handleUserMenuClose = () => {
setUserMenuAnchor(null);
};
const handleUserMenuAction = (action) => {
action.onClick?.();
handleUserMenuClose();
};
const renderLeftSection = () => {
if (leftContent)
return leftContent;
return (_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1 }, children: [showBackButton && (_jsx(IconButton, { color: "inherit", onClick: onBackClick, edge: "start", children: _jsx(ArrowBack, {}) })), showMenuButton && (_jsx(IconButton, { color: "inherit", onClick: onMenuClick, edge: "start", children: _jsx(MenuIcon, {}) })), _jsx(Box, { children: breadcrumbs.length > 0 ? (_jsx(Breadcrumbs, { sx: { color: 'inherit' }, separator: "\u203A", children: breadcrumbs.map((item, index) => (_jsx(Link, { color: "inherit", href: item.href, onClick: item.onClick, sx: {
textDecoration: item.current ? 'none' : 'underline',
fontWeight: item.current ? 'bold' : 'normal',
cursor: item.current ? 'default' : 'pointer',
}, children: item.label }, index))) })) : (_jsxs(_Fragment, { children: [_jsx(Typography, { variant: "h6", component: "div", sx: { flexGrow: 1 }, children: title }), subtitle && (_jsx(Typography, { variant: "body2", sx: { opacity: 0.8 }, children: subtitle }))] })) })] }));
};
const renderRightSection = () => {
if (rightContent)
return rightContent;
return (_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1 }, children: [showSearch && !isMobile && (_jsxs(SearchContainer, { children: [_jsx(SearchIconWrapper, { children: _jsx(Search, {}) }), _jsx(StyledInputBase, { placeholder: searchPlaceholder, value: searchValue, onChange: (e) => onSearchChange?.(e.target.value), inputProps: { 'aria-label': 'search' } })] })), actions.map((action, index) => (_jsx(Box, { children: action }, index))), onNotificationClick && (_jsx(IconButton, { color: "inherit", onClick: onNotificationClick, children: _jsx(Badge, { badgeContent: notificationCount, color: "error", children: _jsx(Notifications, {}) }) })), user && (_jsxs(_Fragment, { children: [_jsx(IconButton, { color: "inherit", onClick: handleUserMenuOpen, sx: { p: 0 }, children: user.avatar ? (_jsx(Avatar, { src: user.avatar, sx: { width: 32, height: 32 } })) : (_jsx(Avatar, { sx: { width: 32, height: 32 }, children: user.name.charAt(0).toUpperCase() })) }), _jsxs(Menu, { anchorEl: userMenuAnchor, open: Boolean(userMenuAnchor), onClose: handleUserMenuClose, onClick: handleUserMenuClose, PaperProps: {
elevation: 0,
sx: {
overflow: 'visible',
filter: 'drop-shadow(0px 2px 8px rgba(0,0,0,0.32))',
mt: 1.5,
'& .MuiAvatar-root': {
width: 32,
height: 32,
ml: -0.5,
mr: 1,
},
},
}, transformOrigin: { horizontal: 'right', vertical: 'top' }, anchorOrigin: { horizontal: 'right', vertical: 'bottom' }, children: [_jsx(MenuItem, { disabled: true, children: _jsxs(Box, { children: [_jsx(Typography, { variant: "subtitle2", children: user.name }), user.email && (_jsx(Typography, { variant: "body2", color: "textSecondary", children: user.email }))] }) }), userMenuActions.map((action) => (_jsxs(Box, { children: [_jsxs(MenuItem, { onClick: () => handleUserMenuAction(action), disabled: action.disabled, children: [action.icon && (_jsx(Box, { sx: { mr: 2, display: 'flex' }, children: action.icon })), action.label] }), action.divider && _jsx("hr", { style: { margin: 0, border: 'none', borderTop: '1px solid #e0e0e0' } })] }, action.id)))] })] })), showSearch && isMobile && (_jsx(IconButton, { color: "inherit", children: _jsx(Search, {}) }))] }));
};
return (_jsx(StyledAppBar, { transparent: transparent, ...props, children: _jsxs(Toolbar, { children: [renderLeftSection(), _jsx(Box, { sx: { flexGrow: 1 } }), renderRightSection()] }) }));
};
//# sourceMappingURL=AppBar.js.map