@adea-ai/ui 0.68.2 → 0.69.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 (46) hide show
  1. package/README.md +79 -15
  2. package/dist/NOTICE +55 -24
  3. package/dist/components/conversation/atomic/chat-composer.d.ts +20 -0
  4. package/dist/components/conversation/atomic/chat-composer.d.ts.map +1 -0
  5. package/dist/components/conversation/atomic/chat-composer.js +69 -0
  6. package/dist/components/conversation/atomic/chat-composer.js.map +1 -0
  7. package/dist/components/conversation/atomic/index.d.ts +3 -0
  8. package/dist/components/conversation/atomic/index.d.ts.map +1 -0
  9. package/dist/components/conversation/atomic/index.js +2 -0
  10. package/dist/components/conversation/chat-composer.d.ts +12 -21
  11. package/dist/components/conversation/chat-composer.d.ts.map +1 -1
  12. package/dist/components/conversation/chat-composer.js +33 -403
  13. package/dist/components/conversation/chat-composer.js.map +1 -1
  14. package/dist/components/conversation/internal/chat-composer-shell.d.ts +38 -0
  15. package/dist/components/conversation/internal/chat-composer-shell.d.ts.map +1 -0
  16. package/dist/components/conversation/internal/chat-composer-shell.js +423 -0
  17. package/dist/components/conversation/internal/chat-composer-shell.js.map +1 -0
  18. package/dist/components/conversation/paste-preview.d.ts +11 -0
  19. package/dist/components/conversation/paste-preview.d.ts.map +1 -0
  20. package/dist/components/conversation/paste-preview.js +28 -0
  21. package/dist/components/conversation/paste-preview.js.map +1 -0
  22. package/dist/components/conversation/paste-token-editor.d.ts +26 -0
  23. package/dist/components/conversation/paste-token-editor.d.ts.map +1 -0
  24. package/dist/components/conversation/paste-token-editor.js +570 -0
  25. package/dist/components/conversation/paste-token-editor.js.map +1 -0
  26. package/dist/components/conversation/paste-tokens.d.ts.map +1 -1
  27. package/dist/components/conversation/paste-tokens.js +11 -2
  28. package/dist/components/conversation/paste-tokens.js.map +1 -1
  29. package/dist/r/conversation.json +26 -0
  30. package/dist/r/registry.json +26 -0
  31. package/dist/r/src/components/conversation/atomic/chat-composer.tsx +57 -0
  32. package/dist/r/src/components/conversation/atomic/index.ts +6 -0
  33. package/dist/r/src/components/conversation/chat-composer.tsx +39 -331
  34. package/dist/r/src/components/conversation/internal/chat-composer-shell.tsx +390 -0
  35. package/dist/r/src/components/conversation/paste-preview.ts +35 -0
  36. package/dist/r/src/components/conversation/paste-token-editor.tsx +672 -0
  37. package/dist/r/src/components/conversation/paste-tokens.ts +15 -2
  38. package/package.json +1 -1
  39. package/registry.json +26 -0
  40. package/src/components/conversation/atomic/chat-composer.tsx +57 -0
  41. package/src/components/conversation/atomic/index.ts +6 -0
  42. package/src/components/conversation/chat-composer.tsx +39 -331
  43. package/src/components/conversation/internal/chat-composer-shell.tsx +390 -0
  44. package/src/components/conversation/paste-preview.ts +35 -0
  45. package/src/components/conversation/paste-token-editor.tsx +672 -0
  46. package/src/components/conversation/paste-tokens.ts +15 -2
@@ -0,0 +1,570 @@
1
+ import { countLines, findTokenRanges, formatToken, isPasteBlock, nextSeq, pruneBlocks, shouldCollapse, stripTrailingBlankLines, tokenRangeAt } from "./paste-tokens.js";
2
+ import { summarizePastePreview } from "./paste-preview.js";
3
+ import { addEventListener, createComponent, delegateEvents, effect, insert, memo, setAttribute, template, use } from "solid-js/web";
4
+ import { For, Show, createEffect, createMemo, createSignal, createUniqueId, on, onCleanup, onMount } from "solid-js";
5
+ import { Tooltip } from "@kobalte/core/tooltip";
6
+ //#region src/components/conversation/paste-token-editor.tsx
7
+ var _tmpl$ = /*#__PURE__*/ template(`<div data-slot=paste-token-mirror aria-hidden=true class="pointer-events-none absolute inset-0 overflow-hidden select-none whitespace-pre-wrap break-words px-4 py-3 text-sm text-transparent">`);
8
+ var _tmpl$2 = /*#__PURE__*/ template(`<textarea data-slot=composer-input aria-keyshortcuts=Alt+ArrowDown class="relative field-sizing-content text-foreground placeholder:text-muted-foreground min-h-11 max-h-36 w-full resize-none border-0 bg-transparent px-4 py-3 text-sm outline-none disabled:opacity-50"rows=1>`);
9
+ var _tmpl$3 = /*#__PURE__*/ template(`<span class=visually-hidden>When the caret is next to a paste token or a token is selected, press Alt+Down Arrow to preview its text. Press Escape to close the preview.`);
10
+ var _tmpl$4 = /*#__PURE__*/ template(`<span class="box-decoration-clone rounded-md bg-primary-subtle">`);
11
+ var _tmpl$5 = /*#__PURE__*/ template(`<span>`);
12
+ var _tmpl$6 = /*#__PURE__*/ template(`<pre class="m-0 max-h-48 max-w-64 overflow-y-auto whitespace-pre-wrap break-words font-mono">`);
13
+ var _tmpl$7 = /*#__PURE__*/ template(`<span>+<!> more lines`);
14
+ var _tmpl$8 = /*#__PURE__*/ template(`<span>+<!> more characters`);
15
+ var PREVIEW_OPEN_DELAY_MS = 300;
16
+ function isTouchDevice() {
17
+ return typeof window !== "undefined" && typeof window.matchMedia === "function" && (window.matchMedia("(pointer: coarse)").matches || window.matchMedia("(hover: none)").matches);
18
+ }
19
+ function isBlockquotePrefix(linePrefix) {
20
+ let sawMarker = false;
21
+ for (let index = 0; index < linePrefix.length; index += 1) {
22
+ const code = linePrefix.charCodeAt(index);
23
+ if (code === 62) sawMarker = true;
24
+ else if (code !== 32 && code !== 9) return false;
25
+ }
26
+ return sawMarker;
27
+ }
28
+ /** Controlled plain-text editor that treats known paste markers as atomic ranges. */
29
+ function PasteTokenEditor(props) {
30
+ const [preview, setPreview] = createSignal(null);
31
+ const previewSummary = createMemo(() => {
32
+ const block = preview();
33
+ return block ? summarizePastePreview(block.content, block.lines) : null;
34
+ });
35
+ const descriptionId = `paste-preview-${createUniqueId()}`;
36
+ const keyboardHintId = `paste-keyboard-hint-${createUniqueId()}`;
37
+ let field;
38
+ let mirror;
39
+ let previewTimer;
40
+ let scheduledBlockId = null;
41
+ let rawPasteNext = false;
42
+ let suppressPasteInput = false;
43
+ let nativePasteInputSeen = false;
44
+ let keyboardNavigationPending = false;
45
+ let acceptingTextDrop = false;
46
+ let snappedCaretPreview = null;
47
+ const ranges = () => findTokenRanges(props.value, props.blocks);
48
+ const clearTimer = () => {
49
+ clearTimeout(previewTimer);
50
+ previewTimer = void 0;
51
+ };
52
+ const closePreview = () => {
53
+ clearTimer();
54
+ scheduledBlockId = null;
55
+ snappedCaretPreview = null;
56
+ setPreview(null);
57
+ };
58
+ const schedulePreview = (block) => {
59
+ if (scheduledBlockId === block.id) return;
60
+ clearTimer();
61
+ scheduledBlockId = block.id;
62
+ setPreview(null);
63
+ previewTimer = setTimeout(() => {
64
+ previewTimer = void 0;
65
+ const current = ranges().find((range) => range.block.id === block.id);
66
+ if (current) setPreview(current.block);
67
+ else closePreview();
68
+ }, PREVIEW_OPEN_DELAY_MS);
69
+ };
70
+ const change = (text, blocks = props.blocks) => {
71
+ props.onChange({
72
+ text,
73
+ blocks: pruneBlocks(text, [...blocks])
74
+ });
75
+ };
76
+ const snapToTokenEdge = (position, tokenRanges = ranges(), edge) => {
77
+ for (const range of tokenRanges) if (position > range.start && position < range.end) {
78
+ if (edge === "start") return range.start;
79
+ if (edge === "end") return range.end;
80
+ return position - range.start <= range.end - position ? range.start : range.end;
81
+ }
82
+ return position;
83
+ };
84
+ const setCaret = (position, focus = false) => {
85
+ requestAnimationFrame(() => {
86
+ if (!field) return;
87
+ if (focus) field.focus();
88
+ field.setSelectionRange(position, position);
89
+ });
90
+ };
91
+ const replaceRange = (start, end) => {
92
+ if (!field) return;
93
+ const removed = ranges().filter((range) => range.start < end && range.end > start);
94
+ if (!removed.length) return;
95
+ const nextStart = Math.min(start, ...removed.map((range) => range.start));
96
+ const nextEnd = Math.max(end, ...removed.map((range) => range.end));
97
+ const next = props.value.slice(0, nextStart) + props.value.slice(nextEnd);
98
+ change(next, props.blocks.filter((block) => !removed.some((range) => range.block.id === block.id)));
99
+ setCaret(nextStart);
100
+ };
101
+ const expandToken = (range) => {
102
+ const next = props.value.slice(0, range.start) + range.block.content + props.value.slice(range.end);
103
+ change(next, props.blocks.filter((block) => block.id !== range.block.id));
104
+ closePreview();
105
+ setCaret(range.start + range.block.content.length, true);
106
+ };
107
+ const segments = () => {
108
+ const result = [];
109
+ let cursor = 0;
110
+ for (const range of ranges()) {
111
+ if (range.start > cursor) result.push({ text: props.value.slice(cursor, range.start) });
112
+ result.push({
113
+ text: props.value.slice(range.start, range.end),
114
+ block: range.block
115
+ });
116
+ cursor = range.end;
117
+ }
118
+ if (cursor < props.value.length) result.push({ text: props.value.slice(cursor) });
119
+ if (!result.length) result.push({ text: props.value });
120
+ return result;
121
+ };
122
+ const scheduleCaretPreview = () => {
123
+ if (isTouchDevice() || props.composing() || !field) {
124
+ closePreview();
125
+ return;
126
+ }
127
+ if (field.selectionStart !== field.selectionEnd) {
128
+ closePreview();
129
+ return;
130
+ }
131
+ const caret = field.selectionStart;
132
+ const range = ranges().find((candidate) => caret > candidate.start && caret < candidate.end);
133
+ if (range) {
134
+ schedulePreview(range.block);
135
+ return;
136
+ }
137
+ const snappedRange = snappedCaretPreview?.position === caret ? ranges().find((candidate) => candidate.block.id === snappedCaretPreview?.blockId) : void 0;
138
+ if (snappedRange) schedulePreview(snappedRange.block);
139
+ else closePreview();
140
+ };
141
+ const openKeyboardPreview = () => {
142
+ if (!field) return false;
143
+ const start = field.selectionStart;
144
+ const end = field.selectionEnd;
145
+ const range = ranges().find((candidate) => start === end ? start >= candidate.start && start <= candidate.end : candidate.start < end && candidate.end > start);
146
+ if (!range) return false;
147
+ clearTimer();
148
+ scheduledBlockId = range.block.id;
149
+ setPreview(range.block);
150
+ return true;
151
+ };
152
+ const schedulePointerPreview = (event) => {
153
+ if (isTouchDevice() || props.composing() || event.buttons !== 0 || !mirror) {
154
+ closePreview();
155
+ return;
156
+ }
157
+ for (const span of mirror.querySelectorAll("[data-paste-seq]")) {
158
+ const rect = span.getBoundingClientRect();
159
+ if (event.clientX >= rect.left && event.clientX <= rect.right && event.clientY >= rect.top && event.clientY <= rect.bottom) {
160
+ const sequence = Number(span.dataset.pasteSeq);
161
+ const range = ranges().find((candidate) => candidate.block.seq === sequence);
162
+ if (range) schedulePreview(range.block);
163
+ else closePreview();
164
+ return;
165
+ }
166
+ }
167
+ closePreview();
168
+ };
169
+ const snapSelection = () => {
170
+ if (!field || props.composing() || acceptingTextDrop) return;
171
+ const start = field.selectionStart;
172
+ const end = field.selectionEnd;
173
+ const direction = field.selectionDirection;
174
+ const tokenRanges = ranges();
175
+ if (start === end) {
176
+ if (keyboardNavigationPending) return;
177
+ scheduleCaretPreview();
178
+ const next = snapToTokenEdge(start, tokenRanges);
179
+ if (next !== start) {
180
+ const range = tokenRanges.find((candidate) => start > candidate.start && start < candidate.end);
181
+ if (range) snappedCaretPreview = {
182
+ blockId: range.block.id,
183
+ position: next
184
+ };
185
+ field.setSelectionRange(next, next, direction);
186
+ }
187
+ return;
188
+ }
189
+ scheduleCaretPreview();
190
+ const nextStart = snapToTokenEdge(start, tokenRanges);
191
+ const nextEnd = snapToTokenEdge(end, tokenRanges);
192
+ if (nextStart !== start || nextEnd !== end) field.setSelectionRange(Math.min(nextStart, nextEnd), Math.max(nextStart, nextEnd), direction);
193
+ };
194
+ const handleKeyDown = (event) => {
195
+ snappedCaretPreview = null;
196
+ rawPasteNext = (event.metaKey || event.ctrlKey) && event.shiftKey && !event.altKey && event.key.toLowerCase() === "v";
197
+ if (props.composing() || event.isComposing || event.keyCode === 229 || !field) {
198
+ props.onKeyDown(event);
199
+ return;
200
+ }
201
+ if (event.key === "ArrowDown" && event.altKey && !event.metaKey && !event.ctrlKey && !event.shiftKey && openKeyboardPreview()) {
202
+ event.preventDefault();
203
+ props.onKeyDown(event);
204
+ return;
205
+ }
206
+ if (event.key === "Escape" && preview()) closePreview();
207
+ const value = props.value;
208
+ const start = field.selectionStart;
209
+ const end = field.selectionEnd;
210
+ const collapsed = start === end;
211
+ const tokenRanges = ranges();
212
+ const plainModifier = !event.metaKey && !event.ctrlKey && !event.altKey;
213
+ const backspace = event.key === "Backspace";
214
+ const deletion = backspace || event.key === "Delete";
215
+ let remove;
216
+ if (deletion && !collapsed) {
217
+ if (tokenRanges.some((range) => range.start < end && range.end > start)) remove = [start, end];
218
+ } else if (deletion) {
219
+ const adjacent = tokenRanges.find((range) => backspace ? range.end === start : range.start === start);
220
+ if (adjacent && (plainModifier || event.altKey || event.ctrlKey)) remove = [adjacent.start, adjacent.end];
221
+ else if (event.metaKey) {
222
+ const boundary = backspace ? value.lastIndexOf("\n", start - 1) + 1 : value.indexOf("\n", start);
223
+ const from = backspace ? boundary : start;
224
+ const to = backspace ? start : boundary < 0 ? value.length : boundary;
225
+ if (tokenRanges.some((range) => range.start < to && range.end > from)) remove = [from, to];
226
+ }
227
+ }
228
+ if (remove) {
229
+ event.preventDefault();
230
+ replaceRange(remove[0], remove[1]);
231
+ props.onKeyDown(event);
232
+ return;
233
+ }
234
+ if (plainModifier && collapsed && !event.shiftKey) {
235
+ const left = event.key === "ArrowLeft";
236
+ const right = event.key === "ArrowRight";
237
+ const adjacent = left ? tokenRanges.find((range) => range.end === start) : right ? tokenRanges.find((range) => range.start === start) : void 0;
238
+ if (adjacent) {
239
+ event.preventDefault();
240
+ setCaret(left ? adjacent.start : adjacent.end);
241
+ props.onKeyDown(event);
242
+ return;
243
+ }
244
+ }
245
+ if (!event.metaKey && !event.ctrlKey && !event.altKey && event.shiftKey) {
246
+ const direction = field.selectionDirection === "backward" ? "backward" : "forward";
247
+ const active = direction === "backward" ? start : end;
248
+ const adjacent = event.key === "ArrowLeft" ? tokenRanges.find((range) => range.end === active) : event.key === "ArrowRight" ? tokenRanges.find((range) => range.start === active) : void 0;
249
+ if (adjacent) {
250
+ event.preventDefault();
251
+ requestAnimationFrame(() => {
252
+ if (!field) return;
253
+ if (event.key === "ArrowLeft" && direction === "backward") field.setSelectionRange(adjacent.start, end, "backward");
254
+ else if (event.key === "ArrowLeft") field.setSelectionRange(start, adjacent.start, start <= adjacent.start ? "forward" : "backward");
255
+ else if (direction === "backward") field.setSelectionRange(adjacent.end, end, adjacent.end <= end ? "backward" : "forward");
256
+ else field.setSelectionRange(start, adjacent.end, "forward");
257
+ });
258
+ props.onKeyDown(event);
259
+ return;
260
+ }
261
+ }
262
+ if (event.key === "Home" || event.key === "End" || (event.key === "ArrowLeft" || event.key === "ArrowRight") && (event.metaKey || event.ctrlKey || event.altKey)) {
263
+ const leftward = event.key === "ArrowLeft" || event.key === "Home";
264
+ keyboardNavigationPending = true;
265
+ requestAnimationFrame(() => {
266
+ if (field) {
267
+ const nextRanges = findTokenRanges(field.value, props.blocks);
268
+ const edge = leftward ? "start" : "end";
269
+ const nextStart = snapToTokenEdge(field.selectionStart, nextRanges, edge);
270
+ const nextEnd = snapToTokenEdge(field.selectionEnd, nextRanges, edge);
271
+ if (nextStart !== field.selectionStart || nextEnd !== field.selectionEnd) field.setSelectionRange(Math.min(nextStart, nextEnd), Math.max(nextStart, nextEnd), field.selectionDirection);
272
+ }
273
+ keyboardNavigationPending = false;
274
+ });
275
+ }
276
+ props.onKeyDown(event);
277
+ };
278
+ const expandSelectionForClipboard = (start, end) => {
279
+ if (start === end) return null;
280
+ const covered = ranges().filter((range) => range.start >= start && range.end <= end);
281
+ if (!covered.length) return null;
282
+ let result = "";
283
+ let cursor = start;
284
+ for (const range of covered) {
285
+ result += props.value.slice(cursor, range.start) + range.block.content;
286
+ cursor = range.end;
287
+ }
288
+ return result + props.value.slice(cursor, end);
289
+ };
290
+ const handlePaste = (event) => {
291
+ const forceRaw = rawPasteNext;
292
+ rawPasteNext = false;
293
+ const pasted = event.clipboardData?.getData("text/plain") ?? "";
294
+ if (!pasted || !field || props.readOnly || props.disabled) return;
295
+ const cleaned = forceRaw ? pasted : stripTrailingBlankLines(pasted);
296
+ const start = field.selectionStart;
297
+ const end = field.selectionEnd;
298
+ const before = props.value.slice(0, start);
299
+ const after = props.value.slice(end);
300
+ if (!forceRaw && shouldCollapse(cleaned)) {
301
+ const id = props.createBlockId();
302
+ if (props.blocks.some((block) => block.id === id)) return;
303
+ const block = {
304
+ id,
305
+ seq: nextSeq([...props.blocks]),
306
+ lines: countLines(cleaned),
307
+ content: cleaned
308
+ };
309
+ if (!isPasteBlock(block)) return;
310
+ const linePrefix = before.slice(before.lastIndexOf("\n") + 1);
311
+ const leading = before && !before.endsWith("\n") && !isBlockquotePrefix(linePrefix) ? "\n" : "";
312
+ const trailing = after && !after.startsWith("\n") ? "\n" : "";
313
+ const insert = leading + formatToken(block) + trailing;
314
+ event.preventDefault();
315
+ change(before + insert + after, [...props.blocks, block]);
316
+ closePreview();
317
+ setCaret(before.length + insert.length);
318
+ return;
319
+ }
320
+ if (forceRaw) return;
321
+ if (cleaned !== pasted && cleaned !== "") {
322
+ event.preventDefault();
323
+ const next = before + cleaned + after;
324
+ nativePasteInputSeen = false;
325
+ suppressPasteInput = true;
326
+ let inserted = false;
327
+ try {
328
+ inserted = typeof document.execCommand === "function" && document.execCommand("insertText", false, cleaned);
329
+ } catch {
330
+ inserted = false;
331
+ }
332
+ if (!nativePasteInputSeen) suppressPasteInput = false;
333
+ change(next);
334
+ if (inserted && field.value === next) return;
335
+ setCaret(before.length + cleaned.length);
336
+ }
337
+ };
338
+ const handleDragOver = (event) => {
339
+ if (!field || props.readOnly || props.disabled || props.composing()) return;
340
+ if (event.dataTransfer?.types.includes("text/plain")) {
341
+ acceptingTextDrop = true;
342
+ closePreview();
343
+ event.preventDefault();
344
+ }
345
+ };
346
+ const handleDragLeave = () => {
347
+ acceptingTextDrop = false;
348
+ };
349
+ const handleDrop = (event) => {
350
+ if (!field || props.readOnly || props.disabled || props.composing()) {
351
+ acceptingTextDrop = false;
352
+ return;
353
+ }
354
+ if (!event.dataTransfer?.types.includes("text/plain")) {
355
+ acceptingTextDrop = false;
356
+ return;
357
+ }
358
+ const dropped = event.dataTransfer.getData("text/plain");
359
+ event.preventDefault();
360
+ acceptingTextDrop = false;
361
+ if (!dropped) return;
362
+ const tokenRanges = ranges();
363
+ let start = field.selectionStart;
364
+ let end = field.selectionEnd;
365
+ const removed = tokenRanges.filter((range) => start === end ? start > range.start && start < range.end : range.start < end && range.end > start);
366
+ if (removed.length) {
367
+ start = Math.min(start, ...removed.map((range) => range.start));
368
+ end = Math.max(end, ...removed.map((range) => range.end));
369
+ }
370
+ change(props.value.slice(0, start) + dropped + props.value.slice(end));
371
+ closePreview();
372
+ setCaret(start + dropped.length);
373
+ };
374
+ const handleClipboard = (event) => {
375
+ if (!field || !event.clipboardData) return;
376
+ const start = field.selectionStart;
377
+ const end = field.selectionEnd;
378
+ const expanded = expandSelectionForClipboard(start, end);
379
+ if (expanded === null) return;
380
+ event.clipboardData.setData("text/plain", expanded);
381
+ event.preventDefault();
382
+ if (event.type === "cut") {
383
+ change(props.value.slice(0, start) + props.value.slice(end));
384
+ setCaret(start);
385
+ }
386
+ };
387
+ const handleClick = (event) => {
388
+ if (!field || !props.blocks.length) return;
389
+ const range = tokenRangeAt(props.value, props.blocks, field.selectionStart);
390
+ if (!range) return;
391
+ if (isTouchDevice() || event.detail >= 2) expandToken(range);
392
+ else requestAnimationFrame(() => field?.setSelectionRange(range.start, range.end));
393
+ };
394
+ createEffect(on(() => props.value, closePreview));
395
+ createEffect(on(() => props.blocks, closePreview));
396
+ createEffect(on(() => props.resetKey, () => {
397
+ rawPasteNext = false;
398
+ closePreview();
399
+ }));
400
+ onMount(() => {
401
+ window.addEventListener("scroll", closePreview, true);
402
+ window.addEventListener("resize", closePreview);
403
+ onCleanup(() => {
404
+ window.removeEventListener("scroll", closePreview, true);
405
+ window.removeEventListener("resize", closePreview);
406
+ });
407
+ });
408
+ onCleanup(() => clearTimer());
409
+ return createComponent(Tooltip, {
410
+ get open() {
411
+ return !!preview();
412
+ },
413
+ onOpenChange: (open) => {
414
+ if (!open) closePreview();
415
+ },
416
+ openDelay: PREVIEW_OPEN_DELAY_MS,
417
+ get children() {
418
+ return [createComponent(Tooltip.Trigger, {
419
+ as: "div",
420
+ "class": "relative",
421
+ get children() {
422
+ return [
423
+ (() => {
424
+ var _el$ = _tmpl$();
425
+ use((element) => mirror = element, _el$);
426
+ insert(_el$, createComponent(For, {
427
+ get each() {
428
+ return segments();
429
+ },
430
+ children: (segment) => segment.block ? (() => {
431
+ var _el$4 = _tmpl$4();
432
+ insert(_el$4, () => segment.text);
433
+ effect(() => setAttribute(_el$4, "data-paste-seq", segment.block.seq));
434
+ return _el$4;
435
+ })() : (() => {
436
+ var _el$5 = _tmpl$5();
437
+ insert(_el$5, () => segment.text);
438
+ return _el$5;
439
+ })()
440
+ }), null);
441
+ insert(_el$, () => props.value.endsWith("\n") ? "​" : "", null);
442
+ return _el$;
443
+ })(),
444
+ (() => {
445
+ var _el$2 = _tmpl$2();
446
+ _el$2.$$keydown = handleKeyDown;
447
+ _el$2.addEventListener("blur", () => {
448
+ rawPasteNext = false;
449
+ acceptingTextDrop = false;
450
+ props.onBlur();
451
+ closePreview();
452
+ });
453
+ addEventListener(_el$2, "focus", props.onFocus);
454
+ addEventListener(_el$2, "compositionend", props.onCompositionEnd);
455
+ addEventListener(_el$2, "compositionstart", props.onCompositionStart);
456
+ _el$2.addEventListener("scroll", (event) => {
457
+ if (mirror) {
458
+ mirror.scrollTop = event.currentTarget.scrollTop;
459
+ mirror.scrollLeft = event.currentTarget.scrollLeft;
460
+ }
461
+ closePreview();
462
+ });
463
+ _el$2.addEventListener("mouseleave", closePreview);
464
+ _el$2.$$mousemove = schedulePointerPreview;
465
+ _el$2.addEventListener("select", snapSelection);
466
+ _el$2.$$click = handleClick;
467
+ _el$2.addEventListener("cut", handleClipboard);
468
+ _el$2.addEventListener("copy", handleClipboard);
469
+ _el$2.addEventListener("drop", handleDrop);
470
+ _el$2.addEventListener("dragleave", handleDragLeave);
471
+ _el$2.addEventListener("dragover", handleDragOver);
472
+ _el$2.addEventListener("paste", handlePaste);
473
+ _el$2.$$input = (event) => {
474
+ if (suppressPasteInput) {
475
+ suppressPasteInput = false;
476
+ nativePasteInputSeen = true;
477
+ return;
478
+ }
479
+ change(event.currentTarget.value);
480
+ };
481
+ use((element) => {
482
+ field = element;
483
+ props.ref(element);
484
+ onCleanup(() => {
485
+ if (field === element) field = void 0;
486
+ props.ref(void 0);
487
+ });
488
+ }, _el$2);
489
+ effect((_p$) => {
490
+ var _v$ = props.inputLabel, _v$2 = preview() ? `${keyboardHintId} ${descriptionId}` : keyboardHintId, _v$3 = props.disabled, _v$4 = props.readOnly, _v$5 = props.placeholder;
491
+ _v$ !== _p$.e && setAttribute(_el$2, "aria-label", _p$.e = _v$);
492
+ _v$2 !== _p$.t && setAttribute(_el$2, "aria-describedby", _p$.t = _v$2);
493
+ _v$3 !== _p$.a && (_el$2.disabled = _p$.a = _v$3);
494
+ _v$4 !== _p$.o && (_el$2.readOnly = _p$.o = _v$4);
495
+ _v$5 !== _p$.i && setAttribute(_el$2, "placeholder", _p$.i = _v$5);
496
+ return _p$;
497
+ }, {
498
+ e: void 0,
499
+ t: void 0,
500
+ a: void 0,
501
+ o: void 0,
502
+ i: void 0
503
+ });
504
+ effect(() => _el$2.value = props.value);
505
+ return _el$2;
506
+ })(),
507
+ (() => {
508
+ var _el$3 = _tmpl$3();
509
+ setAttribute(_el$3, "id", keyboardHintId);
510
+ return _el$3;
511
+ })()
512
+ ];
513
+ }
514
+ }), createComponent(Show, {
515
+ get when() {
516
+ return previewSummary();
517
+ },
518
+ children: (summary) => createComponent(Tooltip.Portal, { get children() {
519
+ return createComponent(Tooltip.Content, {
520
+ id: descriptionId,
521
+ "data-slot": "paste-token-preview",
522
+ "class": "bg-scrim text-scrim-foreground z-(--z-tooltip) w-fit max-w-64 rounded-md px-2 py-1 text-xs origin-(--kb-tooltip-content-transform-origin) text-balance data-expanded:animate-in data-expanded:fade-in-0 data-expanded:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 data-expanded:duration-150 data-closed:duration-100",
523
+ get children() {
524
+ return [
525
+ (() => {
526
+ var _el$6 = _tmpl$6();
527
+ insert(_el$6, () => summary().text);
528
+ return _el$6;
529
+ })(),
530
+ createComponent(Show, {
531
+ get when() {
532
+ return summary().hiddenLines > 0;
533
+ },
534
+ get children() {
535
+ var _el$7 = _tmpl$7(), _el$0 = _el$7.firstChild.nextSibling;
536
+ _el$0.nextSibling;
537
+ insert(_el$7, () => summary().hiddenLines, _el$0);
538
+ return _el$7;
539
+ }
540
+ }),
541
+ createComponent(Show, {
542
+ get when() {
543
+ return memo(() => summary().hiddenLines === 0)() && summary().hiddenCharacters > 0;
544
+ },
545
+ get children() {
546
+ var _el$1 = _tmpl$8(), _el$12 = _el$1.firstChild.nextSibling;
547
+ _el$12.nextSibling;
548
+ insert(_el$1, () => summary().hiddenCharacters, _el$12);
549
+ return _el$1;
550
+ }
551
+ }),
552
+ createComponent(Tooltip.Arrow, { "aria-hidden": "true" })
553
+ ];
554
+ }
555
+ });
556
+ } })
557
+ })];
558
+ }
559
+ });
560
+ }
561
+ delegateEvents([
562
+ "input",
563
+ "click",
564
+ "mousemove",
565
+ "keydown"
566
+ ]);
567
+ //#endregion
568
+ export { PasteTokenEditor };
569
+
570
+ //# sourceMappingURL=paste-token-editor.js.map