RS
REPLY Shippers

Drawer Width - Copy this React, Mui Component to your project

Import React, { useState, useEffect } from "react"; import { Box, List, ListItem, ListItemIcon, ListItemText, IconButton, Typography, styled, AppBar, Toolbar, Switch, TextField, Select, MenuItem, Button, Menu, Tooltip, Paper, Badge, Divider, Collapse, Avatar, useTheme, useMediaQuery, InputBase, Container, Card, CardContent } from "@mui/material"; import { FiMenu, FiHome, FiDollarSign, FiTruck, FiGrid, FiShare2, FiBox, FiUsers, FiFile, FiFolder, FiBookmark, FiDatabase, FiBarChart2, FiShoppingCart, FiUser, FiBell, FiSettings, FiHelpCircle, FiBook, FiSearch, FiMoon, FiSun, FiChevronDown, FiChevronUp, FiGlobe, FiLogOut } from "react-icons/fi"; import { BsFileEarmarkText, BsWallet2 } from "react-icons/bs"; import { motion, AnimatePresence } from "framer-motion"; import { useNavigate } from "react-router-dom"; const modernColors = { primary: "#6366F1", secondary: "#EC4899", success: "#22C55E", warning: "#F59E0B", error: "#EF4444", info: "#3B82F6", background: { light: "#F8FAFC", dark: "#0F172A" }, text: { light: "#334155", dark: "#F1F5F9" }, hover: { light: "#E2E8F0", dark: "#1E293B" } }; const iconColors = { primary: "#6366F1", action: "#EC4899", success: "#22C55E", warning: "#F59E0B", error: "#EF4444", info: "#3B82F6", decorative: "#8B5CF6" }; const menuItems = [ { text: "Dashboard", icon: <FiHome size={20} />, color: iconColors.primary }, { text: "Relationship", icon: <FiUsers size={20} />, color: iconColors.action, hasSubMenu: true, subItems: ["Tasks", "Email", "Leads", "Contacts", "Projects", "Calendar", "Opportunities"] }, { text: "Customers", icon: <FiTruck size={20} />, color: iconColors.success, hasSubMenu: true, subItems: ["Customers", "Invoices", "All Sales", "Deposits"] }, { text: "Expenses", icon: <FiGrid size={20} />, color: iconColors.warning, hasSubMenu: true, subItems: ["Expenses","Vendors", "Bills"] }, { text: "Tickets", icon: <FiShare2 size={20} />, color: iconColors.error, hasSubMenu: true, subItems: ["All Open", "Assigned", "Unassigned","Incidents","Service Requests","Change", "Problem"] }, { text: "Financial", icon: <BsWallet2 size={20} />, color: iconColors.error, hasSubMenu: true, subItems: ["Sales", "Purchases", "Banking", "Payroll", "Accounting"] }, { text: "API Dashboard", icon: <FiShare2 size={20} />, color: iconColors.error, hasSubMenu: true, subItems: ["All Open", "APi",] }, { text: "Reports", icon: <FiBarChart2 size={20} />, color: iconColors.info }, ]; const StyledContainer = styled(Box)<{ darkMode: boolean }>(({ theme, darkMode }) => ({ display: "flex", minHeight: "100vh", backgroundColor: darkMode ? modernColors.background.dark : modernColors.background.light, color: darkMode ? modernColors.text.dark : modernColors.text.light, transition: "all 0.3s cubic-bezier(0.4, 0, 0.2, 1)" })); const StyledAppBar = styled(AppBar)<{ darkMode: boolean }>(({ theme, darkMode }) => ({ backgroundColor: darkMode ? "rgba(15, 23, 42, 0.9)" : "rgba(248, 250, 252, 0.9)", color: darkMode ? modernColors.text.dark : modernColors.text.light, backdropFilter: "blur(12px)", borderBottom: `1px solid ${darkMode ? "rgba(241, 245, 249, 0.1)" : "rgba(51, 65, 85, 0.1)"}` })); const StyledSidebar = styled(Box)<{ open: boolean; darkMode: boolean }>(({ theme, open, darkMode }) => ({ width: open ? 280 : 80, transition: "all 0.3s cubic-bezier(0.4, 0, 0.2, 1)", backgroundColor: darkMode ? "rgba(15, 23, 42, 0.95)" : "rgba(248, 250, 252, 0.95)", borderRight: `1px solid ${darkMode ? "rgba(241, 245, 249, 0.1)" : "rgba(51, 65, 85, 0.1)"}`, position: "fixed", height: "100vh", overflowX: "hidden", overflowY: "auto", "&::-webkit-scrollbar": { width: "6px" }, "&::-webkit-scrollbar-thumb": { backgroundColor: darkMode ? "rgba(241, 245, 249, 0.2)" : "rgba(51, 65, 85, 0.2)", borderRadius: "3px" } })); const StyledListItem = styled(ListItem)<{ darkMode: boolean }>(({ theme, darkMode }) => ({ margin: "4px 8px", borderRadius: "12px", transition: "all 0.2s cubic-bezier(0.4, 0, 0.2, 1)", "&:hover": { backgroundColor: darkMode ? modernColors.hover.dark : modernColors.hover.light, transform: "translateX(4px)" }, "& .MuiListItemIcon-root": { transition: "all 0.2s cubic-bezier(0.4, 0, 0.2, 1)" }, "&:hover .MuiListItemIcon-root": { transform: "scale(1.1)" } })); const SearchBox = styled(InputBase)<{ darkMode: boolean }>(({ theme, darkMode }) => ({ color: "inherit", width: "100%", padding: "6px 12px", borderRadius: "12px", backgroundColor: darkMode ? "rgba(241, 245, 249, 0.1)" : "rgba(51, 65, 85, 0.1)", transition: "all 0.2s cubic-bezier(0.4, 0, 0.2, 1)", "&:hover": { backgroundColor: darkMode ? "rgba(241, 245, 249, 0.15)" : "rgba(51, 65, 85, 0.15)" } })); const ContentArea = styled(Box)<{ darkMode: boolean }>(({ theme, darkMode }) => ({ flexGrow: 1, padding: theme.spacing(3), marginTop: 64, marginLeft: "280px", transition: "all 0.3s cubic-bezier(0.4, 0, 0.2, 1)", backgroundColor: darkMode ? modernColors.background.dark : modernColors.background.light })); const SettingsMenu = styled(Menu)<{ darkMode: boolean }>(({ theme, darkMode }) => ({ "& .MuiPaper-root": { backgroundColor: darkMode ? modernColors.background.dark : modernColors.background.light, border: `1px solid ${darkMode ? "rgba(241, 245, 249, 0.1)" : "rgba(51, 65, 85, 0.1)"}`, borderRadius: "12px", marginTop: "8px", minWidth: "250px", boxShadow: "0 4px 20px rgba(0, 0, 0, 0.1)" } })); const SettingsMenuItem = styled(MenuItem)<{ darkMode: boolean }>(({ theme, darkMode }) => ({ padding: "12px 24px", borderRadius: "8px", margin: "4px 8px", transition: "all 0.2s cubic-bezier(0.4, 0, 0.2, 1)", "&:hover": { backgroundColor: darkMode ? modernColors.hover.dark : modernColors.hover.light, transform: "translateX(4px)" } })); const ProfileMenu = styled(Menu)<{ darkMode: boolean }>(({ theme, darkMode }) => ({ "& .MuiPaper-root": { backgroundColor: darkMode ? modernColors.background.dark : modernColors.background.light, border: `1px solid ${darkMode ? "rgba(241, 245, 249, 0.1)" : "rgba(51, 65, 85, 0.1)"}`, borderRadius: "12px", marginTop: "8px", minWidth: "200px", boxShadow: "0 4px 20px rgba(0, 0, 0, 0.1)" } })); const ProfileMenuItem = styled(MenuItem)<{ darkMode: boolean }>(({ theme, darkMode }) => ({ padding: "12px 24px", display: "flex", alignItems: "center", gap: "12px", transition: "all 0.2s cubic-bezier(0.4, 0, 0.2, 1)", "&:hover": { backgroundColor: darkMode ? modernColors.hover.dark : modernColors.hover.light }, "& .icon": { color: darkMode ? modernColors.text.dark : modernColors.text.light } })); const Layout: React.FC<{ children: React.ReactNode }> = ({ children }) => { const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down("sm")); const [darkMode, setDarkMode] = useState(false); const [open, setOpen] = useState(!isMobile); const [expandedItems, setExpandedItems] = useState<{[key: string]: boolean}>({}); const [searchTerm, setSearchTerm] = useState(""); const [anchorEl, setAnchorEl] = useState(null); const [settingsAnchorEl, setSettingsAnchorEl] = useState(null); const [notificationCount, setNotificationCount] = useState(5); const [languageAnchorEl, setLanguageAnchorEl] = useState(null); const navigate = useNavigate(); const handleNavigation = (path: string) => { navigate(`/${path}`); }; const settingsMenuItems = [ { text: "Manage Users", icon: <FiUsers size={20} /> }, { text: "General Settings", icon: <FiSettings size={20} /> }, { text: "Company Settings", icon: <FiDatabase size={20} /> }, { text: "Payroll Settings", icon: <FiDollarSign size={20} /> }, { text: "Account Settings", icon: <FiUser size={20} /> }, { text: "Template & Documents", icon: <FiFile size={20} /> }, { text: "My Subscription", icon: <FiBookmark size={20} /> } ]; const languages = [ { code: "en", name: "English" }, { code: "es", name: "Spanish" }, { code: "fr", name: "French" }, { code: "de", name: "German" } ]; const profileMenuItems = [ { text: "My Profile", icon: <FiUser size={20} />, action: () => handleProfileAction("profile") }, { text: "Sign Out", icon: <FiLogOut size={20} />, action: () => handleProfileAction("signout") } ]; const handleProfileClick = (event: React.MouseEvent<HTMLButtonElement>) => { setAnchorEl(null); }; const handleSettingsClick = (event: React.MouseEvent<HTMLButtonElement>) => { setSettingsAnchorEl(null); }; const handleLanguageChange = (event: React.MouseEvent<HTMLButtonElement>) => { setLanguageAnchorEl(null); }; const handleLanguageSelect = (languageCode: string) => { console.log(`Selected language: ${languageCode}`); setLanguageAnchorEl(null); }; const handleSettingsClose = () => { setSettingsAnchorEl(null); }; const handleProfileClose = () => { setAnchorEl(null); }; const handleProfileAction = (action: string) => { handleProfileClose(); console.log(`Profile action: ${action}`); }; const handleSettingsAction = (setting: string) => { handleSettingsClose(); console.log(`Selected setting: ${setting}`); }; const handleHelpClick = () => { console.log("Help clicked"); }; return ( <StyledContainer darkMode={darkMode}> <StyledAppBar position="fixed" darkMode={darkMode} elevation={0}> <Toolbar sx={{ justifyContent: "space-between" }}> <Box sx={{ display: "flex", alignItems: "center" }}> <IconButton color="inherit" onClick={() => setOpen(!open)} edge="start" sx={{ marginRight: 2, transition: "transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)", transform: open ? "rotate(0deg)" : "rotate(180deg)" }} > <FiMenu /> </IconButton> <Typography variant="h6" sx={{ fontWeight: 600 }}> Dashboard </Typography> </Box> <Box sx={{ display: "flex", alignItems: "center", gap: 2 }}> <SearchBox placeholder="Search..." darkMode={darkMode} startAdornment={<FiSearch style={{ marginRight: 8 }} />} onChange={(e) => setSearchTerm(e.target.value)} /> <Tooltip title="Learn"> <IconButton color="inherit"> <FiBook size={20} /> </IconButton> </Tooltip> <Tooltip title="Help"> <IconButton color="inherit" onClick={handleHelpClick}> <FiHelpCircle size={20} /> </IconButton> </Tooltip> <Tooltip title="Notifications"> <IconButton color="inherit"> <Badge badgeContent={notificationCount} color="error"> <FiBell size={20} /> </Badge> </IconButton> </Tooltip> <Tooltip title="Change Language"> <IconButton color="inherit" onClick={handleLanguageChange}> <FiGlobe size={20} /> </IconButton> </Tooltip> <Menu anchorEl={languageAnchorEl} open={Boolean(languageAnchorEl)} onClose={() => setLanguageAnchorEl(null)} PaperProps={{ sx: { mt: 1.5, backgroundColor: darkMode ? modernColors.background.dark : modernColors.background.light, border: `1px solid ${darkMode ? "rgba(241, 245, 249, 0.1)" : "rgba(51, 65, 85, 0.1)"}`, borderRadius: "12px", minWidth: "150px" } }} > {languages.map((lang) => ( <MenuItem key={lang.code} onClick={() => handleLanguageSelect(lang.code)} sx={{ py: 1.5, px: 2.5, "&:hover": { backgroundColor: darkMode ? modernColors.hover.dark : modernColors.hover.light } }} > <Typography>{lang.name}</Typography> </MenuItem> ))} </Menu> <IconButton color="inherit" onClick={handleSettingsClick} sx={{ transition: "transform 0.2s cubic-bezier(0.4, 0, 0.2, 1)", "&:hover": { transform: "rotate(90deg)" } }} > <FiSettings /> </IconButton> <SettingsMenu anchorEl={settingsAnchorEl} open={Boolean(settingsAnchorEl)} onClose={handleSettingsClose} darkMode={darkMode} anchorOrigin={{ vertical: "bottom", horizontal: "right" }} transformOrigin={{ vertical: "top", horizontal: "right" }} > {settingsMenuItems.map((item) => ( <SettingsMenuItem key={item.text} onClick={() => handleSettingsAction(item.text)} darkMode={darkMode} > <Box sx={{ display: "flex", alignItems: "center", gap: 2 }}> {item.icon} <Typography>{item.text}</Typography> </Box> </SettingsMenuItem> ))} </SettingsMenu> <IconButton color="inherit" onClick={() => setDarkMode(!darkMode)} sx={{ transition: "transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)", "&:hover": { transform: "rotate(180deg)" } }} > {darkMode ? <FiSun /> : <FiMoon />} </IconButton> <IconButton color="inherit" onClick={handleProfileClick} sx={{ padding: "8px", borderRadius: "50%", border: `2px solid ${darkMode ? modernColors.text.dark : modernColors.text.light}`, transition: "all 0.2s cubic-bezier(0.4, 0, 0.2, 1)", "&:hover": { transform: "scale(1.1)" } }} > <Avatar src="https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=150&q=80" alt="Profile" sx={{ width: 32, height: 32 }} /> </IconButton> <ProfileMenu anchorEl={anchorEl} open={Boolean(anchorEl)} onClose={handleProfileClose} darkMode={darkMode} anchorOrigin={{ vertical: "bottom", horizontal: "right" }} transformOrigin={{ vertical: "top", horizontal: "right" }} > {profileMenuItems.map((item) => ( <ProfileMenuItem key={item.text} onClick={item.action} darkMode={darkMode} > <Box className="icon">{item.icon}</Box> <Typography>{item.text}</Typography> </ProfileMenuItem> ))} </ProfileMenu> </Box> </Toolbar> </StyledAppBar> <StyledSidebar open={open} darkMode={darkMode}> <List> {menuItems.map((item) => ( <React.Fragment key={item.text}> <StyledListItem onClick={() => { if (item.hasSubMenu) { setExpandedItems((prev) => ({ ...prev, [item.text]: !prev[item.text] })); } }} darkMode={darkMode} > <ListItemIcon sx={{ color: item.color }}> {item.icon} </ListItemIcon> <ListItemText primary={item.text} /> {item.hasSubMenu && ( <IconButton size="small"> {expandedItems[item.text] ? <FiChevronUp /> : <FiChevronDown />} </IconButton> )} </StyledListItem> {item.hasSubMenu && ( <Collapse in={expandedItems[item.text]} timeout="auto" unmountOnExit> <List component="div" disablePadding> {item.subItems.map((subItem: string | { text: string }) => ( <StyledListItem key={typeof subItem === 'string' ? subItem : subItem.text} sx={{ pl: 4 }} darkMode={darkMode} > <ListItemText primary={ typeof subItem === "string" ? subItem : subItem.text } /> </StyledListItem> ))} </List> </Collapse> )} </React.Fragment> ))} </List> </StyledSidebar> <ContentArea darkMode={darkMode}> <main style={{ flexGrow: 1, padding: '20px', marginLeft: open ? 240 : 0, transition: 'margin-left 0.3s ease' }}> {children} </main> </ContentArea> </StyledContainer> ); }; export default Layout;

Prompt

About

drawerWidth - Create a responsive drawer menu with EDI options like Dashboard and Settings. Built with React and MUI. Start coding now!

Share

Last updated 1 month ago