mirror of
https://github.com/johndoe6345789/low-code-react-app-b.git
synced 2026-04-24 13:44:54 +00:00
Generated by Spark: Expand All, Collapse All buttons are too big, Maybe just use icon buttons?
This commit is contained in:
@@ -17,6 +17,9 @@ interface ComponentTreeNodeProps {
|
||||
onDragLeave: (e: React.DragEvent) => void
|
||||
onDrop: (e: React.DragEvent) => void
|
||||
depth?: number
|
||||
hasChildren?: boolean
|
||||
isExpanded?: boolean
|
||||
onToggleExpand?: () => void
|
||||
}
|
||||
|
||||
export function ComponentTreeNode({
|
||||
@@ -33,10 +36,12 @@ export function ComponentTreeNode({
|
||||
onDragLeave,
|
||||
onDrop,
|
||||
depth = 0,
|
||||
hasChildren = false,
|
||||
isExpanded = false,
|
||||
onToggleExpand,
|
||||
}: ComponentTreeNodeProps) {
|
||||
const def = getComponentDef(component.type)
|
||||
const IconComponent = def ? (Icons as any)[def.icon] || Icons.Cube : Icons.Cube
|
||||
const hasChildren = Array.isArray(component.children) && component.children.length > 0
|
||||
|
||||
return (
|
||||
<div className="relative">
|
||||
@@ -67,7 +72,19 @@ export function ComponentTreeNode({
|
||||
)}
|
||||
>
|
||||
{hasChildren ? (
|
||||
<Icons.CaretDown className="w-3 h-3 text-muted-foreground" />
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
onToggleExpand?.()
|
||||
}}
|
||||
className="hover:text-accent"
|
||||
>
|
||||
{isExpanded ? (
|
||||
<Icons.CaretDown className="w-3 h-3 text-muted-foreground" />
|
||||
) : (
|
||||
<Icons.CaretRight className="w-3 h-3 text-muted-foreground" />
|
||||
)}
|
||||
</button>
|
||||
) : (
|
||||
<div className="w-3" />
|
||||
)}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { useState, useCallback } from 'react'
|
||||
import { UIComponent } from '@/types/json-ui'
|
||||
import { ComponentTreeNode } from '@/components/atoms/ComponentTreeNode'
|
||||
import { PanelHeader } from '@/components/atoms'
|
||||
import { ScrollArea } from '@/components/ui/scroll-area'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Tree, Plus } from '@phosphor-icons/react'
|
||||
import { Tree, CaretDown, CaretRight } from '@phosphor-icons/react'
|
||||
|
||||
interface ComponentTreeProps {
|
||||
components: UIComponent[]
|
||||
@@ -34,39 +35,108 @@ 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 = (components: UIComponent[]) => {
|
||||
components.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 renderTree = (comps: UIComponent[], depth = 0) => {
|
||||
return comps.map((comp) => (
|
||||
<div key={comp.id}>
|
||||
<ComponentTreeNode
|
||||
component={comp}
|
||||
isSelected={selectedId === comp.id}
|
||||
isHovered={hoveredId === comp.id}
|
||||
isDraggedOver={draggedOverId === comp.id}
|
||||
dropPosition={draggedOverId === comp.id ? dropPosition : null}
|
||||
onSelect={() => onSelect(comp.id)}
|
||||
onHover={() => onHover(comp.id)}
|
||||
onHoverEnd={onHoverEnd}
|
||||
onDragStart={(e) => onDragStart(comp.id, e)}
|
||||
onDragOver={(e) => onDragOver(comp.id, e)}
|
||||
onDragLeave={onDragLeave}
|
||||
onDrop={(e) => onDrop(comp.id, e)}
|
||||
depth={depth}
|
||||
/>
|
||||
{Array.isArray(comp.children) && comp.children.length > 0 && (
|
||||
<div>{renderTree(comp.children, depth + 1)}</div>
|
||||
)}
|
||||
</div>
|
||||
))
|
||||
return comps.map((comp) => {
|
||||
const hasChildren = Array.isArray(comp.children) && comp.children.length > 0
|
||||
const isExpanded = expandedIds.has(comp.id)
|
||||
|
||||
return (
|
||||
<div key={comp.id}>
|
||||
<ComponentTreeNode
|
||||
component={comp}
|
||||
isSelected={selectedId === comp.id}
|
||||
isHovered={hoveredId === comp.id}
|
||||
isDraggedOver={draggedOverId === comp.id}
|
||||
dropPosition={draggedOverId === comp.id ? dropPosition : null}
|
||||
onSelect={() => onSelect(comp.id)}
|
||||
onHover={() => onHover(comp.id)}
|
||||
onHoverEnd={onHoverEnd}
|
||||
onDragStart={(e) => onDragStart(comp.id, e)}
|
||||
onDragOver={(e) => onDragOver(comp.id, e)}
|
||||
onDragLeave={onDragLeave}
|
||||
onDrop={(e) => onDrop(comp.id, e)}
|
||||
depth={depth}
|
||||
hasChildren={hasChildren}
|
||||
isExpanded={isExpanded}
|
||||
onToggleExpand={() => toggleExpand(comp.id)}
|
||||
/>
|
||||
{hasChildren && isExpanded && comp.children && (
|
||||
<div>{renderTree(comp.children, depth + 1)}</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="h-full flex flex-col">
|
||||
<div className="p-4">
|
||||
<PanelHeader
|
||||
title="Component Tree"
|
||||
subtitle={`${components.length} component${components.length !== 1 ? 's' : ''}`}
|
||||
icon={<Tree size={20} weight="duotone" />}
|
||||
/>
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<PanelHeader
|
||||
title="Component Tree"
|
||||
subtitle={`${components.length} component${components.length !== 1 ? 's' : ''}`}
|
||||
icon={<Tree size={20} weight="duotone" />}
|
||||
/>
|
||||
{components.length > 0 && (
|
||||
<div className="flex gap-1">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={handleExpandAll}
|
||||
className="h-7 w-7 p-0"
|
||||
title="Expand All"
|
||||
>
|
||||
<CaretDown size={16} />
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={handleCollapseAll}
|
||||
className="h-7 w-7 p-0"
|
||||
title="Collapse All"
|
||||
>
|
||||
<CaretRight size={16} />
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ScrollArea className="flex-1">
|
||||
|
||||
Reference in New Issue
Block a user