UNPKG

ar-design

Version:

AR Design is a (react | nextjs) ui library.

90 lines (89 loc) 4.76 kB
"use client"; import React, { useEffect, useState } from "react"; import "../../../assets/css/components/navigation/menu/styles.css"; import { DispatchEvent, SessionStorage } from "../../../libs/infrastructure/shared/Enums"; const Menu = ({ data, variant = "vertical", config, ...attributes }) => { // states const [openMenus, setOpenMenus] = useState([]); const [selectedKey, setSelectedKey] = useState(null); const [isMenuLocked, setIsMenuLocked] = useState(true); // methods const handleItemClick = (item) => { if (!isMenuLocked && item.type === "group") return; if (item.type === "group") { const parents = findPath(item.key, data) ?? []; setOpenMenus((prev) => { const isOpen = prev.includes(item.key); if (isOpen) return prev.filter((k) => k !== item.key); return [...parents, item.key]; }); return; } if (item.type !== "divider") { setSelectedKey(item.key); sessionStorage.setItem(SessionStorage.SelectedMenuItem, String(item.key)); } }; const findPath = (key, items, path = []) => { for (const item of items) { if (item.key === key) return path; if (item.submenu) { const result = findPath(key, item.submenu, [...path, item.key]); if (result) return result; } } return null; }; // useEffects useEffect(() => { if (!data.length) return; const selectedMenuItem = sessionStorage.getItem(SessionStorage.SelectedMenuItem) ?? ""; setSelectedKey(selectedMenuItem); const parents = findPath(selectedMenuItem, data); if (parents) setOpenMenus(parents); }, [data]); useEffect(() => { const onStorageChangeSelectedMenuItem = () => { setSelectedKey(JSON.parse(sessionStorage.getItem(SessionStorage.SelectedMenuItem) ?? "")); }; const onStorageChangeMenuLock = () => { setIsMenuLocked(JSON.parse(sessionStorage.getItem(SessionStorage.MenuIsLocked) ?? "true")); }; window.addEventListener(DispatchEvent.SelectedMenuItem, onStorageChangeSelectedMenuItem); window.addEventListener(DispatchEvent.MenuLock, onStorageChangeMenuLock); const styles = document.createElement("style"); styles.innerHTML = ` :root { --selected-icon-color: ${config?.icon?.selectedColor}; --selected-icon-bg-color: ${config?.icon?.selectedBackgroundColor}; --selected-icon-bg-color-rgb: ${config?.icon?.selectedBackgroundBorderColor}; } `; document.head.appendChild(styles); return () => { window.removeEventListener(DispatchEvent.SelectedMenuItem, onStorageChangeSelectedMenuItem); window.removeEventListener(DispatchEvent.MenuLock, onStorageChangeMenuLock); }; }, []); return (React.createElement("nav", { className: "ar-menu", ...attributes }, React.createElement("ul", null, data.map((item) => (React.createElement(MenuItem, { key: item.key, item: item, openMenus: openMenus, selectedKey: selectedKey, isMenuLocked: isMenuLocked, onClick: handleItemClick })))))); }; const MenuItem = ({ item, openMenus, selectedKey, isMenuLocked, onClick }) => { const isOpen = openMenus.includes(item.key); const isSelected = selectedKey === item.key && item.type !== "group"; return (React.createElement("li", { "data-menu-id": `ar-menu-${item.key}`, className: `${item.type === "divider" ? "divider" : ""} ${isSelected ? "selected" : ""}` }, React.createElement("div", { className: `item-render ${isMenuLocked ? "align-left" : "align-center"}`, onClick: () => onClick(item) }, item.type !== "divider" && React.createElement("span", { className: "icon" }, item.icon ?? React.createElement("span", { className: "no-icon" })), isMenuLocked && (item.type === "divider" ? React.createElement("hr", null) : React.createElement("span", { className: "item" }, item.render)), isMenuLocked && item.type === "group" && React.createElement("span", { className: `angel-down ${isOpen ? "opened" : ""}` })), item.submenu && isMenuLocked && (React.createElement("ul", { className: `submenu ${isOpen ? "opened" : ""}` }, React.createElement("div", { className: "submenu-inner" }, item.submenu.map((sub) => (React.createElement(MenuItem, { key: sub.key, item: sub, openMenus: openMenus, selectedKey: selectedKey, isMenuLocked: isMenuLocked, onClick: onClick })))))))); }; Menu.displayName = "Menu"; export default Menu;