feat(web): make object tree collapsible and collapsed by default

This commit is contained in:
2026-08-08 12:27:23 +08:00
parent f126bf7993
commit 3b66e82b67
+27 -5
View File
@@ -1,3 +1,4 @@
import { useState } from 'react';
import type { ObjectTreeNode } from '@tts/extract'; import type { ObjectTreeNode } from '@tts/extract';
interface Props { interface Props {
@@ -38,23 +39,44 @@ function TreeNode({
onSelect: (guid: string) => void; onSelect: (guid: string) => void;
}) { }) {
const selected = node.object.GUID === selectedGuid; const selected = node.object.GUID === selectedGuid;
const hasChildren = node.children.length > 0;
const [expanded, setExpanded] = useState(false);
return ( return (
<li> <li>
<button <div
onClick={() => onSelect(node.object.GUID)} className={`flex items-center rounded pr-2 ${
style={{ paddingLeft: `${depth * 16 + 8}px` }}
className={`block w-full truncate rounded px-2 py-1 text-left text-sm ${
selected selected
? 'bg-zinc-700 text-zinc-100' ? 'bg-zinc-700 text-zinc-100'
: 'text-zinc-300 hover:bg-zinc-800 hover:text-zinc-100' : 'text-zinc-300 hover:bg-zinc-800 hover:text-zinc-100'
}`} }`}
style={{ paddingLeft: `${depth * 16 + 4}px` }}
>
{hasChildren ? (
<button
onClick={() => setExpanded((e) => !e)}
aria-label={expanded ? 'Collapse' : 'Expand'}
className="flex h-6 w-6 shrink-0 items-center justify-center rounded text-zinc-500 hover:text-zinc-200"
>
<span
className={`inline-block text-xs transition-transform ${expanded ? 'rotate-90' : ''}`}
>
</span>
</button>
) : (
<span className="h-6 w-6 shrink-0" />
)}
<button
onClick={() => onSelect(node.object.GUID)}
className="block min-w-0 flex-1 truncate py-1 text-left text-sm"
> >
<span className="mr-1.5 rounded bg-zinc-800 px-1 py-0.5 text-xs uppercase text-zinc-500"> <span className="mr-1.5 rounded bg-zinc-800 px-1 py-0.5 text-xs uppercase text-zinc-500">
{node.object.Name} {node.object.Name}
</span> </span>
<span className="truncate">{node.label}</span> <span className="truncate">{node.label}</span>
</button> </button>
{node.children.length > 0 && ( </div>
{hasChildren && expanded && (
<ul> <ul>
{node.children.map((child, index) => ( {node.children.map((child, index) => (
<TreeNode <TreeNode