Add component tree expansion hook

This commit is contained in:
2026-01-18 01:22:18 +00:00
parent a249435105
commit 104f9461bc
2 changed files with 61 additions and 37 deletions

View File

@@ -1,9 +1,9 @@
import { useState, useCallback } from 'react'
import { UIComponent } from '@/types/json-ui'
import { ScrollArea } from '@/components/ui/scroll-area'
import { ComponentTreeHeader } from '@/components/molecules/component-tree/ComponentTreeHeader'
import { ComponentTreeEmptyState } from '@/components/molecules/component-tree/ComponentTreeEmptyState'
import { ComponentTreeNodes } from '@/components/molecules/component-tree/ComponentTreeNodes'
import { useComponentTreeExpansion } from '@/hooks/use-component-tree-expansion'
interface ComponentTreeProps {
components: UIComponent[]
@@ -34,42 +34,8 @@ export function ComponentTree({
onDragLeave,
onDrop,
}: ComponentTreeProps) {
const [expandedIds, setExpandedIds] = useState<Set<string>>(new Set())
const getAllComponentIds = useCallback((comps: UIComponent[]): string[] => {
const ids: string[] = []
const traverse = (nodes: UIComponent[]) => {
nodes.forEach((comp) => {
if (Array.isArray(comp.children) && comp.children.length > 0) {
ids.push(comp.id)
traverse(comp.children)
}
})
}
traverse(comps)
return ids
}, [])
const handleExpandAll = useCallback(() => {
const allIds = getAllComponentIds(components)
setExpandedIds(new Set(allIds))
}, [components, getAllComponentIds])
const handleCollapseAll = useCallback(() => {
setExpandedIds(new Set())
}, [])
const toggleExpand = useCallback((id: string) => {
setExpandedIds((prev) => {
const next = new Set(prev)
if (next.has(id)) {
next.delete(id)
} else {
next.add(id)
}
return next
})
}, [])
const { expandedIds, handleExpandAll, handleCollapseAll, toggleExpand } =
useComponentTreeExpansion(components)
return (
<div className="h-full flex flex-col">

View File

@@ -0,0 +1,58 @@
import { useCallback, useMemo, useState } from 'react'
import { UIComponent } from '@/types/json-ui'
interface ComponentTreeExpansionState {
expandedIds: Set<string>
handleExpandAll: () => void
handleCollapseAll: () => void
toggleExpand: (id: string) => void
}
const getExpandableIds = (components: UIComponent[]): string[] => {
const ids: string[] = []
const traverse = (nodes: UIComponent[]) => {
nodes.forEach((component) => {
if (Array.isArray(component.children) && component.children.length > 0) {
ids.push(component.id)
traverse(component.children)
}
})
}
traverse(components)
return ids
}
export function useComponentTreeExpansion(
components: UIComponent[],
): ComponentTreeExpansionState {
const [expandedIds, setExpandedIds] = useState<Set<string>>(new Set())
const expandableIds = useMemo(() => getExpandableIds(components), [components])
const handleExpandAll = useCallback(() => {
setExpandedIds(new Set(expandableIds))
}, [expandableIds])
const handleCollapseAll = useCallback(() => {
setExpandedIds(new Set())
}, [])
const toggleExpand = useCallback((id: string) => {
setExpandedIds((prev) => {
const next = new Set(prev)
if (next.has(id)) {
next.delete(id)
} else {
next.add(id)
}
return next
})
}, [])
return {
expandedIds,
handleExpandAll,
handleCollapseAll,
toggleExpand,
}
}