import { useRef } from 'react'; import { slugify } from 'markdown-to-jsx'; import { CollapseExpandButton } from '@@/CollapseExpandButton'; import { Checkbox } from '@@/form-components/Checkbox'; import { isDirectory, getFolderState, isDirectoryWithChildren } from './utils'; import { TreeNodeIcon } from './TreeNodeIcon'; import { FileNode } from './types'; const INDENT_PX = 16; const DOUBLE_CLICK_DELAY_MS = 250; interface Props { item: FileNode; depth: number; expanded: Set; selected: Set; nodePath: string; onExpandDirectory: (path: string) => void; onToggleSelect: (path: string, item: FileNode) => void; } export function TreeNode({ item, depth, expanded, selected, nodePath, onExpandDirectory, onToggleSelect, }: Props) { const isDir = isDirectory(item); const hasSubDir = isDirectoryWithChildren(item); const isOpen = isDir && expanded.has(nodePath); const folderState = isDir ? getFolderState(item, selected, nodePath) : null; const isChecked = isDir ? folderState === 'checked' : selected.has(nodePath); const isIndeterminate = folderState === 'indeterminate'; const checkboxId = slugify(`${nodePath}/${item.name}`); const clickTimerRef = useRef | null>(null); function handleRowClick() { if (clickTimerRef.current) { clearTimeout(clickTimerRef.current); clickTimerRef.current = null; if (isDir) { onExpandDirectory(nodePath); } return; } clickTimerRef.current = setTimeout(() => { clickTimerRef.current = null; onToggleSelect(nodePath, item); }, DOUBLE_CLICK_DELAY_MS); } return ( <>
{ if (e.key === 'Enter' && isDir) onExpandDirectory(nodePath); if (e.key === 'Space') onToggleSelect(nodePath, item); }} > {isDir ? ( onExpandDirectory(nodePath)} /> ) : ( )} onToggleSelect(nodePath, item)} onClick={(e) => e.stopPropagation()} aria-labelledby={`${checkboxId}-label`} /> {item.name}
{isOpen && hasSubDir && item.children.map((child, index) => ( ))} ); }