4-26 树rust-2

This commit is contained in:
lix-2026
2026-04-26 04:29:23 +08:00
parent 94631f3636
commit 338bb2e20f
58 changed files with 11718 additions and 1256 deletions
@@ -1,9 +1,14 @@
"use client";
import type { DragEvent, MouseEvent } from "react";
import { FileTree } from "@/components/sidebar/file-tree";
import { PrivateTree } from "@/components/sidebar/private-tree";
import { TreeShellHost, type TreeRendererFamily } from "@/components/sidebar/tree-shell-host";
import {
TreeShellHost,
type FileTreeShellExternalDropPayload,
type FileTreeShellInternalDropPayload,
type TreeShellPickerCommand,
type TreeRendererFamily,
} from "@/components/sidebar/tree-shell-host";
import type { KernelFileTreeProjectionItem } from "@/lib/kernel-file-tree";
import type { SidebarTreeNode } from "@/lib/kernel-sidebar";
import type { FileTreeRow } from "@/lib/file-tree/types";
import type { PageTreeProjectionItem } from "@/lib/tree-projection";
@@ -16,9 +21,11 @@ type SidebarPageTreeSurfaceProps = {
rendererFamily?: TreeRendererFamily;
workspaceId: string | null;
treeShellEnabled?: boolean;
rows: PageTreeProjectionItem[];
rows?: PageTreeProjectionItem[];
treeShellRows?: PageTreeProjectionItem[];
expanded: Set<string>;
activeId: string;
focusedDocumentId?: string | null;
className?: string;
onToggleExpand: (id: string) => void;
onMove: (nodeId: string, parentId: string | null, index: number) => void;
@@ -26,6 +33,8 @@ type SidebarPageTreeSurfaceProps = {
onContextMenu: (event: MouseEvent, node: SidebarTreeNode) => void;
onNavigate?: (documentId: string) => void;
onPageContextMenu?: (payload: { documentId: string; x: number; y: number }) => void;
onPageExpandChange?: (payload: { documentId: string | null; expanded: boolean }) => void;
onPageFocusChange?: (payload: { documentId: string | null }) => void;
onTreeMutation?: (payload: { type: string; documentId: string | null }) => void;
};
@@ -34,7 +43,8 @@ type SidebarFileTreeSurfaceProps = {
rendererFamily?: TreeRendererFamily;
workspaceId: string | null;
treeShellEnabled?: boolean;
rows: FileTreeRow[];
rows?: FileTreeRow[];
treeShellItems?: KernelFileTreeProjectionItem[];
activeId: string;
selectedRowIds: Set<string>;
className?: string;
@@ -46,8 +56,8 @@ type SidebarFileTreeSurfaceProps = {
onToggleAssetFolderExpand?: (assetId: string) => void;
onCreateChild: (parentId: string | null) => void;
onBlankMouseDown?: (event: MouseEvent) => void;
onDropFiles?: (docId: string, files: FileList | File[], targetRow?: FileTreeRow) => void;
onInternalDrop?: (args: { targetRow: FileTreeRow; rowIds: string[]; copy: boolean }) => void;
onDropFiles?: (payload: FileTreeShellExternalDropPayload) => void;
onInternalDrop?: (payload: FileTreeShellInternalDropPayload) => void;
onNavigate?: (documentId: string) => void;
onFileTreeContextMenu?: (payload: {
documentId: string | null;
@@ -79,8 +89,10 @@ type TreePickerSurfaceProps = {
workspaceId: string | null;
treeShellEnabled?: boolean;
activeDocumentId?: string | null;
activePickerItemKey?: string | null;
allowRootPick?: boolean;
excludeIds?: string[];
pickerCommand?: TreeShellPickerCommand | null;
treeShellItems?: TreePickerSurfaceItem[];
items: TreePickerSurfaceItem[];
highlighted: number;
@@ -88,6 +100,7 @@ type TreePickerSurfaceProps = {
emptyText?: string;
onHighlight: (index: number) => void;
onPick: (targetId: string | null) => void;
onPickerFocusChange?: (payload: { itemKey: string | null; documentId: string | null }) => void;
};
export function SidebarTreeSurface(props: SidebarTreeSurfaceProps) {
@@ -96,33 +109,27 @@ export function SidebarTreeSurface(props: SidebarTreeSurfaceProps) {
? "sidebar-page-tree-shell"
: "sidebar-file-tree-shell";
const rendererFamily = props.rendererFamily ?? "react";
const pageTreeFallback = (
<div
data-testid="page-tree-renderer-removed"
className="flex h-full items-center justify-center px-4 text-center text-sm text-gray-400"
>
React renderer 退使 Rust tree shell 宿
</div>
);
const fileTreeFallback = (
<div
data-testid="file-tree-renderer-removed"
className="flex h-full items-center justify-center px-4 text-center text-sm text-gray-400"
>
React renderer 退使 Rust tree shell 宿
</div>
);
const fallbackContent =
props.mode === "page" ? (
<PrivateTree
rows={props.rows}
expanded={props.expanded}
activeId={props.activeId}
onToggleExpand={props.onToggleExpand}
onMove={props.onMove}
onCreateChild={props.onCreateChild}
onContextMenu={props.onContextMenu}
/>
pageTreeFallback
) : (
<FileTree
rows={props.rows}
activeId={props.activeId}
selectedRowIds={props.selectedRowIds}
onRowClick={props.onRowClick}
onRowDoubleClick={props.onRowDoubleClick}
onRowContextMenu={props.onRowContextMenu}
onRowDragStart={props.onRowDragStart}
onToggleExpand={props.onToggleExpand}
onToggleAssetFolderExpand={props.onToggleAssetFolderExpand}
onCreateChild={props.onCreateChild}
onBlankMouseDown={props.onBlankMouseDown}
onDropFiles={props.onDropFiles}
onInternalDrop={props.onInternalDrop}
/>
fileTreeFallback
);
return (
@@ -131,11 +138,20 @@ export function SidebarTreeSurface(props: SidebarTreeSurfaceProps) {
surfaceTestId={surfaceTestId}
rendererFamily={rendererFamily}
treeShellEnabled={props.treeShellEnabled}
fallbackImplementation={
props.mode === "page"
? "page_tree_renderer_removed"
: "filetree_renderer_removed"
}
workspaceId={props.workspaceId}
activeDocumentId={props.activeId}
fileTreeRows={props.mode === "filetree" ? props.rows : undefined}
focusedDocumentId={props.mode === "page" ? (props.focusedDocumentId ?? null) : undefined}
pageTreeItems={props.mode === "page" ? props.treeShellRows : undefined}
inlineFileTreeItems={props.mode === "filetree" ? props.treeShellItems : undefined}
onNavigate={props.onNavigate}
onPageContextMenu={props.mode === "page" ? props.onPageContextMenu : undefined}
onPageExpandChange={props.mode === "page" ? props.onPageExpandChange : undefined}
onPageFocusChange={props.mode === "page" ? props.onPageFocusChange : undefined}
onFileTreeContextMenu={props.mode === "filetree" ? props.onFileTreeContextMenu : undefined}
onFileTreeSelectionChange={props.mode === "filetree" ? props.onFileTreeSelectionChange : undefined}
onInternalDrop={props.mode === "filetree" ? props.onInternalDrop : undefined}
@@ -157,8 +173,10 @@ export function TreePickerSurface({
workspaceId,
treeShellEnabled = true,
activeDocumentId = null,
activePickerItemKey = null,
allowRootPick = false,
excludeIds = [],
pickerCommand = null,
treeShellItems,
items,
highlighted,
@@ -166,8 +184,11 @@ export function TreePickerSurface({
emptyText = "没有匹配结果",
onHighlight,
onPick,
onPickerFocusChange,
}: TreePickerSurfaceProps) {
const hasItems = items.length > 0;
const effectiveTreeShellItems =
rendererFamily === "rust_family" ? (treeShellItems ?? items) : treeShellItems;
return (
<TreeShellHost
@@ -177,10 +198,13 @@ export function TreePickerSurface({
treeShellEnabled={treeShellEnabled}
workspaceId={workspaceId}
activeDocumentId={activeDocumentId}
activePickerItemKey={activePickerItemKey}
allowRootPick={allowRootPick}
excludeIds={excludeIds}
pickerItems={treeShellItems}
pickerCommand={pickerCommand}
pickerItems={effectiveTreeShellItems}
onPick={onPick}
onPickerFocusChange={onPickerFocusChange}
className={cn(hasItems ? "py-2" : null, className)}
>
{!hasItems ? (