seti-ramesesv1
Version:
Reusable components and context for Next.js apps
53 lines (50 loc) • 4.22 kB
JavaScript
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