"use client"; import { useEffect, useRef, useState } from "react"; import styles from "./CategoryTreeView.module.css"; export type CategoryTreeNode = { id: string; name: string; hint?: string; children: CategoryTreeNode[]; }; export type CategoryTreeActions = { onAddChild?: (id: string) => void; onEdit?: (id: string) => void; onRemove?: (id: string) => void; }; export default function CategoryTreeView({ nodes, emptyLabel = "No categories yet", actions, }: { nodes: CategoryTreeNode[]; emptyLabel?: string; actions?: CategoryTreeActions; }) { if (!nodes.length) { return

{emptyLabel}

; } return ( ); } function TreeBranch({ node, depth, actions, }: { node: CategoryTreeNode; depth: number; actions?: CategoryTreeActions; }) { const [open, setOpen] = useState(false); const childCount = node.children.length; const previousChildCount = useRef(childCount); const hasChildren = childCount > 0; const hasActions = Boolean( actions?.onAddChild || actions?.onEdit || actions?.onRemove, ); useEffect(() => { if (childCount > previousChildCount.current) { setOpen(true); } previousChildCount.current = childCount; }, [childCount]); return (
  • {hasChildren ? ( ) : ( )} {node.name} {node.hint ? {node.hint} : null} {hasActions ? (
    {actions?.onAddChild ? ( ) : null} {actions?.onEdit ? ( ) : null} {actions?.onRemove ? ( ) : null}
    ) : null}
    {hasChildren && open ? ( ) : null}
  • ); }