import { type ComponentType } from 'react' import type { VaultEntry, SidebarSelection } from '../types' import { cn } from '@/lib/utils' import { ChevronRight, ChevronDown, Plus, GripVertical } from 'lucide-react' import { getTypeColor, getTypeLightColor } from '../utils/typeColors' import { type IconProps } from '@phosphor-icons/react' export interface SectionGroup { label: string type: string Icon: ComponentType customColor?: string | null } export function isSelectionActive(current: SidebarSelection, check: SidebarSelection): boolean { if (current.kind !== check.kind) return false switch (check.kind) { case 'filter': return (current as typeof check).filter === check.filter case 'sectionGroup': return (current as typeof check).type === check.type case 'entity': case 'topic': return (current as typeof check).entry.path === check.entry.path default: return false } } // --- NavItem --- export function NavItem({ icon: Icon, label, count, isActive, activeClassName = 'bg-primary/10 text-primary', badgeClassName, badgeStyle, onClick, disabled }: { icon: ComponentType label: string count?: number isActive?: boolean activeClassName?: string badgeClassName?: string badgeStyle?: React.CSSProperties onClick?: () => void disabled?: boolean }) { if (disabled) { return (
{label}
) } return (
{label} {count !== undefined && count > 0 && ( {count} )}
) } // --- Section Content --- export interface SectionContentProps { group: SectionGroup items: VaultEntry[] isCollapsed: boolean selection: SidebarSelection onSelect: (sel: SidebarSelection) => void onSelectNote?: (entry: VaultEntry) => void onCreateType?: (type: string) => void onCreateNewType?: () => void onContextMenu: (e: React.MouseEvent, type: string) => void onToggle: () => void dragHandleProps?: Record } function childSelection(type: string, entry: VaultEntry): SidebarSelection { return type === 'Topic' ? { kind: 'topic', entry } : { kind: 'entity', entry } } function resolveCreateHandler(type: string, onCreateType?: (type: string) => void, onCreateNewType?: () => void): (() => void) | undefined { const isType = type === 'Type' if (!onCreateType && !(isType && onCreateNewType)) return undefined return isType ? () => onCreateNewType?.() : () => onCreateType?.(type) } export function SectionContent({ group, items, isCollapsed, selection, onSelect, onSelectNote, onCreateType, onCreateNewType, onContextMenu, onToggle, dragHandleProps, }: SectionContentProps) { const { label, type, Icon, customColor } = group const sectionColor = getTypeColor(type, customColor) const sectionLightColor = getTypeLightColor(type, customColor) const onCreate = resolveCreateHandler(type, onCreateType, onCreateNewType) return ( <> onSelect({ kind: 'sectionGroup', type })} onContextMenu={(e) => onContextMenu(e, type)} onToggle={onToggle} onCreate={(e) => { e.stopPropagation(); onCreate?.() }} dragHandleProps={dragHandleProps} /> {!isCollapsed && items.length > 0 && ( )} ) } function SectionChildList({ items, type, selection, sectionColor, sectionLightColor, onSelect, onSelectNote }: { items: VaultEntry[]; type: string; selection: SidebarSelection sectionColor: string; sectionLightColor: string onSelect: (sel: SidebarSelection) => void; onSelectNote?: (entry: VaultEntry) => void }) { return (
{items.map((entry) => { const sel = childSelection(type, entry) const active = isSelectionActive(selection, sel) return ( { onSelect(sel); onSelectNote?.(entry) }} /> ) })}
) } function SectionHeader({ label, type, Icon, sectionColor, isCollapsed, isActive, showCreate, onSelect, onContextMenu, onToggle, onCreate, dragHandleProps }: { label: string; type: string; Icon: ComponentType sectionColor: string; isCollapsed: boolean; isActive: boolean; showCreate: boolean onSelect: () => void; onContextMenu: (e: React.MouseEvent) => void onToggle: () => void; onCreate: (e: React.MouseEvent) => void dragHandleProps?: Record }) { return (
{label}
{showCreate && ( )}
) } function SectionChildItem({ title, isActive, sectionColor, sectionLightColor, onClick }: { title: string; isActive: boolean sectionColor?: string; sectionLightColor?: string onClick: () => void }) { return (
{title}
) } // --- Visibility Popover --- export function VisibilityPopover({ sections, isSectionVisible, onToggle }: { sections: SectionGroup[] isSectionVisible: (type: string) => boolean onToggle: (type: string) => void }) { return (
Show in sidebar
{sections.map(({ label, type, Icon }) => ( ))}
) } function ToggleSwitch({ on }: { on: boolean }) { return (
) }