// Copyright 2024, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 import clsx from "clsx"; import React, { memo, useState } from "react"; import "./collapsiblemenu.scss"; interface VerticalNavProps { items: MenuItem[]; className?: string; renderItem?: ( item: MenuItem, isOpen: boolean, handleClick: (e: React.MouseEvent, item: MenuItem, itemKey: string) => void ) => React.ReactNode; } const CollapsibleMenu = memo(({ items, className, renderItem }: VerticalNavProps) => { const [open, setOpen] = useState<{ [key: string]: boolean }>({}); // Helper function to generate a unique key for each item based on its path in the hierarchy const getItemKey = (item: MenuItem, path: string) => `${path}-${item.label}`; const handleClick = (e: React.MouseEvent, item: MenuItem, itemKey: string) => { setOpen((prevState) => ({ ...prevState, [itemKey]: !prevState[itemKey] })); if (item.onClick) { item.onClick(e); } }; const renderListItem = (item: MenuItem, index: number, path: string) => { const itemKey = getItemKey(item, path); const isOpen = open[itemKey] === true; const hasChildren = item.subItems && item.subItems.length > 0; return (
  • {renderItem ? ( renderItem(item, isOpen, (e) => handleClick(e, item, itemKey)) ) : (
    handleClick(e, item, itemKey)}>
    {item.icon &&
    {item.icon}
    }
    {item.label}
    {hasChildren && ( )}
    )} {hasChildren && (
      {item.subItems.map((child, childIndex) => renderListItem(child, childIndex, `${path}-${index}`) )}
    )}
  • ); }; return ( ); }); CollapsibleMenu.displayName = "CollapsibleMenu"; export { CollapsibleMenu };