@tutti-os/workspace-file-reference 0.0.1

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.
@@ -0,0 +1,676 @@
1
+ import {
2
+ normalizeDirectoryPath,
3
+ useWorkspaceFileReferencePickerView
4
+ } from "../chunk-LS7P3J6Z.js";
5
+ import "../chunk-PAR2R2G5.js";
6
+
7
+ // src/ui/internal/reference/WorkspaceFileReferencePicker.tsx
8
+ import { useId } from "react";
9
+ import { createPortal } from "react-dom";
10
+ import {
11
+ Button as Button3,
12
+ Card,
13
+ CardContent,
14
+ CardHeader,
15
+ CardTitle,
16
+ CloseIcon,
17
+ cn as cn2
18
+ } from "@tutti-os/ui-system";
19
+
20
+ // src/ui/internal/reference/WorkspaceFileReferencePickerSections.tsx
21
+ import {
22
+ Badge,
23
+ Button as Button2,
24
+ FileIcon as FileIcon2,
25
+ FolderFilledIcon as FolderFilledIcon2,
26
+ LoadingIcon
27
+ } from "@tutti-os/ui-system";
28
+ import { formatWorkspacePreviewByteLimit } from "@tutti-os/workspace-file-preview";
29
+ import { WorkspaceFilePreviewSurface as SharedWorkspaceFilePreviewSurface } from "@tutti-os/workspace-file-preview/react";
30
+
31
+ // src/ui/internal/reference/WorkspaceFileReferencePickerTree.tsx
32
+ import { useEffect, useState } from "react";
33
+ import { useComposedInputValue } from "@tutti-os/ui-react-hooks";
34
+ import {
35
+ ArrowRightIcon,
36
+ Button,
37
+ CheckIcon,
38
+ FileIcon,
39
+ FolderFilledIcon,
40
+ Input,
41
+ ScrollArea,
42
+ SearchIcon,
43
+ Spinner,
44
+ cn
45
+ } from "@tutti-os/ui-system";
46
+ import { AddIcon as AddLinedIcon } from "@tutti-os/ui-system/icons";
47
+ import { jsx, jsxs } from "react/jsx-runtime";
48
+ var workspaceFileReferenceTreeIndent = 24;
49
+ var workspaceFileReferenceTreeCollapseDurationMs = 200;
50
+ function WorkspaceFileReferencePickerBrowserPane({
51
+ browseRootEntries,
52
+ copy,
53
+ directoryStateByPath,
54
+ expandedFolderPaths,
55
+ focusedPath,
56
+ isLoading,
57
+ mode,
58
+ searchQuery,
59
+ selectedRefs,
60
+ setSearchQuery,
61
+ visibleEntries,
62
+ onFocusPath,
63
+ onToggleFolder,
64
+ onToggleRef
65
+ }) {
66
+ return /* @__PURE__ */ jsxs("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", children: [
67
+ /* @__PURE__ */ jsx("div", { className: "border-b border-[var(--line-1)] p-3", children: /* @__PURE__ */ jsx(
68
+ WorkspaceFileReferencePickerSearchInput,
69
+ {
70
+ placeholder: copy.t("referencePicker.searchPlaceholder"),
71
+ value: searchQuery,
72
+ onChange: setSearchQuery
73
+ }
74
+ ) }),
75
+ isLoading ? /* @__PURE__ */ jsx(WorkspaceFileReferencePickerFeedback, { children: /* @__PURE__ */ jsx(Spinner, { className: "text-[var(--text-secondary)]", size: 16 }) }) : visibleEntries.length === 0 ? /* @__PURE__ */ jsx(WorkspaceFileReferencePickerFeedback, { children: mode === "search" ? copy.t("referencePicker.emptySearch") : copy.t("referencePicker.emptyDirectory") }) : /* @__PURE__ */ jsx(ScrollArea, { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-[2px] p-3", children: mode === "browse" ? /* @__PURE__ */ jsx("div", { className: "space-y-0.5", children: browseRootEntries.map((entry) => /* @__PURE__ */ jsx(
76
+ WorkspaceFileReferencePickerTreeEntry,
77
+ {
78
+ childDepth: 1,
79
+ copy,
80
+ directoryStateByPath,
81
+ entry,
82
+ expandedFolderPaths,
83
+ focusedPath,
84
+ selectedRefs,
85
+ onFocusPath,
86
+ onToggleFolder,
87
+ onToggleRef
88
+ },
89
+ entry.path
90
+ )) }) : visibleEntries.map((entry) => /* @__PURE__ */ jsx(
91
+ WorkspaceFileReferencePickerSearchEntry,
92
+ {
93
+ entry,
94
+ focused: focusedPath === entry.path,
95
+ selected: selectedRefs.some(
96
+ (item) => item.path === entry.path
97
+ ),
98
+ onFocusPath,
99
+ onToggleRef
100
+ },
101
+ entry.path
102
+ )) }) })
103
+ ] });
104
+ }
105
+ function WorkspaceFileReferencePickerSearchInput({
106
+ onChange,
107
+ placeholder,
108
+ value
109
+ }) {
110
+ const searchInput = useComposedInputValue({ onCommit: onChange, value });
111
+ return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
112
+ /* @__PURE__ */ jsx(SearchIcon, { className: "pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2 text-[var(--text-tertiary)]" }),
113
+ /* @__PURE__ */ jsx(
114
+ Input,
115
+ {
116
+ className: "pl-9",
117
+ placeholder,
118
+ value: searchInput.value,
119
+ onBlur: searchInput.onBlur,
120
+ onChange: searchInput.onChange,
121
+ onCompositionEnd: searchInput.onCompositionEnd,
122
+ onCompositionStart: searchInput.onCompositionStart
123
+ }
124
+ )
125
+ ] });
126
+ }
127
+ function WorkspaceFileReferencePickerTreeEntry({
128
+ childDepth,
129
+ copy,
130
+ directoryStateByPath,
131
+ entry,
132
+ expandedFolderPaths,
133
+ focusedPath,
134
+ selectedRefs,
135
+ onFocusPath,
136
+ onToggleFolder,
137
+ onToggleRef
138
+ }) {
139
+ const selected = selectedRefs.some((item) => item.path === entry.path);
140
+ const focused = focusedPath === entry.path;
141
+ const isFolder = entry.kind === "folder";
142
+ const folderKey = normalizeDirectoryPath(entry.path);
143
+ const expanded = expandedFolderPaths[folderKey] ?? false;
144
+ const childState = directoryStateByPath[folderKey];
145
+ const childEntries = childState?.entries ?? [];
146
+ const [shouldRenderChildContent, setShouldRenderChildContent] = useState(expanded);
147
+ useEffect(() => {
148
+ if (expanded) {
149
+ setShouldRenderChildContent(true);
150
+ return;
151
+ }
152
+ const timeoutId = window.setTimeout(() => {
153
+ setShouldRenderChildContent(false);
154
+ }, workspaceFileReferenceTreeCollapseDurationMs);
155
+ return () => window.clearTimeout(timeoutId);
156
+ }, [expanded]);
157
+ const shouldBuildChildContent = expanded || shouldRenderChildContent;
158
+ const childContent = shouldBuildChildContent ? childState?.loading ? /* @__PURE__ */ jsxs(
159
+ "div",
160
+ {
161
+ className: "flex items-center gap-2 px-2 py-2 text-xs text-[var(--text-secondary)]",
162
+ style: {
163
+ paddingLeft: `${childDepth * workspaceFileReferenceTreeIndent + 12}px`
164
+ },
165
+ children: [
166
+ /* @__PURE__ */ jsx(Spinner, { className: "text-[var(--text-secondary)]", size: 14 }),
167
+ /* @__PURE__ */ jsx("span", { children: copy.t("referencePicker.loading") })
168
+ ]
169
+ }
170
+ ) : childEntries.length > 0 ? /* @__PURE__ */ jsx("div", { className: "space-y-0.5", children: childEntries.map((childEntry) => /* @__PURE__ */ jsx(
171
+ WorkspaceFileReferencePickerTreeEntry,
172
+ {
173
+ childDepth: childDepth + 1,
174
+ copy,
175
+ directoryStateByPath,
176
+ entry: childEntry,
177
+ expandedFolderPaths,
178
+ focusedPath,
179
+ selectedRefs,
180
+ onFocusPath,
181
+ onToggleFolder,
182
+ onToggleRef
183
+ },
184
+ childEntry.path
185
+ )) }) : childState?.loaded ? /* @__PURE__ */ jsx(
186
+ "div",
187
+ {
188
+ className: "px-2 py-2 text-xs text-[var(--text-secondary)]",
189
+ style: {
190
+ paddingLeft: `${childDepth * workspaceFileReferenceTreeIndent + 12}px`
191
+ },
192
+ children: copy.t("referencePicker.emptyDirectory")
193
+ }
194
+ ) : null : null;
195
+ return /* @__PURE__ */ jsxs("div", { children: [
196
+ /* @__PURE__ */ jsxs(
197
+ "div",
198
+ {
199
+ className: cn(
200
+ "grid grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-2 rounded-[6px] py-1.5 pr-1 pl-2 transition-colors",
201
+ "nodrag [-webkit-app-region:no-drag]",
202
+ focused || selected ? "bg-transparency-block" : "hover:bg-transparency-block"
203
+ ),
204
+ style: {
205
+ paddingLeft: `${(childDepth - 1) * workspaceFileReferenceTreeIndent + 8}px`
206
+ },
207
+ children: [
208
+ isFolder ? /* @__PURE__ */ jsx(
209
+ "button",
210
+ {
211
+ "aria-label": resolveWorkspaceFileReferenceLabel(entry),
212
+ 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)]",
213
+ type: "button",
214
+ onClick: (event) => {
215
+ event.stopPropagation();
216
+ onToggleFolder(entry);
217
+ },
218
+ children: /* @__PURE__ */ jsx(
219
+ ArrowRightIcon,
220
+ {
221
+ className: cn(
222
+ "size-3.5 transition-transform",
223
+ expanded && "rotate-90"
224
+ )
225
+ }
226
+ )
227
+ }
228
+ ) : /* @__PURE__ */ jsx("span", { className: "block size-5 shrink-0" }),
229
+ /* @__PURE__ */ jsxs(
230
+ "button",
231
+ {
232
+ className: "nodrag flex min-w-0 items-center gap-2 text-left [-webkit-app-region:no-drag]",
233
+ type: "button",
234
+ onClick: (event) => {
235
+ event.stopPropagation();
236
+ onFocusPath(entry.path);
237
+ if (entry.kind === "folder") {
238
+ onToggleFolder(entry);
239
+ }
240
+ },
241
+ children: [
242
+ isFolder ? /* @__PURE__ */ jsx(FolderFilledIcon, { className: "size-4 shrink-0 text-[var(--rich-text-folder)]" }) : /* @__PURE__ */ jsx(FileIcon, { className: "size-4 shrink-0 text-[var(--text-tertiary)]" }),
243
+ /* @__PURE__ */ jsx("span", { className: "truncate text-sm text-[var(--text-primary)]", children: resolveWorkspaceFileReferenceLabel(entry) })
244
+ ]
245
+ }
246
+ ),
247
+ /* @__PURE__ */ jsx(
248
+ Button,
249
+ {
250
+ "aria-label": resolveWorkspaceFileReferenceLabel(entry),
251
+ "aria-pressed": selected,
252
+ size: "icon-sm",
253
+ type: "button",
254
+ variant: "ghost",
255
+ className: "nodrag [-webkit-app-region:no-drag]",
256
+ onClick: (event) => {
257
+ event.stopPropagation();
258
+ onFocusPath(entry.path);
259
+ onToggleRef(entry);
260
+ },
261
+ children: selected ? /* @__PURE__ */ jsx(CheckIcon, { size: 14 }) : /* @__PURE__ */ jsx(AddLinedIcon, { className: "text-[var(--text-secondary)]", size: 16 })
262
+ }
263
+ )
264
+ ]
265
+ }
266
+ ),
267
+ isFolder ? /* @__PURE__ */ jsx(
268
+ "div",
269
+ {
270
+ className: cn(
271
+ "grid transition-[grid-template-rows] duration-200 ease-out motion-reduce:transition-none",
272
+ expanded ? "grid-rows-[1fr]" : "grid-rows-[0fr]",
273
+ childContent && "mt-[2px]"
274
+ ),
275
+ children: /* @__PURE__ */ jsx(
276
+ "div",
277
+ {
278
+ "aria-hidden": expanded ? void 0 : "true",
279
+ className: cn(
280
+ "min-h-0 overflow-hidden transition-[opacity,transform] duration-200 ease-out motion-reduce:transition-none",
281
+ expanded ? "translate-y-0 opacity-100" : "-translate-y-1 opacity-0"
282
+ ),
283
+ inert: expanded ? void 0 : true,
284
+ children: childContent
285
+ }
286
+ )
287
+ }
288
+ ) : null
289
+ ] });
290
+ }
291
+ function WorkspaceFileReferencePickerSearchEntry({
292
+ entry,
293
+ focused,
294
+ selected,
295
+ onFocusPath,
296
+ onToggleRef
297
+ }) {
298
+ const isFolder = entry.kind === "folder";
299
+ return /* @__PURE__ */ jsxs(
300
+ "div",
301
+ {
302
+ className: cn(
303
+ "grid grid-cols-[minmax(0,1fr)_auto] items-center gap-3 rounded-[6px] border py-2.5 pr-1 pl-3 transition-colors",
304
+ "nodrag [-webkit-app-region:no-drag]",
305
+ focused || selected ? "border-border bg-transparency-block" : "border-transparent bg-transparent hover:border-border/70 hover:bg-transparency-block"
306
+ ),
307
+ children: [
308
+ /* @__PURE__ */ jsxs(
309
+ "button",
310
+ {
311
+ className: "nodrag flex min-w-0 items-center gap-3 text-left [-webkit-app-region:no-drag]",
312
+ type: "button",
313
+ onClick: (event) => {
314
+ event.stopPropagation();
315
+ onFocusPath(entry.path);
316
+ },
317
+ children: [
318
+ /* @__PURE__ */ jsx("span", { className: "grid size-9 shrink-0 place-items-center rounded-lg bg-[var(--transparency-block)] text-[var(--text-tertiary)]", children: isFolder ? /* @__PURE__ */ jsx(FolderFilledIcon, { className: "size-4 text-[var(--rich-text-folder)]" }) : /* @__PURE__ */ jsx(FileIcon, { className: "size-4 text-[var(--text-tertiary)]" }) }),
319
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0", children: [
320
+ /* @__PURE__ */ jsx("span", { className: "block truncate text-sm font-medium text-[var(--text-primary)]", children: resolveWorkspaceFileReferenceLabel(entry) }),
321
+ /* @__PURE__ */ jsx("span", { className: "block truncate text-xs text-[var(--text-secondary)]", children: entry.path })
322
+ ] })
323
+ ]
324
+ }
325
+ ),
326
+ /* @__PURE__ */ jsx(
327
+ Button,
328
+ {
329
+ "aria-label": resolveWorkspaceFileReferenceLabel(entry),
330
+ "aria-pressed": selected,
331
+ size: "icon-sm",
332
+ type: "button",
333
+ variant: "ghost",
334
+ className: "nodrag [-webkit-app-region:no-drag]",
335
+ onClick: (event) => {
336
+ event.stopPropagation();
337
+ onFocusPath(entry.path);
338
+ onToggleRef(entry);
339
+ },
340
+ children: selected ? /* @__PURE__ */ jsx(CheckIcon, { size: 14 }) : /* @__PURE__ */ jsx(AddLinedIcon, { className: "text-[var(--text-secondary)]", size: 16 })
341
+ }
342
+ )
343
+ ]
344
+ }
345
+ );
346
+ }
347
+ function WorkspaceFileReferencePickerFeedback({
348
+ children
349
+ }) {
350
+ return /* @__PURE__ */ jsx("div", { className: "grid min-h-0 flex-1 place-items-center px-4 text-center text-sm text-[var(--text-secondary)]", children });
351
+ }
352
+ function resolveWorkspaceFileReferenceLabel(ref) {
353
+ return ref.displayName || ref.path.split("/").filter(Boolean).at(-1) || ref.path;
354
+ }
355
+
356
+ // src/ui/internal/reference/WorkspaceFileReferencePickerSections.tsx
357
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
358
+ var workspaceFileReferencePickerSelectedBadgeClassName = "max-w-[14rem] rounded-[4px] border-transparent bg-[var(--transparency-block)] text-[var(--text-primary)]";
359
+ function WorkspaceFileReferencePickerPreviewPane({
360
+ copy,
361
+ focusedEntry,
362
+ mode,
363
+ previewState
364
+ }) {
365
+ return /* @__PURE__ */ jsx2("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", children: /* @__PURE__ */ jsx2("div", { className: "flex min-h-0 flex-1 flex-col p-2", children: focusedEntry ? /* @__PURE__ */ jsxs2("div", { className: "flex min-h-0 flex-col gap-4 lg:flex-1 lg:gap-5", children: [
366
+ /* @__PURE__ */ jsx2(
367
+ WorkspaceFileReferencePreviewSurface,
368
+ {
369
+ copy,
370
+ focusedEntry,
371
+ previewState
372
+ }
373
+ ),
374
+ /* @__PURE__ */ jsx2("div", { className: "space-y-2 px-2 lg:space-y-3", children: /* @__PURE__ */ jsxs2("div", { className: "space-y-1.5", children: [
375
+ /* @__PURE__ */ jsx2("p", { className: "truncate text-[15px] font-semibold text-[var(--text-primary)]", children: resolveWorkspaceFileReferenceLabel(focusedEntry) }),
376
+ /* @__PURE__ */ jsx2("p", { className: "line-clamp-3 text-sm text-[var(--text-secondary)] [overflow-wrap:anywhere]", children: focusedEntry.path })
377
+ ] }) })
378
+ ] }) : /* @__PURE__ */ jsx2(WorkspaceFileReferencePickerFeedback2, { children: mode === "search" ? copy.t("referencePicker.emptySearch") : copy.t("referencePicker.emptyDirectory") }) }) });
379
+ }
380
+ function WorkspaceFileReferencePreviewSurface({
381
+ copy,
382
+ focusedEntry,
383
+ previewState
384
+ }) {
385
+ return /* @__PURE__ */ jsx2(
386
+ SharedWorkspaceFilePreviewSurface,
387
+ {
388
+ directoryMessage: copy.t("referencePicker.previewFolder"),
389
+ emptyMessage: copy.t("referencePicker.previewUnavailable"),
390
+ 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",
391
+ imageAlt: resolveWorkspaceFileReferenceLabel,
392
+ imageFrameClassName: "p-3",
393
+ loadingIndicator: /* @__PURE__ */ jsx2("span", { className: "mx-auto grid size-11 place-items-center rounded-[6px] bg-[var(--transparency-block)]", children: /* @__PURE__ */ jsx2(LoadingIcon, { className: "size-4 animate-spin" }) }),
394
+ loadingMessage: copy.t("referencePicker.previewLoading"),
395
+ messageClassName: "mx-auto max-w-[24ch] text-sm leading-5 text-[var(--text-secondary)] [overflow-wrap:anywhere]",
396
+ renderIcon: (entry) => entry.kind === "folder" ? /* @__PURE__ */ jsx2(FolderFilledIcon2, { className: "mx-auto size-9 text-[var(--rich-text-folder)]" }) : /* @__PURE__ */ jsx2(FileIcon2, { className: "mx-auto size-9 text-[var(--text-tertiary)]" }),
397
+ state: resolveWorkspaceFileReferenceSurfaceState(
398
+ copy,
399
+ focusedEntry,
400
+ previewState
401
+ ),
402
+ textClassName: "h-full overflow-auto p-3 text-left text-xs leading-5 whitespace-pre-wrap break-words text-[var(--text-primary)]",
403
+ textFrameClassName: "items-stretch justify-stretch"
404
+ }
405
+ );
406
+ }
407
+ function resolveWorkspaceFileReferenceSurfaceState(copy, focusedEntry, previewState) {
408
+ if (focusedEntry.kind === "folder") {
409
+ return {
410
+ entry: focusedEntry,
411
+ status: "directory"
412
+ };
413
+ }
414
+ if (!("reference" in previewState) || previewState.reference.path !== focusedEntry.path) {
415
+ return {
416
+ entry: focusedEntry,
417
+ message: focusedEntry.path,
418
+ status: "unsupported"
419
+ };
420
+ }
421
+ switch (previewState.status) {
422
+ case "loading":
423
+ case "image":
424
+ case "text":
425
+ return {
426
+ ...previewState,
427
+ entry: focusedEntry
428
+ };
429
+ case "readonly":
430
+ return {
431
+ entry: focusedEntry,
432
+ message: resolveWorkspaceFileReferencePreviewReadonlyMessage(
433
+ copy,
434
+ previewState
435
+ ),
436
+ status: "readonly"
437
+ };
438
+ case "error":
439
+ return {
440
+ entry: focusedEntry,
441
+ message: copy.t("referencePicker.previewError"),
442
+ status: "error"
443
+ };
444
+ case "unsupported":
445
+ return {
446
+ entry: focusedEntry,
447
+ message: copy.t("referencePicker.previewUnsupported"),
448
+ status: "unsupported"
449
+ };
450
+ case "unavailable":
451
+ return {
452
+ entry: focusedEntry,
453
+ message: copy.t("referencePicker.previewUnavailable"),
454
+ status: "unsupported"
455
+ };
456
+ case "directory":
457
+ return {
458
+ entry: focusedEntry,
459
+ status: "directory"
460
+ };
461
+ }
462
+ }
463
+ function resolveWorkspaceFileReferencePreviewReadonlyMessage(copy, previewState) {
464
+ switch (previewState.reason) {
465
+ case "binary":
466
+ return copy.t("referencePicker.previewBinary");
467
+ case "decode_failed":
468
+ return copy.t("referencePicker.previewDecodeFailed");
469
+ case "file_too_large":
470
+ return copy.t("referencePicker.previewFileTooLarge", {
471
+ maxSize: formatWorkspacePreviewByteLimit(previewState.maxSizeBytes ?? 0)
472
+ });
473
+ case "text_too_large":
474
+ return copy.t("referencePicker.previewTextTooLarge", {
475
+ maxSize: formatWorkspacePreviewByteLimit(previewState.maxSizeBytes ?? 0)
476
+ });
477
+ }
478
+ }
479
+ function WorkspaceFileReferencePickerFooter({
480
+ copy,
481
+ onClose,
482
+ onConfirm,
483
+ selectedRefs
484
+ }) {
485
+ return /* @__PURE__ */ jsxs2("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", children: [
486
+ /* @__PURE__ */ jsxs2("div", { className: "flex min-w-0 flex-wrap items-center gap-2 lg:flex-1", children: [
487
+ /* @__PURE__ */ jsx2("span", { className: "text-sm text-[var(--text-secondary)]", children: copy.t("referencePicker.selectedCount", {
488
+ count: selectedRefs.length
489
+ }) }),
490
+ selectedRefs.slice(0, 2).map((ref) => /* @__PURE__ */ jsx2(
491
+ Badge,
492
+ {
493
+ className: workspaceFileReferencePickerSelectedBadgeClassName,
494
+ variant: "secondary",
495
+ children: /* @__PURE__ */ jsx2("span", { className: "truncate", children: resolveWorkspaceFileReferenceLabel(ref) })
496
+ },
497
+ ref.path
498
+ )),
499
+ selectedRefs.length > 2 ? /* @__PURE__ */ jsxs2(
500
+ Badge,
501
+ {
502
+ className: workspaceFileReferencePickerSelectedBadgeClassName,
503
+ variant: "secondary",
504
+ children: [
505
+ "+",
506
+ selectedRefs.length - 2
507
+ ]
508
+ }
509
+ ) : null
510
+ ] }),
511
+ /* @__PURE__ */ jsxs2("div", { className: "flex w-full items-center justify-end gap-2 lg:w-auto lg:shrink-0", children: [
512
+ /* @__PURE__ */ jsx2(
513
+ Button2,
514
+ {
515
+ className: "nodrag [-webkit-app-region:no-drag]",
516
+ type: "button",
517
+ variant: "secondary",
518
+ onClick: onClose,
519
+ children: copy.t("actions.cancel")
520
+ }
521
+ ),
522
+ /* @__PURE__ */ jsx2(
523
+ Button2,
524
+ {
525
+ className: "nodrag [-webkit-app-region:no-drag]",
526
+ disabled: selectedRefs.length === 0,
527
+ type: "button",
528
+ onClick: onConfirm,
529
+ children: copy.t("referencePicker.confirm")
530
+ }
531
+ )
532
+ ] })
533
+ ] });
534
+ }
535
+ function WorkspaceFileReferencePickerFeedback2({
536
+ children
537
+ }) {
538
+ return /* @__PURE__ */ jsx2("div", { className: "grid min-h-0 flex-1 place-items-center px-4 text-center text-sm text-[var(--text-secondary)]", children });
539
+ }
540
+
541
+ // src/ui/internal/reference/WorkspaceFileReferencePicker.tsx
542
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
543
+ var workspaceFileReferencePickerBackdropMotionClassName = "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";
544
+ var workspaceFileReferencePickerPanelMotionClassName = "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";
545
+ function WorkspaceFileReferencePicker({
546
+ copy,
547
+ fileAdapter,
548
+ initialPath,
549
+ onClose,
550
+ onConfirm,
551
+ open,
552
+ workspaceId
553
+ }) {
554
+ const titleId = useId();
555
+ const {
556
+ browseRootEntries,
557
+ directoryStateByPath,
558
+ expandedFolderPaths,
559
+ focusedEntry,
560
+ focusedPath,
561
+ isLoading,
562
+ mode,
563
+ previewState,
564
+ searchQuery,
565
+ selectedRefs,
566
+ visibleEntries,
567
+ setFocusedPath,
568
+ setSearchQuery,
569
+ toggleFolder,
570
+ toggleRef
571
+ } = useWorkspaceFileReferencePickerView({
572
+ fileAdapter,
573
+ initialPath,
574
+ onClose,
575
+ onConfirm,
576
+ open,
577
+ workspaceId
578
+ });
579
+ if (!open) {
580
+ return null;
581
+ }
582
+ const dialog = /* @__PURE__ */ jsx3(
583
+ "div",
584
+ {
585
+ className: cn2(
586
+ "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",
587
+ workspaceFileReferencePickerBackdropMotionClassName
588
+ ),
589
+ style: { zIndex: "var(--z-panel)" },
590
+ onClick: onClose,
591
+ children: /* @__PURE__ */ jsxs3(
592
+ Card,
593
+ {
594
+ "aria-labelledby": titleId,
595
+ "aria-modal": "true",
596
+ className: cn2(
597
+ "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)]",
598
+ workspaceFileReferencePickerPanelMotionClassName
599
+ ),
600
+ role: "dialog",
601
+ onClick: (event) => event.stopPropagation(),
602
+ children: [
603
+ /* @__PURE__ */ jsx3(
604
+ CardHeader,
605
+ {
606
+ className: "border-b px-4 py-4 sm:px-6 sm:py-5",
607
+ style: { borderBottomColor: "var(--line-1)" },
608
+ children: /* @__PURE__ */ jsxs3("div", { className: "flex items-start justify-between gap-4", children: [
609
+ /* @__PURE__ */ jsx3("div", { className: "min-w-0", children: /* @__PURE__ */ jsx3(CardTitle, { id: titleId, children: copy.t("referencePicker.title") }) }),
610
+ /* @__PURE__ */ jsx3(
611
+ Button3,
612
+ {
613
+ "aria-label": copy.t("actions.cancel"),
614
+ size: "icon-sm",
615
+ type: "button",
616
+ variant: "ghost",
617
+ onClick: onClose,
618
+ children: /* @__PURE__ */ jsx3(CloseIcon, { size: 16 })
619
+ }
620
+ )
621
+ ] })
622
+ }
623
+ ),
624
+ /* @__PURE__ */ jsxs3(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", children: [
625
+ /* @__PURE__ */ jsx3(
626
+ WorkspaceFileReferencePickerBrowserPane,
627
+ {
628
+ browseRootEntries,
629
+ copy,
630
+ directoryStateByPath,
631
+ expandedFolderPaths,
632
+ focusedPath,
633
+ isLoading,
634
+ mode,
635
+ searchQuery,
636
+ selectedRefs,
637
+ setSearchQuery,
638
+ visibleEntries,
639
+ onFocusPath: setFocusedPath,
640
+ onToggleFolder: toggleFolder,
641
+ onToggleRef: toggleRef
642
+ }
643
+ ),
644
+ /* @__PURE__ */ jsx3(
645
+ WorkspaceFileReferencePickerPreviewPane,
646
+ {
647
+ copy,
648
+ focusedEntry,
649
+ mode,
650
+ previewState
651
+ }
652
+ )
653
+ ] }),
654
+ /* @__PURE__ */ jsx3(
655
+ WorkspaceFileReferencePickerFooter,
656
+ {
657
+ copy,
658
+ onClose,
659
+ onConfirm: () => onConfirm(selectedRefs),
660
+ selectedRefs
661
+ }
662
+ )
663
+ ]
664
+ }
665
+ )
666
+ }
667
+ );
668
+ if (typeof document === "undefined") {
669
+ return dialog;
670
+ }
671
+ return createPortal(dialog, document.body);
672
+ }
673
+ export {
674
+ WorkspaceFileReferencePicker
675
+ };
676
+ //# sourceMappingURL=index.js.map