@openviking/react 0.1.1 → 0.1.2
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/README.md +18 -15
- package/dist/3~0.js +2113 -4
- package/dist/ark-message-list-view~0.js +310 -0
- package/dist/c7~0.js +24 -0
- package/dist/components/agent-connect/agent-connect-copy.d.ts +34 -0
- package/dist/components/agent-connect/agent-connect-design.d.ts +1781 -0
- package/dist/components/agent-connect/agent-connect-detail.d.ts +13 -0
- package/dist/components/agent-connect/agent-connect-installer.d.ts +3 -0
- package/dist/components/agent-connect/agent-connect-instructions-view.d.ts +14 -0
- package/dist/components/agent-connect/agent-connect-instructions.d.ts +145 -0
- package/dist/components/agent-connect/agent-connect-markdown.d.ts +3 -0
- package/dist/components/agent-connect/agent-connect.d.ts +3 -3
- package/dist/components/agent-connect/content-en.d.ts +137 -0
- package/dist/components/agent-connect/content-zh.d.ts +137 -0
- package/dist/components/agent-connect/style.css +495 -6
- package/dist/components/agent-connect/types.d.ts +20 -166
- package/dist/components/file-preview/file-preview-adapters.d.ts +33 -0
- package/dist/components/file-preview/file-preview-body.d.ts +24 -12
- package/dist/components/file-preview/file-preview-breadcrumb-menu.d.ts +16 -0
- package/dist/components/file-preview/file-preview-breadcrumb.d.ts +21 -0
- package/dist/components/file-preview/file-preview-copy-path.d.ts +12 -0
- package/dist/components/file-preview/file-preview-editor.d.ts +22 -0
- package/dist/components/file-preview/file-preview-handle-adapters.d.ts +26 -0
- package/dist/components/file-preview/file-preview-header.d.ts +23 -14
- package/dist/components/file-preview/file-preview-labels.d.ts +15 -4
- package/dist/components/file-preview/file-preview-lazy-viewer.d.ts +3 -0
- package/dist/components/file-preview/file-preview-path.d.ts +30 -0
- package/dist/components/file-preview/file-preview-source.d.ts +24 -0
- package/dist/components/file-preview/file-preview-state.d.ts +28 -0
- package/dist/components/file-preview/file-preview-tab-row.d.ts +16 -0
- package/dist/components/file-preview/file-preview-viewer.d.ts +31 -0
- package/dist/components/file-preview/file-preview.d.ts +8 -11
- package/dist/components/file-preview/style.css +3984 -128
- package/dist/components/file-preview/types.d.ts +250 -169
- package/dist/components/file-preview/use-file-preview-actions-context.d.ts +23 -0
- package/dist/components/file-preview/use-file-preview-actions.d.ts +19 -0
- package/dist/components/file-preview/use-file-preview-editing.d.ts +21 -2
- package/dist/components/file-preview/use-file-preview-ids.d.ts +24 -0
- package/dist/components/file-preview.js +1 -442
- package/dist/components/file-tree/file-tree-body.d.ts +8 -4
- package/dist/components/file-tree/file-tree-entry-row.d.ts +9 -3
- package/dist/components/file-tree/file-tree-icons.d.ts +12 -5
- package/dist/components/file-tree/file-tree-info-labels.d.ts +21 -0
- package/dist/components/file-tree/file-tree-info-tooltip.d.ts +43 -0
- package/dist/components/file-tree/file-tree-info.d.ts +29 -0
- package/dist/components/file-tree/file-tree-keyboard.d.ts +8 -4
- package/dist/components/file-tree/file-tree-row-context.d.ts +31 -9
- package/dist/components/file-tree/file-tree-row-shared.d.ts +11 -0
- package/dist/components/file-tree/file-tree-spinner.d.ts +10 -0
- package/dist/components/file-tree/file-tree-state-row.d.ts +7 -0
- package/dist/components/file-tree/file-tree-tooltip-surface.d.ts +22 -0
- package/dist/components/file-tree/file-tree-tooltip.d.ts +9 -3
- package/dist/components/file-tree/file-tree.d.ts +12 -1
- package/dist/components/file-tree/style.css +225 -57
- package/dist/components/file-tree/types.d.ts +183 -0
- package/dist/components/file-tree/use-file-tree-actions.d.ts +7 -0
- package/dist/components/file-tree.js +1 -1
- package/dist/components/scope-switcher/scope-panel.d.ts +9 -3
- package/dist/components/scope-switcher/scope-selector.d.ts +1 -1
- package/dist/components/scope-switcher/scope-switcher.d.ts +1 -1
- package/dist/components/scope-switcher/style.css +282 -76
- package/dist/components/scope-switcher/types.d.ts +230 -108
- package/dist/components/style.css +13845 -372
- package/dist/components/tui/command-catalog.d.ts +58 -0
- package/dist/components/tui/command-completion.d.ts +19 -0
- package/dist/components/tui/command-definitions.d.ts +10 -0
- package/dist/components/tui/command-input.d.ts +16 -0
- package/dist/components/tui/style.css +1543 -5
- package/dist/components/tui/tui-assist.d.ts +15 -0
- package/dist/components/tui/tui-code-block.d.ts +8 -0
- package/dist/components/tui/tui-command-help.d.ts +9 -0
- package/dist/components/tui/tui-command-text.d.ts +6 -0
- package/dist/components/tui/tui-composer.d.ts +24 -0
- package/dist/components/tui/tui-copy-button.d.ts +9 -0
- package/dist/components/tui/tui-input-mirror.d.ts +14 -0
- package/dist/components/tui/tui-labels-zh.d.ts +2 -0
- package/dist/components/tui/tui-labels.d.ts +5 -0
- package/dist/components/tui/tui-markdown-renderers.d.ts +10 -0
- package/dist/components/tui/tui-markdown.d.ts +6 -0
- package/dist/components/tui/tui-param-hint.d.ts +7 -0
- package/dist/components/tui/tui-record-time.d.ts +11 -0
- package/dist/components/tui/tui-record.d.ts +13 -0
- package/dist/components/tui/tui-resource-preview.d.ts +10 -0
- package/dist/components/tui/tui-resource-tree.d.ts +10 -0
- package/dist/components/tui/tui-result-header.d.ts +7 -0
- package/dist/components/tui/tui-result-text.d.ts +5 -0
- package/dist/components/tui/tui-search-list.d.ts +8 -0
- package/dist/components/tui/tui-skeleton.d.ts +6 -0
- package/dist/components/tui/tui-status-card.d.ts +7 -0
- package/dist/components/tui/tui-text.d.ts +10 -0
- package/dist/components/tui/tui-uri-text.d.ts +19 -0
- package/dist/components/tui/tui-write-result.d.ts +7 -0
- package/dist/components/tui/tui.d.ts +10 -2
- package/dist/components/tui/types.d.ts +57 -15
- package/dist/components/tui/use-tui-assist-position.d.ts +3 -0
- package/dist/components/tui/use-tui-completion.d.ts +14 -0
- package/dist/components/tui/use-tui-composer-keyboard.d.ts +25 -0
- package/dist/components/viking-bot/ark-adapter.d.ts +45 -0
- package/dist/components/viking-bot/ark-message-body.d.ts +16 -0
- package/dist/components/viking-bot/ark-message-list-view.d.ts +7 -0
- package/dist/components/viking-bot/ark-message-row.d.ts +19 -0
- package/dist/components/viking-bot/index.d.ts +10 -0
- package/dist/components/viking-bot/interaction/ask-human-fields.d.ts +10 -0
- package/dist/components/viking-bot/interaction/index.d.ts +4 -0
- package/dist/components/viking-bot/interaction/labels.d.ts +7 -0
- package/dist/components/viking-bot/interaction/lazy-interaction.d.ts +3 -0
- package/dist/components/viking-bot/interaction/schedule-input.d.ts +13 -0
- package/dist/components/viking-bot/interaction/style.css +189 -0
- package/dist/components/viking-bot/interaction/types.d.ts +188 -0
- package/dist/components/viking-bot/interaction/viking-bot-interaction.d.ts +9 -0
- package/dist/components/viking-bot/interaction.js +2 -0
- package/dist/components/viking-bot/labels.d.ts +2 -0
- package/dist/components/viking-bot/lazy-composer.d.ts +3 -0
- package/dist/components/viking-bot/message-groups.d.ts +12 -0
- package/dist/components/viking-bot/model.d.ts +252 -0
- package/dist/components/viking-bot/render-part.d.ts +12 -0
- package/dist/components/viking-bot/style.css +7135 -0
- package/dist/components/viking-bot/style.js +0 -0
- package/dist/components/viking-bot/types.d.ts +140 -0
- package/dist/components/viking-bot/viking-bot-composer.d.ts +6 -0
- package/dist/components/viking-bot/viking-bot-message-list.d.ts +3 -0
- package/dist/components/viking-bot/viking-bot.d.ts +16 -0
- package/dist/components/viking-bot.js +4 -0
- package/dist/c~0.js +201 -0
- package/dist/file-preview-viewer~0.js +191 -0
- package/dist/f~0.js +149 -77
- package/dist/g~0.js +1207 -0
- package/dist/h~0.js +58 -0
- package/dist/icons/file-type-icon.d.ts +31 -0
- package/dist/icons/index.d.ts +33 -23
- package/dist/icons/nextjs-icon.d.ts +19 -0
- package/dist/icons.js +1 -25
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/k~0.js +1440 -0
- package/dist/lk~0.js +25 -12
- package/dist/modules/console/style.css +83 -1
- package/dist/modules/file-browser/style.css +89 -6
- package/dist/modules/scope-cascade/style.css +282 -76
- package/dist/modules/style.css +533 -110
- package/dist/n~0.js +434 -206
- package/dist/shared/components/tooltip/index.d.ts +1 -0
- package/dist/shared/components/tooltip/tooltip.d.ts +25 -0
- package/dist/shared/components/tooltip/types.d.ts +42 -0
- package/dist/shared/components/tooltip/use-tooltip-position.d.ts +38 -0
- package/dist/style.css +14451 -474
- package/dist/u~0.js +1597 -4
- package/dist/viking-bot-composer~0.js +164 -0
- package/dist/viking-bot-interaction~0.js +284 -0
- package/dist/w~0.js +19 -0
- package/package.json +18 -10
- package/dist/components/file-preview/file-preview-icons.d.ts +0 -2
- package/dist/components/file-preview/file-preview-operations.d.ts +0 -1
- package/dist/components/file-tree/file-tree-dom.d.ts +0 -4
- package/dist/components/file-tree/file-tree-labels.d.ts +0 -5
- package/dist/components/file-tree/file-tree-rows.d.ts +0 -12
- package/dist/i~0.js +0 -21
- package/dist/modules/task-center/columns.d.ts +0 -129
- package/dist/modules/task-center/index.d.ts +0 -1
- package/dist/modules/task-center/style.css +0 -29
- package/dist/modules/task-center/task-center.d.ts +0 -4
- package/dist/modules/task-center/types.d.ts +0 -168
- package/dist/modules/task-center.js +0 -1
- /package/dist/{modules/task-center → components/viking-bot/interaction}/style.js +0 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 页签与面板的 DOM id 生成器,带实例前缀。
|
|
3
|
+
*
|
|
4
|
+
* 只用宿主给的 `tab.key` 拼 id,两个预览同时挂载时会产生重复 id,`aria-controls`
|
|
5
|
+
* 与 `aria-labelledby` 因此可能指向另一个实例的元素。`useId` 给出每个实例唯一
|
|
6
|
+
* 的前缀,页签行与面板两侧共用同一份。
|
|
7
|
+
*
|
|
8
|
+
* DOM id generators for tabs and panels, prefixed per instance.
|
|
9
|
+
*
|
|
10
|
+
* Building ids from the host's `tab.key` alone collides when two previews are
|
|
11
|
+
* mounted at once, so `aria-controls` and `aria-labelledby` could point at the
|
|
12
|
+
* other instance's elements. `useId` supplies a unique prefix per instance, shared
|
|
13
|
+
* by the tab row and the panels.
|
|
14
|
+
*/
|
|
15
|
+
export declare function useFilePreviewIds(activeKey: string): {
|
|
16
|
+
tabId: (key: string) => string;
|
|
17
|
+
panelId: (key: string) => string;
|
|
18
|
+
/** 面板的公共属性:id、role 与 aria 关联,随当前页签变化。 */
|
|
19
|
+
panelProps: {
|
|
20
|
+
id: string;
|
|
21
|
+
role: 'tabpanel';
|
|
22
|
+
'aria-labelledby': string;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
@@ -1,442 +1 @@
|
|
|
1
|
-
|
|
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 };
|
|
1
|
+
export { FilePreview } from "../g~0.js";
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
|
-
import type { FileTreeRowContext } from './file-tree-row-context.js';
|
|
3
|
-
import type {
|
|
2
|
+
import type { FileTreeRowContext, ResolvedLabels } from './file-tree-row-context.js';
|
|
3
|
+
import type { FileTreeRow } from './types.js';
|
|
4
4
|
export interface FileTreeBodyProps {
|
|
5
5
|
rows: readonly FileTreeRow[];
|
|
6
6
|
isReady: boolean;
|
|
7
|
-
text:
|
|
7
|
+
text: ResolvedLabels;
|
|
8
8
|
loadingFallback?: ReactNode;
|
|
9
9
|
errorFallback?: ReactNode;
|
|
10
10
|
emptyFallback?: ReactNode;
|
|
11
11
|
ctx: FileTreeRowContext;
|
|
12
12
|
}
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* 树内容区:首次加载、整树失败、空态与正常行列表。
|
|
15
|
+
*
|
|
16
|
+
* The tree body: first load, whole-tree failure, empty state, and the row list.
|
|
17
|
+
*/
|
|
14
18
|
export declare function FileTreeBody({ rows, isReady, text, loadingFallback, errorFallback, emptyFallback, ctx, }: FileTreeBodyProps): import("react").JSX.Element;
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import type { FileTreeRowContext } from './file-tree-row-context.js';
|
|
2
|
+
import type { FileTreeEntryRow } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* 一条条目行:展开箭头、图标、名称、行内说明、行尾指示器与悬停浮层。
|
|
5
|
+
*
|
|
6
|
+
* One entry row: chevron, icon, name, inline description, the row-end indicator
|
|
7
|
+
* and the hover tooltip.
|
|
8
|
+
*/
|
|
9
|
+
export declare function FileTreeRowView({ row, ctx, }: {
|
|
4
10
|
row: FileTreeEntryRow;
|
|
5
11
|
ctx: FileTreeRowContext;
|
|
6
12
|
}): import("react").JSX.Element;
|
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* 文件夹图标。展开态与收起态叠放在一起交叉淡入,和宿主一致。
|
|
3
|
+
*
|
|
4
|
+
* The folder icon. The open and collapsed states sit stacked and cross-fade,
|
|
5
|
+
* matching the host tree.
|
|
6
|
+
*/
|
|
7
|
+
export declare function FileTreeFolderIcon({ open }: {
|
|
8
|
+
open: boolean;
|
|
3
9
|
}): import("react").JSX.Element;
|
|
4
|
-
|
|
10
|
+
/** 宿主没有提供 `renderRowIcon` 时的文件图标。Fallback file icon. */
|
|
11
|
+
export declare function FileTreeFileIcon(): import("react").JSX.Element;
|
|
12
|
+
/** 展开箭头,展开时旋转 90°。The expand chevron, rotated when open. */
|
|
13
|
+
export declare function FileTreeChevron({ open }: {
|
|
5
14
|
open: boolean;
|
|
6
15
|
}): 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,21 @@
|
|
|
1
|
+
import type { FileTreeInfoKey, FileTreeInfoLabels } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* 内置英文文案。`FileTreeLabels.info` 未提供的键沿用这里的值。
|
|
4
|
+
*
|
|
5
|
+
* Built-in English copy. Keys missing from `FileTreeLabels.info` fall back here.
|
|
6
|
+
*/
|
|
7
|
+
export declare const DEFAULT_INFO_LABELS: FileTreeInfoLabels;
|
|
8
|
+
/**
|
|
9
|
+
* 按宿主的覆盖合并内置文案,键为单位。宿主的空字符串表示该键不显示,因此
|
|
10
|
+
* 合并时保留空串,由渲染方判断。
|
|
11
|
+
*
|
|
12
|
+
* Merges host overrides over the built-in copy, key by key. An empty host string
|
|
13
|
+
* means "hide this key", so it is kept and the renderer decides.
|
|
14
|
+
*
|
|
15
|
+
* Returns the copy of one key, or `undefined` when the key is hidden or has no
|
|
16
|
+
* copy.
|
|
17
|
+
*/
|
|
18
|
+
export declare function resolveInfoCopy(key: FileTreeInfoKey, hostLabels: FileTreeInfoLabels | undefined): {
|
|
19
|
+
description?: string;
|
|
20
|
+
triggerBehavior?: string;
|
|
21
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { FileTreeEntryRow, FileTreeInfoLabels } from './types.js';
|
|
2
|
+
export interface FileTreeInfoCopy {
|
|
3
|
+
/** 行名称,作为浮层标题。Row name, used as the tooltip title. */
|
|
4
|
+
title: string;
|
|
5
|
+
/** 说明,已按行内同样的优先级解析。Description, resolved with the same precedence as inline. */
|
|
6
|
+
description?: string;
|
|
7
|
+
/** 触发行为,只出现在浮层。Trigger copy, tooltip only. */
|
|
8
|
+
triggerBehavior?: string;
|
|
9
|
+
/** 完整路径。Full path. */
|
|
10
|
+
path: string;
|
|
11
|
+
/** 浮层里各行的字段名。Field names used inside the tooltip. */
|
|
12
|
+
fields: {
|
|
13
|
+
description: string;
|
|
14
|
+
triggerBehavior: string;
|
|
15
|
+
path: string;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* 解析目录浮层要显示的内容,没有可显示内容时返回 `null`。
|
|
20
|
+
*
|
|
21
|
+
* 说明按 `row.description` → 内置文案的顺序解析,与行内一致:宿主给了就用宿主的
|
|
22
|
+
* (含显式空串),没给才用内置。调用方据此决定是否创建浮层外壳,避免留下一个
|
|
23
|
+
* 只有背景和内边距的空壳。
|
|
24
|
+
*
|
|
25
|
+
* Resolves what a directory tooltip should show, or `null` when there is nothing.
|
|
26
|
+
*
|
|
27
|
+
* The description resolves as `row.description` then built-in copy, matching the
|
|
28
|
+
* inline behaviour: a host value wins, including an explicit empty string, and
|
|
29
|
+
* the built-in copy applies only when absent. The caller uses this to decide
|
|
30
|
+
* whether to create the tooltip shell, so no empty shell is left behind.
|
|
31
|
+
*/
|
|
32
|
+
export declare function resolveFileTreeInfoCopy(row: FileTreeEntryRow, infoLabels?: FileTreeInfoLabels): FileTreeInfoCopy | null;
|
|
33
|
+
/**
|
|
34
|
+
* 目录的默认浮层内容:说明、触发行为与路径。九类长期记忆的说明只出现在这里,
|
|
35
|
+
* 因此这个浮层是它们唯一的展示位置。
|
|
36
|
+
*
|
|
37
|
+
* The default tooltip content for a directory: description, trigger copy and
|
|
38
|
+
* path. The nine long-term-memory keys describe themselves here only, so this
|
|
39
|
+
* tooltip is the sole place their copy appears.
|
|
40
|
+
*/
|
|
41
|
+
export declare function FileTreeInfoTooltip({ copy }: {
|
|
42
|
+
copy: FileTreeInfoCopy;
|
|
43
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { FileTreeInfoKey } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* 把 `viking://` 地址拆成小写路径段,忽略协议、查询串与末尾斜杠。
|
|
4
|
+
*
|
|
5
|
+
* Splits a `viking://` address into lower-cased segments, ignoring the scheme,
|
|
6
|
+
* query string and trailing slashes.
|
|
7
|
+
*/
|
|
8
|
+
export declare function splitVikingUri(uri: string): string[];
|
|
9
|
+
/**
|
|
10
|
+
* 按路径结构判定目录的语义键,判定不出来时返回 `null`。
|
|
11
|
+
*
|
|
12
|
+
* 只认路径形状,不认节点类型:同名目录在目录与文件位置上含义相同,由调用方
|
|
13
|
+
* 决定是否使用。判定规则与产品无关,任何宿主都能直接命中。
|
|
14
|
+
*
|
|
15
|
+
* Resolves the semantic key of a directory from its path structure, or `null`
|
|
16
|
+
* when nothing matches.
|
|
17
|
+
*
|
|
18
|
+
* Only the path shape is inspected, not the node type: a name means the same
|
|
19
|
+
* thing whether it is a directory or a file, and the caller decides whether to
|
|
20
|
+
* use it. The rules are product-neutral, so any host matches them.
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolveFileTreeInfoKey(uri: string): FileTreeInfoKey | null;
|
|
23
|
+
/**
|
|
24
|
+
* 该键的说明是否显示在行内。判定不出来时为 `false`。
|
|
25
|
+
*
|
|
26
|
+
* Whether the description of this key renders inline; `false` when nothing
|
|
27
|
+
* matched.
|
|
28
|
+
*/
|
|
29
|
+
export declare function showsInlineDescription(key: FileTreeInfoKey | null): boolean;
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import type { KeyboardEvent } from 'react';
|
|
2
2
|
import type { FileTreeEntryRow } from './types.js';
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* 树行的键盘语义:上下移动焦点,左右展开折叠,回车与空格选中。
|
|
5
|
+
*
|
|
6
|
+
* Keyboard semantics for a row: up/down move focus, left/right collapse and
|
|
7
|
+
* expand, Enter and Space select.
|
|
8
|
+
*/
|
|
9
|
+
export declare function handleRowKeyDown(event: KeyboardEvent<HTMLDivElement>, { root, row, onSelect, onToggleExpand, }: {
|
|
4
10
|
root: HTMLElement | null;
|
|
5
11
|
row: FileTreeEntryRow;
|
|
6
12
|
onSelect?: (row: FileTreeEntryRow) => void;
|
|
7
13
|
onToggleExpand?: (row: FileTreeEntryRow) => void;
|
|
8
|
-
}
|
|
9
|
-
/** 树行的键盘语义:上下移动焦点,左右展开折叠,回车与空格选中。 */
|
|
10
|
-
export declare function handleRowKeyDown(event: KeyboardEvent<HTMLDivElement>, { root, row, onSelect, onToggleExpand }: FileTreeKeyHandlerOptions): void;
|
|
14
|
+
}): void;
|