UNPKG

@darksnow-ui/node-tree-react

Version:
1 lines 31 kB
{"version":3,"sources":["../src/components/NodeTree.tsx","../src/components/TreeNode.tsx","../src/components/NodeWrapper.tsx","../src/components/ContextMenu.tsx","../src/hooks/useNodeTreeMenuItems.tsx"],"sourcesContent":["import {\n useNodeTree,\n useNodeTreeState,\n useContextMenu,\n NodeRow,\n Node,\n} from \"@darksnow-ui/node-tree-headless\";\nimport { TreeNode } from \"./TreeNode\";\nimport { ContextMenu } from \"./ContextMenu\";\nimport { MenuItemConfig } from \"@darksnow-ui/menus\";\nimport { useState, useCallback } from \"react\";\nimport { clsx } from \"clsx\";\n\nexport interface NodeTreeProps {\n className?: string;\n style?: React.CSSProperties;\n renderNode?: (props: { row: any }) => React.ReactNode;\n renderEmptyState?: () => React.ReactNode;\n onContextMenuAction?: (action: string, nodeId: string) => void;\n indentSize?: number;\n showContextMenu?: boolean;\n contextMenuClassName?: string;\n contextMenuItems?: MenuItemConfig[] | ((nodeId: string) => MenuItemConfig[]);\n emptyStateClassName?: string;\n showRootDropArea?: boolean;\n rootDropAreaClassName?: string;\n renderRootDropArea?: (isDragOver: boolean) => React.ReactNode;\n resolveIcon?: (node: Node, isExpanded: boolean) => string;\n}\n\nexport function NodeTree({\n className,\n style,\n renderNode,\n renderEmptyState,\n onContextMenuAction,\n indentSize = 20,\n showContextMenu = true,\n contextMenuClassName,\n contextMenuItems,\n emptyStateClassName,\n showRootDropArea = true,\n rootDropAreaClassName,\n renderRootDropArea,\n resolveIcon,\n}: NodeTreeProps) {\n const context = useNodeTree();\n const indexedNodes = useNodeTreeState((state) => state.indexedNodes);\n const nodes = useNodeTreeState((state) => state.nodes);\n const dragOverId = useNodeTreeState((state) => state.dragOverId);\n const dragStartId = useNodeTreeState((state) => state.dragStartId);\n const { contextMenu, closeContextMenu } = useContextMenu();\n const [hasFocus, setHasFocus] = useState(false);\n\n const defaultRenderNode = useCallback(\n (row: NodeRow) => {\n const node = nodes.get(row.id);\n if (!node) return null;\n\n const state = context.services.store.getState();\n const enhancedRow = {\n ...row,\n node,\n selected: state.selectedNodes.has(row.id),\n expanded: state.expandedNodes.has(row.id),\n visible: true,\n isCursor: state.cursorId === row.id,\n isFocus: state.focusId === row.id,\n };\n\n return (\n <TreeNode\n key={row.id}\n row={enhancedRow}\n indentSize={indentSize}\n resolveIcon={resolveIcon}\n />\n );\n },\n [nodes, context.services.store, indentSize],\n );\n\n const defaultRenderEmptyState = () => (\n <div\n className={\n emptyStateClassName ||\n \"text-center py-8 text-gray-500 dark:text-gray-400\"\n }\n >\n No nodes to display\n </div>\n );\n\n const defaultRenderRootDropArea = (isDragOver: boolean) => (\n <div\n className={clsx(\n rootDropAreaClassName || \"node-tree-root-drop-area\",\n isDragOver && \"drag-over\",\n )}\n style={{\n flex: 1,\n minHeight: \"20px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.2s ease\",\n cursor: \"pointer\",\n }}\n />\n );\n\n return (\n <>\n <div\n ref={context.elementRef}\n tabIndex={0}\n className={clsx(\n \"node-tree-container\",\n hasFocus && \"has-focus\",\n className,\n )}\n style={{\n ...style,\n display: \"flex\",\n flexDirection: \"column\",\n height: \"100%\",\n }}\n onFocus={() => setHasFocus(true)}\n onBlur={() => setHasFocus(false)}\n >\n <div className=\"node-tree-content\" style={{ flexShrink: 0 }}>\n {indexedNodes && indexedNodes.length > 0\n ? indexedNodes.map((row: NodeRow) => {\n if (renderNode) {\n const node = nodes.get(row.id);\n if (!node) return null;\n\n const state = context.services.store.getState();\n const enhancedRow = {\n ...row,\n node,\n selected: state.selectedNodes.has(row.id),\n expanded: state.expandedNodes.has(row.id),\n visible: true,\n isCursor: state.cursorId === row.id,\n isFocus: state.focusId === row.id,\n };\n\n return renderNode({ row: enhancedRow });\n }\n return defaultRenderNode(row);\n })\n : renderEmptyState\n ? renderEmptyState()\n : defaultRenderEmptyState()}\n </div>\n\n {/* Root Drop Area - sempre visível quando houver nodes e showRootDropArea for true */}\n {showRootDropArea && indexedNodes && indexedNodes.length > 0 && (\n <div\n {...context.handlers.rootDropProps}\n style={{ flex: 1, display: \"flex\" }}\n >\n {renderRootDropArea\n ? renderRootDropArea(dragOverId === \"root\")\n : defaultRenderRootDropArea(dragOverId === \"root\")}\n </div>\n )}\n </div>\n\n {showContextMenu && contextMenu && (\n <ContextMenu\n x={contextMenu.x}\n y={contextMenu.y}\n nodeId={contextMenu.nodeId}\n containerElementRef={contextMenu.containerElementRef}\n onClose={closeContextMenu}\n className={contextMenuClassName}\n onAction={onContextMenuAction}\n items={\n contextMenuItems\n ? typeof contextMenuItems === \"function\"\n ? contextMenuItems(contextMenu.nodeId)\n : contextMenuItems\n : undefined\n }\n useDefaultItems={!contextMenuItems}\n />\n )}\n </>\n );\n}\n","import {\n useNodeTreeState,\n Node,\n NodeRow,\n} from \"@darksnow-ui/node-tree-headless\";\nimport { ChevronRight, ChevronDown } from \"lucide-react\";\nimport { clsx } from \"clsx\";\nimport { NodeWrapper } from \"./NodeWrapper\";\n\ninterface EnhancedNodeRow extends NodeRow {\n node: Node;\n selected: boolean;\n expanded: boolean;\n visible: boolean;\n isCursor?: boolean;\n isFocus?: boolean;\n}\n\ninterface TreeNodeProps {\n row: EnhancedNodeRow;\n renderLabel?: (node: Node) => React.ReactNode;\n renderIcon?: (node: Node, isExpanded: boolean) => React.ReactNode;\n indentSize?: number;\n}\n\ninterface TreeNodeProps {\n row: EnhancedNodeRow;\n renderLabel?: (node: Node) => React.ReactNode;\n resolveIcon?: (node: Node, isExpanded: boolean) => string;\n indentSize?: number;\n}\n\nexport function TreeNode({\n row,\n renderLabel,\n resolveIcon,\n indentSize = 20,\n}: TreeNodeProps) {\n const { node } = row;\n const isExpanded = useNodeTreeState((s) => s.expandedNodes.has(node.id));\n const isSelected = useNodeTreeState((s) => s.selectedNodes.has(node.id));\n const isCursor = useNodeTreeState((s) => s.cursorId === node.id);\n const isFocus = useNodeTreeState((s) => s.focusId === node.id);\n const isDragOver = useNodeTreeState((s) => s.dragOverId === node.id);\n const isCut = useNodeTreeState(\n (s) => s.clipboardOperation === \"cut\" && s.clipboardNodeIds?.has(node.id),\n );\n\n // Default icon resolver\n const defaultIconResolver = (node: Node, isExpanded: boolean) => {\n if (!node.expandable) {\n const ext = node.label.split(\".\").pop()?.toLowerCase();\n switch (ext) {\n case \"ts\":\n return \"typescript\";\n case \"tsx\":\n return \"react_ts\";\n case \"js\":\n return \"javascript\";\n case \"jsx\":\n return \"react\";\n case \"json\":\n return \"json\";\n case \"md\":\n return \"markdown\";\n default:\n return \"file\";\n }\n }\n return isExpanded ? \"folder-open\" : \"folder\";\n };\n\n const iconName = resolveIcon\n ? resolveIcon(node, isExpanded)\n : defaultIconResolver(node, isExpanded);\n\n return (\n <NodeWrapper\n id={node.id}\n className={clsx(\n \"group flex items-center px-2 cursor-pointer relative\",\n \"hover:bg-vscode-list-hoverBackground\",\n isSelected && \"bg-vscode-list-activeSelectionBackground\",\n isCursor && \"outline outline-1 outline-vscode-focusBorder\",\n isDragOver && \"bg-vscode-list-dropBackground\",\n node.expandable && \"expandable\",\n )}\n >\n {/* Indent spacer */}\n <div style={{ width: `${row.level * indentSize}px` }} />\n\n {/* Expander */}\n <div className=\"flex items-center justify-center w-5 h-5\">\n {node.expandable ? (\n <span\n className={clsx(\n \"flex items-center justify-center w-full h-full\",\n \"hover:bg-vscode-border/50 rounded transition-colors\",\n )}\n aria-expanded={isExpanded}\n >\n {isExpanded ? (\n <ChevronDown className=\"w-3 h-3\" />\n ) : (\n <ChevronRight className=\"w-3 h-3\" />\n )}\n </span>\n ) : null}\n </div>\n\n {/* Icon usando classe CSS */}\n <div className={clsx(\"flex-shrink-0 mr-2\", isCut && \"opacity-50\")}>\n <i className={`icon icon-${iconName}`} />\n </div>\n\n {/* Label */}\n <span\n className={clsx(\n \"flex-1 text-sm truncate\",\n isSelected\n ? \"text-vscode-list-activeSelectionForeground\"\n : \"text-vscode-foreground\",\n isCut && \"opacity-50\",\n // isFocus && \"font-semibold\",\n )}\n aria-selected={isSelected}\n >\n {renderLabel ? renderLabel(node) : node.label}\n </span>\n </NodeWrapper>\n );\n}\n","import { useNodeTree, useNodeTreeState } from \"@darksnow-ui/node-tree-headless\";\nimport { memo, useMemo } from \"react\";\nimport { clsx } from \"clsx\";\n\ninterface NodeWrapperProps {\n id: string;\n children: React.ReactNode;\n className?: string;\n}\n\nexport const NodeWrapper = memo(\n ({ id, children, className }: NodeWrapperProps) => {\n const { handlers } = useNodeTree();\n\n // Get ALL necessary handlers from the system\n const wrapperProps = useMemo(\n () => handlers.wrapperProps(id),\n [handlers, id],\n );\n\n // Get visual states\n const isSelected = useNodeTreeState((s) => s.selectedNodes.has(id));\n const isFocused = useNodeTreeState((s) => s.focusId === id);\n const isCursor = useNodeTreeState((s) => s.cursorId === id);\n const isDragOver = useNodeTreeState((s) => s.dragOverId === id);\n const isDragging = useNodeTreeState((s) => s.dragStartId === id);\n\n return (\n <div\n {...wrapperProps}\n data-node-id={id}\n className={clsx(\n \"node-wrapper\",\n className,\n isSelected && \"selected\",\n isFocused && \"focused\",\n isCursor && \"cursor\",\n isDragOver && \"drag-over\",\n isDragging && \"dragging\",\n )}\n >\n {children}\n </div>\n );\n },\n);\n\nNodeWrapper.displayName = \"NodeWrapper\";\n","import React, { useRef, useEffect } from \"react\";\nimport { FloatingMenu } from \"@darksnow-ui/menus\";\nimport {\n useNodeTreeMenuItems,\n NodeMenuContext,\n} from \"../hooks/useNodeTreeMenuItems\";\nimport { MenuItemConfig as NewMenuItemConfig } from \"@darksnow-ui/menus\";\n\nexport interface ContextMenuProps {\n x: number;\n y: number;\n nodeId: string;\n containerElementRef?: React.RefObject<HTMLDivElement>;\n onClose: () => void;\n className?: string;\n onAction?: (action: string, nodeId: string) => void;\n items?: NewMenuItemConfig<NodeMenuContext>[];\n useDefaultItems?: boolean;\n}\n\n/**\n * Wrapper para o ContextMenu que integra com o node-tree\n */\nexport function ContextMenu({\n x,\n y,\n nodeId,\n containerElementRef,\n onClose,\n className,\n onAction,\n items,\n useDefaultItems = true,\n}: ContextMenuProps) {\n const elementRef = useRef<HTMLDivElement>(null);\n\n // Obter items do menu usando o hook\n const { items: defaultItems, context } = useNodeTreeMenuItems(nodeId, {\n onAction,\n });\n\n // Determinar items finais\n const finalItems =\n items && items.length > 0\n ? (items as NewMenuItemConfig<NodeMenuContext>[])\n : useDefaultItems\n ? defaultItems\n : [];\n\n // Gerenciar foco\n useEffect(() => {\n // Manter o foco no container após fechar\n return () => {\n containerElementRef?.current?.focus();\n };\n }, [containerElementRef]);\n\n // Se não há items, não renderizar\n if (finalItems.length === 0) {\n return null;\n }\n\n return (\n <FloatingMenu\n items={finalItems}\n context={context}\n open={true}\n onOpenChange={(open: boolean) => !open && onClose()}\n x={x}\n y={y}\n className={className}\n />\n );\n}\n","import { useMemo } from \"react\";\nimport {\n useNodeTree,\n useNodeTreeState,\n Node,\n} from \"@darksnow-ui/node-tree-headless\";\nimport { MenuItemConfig as NewMenuItemConfig } from \"@darksnow-ui/menus\";\nimport {\n FolderOpen,\n FolderClosed,\n FolderPlus,\n FilePlus,\n Copy,\n Scissors,\n Clipboard,\n Edit2,\n Trash2,\n} from \"lucide-react\";\n\nexport interface NodeMenuContext {\n nodeId: string;\n node: Node | null;\n isRoot: boolean;\n isExpanded: boolean;\n controller: any;\n services: any;\n}\n\ninterface UseNodeTreeMenuItemsOptions {\n onAction?: (action: string, nodeId: string) => void;\n customItems?:\n | NewMenuItemConfig<NodeMenuContext>[]\n | ((context: NodeMenuContext) => NewMenuItemConfig<NodeMenuContext>[]);\n}\n\n/**\n * Hook para converter os items do menu do node-tree para o formato do @darksnow-ui/menus\n */\nexport function useNodeTreeMenuItems(\n nodeId: string,\n options: UseNodeTreeMenuItemsOptions = {},\n) {\n const { services, controller } = useNodeTree();\n const nodes = useNodeTreeState((state) => state.nodes);\n const expandedNodes = useNodeTreeState((state) => state.expandedNodes);\n const clipboardNodeIds = useNodeTreeState((state) => state.clipboardNodeIds);\n\n const isRoot = nodeId === \"root\" || !nodeId;\n const node = isRoot ? null : nodes.get(nodeId) || null;\n const isExpanded = !isRoot && expandedNodes.has(nodeId);\n const hasClipboard = clipboardNodeIds && clipboardNodeIds.size > 0;\n\n const context: NodeMenuContext = {\n nodeId,\n node,\n isRoot,\n isExpanded,\n controller,\n services,\n };\n\n const defaultItems = useMemo((): NewMenuItemConfig<NodeMenuContext>[] => {\n if (isRoot) {\n // Menu para área vazia (root)\n const items: NewMenuItemConfig<NodeMenuContext>[] = [\n {\n type: \"item\",\n label: \"New Folder\",\n icon: <FolderPlus className=\"h-4 w-4\" />,\n handle: async (ctx) => {\n const name = prompt(\"New folder name:\");\n if (name) {\n await ctx.controller.createNode(undefined, name);\n options.onAction?.(\"create-folder\", ctx.nodeId);\n }\n },\n },\n {\n type: \"item\",\n label: \"New File\",\n icon: <FilePlus className=\"h-4 w-4\" />,\n handle: async (ctx) => {\n const name = prompt(\"New file name:\");\n if (name) {\n await ctx.controller.createNode(undefined, name);\n options.onAction?.(\"create-file\", ctx.nodeId);\n }\n },\n },\n ];\n\n if (hasClipboard) {\n items.push(\n { type: \"separator\" },\n {\n type: \"item\",\n label: \"Paste\",\n icon: <Clipboard className=\"h-4 w-4\" />,\n shortcut: \"Ctrl+V\",\n handle: async (ctx) => {\n await ctx.controller.pasteNodes(undefined);\n options.onAction?.(\"paste\", ctx.nodeId);\n },\n },\n );\n }\n\n return items;\n }\n\n // Menu para nodes\n const items: NewMenuItemConfig<NodeMenuContext>[] = [];\n\n // Expand/Collapse para pastas\n if (node?.expandable) {\n items.push({\n type: \"item\",\n label: isExpanded ? \"Collapse\" : \"Expand\",\n icon: isExpanded ? (\n <FolderClosed className=\"h-4 w-4\" />\n ) : (\n <FolderOpen className=\"h-4 w-4\" />\n ),\n handle: (ctx) => {\n if (ctx.isExpanded) {\n ctx.services.navigationService.collapseNode(ctx.nodeId);\n } else {\n ctx.services.navigationService.expandNode(ctx.nodeId);\n }\n options.onAction?.(\n ctx.isExpanded ? \"collapse\" : \"expand\",\n ctx.nodeId,\n );\n },\n });\n items.push({ type: \"separator\" });\n }\n\n // New Folder/File para pastas\n if (node?.expandable) {\n items.push(\n {\n type: \"item\",\n label: \"New Folder\",\n icon: <FolderPlus className=\"h-4 w-4\" />,\n handle: async (ctx) => {\n const name = prompt(\"New folder name:\");\n if (name) {\n await ctx.controller.createNode(ctx.nodeId, name);\n options.onAction?.(\"create-folder\", ctx.nodeId);\n }\n },\n },\n {\n type: \"item\",\n label: \"New File\",\n icon: <FilePlus className=\"h-4 w-4\" />,\n handle: async (ctx) => {\n const name = prompt(\"New file name:\");\n if (name) {\n await ctx.controller.createNode(ctx.nodeId, name);\n options.onAction?.(\"create-file\", ctx.nodeId);\n }\n },\n },\n { type: \"separator\" },\n );\n }\n\n // Copy/Cut\n items.push(\n {\n type: \"item\",\n label: \"Copy\",\n icon: <Copy className=\"h-4 w-4\" />,\n shortcut: \"Ctrl+C\",\n handle: (ctx) => {\n ctx.controller.copyNodes([ctx.nodeId]);\n options.onAction?.(\"copy\", ctx.nodeId);\n },\n },\n {\n type: \"item\",\n label: \"Cut\",\n icon: <Scissors className=\"h-4 w-4\" />,\n shortcut: \"Ctrl+X\",\n handle: (ctx) => {\n ctx.controller.cutNodes([ctx.nodeId]);\n options.onAction?.(\"cut\", ctx.nodeId);\n },\n },\n );\n\n // Paste para pastas\n if (node?.expandable && hasClipboard) {\n items.push({\n type: \"item\",\n label: \"Paste\",\n icon: <Clipboard className=\"h-4 w-4\" />,\n shortcut: \"Ctrl+V\",\n handle: async (ctx) => {\n await ctx.controller.pasteNodes(ctx.nodeId);\n options.onAction?.(\"paste\", ctx.nodeId);\n },\n });\n }\n\n // Rename/Delete\n items.push(\n { type: \"separator\" },\n {\n type: \"item\",\n label: \"Rename\",\n icon: <Edit2 className=\"h-4 w-4\" />,\n shortcut: \"F2\",\n handle: async (ctx) => {\n await ctx.controller.renameNode(ctx.nodeId);\n options.onAction?.(\"rename\", ctx.nodeId);\n },\n },\n {\n type: \"item\",\n label: \"Delete\",\n icon: <Trash2 className=\"h-4 w-4\" />,\n className: \"text-destructive\",\n shortcut: \"Delete\",\n handle: async (ctx) => {\n await ctx.controller.deleteNodes([ctx.nodeId]);\n options.onAction?.(\"delete\", ctx.nodeId);\n },\n },\n );\n\n return items;\n }, [isRoot, node, isExpanded, hasClipboard, options.onAction]);\n\n // Mesclar com items customizados se fornecidos\n const finalItems = useMemo(() => {\n if (!options.customItems) {\n return defaultItems;\n }\n\n const customItems =\n typeof options.customItems === \"function\"\n ? options.customItems(context)\n : options.customItems;\n\n return [...defaultItems, ...customItems];\n }, [defaultItems, options.customItems, context]);\n\n return {\n items: finalItems,\n context,\n };\n}\n"],"mappings":"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","names":["useNodeTree","useNodeTreeState","useNodeTreeState","clsx","jsx","useNodeTreeState","node","isExpanded","clsx","useMemo","useNodeTree","useNodeTreeState","jsx","items","jsx","clsx","jsx","jsxs","useNodeTree","useNodeTreeState"]}