@tutti-os/workspace-file-reference 0.0.12 → 0.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-7C3RZYQE.js +286 -0
- package/dist/chunk-7C3RZYQE.js.map +1 -0
- package/dist/{chunk-LS7P3J6Z.js → chunk-CD3YNHYJ.js} +433 -3
- package/dist/chunk-CD3YNHYJ.js.map +1 -0
- package/dist/contracts/index.d.ts +124 -1
- package/dist/core/index.d.ts +97 -2
- package/dist/core/index.js +31 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +31 -1
- package/dist/react/index.d.ts +75 -2
- package/dist/react/index.js +6 -2
- package/dist/referenceSourceAggregator-yyyLVOPi.d.ts +42 -0
- package/dist/ui/index.d.ts +13 -1
- package/dist/ui/index.js +981 -7
- package/dist/ui/index.js.map +1 -1
- package/package.json +5 -4
- package/dist/chunk-LS7P3J6Z.js.map +0 -1
- package/dist/chunk-PAR2R2G5.js +0 -23
- package/dist/chunk-PAR2R2G5.js.map +0 -1
package/dist/ui/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ui/internal/reference/WorkspaceFileReferencePicker.tsx","../../src/ui/internal/reference/WorkspaceFileReferencePickerSections.tsx","../../src/ui/internal/reference/WorkspaceFileReferencePickerTree.tsx"],"sourcesContent":["import { useId } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport {\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n CloseIcon,\n cn\n} from \"@tutti-os/ui-system\";\nimport type {\n WorkspaceFileReferenceAdapter,\n WorkspaceFileReference,\n WorkspaceFileReferenceCopy\n} from \"../../../contracts/index.ts\";\nimport { useWorkspaceFileReferencePickerView } from \"../../../react/index.ts\";\nimport {\n WorkspaceFileReferencePickerFooter,\n WorkspaceFileReferencePickerPreviewPane\n} from \"./WorkspaceFileReferencePickerSections.tsx\";\nimport { WorkspaceFileReferencePickerBrowserPane } from \"./WorkspaceFileReferencePickerTree.tsx\";\n\nexport interface WorkspaceFileReferencePickerProps {\n copy: WorkspaceFileReferenceCopy;\n fileAdapter?: WorkspaceFileReferenceAdapter;\n initialPath?: string | null;\n onClose: () => void;\n onConfirm: (refs: WorkspaceFileReference[]) => void;\n open: boolean;\n workspaceId: string;\n}\n\nconst workspaceFileReferencePickerBackdropMotionClassName =\n \"motion-safe:animate-in motion-safe:fade-in-0 motion-safe:duration-[180ms] motion-safe:ease-[cubic-bezier(0.22,1,0.36,1)] motion-reduce:animate-none\";\n\nconst workspaceFileReferencePickerPanelMotionClassName =\n \"motion-safe:animate-in motion-safe:fade-in-0 motion-safe:zoom-in-[0.96] motion-safe:duration-[250ms] motion-safe:ease-[cubic-bezier(0.22,1,0.36,1)] motion-reduce:animate-none\";\n\nexport function WorkspaceFileReferencePicker({\n copy,\n fileAdapter,\n initialPath,\n onClose,\n onConfirm,\n open,\n workspaceId\n}: WorkspaceFileReferencePickerProps) {\n const titleId = useId();\n const {\n browseRootEntries,\n directoryStateByPath,\n expandedFolderPaths,\n focusedEntry,\n focusedPath,\n isLoading,\n mode,\n previewState,\n searchQuery,\n selectedRefs,\n visibleEntries,\n setFocusedPath,\n setSearchQuery,\n toggleFolder,\n toggleRef\n } = useWorkspaceFileReferencePickerView({\n fileAdapter,\n initialPath,\n onClose,\n onConfirm,\n open,\n workspaceId\n });\n\n if (!open) {\n return null;\n }\n\n const dialog = (\n <div\n className={cn(\n \"nodrag fixed inset-0 grid place-items-center bg-[var(--backdrop)] px-3 py-4 backdrop-blur-md [-webkit-app-region:no-drag] sm:px-6 sm:py-8\",\n workspaceFileReferencePickerBackdropMotionClassName\n )}\n style={{ zIndex: \"var(--z-panel)\" }}\n onClick={onClose}\n >\n <Card\n aria-labelledby={titleId}\n aria-modal=\"true\"\n className={cn(\n \"nodrag flex h-[min(88vh,44rem)] w-full max-w-5xl origin-center flex-col gap-0 overflow-hidden border-[var(--line-1)] bg-[var(--background-fronted)] py-0 text-[var(--text-primary)] shadow-panel [-webkit-app-region:no-drag] sm:h-[min(82vh,44rem)]\",\n workspaceFileReferencePickerPanelMotionClassName\n )}\n role=\"dialog\"\n onClick={(event) => event.stopPropagation()}\n >\n <CardHeader\n className=\"border-b px-4 py-4 sm:px-6 sm:py-5\"\n style={{ borderBottomColor: \"var(--line-1)\" }}\n >\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0\">\n <CardTitle id={titleId}>\n {copy.t(\"referencePicker.title\")}\n </CardTitle>\n </div>\n <Button\n aria-label={copy.t(\"actions.cancel\")}\n size=\"icon-sm\"\n type=\"button\"\n variant=\"ghost\"\n onClick={onClose}\n >\n <CloseIcon size={16} />\n </Button>\n </div>\n </CardHeader>\n <CardContent className=\"grid min-h-0 flex-1 grid-rows-[minmax(0,1fr)_auto] gap-0 overflow-hidden p-0 lg:grid-cols-[minmax(0,1.15fr)_minmax(20rem,0.85fr)] lg:grid-rows-1\">\n <WorkspaceFileReferencePickerBrowserPane\n browseRootEntries={browseRootEntries}\n copy={copy}\n directoryStateByPath={directoryStateByPath}\n expandedFolderPaths={expandedFolderPaths}\n focusedPath={focusedPath}\n isLoading={isLoading}\n mode={mode}\n searchQuery={searchQuery}\n selectedRefs={selectedRefs}\n setSearchQuery={setSearchQuery}\n visibleEntries={visibleEntries}\n onFocusPath={setFocusedPath}\n onToggleFolder={toggleFolder}\n onToggleRef={toggleRef}\n />\n <WorkspaceFileReferencePickerPreviewPane\n copy={copy}\n focusedEntry={focusedEntry}\n mode={mode}\n previewState={previewState}\n />\n </CardContent>\n <WorkspaceFileReferencePickerFooter\n copy={copy}\n onClose={onClose}\n onConfirm={() => onConfirm(selectedRefs)}\n selectedRefs={selectedRefs}\n />\n </Card>\n </div>\n );\n\n if (typeof document === \"undefined\") {\n return dialog;\n }\n return createPortal(dialog, document.body);\n}\n","import type { JSX, ReactNode } from \"react\";\nimport {\n Badge,\n Button,\n FileIcon,\n FolderFilledIcon,\n LoadingIcon\n} from \"@tutti-os/ui-system\";\nimport { formatWorkspacePreviewByteLimit } from \"@tutti-os/workspace-file-preview\";\nimport { WorkspaceFilePreviewSurface as SharedWorkspaceFilePreviewSurface } from \"@tutti-os/workspace-file-preview/react\";\nimport type {\n WorkspaceFileReference,\n WorkspaceFileReferenceCopy\n} from \"../../../contracts/index.ts\";\nimport type { WorkspaceFileReferencePreviewState } from \"../../../react/internal/reference/useWorkspaceFileReferencePickerView.ts\";\nimport { resolveWorkspaceFileReferenceLabel } from \"./WorkspaceFileReferencePickerTree.tsx\";\n\nconst workspaceFileReferencePickerSelectedBadgeClassName =\n \"max-w-[14rem] rounded-[4px] border-transparent bg-[var(--transparency-block)] text-[var(--text-primary)]\";\n\nexport function WorkspaceFileReferencePickerPreviewPane({\n copy,\n focusedEntry,\n mode,\n previewState\n}: {\n copy: WorkspaceFileReferenceCopy;\n focusedEntry: WorkspaceFileReference | null;\n mode: \"browse\" | \"search\";\n previewState: WorkspaceFileReferencePreviewState;\n}): JSX.Element {\n return (\n <aside className=\"flex shrink-0 flex-col border-t border-[var(--line-1)] bg-[var(--background-fronted)] lg:min-h-0 lg:flex-1 lg:border-t-0\">\n <div className=\"flex min-h-0 flex-1 flex-col p-2\">\n {focusedEntry ? (\n <div className=\"flex min-h-0 flex-col gap-4 lg:flex-1 lg:gap-5\">\n <WorkspaceFileReferencePreviewSurface\n copy={copy}\n focusedEntry={focusedEntry}\n previewState={previewState}\n />\n <div className=\"space-y-2 px-2 lg:space-y-3\">\n <div className=\"space-y-1.5\">\n <p className=\"truncate text-[15px] font-semibold text-[var(--text-primary)]\">\n {resolveWorkspaceFileReferenceLabel(focusedEntry)}\n </p>\n <p className=\"line-clamp-3 text-[13px] text-[var(--text-secondary)] [overflow-wrap:anywhere]\">\n {focusedEntry.path}\n </p>\n </div>\n </div>\n </div>\n ) : (\n <WorkspaceFileReferencePickerFeedback>\n {mode === \"search\"\n ? copy.t(\"referencePicker.emptySearch\")\n : copy.t(\"referencePicker.emptyDirectory\")}\n </WorkspaceFileReferencePickerFeedback>\n )}\n </div>\n </aside>\n );\n}\n\nfunction WorkspaceFileReferencePreviewSurface({\n copy,\n focusedEntry,\n previewState\n}: {\n copy: WorkspaceFileReferenceCopy;\n focusedEntry: WorkspaceFileReference;\n previewState: WorkspaceFileReferencePreviewState;\n}): JSX.Element {\n return (\n <SharedWorkspaceFilePreviewSurface\n directoryMessage={copy.t(\"referencePicker.previewFolder\")}\n emptyMessage={copy.t(\"referencePicker.previewUnavailable\")}\n frameClassName=\"flex aspect-[3/2] w-full flex-col items-center justify-center overflow-hidden rounded-[8px] border border-[var(--line-2,var(--border-2))] bg-[var(--transparency-block)] p-0 text-center\"\n imageAlt={resolveWorkspaceFileReferenceLabel}\n imageFrameClassName=\"p-3\"\n loadingIndicator={\n <span className=\"mx-auto grid size-11 place-items-center rounded-[6px] bg-[var(--transparency-block)]\">\n <LoadingIcon className=\"size-4 animate-spin\" />\n </span>\n }\n loadingMessage={copy.t(\"referencePicker.previewLoading\")}\n messageClassName=\"mx-auto max-w-[24ch] text-[13px] leading-5 text-[var(--text-secondary)] [overflow-wrap:anywhere]\"\n renderIcon={(entry) =>\n entry.kind === \"folder\" ? (\n <FolderFilledIcon className=\"mx-auto size-9 text-[var(--rich-text-folder)]\" />\n ) : (\n <FileIcon className=\"mx-auto size-9 text-[var(--text-tertiary)]\" />\n )\n }\n state={resolveWorkspaceFileReferenceSurfaceState(\n copy,\n focusedEntry,\n previewState\n )}\n textClassName=\"h-full overflow-auto p-3 text-left text-[11px] leading-5 whitespace-pre-wrap break-words text-[var(--text-primary)]\"\n textFrameClassName=\"items-stretch justify-stretch\"\n />\n );\n}\n\nfunction resolveWorkspaceFileReferenceSurfaceState(\n copy: WorkspaceFileReferenceCopy,\n focusedEntry: WorkspaceFileReference,\n previewState: WorkspaceFileReferencePreviewState\n) {\n if (focusedEntry.kind === \"folder\") {\n return {\n entry: focusedEntry,\n status: \"directory\" as const\n };\n }\n\n if (\n !(\"reference\" in previewState) ||\n previewState.reference.path !== focusedEntry.path\n ) {\n return {\n entry: focusedEntry,\n message: focusedEntry.path,\n status: \"unsupported\" as const\n };\n }\n\n switch (previewState.status) {\n case \"loading\":\n case \"image\":\n case \"text\":\n return {\n ...previewState,\n entry: focusedEntry\n };\n case \"readonly\":\n return {\n entry: focusedEntry,\n message: resolveWorkspaceFileReferencePreviewReadonlyMessage(\n copy,\n previewState\n ),\n status: \"readonly\" as const\n };\n case \"error\":\n return {\n entry: focusedEntry,\n message: copy.t(\"referencePicker.previewError\"),\n status: \"error\" as const\n };\n case \"unsupported\":\n return {\n entry: focusedEntry,\n message: copy.t(\"referencePicker.previewUnsupported\"),\n status: \"unsupported\" as const\n };\n case \"unavailable\":\n return {\n entry: focusedEntry,\n message: copy.t(\"referencePicker.previewUnavailable\"),\n status: \"unsupported\" as const\n };\n case \"directory\":\n return {\n entry: focusedEntry,\n status: \"directory\" as const\n };\n }\n}\n\nfunction resolveWorkspaceFileReferencePreviewReadonlyMessage(\n copy: WorkspaceFileReferenceCopy,\n previewState: Extract<\n WorkspaceFileReferencePreviewState,\n { status: \"readonly\" }\n >\n): string {\n switch (previewState.reason) {\n case \"binary\":\n return copy.t(\"referencePicker.previewBinary\");\n case \"decode_failed\":\n return copy.t(\"referencePicker.previewDecodeFailed\");\n case \"file_too_large\":\n return copy.t(\"referencePicker.previewFileTooLarge\", {\n maxSize: formatWorkspacePreviewByteLimit(previewState.maxSizeBytes ?? 0)\n });\n case \"text_too_large\":\n return copy.t(\"referencePicker.previewTextTooLarge\", {\n maxSize: formatWorkspacePreviewByteLimit(previewState.maxSizeBytes ?? 0)\n });\n }\n}\n\nexport function WorkspaceFileReferencePickerFooter({\n copy,\n onClose,\n onConfirm,\n selectedRefs\n}: {\n copy: WorkspaceFileReferenceCopy;\n onClose: () => void;\n onConfirm: () => void;\n selectedRefs: readonly WorkspaceFileReference[];\n}): JSX.Element {\n return (\n <div className=\"nodrag flex flex-col gap-3 border-t border-[var(--line-1)] px-4 py-4 [-webkit-app-region:no-drag] sm:px-6 lg:flex-row lg:items-center lg:justify-between\">\n <div className=\"flex min-w-0 flex-wrap items-center gap-2 lg:flex-1\">\n <span className=\"text-[13px] text-[var(--text-secondary)]\">\n {copy.t(\"referencePicker.selectedCount\", {\n count: selectedRefs.length\n })}\n </span>\n {selectedRefs.slice(0, 2).map((ref) => (\n <Badge\n className={workspaceFileReferencePickerSelectedBadgeClassName}\n key={ref.path}\n variant=\"secondary\"\n >\n <span className=\"truncate\">\n {resolveWorkspaceFileReferenceLabel(ref)}\n </span>\n </Badge>\n ))}\n {selectedRefs.length > 2 ? (\n <Badge\n className={workspaceFileReferencePickerSelectedBadgeClassName}\n variant=\"secondary\"\n >\n +{selectedRefs.length - 2}\n </Badge>\n ) : null}\n </div>\n <div className=\"flex w-full items-center justify-end gap-2 lg:w-auto lg:shrink-0\">\n <Button\n className=\"nodrag [-webkit-app-region:no-drag]\"\n type=\"button\"\n variant=\"secondary\"\n onClick={onClose}\n >\n {copy.t(\"actions.cancel\")}\n </Button>\n <Button\n className=\"nodrag [-webkit-app-region:no-drag]\"\n disabled={selectedRefs.length === 0}\n type=\"button\"\n onClick={onConfirm}\n >\n {copy.t(\"referencePicker.confirm\")}\n </Button>\n </div>\n </div>\n );\n}\n\nfunction WorkspaceFileReferencePickerFeedback({\n children\n}: {\n children: ReactNode;\n}): JSX.Element {\n return (\n <div className=\"grid min-h-0 flex-1 place-items-center px-4 text-center text-[13px] text-[var(--text-secondary)]\">\n {children}\n </div>\n );\n}\n","import { useEffect, useState, type JSX, type ReactNode } from \"react\";\nimport { useComposedInputValue } from \"@tutti-os/ui-react-hooks\";\nimport {\n ArrowRightIcon,\n Button,\n CheckIcon,\n FileIcon,\n FolderFilledIcon,\n Input,\n ScrollArea,\n SearchIcon,\n Spinner,\n cn\n} from \"@tutti-os/ui-system\";\nimport { AddIcon as AddLinedIcon } from \"@tutti-os/ui-system/icons\";\nimport type {\n WorkspaceFileReference,\n WorkspaceFileReferenceCopy\n} from \"../../../contracts/index.ts\";\nimport {\n normalizeDirectoryPath,\n type WorkspaceFileReferenceDirectoryState\n} from \"../../../react/index.ts\";\n\nconst workspaceFileReferenceTreeIndent = 24;\nconst workspaceFileReferenceTreeCollapseDurationMs = 200;\n\nexport function WorkspaceFileReferencePickerBrowserPane({\n browseRootEntries,\n copy,\n directoryStateByPath,\n expandedFolderPaths,\n focusedPath,\n isLoading,\n mode,\n searchQuery,\n selectedRefs,\n setSearchQuery,\n visibleEntries,\n onFocusPath,\n onToggleFolder,\n onToggleRef\n}: {\n browseRootEntries: readonly WorkspaceFileReference[];\n copy: WorkspaceFileReferenceCopy;\n directoryStateByPath: Record<string, WorkspaceFileReferenceDirectoryState>;\n expandedFolderPaths: Record<string, boolean>;\n focusedPath: string | null;\n isLoading: boolean;\n mode: \"browse\" | \"search\";\n searchQuery: string;\n selectedRefs: readonly WorkspaceFileReference[];\n setSearchQuery: (query: string) => void;\n visibleEntries: readonly WorkspaceFileReference[];\n onFocusPath: (path: string) => void;\n onToggleFolder: (entry: WorkspaceFileReference) => void;\n onToggleRef: (entry: WorkspaceFileReference) => void;\n}): JSX.Element {\n return (\n <section className=\"nodrag flex min-h-0 flex-col border-b border-[var(--line-1)] [-webkit-app-region:no-drag] lg:border-r lg:border-b-0\">\n <div className=\"border-b border-[var(--line-1)] p-3\">\n <WorkspaceFileReferencePickerSearchInput\n placeholder={copy.t(\"referencePicker.searchPlaceholder\")}\n value={searchQuery}\n onChange={setSearchQuery}\n />\n </div>\n {isLoading ? (\n <WorkspaceFileReferencePickerFeedback>\n <Spinner className=\"text-[var(--text-secondary)]\" size={16} />\n </WorkspaceFileReferencePickerFeedback>\n ) : visibleEntries.length === 0 ? (\n <WorkspaceFileReferencePickerFeedback>\n {mode === \"search\"\n ? copy.t(\"referencePicker.emptySearch\")\n : copy.t(\"referencePicker.emptyDirectory\")}\n </WorkspaceFileReferencePickerFeedback>\n ) : (\n <ScrollArea className=\"min-h-0 flex-1\">\n <div className=\"flex flex-col gap-[2px] p-3\">\n {mode === \"browse\" ? (\n <div className=\"space-y-0.5\">\n {browseRootEntries.map((entry) => (\n <WorkspaceFileReferencePickerTreeEntry\n childDepth={1}\n copy={copy}\n directoryStateByPath={directoryStateByPath}\n entry={entry}\n expandedFolderPaths={expandedFolderPaths}\n focusedPath={focusedPath}\n key={entry.path}\n selectedRefs={selectedRefs}\n onFocusPath={onFocusPath}\n onToggleFolder={onToggleFolder}\n onToggleRef={onToggleRef}\n />\n ))}\n </div>\n ) : (\n visibleEntries.map((entry) => (\n <WorkspaceFileReferencePickerSearchEntry\n entry={entry}\n focused={focusedPath === entry.path}\n key={entry.path}\n selected={selectedRefs.some(\n (item) => item.path === entry.path\n )}\n onFocusPath={onFocusPath}\n onToggleRef={onToggleRef}\n />\n ))\n )}\n </div>\n </ScrollArea>\n )}\n </section>\n );\n}\n\nfunction WorkspaceFileReferencePickerSearchInput({\n onChange,\n placeholder,\n value\n}: {\n onChange: (value: string) => void;\n placeholder: string;\n value: string;\n}): JSX.Element {\n const searchInput = useComposedInputValue({ onCommit: onChange, value });\n\n return (\n <div className=\"relative\">\n <SearchIcon className=\"pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2 text-[var(--text-tertiary)]\" />\n <Input\n className=\"pl-9\"\n placeholder={placeholder}\n value={searchInput.value}\n onBlur={searchInput.onBlur}\n onChange={searchInput.onChange}\n onCompositionEnd={searchInput.onCompositionEnd}\n onCompositionStart={searchInput.onCompositionStart}\n />\n </div>\n );\n}\n\nfunction WorkspaceFileReferencePickerTreeEntry({\n childDepth,\n copy,\n directoryStateByPath,\n entry,\n expandedFolderPaths,\n focusedPath,\n selectedRefs,\n onFocusPath,\n onToggleFolder,\n onToggleRef\n}: {\n childDepth: number;\n copy: WorkspaceFileReferenceCopy;\n directoryStateByPath: Record<string, WorkspaceFileReferenceDirectoryState>;\n entry: WorkspaceFileReference;\n expandedFolderPaths: Record<string, boolean>;\n focusedPath: string | null;\n selectedRefs: readonly WorkspaceFileReference[];\n onFocusPath: (path: string) => void;\n onToggleFolder: (entry: WorkspaceFileReference) => void;\n onToggleRef: (entry: WorkspaceFileReference) => void;\n}): JSX.Element {\n const selected = selectedRefs.some((item) => item.path === entry.path);\n const focused = focusedPath === entry.path;\n const isFolder = entry.kind === \"folder\";\n const folderKey = normalizeDirectoryPath(entry.path);\n const expanded = expandedFolderPaths[folderKey] ?? false;\n const childState = directoryStateByPath[folderKey];\n const childEntries = childState?.entries ?? [];\n const [shouldRenderChildContent, setShouldRenderChildContent] =\n useState(expanded);\n\n useEffect(() => {\n if (expanded) {\n setShouldRenderChildContent(true);\n return;\n }\n\n const timeoutId = window.setTimeout(() => {\n setShouldRenderChildContent(false);\n }, workspaceFileReferenceTreeCollapseDurationMs);\n\n return () => window.clearTimeout(timeoutId);\n }, [expanded]);\n\n const shouldBuildChildContent = expanded || shouldRenderChildContent;\n const childContent = shouldBuildChildContent ? (\n childState?.loading ? (\n <div\n className=\"flex items-center gap-2 px-2 py-2 text-[11px] text-[var(--text-secondary)]\"\n style={{\n paddingLeft: `${childDepth * workspaceFileReferenceTreeIndent + 12}px`\n }}\n >\n <Spinner className=\"text-[var(--text-secondary)]\" size={14} />\n <span>{copy.t(\"referencePicker.loading\")}</span>\n </div>\n ) : childEntries.length > 0 ? (\n <div className=\"space-y-0.5\">\n {childEntries.map((childEntry) => (\n <WorkspaceFileReferencePickerTreeEntry\n childDepth={childDepth + 1}\n copy={copy}\n directoryStateByPath={directoryStateByPath}\n entry={childEntry}\n expandedFolderPaths={expandedFolderPaths}\n focusedPath={focusedPath}\n key={childEntry.path}\n selectedRefs={selectedRefs}\n onFocusPath={onFocusPath}\n onToggleFolder={onToggleFolder}\n onToggleRef={onToggleRef}\n />\n ))}\n </div>\n ) : childState?.loaded ? (\n <div\n className=\"px-2 py-2 text-[11px] text-[var(--text-secondary)]\"\n style={{\n paddingLeft: `${childDepth * workspaceFileReferenceTreeIndent + 12}px`\n }}\n >\n {copy.t(\"referencePicker.emptyDirectory\")}\n </div>\n ) : null\n ) : null;\n\n return (\n <div>\n <div\n className={cn(\n \"grid grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-2 rounded-[6px] py-1.5 pr-1 pl-2 transition-colors\",\n \"nodrag [-webkit-app-region:no-drag]\",\n focused || selected\n ? \"bg-transparency-block\"\n : \"hover:bg-transparency-block\"\n )}\n style={{\n paddingLeft: `${(childDepth - 1) * workspaceFileReferenceTreeIndent + 8}px`\n }}\n >\n {isFolder ? (\n <button\n aria-label={resolveWorkspaceFileReferenceLabel(entry)}\n className=\"nodrag grid size-5 shrink-0 place-items-center rounded-sm text-[var(--text-secondary)] [-webkit-app-region:no-drag] hover:bg-[var(--transparency-hover)]\"\n type=\"button\"\n onClick={(event) => {\n event.stopPropagation();\n onToggleFolder(entry);\n }}\n >\n <ArrowRightIcon\n className={cn(\n \"size-3.5 transition-transform\",\n expanded && \"rotate-90\"\n )}\n />\n </button>\n ) : (\n <span className=\"block size-5 shrink-0\" />\n )}\n <button\n className=\"nodrag flex min-w-0 items-center gap-2 text-left [-webkit-app-region:no-drag]\"\n type=\"button\"\n onClick={(event) => {\n event.stopPropagation();\n onFocusPath(entry.path);\n if (entry.kind === \"folder\") {\n onToggleFolder(entry);\n }\n }}\n >\n {isFolder ? (\n <FolderFilledIcon className=\"size-4 shrink-0 text-[var(--rich-text-folder)]\" />\n ) : (\n <FileIcon className=\"size-4 shrink-0 text-[var(--text-tertiary)]\" />\n )}\n <span className=\"truncate text-[13px] text-[var(--text-primary)]\">\n {resolveWorkspaceFileReferenceLabel(entry)}\n </span>\n </button>\n <Button\n aria-label={resolveWorkspaceFileReferenceLabel(entry)}\n aria-pressed={selected}\n size=\"icon-sm\"\n type=\"button\"\n variant=\"ghost\"\n className=\"nodrag [-webkit-app-region:no-drag]\"\n onClick={(event) => {\n event.stopPropagation();\n onFocusPath(entry.path);\n onToggleRef(entry);\n }}\n >\n {selected ? (\n <CheckIcon size={14} />\n ) : (\n <AddLinedIcon className=\"text-[var(--text-secondary)]\" size={16} />\n )}\n </Button>\n </div>\n {isFolder ? (\n <div\n className={cn(\n \"grid transition-[grid-template-rows] duration-200 ease-out motion-reduce:transition-none\",\n expanded ? \"grid-rows-[1fr]\" : \"grid-rows-[0fr]\",\n childContent && \"mt-[2px]\"\n )}\n >\n <div\n aria-hidden={expanded ? undefined : \"true\"}\n className={cn(\n \"min-h-0 overflow-hidden transition-[opacity,transform] duration-200 ease-out motion-reduce:transition-none\",\n expanded\n ? \"translate-y-0 opacity-100\"\n : \"-translate-y-1 opacity-0\"\n )}\n inert={expanded ? undefined : true}\n >\n {childContent}\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction WorkspaceFileReferencePickerSearchEntry({\n entry,\n focused,\n selected,\n onFocusPath,\n onToggleRef\n}: {\n entry: WorkspaceFileReference;\n focused: boolean;\n selected: boolean;\n onFocusPath: (path: string) => void;\n onToggleRef: (entry: WorkspaceFileReference) => void;\n}): JSX.Element {\n const isFolder = entry.kind === \"folder\";\n\n return (\n <div\n className={cn(\n \"grid grid-cols-[minmax(0,1fr)_auto] items-center gap-3 rounded-[6px] border py-2.5 pr-1 pl-3 transition-colors\",\n \"nodrag [-webkit-app-region:no-drag]\",\n focused || selected\n ? \"border-border bg-transparency-block\"\n : \"border-transparent bg-transparent hover:border-border/70 hover:bg-transparency-block\"\n )}\n >\n <button\n className=\"nodrag flex min-w-0 items-center gap-3 text-left [-webkit-app-region:no-drag]\"\n type=\"button\"\n onClick={(event) => {\n event.stopPropagation();\n onFocusPath(entry.path);\n }}\n >\n <span className=\"grid size-9 shrink-0 place-items-center rounded-lg bg-[var(--transparency-block)] text-[var(--text-tertiary)]\">\n {isFolder ? (\n <FolderFilledIcon className=\"size-4 text-[var(--rich-text-folder)]\" />\n ) : (\n <FileIcon className=\"size-4 text-[var(--text-tertiary)]\" />\n )}\n </span>\n <span className=\"min-w-0\">\n <span className=\"block truncate text-[13px] font-medium text-[var(--text-primary)]\">\n {resolveWorkspaceFileReferenceLabel(entry)}\n </span>\n <span className=\"block truncate text-[11px] text-[var(--text-secondary)]\">\n {entry.path}\n </span>\n </span>\n </button>\n <Button\n aria-label={resolveWorkspaceFileReferenceLabel(entry)}\n aria-pressed={selected}\n size=\"icon-sm\"\n type=\"button\"\n variant=\"ghost\"\n className=\"nodrag [-webkit-app-region:no-drag]\"\n onClick={(event) => {\n event.stopPropagation();\n onFocusPath(entry.path);\n onToggleRef(entry);\n }}\n >\n {selected ? (\n <CheckIcon size={14} />\n ) : (\n <AddLinedIcon className=\"text-[var(--text-secondary)]\" size={16} />\n )}\n </Button>\n </div>\n );\n}\n\nfunction WorkspaceFileReferencePickerFeedback({\n children\n}: {\n children: ReactNode;\n}): JSX.Element {\n return (\n <div className=\"grid min-h-0 flex-1 place-items-center px-4 text-center text-[13px] text-[var(--text-secondary)]\">\n {children}\n </div>\n );\n}\n\nexport function resolveWorkspaceFileReferenceLabel(\n ref: WorkspaceFileReference\n): string {\n return (\n ref.displayName || ref.path.split(\"/\").filter(Boolean).at(-1) || ref.path\n );\n}\n"],"mappings":"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","names":["Button","cn","Button","FileIcon","FolderFilledIcon","jsx","jsxs","WorkspaceFileReferencePickerFeedback","FolderFilledIcon","FileIcon","Button","jsx","jsxs","cn","Button"]}
|
|
1
|
+
{"version":3,"sources":["../../src/ui/internal/reference/WorkspaceFileReferencePicker.tsx","../../src/ui/internal/reference/WorkspaceFileReferencePickerSections.tsx","../../src/ui/internal/reference/WorkspaceFileReferencePickerTree.tsx","../../src/ui/internal/reference/ReferenceSourcePicker.tsx","../../src/react/internal/reference/useReferenceSourcePickerView.ts"],"sourcesContent":["import { useId } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport {\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n CloseIcon,\n cn\n} from \"@tutti-os/ui-system\";\nimport type {\n WorkspaceFileReferenceAdapter,\n WorkspaceFileReference,\n WorkspaceFileReferenceCopy\n} from \"../../../contracts/index.ts\";\nimport { useWorkspaceFileReferencePickerView } from \"../../../react/index.ts\";\nimport {\n WorkspaceFileReferencePickerFooter,\n WorkspaceFileReferencePickerPreviewPane\n} from \"./WorkspaceFileReferencePickerSections.tsx\";\nimport { WorkspaceFileReferencePickerBrowserPane } from \"./WorkspaceFileReferencePickerTree.tsx\";\n\nexport interface WorkspaceFileReferencePickerProps {\n copy: WorkspaceFileReferenceCopy;\n fileAdapter?: WorkspaceFileReferenceAdapter;\n initialPath?: string | null;\n onClose: () => void;\n onConfirm: (refs: WorkspaceFileReference[]) => void;\n open: boolean;\n workspaceId: string;\n}\n\nconst workspaceFileReferencePickerBackdropMotionClassName =\n \"motion-safe:animate-in motion-safe:fade-in-0 motion-safe:duration-[180ms] motion-safe:ease-[cubic-bezier(0.22,1,0.36,1)] motion-reduce:animate-none\";\n\nconst workspaceFileReferencePickerPanelMotionClassName =\n \"motion-safe:animate-in motion-safe:fade-in-0 motion-safe:zoom-in-[0.96] motion-safe:duration-[250ms] motion-safe:ease-[cubic-bezier(0.22,1,0.36,1)] motion-reduce:animate-none\";\n\nexport function WorkspaceFileReferencePicker({\n copy,\n fileAdapter,\n initialPath,\n onClose,\n onConfirm,\n open,\n workspaceId\n}: WorkspaceFileReferencePickerProps) {\n const titleId = useId();\n const {\n browseRootEntries,\n directoryStateByPath,\n expandedFolderPaths,\n focusedEntry,\n focusedPath,\n isLoading,\n mode,\n previewState,\n searchQuery,\n selectedRefs,\n visibleEntries,\n setFocusedPath,\n setSearchQuery,\n toggleFolder,\n toggleRef\n } = useWorkspaceFileReferencePickerView({\n fileAdapter,\n initialPath,\n onClose,\n onConfirm,\n open,\n workspaceId\n });\n\n if (!open) {\n return null;\n }\n\n const dialog = (\n <div\n className={cn(\n \"nodrag fixed inset-0 grid place-items-center bg-[var(--backdrop)] px-3 py-4 backdrop-blur-md [-webkit-app-region:no-drag] sm:px-6 sm:py-8\",\n workspaceFileReferencePickerBackdropMotionClassName\n )}\n style={{ zIndex: \"var(--z-panel)\" }}\n onClick={onClose}\n >\n <Card\n aria-labelledby={titleId}\n aria-modal=\"true\"\n className={cn(\n \"nodrag flex h-[min(88vh,44rem)] w-full max-w-5xl origin-center flex-col gap-0 overflow-hidden border-[var(--line-1)] bg-[var(--background-fronted)] py-0 text-[var(--text-primary)] shadow-panel [-webkit-app-region:no-drag] sm:h-[min(82vh,44rem)]\",\n workspaceFileReferencePickerPanelMotionClassName\n )}\n role=\"dialog\"\n onClick={(event) => event.stopPropagation()}\n >\n <CardHeader\n className=\"border-b px-4 py-4 sm:px-6 sm:py-5\"\n style={{ borderBottomColor: \"var(--line-1)\" }}\n >\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0\">\n <CardTitle id={titleId}>\n {copy.t(\"referencePicker.title\")}\n </CardTitle>\n </div>\n <Button\n aria-label={copy.t(\"actions.cancel\")}\n size=\"icon-sm\"\n type=\"button\"\n variant=\"ghost\"\n onClick={onClose}\n >\n <CloseIcon size={16} />\n </Button>\n </div>\n </CardHeader>\n <CardContent className=\"grid min-h-0 flex-1 grid-rows-[minmax(0,1fr)_auto] gap-0 overflow-hidden p-0 lg:grid-cols-[minmax(0,1.15fr)_minmax(20rem,0.85fr)] lg:grid-rows-1\">\n <WorkspaceFileReferencePickerBrowserPane\n browseRootEntries={browseRootEntries}\n copy={copy}\n directoryStateByPath={directoryStateByPath}\n expandedFolderPaths={expandedFolderPaths}\n focusedPath={focusedPath}\n isLoading={isLoading}\n mode={mode}\n searchQuery={searchQuery}\n selectedRefs={selectedRefs}\n setSearchQuery={setSearchQuery}\n visibleEntries={visibleEntries}\n onFocusPath={setFocusedPath}\n onToggleFolder={toggleFolder}\n onToggleRef={toggleRef}\n />\n <WorkspaceFileReferencePickerPreviewPane\n copy={copy}\n focusedEntry={focusedEntry}\n mode={mode}\n previewState={previewState}\n />\n </CardContent>\n <WorkspaceFileReferencePickerFooter\n copy={copy}\n onClose={onClose}\n onConfirm={() => onConfirm(selectedRefs)}\n selectedRefs={selectedRefs}\n />\n </Card>\n </div>\n );\n\n if (typeof document === \"undefined\") {\n return dialog;\n }\n return createPortal(dialog, document.body);\n}\n","import type { JSX, ReactNode } from \"react\";\nimport {\n Badge,\n Button,\n FileIcon,\n FolderFilledIcon,\n LoadingIcon\n} from \"@tutti-os/ui-system\";\nimport { formatWorkspacePreviewByteLimit } from \"@tutti-os/workspace-file-preview\";\nimport { WorkspaceFilePreviewSurface as SharedWorkspaceFilePreviewSurface } from \"@tutti-os/workspace-file-preview/react\";\nimport type {\n WorkspaceFileReference,\n WorkspaceFileReferenceCopy\n} from \"../../../contracts/index.ts\";\nimport type { WorkspaceFileReferencePreviewState } from \"../../../react/internal/reference/useWorkspaceFileReferencePickerView.ts\";\nimport { resolveWorkspaceFileReferenceLabel } from \"./WorkspaceFileReferencePickerTree.tsx\";\n\nconst workspaceFileReferencePickerSelectedBadgeClassName =\n \"max-w-[14rem] rounded-[4px] border-transparent bg-[var(--transparency-block)] text-[var(--text-primary)]\";\n\nexport function WorkspaceFileReferencePickerPreviewPane({\n copy,\n focusedEntry,\n mode,\n previewState\n}: {\n copy: WorkspaceFileReferenceCopy;\n focusedEntry: WorkspaceFileReference | null;\n mode: \"browse\" | \"search\";\n previewState: WorkspaceFileReferencePreviewState;\n}): JSX.Element {\n return (\n <aside className=\"flex shrink-0 flex-col border-t border-[var(--line-1)] bg-[var(--background-fronted)] lg:min-h-0 lg:flex-1 lg:border-t-0\">\n <div className=\"flex min-h-0 flex-1 flex-col p-2\">\n {focusedEntry ? (\n <div className=\"flex min-h-0 flex-col gap-4 lg:flex-1 lg:gap-5\">\n <WorkspaceFileReferencePreviewSurface\n copy={copy}\n focusedEntry={focusedEntry}\n previewState={previewState}\n />\n <div className=\"space-y-2 px-2 lg:space-y-3\">\n <div className=\"space-y-1.5\">\n <p className=\"truncate text-[15px] font-semibold text-[var(--text-primary)]\">\n {resolveWorkspaceFileReferenceLabel(focusedEntry)}\n </p>\n <p className=\"line-clamp-3 text-[13px] text-[var(--text-secondary)] [overflow-wrap:anywhere]\">\n {focusedEntry.path}\n </p>\n </div>\n </div>\n </div>\n ) : (\n <WorkspaceFileReferencePickerFeedback>\n {mode === \"search\"\n ? copy.t(\"referencePicker.emptySearch\")\n : copy.t(\"referencePicker.emptyDirectory\")}\n </WorkspaceFileReferencePickerFeedback>\n )}\n </div>\n </aside>\n );\n}\n\nfunction WorkspaceFileReferencePreviewSurface({\n copy,\n focusedEntry,\n previewState\n}: {\n copy: WorkspaceFileReferenceCopy;\n focusedEntry: WorkspaceFileReference;\n previewState: WorkspaceFileReferencePreviewState;\n}): JSX.Element {\n return (\n <SharedWorkspaceFilePreviewSurface\n directoryMessage={copy.t(\"referencePicker.previewFolder\")}\n emptyMessage={copy.t(\"referencePicker.previewUnavailable\")}\n frameClassName=\"flex aspect-[3/2] w-full flex-col items-center justify-center overflow-hidden rounded-[8px] border border-[var(--line-2,var(--border-2))] bg-[var(--transparency-block)] p-0 text-center\"\n imageAlt={resolveWorkspaceFileReferenceLabel}\n imageFrameClassName=\"p-3\"\n loadingIndicator={\n <span className=\"mx-auto grid size-11 place-items-center rounded-[6px] bg-[var(--transparency-block)]\">\n <LoadingIcon className=\"size-4 animate-spin\" />\n </span>\n }\n loadingMessage={copy.t(\"referencePicker.previewLoading\")}\n messageClassName=\"mx-auto max-w-[24ch] text-[13px] leading-5 text-[var(--text-secondary)] [overflow-wrap:anywhere]\"\n renderIcon={(entry) =>\n entry.kind === \"folder\" ? (\n <FolderFilledIcon className=\"mx-auto size-9 text-[var(--rich-text-folder)]\" />\n ) : (\n <FileIcon className=\"mx-auto size-9 text-[var(--text-tertiary)]\" />\n )\n }\n state={resolveWorkspaceFileReferenceSurfaceState(\n copy,\n focusedEntry,\n previewState\n )}\n textClassName=\"h-full overflow-auto p-3 text-left text-[11px] leading-5 whitespace-pre-wrap break-words text-[var(--text-primary)]\"\n textFrameClassName=\"items-stretch justify-stretch\"\n />\n );\n}\n\nfunction resolveWorkspaceFileReferenceSurfaceState(\n copy: WorkspaceFileReferenceCopy,\n focusedEntry: WorkspaceFileReference,\n previewState: WorkspaceFileReferencePreviewState\n) {\n if (focusedEntry.kind === \"folder\") {\n return {\n entry: focusedEntry,\n status: \"directory\" as const\n };\n }\n\n if (\n !(\"reference\" in previewState) ||\n previewState.reference.path !== focusedEntry.path\n ) {\n return {\n entry: focusedEntry,\n message: focusedEntry.path,\n status: \"unsupported\" as const\n };\n }\n\n switch (previewState.status) {\n case \"loading\":\n case \"image\":\n case \"text\":\n return {\n ...previewState,\n entry: focusedEntry\n };\n case \"readonly\":\n return {\n entry: focusedEntry,\n message: resolveWorkspaceFileReferencePreviewReadonlyMessage(\n copy,\n previewState\n ),\n status: \"readonly\" as const\n };\n case \"error\":\n return {\n entry: focusedEntry,\n message: copy.t(\"referencePicker.previewError\"),\n status: \"error\" as const\n };\n case \"unsupported\":\n return {\n entry: focusedEntry,\n message: copy.t(\"referencePicker.previewUnsupported\"),\n status: \"unsupported\" as const\n };\n case \"unavailable\":\n return {\n entry: focusedEntry,\n message: copy.t(\"referencePicker.previewUnavailable\"),\n status: \"unsupported\" as const\n };\n case \"directory\":\n return {\n entry: focusedEntry,\n status: \"directory\" as const\n };\n }\n}\n\nfunction resolveWorkspaceFileReferencePreviewReadonlyMessage(\n copy: WorkspaceFileReferenceCopy,\n previewState: Extract<\n WorkspaceFileReferencePreviewState,\n { status: \"readonly\" }\n >\n): string {\n switch (previewState.reason) {\n case \"binary\":\n return copy.t(\"referencePicker.previewBinary\");\n case \"decode_failed\":\n return copy.t(\"referencePicker.previewDecodeFailed\");\n case \"file_too_large\":\n return copy.t(\"referencePicker.previewFileTooLarge\", {\n maxSize: formatWorkspacePreviewByteLimit(previewState.maxSizeBytes ?? 0)\n });\n case \"text_too_large\":\n return copy.t(\"referencePicker.previewTextTooLarge\", {\n maxSize: formatWorkspacePreviewByteLimit(previewState.maxSizeBytes ?? 0)\n });\n }\n}\n\nexport function WorkspaceFileReferencePickerFooter({\n copy,\n onClose,\n onConfirm,\n selectedRefs\n}: {\n copy: WorkspaceFileReferenceCopy;\n onClose: () => void;\n onConfirm: () => void;\n selectedRefs: readonly WorkspaceFileReference[];\n}): JSX.Element {\n return (\n <div className=\"nodrag flex flex-col gap-3 border-t border-[var(--line-1)] px-4 py-4 [-webkit-app-region:no-drag] sm:px-6 lg:flex-row lg:items-center lg:justify-between\">\n <div className=\"flex min-w-0 flex-wrap items-center gap-2 lg:flex-1\">\n <span className=\"text-[13px] text-[var(--text-secondary)]\">\n {copy.t(\"referencePicker.selectedCount\", {\n count: selectedRefs.length\n })}\n </span>\n {selectedRefs.slice(0, 2).map((ref) => (\n <Badge\n className={workspaceFileReferencePickerSelectedBadgeClassName}\n key={ref.path}\n variant=\"secondary\"\n >\n <span className=\"truncate\">\n {resolveWorkspaceFileReferenceLabel(ref)}\n </span>\n </Badge>\n ))}\n {selectedRefs.length > 2 ? (\n <Badge\n className={workspaceFileReferencePickerSelectedBadgeClassName}\n variant=\"secondary\"\n >\n +{selectedRefs.length - 2}\n </Badge>\n ) : null}\n </div>\n <div className=\"flex w-full items-center justify-end gap-2 lg:w-auto lg:shrink-0\">\n <Button\n className=\"nodrag [-webkit-app-region:no-drag]\"\n type=\"button\"\n variant=\"secondary\"\n onClick={onClose}\n >\n {copy.t(\"actions.cancel\")}\n </Button>\n <Button\n className=\"nodrag [-webkit-app-region:no-drag]\"\n disabled={selectedRefs.length === 0}\n type=\"button\"\n onClick={onConfirm}\n >\n {copy.t(\"referencePicker.confirm\")}\n </Button>\n </div>\n </div>\n );\n}\n\nfunction WorkspaceFileReferencePickerFeedback({\n children\n}: {\n children: ReactNode;\n}): JSX.Element {\n return (\n <div className=\"grid min-h-0 flex-1 place-items-center px-4 text-center text-[13px] text-[var(--text-secondary)]\">\n {children}\n </div>\n );\n}\n","import { useEffect, useState, type JSX, type ReactNode } from \"react\";\nimport { useComposedInputValue } from \"@tutti-os/ui-react-hooks\";\nimport {\n ArrowRightIcon,\n Button,\n CheckIcon,\n FileIcon,\n FolderFilledIcon,\n Input,\n ScrollArea,\n SearchIcon,\n Spinner,\n cn\n} from \"@tutti-os/ui-system\";\nimport { AddIcon as AddLinedIcon } from \"@tutti-os/ui-system/icons\";\nimport type {\n WorkspaceFileReference,\n WorkspaceFileReferenceCopy\n} from \"../../../contracts/index.ts\";\nimport {\n normalizeDirectoryPath,\n type WorkspaceFileReferenceDirectoryState\n} from \"../../../react/index.ts\";\n\n// 每级缩进 = 箭头列宽(20px)+ 间距(8px),使子级文件图标对齐到父文件夹图标下方。\nconst workspaceFileReferenceTreeIndent = 28;\nconst workspaceFileReferenceTreeCollapseDurationMs = 200;\n\nexport function WorkspaceFileReferencePickerBrowserPane({\n browseRootEntries,\n copy,\n directoryStateByPath,\n expandedFolderPaths,\n focusedPath,\n isLoading,\n mode,\n searchQuery,\n selectedRefs,\n setSearchQuery,\n visibleEntries,\n onFocusPath,\n onToggleFolder,\n onToggleRef\n}: {\n browseRootEntries: readonly WorkspaceFileReference[];\n copy: WorkspaceFileReferenceCopy;\n directoryStateByPath: Record<string, WorkspaceFileReferenceDirectoryState>;\n expandedFolderPaths: Record<string, boolean>;\n focusedPath: string | null;\n isLoading: boolean;\n mode: \"browse\" | \"search\";\n searchQuery: string;\n selectedRefs: readonly WorkspaceFileReference[];\n setSearchQuery: (query: string) => void;\n visibleEntries: readonly WorkspaceFileReference[];\n onFocusPath: (path: string) => void;\n onToggleFolder: (entry: WorkspaceFileReference) => void;\n onToggleRef: (entry: WorkspaceFileReference) => void;\n}): JSX.Element {\n return (\n <section className=\"nodrag flex min-h-0 flex-col border-b border-[var(--line-1)] [-webkit-app-region:no-drag] lg:border-r lg:border-b-0\">\n <div className=\"border-b border-[var(--line-1)] p-3\">\n <WorkspaceFileReferencePickerSearchInput\n placeholder={copy.t(\"referencePicker.searchPlaceholder\")}\n value={searchQuery}\n onChange={setSearchQuery}\n />\n </div>\n {isLoading ? (\n <WorkspaceFileReferencePickerFeedback>\n <Spinner className=\"text-[var(--text-secondary)]\" size={16} />\n </WorkspaceFileReferencePickerFeedback>\n ) : visibleEntries.length === 0 ? (\n <WorkspaceFileReferencePickerFeedback>\n {mode === \"search\"\n ? copy.t(\"referencePicker.emptySearch\")\n : copy.t(\"referencePicker.emptyDirectory\")}\n </WorkspaceFileReferencePickerFeedback>\n ) : (\n <ScrollArea className=\"min-h-0 flex-1\">\n <div className=\"flex flex-col gap-[2px] p-3\">\n {mode === \"browse\" ? (\n <div className=\"space-y-0.5\">\n {browseRootEntries.map((entry) => (\n <WorkspaceFileReferencePickerTreeEntry\n childDepth={1}\n copy={copy}\n directoryStateByPath={directoryStateByPath}\n entry={entry}\n expandedFolderPaths={expandedFolderPaths}\n focusedPath={focusedPath}\n key={entry.path}\n selectedRefs={selectedRefs}\n onFocusPath={onFocusPath}\n onToggleFolder={onToggleFolder}\n onToggleRef={onToggleRef}\n />\n ))}\n </div>\n ) : (\n visibleEntries.map((entry) => (\n <WorkspaceFileReferencePickerSearchEntry\n entry={entry}\n focused={focusedPath === entry.path}\n key={entry.path}\n selected={selectedRefs.some(\n (item) => item.path === entry.path\n )}\n onFocusPath={onFocusPath}\n onToggleRef={onToggleRef}\n />\n ))\n )}\n </div>\n </ScrollArea>\n )}\n </section>\n );\n}\n\nfunction WorkspaceFileReferencePickerSearchInput({\n onChange,\n placeholder,\n value\n}: {\n onChange: (value: string) => void;\n placeholder: string;\n value: string;\n}): JSX.Element {\n const searchInput = useComposedInputValue({ onCommit: onChange, value });\n\n return (\n <div className=\"relative\">\n <SearchIcon className=\"pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2 text-[var(--text-tertiary)]\" />\n <Input\n className=\"pl-9\"\n placeholder={placeholder}\n value={searchInput.value}\n onBlur={searchInput.onBlur}\n onChange={searchInput.onChange}\n onCompositionEnd={searchInput.onCompositionEnd}\n onCompositionStart={searchInput.onCompositionStart}\n />\n </div>\n );\n}\n\nfunction WorkspaceFileReferencePickerTreeEntry({\n childDepth,\n copy,\n directoryStateByPath,\n entry,\n expandedFolderPaths,\n focusedPath,\n selectedRefs,\n onFocusPath,\n onToggleFolder,\n onToggleRef\n}: {\n childDepth: number;\n copy: WorkspaceFileReferenceCopy;\n directoryStateByPath: Record<string, WorkspaceFileReferenceDirectoryState>;\n entry: WorkspaceFileReference;\n expandedFolderPaths: Record<string, boolean>;\n focusedPath: string | null;\n selectedRefs: readonly WorkspaceFileReference[];\n onFocusPath: (path: string) => void;\n onToggleFolder: (entry: WorkspaceFileReference) => void;\n onToggleRef: (entry: WorkspaceFileReference) => void;\n}): JSX.Element {\n const selected = selectedRefs.some((item) => item.path === entry.path);\n const focused = focusedPath === entry.path;\n const isFolder = entry.kind === \"folder\";\n const folderKey = normalizeDirectoryPath(entry.path);\n const expanded = expandedFolderPaths[folderKey] ?? false;\n const childState = directoryStateByPath[folderKey];\n const childEntries = childState?.entries ?? [];\n const [shouldRenderChildContent, setShouldRenderChildContent] =\n useState(expanded);\n\n useEffect(() => {\n if (expanded) {\n setShouldRenderChildContent(true);\n return;\n }\n\n const timeoutId = window.setTimeout(() => {\n setShouldRenderChildContent(false);\n }, workspaceFileReferenceTreeCollapseDurationMs);\n\n return () => window.clearTimeout(timeoutId);\n }, [expanded]);\n\n const shouldBuildChildContent = expanded || shouldRenderChildContent;\n const childContent = shouldBuildChildContent ? (\n childState?.loading ? (\n <div\n className=\"flex items-center gap-2 px-2 py-2 text-[11px] text-[var(--text-secondary)]\"\n style={{\n paddingLeft: `${childDepth * workspaceFileReferenceTreeIndent + 12}px`\n }}\n >\n <Spinner className=\"text-[var(--text-secondary)]\" size={14} />\n <span>{copy.t(\"referencePicker.loading\")}</span>\n </div>\n ) : childEntries.length > 0 ? (\n <div className=\"space-y-0.5\">\n {childEntries.map((childEntry) => (\n <WorkspaceFileReferencePickerTreeEntry\n childDepth={childDepth + 1}\n copy={copy}\n directoryStateByPath={directoryStateByPath}\n entry={childEntry}\n expandedFolderPaths={expandedFolderPaths}\n focusedPath={focusedPath}\n key={childEntry.path}\n selectedRefs={selectedRefs}\n onFocusPath={onFocusPath}\n onToggleFolder={onToggleFolder}\n onToggleRef={onToggleRef}\n />\n ))}\n </div>\n ) : childState?.loaded ? (\n <div\n className=\"px-2 py-2 text-[11px] text-[var(--text-secondary)]\"\n style={{\n paddingLeft: `${childDepth * workspaceFileReferenceTreeIndent + 12}px`\n }}\n >\n {copy.t(\"referencePicker.emptyDirectory\")}\n </div>\n ) : null\n ) : null;\n\n return (\n <div>\n <div\n className={cn(\n \"flex items-center gap-2 rounded-[6px] py-1.5 pr-1 transition-colors\",\n \"nodrag [-webkit-app-region:no-drag]\",\n focused || selected\n ? \"bg-transparency-block\"\n : \"hover:bg-transparency-block\"\n )}\n style={{\n paddingLeft: `${(childDepth - 1) * workspaceFileReferenceTreeIndent + 8}px`\n }}\n >\n {isFolder ? (\n <button\n aria-label={resolveWorkspaceFileReferenceLabel(entry)}\n className=\"nodrag grid size-5 shrink-0 place-items-center rounded-sm text-[var(--text-secondary)] [-webkit-app-region:no-drag] hover:bg-[var(--transparency-hover)]\"\n type=\"button\"\n onClick={(event) => {\n event.stopPropagation();\n onToggleFolder(entry);\n }}\n >\n <ArrowRightIcon\n className={cn(\n \"size-3.5 transition-transform\",\n expanded && \"rotate-90\"\n )}\n />\n </button>\n ) : null}\n <button\n className=\"nodrag flex min-w-0 flex-1 items-center gap-2 text-left [-webkit-app-region:no-drag]\"\n type=\"button\"\n onClick={(event) => {\n event.stopPropagation();\n onFocusPath(entry.path);\n if (entry.kind === \"folder\") {\n onToggleFolder(entry);\n }\n }}\n >\n {isFolder ? (\n <FolderFilledIcon className=\"size-4 shrink-0 text-[var(--rich-text-folder)]\" />\n ) : (\n <FileIcon className=\"size-4 shrink-0 text-[var(--text-tertiary)]\" />\n )}\n <span className=\"truncate text-[13px] text-[var(--text-primary)]\">\n {resolveWorkspaceFileReferenceLabel(entry)}\n </span>\n </button>\n <Button\n aria-label={resolveWorkspaceFileReferenceLabel(entry)}\n aria-pressed={selected}\n size=\"icon-sm\"\n type=\"button\"\n variant=\"ghost\"\n className=\"nodrag shrink-0 [-webkit-app-region:no-drag]\"\n onClick={(event) => {\n event.stopPropagation();\n onFocusPath(entry.path);\n onToggleRef(entry);\n }}\n >\n {selected ? (\n <CheckIcon size={14} />\n ) : (\n <AddLinedIcon className=\"text-[var(--text-secondary)]\" size={16} />\n )}\n </Button>\n </div>\n {isFolder ? (\n <div\n className={cn(\n \"grid transition-[grid-template-rows] duration-200 ease-out motion-reduce:transition-none\",\n expanded ? \"grid-rows-[1fr]\" : \"grid-rows-[0fr]\",\n childContent && \"mt-[2px]\"\n )}\n >\n <div\n aria-hidden={expanded ? undefined : \"true\"}\n className={cn(\n \"min-h-0 overflow-hidden transition-[opacity,transform] duration-200 ease-out motion-reduce:transition-none\",\n expanded\n ? \"translate-y-0 opacity-100\"\n : \"-translate-y-1 opacity-0\"\n )}\n inert={expanded ? undefined : true}\n >\n {childContent}\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction WorkspaceFileReferencePickerSearchEntry({\n entry,\n focused,\n selected,\n onFocusPath,\n onToggleRef\n}: {\n entry: WorkspaceFileReference;\n focused: boolean;\n selected: boolean;\n onFocusPath: (path: string) => void;\n onToggleRef: (entry: WorkspaceFileReference) => void;\n}): JSX.Element {\n const isFolder = entry.kind === \"folder\";\n\n return (\n <div\n className={cn(\n \"grid grid-cols-[minmax(0,1fr)_auto] items-center gap-3 rounded-[6px] border py-2.5 pr-1 pl-3 transition-colors\",\n \"nodrag [-webkit-app-region:no-drag]\",\n focused || selected\n ? \"border-border bg-transparency-block\"\n : \"border-transparent bg-transparent hover:border-border/70 hover:bg-transparency-block\"\n )}\n >\n <button\n className=\"nodrag flex min-w-0 items-center gap-3 text-left [-webkit-app-region:no-drag]\"\n type=\"button\"\n onClick={(event) => {\n event.stopPropagation();\n onFocusPath(entry.path);\n }}\n >\n <span className=\"grid size-9 shrink-0 place-items-center rounded-lg bg-[var(--transparency-block)] text-[var(--text-tertiary)]\">\n {isFolder ? (\n <FolderFilledIcon className=\"size-4 text-[var(--rich-text-folder)]\" />\n ) : (\n <FileIcon className=\"size-4 text-[var(--text-tertiary)]\" />\n )}\n </span>\n <span className=\"min-w-0\">\n <span className=\"block truncate text-[13px] font-medium text-[var(--text-primary)]\">\n {resolveWorkspaceFileReferenceLabel(entry)}\n </span>\n <span className=\"block truncate text-[11px] text-[var(--text-secondary)]\">\n {entry.path}\n </span>\n </span>\n </button>\n <Button\n aria-label={resolveWorkspaceFileReferenceLabel(entry)}\n aria-pressed={selected}\n size=\"icon-sm\"\n type=\"button\"\n variant=\"ghost\"\n className=\"nodrag [-webkit-app-region:no-drag]\"\n onClick={(event) => {\n event.stopPropagation();\n onFocusPath(entry.path);\n onToggleRef(entry);\n }}\n >\n {selected ? (\n <CheckIcon size={14} />\n ) : (\n <AddLinedIcon className=\"text-[var(--text-secondary)]\" size={16} />\n )}\n </Button>\n </div>\n );\n}\n\nfunction WorkspaceFileReferencePickerFeedback({\n children\n}: {\n children: ReactNode;\n}): JSX.Element {\n return (\n <div className=\"grid min-h-0 flex-1 place-items-center px-4 text-center text-[13px] text-[var(--text-secondary)]\">\n {children}\n </div>\n );\n}\n\nexport function resolveWorkspaceFileReferenceLabel(\n ref: WorkspaceFileReference\n): string {\n return (\n ref.displayName || ref.path.split(\"/\").filter(Boolean).at(-1) || ref.path\n );\n}\n","import {\n useEffect,\n useId,\n useRef,\n useState,\n type JSX,\n type ReactNode,\n type RefObject\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport {\n ArrowRightIcon,\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n CheckIcon,\n CloseIcon,\n FileIcon,\n FolderFilledIcon,\n Input,\n ResizableHandle,\n ResizablePanel,\n ResizablePanelGroup,\n ScrollArea,\n SearchIcon,\n Spinner,\n cn\n} from \"@tutti-os/ui-system\";\nimport { AddIcon } from \"@tutti-os/ui-system/icons\";\nimport type { ReferenceNode } from \"../../../contracts/referenceSource.ts\";\nimport type {\n WorkspaceFileReference,\n WorkspaceFileReferenceCopy\n} from \"../../../contracts/index.ts\";\nimport type { ReferenceSourceAggregator } from \"../../../core/referenceSourceAggregator.ts\";\nimport { nodeRefKey } from \"../../../core/index.ts\";\nimport { useReferenceSourcePickerView } from \"../../../react/internal/reference/useReferenceSourcePickerView.ts\";\n\nexport interface ReferenceSourcePickerProps {\n aggregator: ReferenceSourceAggregator;\n copy: WorkspaceFileReferenceCopy;\n onClose: () => void;\n onConfirm: (refs: WorkspaceFileReference[]) => void;\n open: boolean;\n workspaceId: string;\n}\n\n// v1 新增 UI 文案默认中文;后续接入 i18n。\nconst L = {\n sourceColumn: \"分类\",\n selectGroupHint: \"从左侧选择一个目录\",\n previewSource: \"产出来源\",\n previewModified: \"产出时间\",\n previewSize: \"文件大小\",\n previewHierarchy: \"所属层级\",\n reference: \"引用\",\n loadMore: \"加载更多\",\n emptyPreview: \"选择一个文件查看详情\"\n};\n\ntype PickerView = ReturnType<typeof useReferenceSourcePickerView>;\n\n/** react-resizable-panels 命令式句柄(只用到 resize)。 */\ntype ResizablePanelHandle = { resize: (size: number) => void };\n\n/**\n * 双击分割线:把 panel 自动适配到内容自然宽度。\n * 量 `[data-autofit-label]`(truncate 元素的 scrollWidth = 完整文本宽度)的最右边缘,\n * 加上尾部控件/内边距,折算成占整体宽度的百分比;resize 内部会按 minSize 再做夹取。\n */\nfunction autoFitPanelWidth(\n groupEl: HTMLElement | null,\n contentEl: HTMLElement | null,\n panel: ResizablePanelHandle | null,\n trailingPx: number\n): void {\n if (!groupEl || !contentEl || !panel) {\n return;\n }\n const groupWidth = groupEl.clientWidth;\n if (groupWidth <= 0) {\n return;\n }\n const contentLeft = contentEl.getBoundingClientRect().left;\n const labels = contentEl.querySelectorAll<HTMLElement>(\n \"[data-autofit-label]\"\n );\n let maxRight = 0;\n labels.forEach((label) => {\n const right =\n label.getBoundingClientRect().left - contentLeft + label.scrollWidth;\n if (right > maxRight) {\n maxRight = right;\n }\n });\n if (maxRight <= 0) {\n return;\n }\n const naturalWidth = maxRight + trailingPx;\n panel.resize(Math.min(80, (naturalWidth / groupWidth) * 100));\n}\n\nexport function ReferenceSourcePicker({\n aggregator,\n copy,\n onClose,\n onConfirm,\n open,\n workspaceId\n}: ReferenceSourcePickerProps): JSX.Element | null {\n const titleId = useId();\n const view = useReferenceSourcePickerView({\n aggregator,\n workspaceId,\n open,\n onClose,\n onConfirm\n });\n\n // 三栏可拖拽 + 双击自动适配:layoutRef 量整体宽度,content/panel ref 用于双击适配。\n const layoutRef = useRef<HTMLDivElement | null>(null);\n const sidebarContentRef = useRef<HTMLDivElement | null>(null);\n const middleContentRef = useRef<HTMLDivElement | null>(null);\n const sidebarPanelRef = useRef<ResizablePanelHandle | null>(null);\n const middlePanelRef = useRef<ResizablePanelHandle | null>(null);\n\n if (!open) {\n return null;\n }\n\n const hasSelectedGroup = view.selectedGroupKey != null;\n const fitSidebar = () =>\n autoFitPanelWidth(\n layoutRef.current,\n sidebarContentRef.current,\n sidebarPanelRef.current,\n 36\n );\n const fitMiddle = () =>\n autoFitPanelWidth(\n layoutRef.current,\n middleContentRef.current,\n middlePanelRef.current,\n 56\n );\n\n const dialog = (\n <div\n className=\"nodrag fixed inset-0 grid place-items-center bg-[var(--backdrop)] px-3 py-4 backdrop-blur-md [-webkit-app-region:no-drag] sm:px-6 sm:py-8\"\n style={{ zIndex: \"var(--z-panel)\" }}\n onClick={onClose}\n >\n <Card\n aria-labelledby={titleId}\n aria-modal=\"true\"\n className=\"nodrag flex h-[min(88vh,46rem)] w-full max-w-5xl flex-col gap-0 overflow-hidden border-[var(--line-1)] bg-[var(--background-fronted)] py-0 text-[var(--text-primary)] shadow-panel [-webkit-app-region:no-drag]\"\n role=\"dialog\"\n onClick={(event) => event.stopPropagation()}\n >\n <CardHeader className=\"gap-3 px-4 pt-4 pb-4 sm:px-6\">\n <div className=\"flex items-start justify-between gap-4\">\n <CardTitle id={titleId}>\n {copy.t(\"referencePicker.title\")}\n </CardTitle>\n <Button\n aria-label={copy.t(\"actions.cancel\")}\n size=\"icon-sm\"\n type=\"button\"\n variant=\"ghost\"\n onClick={onClose}\n >\n <CloseIcon size={16} />\n </Button>\n </div>\n </CardHeader>\n\n <CardContent className=\"flex min-h-0 flex-1 overflow-hidden border-t border-[var(--line-1)] p-0\">\n <div ref={layoutRef} className=\"flex min-h-0 flex-1\">\n <ResizablePanelGroup\n className=\"min-h-0 flex-1\"\n orientation=\"horizontal\"\n // 三栏初始占比 2:5:3。v4 在三面板下 `defaultSize` 初始布局会因注册时序被忽略而回退等分,\n // 这里用 `defaultLayout`(按 panel id 指定 flexGrow 权重)作为权威初始布局。\n defaultLayout={{ sidebar: 2, middle: 5, preview: 3 }}\n >\n <ResizablePanel\n id=\"sidebar\"\n className=\"min-h-0 border-r border-[var(--line-1)]\"\n defaultSize={20}\n minSize=\"180px\"\n panelRef={(handle) => {\n sidebarPanelRef.current = handle;\n }}\n >\n <SourceSidebar contentRef={sidebarContentRef} view={view} />\n </ResizablePanel>\n <ResizableHandle\n disableDoubleClick\n withHandle\n onDoubleClick={fitSidebar}\n />\n <ResizablePanel\n id=\"middle\"\n className=\"min-h-0\"\n defaultSize={50}\n minSize=\"260px\"\n panelRef={(handle) => {\n middlePanelRef.current = handle;\n }}\n >\n <div className=\"flex h-full min-h-0 flex-col\">\n <div className=\"flex items-center gap-2 border-b border-[var(--line-1)] p-3\">\n <div className=\"relative flex-1\">\n <SearchIcon className=\"pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2 text-[var(--text-tertiary)]\" />\n <Input\n className=\"pl-9\"\n placeholder={copy.t(\n \"referencePicker.searchPlaceholder\"\n )}\n value={view.searchQuery}\n onChange={(event) =>\n view.setSearchQuery(event.target.value)\n }\n />\n </div>\n </div>\n <ScrollArea className=\"min-h-0 flex-1\">\n <div\n ref={middleContentRef}\n className=\"flex flex-col gap-[2px] p-3\"\n >\n {view.isLoading ? (\n <Feedback>\n <Spinner size={16} />\n </Feedback>\n ) : view.isSearch ? (\n // 搜索:扁平结果\n view.searchResults.length === 0 ? (\n <Feedback>\n {copy.t(\"referencePicker.emptyDirectory\")}\n </Feedback>\n ) : (\n view.searchResults.map((node) => (\n <SearchResultRow\n key={nodeRefKey(node.ref)}\n focused={isFocused(view.focusedNode, node)}\n node={node}\n selected={view.isSelected(node)}\n onFocus={view.setFocusedNode}\n onToggle={view.toggleSelection}\n />\n ))\n )\n ) : !hasSelectedGroup ? (\n <Feedback>{L.selectGroupHint}</Feedback>\n ) : view.currentEntries.length === 0 ? (\n <Feedback>\n {copy.t(\"referencePicker.emptyDirectory\")}\n </Feedback>\n ) : (\n // 浏览:就地递归展开树(复刻 agent 引用面板文件树交互)\n view.currentEntries.map((node) => (\n <TreeNodeRow\n key={nodeRefKey(node.ref)}\n copy={copy}\n depth={0}\n node={node}\n view={view}\n />\n ))\n )}\n {view.hasMore && hasSelectedGroup && !view.isSearch ? (\n <Button\n className=\"mt-1 w-full\"\n size=\"sm\"\n type=\"button\"\n variant=\"ghost\"\n onClick={view.loadMore}\n >\n {L.loadMore}\n </Button>\n ) : null}\n </div>\n </ScrollArea>\n </div>\n </ResizablePanel>\n <ResizableHandle\n disableDoubleClick\n withHandle\n onDoubleClick={fitMiddle}\n />\n <ResizablePanel\n id=\"preview\"\n className=\"min-h-0 border-l border-[var(--line-1)]\"\n defaultSize={30}\n minSize=\"200px\"\n >\n <PreviewInfoPane\n node={view.focusedNode}\n sourceLabel={view.activeTabLabel}\n hierarchy={view.breadcrumb}\n onReference={view.toggleSelection}\n referenced={\n view.focusedNode ? view.isSelected(view.focusedNode) : false\n }\n />\n </ResizablePanel>\n </ResizablePanelGroup>\n </div>\n </CardContent>\n\n <Footer\n cancelLabel={copy.t(\"actions.cancel\")}\n confirmLabel={copy.t(\"referencePicker.confirm\")}\n countLabel={copy.t(\"referencePicker.selectedCount\", {\n count: view.selectionCount\n })}\n disabled={view.selectionCount === 0}\n loading={view.isConfirming}\n selection={view.selection}\n onClose={onClose}\n onConfirm={() => void view.confirm()}\n />\n </Card>\n </div>\n );\n\n if (typeof document === \"undefined\") {\n return dialog;\n }\n return createPortal(dialog, document.body);\n}\n\n/**\n * 左侧两级分栏(类 macOS Finder 边栏):\n * 一级 = 各引用源(本地/应用/issue),可多源同时展开;二级 = 该源根下的目录分组。\n */\nfunction SourceSidebar({\n view,\n contentRef\n}: {\n view: PickerView;\n contentRef: RefObject<HTMLDivElement | null>;\n}): JSX.Element {\n return (\n <ScrollArea className=\"h-full min-h-0 w-full\">\n <div ref={contentRef} className=\"flex flex-col gap-0.5 p-2\">\n <p className=\"px-2 py-1 text-[11px] font-semibold text-[var(--text-tertiary)]\">\n {L.sourceColumn}\n </p>\n {view.tabs.map((tab) => {\n const active = tab.sourceId === view.activeSourceId;\n const expanded = view.isSourceExpanded(tab.sourceId);\n const groups = view.sidebarGroupsBySource[tab.sourceId] ?? [];\n return (\n <div key={tab.sourceId} className=\"flex flex-col gap-0.5\">\n <button\n aria-expanded={expanded}\n className={cn(\n \"flex items-center gap-1.5 rounded-[6px] px-2 py-1.5 text-left text-[13px] font-semibold transition-colors hover:bg-transparency-block\",\n active\n ? \"text-[var(--text-primary)]\"\n : \"text-[var(--text-secondary)]\"\n )}\n type=\"button\"\n onClick={() => view.toggleSourceExpanded(tab.sourceId)}\n >\n <ArrowRightIcon\n className={cn(\n \"size-3 shrink-0 text-[var(--text-tertiary)] transition-transform\",\n expanded && \"rotate-90\"\n )}\n />\n <span className=\"truncate\" data-autofit-label>\n {tab.label}\n </span>\n </button>\n {expanded ? (\n <div className=\"flex flex-col gap-0.5\">\n {groups.length === 0 ? (\n <p className=\"px-2 py-1.5 pl-7 text-[12px] text-[var(--text-tertiary)]\">\n {view.isLoadingTabs ? \"…\" : \"\"}\n </p>\n ) : (\n groups.map((group) => {\n const key = nodeRefKey(group.ref);\n const selected = key === view.selectedGroupKey;\n return (\n <button\n key={key}\n className={cn(\n \"flex items-center gap-2 rounded-[6px] py-1.5 pr-2 pl-7 text-left text-[13px] transition-colors hover:bg-transparency-block\",\n selected\n ? \"bg-transparency-block text-[var(--text-primary)]\"\n : \"text-[var(--text-secondary)]\"\n )}\n type=\"button\"\n onClick={() => view.selectGroup(group)}\n >\n {group.iconUrl ? (\n <img\n alt=\"\"\n className=\"size-4 shrink-0 rounded-[3px] object-cover\"\n src={group.iconUrl}\n />\n ) : (\n <FolderFilledIcon className=\"size-4 shrink-0 text-[var(--rich-text-folder)]\" />\n )}\n <span\n className=\"min-w-0 flex-1 truncate\"\n data-autofit-label\n >\n {group.displayName}\n </span>\n {group.childCount != null ? (\n <span className=\"shrink-0 text-[11px] text-[var(--text-tertiary)]\">\n {group.childCount}\n </span>\n ) : null}\n </button>\n );\n })\n )}\n </div>\n ) : null}\n </div>\n );\n })}\n </div>\n </ScrollArea>\n );\n}\n\nfunction SearchResultRow({\n node,\n focused,\n selected,\n onFocus,\n onToggle\n}: {\n node: ReferenceNode;\n focused: boolean;\n selected: boolean;\n onFocus: (node: ReferenceNode) => void;\n onToggle: (node: ReferenceNode) => void;\n}): JSX.Element {\n const isFolder = node.kind === \"folder\";\n return (\n <div\n className={cn(\n \"grid grid-cols-[minmax(0,1fr)_auto] items-center gap-3 rounded-[6px] border py-2.5 pr-1 pl-3 transition-colors\",\n focused || selected\n ? \"border-border bg-transparency-block\"\n : \"border-transparent bg-transparent hover:border-border/70 hover:bg-transparency-block\"\n )}\n >\n <button\n className=\"flex min-w-0 items-center gap-3 text-left\"\n type=\"button\"\n onClick={() => onFocus(node)}\n >\n <span className=\"grid size-9 shrink-0 place-items-center rounded-lg bg-[var(--transparency-block)] text-[var(--text-tertiary)]\">\n {isFolder ? (\n <FolderFilledIcon className=\"size-4 text-[var(--rich-text-folder)]\" />\n ) : (\n <FileIcon className=\"size-4 text-[var(--text-tertiary)]\" />\n )}\n </span>\n <span className=\"min-w-0\">\n <span className=\"block truncate text-[13px] font-medium text-[var(--text-primary)]\">\n {node.displayName}\n </span>\n <span className=\"block truncate text-[11px] text-[var(--text-secondary)]\">\n {node.ref.nodeId}\n </span>\n </span>\n </button>\n <Button\n aria-label={node.displayName}\n aria-pressed={selected}\n size=\"icon-sm\"\n type=\"button\"\n variant=\"ghost\"\n onClick={() => {\n onFocus(node);\n onToggle(node);\n }}\n >\n {selected ? (\n <CheckIcon size={14} />\n ) : (\n <AddIcon className=\"text-[var(--text-secondary)]\" size={16} />\n )}\n </Button>\n </div>\n );\n}\n\nfunction PreviewInfoPane({\n node,\n sourceLabel,\n hierarchy,\n referenced,\n onReference\n}: {\n node: ReferenceNode | null;\n sourceLabel: string;\n hierarchy: readonly ReferenceNode[];\n referenced: boolean;\n onReference: (node: ReferenceNode) => void;\n}): JSX.Element {\n return (\n <aside className=\"flex h-full min-h-0 w-full flex-col bg-[var(--background-fronted)]\">\n {node ? (\n <div className=\"flex min-h-0 flex-1 flex-col gap-4 p-4\">\n <div className=\"grid aspect-[3/2] w-full place-items-center rounded-[8px] border border-[var(--line-2,var(--border-2))] bg-[var(--transparency-block)]\">\n <FileIcon className=\"size-9 text-[var(--text-tertiary)]\" />\n </div>\n <p className=\"truncate text-[15px] font-semibold\">\n {node.displayName}\n </p>\n <dl className=\"space-y-2 text-[13px]\">\n <InfoRow label={L.previewSource}>\n <Badge variant=\"secondary\">{sourceLabel}</Badge>\n </InfoRow>\n {node.mtimeMs != null ? (\n <InfoRow label={L.previewModified}>\n {formatDateTime(node.mtimeMs)}\n </InfoRow>\n ) : null}\n {node.sizeBytes != null ? (\n <InfoRow label={L.previewSize}>\n {formatBytes(node.sizeBytes)}\n </InfoRow>\n ) : null}\n </dl>\n {hierarchy.length > 0 ? (\n <div className=\"space-y-1.5\">\n <p className=\"text-[11px] font-semibold text-[var(--text-tertiary)]\">\n {L.previewHierarchy}\n </p>\n <div className=\"flex flex-wrap gap-1\">\n {hierarchy.map((crumb) => (\n <Badge key={nodeRefKey(crumb.ref)} variant=\"secondary\">\n {crumb.displayName}\n </Badge>\n ))}\n </div>\n </div>\n ) : null}\n <div className=\"mt-auto flex justify-end\">\n <Button\n type=\"button\"\n variant={referenced ? \"secondary\" : undefined}\n onClick={() => onReference(node)}\n >\n {L.reference}\n </Button>\n </div>\n </div>\n ) : (\n <Feedback>{L.emptyPreview}</Feedback>\n )}\n </aside>\n );\n}\n\nfunction InfoRow({\n label,\n children\n}: {\n label: string;\n children: ReactNode;\n}): JSX.Element {\n return (\n <div className=\"flex items-center justify-between gap-3\">\n <dt className=\"text-[var(--text-secondary)]\">{label}</dt>\n <dd className=\"min-w-0 truncate text-right text-[var(--text-primary)]\">\n {children}\n </dd>\n </div>\n );\n}\n\nfunction Footer({\n cancelLabel,\n confirmLabel,\n countLabel,\n disabled,\n loading = false,\n selection,\n onClose,\n onConfirm\n}: {\n cancelLabel: string;\n confirmLabel: string;\n countLabel: string;\n disabled: boolean;\n loading?: boolean;\n selection: readonly ReferenceNode[];\n onClose: () => void;\n onConfirm: () => void;\n}): JSX.Element {\n return (\n <div className=\"flex items-center justify-between gap-3 border-t border-[var(--line-1)] px-4 py-3 sm:px-6\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <span className=\"text-[13px] text-[var(--text-secondary)]\">\n {countLabel}\n </span>\n {selection.slice(0, 2).map((node) => (\n <Badge key={nodeRefKey(node.ref)} variant=\"secondary\">\n <span className=\"truncate\">{node.displayName}</span>\n </Badge>\n ))}\n {selection.length > 2 ? (\n <Badge variant=\"secondary\">+{selection.length - 2}</Badge>\n ) : null}\n </div>\n <div className=\"flex items-center gap-2\">\n <Button type=\"button\" variant=\"secondary\" onClick={onClose}>\n {cancelLabel}\n </Button>\n <Button\n disabled={disabled || loading}\n type=\"button\"\n onClick={onConfirm}\n >\n {loading ? <Spinner className=\"text-current\" size={14} /> : null}\n {confirmLabel}\n </Button>\n </div>\n </div>\n );\n}\n\nfunction Feedback({ children }: { children: ReactNode }): JSX.Element {\n return (\n <div className=\"grid min-h-0 flex-1 place-items-center px-4 py-8 text-center text-[13px] text-[var(--text-secondary)]\">\n {children}\n </div>\n );\n}\n\n// 每级缩进 = 箭头列宽(20px)+ 间距(8px)。文件没有箭头列,因此其图标恰好落在\n// 父文件夹图标的正下方;更深层级仍逐级缩进以体现层级关系。\nconst TREE_INDENT = 28;\nconst TREE_COLLAPSE_DURATION_MS = 200;\n\nfunction isFocused(\n focused: ReferenceNode | null,\n node: ReferenceNode\n): boolean {\n return focused ? nodeRefKey(focused.ref) === nodeRefKey(node.ref) : false;\n}\n\n/**\n * 递归文件树节点,交互复刻 main 分支 `WorkspaceFileReferencePickerTreeEntry`:\n * 24px 缩进、folder 箭头旋转、点名称展开/收起、grid-rows 展开动画、add/check 勾选\n * (文件夹与文件都可作为引用选中)。\n */\nfunction TreeNodeRow({\n node,\n depth,\n view,\n copy\n}: {\n node: ReferenceNode;\n depth: number;\n view: PickerView;\n copy: WorkspaceFileReferenceCopy;\n}): JSX.Element {\n const key = nodeRefKey(node.ref);\n const isFolder = node.kind === \"folder\";\n const expanded = view.expandedKeys[key] ?? false;\n const childState = view.childrenByKey[key];\n const childEntries = view.sortNodes(childState?.entries ?? []);\n const selected = view.isSelected(node);\n const focused = isFocused(view.focusedNode, node);\n\n const [shouldRenderChildContent, setShouldRenderChildContent] =\n useState(expanded);\n\n useEffect(() => {\n if (expanded) {\n setShouldRenderChildContent(true);\n return;\n }\n const timeoutId = window.setTimeout(() => {\n setShouldRenderChildContent(false);\n }, TREE_COLLAPSE_DURATION_MS);\n return () => window.clearTimeout(timeoutId);\n }, [expanded]);\n\n const shouldBuildChildContent = expanded || shouldRenderChildContent;\n const childContent = shouldBuildChildContent ? (\n childState?.loading ? (\n <div\n className=\"flex items-center gap-2 px-2 py-2 text-[11px] text-[var(--text-secondary)]\"\n style={{ paddingLeft: `${(depth + 1) * TREE_INDENT + 12}px` }}\n >\n <Spinner className=\"text-[var(--text-secondary)]\" size={14} />\n <span>{copy.t(\"referencePicker.loading\")}</span>\n </div>\n ) : childEntries.length > 0 ? (\n <div className=\"space-y-0.5\">\n {childEntries.map((child) => (\n <TreeNodeRow\n key={nodeRefKey(child.ref)}\n copy={copy}\n depth={depth + 1}\n node={child}\n view={view}\n />\n ))}\n </div>\n ) : childState?.loaded ? (\n <div\n className=\"px-2 py-2 text-[11px] text-[var(--text-secondary)]\"\n style={{ paddingLeft: `${(depth + 1) * TREE_INDENT + 12}px` }}\n >\n {copy.t(\"referencePicker.emptyDirectory\")}\n </div>\n ) : null\n ) : null;\n\n return (\n <div>\n <div\n className={cn(\n \"flex items-center gap-2 rounded-[6px] py-1.5 pr-1 transition-colors\",\n focused || selected\n ? \"bg-transparency-block\"\n : \"hover:bg-transparency-block\"\n )}\n style={{ paddingLeft: `${depth * TREE_INDENT + 8}px` }}\n >\n {isFolder ? (\n <button\n aria-label={node.displayName}\n className=\"grid size-5 shrink-0 place-items-center rounded-sm text-[var(--text-secondary)] hover:bg-[var(--transparency-hover)]\"\n type=\"button\"\n onClick={() => view.toggleNode(node)}\n >\n <ArrowRightIcon\n className={cn(\n \"size-3.5 transition-transform\",\n expanded && \"rotate-90\"\n )}\n />\n </button>\n ) : null}\n <button\n className=\"flex min-w-0 flex-1 items-center gap-2 text-left\"\n type=\"button\"\n onClick={() => {\n view.setFocusedNode(node);\n if (isFolder) {\n view.toggleNode(node);\n }\n }}\n >\n {isFolder ? (\n <FolderFilledIcon className=\"size-4 shrink-0 text-[var(--rich-text-folder)]\" />\n ) : (\n <FileIcon className=\"size-4 shrink-0 text-[var(--text-tertiary)]\" />\n )}\n <span\n className=\"truncate text-[13px] text-[var(--text-primary)]\"\n data-autofit-label\n >\n {node.displayName}\n </span>\n </button>\n <Button\n aria-label={node.displayName}\n aria-pressed={selected}\n className=\"shrink-0\"\n size=\"icon-sm\"\n type=\"button\"\n variant=\"ghost\"\n onClick={() => {\n view.setFocusedNode(node);\n view.toggleSelection(node);\n }}\n >\n {selected ? (\n <CheckIcon size={14} />\n ) : (\n <AddIcon className=\"text-[var(--text-secondary)]\" size={16} />\n )}\n </Button>\n </div>\n {isFolder ? (\n <div\n className={cn(\n \"grid transition-[grid-template-rows] duration-200 ease-out motion-reduce:transition-none\",\n expanded ? \"grid-rows-[1fr]\" : \"grid-rows-[0fr]\",\n childContent && \"mt-[2px]\"\n )}\n >\n <div\n aria-hidden={expanded ? undefined : \"true\"}\n className={cn(\n \"min-h-0 overflow-hidden transition-[opacity,transform] duration-200 ease-out motion-reduce:transition-none\",\n expanded\n ? \"translate-y-0 opacity-100\"\n : \"-translate-y-1 opacity-0\"\n )}\n inert={expanded ? undefined : true}\n >\n {childContent}\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction formatDateTime(ms: number): string {\n const date = new Date(ms);\n const pad = (value: number) => String(value).padStart(2, \"0\");\n return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}`;\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) {\n return `${bytes} B`;\n }\n const units = [\"KB\", \"MB\", \"GB\"];\n let value = bytes / 1024;\n let unitIndex = 0;\n while (value >= 1024 && unitIndex < units.length - 1) {\n value /= 1024;\n unitIndex += 1;\n }\n return `${value.toFixed(1)} ${units[unitIndex]}`;\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useSnapshot } from \"valtio\";\nimport type {\n ReferenceNode,\n ReferenceScope,\n SelectedReference,\n WorkspaceFileReference\n} from \"../../../contracts/index.ts\";\nimport {\n WORKSPACE_ROOT_GROUP_NODE_ID,\n nodeRefKey,\n selectedReferenceToWorkspaceFileReference\n} from \"../../../core/index.ts\";\nimport type { ReferenceSourceAggregator } from \"../../../core/referenceSourceAggregator.ts\";\nimport {\n sortWorkspaceFileEntriesForArrangeMode,\n type WorkspaceFileEntry,\n type WorkspaceFileManagerArrangeMode\n} from \"@tutti-os/workspace-file-manager/services\";\nimport {\n ROOT_CHILDREN_KEY,\n createReferenceSourcePickerController\n} from \"./referenceSourcePickerController.ts\";\n\nexport type { WorkspaceFileManagerArrangeMode };\n\nexport { WORKSPACE_ROOT_GROUP_NODE_ID } from \"../../../core/index.ts\";\n\n/** 本地源「工作区根」二级节点展示名(仅源未自带分组时的回退用)。 */\nconst WORKSPACE_ROOT_GROUP_LABEL = \"工作区\";\n\nexport interface UseReferenceSourcePickerViewInput {\n aggregator: ReferenceSourceAggregator;\n workspaceId: string;\n open: boolean;\n onClose: () => void;\n onConfirm: (refs: WorkspaceFileReference[]) => void;\n}\n\n/**\n * 多源 picker 的视图 hook。\n * controller 负责数据/缓存/分页/选中;hook 负责 UI 导航态(当前面包屑、焦点节点)。\n */\nexport function useReferenceSourcePickerView({\n aggregator,\n workspaceId,\n open,\n onClose,\n onConfirm\n}: UseReferenceSourcePickerViewInput) {\n const readSnapshot = useSnapshot as <T extends object>(store: T) => T;\n const scope = useMemo<ReferenceScope>(() => ({ workspaceId }), [workspaceId]);\n\n const controller = useMemo(\n () => createReferenceSourcePickerController({ aggregator, scope }),\n [aggregator, scope]\n );\n const snapshot = readSnapshot(controller.store);\n\n // UI 导航态:每个源各一条面包屑栈([] = 源根)。\n const [breadcrumbBySource, setBreadcrumbBySource] = useState<\n Record<string, ReferenceNode[]>\n >({});\n const [focusedNode, setFocusedNode] = useState<ReferenceNode | null>(null);\n const [arrangeMode, setArrangeMode] =\n useState<WorkspaceFileManagerArrangeMode>(\"none\");\n // 左栏一级源的展开态(可多源同时展开)。缺省:仅首个 active 源展开(见 seed effect)。\n const [expandedSources, setExpandedSources] = useState<\n Record<string, boolean>\n >({});\n const expandSeededRef = useRef(false);\n\n // 复用 file-manager 的排序能力:把 ReferenceNode 映射成 WorkspaceFileEntry 排序后映射回。\n const sortNodes = useCallback(\n (nodes: readonly ReferenceNode[]): ReferenceNode[] => {\n if (arrangeMode === \"none\") {\n return [...nodes];\n }\n const byKey = new Map<string, ReferenceNode>();\n const fileEntries: WorkspaceFileEntry[] = nodes.map((node) => {\n const key = nodeRefKey(node.ref);\n byKey.set(key, node);\n return {\n hasChildren: node.kind === \"folder\",\n kind: node.kind === \"folder\" ? \"directory\" : \"file\",\n mtimeMs: node.mtimeMs ?? null,\n name: node.displayName,\n path: key,\n sizeBytes: node.sizeBytes ?? null\n };\n });\n return sortWorkspaceFileEntriesForArrangeMode(fileEntries, arrangeMode)\n .map((entry) => byKey.get(entry.path))\n .filter((node): node is ReferenceNode => node !== undefined);\n },\n [arrangeMode]\n );\n // 每次打开对话框内,已自动进入过首个分组的源(避免覆盖用户手动导航/回到根)。\n const autoEnteredSourcesRef = useRef<Set<string>>(new Set());\n\n useEffect(() => {\n if (!open) {\n return;\n }\n controller.reset();\n controller.open();\n setBreadcrumbBySource({});\n setFocusedNode(null);\n setExpandedSources({});\n expandSeededRef.current = false;\n autoEnteredSourcesRef.current = new Set();\n return () => {\n controller.close();\n };\n }, [controller, open]);\n\n const activeSourceId = snapshot.activeSourceId;\n const activeTab = useMemo(\n () => snapshot.tabs.find((tab) => tab.sourceId === activeSourceId) ?? null,\n [activeSourceId, snapshot.tabs]\n );\n const capabilities = activeTab?.capabilities ?? null;\n\n const breadcrumb = activeSourceId\n ? (breadcrumbBySource[activeSourceId] ?? [])\n : [];\n const currentNode = breadcrumb.at(-1) ?? null;\n const currentKey = currentNode\n ? nodeRefKey(currentNode.ref)\n : ROOT_CHILDREN_KEY;\n\n const activeTabState = activeSourceId\n ? snapshot.bySource[activeSourceId]\n : undefined;\n const isSearch =\n activeTabState?.mode === \"search\" &&\n activeTabState.searchQuery.trim() !== \"\";\n\n const currentChildren = activeTabState?.childrenByKey[currentKey];\n\n // 浏览态内容区:当前选中二级节点(currentNode,本地根时为 null → 源根)的子节点,\n // 递归就地展开成文件树。搜索态:扁平搜索结果。\n const currentEntries = useMemo(\n () => sortNodes(currentChildren?.entries ?? []),\n [currentChildren?.entries, sortNodes]\n );\n const searchResults = useMemo(\n () => sortNodes(activeTabState?.searchEntries ?? []),\n [activeTabState?.searchEntries, sortNodes]\n );\n\n // 每个源的左栏二级分组(左栏可多源同时展开,故按源全量计算):\n // - 源自带分组(listSidebarGroups,如本地源的 最近访问/下载/文稿/桌面/个人)优先;\n // - 否则取该源根下的 folder;非 navigable 源额外合成「工作区根」入口保住根级散文件可达。\n // 依赖 snapshot.tabs(getLoadedSource 在 tabs 加载后才有值)与 snapshot.bySource(根加载)。\n const sidebarGroupsBySource = useMemo<Record<string, ReferenceNode[]>>(() => {\n const result: Record<string, ReferenceNode[]> = {};\n for (const tab of snapshot.tabs) {\n const sourceId = tab.sourceId;\n const provided = aggregator\n .getLoadedSource(sourceId)\n ?.listSidebarGroups?.(scope);\n if (provided && provided.length > 0) {\n result[sourceId] = provided;\n continue;\n }\n const root =\n snapshot.bySource[sourceId]?.childrenByKey[ROOT_CHILDREN_KEY];\n const folders = (root?.entries ?? []).filter(\n (node) => node.kind === \"folder\"\n );\n if (tab.capabilities.navigable) {\n result[sourceId] = folders;\n } else {\n const workspaceRoot: ReferenceNode = {\n ref: { sourceId, nodeId: WORKSPACE_ROOT_GROUP_NODE_ID },\n kind: \"folder\",\n displayName: WORKSPACE_ROOT_GROUP_LABEL\n };\n result[sourceId] = [workspaceRoot, ...folders];\n }\n }\n return result;\n }, [snapshot.tabs, snapshot.bySource, aggregator, scope]);\n\n // active 源的二级分组(供自动进入首组、选中高亮等复用)。\n const sidebarGroups = activeSourceId\n ? (sidebarGroupsBySource[activeSourceId] ?? [])\n : [];\n\n // 当前选中的二级分组 key(本地根选中时 = 合成「工作区根」节点的 key)。\n const selectedGroupKey =\n currentNode != null\n ? nodeRefKey(currentNode.ref)\n : activeSourceId && !capabilities?.navigable\n ? nodeRefKey({\n sourceId: activeSourceId,\n nodeId: WORKSPACE_ROOT_GROUP_NODE_ID\n })\n : null;\n\n const setActiveSource = useCallback(\n (sourceId: string) => {\n controller.setActiveSource(sourceId);\n setFocusedNode(null);\n },\n [controller]\n );\n\n const enterFolder = useCallback(\n (node: ReferenceNode) => {\n const sourceId = node.ref.sourceId;\n if (\n node.kind !== \"folder\" ||\n !sourceId ||\n node.ref.nodeId === WORKSPACE_ROOT_GROUP_NODE_ID\n ) {\n return;\n }\n controller.ensureChildren(node);\n setBreadcrumbBySource((current) => {\n const stack = current[sourceId] ?? [];\n const index = stack.findIndex(\n (item) => nodeRefKey(item.ref) === nodeRefKey(node.ref)\n );\n const nextStack =\n index >= 0 ? stack.slice(0, index + 1) : [...stack, node];\n return { ...current, [sourceId]: nextStack };\n });\n setFocusedNode(null);\n },\n [controller]\n );\n\n // 切到可逐层进入的源(如「应用」)时,默认进入第一个分组(app),\n // 而非停在根列表。每个源每次打开只自动选一次,用户回到根/手动导航后不再覆盖。\n useEffect(() => {\n if (!open || !activeSourceId || !capabilities?.navigable) {\n return;\n }\n if (autoEnteredSourcesRef.current.has(activeSourceId)) {\n return;\n }\n const stack = breadcrumbBySource[activeSourceId] ?? [];\n if (stack.length > 0) {\n // 该源已有导航(例如此前已自动/手动进入过),视为已初始化。\n autoEnteredSourcesRef.current.add(activeSourceId);\n return;\n }\n const firstGroup = sidebarGroups[0];\n if (!firstGroup) {\n // 根分组尚未加载完,等加载后再触发。\n return;\n }\n autoEnteredSourcesRef.current.add(activeSourceId);\n enterFolder(firstGroup);\n }, [\n open,\n activeSourceId,\n capabilities?.navigable,\n sidebarGroups,\n breadcrumbBySource,\n enterFolder\n ]);\n\n // 首次有 active 源时,默认展开它(其余源保持收起,用户可再独立展开)。\n useEffect(() => {\n if (!open || expandSeededRef.current || !activeSourceId) {\n return;\n }\n expandSeededRef.current = true;\n setExpandedSources((current) =>\n current[activeSourceId] != null\n ? current\n : { ...current, [activeSourceId]: true }\n );\n }, [open, activeSourceId]);\n\n const navigateToBreadcrumb = useCallback(\n (index: number) => {\n if (!activeSourceId) {\n return;\n }\n setBreadcrumbBySource((current) => {\n const stack = current[activeSourceId] ?? [];\n return { ...current, [activeSourceId]: stack.slice(0, index + 1) };\n });\n const target = (breadcrumbBySource[activeSourceId] ?? [])[index] ?? null;\n controller.ensureChildren(target);\n setFocusedNode(null);\n },\n [activeSourceId, breadcrumbBySource, controller]\n );\n\n const navigateToRoot = useCallback(\n (sourceId?: string) => {\n const sid = sourceId ?? activeSourceId;\n if (!sid) {\n return;\n }\n setBreadcrumbBySource((current) => ({ ...current, [sid]: [] }));\n controller.ensureSourceRoot(sid);\n setFocusedNode(null);\n },\n [activeSourceId, controller]\n );\n\n // 选中左栏二级分组:先切到该分组所属源(右侧内容随之切换),\n // 再:合成「工作区根」→ 回源根;其余 → 进入该目录。\n const selectGroup = useCallback(\n (node: ReferenceNode) => {\n const sourceId = node.ref.sourceId;\n if (!sourceId) {\n return;\n }\n if (sourceId !== snapshot.activeSourceId) {\n controller.setActiveSource(sourceId);\n }\n if (node.ref.nodeId === WORKSPACE_ROOT_GROUP_NODE_ID) {\n navigateToRoot(sourceId);\n return;\n }\n enterFolder(node);\n },\n [controller, snapshot.activeSourceId, enterFolder, navigateToRoot]\n );\n\n // 一级源展开态:缺省仅 active 源展开(seed effect);其余可独立切换、同时展开。\n const isSourceExpanded = useCallback(\n (sourceId: string) => expandedSources[sourceId] ?? false,\n [expandedSources]\n );\n\n const toggleSourceExpanded = useCallback(\n (sourceId: string) => {\n const willExpand = !(expandedSources[sourceId] ?? false);\n setExpandedSources((current) => ({\n ...current,\n [sourceId]: !(current[sourceId] ?? false)\n }));\n // 展开非自带分组的源时预载其根,以便其二级分组就绪。\n if (\n willExpand &&\n !aggregator.getLoadedSource(sourceId)?.listSidebarGroups\n ) {\n controller.ensureSourceRoot(sourceId);\n }\n },\n [aggregator, controller, expandedSources]\n );\n\n const isSelected = useCallback(\n (node: ReferenceNode) =>\n snapshot.selection.some(\n (item) => nodeRefKey(item.ref) === nodeRefKey(node.ref)\n ),\n [snapshot.selection]\n );\n\n // app/issue 源的文件夹引用需异步递归枚举展开,故 confirm 异步;期间置 isConfirming 防重复提交。\n const [isConfirming, setIsConfirming] = useState(false);\n const confirm = useCallback(async () => {\n if (isConfirming) {\n return;\n }\n setIsConfirming(true);\n try {\n const selected: SelectedReference[] = await controller.confirm();\n onConfirm(selected.map(selectedReferenceToWorkspaceFileReference));\n onClose();\n } finally {\n setIsConfirming(false);\n }\n }, [controller, isConfirming, onClose, onConfirm]);\n\n return {\n tabs: snapshot.tabs,\n activeSourceId,\n activeTabLabel: activeTab?.label ?? \"\",\n capabilities,\n // 内容区递归就地树:当前选中二级节点的子条目(本地根时为源根子条目)。\n currentEntries,\n // 搜索态:扁平搜索结果。\n searchResults,\n expandedKeys: activeTabState?.expandedKeys ?? {},\n childrenByKey: activeTabState?.childrenByKey ?? {},\n toggleNode: (node: ReferenceNode) => controller.toggleNode(node),\n sortNodes,\n isLoadingTabs: snapshot.isLoadingTabs,\n breadcrumb,\n currentNode,\n sidebarGroups,\n sidebarGroupsBySource,\n isSourceExpanded,\n toggleSourceExpanded,\n selectedGroupKey,\n arrangeMode,\n setArrangeMode,\n isSearch,\n searchQuery: activeTabState?.searchQuery ?? \"\",\n isLoading: isSearch\n ? (activeTabState?.isSearchLoading ?? false)\n : (currentChildren?.loading ?? false),\n hasMore: !isSearch && Boolean(currentChildren?.nextCursor),\n focusedNode,\n selection: snapshot.selection,\n selectionCount: snapshot.selection.length,\n setActiveSource,\n enterFolder,\n selectGroup,\n navigateToBreadcrumb,\n navigateToRoot,\n setFocusedNode,\n setSearchQuery: (query: string) => controller.setSearchQuery(query),\n toggleSelection: (node: ReferenceNode) => controller.toggleSelection(node),\n loadMore: () => controller.loadMore(currentNode),\n isSelected,\n confirm,\n isConfirming\n };\n}\n"],"mappings":"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","names":["Button","cn","Button","FileIcon","FolderFilledIcon","jsx","jsxs","WorkspaceFileReferencePickerFeedback","FolderFilledIcon","FileIcon","Button","jsx","jsxs","cn","Button","useEffect","useId","useRef","useState","createPortal","ArrowRightIcon","Badge","Button","Card","CardContent","CardHeader","CardTitle","CheckIcon","CloseIcon","FileIcon","FolderFilledIcon","Input","ScrollArea","SearchIcon","Spinner","cn","useEffect","useState","useState","useEffect","jsx","jsxs","useId","useRef","Card","CardHeader","CardTitle","Button","CloseIcon","CardContent","SearchIcon","Input","ScrollArea","Spinner","createPortal","cn","ArrowRightIcon","FolderFilledIcon","FileIcon","CheckIcon","Badge","useState","useEffect"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tutti-os/workspace-file-reference",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.14",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -36,9 +36,10 @@
|
|
|
36
36
|
"directory": "packages/workspace/file-reference"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@tutti-os/ui-react-hooks": "0.0.
|
|
40
|
-
"@tutti-os/ui-system": "0.0.
|
|
41
|
-
"@tutti-os/workspace-file-
|
|
39
|
+
"@tutti-os/ui-react-hooks": "0.0.14",
|
|
40
|
+
"@tutti-os/ui-system": "0.0.14",
|
|
41
|
+
"@tutti-os/workspace-file-manager": "0.0.14",
|
|
42
|
+
"@tutti-os/workspace-file-preview": "0.0.14",
|
|
42
43
|
"valtio": "^2.3.2"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react/internal/reference/WorkspaceFileReferencePickerState.ts","../src/react/internal/reference/useWorkspaceFileReferencePickerView.ts","../src/react/internal/reference/WorkspaceFileReferencePickerController.ts"],"sourcesContent":["import type {\n WorkspaceFileReference,\n WorkspaceFileReferencePrefetchReason,\n WorkspaceFileReferencePrefetchState,\n WorkspaceFileReferenceTreeSnapshot\n} from \"../../../contracts/index.ts\";\n\nexport const workspaceFileReferenceDefaultExpandedDepth = 4;\n\nexport interface WorkspaceFileReferenceDirectoryState {\n displayPath: string;\n entries: WorkspaceFileReference[];\n loaded: boolean;\n loading: boolean;\n prefetchReason?: WorkspaceFileReferencePrefetchReason | null;\n prefetchState?: WorkspaceFileReferencePrefetchState | null;\n}\n\nexport function normalizeDirectoryPath(path: string): string {\n if (!path || path === \"/\") {\n return \"/\";\n }\n return path.replace(/\\/+$/, \"\") || \"/\";\n}\n\nexport function collectVisibleTreeEntries(\n entries: readonly WorkspaceFileReference[],\n directoryStateByPath: Record<string, WorkspaceFileReferenceDirectoryState>,\n expandedFolderPaths: Record<string, boolean>\n): WorkspaceFileReference[] {\n const collected: WorkspaceFileReference[] = [];\n\n for (const entry of entries) {\n collected.push(entry);\n if (entry.kind !== \"folder\") {\n continue;\n }\n const folderKey = normalizeDirectoryPath(entry.path);\n if (!expandedFolderPaths[folderKey]) {\n continue;\n }\n const childEntries = directoryStateByPath[folderKey]?.entries ?? [];\n if (childEntries.length === 0) {\n continue;\n }\n collected.push(\n ...collectVisibleTreeEntries(\n childEntries,\n directoryStateByPath,\n expandedFolderPaths\n )\n );\n }\n\n return collected;\n}\n\nexport function mergeExpandedFolderPaths(\n current: Record<string, boolean>,\n prefetched: Record<string, boolean>\n): Record<string, boolean> {\n return {\n ...prefetched,\n ...current\n };\n}\n\nexport function mergePrefetchedDirectoryState(\n current: Record<string, WorkspaceFileReferenceDirectoryState>,\n prefetched: Record<string, WorkspaceFileReferenceDirectoryState>\n): Record<string, WorkspaceFileReferenceDirectoryState> {\n return {\n ...current,\n ...prefetched\n };\n}\n\nexport function createWorkspaceFileReferenceDirectoryStateFromSnapshot(\n snapshot: WorkspaceFileReferenceTreeSnapshot\n): Record<string, WorkspaceFileReferenceDirectoryState> {\n const stateByPath: Record<string, WorkspaceFileReferenceDirectoryState> = {};\n addReferenceDirectoryStateFromSnapshot(stateByPath, snapshot.directory);\n return stateByPath;\n}\n\nfunction addReferenceDirectoryStateFromSnapshot(\n stateByPath: Record<string, WorkspaceFileReferenceDirectoryState>,\n directory: WorkspaceFileReferenceTreeSnapshot[\"directory\"]\n) {\n const normalizedPath = normalizeDirectoryPath(directory.directoryPath);\n stateByPath[normalizedPath] = {\n displayPath: directory.directoryPath,\n entries: directory.entries.map((entry) => ({\n displayName: entry.displayName,\n kind: entry.kind,\n path: entry.path\n })),\n loaded: true,\n loading: false,\n prefetchReason: directory.prefetchReason,\n prefetchState: directory.prefetchState\n };\n\n for (const entry of directory.entries) {\n if (entry.kind !== \"folder\") {\n continue;\n }\n const folderKey = normalizeDirectoryPath(entry.path);\n if (entry.prefetchedDirectory) {\n addReferenceDirectoryStateFromSnapshot(\n stateByPath,\n entry.prefetchedDirectory\n );\n continue;\n }\n if (entry.prefetchState) {\n stateByPath[folderKey] = {\n displayPath: entry.path,\n entries: [],\n loaded: false,\n loading: false,\n prefetchReason: entry.prefetchReason,\n prefetchState: entry.prefetchState\n };\n }\n }\n}\n\nexport async function prefetchReferenceTree(input: {\n listDirectory: (path: string) => Promise<{\n displayPath: string;\n entries: WorkspaceFileReference[];\n normalizedPath: string;\n } | null>;\n maxDepth: number;\n path: string;\n depth?: number;\n}): Promise<{\n directoryStateByPath: Record<string, WorkspaceFileReferenceDirectoryState>;\n expandedFolderPaths: Record<string, boolean>;\n}> {\n const { depth = 1, listDirectory, maxDepth, path } = input;\n const listing = await listDirectory(path);\n if (!listing) {\n return {\n directoryStateByPath: {},\n expandedFolderPaths: {}\n };\n }\n\n const directoryStateByPath: Record<\n string,\n WorkspaceFileReferenceDirectoryState\n > = {\n [listing.normalizedPath]: {\n displayPath: listing.displayPath,\n entries: listing.entries,\n loaded: true,\n loading: false\n }\n };\n const expandedFolderPaths: Record<string, boolean> = {\n [listing.normalizedPath]: true\n };\n\n if (depth >= maxDepth) {\n return {\n directoryStateByPath,\n expandedFolderPaths\n };\n }\n\n for (const entry of listing.entries) {\n if (entry.kind !== \"folder\") {\n continue;\n }\n try {\n const childTree = await prefetchReferenceTree({\n depth: depth + 1,\n listDirectory,\n maxDepth,\n path: entry.path\n });\n Object.assign(directoryStateByPath, childTree.directoryStateByPath);\n Object.assign(expandedFolderPaths, childTree.expandedFolderPaths);\n } catch {\n // Skip unreadable branches so one protected folder does not blank the whole tree.\n }\n }\n\n return {\n directoryStateByPath,\n expandedFolderPaths\n };\n}\n","import {\n useCallback,\n useEffect,\n useEffectEvent,\n useMemo,\n useState\n} from \"react\";\nimport { useSnapshot } from \"valtio\";\nimport type {\n WorkspaceFileReferenceAdapter,\n WorkspaceFileReference\n} from \"../../../contracts/index.ts\";\nimport { uniqueWorkspaceFileReferences } from \"../../../core/index.ts\";\nimport {\n collectVisibleTreeEntries,\n normalizeDirectoryPath\n} from \"./WorkspaceFileReferencePickerState.ts\";\nimport {\n createWorkspaceFileReferencePickerController,\n type WorkspaceFileReferencePreviewState\n} from \"./WorkspaceFileReferencePickerController.ts\";\n\nexport type { WorkspaceFileReferencePreviewState };\n\nexport interface UseWorkspaceFileReferencePickerViewInput {\n fileAdapter?: WorkspaceFileReferenceAdapter;\n initialPath?: string | null;\n onClose: () => void;\n onConfirm: (refs: WorkspaceFileReference[]) => void;\n open: boolean;\n workspaceId: string;\n}\n\nexport function useWorkspaceFileReferencePickerView({\n fileAdapter,\n initialPath,\n onClose,\n onConfirm,\n open,\n workspaceId\n}: UseWorkspaceFileReferencePickerViewInput) {\n const readPickerSnapshot = useSnapshot as <T extends object>(store: T) => T;\n const trimmedInitialPath = initialPath?.trim() ?? \"\";\n const initialDirectoryPath = trimmedInitialPath\n ? normalizeDirectoryPath(trimmedInitialPath)\n : null;\n const [focusedPath, setFocusedPath] = useState<string | null>(null);\n const [selectedRefs, setSelectedRefs] = useState<WorkspaceFileReference[]>(\n []\n );\n\n const pickerController = useMemo(\n () =>\n createWorkspaceFileReferencePickerController({\n fileAdapter,\n workspaceId\n }),\n [fileAdapter, workspaceId]\n );\n const pickerSnapshot = readPickerSnapshot(pickerController.store);\n const {\n browseRootPath,\n directoryStateByPath,\n expandedFolderPaths,\n isBrowseLoading,\n isSearchLoading,\n mode,\n previewState,\n searchEntries,\n searchQuery\n } = pickerSnapshot;\n const isLoading = mode === \"search\" ? isSearchLoading : isBrowseLoading;\n\n const finalizeRequestedReferences = useEffectEvent(\n (refs: WorkspaceFileReference[]) => {\n onConfirm(uniqueWorkspaceFileReferences(refs));\n onClose();\n }\n );\n\n const setSearchQuery = useCallback(\n (query: string) => {\n pickerController.setSearchQuery(query);\n },\n [pickerController]\n );\n\n useEffect(() => {\n if (!open) {\n return;\n }\n\n pickerController.reset();\n pickerController.open();\n setFocusedPath(null);\n setSelectedRefs([]);\n return () => {\n pickerController.close();\n };\n }, [initialDirectoryPath, open, pickerController]);\n\n useEffect(() => {\n if (!open || mode !== \"browse\") {\n return;\n }\n pickerController.loadBrowseRoot();\n }, [mode, open, pickerController]);\n\n useEffect(() => {\n if (!open || !fileAdapter || mode !== \"browse\") {\n return;\n }\n if (\n fileAdapter.listDirectory ||\n fileAdapter.loadReferenceTree ||\n !fileAdapter.requestReferences\n ) {\n return;\n }\n let canceled = false;\n void fileAdapter.requestReferences({ workspaceId }).then((refs) => {\n if (!canceled) {\n finalizeRequestedReferences(refs);\n }\n });\n return () => {\n canceled = true;\n };\n }, [fileAdapter, finalizeRequestedReferences, mode, open, workspaceId]);\n\n useEffect(() => {\n if (\n !open ||\n mode !== \"browse\" ||\n pickerSnapshot.initialPathRevealed ||\n !initialDirectoryPath ||\n !browseRootPath\n ) {\n return;\n }\n\n let canceled = false;\n const reveal = async () => {\n const focusedInitialPath =\n await pickerController.revealInitialPath(initialDirectoryPath);\n if (!canceled && focusedInitialPath) {\n setFocusedPath(focusedInitialPath);\n }\n };\n\n void reveal();\n return () => {\n canceled = true;\n };\n }, [\n browseRootPath,\n initialDirectoryPath,\n mode,\n open,\n pickerController,\n pickerSnapshot.initialPathRevealed\n ]);\n\n const browseRootEntries = useMemo(\n () =>\n browseRootPath\n ? (directoryStateByPath[normalizeDirectoryPath(browseRootPath)]\n ?.entries ?? [])\n : [],\n [browseRootPath, directoryStateByPath]\n );\n\n const visibleEntries = useMemo(\n () =>\n mode === \"search\"\n ? searchEntries\n : collectVisibleTreeEntries(\n browseRootEntries,\n directoryStateByPath,\n expandedFolderPaths\n ),\n [\n browseRootEntries,\n directoryStateByPath,\n expandedFolderPaths,\n mode,\n searchEntries\n ]\n );\n\n useEffect(() => {\n if (!open) {\n return;\n }\n setFocusedPath((current) => {\n if (current && visibleEntries.some((entry) => entry.path === current)) {\n return current;\n }\n return visibleEntries[0]?.path ?? null;\n });\n }, [open, visibleEntries]);\n\n const focusedEntry =\n visibleEntries.find((entry) => entry.path === focusedPath) ??\n selectedRefs.find((entry) => entry.path === focusedPath) ??\n null;\n\n useEffect(() => {\n pickerController.setPreviewReference(open ? focusedEntry : null);\n }, [focusedEntry, open, pickerController]);\n\n const toggleRef = (ref: WorkspaceFileReference) => {\n setSelectedRefs((current) => {\n const existing = current.some((item) => item.path === ref.path);\n return existing\n ? current.filter((item) => item.path !== ref.path)\n : uniqueWorkspaceFileReferences([...current, ref]);\n });\n };\n\n const toggleFolder = (entry: WorkspaceFileReference) => {\n pickerController.toggleFolder(entry);\n };\n\n return {\n browseRootEntries,\n directoryStateByPath,\n expandedFolderPaths,\n focusedEntry,\n focusedPath,\n isLoading,\n mode,\n previewState,\n searchQuery,\n selectedRefs,\n visibleEntries,\n setFocusedPath,\n setSearchQuery,\n toggleFolder,\n toggleRef\n };\n}\n","import { proxy } from \"valtio/vanilla\";\nimport {\n createWorkspaceFilePreviewLoadedState,\n resolveWorkspaceFilePreviewReadiness\n} from \"@tutti-os/workspace-file-preview\";\nimport type {\n WorkspaceFilePreviewActivationTarget,\n WorkspaceFilePreviewReadonlyReason\n} from \"@tutti-os/workspace-file-preview\";\nimport type {\n WorkspaceFileReference,\n WorkspaceFileReferenceAdapter,\n WorkspaceFileReferencePreview\n} from \"../../../contracts/index.ts\";\nimport { uniqueWorkspaceFileReferences } from \"../../../core/index.ts\";\nimport {\n createWorkspaceFileReferenceDirectoryStateFromSnapshot,\n normalizeDirectoryPath,\n type WorkspaceFileReferenceDirectoryState\n} from \"./WorkspaceFileReferencePickerState.ts\";\n\nexport type WorkspaceFileReferencePickerMode = \"browse\" | \"search\";\n\nexport type WorkspaceFileReferencePreviewState =\n | { status: \"directory\"; reference: WorkspaceFileReference }\n | { status: \"empty\" }\n | { status: \"error\"; reference: WorkspaceFileReference }\n | { status: \"image\"; objectUrl: string; reference: WorkspaceFileReference }\n | { status: \"loading\"; reference: WorkspaceFileReference }\n | {\n maxSizeBytes?: number;\n reason: WorkspaceFilePreviewReadonlyReason;\n reference: WorkspaceFileReference;\n status: \"readonly\";\n }\n | { status: \"text\"; content: string; reference: WorkspaceFileReference }\n | { status: \"unsupported\"; reference: WorkspaceFileReference }\n | { status: \"unavailable\"; reference: WorkspaceFileReference };\n\nexport interface WorkspaceFileReferencePickerControllerSnapshot {\n browseError: Error | null;\n browseRootPath: string | null;\n directoryStateByPath: Record<string, WorkspaceFileReferenceDirectoryState>;\n expandedFolderPaths: Record<string, boolean>;\n initialPathRevealed: boolean;\n isBrowseLoading: boolean;\n isSearchLoading: boolean;\n mode: WorkspaceFileReferencePickerMode;\n previewState: WorkspaceFileReferencePreviewState;\n searchEntries: WorkspaceFileReference[];\n searchError: Error | null;\n searchQuery: string;\n}\n\nexport interface CreateWorkspaceFileReferencePickerControllerInput {\n fileAdapter?: WorkspaceFileReferenceAdapter;\n searchDebounceMs?: number;\n workspaceId: string;\n}\n\nexport interface WorkspaceFileReferencePickerController {\n close(): void;\n getSnapshot(): WorkspaceFileReferencePickerControllerSnapshot;\n loadBrowseRoot(): void;\n open(): void;\n reset(): void;\n revealInitialPath(initialDirectoryPath: string): Promise<string | null>;\n setPreviewReference(reference: WorkspaceFileReference | null): void;\n setSearchQuery(query: string): void;\n readonly store: WorkspaceFileReferencePickerControllerSnapshot;\n toggleFolder(entry: WorkspaceFileReference): void;\n}\n\nconst defaultDirectoryPath = \"/\";\nconst defaultSearchDebounceMs = 180;\n\nexport function createWorkspaceFileReferencePickerController(\n input: CreateWorkspaceFileReferencePickerControllerInput\n): WorkspaceFileReferencePickerController {\n const searchDebounceMs = input.searchDebounceMs ?? defaultSearchDebounceMs;\n let browseSequence = 0;\n let previewObjectUrl: string | null = null;\n let previewSequence = 0;\n let retained = false;\n let searchAbortController: AbortController | null = null;\n let searchSequence = 0;\n let searchTimer: ReturnType<typeof setTimeout> | null = null;\n let snapshot: WorkspaceFileReferencePickerControllerSnapshot = {\n browseError: null,\n browseRootPath: null,\n directoryStateByPath: {},\n expandedFolderPaths: {},\n initialPathRevealed: false,\n isBrowseLoading: false,\n isSearchLoading: false,\n mode: \"browse\",\n previewState: { status: \"empty\" },\n searchEntries: [],\n searchError: null,\n searchQuery: \"\"\n };\n const store = proxy(snapshot);\n\n const setSnapshot = (\n update:\n | Partial<WorkspaceFileReferencePickerControllerSnapshot>\n | ((\n current: WorkspaceFileReferencePickerControllerSnapshot\n ) => WorkspaceFileReferencePickerControllerSnapshot)\n ) => {\n const next =\n typeof update === \"function\"\n ? update(snapshot)\n : { ...snapshot, ...update };\n if (next === snapshot) {\n return;\n }\n snapshot = next;\n Object.assign(store, next);\n };\n\n const loadDirectoryListing = async (path?: string | null) => {\n if (!input.fileAdapter?.listDirectory) {\n return null;\n }\n const listing = await input.fileAdapter.listDirectory({\n path: path ?? undefined,\n workspaceId: input.workspaceId\n });\n const displayPath =\n listing.directoryPath || listing.rootPath || path || defaultDirectoryPath;\n const normalizedPath = normalizeDirectoryPath(displayPath);\n\n return {\n displayPath,\n entries: uniqueWorkspaceFileReferences(listing.entries),\n normalizedPath\n };\n };\n\n const resolveMode = (query: string) =>\n query.trim().length > 0 && input.fileAdapter?.searchReferences\n ? \"search\"\n : \"browse\";\n\n const clearSearchTimer = () => {\n if (searchTimer === null) {\n return;\n }\n clearTimeout(searchTimer);\n searchTimer = null;\n };\n\n const cancelCurrentSearch = () => {\n clearSearchTimer();\n searchSequence += 1;\n searchAbortController?.abort();\n searchAbortController = null;\n };\n\n const cancelCurrentBrowse = () => {\n browseSequence += 1;\n };\n\n const cancelCurrentPreview = () => {\n previewSequence += 1;\n if (!previewObjectUrl) {\n return;\n }\n URL.revokeObjectURL(previewObjectUrl);\n previewObjectUrl = null;\n };\n\n const clearSearchResults = () => {\n cancelCurrentSearch();\n setSnapshot({\n isSearchLoading: false,\n searchEntries: [],\n searchError: null\n });\n };\n\n const runSearch = async (query: string) => {\n if (!retained || !input.fileAdapter?.searchReferences) {\n return;\n }\n\n const sequence = ++searchSequence;\n searchAbortController?.abort();\n const abortController = new AbortController();\n searchAbortController = abortController;\n setSnapshot({\n isSearchLoading: true,\n searchError: null\n });\n\n try {\n const refs = await input.fileAdapter.searchReferences({\n query,\n signal: abortController.signal,\n workspaceId: input.workspaceId\n });\n if (!retained || sequence !== searchSequence) {\n return;\n }\n setSnapshot({\n isSearchLoading: false,\n searchEntries: uniqueWorkspaceFileReferences(refs),\n searchError: null\n });\n } catch (error) {\n if (isAbortError(error) || sequence !== searchSequence || !retained) {\n return;\n }\n setSnapshot({\n isSearchLoading: false,\n searchEntries: [],\n searchError: normalizeControllerError(\n error,\n \"Workspace file reference search failed\"\n )\n });\n } finally {\n if (sequence === searchSequence) {\n searchAbortController = null;\n }\n }\n };\n\n const scheduleSearch = () => {\n clearSearchTimer();\n const query = snapshot.searchQuery.trim();\n if (!retained || !input.fileAdapter?.searchReferences || !query) {\n clearSearchResults();\n return;\n }\n\n if (searchDebounceMs <= 0) {\n void runSearch(query);\n return;\n }\n\n searchTimer = setTimeout(() => {\n searchTimer = null;\n void runSearch(query);\n }, searchDebounceMs);\n };\n\n const loadBrowseRoot = async () => {\n if (\n !retained ||\n snapshot.mode !== \"browse\" ||\n !(\n input.fileAdapter?.listDirectory || input.fileAdapter?.loadReferenceTree\n )\n ) {\n return;\n }\n const activeBrowseRootPath = snapshot.browseRootPath;\n const normalizedRoot = activeBrowseRootPath\n ? normalizeDirectoryPath(activeBrowseRootPath)\n : null;\n if (\n normalizedRoot &&\n snapshot.directoryStateByPath[normalizedRoot]?.loaded\n ) {\n return;\n }\n\n const sequence = ++browseSequence;\n setSnapshot({\n browseError: null,\n isBrowseLoading: true\n });\n\n try {\n if (input.fileAdapter.loadReferenceTree) {\n const treeSnapshot = await input.fileAdapter.loadReferenceTree({\n path: activeBrowseRootPath ?? undefined,\n prefetchBudgetMs: 500,\n prefetchDepth: 4,\n workspaceId: input.workspaceId\n });\n if (!retained || sequence !== browseSequence) {\n return;\n }\n setSnapshot({\n browseRootPath: normalizeDirectoryPath(\n treeSnapshot.directory.directoryPath\n ),\n directoryStateByPath:\n createWorkspaceFileReferenceDirectoryStateFromSnapshot(\n treeSnapshot\n ),\n isBrowseLoading: false\n });\n return;\n }\n\n const listing = await loadDirectoryListing(activeBrowseRootPath);\n if (!retained || sequence !== browseSequence || !listing) {\n return;\n }\n setSnapshot((current) => ({\n ...current,\n browseRootPath: listing.normalizedPath,\n directoryStateByPath: {\n ...current.directoryStateByPath,\n [listing.normalizedPath]: {\n displayPath: listing.displayPath,\n entries: listing.entries,\n loaded: true,\n loading: false\n }\n },\n isBrowseLoading: false\n }));\n } catch (error) {\n if (!retained || sequence !== browseSequence) {\n return;\n }\n setSnapshot({\n browseError: normalizeControllerError(\n error,\n \"Workspace file reference browse failed\"\n ),\n isBrowseLoading: false\n });\n }\n };\n\n const loadFolderChildren = async (folder: WorkspaceFileReference) => {\n const folderKey = normalizeDirectoryPath(folder.path);\n if (\n !retained ||\n snapshot.directoryStateByPath[folderKey]?.loaded ||\n snapshot.directoryStateByPath[folderKey]?.loading\n ) {\n return;\n }\n\n const sequence = ++browseSequence;\n setSnapshot((current) => ({\n ...current,\n directoryStateByPath: {\n ...current.directoryStateByPath,\n [folderKey]: {\n displayPath: folder.path,\n entries: current.directoryStateByPath[folderKey]?.entries ?? [],\n loaded: current.directoryStateByPath[folderKey]?.loaded ?? false,\n loading: true\n }\n }\n }));\n\n try {\n const listing = await loadDirectoryListing(folderKey);\n if (!retained || sequence !== browseSequence || !listing) {\n return;\n }\n setSnapshot((current) => ({\n ...current,\n directoryStateByPath: {\n ...current.directoryStateByPath,\n [folderKey]: {\n displayPath: listing.displayPath,\n entries: listing.entries,\n loaded: true,\n loading: false\n }\n }\n }));\n } catch {\n if (!retained || sequence !== browseSequence) {\n return;\n }\n setSnapshot((current) => ({\n ...current,\n directoryStateByPath: {\n ...current.directoryStateByPath,\n [folderKey]: {\n displayPath:\n current.directoryStateByPath[folderKey]?.displayPath ??\n folder.path,\n entries: current.directoryStateByPath[folderKey]?.entries ?? [],\n loaded: current.directoryStateByPath[folderKey]?.loaded ?? false,\n loading: false\n }\n }\n }));\n }\n };\n\n const loadReferencePreview = async (\n reference: WorkspaceFileReference,\n target: WorkspaceFilePreviewActivationTarget,\n sequence: number\n ) => {\n try {\n const preview = await input.fileAdapter?.readReferencePreview?.({\n reference,\n workspaceId: input.workspaceId\n });\n if (!retained || sequence !== previewSequence) {\n return;\n }\n if (!preview) {\n setSnapshot({\n previewState: { reference, status: \"unsupported\" }\n });\n return;\n }\n\n const nextState = createReferencePreviewState(reference, target, preview);\n if (!retained || sequence !== previewSequence) {\n if (nextState.status === \"image\") {\n URL.revokeObjectURL(nextState.objectUrl);\n }\n return;\n }\n if (nextState.status === \"image\") {\n previewObjectUrl = nextState.objectUrl;\n }\n setSnapshot({\n previewState: nextState\n });\n } catch {\n if (!retained || sequence !== previewSequence) {\n return;\n }\n setSnapshot({\n previewState: { reference, status: \"error\" }\n });\n }\n };\n\n const setPreviewReference = (reference: WorkspaceFileReference | null) => {\n cancelCurrentPreview();\n if (!retained || !reference) {\n setSnapshot({\n previewState: { status: \"empty\" }\n });\n return;\n }\n\n const readiness = resolveWorkspaceFilePreviewReadiness(reference);\n if (readiness.status === \"directory\") {\n setSnapshot({\n previewState: { reference, status: \"directory\" }\n });\n return;\n }\n if (readiness.status === \"unsupported\") {\n setSnapshot({\n previewState: { reference, status: \"unsupported\" }\n });\n return;\n }\n if (readiness.status === \"readonly\") {\n setSnapshot({\n previewState: {\n maxSizeBytes: readiness.maxSizeBytes,\n reason: readiness.reason,\n reference,\n status: \"readonly\"\n }\n });\n return;\n }\n\n if (!input.fileAdapter?.readReferencePreview) {\n setSnapshot({\n previewState: { reference, status: \"unavailable\" }\n });\n return;\n }\n\n const sequence = ++previewSequence;\n setSnapshot({\n previewState: { reference, status: \"loading\" }\n });\n void loadReferencePreview(reference, readiness.target, sequence);\n };\n\n return {\n close() {\n retained = false;\n cancelCurrentBrowse();\n cancelCurrentPreview();\n cancelCurrentSearch();\n setSnapshot({\n isBrowseLoading: false,\n isSearchLoading: false,\n previewState: { status: \"empty\" }\n });\n },\n getSnapshot() {\n return snapshot;\n },\n loadBrowseRoot() {\n void loadBrowseRoot();\n },\n open() {\n if (retained) {\n return;\n }\n retained = true;\n if (snapshot.mode === \"search\") {\n scheduleSearch();\n return;\n }\n void loadBrowseRoot();\n },\n async revealInitialPath(initialDirectoryPath) {\n if (\n !retained ||\n snapshot.mode !== \"browse\" ||\n snapshot.initialPathRevealed ||\n !snapshot.browseRootPath\n ) {\n return null;\n }\n\n const rootPath = normalizeDirectoryPath(snapshot.browseRootPath);\n if (!isPathInsideOrEqual(initialDirectoryPath, rootPath)) {\n setSnapshot({\n initialPathRevealed: true\n });\n return null;\n }\n\n const sequence = ++browseSequence;\n const loadedDirectories: Record<\n string,\n WorkspaceFileReferenceDirectoryState\n > = {};\n const expandedDirectories: Record<string, boolean> = {};\n const directoryState = (path: string) =>\n loadedDirectories[path] ?? snapshot.directoryStateByPath[path];\n\n const directoryPaths = directoryChainBetween(\n rootPath,\n initialDirectoryPath\n );\n for (const directoryPath of directoryPaths) {\n expandedDirectories[directoryPath] = true;\n }\n\n const listings = await Promise.all(\n directoryPaths\n .filter((directoryPath) => !directoryState(directoryPath)?.loaded)\n .map(async (directoryPath) => {\n try {\n return await loadDirectoryListing(directoryPath);\n } catch {\n return null;\n }\n })\n );\n\n for (const listing of listings) {\n if (!listing) {\n continue;\n }\n loadedDirectories[listing.normalizedPath] = {\n displayPath: listing.displayPath,\n entries: listing.entries,\n loaded: true,\n loading: false\n };\n }\n\n if (!retained || sequence !== browseSequence) {\n return null;\n }\n setSnapshot((current) => ({\n ...current,\n directoryStateByPath: {\n ...current.directoryStateByPath,\n ...loadedDirectories\n },\n expandedFolderPaths: {\n ...current.expandedFolderPaths,\n ...expandedDirectories\n },\n initialPathRevealed: true\n }));\n return initialDirectoryPath;\n },\n reset() {\n cancelCurrentBrowse();\n cancelCurrentPreview();\n cancelCurrentSearch();\n setSnapshot({\n browseError: null,\n browseRootPath: null,\n directoryStateByPath: {},\n expandedFolderPaths: {},\n initialPathRevealed: false,\n isBrowseLoading: false,\n isSearchLoading: false,\n mode: \"browse\",\n previewState: { status: \"empty\" },\n searchEntries: [],\n searchError: null,\n searchQuery: \"\"\n });\n },\n setPreviewReference(reference) {\n setPreviewReference(reference);\n },\n setSearchQuery(query) {\n if (query === snapshot.searchQuery) {\n return;\n }\n const nextMode = resolveMode(query);\n setSnapshot({\n mode: nextMode,\n searchQuery: query,\n ...(nextMode === \"browse\" ? { isSearchLoading: false } : {})\n });\n if (nextMode === \"search\") {\n cancelCurrentBrowse();\n scheduleSearch();\n return;\n }\n clearSearchResults();\n void loadBrowseRoot();\n },\n get store() {\n return store;\n },\n toggleFolder(entry) {\n const folderKey = normalizeDirectoryPath(entry.path);\n const childState = snapshot.directoryStateByPath[folderKey];\n const nextExpanded = !(snapshot.expandedFolderPaths[folderKey] ?? false);\n\n setSnapshot((current) => ({\n ...current,\n expandedFolderPaths: {\n ...current.expandedFolderPaths,\n [folderKey]: nextExpanded\n }\n }));\n if (nextExpanded && !childState?.loaded && !childState?.loading) {\n void loadFolderChildren(entry);\n }\n }\n };\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof Error && error.name === \"AbortError\";\n}\n\nfunction normalizeControllerError(\n error: unknown,\n fallbackMessage: string\n): Error {\n return error instanceof Error ? error : new Error(fallbackMessage);\n}\n\nfunction createReferencePreviewState(\n reference: WorkspaceFileReference,\n target: WorkspaceFilePreviewActivationTarget,\n preview: WorkspaceFileReferencePreview\n): WorkspaceFileReferencePreviewState {\n const loadedState = createWorkspaceFilePreviewLoadedState({\n bytes: preview.bytes,\n contentType: preview.contentType,\n entry: reference,\n target: {\n ...target,\n fileKind: preview.kind\n }\n });\n\n if (loadedState.status === \"image\") {\n return {\n objectUrl: URL.createObjectURL(\n new Blob([loadedState.bytes], {\n type: loadedState.contentType\n })\n ),\n reference,\n status: \"image\"\n };\n }\n\n if (loadedState.status === \"text\") {\n return {\n content: loadedState.content,\n reference,\n status: \"text\"\n };\n }\n\n return {\n maxSizeBytes: loadedState.maxSizeBytes,\n reason: loadedState.reason,\n reference,\n status: \"readonly\"\n };\n}\n\nfunction isPathInsideOrEqual(path: string, root: string): boolean {\n const normalizedPath = normalizeDirectoryPath(path);\n const normalizedRoot = normalizeDirectoryPath(root);\n if (normalizedRoot === \"/\") {\n return normalizedPath.startsWith(\"/\");\n }\n return (\n normalizedPath === normalizedRoot ||\n normalizedPath.startsWith(`${normalizedRoot}/`)\n );\n}\n\nfunction directoryChainBetween(root: string, target: string): string[] {\n const normalizedRoot = normalizeDirectoryPath(root);\n let current = normalizeDirectoryPath(target);\n const chain: string[] = [];\n\n while (current && current !== normalizedRoot) {\n chain.unshift(current);\n const parent = dirnameDirectoryPath(current);\n if (parent === current) {\n break;\n }\n current = parent;\n }\n\n return chain;\n}\n\nfunction dirnameDirectoryPath(path: string): string {\n const normalized = normalizeDirectoryPath(path);\n if (normalized === \"/\") {\n return \"/\";\n }\n const index = normalized.lastIndexOf(\"/\");\n if (index <= 0) {\n return \"/\";\n }\n return normalized.slice(0, index);\n}\n"],"mappings":"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","names":[]}
|
package/dist/chunk-PAR2R2G5.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
// src/core/index.ts
|
|
2
|
-
function uniqueWorkspaceFileReferences(refs) {
|
|
3
|
-
const unique = /* @__PURE__ */ new Map();
|
|
4
|
-
for (const ref of refs) {
|
|
5
|
-
const normalizedPath = ref.path.trim();
|
|
6
|
-
if (!normalizedPath || unique.has(normalizedPath)) {
|
|
7
|
-
continue;
|
|
8
|
-
}
|
|
9
|
-
unique.set(normalizedPath, {
|
|
10
|
-
displayName: ref.displayName?.trim() || void 0,
|
|
11
|
-
kind: ref.kind === "folder" ? "folder" : "file",
|
|
12
|
-
path: normalizedPath,
|
|
13
|
-
...ref.mtimeMs === void 0 ? {} : { mtimeMs: ref.mtimeMs },
|
|
14
|
-
...ref.sizeBytes === void 0 ? {} : { sizeBytes: ref.sizeBytes }
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
return [...unique.values()];
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export {
|
|
21
|
-
uniqueWorkspaceFileReferences
|
|
22
|
-
};
|
|
23
|
-
//# sourceMappingURL=chunk-PAR2R2G5.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/index.ts"],"sourcesContent":["import type { WorkspaceFileReference } from \"../contracts/index.ts\";\n\nexport function uniqueWorkspaceFileReferences(\n refs: readonly WorkspaceFileReference[]\n): WorkspaceFileReference[] {\n const unique = new Map<string, WorkspaceFileReference>();\n for (const ref of refs) {\n const normalizedPath = ref.path.trim();\n if (!normalizedPath || unique.has(normalizedPath)) {\n continue;\n }\n unique.set(normalizedPath, {\n displayName: ref.displayName?.trim() || undefined,\n kind: ref.kind === \"folder\" ? \"folder\" : \"file\",\n path: normalizedPath,\n ...(ref.mtimeMs === undefined ? {} : { mtimeMs: ref.mtimeMs }),\n ...(ref.sizeBytes === undefined ? {} : { sizeBytes: ref.sizeBytes })\n });\n }\n return [...unique.values()];\n}\n"],"mappings":";AAEO,SAAS,8BACd,MAC0B;AAC1B,QAAM,SAAS,oBAAI,IAAoC;AACvD,aAAW,OAAO,MAAM;AACtB,UAAM,iBAAiB,IAAI,KAAK,KAAK;AACrC,QAAI,CAAC,kBAAkB,OAAO,IAAI,cAAc,GAAG;AACjD;AAAA,IACF;AACA,WAAO,IAAI,gBAAgB;AAAA,MACzB,aAAa,IAAI,aAAa,KAAK,KAAK;AAAA,MACxC,MAAM,IAAI,SAAS,WAAW,WAAW;AAAA,MACzC,MAAM;AAAA,MACN,GAAI,IAAI,YAAY,SAAY,CAAC,IAAI,EAAE,SAAS,IAAI,QAAQ;AAAA,MAC5D,GAAI,IAAI,cAAc,SAAY,CAAC,IAAI,EAAE,WAAW,IAAI,UAAU;AAAA,IACpE,CAAC;AAAA,EACH;AACA,SAAO,CAAC,GAAG,OAAO,OAAO,CAAC;AAC5B;","names":[]}
|