import { ReactNode } from 'react'; import { AthenaUiNavigationIconKey } from '../icons/athena-icons.js'; import { DashboardSidebarActiveItemVariant, DashboardSidebarBadgeVariant, DashboardSidebarItemVariant, DashboardSidebarRadius, DashboardSidebarSize, DashboardSidebarSurfaceVariant } from './tokens.js'; /** Nested panel id. Free-form string so apps compose arbitrary drill-in groups. */ export type DashboardSidebarNestedKey = string; export type DashboardSidebarNavigationIconKey = AthenaUiNavigationIconKey; export interface DashboardSidebarItemConfig { adminPermissions?: string[]; badge?: string; external?: boolean; href: string; icon: DashboardSidebarNavigationIconKey; iconSize?: DashboardSidebarSize; id: string; label: string; nestedKey?: DashboardSidebarNestedKey; separatorBefore?: boolean; showBadge?: boolean; showExternalIcon?: boolean; showNestedArrow?: boolean; } export interface DashboardSidebarNestedGroupConfig { eyebrow: string; icon: DashboardSidebarNavigationIconKey; items: DashboardSidebarItemConfig[]; key: DashboardSidebarNestedKey; title: string; } export interface DashboardSidebarRoutePin { label: string; nestedKey: DashboardSidebarNestedKey; pathExpression?: string; pathnamePrefix: string; } export interface DashboardSidebarAccountConfig { badge?: string; email: string; initials: string; name: string; } export interface DashboardSidebarConfig { account: DashboardSidebarAccountConfig; activeItemVariant: DashboardSidebarActiveItemVariant; animationDurationMs: number; autoOpenPinnedRoutes: boolean; avatarSize: DashboardSidebarSize; badgeVariant: DashboardSidebarBadgeVariant; footerBadge?: string; iconSize: DashboardSidebarSize; itemSize: DashboardSidebarSize; itemVariant: DashboardSidebarItemVariant; logoIcon: DashboardSidebarNavigationIconKey; nestedBackButtonAlign: "center" | "start"; nestedGroups: Record; organizationLabel: string; radius: DashboardSidebarRadius; rootItems: DashboardSidebarItemConfig[]; routePins: DashboardSidebarRoutePin[]; showBadges: boolean; showExternalLinks: boolean; showNestedArrows: boolean; showNestedGroupHeader: boolean; surfaceVariant: DashboardSidebarSurfaceVariant; title: string; widthClassName: string; } export interface DashboardSidebarSlots { /** Replace the footer account row. */ footer?: ReactNode | ((ctx: DashboardSidebarRenderContext) => ReactNode); /** Replace the logo / title header. */ header?: ReactNode | ((ctx: DashboardSidebarRenderContext) => ReactNode); /** Wrap or replace a single nav row. */ item?: (ctx: DashboardSidebarItemRenderContext) => ReactNode; } export interface DashboardSidebarRenderContext { activePath: string; config: DashboardSidebarConfig; nestedKey: DashboardSidebarNestedKey | null; onCloseNested: () => void; onNavigate: (href: string) => void; onOpenNested: (key: DashboardSidebarNestedKey) => void; } export interface DashboardSidebarItemRenderContext extends DashboardSidebarRenderContext { isActive: boolean; item: DashboardSidebarItemConfig; } export interface DashboardSidebarProps { activePath: string; config?: DashboardSidebarConfig; /** * Optional close (X) for mobile/drawer embeddings. Wired into the default * header when `slots.header` is not replaced. */ onClose?: () => void; onNavigate: (href: string) => void; /** * Optional composition slots. Prefer compound exports * (`DashboardSidebarHeader`, `DashboardSidebarNav`, …) for full control. */ slots?: DashboardSidebarSlots; }