@adecore/agents-react 0.37.1 → 0.37.3
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/chat/chat-client.d.ts +1 -0
- package/dist/chat/chat-client.js +2 -1
- package/dist/chat/chat-references.d.ts +16 -1
- package/dist/chat/chat-references.js +29 -3
- package/dist/chat/drafts.d.ts +2 -0
- package/dist/chat/drafts.js +21 -5
- package/dist/chat/index.d.ts +1 -1
- package/dist/chat/logic/picker-entries.d.ts +6 -1
- package/dist/chat/logic/picker-entries.js +10 -0
- package/dist/chat/mentions.d.ts +31 -14
- package/dist/chat/mentions.js +186 -41
- package/dist/chat/stash.d.ts +1 -0
- package/dist/chat/stash.js +4 -2
- package/dist/chat/ui/Composer.js +438 -429
- package/dist/chat/ui/ComposerInput.d.ts +1 -0
- package/dist/chat/ui/ComposerInput.js +2 -0
- package/dist/chat/ui/Markdown.d.ts +3 -1
- package/dist/chat/ui/Markdown.js +194 -120
- package/dist/chat/ui/MessageActions.js +70 -66
- package/dist/chat/ui/Pickers.js +151 -207
- package/dist/chat/ui/ReferenceChip.d.ts +15 -0
- package/dist/chat/ui/ReferenceChip.js +255 -0
- package/dist/chat/ui/RunSettings.js +25 -21
- package/dist/chat/ui/Timeline.js +52 -29
- package/dist/chat/ui/TimelineMenu.js +84 -78
- package/dist/chat/ui/chip-clipboard.d.ts +9 -0
- package/dist/chat/ui/chip-clipboard.js +105 -0
- package/dist/chat/ui/chips.d.ts +5 -0
- package/dist/chat/ui/chips.js +15 -1
- package/dist/chat/ui/composer/ComposerMenu.js +140 -79
- package/dist/chat/ui/composer/DraftParts.d.ts +0 -4
- package/dist/chat/ui/composer/DraftParts.js +0 -41
- package/dist/chat/ui/composer/chip-paste.d.ts +15 -0
- package/dist/chat/ui/composer/chip-paste.js +104 -0
- package/dist/chat/ui/composer/chips.d.ts +5 -0
- package/dist/chat/ui/composer/chips.js +59 -9
- package/dist/chat/ui/composer/key-handler.js +9 -0
- package/dist/chat/ui/composer/use-composer-draft.d.ts +0 -1
- package/dist/chat/ui/composer/use-composer-draft.js +2 -10
- package/dist/chat/ui/composer/use-composer-menus.d.ts +12 -2
- package/dist/chat/ui/composer/use-composer-menus.js +192 -149
- package/dist/chat/ui/composer/use-composer-submit.js +17 -12
- package/dist/chat/ui/composer/use-draft-files.d.ts +7 -1
- package/dist/chat/ui/composer/use-draft-files.js +90 -58
- package/dist/chat/ui/composer/use-take-back.js +2 -1
- package/dist/chat/ui/index.d.ts +0 -1
- package/dist/chat/ui/index.js +0 -1
- package/dist/chat/ui/reference-icons.d.ts +3 -0
- package/dist/chat/ui/reference-icons.js +15 -0
- package/dist/chat/ui/reference-lookup.d.ts +7 -0
- package/dist/chat/ui/reference-lookup.js +6 -0
- package/dist/chat/ui/rehype-chips.d.ts +8 -1
- package/dist/chat/ui/rehype-chips.js +35 -11
- package/dist/chat/ui/rows/MessageRows.js +218 -158
- package/dist/chat/ui/thread-references.d.ts +4 -0
- package/dist/chat/ui/thread-references.js +78 -0
- package/dist/host-hooks.d.ts +2 -0
- package/dist/host-hooks.js +7 -0
- package/dist/host.d.ts +3 -0
- package/dist/locales/en/agent-chat.d.ts +20 -3
- package/dist/locales/en/agent-chat.js +24 -7
- package/dist/locales/nl/agent-chat.d.ts +20 -3
- package/dist/locales/nl/agent-chat.js +24 -7
- package/package.json +8 -8
- package/src/chat/chat-client.ts +4 -1
- package/src/chat/chat-references.ts +44 -3
- package/src/chat/drafts.ts +24 -6
- package/src/chat/index.ts +1 -1
- package/src/chat/logic/picker-entries.ts +12 -1
- package/src/chat/mentions.ts +202 -36
- package/src/chat/stash.ts +6 -2
- package/src/chat/ui/Composer.tsx +14 -4
- package/src/chat/ui/ComposerInput.tsx +4 -0
- package/src/chat/ui/Markdown.tsx +57 -25
- package/src/chat/ui/MessageActions.tsx +5 -2
- package/src/chat/ui/Pickers.tsx +8 -2
- package/src/chat/ui/ReferenceChip.tsx +74 -0
- package/src/chat/ui/RunSettings.tsx +29 -23
- package/src/chat/ui/Timeline.tsx +24 -2
- package/src/chat/ui/TimelineMenu.tsx +7 -3
- package/src/chat/ui/chip-clipboard.ts +115 -0
- package/src/chat/ui/chips.ts +20 -1
- package/src/chat/ui/composer/ComposerMenu.tsx +53 -37
- package/src/chat/ui/composer/DraftParts.tsx +0 -12
- package/src/chat/ui/composer/chip-paste.ts +122 -0
- package/src/chat/ui/composer/chips.ts +60 -10
- package/src/chat/ui/composer/key-handler.ts +9 -0
- package/src/chat/ui/composer/use-composer-draft.ts +1 -7
- package/src/chat/ui/composer/use-composer-menus.ts +68 -29
- package/src/chat/ui/composer/use-composer-submit.ts +13 -6
- package/src/chat/ui/composer/use-draft-files.ts +39 -5
- package/src/chat/ui/composer/use-take-back.ts +2 -1
- package/src/chat/ui/index.ts +0 -1
- package/src/chat/ui/reference-icons.ts +17 -0
- package/src/chat/ui/reference-lookup.ts +13 -0
- package/src/chat/ui/rehype-chips.ts +38 -13
- package/src/chat/ui/rows/MessageRows.tsx +88 -64
- package/src/chat/ui/thread-references.ts +47 -0
- package/src/host-hooks.ts +9 -0
- package/src/host.ts +6 -1
- package/src/locales/en/agent-chat.ts +24 -7
- package/src/locales/nl/agent-chat.ts +24 -7
- package/dist/chat/ui/ChatReferenceChip.d.ts +0 -4
- package/dist/chat/ui/ChatReferenceChip.js +0 -110
- package/src/chat/ui/ChatReferenceChip.tsx +0 -26
|
@@ -9,12 +9,14 @@ import { markdownOf, messageTextOf } from '../logic/timeline-copy.js';
|
|
|
9
9
|
import { useChatHost } from '../../host.js';
|
|
10
10
|
import { useChatScope } from '../../scope.js';
|
|
11
11
|
import { useChatRow } from '../../state/chats.js';
|
|
12
|
+
import { copyWithChips, rowClipboardChips } from './chip-clipboard.js';
|
|
12
13
|
import { useFileLinkCwd, useFileLinkScopeId, useOpenFileLink } from './file-links.js';
|
|
14
|
+
import { useReferenceLookup } from './thread-references.js';
|
|
13
15
|
import { ContextMenu, copyText, DisabledReason, EDIT_SHORTCUTS, Icon, Kbd, selectAllWithin } from '@adecore/ui';
|
|
14
16
|
/* The menu behind a right-click in a thread, mostly for copying: a whole message, a code block or an answer's markdown. */
|
|
15
17
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
16
18
|
export function TimelineMenuPopup(t0) {
|
|
17
|
-
const $ = _c(
|
|
19
|
+
const $ = _c(72);
|
|
18
20
|
const {
|
|
19
21
|
target,
|
|
20
22
|
thread,
|
|
@@ -26,10 +28,11 @@ export function TimelineMenuPopup(t0) {
|
|
|
26
28
|
const {
|
|
27
29
|
t
|
|
28
30
|
} = useTranslation("agent-chat");
|
|
31
|
+
const row = target.row;
|
|
29
32
|
let t3;
|
|
30
|
-
if ($[0] !==
|
|
31
|
-
t3 =
|
|
32
|
-
$[0] =
|
|
33
|
+
if ($[0] !== row) {
|
|
34
|
+
t3 = row === null ? null : messageTextOf(row);
|
|
35
|
+
$[0] = row;
|
|
33
36
|
$[1] = t3;
|
|
34
37
|
} else {
|
|
35
38
|
t3 = $[1];
|
|
@@ -47,7 +50,7 @@ export function TimelineMenuPopup(t0) {
|
|
|
47
50
|
const turnId = t4;
|
|
48
51
|
let t5;
|
|
49
52
|
if ($[5] !== turnId) {
|
|
50
|
-
t5 =
|
|
53
|
+
t5 = row_0 => turnId === null ? null : forkRefusal(row_0?.info ?? null, row_0?.structure[turnId]);
|
|
51
54
|
$[5] = turnId;
|
|
52
55
|
$[6] = t5;
|
|
53
56
|
} else {
|
|
@@ -66,6 +69,7 @@ export function TimelineMenuPopup(t0) {
|
|
|
66
69
|
const markable = chatId !== null && (target.row?.kind === "user" || target.row?.kind === "assistant") ? target.row.id : null;
|
|
67
70
|
const cwd = useFileLinkCwd();
|
|
68
71
|
const scopeId = useFileLinkScopeId();
|
|
72
|
+
const lookup = useReferenceLookup(chatId ?? "");
|
|
69
73
|
const {
|
|
70
74
|
fork,
|
|
71
75
|
fileLinks
|
|
@@ -150,22 +154,24 @@ export function TimelineMenuPopup(t0) {
|
|
|
150
154
|
t13 = $[25];
|
|
151
155
|
}
|
|
152
156
|
let t14;
|
|
153
|
-
if ($[26] !==
|
|
154
|
-
t14 = message !== null && /*#__PURE__*/_jsxs(ContextMenu.Item, {
|
|
155
|
-
onClick: () =>
|
|
157
|
+
if ($[26] !== lookup || $[27] !== message || $[28] !== row || $[29] !== t) {
|
|
158
|
+
t14 = row !== null && message !== null && /*#__PURE__*/_jsxs(ContextMenu.Item, {
|
|
159
|
+
onClick: () => copyWithChips(rowClipboardChips(row, message, lookup)),
|
|
156
160
|
children: [/*#__PURE__*/_jsx(Icon, {
|
|
157
161
|
icon: MessageSquare,
|
|
158
162
|
size: 14
|
|
159
163
|
}), " ", t("timeline.menu.copyMessage")]
|
|
160
164
|
});
|
|
161
|
-
$[26] =
|
|
162
|
-
$[27] =
|
|
163
|
-
$[28] =
|
|
165
|
+
$[26] = lookup;
|
|
166
|
+
$[27] = message;
|
|
167
|
+
$[28] = row;
|
|
168
|
+
$[29] = t;
|
|
169
|
+
$[30] = t14;
|
|
164
170
|
} else {
|
|
165
|
-
t14 = $[
|
|
171
|
+
t14 = $[30];
|
|
166
172
|
}
|
|
167
173
|
let t15;
|
|
168
|
-
if ($[
|
|
174
|
+
if ($[31] !== t || $[32] !== target.code) {
|
|
169
175
|
t15 = target.code !== null && /*#__PURE__*/_jsxs(ContextMenu.Item, {
|
|
170
176
|
onClick: () => copyText(target.code ?? ""),
|
|
171
177
|
children: [/*#__PURE__*/_jsx(Icon, {
|
|
@@ -173,14 +179,14 @@ export function TimelineMenuPopup(t0) {
|
|
|
173
179
|
size: 14
|
|
174
180
|
}), " ", t("timeline.menu.copyCode")]
|
|
175
181
|
});
|
|
176
|
-
$[
|
|
177
|
-
$[
|
|
178
|
-
$[
|
|
182
|
+
$[31] = t;
|
|
183
|
+
$[32] = target.code;
|
|
184
|
+
$[33] = t15;
|
|
179
185
|
} else {
|
|
180
|
-
t15 = $[
|
|
186
|
+
t15 = $[33];
|
|
181
187
|
}
|
|
182
188
|
let t16;
|
|
183
|
-
if ($[
|
|
189
|
+
if ($[34] !== markdown || $[35] !== t) {
|
|
184
190
|
t16 = markdown !== null && /*#__PURE__*/_jsxs(ContextMenu.Item, {
|
|
185
191
|
onClick: () => copyText(markdown),
|
|
186
192
|
children: [/*#__PURE__*/_jsx(Icon, {
|
|
@@ -188,14 +194,14 @@ export function TimelineMenuPopup(t0) {
|
|
|
188
194
|
size: 14
|
|
189
195
|
}), " ", t("timeline.menu.copyMarkdown")]
|
|
190
196
|
});
|
|
191
|
-
$[
|
|
192
|
-
$[
|
|
193
|
-
$[
|
|
197
|
+
$[34] = markdown;
|
|
198
|
+
$[35] = t;
|
|
199
|
+
$[36] = t16;
|
|
194
200
|
} else {
|
|
195
|
-
t16 = $[
|
|
201
|
+
t16 = $[36];
|
|
196
202
|
}
|
|
197
203
|
let t17;
|
|
198
|
-
if ($[
|
|
204
|
+
if ($[37] !== chatId || $[38] !== fork || $[39] !== forkBlocked || $[40] !== t || $[41] !== turnId) {
|
|
199
205
|
t17 = chatId !== null && turnId !== null && fork !== null && /*#__PURE__*/_jsx(DisabledReason, {
|
|
200
206
|
reason: forkBlocked,
|
|
201
207
|
children: /*#__PURE__*/_jsxs(ContextMenu.Item, {
|
|
@@ -207,74 +213,74 @@ export function TimelineMenuPopup(t0) {
|
|
|
207
213
|
}), " ", t("timeline.menu.forkFromHere")]
|
|
208
214
|
})
|
|
209
215
|
});
|
|
210
|
-
$[
|
|
211
|
-
$[
|
|
212
|
-
$[
|
|
213
|
-
$[
|
|
214
|
-
$[
|
|
215
|
-
$[
|
|
216
|
+
$[37] = chatId;
|
|
217
|
+
$[38] = fork;
|
|
218
|
+
$[39] = forkBlocked;
|
|
219
|
+
$[40] = t;
|
|
220
|
+
$[41] = turnId;
|
|
221
|
+
$[42] = t17;
|
|
216
222
|
} else {
|
|
217
|
-
t17 = $[
|
|
223
|
+
t17 = $[42];
|
|
218
224
|
}
|
|
219
225
|
let t18;
|
|
220
|
-
if ($[
|
|
226
|
+
if ($[43] !== chatId || $[44] !== markable) {
|
|
221
227
|
t18 = chatId !== null && markable !== null && /*#__PURE__*/_jsx(BookmarkMenuItems, {
|
|
222
228
|
chatId: chatId,
|
|
223
229
|
itemId: markable
|
|
224
230
|
});
|
|
225
|
-
$[
|
|
226
|
-
$[
|
|
227
|
-
$[
|
|
231
|
+
$[43] = chatId;
|
|
232
|
+
$[44] = markable;
|
|
233
|
+
$[45] = t18;
|
|
228
234
|
} else {
|
|
229
|
-
t18 = $[
|
|
235
|
+
t18 = $[45];
|
|
230
236
|
}
|
|
231
237
|
let t19;
|
|
232
|
-
if ($[
|
|
238
|
+
if ($[46] === Symbol.for("react.memo_cache_sentinel")) {
|
|
233
239
|
t19 = /*#__PURE__*/_jsx(ContextMenu.Separator, {});
|
|
234
|
-
$[
|
|
240
|
+
$[46] = t19;
|
|
235
241
|
} else {
|
|
236
|
-
t19 = $[
|
|
242
|
+
t19 = $[46];
|
|
237
243
|
}
|
|
238
244
|
let t20;
|
|
239
|
-
if ($[
|
|
245
|
+
if ($[47] !== thread.current) {
|
|
240
246
|
t20 = () => selectAllWithin(thread.current);
|
|
241
|
-
$[
|
|
242
|
-
$[
|
|
247
|
+
$[47] = thread.current;
|
|
248
|
+
$[48] = t20;
|
|
243
249
|
} else {
|
|
244
|
-
t20 = $[
|
|
250
|
+
t20 = $[48];
|
|
245
251
|
}
|
|
246
252
|
let t21;
|
|
247
|
-
if ($[
|
|
253
|
+
if ($[49] === Symbol.for("react.memo_cache_sentinel")) {
|
|
248
254
|
t21 = /*#__PURE__*/_jsx(Icon, {
|
|
249
255
|
icon: Scan,
|
|
250
256
|
size: 14
|
|
251
257
|
});
|
|
252
|
-
$[
|
|
258
|
+
$[49] = t21;
|
|
253
259
|
} else {
|
|
254
|
-
t21 = $[
|
|
260
|
+
t21 = $[49];
|
|
255
261
|
}
|
|
256
262
|
let t22;
|
|
257
|
-
if ($[
|
|
263
|
+
if ($[50] !== t) {
|
|
258
264
|
t22 = t("common.action.selectAll");
|
|
259
|
-
$[
|
|
260
|
-
$[
|
|
265
|
+
$[50] = t;
|
|
266
|
+
$[51] = t22;
|
|
261
267
|
} else {
|
|
262
|
-
t22 = $[
|
|
268
|
+
t22 = $[51];
|
|
263
269
|
}
|
|
264
270
|
let t23;
|
|
265
|
-
if ($[
|
|
271
|
+
if ($[52] !== t20 || $[53] !== t22) {
|
|
266
272
|
t23 = /*#__PURE__*/_jsxs(ContextMenu.Item, {
|
|
267
273
|
onClick: t20,
|
|
268
274
|
children: [t21, " ", t22]
|
|
269
275
|
});
|
|
270
|
-
$[
|
|
271
|
-
$[
|
|
272
|
-
$[
|
|
276
|
+
$[52] = t20;
|
|
277
|
+
$[53] = t22;
|
|
278
|
+
$[54] = t23;
|
|
273
279
|
} else {
|
|
274
|
-
t23 = $[
|
|
280
|
+
t23 = $[54];
|
|
275
281
|
}
|
|
276
282
|
let t24;
|
|
277
|
-
if ($[
|
|
283
|
+
if ($[55] !== fileLinks || $[56] !== openInPreview || $[57] !== t || $[58] !== target.path) {
|
|
278
284
|
t24 = target.path !== null && fileLinks !== null && /*#__PURE__*/_jsxs(_Fragment, {
|
|
279
285
|
children: [/*#__PURE__*/_jsx(ContextMenu.Separator, {}), /*#__PURE__*/_jsxs(ContextMenu.Item, {
|
|
280
286
|
onClick: openInPreview,
|
|
@@ -284,41 +290,41 @@ export function TimelineMenuPopup(t0) {
|
|
|
284
290
|
}), " ", t("timeline.menu.openInPreview")]
|
|
285
291
|
})]
|
|
286
292
|
});
|
|
287
|
-
$[
|
|
288
|
-
$[
|
|
289
|
-
$[
|
|
290
|
-
$[
|
|
291
|
-
$[
|
|
293
|
+
$[55] = fileLinks;
|
|
294
|
+
$[56] = openInPreview;
|
|
295
|
+
$[57] = t;
|
|
296
|
+
$[58] = target.path;
|
|
297
|
+
$[59] = t24;
|
|
292
298
|
} else {
|
|
293
|
-
t24 = $[
|
|
299
|
+
t24 = $[59];
|
|
294
300
|
}
|
|
295
301
|
let t25;
|
|
296
|
-
if ($[
|
|
302
|
+
if ($[60] !== column) {
|
|
297
303
|
t25 = column && /*#__PURE__*/_jsxs(_Fragment, {
|
|
298
304
|
children: [/*#__PURE__*/_jsx(ContextMenu.Separator, {}), /*#__PURE__*/_jsx(ReadingWidthSubmenu, {})]
|
|
299
305
|
});
|
|
300
|
-
$[
|
|
301
|
-
$[
|
|
306
|
+
$[60] = column;
|
|
307
|
+
$[61] = t25;
|
|
302
308
|
} else {
|
|
303
|
-
t25 = $[
|
|
309
|
+
t25 = $[61];
|
|
304
310
|
}
|
|
305
311
|
let t26;
|
|
306
|
-
if ($[
|
|
312
|
+
if ($[62] !== t13 || $[63] !== t14 || $[64] !== t15 || $[65] !== t16 || $[66] !== t17 || $[67] !== t18 || $[68] !== t23 || $[69] !== t24 || $[70] !== t25) {
|
|
307
313
|
t26 = /*#__PURE__*/_jsxs(ContextMenu.Popup, {
|
|
308
314
|
children: [t13, t14, t15, t16, t17, t18, t19, t23, t24, t25]
|
|
309
315
|
});
|
|
310
|
-
$[
|
|
311
|
-
$[
|
|
312
|
-
$[
|
|
313
|
-
$[
|
|
314
|
-
$[
|
|
315
|
-
$[
|
|
316
|
-
$[
|
|
317
|
-
$[
|
|
318
|
-
$[
|
|
319
|
-
$[
|
|
320
|
-
} else {
|
|
321
|
-
t26 = $[
|
|
316
|
+
$[62] = t13;
|
|
317
|
+
$[63] = t14;
|
|
318
|
+
$[64] = t15;
|
|
319
|
+
$[65] = t16;
|
|
320
|
+
$[66] = t17;
|
|
321
|
+
$[67] = t18;
|
|
322
|
+
$[68] = t23;
|
|
323
|
+
$[69] = t24;
|
|
324
|
+
$[70] = t25;
|
|
325
|
+
$[71] = t26;
|
|
326
|
+
} else {
|
|
327
|
+
t26 = $[71];
|
|
322
328
|
}
|
|
323
329
|
return t26;
|
|
324
330
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ChatAssistantItem, ChatUserItem } from '@adecore/agent-contracts';
|
|
2
|
+
import { type ClipboardChips } from '../mentions.js';
|
|
3
|
+
import type { TimelineRow } from '../logic/timeline.js';
|
|
4
|
+
import type { ReferenceLookup } from './reference-lookup.js';
|
|
5
|
+
export declare function messageClipboardChips(item: ChatUserItem | ChatAssistantItem, text: string, lookup: Pick<ReferenceLookup, 'items' | 'referenced'>): ClipboardChips;
|
|
6
|
+
export declare function rowClipboardChips(row: TimelineRow, text: string, lookup: Pick<ReferenceLookup, 'items' | 'referenced'>): ClipboardChips;
|
|
7
|
+
export declare function selectionChips(selection: Selection): ClipboardChips;
|
|
8
|
+
export declare function copySelectionWithChips(event: ClipboardEvent): void;
|
|
9
|
+
export declare function copyWithChips(chips: ClipboardChips): void;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { copyText } from '@adecore/ui';
|
|
2
|
+
import { referenceTokens } from '../chat-references.js';
|
|
3
|
+
import { clipboardChipsOf, hasClipboardChips, tokenizeChips, tokenizeNamedReferences, writeClipboardChips } from '../mentions.js';
|
|
4
|
+
/* The chips a copy of a whole message carries: what the person picked, or what a reply names. */
|
|
5
|
+
export function messageClipboardChips(item, text, lookup) {
|
|
6
|
+
if (item.kind === 'assistant') {
|
|
7
|
+
return clipboardChipsOf(text, tokenizeNamedReferences(text, lookup.items, lookup.referenced));
|
|
8
|
+
}
|
|
9
|
+
const tokens = referenceTokens([...(item.chats ?? []), ...(item.references ?? [])], lookup.items);
|
|
10
|
+
return clipboardChipsOf(text, tokenizeChips(text, item.mentions ?? [], item.skills ?? [], tokens));
|
|
11
|
+
}
|
|
12
|
+
/* The chips a copy of a row of the thread carries; only a message has any. */
|
|
13
|
+
export function rowClipboardChips(row, text, lookup) {
|
|
14
|
+
if (row.kind === 'user' || row.kind === 'assistant') {
|
|
15
|
+
return messageClipboardChips(row.item, text, lookup);
|
|
16
|
+
}
|
|
17
|
+
return clipboardChipsOf(text, []);
|
|
18
|
+
}
|
|
19
|
+
/* What a chip the transcript drew stands for, read back from the attributes `TokenChip` writes. */
|
|
20
|
+
function segmentOf(chip) {
|
|
21
|
+
const value = chip.getAttribute('data-chip-value');
|
|
22
|
+
if (value === null) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
switch (chip.getAttribute('data-chip')) {
|
|
26
|
+
case 'mention':
|
|
27
|
+
return {
|
|
28
|
+
kind: 'mention',
|
|
29
|
+
path: value
|
|
30
|
+
};
|
|
31
|
+
case 'skill':
|
|
32
|
+
return {
|
|
33
|
+
kind: 'skill',
|
|
34
|
+
name: value
|
|
35
|
+
};
|
|
36
|
+
case 'reference':
|
|
37
|
+
{
|
|
38
|
+
const name = chip.getAttribute('data-chip-name');
|
|
39
|
+
return name === null || name === '' ? null : {
|
|
40
|
+
kind: 'reference',
|
|
41
|
+
id: value,
|
|
42
|
+
name
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
default:
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/* The chips a selection holds whole, beside the text it copies; a chip cut in half is only text. */
|
|
50
|
+
export function selectionChips(selection) {
|
|
51
|
+
const segments = [];
|
|
52
|
+
for (let i = 0; i < selection.rangeCount; i++) {
|
|
53
|
+
const container = selection.getRangeAt(i).commonAncestorContainer;
|
|
54
|
+
const root = container instanceof Element ? container : container.parentElement;
|
|
55
|
+
const own = root?.closest('[data-chip]');
|
|
56
|
+
const candidates = own ? [own] : [...(root?.querySelectorAll('[data-chip]') ?? [])];
|
|
57
|
+
for (const chip of candidates) {
|
|
58
|
+
const segment = selection.containsNode(chip, false) ? segmentOf(chip) : null;
|
|
59
|
+
if (segment !== null) {
|
|
60
|
+
segments.push(segment);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return clipboardChipsOf(selection.toString(), segments);
|
|
65
|
+
}
|
|
66
|
+
/* A copy of a selection in the thread, which carries the chips in it as well when it holds any. */
|
|
67
|
+
export function copySelectionWithChips(event) {
|
|
68
|
+
const selection = document.getSelection();
|
|
69
|
+
if (event.defaultPrevented || event.clipboardData === null || selection === null || selection.isCollapsed) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const chips = selectionChips(selection);
|
|
73
|
+
if (!hasClipboardChips(chips)) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
writeClipboardChips(event.clipboardData, chips);
|
|
77
|
+
event.preventDefault();
|
|
78
|
+
}
|
|
79
|
+
/*
|
|
80
|
+
* Copies a text and its chips. The asynchronous clipboard writes no type of an app's own that a paste
|
|
81
|
+
* can read, so the copy goes through a copy event, which only a page with the user's gesture gets.
|
|
82
|
+
*/
|
|
83
|
+
export function copyWithChips(chips) {
|
|
84
|
+
if (!hasClipboardChips(chips) || typeof document.execCommand !== 'function') {
|
|
85
|
+
void copyText(chips.text);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
let written = false;
|
|
89
|
+
const write = event => {
|
|
90
|
+
if (event.clipboardData !== null) {
|
|
91
|
+
writeClipboardChips(event.clipboardData, chips);
|
|
92
|
+
event.preventDefault();
|
|
93
|
+
written = true;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
document.addEventListener('copy', write, true);
|
|
97
|
+
try {
|
|
98
|
+
document.execCommand('copy');
|
|
99
|
+
} finally {
|
|
100
|
+
document.removeEventListener('copy', write, true);
|
|
101
|
+
}
|
|
102
|
+
if (!written) {
|
|
103
|
+
void copyText(chips.text);
|
|
104
|
+
}
|
|
105
|
+
}
|
package/dist/chat/ui/chips.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
export declare const MENTION_TONE = "bg-accent-soft text-accent shadow-[inset_0_0_0_1px_color-mix(in_srgb,var(--accent)_25%,transparent)]";
|
|
2
2
|
export declare const SKILL_TONE = "bg-skill-soft text-skill shadow-[inset_0_0_0_1px_color-mix(in_srgb,var(--skill)_25%,transparent)]";
|
|
3
|
+
export declare const REFERENCE_TONE = "bg-text/8 text-text shadow-[inset_0_0_0_1px_var(--border-strong)]";
|
|
4
|
+
export declare const REFERENCE_GONE_TONE = "bg-text/4 text-text-faint shadow-[inset_0_0_0_1px_var(--border)]";
|
|
3
5
|
export declare const CHIP_IN_EDITOR = "box-decoration-clone rounded-md px-1 py-0.5";
|
|
6
|
+
export declare const TOKEN_IN_MESSAGE = "box-decoration-clone rounded-md px-1.5 py-0.5 text-xs font-medium";
|
|
7
|
+
export declare const TOKEN_ICON = "mr-1 inline align-[calc(0.5cap-7px)]!";
|
|
8
|
+
export declare const TOKEN_ICON_IN_EDITOR = "mr-1 inline-block align-[calc(0.5cap-6px)]";
|
|
4
9
|
export declare const CHIP_IN_MESSAGE = "inline-flex h-5 max-w-full items-center gap-1 rounded-md px-1.5 align-[-3px] text-xs/none font-medium";
|
package/dist/chat/ui/chips.js
CHANGED
|
@@ -1,11 +1,25 @@
|
|
|
1
|
-
/* An `@file` or
|
|
1
|
+
/* An `@file`, `$skill` or `#reference` token drawn as a pill: the tone says which it is, the shape
|
|
2
2
|
says where it is drawn. */
|
|
3
3
|
export const MENTION_TONE = 'bg-accent-soft text-accent shadow-[inset_0_0_0_1px_color-mix(in_srgb,var(--accent)_25%,transparent)]';
|
|
4
4
|
/* A skill is the same token shape as a file mention, in its own hue. */
|
|
5
5
|
export const SKILL_TONE = 'bg-skill-soft text-skill shadow-[inset_0_0_0_1px_color-mix(in_srgb,var(--skill)_25%,transparent)]';
|
|
6
|
+
/* A `#` to a view, node or chat is neutral, so it never reads as a file or a skill. */
|
|
7
|
+
export const REFERENCE_TONE = 'bg-text/8 text-text shadow-[inset_0_0_0_1px_var(--border-strong)]';
|
|
8
|
+
/* A `#` whose view or node is no longer in the project. */
|
|
9
|
+
export const REFERENCE_GONE_TONE = 'bg-text/4 text-text-faint shadow-[inset_0_0_0_1px_var(--border)]';
|
|
6
10
|
/* The pill in the composer's editor, around the token's own characters: the editor places the caret
|
|
7
11
|
from what it drew, so padding is safe, and a chip that wraps keeps it on every fragment. */
|
|
8
12
|
export const CHIP_IN_EDITOR = 'box-decoration-clone rounded-md px-1 py-0.5';
|
|
13
|
+
/* A picked or named token in a message or a reply, a shade smaller than the text around it. Inline like
|
|
14
|
+
the editor's pill, so its name sits on the baseline of the sentence, and a selection copies it on the
|
|
15
|
+
same line as the words around it, where a flex box would put it on lines of its own. */
|
|
16
|
+
export const TOKEN_IN_MESSAGE = 'box-decoration-clone rounded-md px-1.5 py-0.5 text-xs font-medium';
|
|
17
|
+
/* The mark in place of the sigil, a 14px icon. Inline, since the base styles make an svg a block of its
|
|
18
|
+
own. Its middle goes on the middle of the name's capitals, where a mark reads as centered; the middle
|
|
19
|
+
of the x-height `Icon` aligns on sits low next to a capital. */
|
|
20
|
+
export const TOKEN_ICON = 'mr-1 inline align-[calc(0.5cap-7px)]!';
|
|
21
|
+
/* The same middle for the 12px mark the composer draws, in a box whose bottom edge is its baseline. */
|
|
22
|
+
export const TOKEN_ICON_IN_EDITOR = 'mr-1 inline-block align-[calc(0.5cap-6px)]';
|
|
9
23
|
/* The same pill in the transcript: a real inline box a shade smaller than the text around it, with
|
|
10
24
|
the icon in place of the sigil. */
|
|
11
25
|
export const CHIP_IN_MESSAGE = 'inline-flex h-5 max-w-full items-center gap-1 rounded-md px-1.5 align-[-3px] text-xs/none font-medium';
|