@openviking/react 0.0.0-stage → 0.1.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.
Files changed (104) hide show
  1. package/README.md +82 -2
  2. package/dist/3~0.js +8 -0
  3. package/dist/a~0.js +21 -0
  4. package/dist/client/client.d.ts +12 -0
  5. package/dist/client/errors.d.ts +30 -0
  6. package/dist/client/index.d.ts +4 -0
  7. package/dist/client/options.d.ts +101 -0
  8. package/dist/client/provider.d.ts +52 -0
  9. package/dist/client/types.d.ts +160 -0
  10. package/dist/client.js +239 -0
  11. package/dist/components/agent-connect/agent-connect.d.ts +4 -0
  12. package/dist/components/agent-connect/index.d.ts +1 -0
  13. package/dist/components/agent-connect/style.css +16 -0
  14. package/dist/components/agent-connect/style.js +0 -0
  15. package/dist/components/agent-connect/types.d.ts +175 -0
  16. package/dist/components/agent-connect.js +1 -0
  17. package/dist/components/file-preview/file-preview-body.d.ts +15 -0
  18. package/dist/components/file-preview/file-preview-header.d.ts +16 -0
  19. package/dist/components/file-preview/file-preview-icons.d.ts +2 -0
  20. package/dist/components/file-preview/file-preview-labels.d.ts +5 -0
  21. package/dist/components/file-preview/file-preview-operations.d.ts +1 -0
  22. package/dist/components/file-preview/file-preview.d.ts +17 -0
  23. package/dist/components/file-preview/index.d.ts +1 -0
  24. package/dist/components/file-preview/style.css +285 -0
  25. package/dist/components/file-preview/style.js +0 -0
  26. package/dist/components/file-preview/types.d.ts +435 -0
  27. package/dist/components/file-preview/use-file-preview-editing.d.ts +13 -0
  28. package/dist/components/file-preview.js +442 -0
  29. package/dist/components/file-tree/file-tree-body.d.ts +14 -0
  30. package/dist/components/file-tree/file-tree-dom.d.ts +4 -0
  31. package/dist/components/file-tree/file-tree-entry-row.d.ts +6 -0
  32. package/dist/components/file-tree/file-tree-icons.d.ts +8 -0
  33. package/dist/components/file-tree/file-tree-keyboard.d.ts +10 -0
  34. package/dist/components/file-tree/file-tree-labels.d.ts +5 -0
  35. package/dist/components/file-tree/file-tree-row-context.d.ts +24 -0
  36. package/dist/components/file-tree/file-tree-rows.d.ts +12 -0
  37. package/dist/components/file-tree/file-tree-tooltip.d.ts +11 -0
  38. package/dist/components/file-tree/file-tree.d.ts +4 -0
  39. package/dist/components/file-tree/index.d.ts +1 -0
  40. package/dist/components/file-tree/style.css +244 -0
  41. package/dist/components/file-tree/style.js +0 -0
  42. package/dist/components/file-tree/types.d.ts +406 -0
  43. package/dist/components/file-tree/use-file-tree-actions.d.ts +10 -0
  44. package/dist/components/file-tree.js +1 -0
  45. package/dist/components/scope-switcher/index.d.ts +1 -0
  46. package/dist/components/scope-switcher/scope-keyboard.d.ts +2 -0
  47. package/dist/components/scope-switcher/scope-panel.d.ts +5 -0
  48. package/dist/components/scope-switcher/scope-selector.d.ts +2 -0
  49. package/dist/components/scope-switcher/scope-switcher.d.ts +6 -0
  50. package/dist/components/scope-switcher/style.css +248 -0
  51. package/dist/components/scope-switcher/style.js +0 -0
  52. package/dist/components/scope-switcher/types.d.ts +367 -0
  53. package/dist/components/scope-switcher.js +3 -0
  54. package/dist/components/style.css +811 -0
  55. package/dist/components/style.js +0 -0
  56. package/dist/components/tui/index.d.ts +1 -0
  57. package/dist/components/tui/style.css +16 -0
  58. package/dist/components/tui/style.js +0 -0
  59. package/dist/components/tui/tui.d.ts +3 -0
  60. package/dist/components/tui/types.d.ts +485 -0
  61. package/dist/components/tui.js +1 -0
  62. package/dist/f~0.js +284 -0
  63. package/dist/icons/index.d.ts +23 -0
  64. package/dist/icons.js +25 -0
  65. package/dist/index.d.ts +16 -0
  66. package/dist/index.js +8 -0
  67. package/dist/i~0.js +21 -0
  68. package/dist/lk~0.js +220 -0
  69. package/dist/l~0.js +44 -0
  70. package/dist/modules/console/console.d.ts +4 -0
  71. package/dist/modules/console/index.d.ts +1 -0
  72. package/dist/modules/console/style.css +29 -0
  73. package/dist/modules/console/style.js +0 -0
  74. package/dist/modules/console/types.d.ts +101 -0
  75. package/dist/modules/console.js +1 -0
  76. package/dist/modules/file-browser/file-browser-toolbar-button.d.ts +10 -0
  77. package/dist/modules/file-browser/file-browser.d.ts +6 -0
  78. package/dist/modules/file-browser/index.d.ts +1 -0
  79. package/dist/modules/file-browser/style.css +75 -0
  80. package/dist/modules/file-browser/style.js +0 -0
  81. package/dist/modules/file-browser/types.d.ts +101 -0
  82. package/dist/modules/file-browser.js +1 -0
  83. package/dist/modules/scope-cascade/controller.d.ts +6 -0
  84. package/dist/modules/scope-cascade/index.d.ts +3 -0
  85. package/dist/modules/scope-cascade/scope-cascade.d.ts +3 -0
  86. package/dist/modules/scope-cascade/style.css +250 -0
  87. package/dist/modules/scope-cascade/style.js +0 -0
  88. package/dist/modules/scope-cascade/types.d.ts +39 -0
  89. package/dist/modules/scope-cascade/use-scope-cascade.d.ts +5 -0
  90. package/dist/modules/scope-cascade.js +1 -0
  91. package/dist/modules/style.css +385 -0
  92. package/dist/modules/style.js +0 -0
  93. package/dist/modules/task-center/columns.d.ts +129 -0
  94. package/dist/modules/task-center/index.d.ts +1 -0
  95. package/dist/modules/task-center/style.css +29 -0
  96. package/dist/modules/task-center/style.js +0 -0
  97. package/dist/modules/task-center/task-center.d.ts +4 -0
  98. package/dist/modules/task-center/types.d.ts +168 -0
  99. package/dist/modules/task-center.js +1 -0
  100. package/dist/n~0.js +499 -0
  101. package/dist/style.css +1198 -0
  102. package/dist/style.js +0 -0
  103. package/dist/u~0.js +8 -0
  104. package/package.json +103 -4
@@ -0,0 +1,442 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { forwardRef, useId, useImperativeHandle, useRef, useState } from "react";
3
+ function FilePreviewBody({ fileTab, contentTab, text, editing, loadingEdit, editFailed, saving, saveFailed, draft, onDraftChange }) {
4
+ const errorId = useId();
5
+ if (contentTab) return contentTab.content;
6
+ if (!fileTab) return null;
7
+ const { source } = fileTab;
8
+ if (loadingEdit) return /*#__PURE__*/ jsx("div", {
9
+ className: "ov-file-preview__state",
10
+ children: /*#__PURE__*/ jsx("span", {
11
+ className: "ov-file-preview__muted",
12
+ children: text.loading
13
+ })
14
+ });
15
+ if (editFailed) return /*#__PURE__*/ jsx("div", {
16
+ className: "ov-file-preview__state",
17
+ "data-tone": "error",
18
+ children: /*#__PURE__*/ jsx("span", {
19
+ className: "ov-file-preview__muted",
20
+ children: text.loadFailed
21
+ })
22
+ });
23
+ if (editing && fileTab.editing) return /*#__PURE__*/ jsxs("div", {
24
+ className: "ov-file-preview__editor",
25
+ "aria-busy": saving || void 0,
26
+ children: [
27
+ saveFailed ? /*#__PURE__*/ jsx("div", {
28
+ id: errorId,
29
+ role: "alert",
30
+ className: "ov-file-preview__save-error",
31
+ children: text.saveFailed
32
+ }) : null,
33
+ /*#__PURE__*/ jsx("textarea", {
34
+ className: "ov-file-preview__textarea",
35
+ "aria-label": text.edit,
36
+ "aria-describedby": saveFailed ? errorId : void 0,
37
+ readOnly: saving,
38
+ value: draft,
39
+ onChange: (event)=>onDraftChange(event.target.value)
40
+ })
41
+ ]
42
+ });
43
+ if ('string' != typeof source.content) return /*#__PURE__*/ jsx("div", {
44
+ className: "ov-file-preview__state",
45
+ children: fileTab.slots?.unsupportedFallback ?? /*#__PURE__*/ jsx("span", {
46
+ className: "ov-file-preview__muted",
47
+ children: source.file || source.url ? text.binaryUnsupported : text.unsupported
48
+ })
49
+ });
50
+ return /*#__PURE__*/ jsx("div", {
51
+ className: "ov-file-preview__text-body",
52
+ children: /*#__PURE__*/ jsx("pre", {
53
+ className: "ov-file-preview__pre",
54
+ children: source.content
55
+ })
56
+ });
57
+ }
58
+ function FileIcon() {
59
+ return /*#__PURE__*/ jsxs("svg", {
60
+ "aria-hidden": "true",
61
+ className: "ov-file-preview__icon",
62
+ viewBox: "0 0 16 16",
63
+ width: "14",
64
+ height: "14",
65
+ children: [
66
+ /*#__PURE__*/ jsx("path", {
67
+ d: "M4 1.5h5L12.5 5v9.5h-8.5V1.5Z",
68
+ fill: "none",
69
+ stroke: "currentColor",
70
+ strokeLinejoin: "round",
71
+ strokeWidth: "1.2"
72
+ }),
73
+ /*#__PURE__*/ jsx("path", {
74
+ d: "M9 1.5V5h3.5",
75
+ fill: "none",
76
+ stroke: "currentColor",
77
+ strokeWidth: "1.2"
78
+ })
79
+ ]
80
+ });
81
+ }
82
+ function CopyIcon() {
83
+ return /*#__PURE__*/ jsxs("svg", {
84
+ "aria-hidden": "true",
85
+ className: "ov-file-preview__action-icon",
86
+ viewBox: "0 0 16 16",
87
+ width: "12",
88
+ height: "12",
89
+ children: [
90
+ /*#__PURE__*/ jsx("rect", {
91
+ x: "5.5",
92
+ y: "5.5",
93
+ width: "8",
94
+ height: "9",
95
+ rx: "1.2",
96
+ fill: "none",
97
+ stroke: "currentColor",
98
+ strokeWidth: "1.2"
99
+ }),
100
+ /*#__PURE__*/ jsx("path", {
101
+ d: "M10.5 5.5v-2a1 1 0 0 0-1-1h-7a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h2",
102
+ fill: "none",
103
+ stroke: "currentColor",
104
+ strokeWidth: "1.2"
105
+ })
106
+ ]
107
+ });
108
+ }
109
+ const DEFAULT_LABELS = {
110
+ copyContent: 'Copy content',
111
+ copyContentSuccess: 'Content copied',
112
+ copyContentEmpty: 'Nothing to copy',
113
+ copyPath: 'Copy path',
114
+ copyPathSuccess: 'Path copied',
115
+ openParent: 'Open parent directory',
116
+ edit: 'Edit',
117
+ save: 'Save',
118
+ cancel: 'Cancel',
119
+ preview: 'Preview',
120
+ source: 'Source',
121
+ retry: 'Retry',
122
+ loadFailed: 'Failed to load the file',
123
+ saveFailed: 'Failed to save',
124
+ unsupported: 'Preview is not supported for this format',
125
+ loading: 'Loading…',
126
+ download: 'Download',
127
+ binaryUnsupported: 'Binary preview requires FileViewer'
128
+ };
129
+ function readCopyableText(tab) {
130
+ const { content } = tab.source;
131
+ return 'string' == typeof content && content.length > 0 ? content : void 0;
132
+ }
133
+ async function performPreviewOperation(execute, notify) {
134
+ if (!execute) return;
135
+ try {
136
+ await execute();
137
+ } catch {
138
+ return;
139
+ }
140
+ notify?.();
141
+ }
142
+ async function copyText(value, onCopied) {
143
+ try {
144
+ await navigator.clipboard.writeText(value);
145
+ } catch {
146
+ return;
147
+ }
148
+ onCopied?.(value);
149
+ }
150
+ function FilePreviewHeader({ activeTab, fileTab, text, viewMode, editing, loadingEdit, saving, onViewModeChange, onEditStart, onEditCancel, onEditSave }) {
151
+ const titleExtra = activeTab.slots?.titleExtra;
152
+ const headerActions = activeTab.slots?.actions;
153
+ const path = fileTab?.source.path;
154
+ return /*#__PURE__*/ jsxs("div", {
155
+ className: "ov-file-preview__header",
156
+ children: [
157
+ /*#__PURE__*/ jsxs("div", {
158
+ className: "ov-file-preview__path-row",
159
+ children: [
160
+ path ? /*#__PURE__*/ jsx("button", {
161
+ type: "button",
162
+ className: "ov-file-preview__breadcrumb",
163
+ onClick: (event)=>{
164
+ event.stopPropagation();
165
+ performPreviewOperation(fileTab.operations?.openParent ? ()=>fileTab.operations.openParent(path) : void 0, ()=>fileTab.onOpenParent?.(path));
166
+ },
167
+ disabled: !fileTab.operations?.openParent || saving,
168
+ title: path,
169
+ children: path
170
+ }) : /*#__PURE__*/ jsx("span", {
171
+ className: "ov-file-preview__breadcrumb",
172
+ children: activeTab.key
173
+ }),
174
+ path ? /*#__PURE__*/ jsx("button", {
175
+ type: "button",
176
+ className: "ov-file-preview__action",
177
+ "aria-label": text.copyPath,
178
+ title: text.copyPath,
179
+ onClick: ()=>void copyText(path, fileTab.onCopyPath),
180
+ children: /*#__PURE__*/ jsx(CopyIcon, {})
181
+ }) : null,
182
+ titleExtra ? /*#__PURE__*/ jsx("span", {
183
+ className: "ov-file-preview__title-extra",
184
+ children: titleExtra
185
+ }) : null
186
+ ]
187
+ }),
188
+ /*#__PURE__*/ jsxs("div", {
189
+ className: "ov-file-preview__header-actions",
190
+ children: [
191
+ fileTab && false !== fileTab.showViewModeSwitch ? /*#__PURE__*/ jsxs("span", {
192
+ className: "ov-file-preview__switch",
193
+ children: [
194
+ /*#__PURE__*/ jsx("button", {
195
+ type: "button",
196
+ className: "ov-file-preview__switch-item",
197
+ "data-active": 'preview' === viewMode || void 0,
198
+ onClick: ()=>onViewModeChange('preview'),
199
+ children: text.preview
200
+ }),
201
+ /*#__PURE__*/ jsx("button", {
202
+ type: "button",
203
+ className: "ov-file-preview__switch-item",
204
+ "data-active": 'source' === viewMode || void 0,
205
+ onClick: ()=>onViewModeChange('source'),
206
+ children: text.source
207
+ })
208
+ ]
209
+ }) : null,
210
+ fileTab ? /*#__PURE__*/ jsx("button", {
211
+ type: "button",
212
+ className: "ov-file-preview__action",
213
+ "aria-label": text.copyContent,
214
+ title: readCopyableText(fileTab) ? text.copyContent : text.copyContentEmpty,
215
+ disabled: !readCopyableText(fileTab),
216
+ onClick: ()=>{
217
+ const value = readCopyableText(fileTab);
218
+ if (value) copyText(value, fileTab.onCopyContent);
219
+ },
220
+ children: /*#__PURE__*/ jsx(CopyIcon, {})
221
+ }) : null,
222
+ fileTab?.editing && !editing ? /*#__PURE__*/ jsx("button", {
223
+ type: "button",
224
+ className: "ov-file-preview__button",
225
+ disabled: loadingEdit || !fileTab.editing.loadContent && void 0 === fileTab.source.content && !fileTab.source.file,
226
+ onClick: onEditStart,
227
+ children: text.edit
228
+ }) : null,
229
+ fileTab?.editing && editing ? /*#__PURE__*/ jsxs(Fragment, {
230
+ children: [
231
+ /*#__PURE__*/ jsx("button", {
232
+ type: "button",
233
+ className: "ov-file-preview__button",
234
+ onClick: onEditCancel,
235
+ disabled: saving,
236
+ children: text.cancel
237
+ }),
238
+ /*#__PURE__*/ jsx("button", {
239
+ type: "button",
240
+ className: "ov-file-preview__button--primary",
241
+ onClick: onEditSave,
242
+ disabled: saving,
243
+ children: text.save
244
+ })
245
+ ]
246
+ }) : null,
247
+ fileTab?.operations?.download ? /*#__PURE__*/ jsx("button", {
248
+ type: "button",
249
+ className: "ov-file-preview__button",
250
+ onClick: ()=>{
251
+ performPreviewOperation(fileTab.operations?.download, fileTab.onDownload);
252
+ },
253
+ children: text.download
254
+ }) : null,
255
+ headerActions ? /*#__PURE__*/ jsx("span", {
256
+ className: "ov-file-preview__extra-actions",
257
+ children: headerActions
258
+ }) : null
259
+ ]
260
+ })
261
+ ]
262
+ });
263
+ }
264
+ function useFilePreviewEditing() {
265
+ const [editing, setEditing] = useState(false);
266
+ const [loadingEdit, setLoadingEdit] = useState(false);
267
+ const [editFailed, setEditFailed] = useState(false);
268
+ const [saving, setSaving] = useState(false);
269
+ const [saveFailed, setSaveFailed] = useState(false);
270
+ const [draft, setDraft] = useState('');
271
+ const requestId = useRef(0);
272
+ const loading = useRef(false);
273
+ const pendingSave = useRef(false);
274
+ function discard(tab) {
275
+ requestId.current += 1;
276
+ loading.current = false;
277
+ setEditing(false);
278
+ setLoadingEdit(false);
279
+ setEditFailed(false);
280
+ setSaveFailed(false);
281
+ setDraft('');
282
+ if (editing && 'file' === tab.kind) tab.editing?.onCancel?.(draft);
283
+ }
284
+ async function start(tab) {
285
+ if (loading.current || pendingSave.current) return;
286
+ const id = ++requestId.current;
287
+ loading.current = true;
288
+ setLoadingEdit(true);
289
+ setEditFailed(false);
290
+ setSaveFailed(false);
291
+ let content;
292
+ try {
293
+ content = tab.editing?.loadContent ? await tab.editing.loadContent(tab.source) : tab.source.content ?? await tab.source.file?.text();
294
+ } catch {
295
+ if (id === requestId.current) setEditFailed(true);
296
+ }
297
+ if (id !== requestId.current) return;
298
+ loading.current = false;
299
+ setLoadingEdit(false);
300
+ if (void 0 !== content) {
301
+ setDraft(content);
302
+ setEditing(true);
303
+ }
304
+ }
305
+ async function save(tab) {
306
+ if (!editing || !tab.editing || pendingSave.current) return;
307
+ pendingSave.current = true;
308
+ setSaving(true);
309
+ setSaveFailed(false);
310
+ const value = draft;
311
+ try {
312
+ await tab.editing.save(value);
313
+ } catch {
314
+ setSaveFailed(true);
315
+ return;
316
+ } finally{
317
+ pendingSave.current = false;
318
+ setSaving(false);
319
+ }
320
+ setEditing(false);
321
+ setDraft('');
322
+ tab.editing.onSave?.(value);
323
+ }
324
+ return {
325
+ editing,
326
+ loadingEdit,
327
+ editFailed,
328
+ saving,
329
+ saveFailed,
330
+ draft,
331
+ discard,
332
+ start,
333
+ save,
334
+ updateDraft: (value)=>{
335
+ setDraft(value);
336
+ setSaveFailed(false);
337
+ }
338
+ };
339
+ }
340
+ function isFileTab(tab) {
341
+ return 'file' === tab.kind;
342
+ }
343
+ const file_preview_FilePreview = /*#__PURE__*/ forwardRef(function({ tabs, labels, className, ...rest }, ref) {
344
+ const text = {
345
+ ...DEFAULT_LABELS,
346
+ ...labels
347
+ };
348
+ const [activeKey, setActiveKey] = useState(()=>tabs[0].key);
349
+ const [viewMode, setViewMode] = useState('preview');
350
+ const editor = useFilePreviewEditing();
351
+ const activeTab = tabs.find((tab)=>tab.key === activeKey) ?? tabs[0];
352
+ const tabText = {
353
+ ...text,
354
+ ...activeTab.labels
355
+ };
356
+ const fileTab = isFileTab(activeTab) ? activeTab : void 0;
357
+ const contentTab = isFileTab(activeTab) ? void 0 : activeTab;
358
+ const switchTab = (key)=>{
359
+ if (key === activeKey) return true;
360
+ if (editor.saving) return false;
361
+ setActiveKey(key);
362
+ setViewMode('preview');
363
+ editor.discard(activeTab);
364
+ return true;
365
+ };
366
+ useImperativeHandle(ref, ()=>({
367
+ setActiveTab: (key)=>{
368
+ const target = tabs.find((tab)=>tab.key === key);
369
+ if (!target || target.disabled) return false;
370
+ return switchTab(key);
371
+ },
372
+ getActiveTab: ()=>activeKey
373
+ }));
374
+ const handleTabClick = (tab)=>{
375
+ if (tab.disabled) return;
376
+ switchTab(tab.key);
377
+ };
378
+ return /*#__PURE__*/ jsxs("div", {
379
+ ...rest,
380
+ className: [
381
+ 'ov-file-preview',
382
+ className
383
+ ].filter(Boolean).join(' '),
384
+ children: [
385
+ /*#__PURE__*/ jsx("div", {
386
+ role: "tablist",
387
+ className: "ov-file-preview__tab-row",
388
+ children: tabs.map((tab)=>/*#__PURE__*/ jsxs("button", {
389
+ type: "button",
390
+ role: "tab",
391
+ "aria-selected": tab.key === activeTab.key,
392
+ disabled: tab.disabled || editor.saving,
393
+ className: "ov-file-preview__tab",
394
+ onClick: ()=>handleTabClick(tab),
395
+ children: [
396
+ /*#__PURE__*/ jsx("span", {
397
+ className: "ov-file-preview__icon-slot",
398
+ children: tab.icon ?? /*#__PURE__*/ jsx(FileIcon, {})
399
+ }),
400
+ /*#__PURE__*/ jsx("span", {
401
+ className: "ov-file-preview__tab-title",
402
+ children: tab.title ?? (isFileTab(tab) ? tab.source.fileName : tab.key)
403
+ })
404
+ ]
405
+ }, tab.key))
406
+ }),
407
+ /*#__PURE__*/ jsx(FilePreviewHeader, {
408
+ activeTab: activeTab,
409
+ fileTab: fileTab,
410
+ text: tabText,
411
+ viewMode: viewMode,
412
+ editing: editor.editing,
413
+ loadingEdit: editor.loadingEdit,
414
+ saving: editor.saving,
415
+ onViewModeChange: setViewMode,
416
+ onEditStart: ()=>{
417
+ if (fileTab) editor.start(fileTab);
418
+ },
419
+ onEditCancel: ()=>editor.discard(activeTab),
420
+ onEditSave: ()=>{
421
+ if (fileTab) editor.save(fileTab);
422
+ }
423
+ }),
424
+ /*#__PURE__*/ jsx("div", {
425
+ className: "ov-file-preview__body",
426
+ children: /*#__PURE__*/ jsx(FilePreviewBody, {
427
+ fileTab: fileTab,
428
+ contentTab: contentTab,
429
+ text: tabText,
430
+ editing: editor.editing,
431
+ loadingEdit: editor.loadingEdit,
432
+ editFailed: editor.editFailed,
433
+ saving: editor.saving,
434
+ saveFailed: editor.saveFailed,
435
+ draft: editor.draft,
436
+ onDraftChange: editor.updateDraft
437
+ })
438
+ })
439
+ ]
440
+ });
441
+ });
442
+ export { file_preview_FilePreview as FilePreview };
@@ -0,0 +1,14 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { FileTreeRowContext } from './file-tree-row-context.js';
3
+ import type { FileTreeLabels, FileTreeRow } from './types.js';
4
+ export interface FileTreeBodyProps {
5
+ rows: readonly FileTreeRow[];
6
+ isReady: boolean;
7
+ text: Required<FileTreeLabels>;
8
+ loadingFallback?: ReactNode;
9
+ errorFallback?: ReactNode;
10
+ emptyFallback?: ReactNode;
11
+ ctx: FileTreeRowContext;
12
+ }
13
+ /** 树内容区:加载中、整树失败、空态与正常行列表。 */
14
+ export declare function FileTreeBody({ rows, isReady, text, loadingFallback, errorFallback, emptyFallback, ctx, }: FileTreeBodyProps): import("react").JSX.Element;
@@ -0,0 +1,4 @@
1
+ /** 按 DOM 顺序取出所有行元素,用于键盘上下移动焦点。 */
2
+ export declare function queryRowElements(root: HTMLElement | null): HTMLElement[];
3
+ /** 按行 id 找到行元素;行不在当前可见列表中时返回 `null`。 */
4
+ export declare function findRowElement(root: HTMLElement | null, id: string): HTMLElement | null;
@@ -0,0 +1,6 @@
1
+ import { type FileTreeRowContext } from './file-tree-row-context.js';
2
+ import { type FileTreeEntryRow } from './types.js';
3
+ export declare function FileTreeEntryRowView({ row, ctx, }: {
4
+ row: FileTreeEntryRow;
5
+ ctx: FileTreeRowContext;
6
+ }): import("react").JSX.Element;
@@ -0,0 +1,8 @@
1
+ export declare function Chevron({ expanded }: {
2
+ expanded: boolean;
3
+ }): import("react").JSX.Element;
4
+ export declare function FolderIcon({ open }: {
5
+ open: boolean;
6
+ }): import("react").JSX.Element;
7
+ export declare function FileIcon(): import("react").JSX.Element;
8
+ export declare function Spinner(): import("react").JSX.Element;
@@ -0,0 +1,10 @@
1
+ import type { KeyboardEvent } from 'react';
2
+ import type { FileTreeEntryRow } from './types.js';
3
+ export interface FileTreeKeyHandlerOptions {
4
+ root: HTMLElement | null;
5
+ row: FileTreeEntryRow;
6
+ onSelect?: (row: FileTreeEntryRow) => void;
7
+ onToggleExpand?: (row: FileTreeEntryRow) => void;
8
+ }
9
+ /** 树行的键盘语义:上下移动焦点,左右展开折叠,回车与空格选中。 */
10
+ export declare function handleRowKeyDown(event: KeyboardEvent<HTMLDivElement>, { root, row, onSelect, onToggleExpand }: FileTreeKeyHandlerOptions): void;
@@ -0,0 +1,5 @@
1
+ import type { FileTreeLabels } from './types.js';
2
+ /** 组件内置文案,宿主可通过 `labels` 逐项覆盖。 */
3
+ export declare const DEFAULT_LABELS: Required<FileTreeLabels>;
4
+ /** 用节点名替换文案里的 `{name}` 占位。 */
5
+ export declare function fillName(template: string, name: string): string;
@@ -0,0 +1,24 @@
1
+ import type { KeyboardEvent, ReactNode } from 'react';
2
+ import type { HTMLAttributes } from 'react';
3
+ import type { FileTreeEntryRow, FileTreeErrorRow, FileTreeLabels, FileTreeLoadMoreRow, FileTreeRow } from './types.js';
4
+ /** 渲染行所需的外部输入,由组件主体注入。 */
5
+ export interface FileTreeRowContext {
6
+ text: Required<FileTreeLabels>;
7
+ selectedId?: string | null;
8
+ tooltipRowId: string | null;
9
+ getRowAttributes?: (row: FileTreeRow) => HTMLAttributes<HTMLDivElement>;
10
+ renderDashboard?: (row: FileTreeEntryRow) => ReactNode;
11
+ renderRowTooltip?: (row: FileTreeEntryRow) => ReactNode;
12
+ onSelect?: (row: FileTreeEntryRow) => void;
13
+ onToggleExpand?: (row: FileTreeEntryRow) => void;
14
+ onLoadMore?: (row: FileTreeLoadMoreRow) => void;
15
+ onRetry?: (row: FileTreeErrorRow) => void;
16
+ onOpenRetentionSettings?: (uri: string) => void;
17
+ onRowKeyDown: (event: KeyboardEvent<HTMLDivElement>, row: FileTreeEntryRow) => void;
18
+ onRowEnter: (rowId: string) => void;
19
+ onRowLeave: () => void;
20
+ }
21
+ /** 行按深度缩进,其余内边距由样式负责。 */
22
+ export declare function rowIndent(row: FileTreeRow): {
23
+ paddingLeft: string;
24
+ };
@@ -0,0 +1,12 @@
1
+ import { type FileTreeRowContext } from './file-tree-row-context.js';
2
+ import { type FileTreeRow } from './types.js';
3
+ /**
4
+ * 整树级失败:只有一个错误行且没有归属父节点。
5
+ * Whole-tree failure: a single error row that belongs to no parent.
6
+ */
7
+ export declare function isWholeTreeError(rows: readonly FileTreeRow[]): boolean;
8
+ /** 按行类型分派渲染,条目行与状态行分别处理。 */
9
+ export declare function FileTreeRowView({ row, ctx, }: {
10
+ row: FileTreeRow;
11
+ ctx: FileTreeRowContext;
12
+ }): import("react").JSX.Element;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * 悬停停留一段时间后才展示行提示。
3
+ *
4
+ * 用 timeout 而不是 CSS 延迟,是因为提示内容由宿主渲染、需要按行 id 切换;
5
+ * 卸载或换行时清掉未触发的定时器,避免迟到的回调写入已失效的行。
6
+ */
7
+ export declare function useRowTooltip(delay?: number): {
8
+ tooltipRowId: string | null;
9
+ show: (rowId: string) => void;
10
+ hide: () => void;
11
+ };
@@ -0,0 +1,4 @@
1
+ import type { FileTreeComponent } from './types.js';
2
+ export { FILE_TREE_ROW_ATTRIBUTE } from './types.js';
3
+ export type { FileTreeChildRow, FileTreeComponent, FileTreeEmptyRow, FileTreeEntryRow, FileTreeErrorRow, FileTreeHandle, FileTreeLabels, FileTreeLoadingRow, FileTreeLoadMoreRow, FileTreeOperations, FileTreeProps, FileTreeRow, FileTreeRowBase, FileTreeSlots, } from './types.js';
4
+ export declare const FileTree: FileTreeComponent;
@@ -0,0 +1 @@
1
+ export * from './file-tree.js';