UNPKG

seti-ramesesv1

Version:

Reusable components and context for Next.js apps

53 lines (50 loc) 4.22 kB
import { jsxs, jsx } from 'react/jsx-runtime'; import { ChevronLeft } from 'lucide-react'; import { useState, useEffect } from 'react'; import styles from '../../styles/Sidebar.module.css.js'; import Button from '../ui/Button.js'; import '../../styles/Checkbox.module.css.js'; import '../../styles/Text.module.css.js'; import '../../styles/Modal.module.css.js'; import '../../styles/Panel.module.css.js'; import '../../styles/Radio.module.css.js'; import './RadioGroup.js'; import '../../styles/Select.module.css.js'; import '../../styles/Tooltip.module.css.js'; function Sidebar({ onClick, items, activeItem, storageKey = "sidebar-isOpen", hideToggle = false }) { const [isOpen, setIsOpen] = useState(null); const [openCategoryIndex, setOpenCategoryIndex] = useState(null); // Accordion control useEffect(() => { const stored = localStorage.getItem(storageKey); const parsed = stored === null ? true : stored === "true"; setIsOpen(parsed); }, [storageKey]); useEffect(() => { if (isOpen !== null) { localStorage.setItem(storageKey, String(isOpen)); } }, [isOpen, storageKey]); if (isOpen === null) return null; const hasAnyIcon = items.some((item) => item.items?.some((subItem) => !!subItem.icon)); const sidebarClass = `${styles.sidebar} ${isOpen ? styles.sidebarOpen : hasAnyIcon ? styles.sidebarCollapsed : styles.sidebarCollapsedNoIcon}`; const allSubItems = items.flatMap((group) => group.items || []); const matchKey = allSubItems.find((item) => Object.entries(item).some(([key, value]) => value === activeItem))?.type ? "type" : allSubItems.find((item) => Object.entries(item).some(([key, value]) => value === activeItem))?.page ? "page" : undefined; const handleCategoryToggle = (index) => { setOpenCategoryIndex((prev) => (prev === index ? null : index)); }; return (jsxs("div", { className: sidebarClass, children: [!hideToggle && (jsx(Button, { onClick: () => setIsOpen(!isOpen), className: `${styles.sidebarToggle} ${isOpen ? styles.sidebarToggleExpanded : ""}`, variant: "custom", children: jsx("svg", { className: `${styles.sidebarArrow} ${!isOpen ? styles.sidebarArrowRotated : ""}`, fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: jsx("path", { d: "M15 19l-7-7 7-7" }) }) })), jsx("div", { className: styles.sidebarContent, children: items.map((item, index) => (jsxs("div", { className: styles.sidebarSection, children: [item.type === "category" && isOpen && (jsxs("div", { className: styles.sidebarCategory, style: { cursor: item.isDropdown ? "pointer" : "default" }, onClick: () => item.isDropdown && handleCategoryToggle(index), children: [jsx("p", { children: item.title }), item.isDropdown && (jsx(ChevronLeft, { className: `transition-transform duration-200 ${openCategoryIndex === index ? "rotate-[-90deg]" : "rotate-0"}` }))] })), item.items && (!item.isDropdown || openCategoryIndex === index) && // Only show if dropdown is open or not a dropdown item.items.map((subItem, subIndex) => { if (!isOpen && !subItem.icon) return null; const isActive = matchKey ? subItem[matchKey] === activeItem : false; return (jsxs("div", { className: styles.sidebarItemWrapper, onClick: () => subItem && onClick(subItem), children: [jsxs("div", { className: `${styles.sidebarItem} ${isOpen ? styles.sidebarItemOpen : styles.sidebarItemCollapsed} ${isActive ? styles.sidebarItemActive : ""}`, children: [subItem.icon && (jsx("img", { src: subItem.icon, alt: subItem.title, className: `${styles.sidebarIcon} ${styles.fadeIn}` })), jsx("p", { className: `${styles.sidebarTitle} ${!isOpen ? styles.sidebarTitleCollapsed : styles.slideIn}`, children: isOpen && subItem.title })] }), !isOpen && subItem.icon && jsx("div", { className: styles.sidebarTooltip, children: subItem.title })] }, subIndex)); })] }, index))) })] })); } export { Sidebar as default }; //# sourceMappingURL=Sidebar.js.map