import * as react from 'react'; import { ReactNode } from 'react'; interface TreeNodeData { /** Unique identifier */ id: string; /** Display label */ label: string; /** Node type for icon rendering */ type?: "file" | "folder"; /** File extension hint (e.g., "ts", "php", "html") for icon coloring */ ext?: string; /** Nested children */ children?: TreeNodeData[]; /** Custom icon override */ icon?: ReactNode; /** Whether the node is disabled */ disabled?: boolean; } /** Where the dragged node will land relative to the drop target */ type DropPosition = "before" | "after" | "inside"; interface DragState { draggedNodeId: string | null; dropTargetId: string | null; dropPosition: DropPosition | null; } interface TreeNavProps { /** Tree data */ nodes: TreeNodeData[]; /** Currently selected node ID */ selectedId?: string; /** Callback when a node is selected */ onSelect?: (id: string, node: TreeNodeData) => void; /** Callback when a node is right-clicked */ onNodeContextMenu?: (e: React.MouseEvent, node: TreeNodeData) => void; /** Enable drag-and-drop reordering (default: false) */ draggable?: boolean; /** Callback when a node is moved via drag and drop */ onNodeMove?: (sourceId: string, targetId: string, position: DropPosition) => void; /** Accept drops from outside the tree — OS files, items from other * components, etc. When true, drag-over is allowed for any data source * and `onExternalDrop` fires on drop. (default: false) */ acceptExternalDrops?: boolean; /** Called when an external drag (file or cross-component) is dropped on * a node. The raw event lets you read `event.dataTransfer.files` for OS * file drops or `event.dataTransfer.getData(type)` for custom MIME * payloads from other components. */ onExternalDrop?: (event: React.DragEvent, target: TreeNodeData, position: DropPosition) => void; /** Controlled expanded node IDs */ expandedIds?: string[]; /** Default expanded node IDs (uncontrolled) */ defaultExpandedIds?: string[]; /** Callback when expanded state changes */ onExpandedChange?: (ids: string[]) => void; /** Expand all folders by default */ defaultExpandAll?: boolean; /** Indent size per nesting level in px (default: 16) */ indentSize?: number; /** Show file/folder icons (default: true) */ showIcons?: boolean; /** * Cursor shown on hover over a draggable node. * - `"none"` (default): the normal clickable cursor — no move affordance on * mere hover. A closed-hand `grabbing` cursor still appears while a drag is * actually happening. This suits click-to-select/open trees (file/nav * trees), where an always-on grab cursor wrongly implies move-first intent. * - `"grab"`: show the open-hand `grab` cursor on hover. Opt in when the whole * row is genuinely a drag handle and reordering is the primary interaction. * @default "none" */ dragCursor?: "grab" | "none"; /** Custom className */ className?: string; } interface TreeNavContextValue { selectedId?: string; onSelect?: (id: string, node: TreeNodeData) => void; onNodeContextMenu?: (e: React.MouseEvent, node: TreeNodeData) => void; expandedIds: string[]; toggle: (id: string) => void; indentSize: number; showIcons: boolean; draggable: boolean; dragCursor: "grab" | "none"; dragState: DragState; setDragState: (state: DragState) => void; onNodeMove?: (sourceId: string, targetId: string, position: DropPosition) => void; acceptExternalDrops: boolean; onExternalDrop?: (event: React.DragEvent, target: TreeNodeData, position: DropPosition) => void; nodes: TreeNodeData[]; expandNode: (id: string) => void; } interface TreeNodeProps { node: TreeNodeData; depth: number; className?: string; } declare function TreeNode({ node, depth }: TreeNodeProps): react.JSX.Element; declare namespace TreeNode { var displayName: string; } declare function TreeNavRoot({ nodes, selectedId, onSelect, onNodeContextMenu, draggable, onNodeMove, acceptExternalDrops, onExternalDrop, expandedIds: controlledExpanded, defaultExpandedIds, onExpandedChange, defaultExpandAll, indentSize, showIcons, dragCursor, className, }: TreeNavProps): react.JSX.Element; declare namespace TreeNavRoot { var displayName: string; } declare const TreeNav: typeof TreeNavRoot & { Node: typeof TreeNode; }; declare function useTreeNav(): TreeNavContextValue; export { type DropPosition, TreeNav, type TreeNavContextValue, type TreeNavProps, type TreeNodeData, type TreeNodeProps, useTreeNav };