import React, { useLayoutEffect, useRef, useState } from 'react' export interface SidebarNavItem { label: string icon: string href?: string badge?: number children?: SidebarNavItem[] disabled?: boolean active?: boolean } export interface SidebarNavGroup { title?: string children: SidebarNavItem[] } export interface SidebarNavProps { items: SidebarNavGroup[] activePath?: string onItemClick?: (item: SidebarNavItem) => void header?: React.ReactNode footer?: React.ReactNode showLogo?: boolean showUser?: boolean } export const SidebarNav: React.FC = ({ items, activePath, onItemClick, header, footer, showLogo = true, showUser = true, }) => { const [expanded, setExpanded] = useState>(new Set()) const navRef = useRef(null) const [indicator, setIndicator] = useState<{ top: number; left: number; width: number; height: number } | null>(null) const toggleExpanded = (key: number) => { setExpanded(prev => { const next = new Set(prev) if (next.has(key)) next.delete(key) else next.add(key) return next }) } useLayoutEffect(() => { const nav = navRef.current if (!nav) return const active = nav.querySelector('[data-active="true"]') if (!active) { setIndicator(null); return } const navRect = nav.getBoundingClientRect() const aRect = active.getBoundingClientRect() setIndicator({ top: aRect.top - navRect.top + nav.scrollTop, left: aRect.left - navRect.left, width: aRect.width, height: aRect.height, }) }, [activePath, expanded, items]) return ( ) }