@k2b/ui 0.28.0 → 0.30.0
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 +1 -1
- package/dist/base.css +2 -2
- package/dist/browser/actions/ContextMenu.js +5 -0
- package/dist/browser/actions/ContextMenu.js.map +1 -1
- package/dist/browser/actions/DragAndDrop.js +89 -0
- package/dist/browser/actions/DragAndDrop.js.map +1 -0
- package/dist/browser/actions/Dropdown.js +6 -3
- package/dist/browser/actions/Dropdown.js.map +1 -1
- package/dist/browser/actions/FilterChip.js +137 -7
- package/dist/browser/actions/FilterChip.js.map +1 -1
- package/dist/browser/actions/GestureMenu.js +26 -3
- package/dist/browser/actions/GestureMenu.js.map +1 -1
- package/dist/browser/actions/SegmentedControl.js +5 -9
- package/dist/browser/actions/SegmentedControl.js.map +1 -1
- package/dist/browser/actions/SpotlightSearch.js +6 -3
- package/dist/browser/actions/SpotlightSearch.js.map +1 -1
- package/dist/browser/actions/Tabs.js +5 -2
- package/dist/browser/actions/Tabs.js.map +1 -1
- package/dist/browser/actions/ViewTabs.js +294 -0
- package/dist/browser/actions/ViewTabs.js.map +1 -0
- package/dist/browser/actions/drag-and-drop-messages.js +75 -0
- package/dist/browser/actions/drag-and-drop-messages.js.map +1 -0
- package/dist/browser/actions/drag-and-drop.js +692 -0
- package/dist/browser/actions/drag-and-drop.js.map +1 -0
- package/dist/browser/actions/filter-messages.js +6 -2
- package/dist/browser/actions/filter-messages.js.map +1 -1
- package/dist/browser/actions/index.js +3 -1
- package/dist/browser/actions/index.js.map +1 -1
- package/dist/browser/chat/ChatComposer.js +1229 -605
- package/dist/browser/chat/ChatComposer.js.map +1 -1
- package/dist/browser/chat/ChatDecision.js +814 -0
- package/dist/browser/chat/ChatDecision.js.map +1 -0
- package/dist/browser/chat/ChatPrimitives.js +292 -153
- package/dist/browser/chat/ChatPrimitives.js.map +1 -1
- package/dist/browser/chat/ChatTimeline.js.map +1 -1
- package/dist/browser/chat/chat-messages.js +14 -0
- package/dist/browser/chat/chat-messages.js.map +1 -1
- package/dist/browser/chat/command-search.js +35 -17
- package/dist/browser/chat/command-search.js.map +1 -1
- package/dist/browser/chat/index.js +10 -3
- package/dist/browser/chat/index.js.map +1 -1
- package/dist/browser/chat/types.js.map +1 -1
- package/dist/browser/content/Calendar.js +146 -119
- package/dist/browser/content/Calendar.js.map +1 -1
- package/dist/browser/content/CalendarWeekView.js +291 -266
- package/dist/browser/content/CalendarWeekView.js.map +1 -1
- package/dist/browser/content/Chart.js +54 -71
- package/dist/browser/content/Chart.js.map +1 -1
- package/dist/browser/content/DataTable.js +224 -155
- package/dist/browser/content/DataTable.js.map +1 -1
- package/dist/browser/content/FileBrowser.js +2 -2
- package/dist/browser/content/FileBrowser.js.map +1 -1
- package/dist/browser/content/FileTree.js +42 -36
- package/dist/browser/content/FileTree.js.map +1 -1
- package/dist/browser/content/FileTypeIcon.js +72 -0
- package/dist/browser/content/FileTypeIcon.js.map +1 -0
- package/dist/browser/content/FileView.js +2 -2
- package/dist/browser/content/FileView.js.map +1 -1
- package/dist/browser/content/ReferenceChip.js +162 -0
- package/dist/browser/content/ReferenceChip.js.map +1 -0
- package/dist/browser/content/calendar-pointer.js +9 -0
- package/dist/browser/content/calendar-pointer.js.map +1 -1
- package/dist/browser/content/calendar-time-view.js +6 -3
- package/dist/browser/content/calendar-time-view.js.map +1 -1
- package/dist/browser/content/data-table-messages.js +4 -2
- package/dist/browser/content/data-table-messages.js.map +1 -1
- package/dist/browser/content/index.js +2 -0
- package/dist/browser/content/index.js.map +1 -1
- package/dist/browser/feedback/MovedHint.js +197 -0
- package/dist/browser/feedback/MovedHint.js.map +1 -0
- package/dist/browser/feedback/dialog-core.js +66 -9
- package/dist/browser/feedback/dialog-core.js.map +1 -1
- package/dist/browser/feedback/index.js +1 -0
- package/dist/browser/feedback/index.js.map +1 -1
- package/dist/browser/feedback/prompts.js +6 -1
- package/dist/browser/feedback/prompts.js.map +1 -1
- package/dist/browser/inputs/DatePicker.js +337 -212
- package/dist/browser/inputs/DatePicker.js.map +1 -1
- package/dist/browser/inputs/date-picker.js +59 -5
- package/dist/browser/inputs/date-picker.js.map +1 -1
- package/dist/browser/intl/messages.js +12 -0
- package/dist/browser/intl/messages.js.map +1 -1
- package/dist/browser/intl/weekend.js +39 -0
- package/dist/browser/intl/weekend.js.map +1 -0
- package/dist/browser/layout/AppOverview.js +1 -2
- package/dist/browser/layout/AppOverview.js.map +1 -1
- package/dist/browser/layout/AppWorkspace.js +947 -531
- package/dist/browser/layout/AppWorkspace.js.map +1 -1
- package/dist/browser/layout/PageTitle.js +3 -2
- package/dist/browser/layout/PageTitle.js.map +1 -1
- package/dist/browser/layout/PanelDialog.js +88 -86
- package/dist/browser/layout/PanelDialog.js.map +1 -1
- package/dist/browser/layout/ResizeSeparator.js +81 -0
- package/dist/browser/layout/ResizeSeparator.js.map +1 -0
- package/dist/browser/layout/SettingsModal.js +2 -2
- package/dist/browser/layout/SettingsModal.js.map +1 -1
- package/dist/browser/layout/SidebarSwitcher.js +19 -11
- package/dist/browser/layout/SidebarSwitcher.js.map +1 -1
- package/dist/browser/layout/TabBar.js +16 -13
- package/dist/browser/layout/TabBar.js.map +1 -1
- package/dist/browser/layout/app-host-width.js +44 -0
- package/dist/browser/layout/app-host-width.js.map +1 -0
- package/dist/browser/layout/app-workspace-controller.js +337 -44
- package/dist/browser/layout/app-workspace-controller.js.map +1 -1
- package/dist/browser/layout/index.js +4 -1
- package/dist/browser/layout/index.js.map +1 -1
- package/dist/browser/layout/resize-separator.js +90 -0
- package/dist/browser/layout/resize-separator.js.map +1 -0
- package/dist/browser/layout/workspace-messages.js +12 -2
- package/dist/browser/layout/workspace-messages.js.map +1 -1
- package/dist/browser/surfaces/LinkCard.js +1 -1
- package/dist/browser/surfaces/LinkCard.js.map +1 -1
- package/dist/browser/surfaces/Placeholder.js +45 -11
- package/dist/browser/surfaces/Placeholder.js.map +1 -1
- package/dist/browser/surfaces/StatCell.js +23 -0
- package/dist/browser/surfaces/StatCell.js.map +1 -1
- package/dist/browser/widgets/Widget.js +1 -1
- package/dist/browser/widgets/Widget.js.map +1 -1
- package/dist/ssr/actions/ContextMenu.js +5 -0
- package/dist/ssr/actions/ContextMenu.js.map +1 -1
- package/dist/ssr/actions/DragAndDrop.js +63 -0
- package/dist/ssr/actions/DragAndDrop.js.map +1 -0
- package/dist/ssr/actions/Dropdown.js +5 -2
- package/dist/ssr/actions/Dropdown.js.map +1 -1
- package/dist/ssr/actions/FilterChip.js +59 -7
- package/dist/ssr/actions/FilterChip.js.map +1 -1
- package/dist/ssr/actions/GestureMenu.js +26 -3
- package/dist/ssr/actions/GestureMenu.js.map +1 -1
- package/dist/ssr/actions/SegmentedControl.js +1 -2
- package/dist/ssr/actions/SegmentedControl.js.map +1 -1
- package/dist/ssr/actions/SpotlightSearch.js +2 -2
- package/dist/ssr/actions/SpotlightSearch.js.map +1 -1
- package/dist/ssr/actions/Tabs.js +2 -2
- package/dist/ssr/actions/Tabs.js.map +1 -1
- package/dist/ssr/actions/ViewTabs.js +211 -0
- package/dist/ssr/actions/ViewTabs.js.map +1 -0
- package/dist/ssr/actions/drag-and-drop-messages.js +75 -0
- package/dist/ssr/actions/drag-and-drop-messages.js.map +1 -0
- package/dist/ssr/actions/drag-and-drop.js +692 -0
- package/dist/ssr/actions/drag-and-drop.js.map +1 -0
- package/dist/ssr/actions/filter-messages.js +6 -2
- package/dist/ssr/actions/filter-messages.js.map +1 -1
- package/dist/ssr/actions/index.js +3 -1
- package/dist/ssr/actions/index.js.map +1 -1
- package/dist/ssr/chat/ChatComposer.js +668 -136
- package/dist/ssr/chat/ChatComposer.js.map +1 -1
- package/dist/ssr/chat/ChatDecision.js +479 -0
- package/dist/ssr/chat/ChatDecision.js.map +1 -0
- package/dist/ssr/chat/ChatPrimitives.js +95 -24
- package/dist/ssr/chat/ChatPrimitives.js.map +1 -1
- package/dist/ssr/chat/ChatTimeline.js.map +1 -1
- package/dist/ssr/chat/chat-messages.js +14 -0
- package/dist/ssr/chat/chat-messages.js.map +1 -1
- package/dist/ssr/chat/command-search.js +35 -17
- package/dist/ssr/chat/command-search.js.map +1 -1
- package/dist/ssr/chat/index.js +10 -3
- package/dist/ssr/chat/index.js.map +1 -1
- package/dist/ssr/chat/types.js.map +1 -1
- package/dist/ssr/content/Calendar.js +112 -103
- package/dist/ssr/content/Calendar.js.map +1 -1
- package/dist/ssr/content/CalendarWeekView.js +42 -28
- package/dist/ssr/content/CalendarWeekView.js.map +1 -1
- package/dist/ssr/content/Chart.js +19 -23
- package/dist/ssr/content/Chart.js.map +1 -1
- package/dist/ssr/content/DataTable.js +78 -31
- package/dist/ssr/content/DataTable.js.map +1 -1
- package/dist/ssr/content/FileBrowser.js +2 -2
- package/dist/ssr/content/FileBrowser.js.map +1 -1
- package/dist/ssr/content/FileTree.js +21 -14
- package/dist/ssr/content/FileTree.js.map +1 -1
- package/dist/ssr/content/FileTypeIcon.js +50 -0
- package/dist/ssr/content/FileTypeIcon.js.map +1 -0
- package/dist/ssr/content/FileView.js +2 -2
- package/dist/ssr/content/FileView.js.map +1 -1
- package/dist/ssr/content/ReferenceChip.js +121 -0
- package/dist/ssr/content/ReferenceChip.js.map +1 -0
- package/dist/ssr/content/calendar-pointer.js +9 -0
- package/dist/ssr/content/calendar-pointer.js.map +1 -1
- package/dist/ssr/content/calendar-time-view.js +6 -3
- package/dist/ssr/content/calendar-time-view.js.map +1 -1
- package/dist/ssr/content/data-table-messages.js +4 -2
- package/dist/ssr/content/data-table-messages.js.map +1 -1
- package/dist/ssr/content/index.js +2 -0
- package/dist/ssr/content/index.js.map +1 -1
- package/dist/ssr/feedback/MovedHint.js +166 -0
- package/dist/ssr/feedback/MovedHint.js.map +1 -0
- package/dist/ssr/feedback/dialog-core.js +66 -9
- package/dist/ssr/feedback/dialog-core.js.map +1 -1
- package/dist/ssr/feedback/index.js +1 -0
- package/dist/ssr/feedback/index.js.map +1 -1
- package/dist/ssr/feedback/prompts.js +6 -1
- package/dist/ssr/feedback/prompts.js.map +1 -1
- package/dist/ssr/inputs/DatePicker.js +138 -69
- package/dist/ssr/inputs/DatePicker.js.map +1 -1
- package/dist/ssr/inputs/date-picker.js +59 -5
- package/dist/ssr/inputs/date-picker.js.map +1 -1
- package/dist/ssr/intl/messages.js +12 -0
- package/dist/ssr/intl/messages.js.map +1 -1
- package/dist/ssr/intl/weekend.js +39 -0
- package/dist/ssr/intl/weekend.js.map +1 -0
- package/dist/ssr/layout/AppOverview.js +1 -2
- package/dist/ssr/layout/AppOverview.js.map +1 -1
- package/dist/ssr/layout/AppWorkspace.js +457 -116
- package/dist/ssr/layout/AppWorkspace.js.map +1 -1
- package/dist/ssr/layout/PageTitle.js +3 -2
- package/dist/ssr/layout/PageTitle.js.map +1 -1
- package/dist/ssr/layout/PanelDialog.js +7 -6
- package/dist/ssr/layout/PanelDialog.js.map +1 -1
- package/dist/ssr/layout/ResizeSeparator.js +45 -0
- package/dist/ssr/layout/ResizeSeparator.js.map +1 -0
- package/dist/ssr/layout/SettingsModal.js +2 -2
- package/dist/ssr/layout/SettingsModal.js.map +1 -1
- package/dist/ssr/layout/SidebarSwitcher.js +19 -11
- package/dist/ssr/layout/SidebarSwitcher.js.map +1 -1
- package/dist/ssr/layout/TabBar.js +2 -2
- package/dist/ssr/layout/TabBar.js.map +1 -1
- package/dist/ssr/layout/app-host-width.js +44 -0
- package/dist/ssr/layout/app-host-width.js.map +1 -0
- package/dist/ssr/layout/app-workspace-controller.js +337 -44
- package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
- package/dist/ssr/layout/index.js +4 -1
- package/dist/ssr/layout/index.js.map +1 -1
- package/dist/ssr/layout/resize-separator.js +90 -0
- package/dist/ssr/layout/resize-separator.js.map +1 -0
- package/dist/ssr/layout/workspace-messages.js +12 -2
- package/dist/ssr/layout/workspace-messages.js.map +1 -1
- package/dist/ssr/surfaces/LinkCard.js +1 -1
- package/dist/ssr/surfaces/LinkCard.js.map +1 -1
- package/dist/ssr/surfaces/Placeholder.js +25 -6
- package/dist/ssr/surfaces/Placeholder.js.map +1 -1
- package/dist/ssr/surfaces/StatCell.js +23 -0
- package/dist/ssr/surfaces/StatCell.js.map +1 -1
- package/dist/ssr/widgets/Widget.js +1 -1
- package/dist/ssr/widgets/Widget.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/actions/ContextMenu.d.ts +1 -0
- package/dist/types/actions/DragAndDrop.d.ts +29 -0
- package/dist/types/actions/Dropdown.d.ts +4 -0
- package/dist/types/actions/FilterChip.d.ts +22 -0
- package/dist/types/actions/ViewTabs.d.ts +30 -0
- package/dist/types/actions/drag-and-drop-messages.d.ts +35 -0
- package/dist/types/actions/drag-and-drop.d.ts +36 -0
- package/dist/types/actions/filter-messages.d.ts +2 -0
- package/dist/types/actions/index.d.ts +6 -2
- package/dist/types/chat/ChatComposer.d.ts +71 -1
- package/dist/types/chat/ChatDecision.d.ts +149 -0
- package/dist/types/chat/ChatPrimitives.d.ts +14 -1
- package/dist/types/chat/ChatTimeline.d.ts +2 -1
- package/dist/types/chat/chat-messages.d.ts +7 -0
- package/dist/types/chat/command-search.d.ts +5 -0
- package/dist/types/chat/index.d.ts +28 -5
- package/dist/types/chat/types.d.ts +54 -1
- package/dist/types/content/Chart.d.ts +9 -3
- package/dist/types/content/DataTable.d.ts +3 -0
- package/dist/types/content/FileTypeIcon.d.ts +27 -0
- package/dist/types/content/ReferenceChip.d.ts +49 -0
- package/dist/types/content/calendar-pointer.d.ts +6 -0
- package/dist/types/content/data-table-messages.d.ts +1 -0
- package/dist/types/content/index.d.ts +3 -0
- package/dist/types/feedback/MovedHint.d.ts +25 -0
- package/dist/types/feedback/dialog-core.d.ts +5 -2
- package/dist/types/feedback/index.d.ts +2 -0
- package/dist/types/feedback/prompts.d.ts +2 -0
- package/dist/types/inputs/DatePicker.d.ts +7 -0
- package/dist/types/inputs/date-picker.d.ts +25 -1
- package/dist/types/intl/messages.d.ts +6 -0
- package/dist/types/intl/weekend.d.ts +12 -0
- package/dist/types/layout/AppWorkspace.d.ts +48 -10
- package/dist/types/layout/ResizeSeparator.d.ts +9 -0
- package/dist/types/layout/TabBar.d.ts +7 -0
- package/dist/types/layout/app-host-width.d.ts +6 -0
- package/dist/types/layout/app-workspace-controller.d.ts +2 -0
- package/dist/types/layout/index.d.ts +5 -2
- package/dist/types/layout/resize-separator.d.ts +18 -0
- package/dist/types/layout/workspace-messages.d.ts +5 -0
- package/dist/types/surfaces/Placeholder.d.ts +2 -1
- package/dist/types/surfaces/StatCell.d.ts +6 -0
- package/package.json +5 -5
|
@@ -26,12 +26,14 @@ var _tmpl$ = "<span class=\"k2b-chat-progress-dots\" aria-hidden=\"true\"><span>
|
|
|
26
26
|
_tmpl$17 = "<i class=\"ti ti-chevron-right k2b-chat-activity__chevron\" aria-hidden=\"true\"></i>",
|
|
27
27
|
_tmpl$18 = ["<i", "></i>"],
|
|
28
28
|
_tmpl$19 = ["<small>", "</small>"],
|
|
29
|
-
_tmpl$20 = ["<
|
|
30
|
-
_tmpl$21 = ["<
|
|
31
|
-
_tmpl$22 = "<
|
|
32
|
-
_tmpl$23 = ["<div><
|
|
33
|
-
_tmpl$24 =
|
|
34
|
-
|
|
29
|
+
_tmpl$20 = ["<button type=\"button\" class=\"k2b-chat-activity__toggle\"", "><span class=\"k2b-chat-activity__toggle-label\">", "</span><i class=\"ti ti-chevron-right k2b-chat-activity__chevron\" aria-hidden=\"true\"></i></button>"],
|
|
30
|
+
_tmpl$21 = ["<details class=\"", "\"", " style=\"", "\"", "><summary class=\"k2b-chat-activity__row\"", ">", "</summary><div class=\"k2b-chat-activity__body\">", "</div></details>"],
|
|
31
|
+
_tmpl$22 = ["<div class=\"", "\"", " style=\"", "\"", "><div class=\"k2b-chat-activity__row\">", "</div></div>"],
|
|
32
|
+
_tmpl$23 = ["<div class=\"", "\"", " style=\"", "\"", "><div class=\"k2b-chat-activity__row\">", "</div><div", " class=\"k2b-chat-activity__body\"", ">", "</div></div>"],
|
|
33
|
+
_tmpl$24 = "<i class=\"ti ti-brain\" aria-hidden=\"true\"></i>",
|
|
34
|
+
_tmpl$25 = ["<div><dt>", "</dt><dd>", "</dd></div>"],
|
|
35
|
+
_tmpl$26 = ["<dl>", "<div><dt>", "</dt><dd>", "</dd></div><div><dt>", "</dt><dd>", "</dd></div>", "<div><dt>", "</dt><dd>", "</dd></div>", "</dl>"];
|
|
36
|
+
import { children, createContext, createRenderEffect, createSignal, createUniqueId, For, onCleanup, Show, useContext } from "solid-js";
|
|
35
37
|
import { Button } from "../actions/Button";
|
|
36
38
|
import { Dropdown } from "../actions/Dropdown";
|
|
37
39
|
import { Tooltip } from "../feedback/Tooltip";
|
|
@@ -304,6 +306,25 @@ const ActivityContent = props => [_$ssr(_tmpl$14, _$escape(_$createComponent(Sho
|
|
|
304
306
|
return _$ssr(_tmpl$17);
|
|
305
307
|
}
|
|
306
308
|
})];
|
|
309
|
+
const ActivityDisclosureContext = createContext();
|
|
310
|
+
/**
|
|
311
|
+
* The words of an activity label that open its body, with the chevron right after them. With a toggle in its label,
|
|
312
|
+
* only these words are the disclosure, and the rest of the row, chips with links included, stays ordinary content.
|
|
313
|
+
* Outside an activity with a body it renders its words as plain text.
|
|
314
|
+
*/
|
|
315
|
+
export function ChatActivityToggle(props) {
|
|
316
|
+
const disclosure = useContext(ActivityDisclosureContext);
|
|
317
|
+
disclosure?.register();
|
|
318
|
+
return _$createComponent(Show, {
|
|
319
|
+
get when() {
|
|
320
|
+
return disclosure?.expandable() ? disclosure : undefined;
|
|
321
|
+
},
|
|
322
|
+
get fallback() {
|
|
323
|
+
return props.children;
|
|
324
|
+
},
|
|
325
|
+
children: current => _$ssr(_tmpl$20, _$ssrAttribute("aria-expanded", current().open() ? "true" : "false", false) + _$ssrAttribute("aria-controls", _$escape(current().bodyId, true), false), _$escape(props.children))
|
|
326
|
+
});
|
|
327
|
+
}
|
|
307
328
|
export function ChatActivity(props) {
|
|
308
329
|
// The disclosure's real state. A controlled `open` sets it, and every toggle reports it, so the body renders whenever
|
|
309
330
|
// the row is open, also when a host has not yet passed its new `open` back.
|
|
@@ -313,26 +334,76 @@ export function ChatActivity(props) {
|
|
|
313
334
|
if (open !== undefined) setExpanded(open);
|
|
314
335
|
});
|
|
315
336
|
const open = expanded;
|
|
337
|
+
const setOpen = next => {
|
|
338
|
+
if (next === expanded()) return;
|
|
339
|
+
setExpanded(next);
|
|
340
|
+
props.onOpenChange?.(next);
|
|
341
|
+
};
|
|
316
342
|
const tone = () => props.tone ?? "neutral";
|
|
317
343
|
const style = () => props.accent ? {
|
|
318
344
|
"--k2b-chat-activity-accent": props.accent
|
|
319
345
|
} : undefined;
|
|
320
|
-
|
|
346
|
+
const expandable = () => Boolean(props.renderBody || props.children);
|
|
347
|
+
// A `Chat.Activity.Toggle` in the label registers while the label resolves, before the row picks its element, so the
|
|
348
|
+
// server and the first browser frame agree on whether the whole row or only the toggle is the disclosure.
|
|
349
|
+
const [toggles, setToggles] = createSignal(0);
|
|
350
|
+
const bodyId = createUniqueId();
|
|
351
|
+
const disclosure = {
|
|
352
|
+
expandable,
|
|
353
|
+
open,
|
|
354
|
+
toggle: () => setOpen(!expanded()),
|
|
355
|
+
bodyId,
|
|
356
|
+
register: () => {
|
|
357
|
+
setToggles(count => count + 1);
|
|
358
|
+
onCleanup(() => setToggles(count => count - 1));
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
const body = () => props.renderBody ? _$createComponent(Show, {
|
|
321
362
|
get when() {
|
|
322
|
-
return props.renderBody
|
|
323
|
-
},
|
|
324
|
-
get fallback() {
|
|
325
|
-
return _$ssr(_tmpl$21, `k2b-chat-activity ${_$escape(props.class ?? "", true)}`, _$ssrAttribute("data-tone", _$escape(tone(), true), false) + _$ssrAttribute("data-accent", props.accent ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-busy", props.busy ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-chat-anchor", props.anchorId !== undefined ? _$escape(String(props.anchorId), true) : _$escape(undefined, true), false), _$ssrStyle(style()), _$ssrAttribute("aria-busy", props.busy ? "true" : _$escape(undefined, true), false), _$escape(_$createComponent(ActivityContent, props)));
|
|
363
|
+
return _$memo(() => !!open())() ? props.renderBody : undefined;
|
|
326
364
|
},
|
|
365
|
+
children: render => render()()
|
|
366
|
+
}) : props.children;
|
|
367
|
+
return _$createComponent(ActivityDisclosureContext.Provider, {
|
|
368
|
+
value: disclosure,
|
|
327
369
|
get children() {
|
|
328
|
-
return
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
370
|
+
return (() => {
|
|
371
|
+
const label = children(() => props.label);
|
|
372
|
+
return _$createComponent(Show, {
|
|
373
|
+
get when() {
|
|
374
|
+
return expandable();
|
|
375
|
+
},
|
|
376
|
+
get fallback() {
|
|
377
|
+
return _$ssr(_tmpl$22, `k2b-chat-activity ${_$escape(props.class ?? "", true)}`, _$ssrAttribute("data-tone", _$escape(tone(), true), false) + _$ssrAttribute("data-accent", props.accent ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-busy", props.busy ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-wrap", props.wrap ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-chat-anchor", props.anchorId !== undefined ? _$escape(String(props.anchorId), true) : _$escape(undefined, true), false), _$ssrStyle(style()), _$ssrAttribute("aria-busy", props.busy ? "true" : _$escape(undefined, true), false), _$escape(_$createComponent(ActivityContent, _$mergeProps(props, {
|
|
378
|
+
get label() {
|
|
379
|
+
return label();
|
|
380
|
+
}
|
|
381
|
+
}))));
|
|
382
|
+
},
|
|
383
|
+
get children() {
|
|
384
|
+
return _$createComponent(Show, {
|
|
385
|
+
get when() {
|
|
386
|
+
return toggles() === 0;
|
|
387
|
+
},
|
|
388
|
+
get fallback() {
|
|
389
|
+
return _$ssr(_tmpl$23, `k2b-chat-activity ${_$escape(props.class ?? "", true)}`, _$ssrAttribute("data-tone", _$escape(tone(), true), false) + _$ssrAttribute("data-accent", props.accent ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-busy", props.busy ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-wrap", props.wrap ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-body-inset", props.bodyInset === false ? "false" : _$escape(undefined, true), false) + _$ssrAttribute("data-open", open() ? "true" : "false", false) + _$ssrAttribute("data-chat-anchor", props.anchorId !== undefined ? _$escape(String(props.anchorId), true) : _$escape(undefined, true), false), _$ssrStyle(style()), _$ssrAttribute("aria-busy", props.busy ? "true" : _$escape(undefined, true), false), _$escape(_$createComponent(ActivityContent, _$mergeProps(props, {
|
|
390
|
+
get label() {
|
|
391
|
+
return label();
|
|
392
|
+
}
|
|
393
|
+
}))), _$ssrAttribute("id", _$escape(bodyId, true), false), _$ssrAttribute("hidden", !open(), true), _$escape(body()));
|
|
394
|
+
},
|
|
395
|
+
get children() {
|
|
396
|
+
return _$ssr(_tmpl$21, `k2b-chat-activity ${_$escape(props.class ?? "", true)}`, _$ssrAttribute("data-tone", _$escape(tone(), true), false) + _$ssrAttribute("data-accent", props.accent ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-busy", props.busy ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-wrap", props.wrap ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-body-inset", props.bodyInset === false ? "false" : _$escape(undefined, true), false) + _$ssrAttribute("data-chat-anchor", props.anchorId !== undefined ? _$escape(String(props.anchorId), true) : _$escape(undefined, true), false), _$ssrStyle(style()), _$ssrAttribute("open", open(), true) + _$ssrAttribute("aria-busy", props.busy ? "true" : _$escape(undefined, true), false), _$ssrAttribute("aria-label", _$escape(props.ariaLabel, true), false), _$escape(_$createComponent(ActivityContent, _$mergeProps(props, {
|
|
397
|
+
get label() {
|
|
398
|
+
return label();
|
|
399
|
+
},
|
|
400
|
+
disclosure: true
|
|
401
|
+
}))), _$escape(body()));
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
});
|
|
406
|
+
})();
|
|
336
407
|
}
|
|
337
408
|
});
|
|
338
409
|
}
|
|
@@ -400,24 +471,24 @@ export function ChatContextUsage(props) {
|
|
|
400
471
|
}
|
|
401
472
|
});
|
|
402
473
|
}
|
|
403
|
-
}), _$ssr(_tmpl$
|
|
474
|
+
}), _$ssr(_tmpl$26, _$escape(_$createComponent(Show, {
|
|
404
475
|
get when() {
|
|
405
476
|
return props.modelLabel;
|
|
406
477
|
},
|
|
407
|
-
children: model => _$ssr(_tmpl$
|
|
478
|
+
children: model => _$ssr(_tmpl$25, _$escape(chatMessages().model), _$escape(model()))
|
|
408
479
|
})), _$escape(chatMessages().input), _$escape(formattedUsageValue(usage().input)), _$escape(chatMessages().output), _$escape(formattedUsageValue(usage().output)), _$escape(_$createComponent(Show, {
|
|
409
480
|
get when() {
|
|
410
481
|
return loopUsage().reported;
|
|
411
482
|
},
|
|
412
483
|
get children() {
|
|
413
|
-
return _$ssr(_tmpl$
|
|
484
|
+
return _$ssr(_tmpl$25, _$escape(chatMessages().loopTotal), _$escape(formattedUsageValue(loopUsage().total)));
|
|
414
485
|
}
|
|
415
486
|
})), _$escape(chatMessages().contextWindow), windowSize() > 0 ? _$escape(formatNumber(windowSize())) : _$escape(chatMessages().notConfigured), _$escape(_$createComponent(Show, {
|
|
416
487
|
get when() {
|
|
417
488
|
return remaining() !== null;
|
|
418
489
|
},
|
|
419
490
|
get children() {
|
|
420
|
-
return _$ssr(_tmpl$
|
|
491
|
+
return _$ssr(_tmpl$25, _$escape(chatMessages().remaining), remaining() === null ? _$escape(messages().unknown) : _$escape(formatNumber(remaining())));
|
|
421
492
|
}
|
|
422
493
|
}))), _$createComponent(Show, {
|
|
423
494
|
get when() {
|
|
@@ -452,7 +523,7 @@ export function ChatContextUsage(props) {
|
|
|
452
523
|
return accessibleLabel();
|
|
453
524
|
},
|
|
454
525
|
get children() {
|
|
455
|
-
return [_$ssr(_tmpl$
|
|
526
|
+
return [_$ssr(_tmpl$24), _$ssr(_tmpl$0, percent() === null ? "–" : `${_$escape(percent())}%`)];
|
|
456
527
|
}
|
|
457
528
|
});
|
|
458
529
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["chat/ChatPrimitives.tsx"],"sourcesContent":["import { createRenderEffect, createSignal, For, type JSX, onCleanup, Show } from \"solid-js\";\nimport { Button } from \"../actions/Button\";\nimport { Dropdown, type DropdownItem } from \"../actions/Dropdown\";\nimport { Tooltip } from \"../feedback/Tooltip\";\nimport { useLocale } from \"../intl/locale\";\nimport { useUiMessages } from \"../intl/messages\";\nimport { ProgressBar } from \"../surfaces/ProgressBar\";\nimport { ChatContextPanel, ChatContextPopup } from \"./ChatContextPopup\";\nimport { executeChatAction } from \"./chat-behavior\";\nimport { type ChatMessages, useChatMessages } from \"./chat-messages\";\nimport type { ChatAction, ChatActivityTone, ChatAttachment, ChatContextUsageData, ChatMessageStatus, ChatRole } from \"./types\";\n\nexport type ChatMessageProps = {\n role: ChatRole;\n children?: JSX.Element;\n label?: string;\n createdAt?: string | Date;\n timeLabel?: string;\n status?: ChatMessageStatus;\n attachments?: readonly ChatAttachment[];\n actions?: readonly ChatAction[];\n actionDisplay?: \"auto\" | \"inline\" | \"menu\";\n anchorId?: string | number;\n onActionError?: (error: unknown) => void;\n class?: string;\n};\n\nexport type ChatActivityProps = {\n label: string;\n /** Spelled-out name for an expandable row whose visible text abbreviates, such as durations. */\n ariaLabel?: string;\n description?: string;\n icon?: string;\n /** Optional host-owned leading visual rendered instead of the icon. */\n leading?: JSX.Element;\n /** Optional identity accent for the leading visual. Semantic tones still take precedence. */\n accent?: string;\n tone?: ChatActivityTone;\n /** Marks the activity as running with the shared accent sweep. */\n busy?: boolean;\n trailing?: JSX.Element;\n /** Controlled disclosure state. Omit to keep native details behavior. */\n open?: boolean;\n /** Reports disclosure changes when `open` is controlled by the host. */\n onOpenChange?: (open: boolean) => void;\n defaultOpen?: boolean;\n /** Set to false when the body is a peer list that should align with the activity row. */\n bodyInset?: boolean;\n anchorId?: string | number;\n children?: JSX.Element;\n /** Mount expensive details only while expanded. */\n renderBody?: () => JSX.Element;\n class?: string;\n};\n\nexport type ChatContextUsageProps = ChatContextUsageData & {\n action?: ChatAction;\n onActionError?: (error: unknown) => void;\n /** Host-owned number formatting. The default groups whole numbers in the inherited render locale. */\n formatNumber?: (value: number) => string;\n class?: string;\n};\n\nconst roleLabel = (role: ChatRole, messages: ChatMessages): string => {\n if (role === \"assistant\") return messages.assistant;\n if (role === \"user\") return messages.user;\n if (role === \"tool\") return messages.tool;\n return messages.system;\n};\n\nconst statusLabel = (status: ChatMessageStatus | undefined, messages: ChatMessages): string | null => {\n if (status === \"pending\") return messages.waiting;\n if (status === \"streaming\") return messages.generating;\n if (status === \"error\") return messages.failed;\n return null;\n};\n\nconst statusIcon = (status: ChatMessageStatus | undefined): string => {\n if (status === \"pending\") return \"ti ti-clock\";\n return \"ti ti-alert-circle\";\n};\n\nconst ChatProgressDots = () => (\n <span class=\"k2b-chat-progress-dots\" aria-hidden=\"true\">\n <span />\n <span />\n <span />\n </span>\n);\n\nconst attachmentIcon = (attachment: ChatAttachment): string =>\n attachment.icon ?? (attachment.kind === \"image\" ? \"ti ti-photo\" : attachment.kind === \"resource\" ? \"ti ti-link\" : \"ti ti-file\");\n\nconst finiteNonNegative = (value: number | undefined): number =>\n typeof value === \"number\" && Number.isFinite(value) ? Math.max(0, value) : 0;\n\nconst finiteUsageValue = (value: number | undefined): number | null =>\n typeof value === \"number\" && Number.isFinite(value) && value >= 0 ? value : null;\n\nconst normalizedUsage = (usage: ChatContextUsageData[\"usage\"]) => {\n const input = finiteUsageValue(usage?.input);\n const output = finiteUsageValue(usage?.output);\n const explicitTotal = finiteUsageValue(usage?.total);\n const total = explicitTotal ?? (input !== null || output !== null ? (input ?? 0) + (output ?? 0) : null);\n return { input, output, total, reported: total !== null };\n};\n\n/** Whole numbers in the render locale, so a German page reads 128.000 and an English one 128,000. */\nconst formatLocaleInteger = (value: number, locale: string): string =>\n new Intl.NumberFormat(locale, { maximumFractionDigits: 0 }).format(Math.round(finiteNonNegative(value)));\n\nexport const formatChatTokens = (tokens: number): string => {\n const value = finiteNonNegative(tokens);\n if (value >= 1_000_000) return `${(value / 1_000_000).toFixed(1)}M`;\n if (value >= 1_000) return `${(value / 1_000).toFixed(1)}k`;\n return String(Math.round(value));\n};\n\nconst dateTime = (value: string | Date | undefined): string | null => {\n if (!value) return null;\n const date = value instanceof Date ? value : new Date(value);\n return Number.isFinite(date.getTime()) ? date.toISOString() : null;\n};\n\nexport function ChatMessage(props: ChatMessageProps): JSX.Element {\n const chatMessages = useChatMessages();\n const [busyActionId, setBusyActionId] = createSignal<string | null>(null);\n const [completedActionId, setCompletedActionId] = createSignal<string | null>(null);\n let completedTimer: ReturnType<typeof setTimeout> | undefined;\n const status = () => statusLabel(props.status, chatMessages());\n const timestamp = () => dateTime(props.createdAt);\n // Locale and timezone are application policy. Requiring an explicit visible\n // label keeps SSR and hydration byte-stable while `createdAt` still supplies\n // the semantic machine-readable timestamp.\n const time = () => props.timeLabel ?? null;\n const actions = () => props.actions ?? [];\n const actionDisplay = () =>\n props.actionDisplay === \"auto\" || !props.actionDisplay ? (props.role === \"user\" ? \"menu\" : \"inline\") : props.actionDisplay;\n const hasMeta = () => props.status === \"streaming\" || status() !== null || Boolean(time()) || actions().length > 0;\n\n const runAction = async (action: ChatAction) => {\n if (action.disabled || busyActionId()) return;\n setBusyActionId(action.id);\n try {\n await executeChatAction(action);\n setCompletedActionId(action.id);\n if (completedTimer) clearTimeout(completedTimer);\n completedTimer = setTimeout(() => setCompletedActionId(null), 1400);\n } catch (error) {\n props.onActionError?.(error);\n } finally {\n setBusyActionId(null);\n }\n };\n\n const actionIcon = (action: ChatAction) =>\n busyActionId() === action.id\n ? \"ti ti-loader-2 k2b-spin\"\n : completedActionId() === action.id\n ? \"ti ti-check\"\n : (action.icon ?? \"ti ti-dots\");\n\n onCleanup(() => {\n if (completedTimer) clearTimeout(completedTimer);\n });\n\n const menuItems = (): readonly DropdownItem[] =>\n actions().map((action) => ({\n icon: actionIcon(action),\n label: action.label,\n variant: action.variant,\n disabled: action.disabled || Boolean(busyActionId()),\n action: () => void runAction(action),\n }));\n\n return (\n <article\n class={`k2b-chat-message ${props.class ?? \"\"}`}\n data-role={props.role}\n data-status={props.status ?? \"complete\"}\n data-chat-anchor={props.anchorId !== undefined ? String(props.anchorId) : undefined}\n aria-busy={props.status === \"pending\" || props.status === \"streaming\" ? \"true\" : undefined}\n >\n <span class=\"k2b-sr-only\">{props.label ?? roleLabel(props.role, chatMessages())}: </span>\n <Show when={(props.attachments?.length ?? 0) > 0}>\n <div class=\"k2b-chat-message__attachments\" role=\"list\" aria-label={chatMessages().attachments}>\n <For each={props.attachments}>\n {(attachment) => {\n // A preview that no longer loads, such as a deleted file, falls back to the attachment icon; a new URL tries again.\n const [failedPreviewUrl, setFailedPreviewUrl] = createSignal<string>();\n const content = () => (\n <>\n <Show\n when={attachment.kind === \"image\" && attachment.previewUrl && attachment.previewUrl !== failedPreviewUrl()}\n fallback={<i class={attachmentIcon(attachment)} aria-hidden=\"true\" />}\n >\n <img\n src={attachment.previewUrl}\n alt={attachment.alt ?? attachment.name}\n onError={() => setFailedPreviewUrl(attachment.previewUrl)}\n />\n </Show>\n <Show when={attachment.kind !== \"image\"}>\n <span>{attachment.name}</span>\n </Show>\n </>\n );\n return (\n <Show\n when={attachment.href}\n fallback={\n <div class=\"k2b-chat-message__attachment\" data-kind={attachment.kind} role=\"listitem\" title={attachment.name}>\n {content()}\n </div>\n }\n >\n {(href) => (\n <a\n class=\"k2b-chat-message__attachment\"\n data-kind={attachment.kind}\n role=\"listitem\"\n title={attachment.name}\n href={href()}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label={chatMessages().openInNewTab({ name: attachment.name })}\n >\n {content()}\n </a>\n )}\n </Show>\n );\n }}\n </For>\n </div>\n </Show>\n\n <Show when={props.children !== undefined && props.children !== null && props.children !== \"\"}>\n <div class=\"k2b-chat-message__bubble\">\n <div class=\"k2b-chat-message__content\">{props.children}</div>\n </div>\n </Show>\n\n <Show when={hasMeta()}>\n <footer class=\"k2b-chat-message__meta\">\n <Show\n when={props.status === \"streaming\"}\n fallback={\n <Show when={status()}>\n {(label) => (\n <span class=\"k2b-chat-message__status\" role={props.status === \"error\" ? \"alert\" : \"status\"}>\n <i class={statusIcon(props.status)} aria-hidden=\"true\" />\n {label()}\n </span>\n )}\n </Show>\n }\n >\n <span class=\"k2b-chat-message__status k2b-chat-message__status--streaming\" role=\"status\" aria-label={chatMessages().generating}>\n <ChatProgressDots />\n </span>\n </Show>\n <Show when={time()}>{(label) => <time dateTime={timestamp() ?? undefined}>{label()}</time>}</Show>\n <Show when={actions().length > 0 && actionDisplay() === \"inline\"}>\n <span class=\"k2b-chat-message__actions\" role=\"group\" aria-label={chatMessages().messageActions}>\n <For each={actions()}>\n {(action) => (\n <Tooltip.Trigger\n type=\"button\"\n aria-label={action.label}\n aria-pressed={action.pressed}\n data-pressed-tone={action.pressedTone}\n content={action.label}\n data-danger={action.variant === \"danger\" ? \"true\" : undefined}\n disabled={action.disabled || Boolean(busyActionId())}\n onClick={() => void runAction(action)}\n >\n <i class={actionIcon(action)} aria-hidden=\"true\" />\n </Tooltip.Trigger>\n )}\n </For>\n </span>\n </Show>\n <Show when={actions().length > 0 && actionDisplay() === \"menu\"}>\n <Dropdown.Root position=\"bottom-left\" label={chatMessages().messageActions} items={menuItems()}>\n <Dropdown.Trigger\n appearance=\"plain\"\n class=\"k2b-chat-message__menu\"\n label={chatMessages().messageActions}\n title={chatMessages().messageActions}\n >\n <i class=\"ti ti-dots\" aria-hidden=\"true\" />\n </Dropdown.Trigger>\n </Dropdown.Root>\n </Show>\n </footer>\n </Show>\n </article>\n );\n}\n\nconst ActivityContent = (props: ChatActivityProps & { disclosure?: boolean }) => (\n <>\n <span class=\"k2b-chat-activity__leading\" aria-hidden=\"true\">\n <Show when={props.leading} fallback={<i class={props.icon ?? \"ti ti-sparkles\"} />}>\n {props.leading}\n </Show>\n </span>\n <span class=\"k2b-chat-activity__copy\">\n <strong>{props.label}</strong>\n <Show when={props.description}>{(description) => <small>{description()}</small>}</Show>\n </span>\n <Show when={props.trailing}>\n <span class=\"k2b-chat-activity__trailing\">{props.trailing}</span>\n </Show>\n <Show when={props.disclosure}>\n <i class=\"ti ti-chevron-right k2b-chat-activity__chevron\" aria-hidden=\"true\" />\n </Show>\n </>\n);\n\nexport function ChatActivity(props: ChatActivityProps): JSX.Element {\n // The disclosure's real state. A controlled `open` sets it, and every toggle reports it, so the body renders whenever\n // the row is open, also when a host has not yet passed its new `open` back.\n const [expanded, setExpanded] = createSignal(props.open ?? props.defaultOpen ?? false);\n createRenderEffect(() => {\n const open = props.open;\n if (open !== undefined) setExpanded(open);\n });\n const open = expanded;\n const tone = () => props.tone ?? \"neutral\";\n const style = () => (props.accent ? { \"--k2b-chat-activity-accent\": props.accent } : undefined);\n return (\n <Show\n when={props.renderBody || props.children}\n fallback={\n <div\n class={`k2b-chat-activity ${props.class ?? \"\"}`}\n data-tone={tone()}\n data-accent={props.accent ? \"true\" : undefined}\n data-busy={props.busy ? \"true\" : undefined}\n data-chat-anchor={props.anchorId !== undefined ? String(props.anchorId) : undefined}\n style={style()}\n aria-busy={props.busy ? \"true\" : undefined}\n >\n <div class=\"k2b-chat-activity__row\">\n <ActivityContent {...props} />\n </div>\n </div>\n }\n >\n <details\n class={`k2b-chat-activity ${props.class ?? \"\"}`}\n data-tone={tone()}\n data-accent={props.accent ? \"true\" : undefined}\n data-busy={props.busy ? \"true\" : undefined}\n data-body-inset={props.bodyInset === false ? \"false\" : undefined}\n data-chat-anchor={props.anchorId !== undefined ? String(props.anchorId) : undefined}\n style={style()}\n open={open()}\n onToggle={(event) => {\n setExpanded(event.currentTarget.open);\n props.onOpenChange?.(event.currentTarget.open);\n }}\n aria-busy={props.busy ? \"true\" : undefined}\n >\n <summary class=\"k2b-chat-activity__row\" aria-label={props.ariaLabel}>\n <ActivityContent {...props} disclosure />\n </summary>\n <div class=\"k2b-chat-activity__body\">\n {props.renderBody ? <Show when={open() ? props.renderBody : undefined}>{(render) => render()()}</Show> : props.children}\n </div>\n </details>\n </Show>\n );\n}\n\nexport function ChatContextUsage(props: ChatContextUsageProps): JSX.Element {\n const [busy, setBusy] = createSignal(false);\n const run = async () => {\n const action = props.action;\n if (!action || action.disabled || busy()) return;\n setBusy(true);\n try {\n await executeChatAction(action);\n } catch (error) {\n props.onActionError?.(error);\n } finally {\n setBusy(false);\n }\n };\n const messages = useUiMessages();\n const chatMessages = useChatMessages();\n const locale = useLocale();\n const formatNumber = (value: number) => (props.formatNumber ? props.formatNumber(value) : formatLocaleInteger(value, locale()));\n const formattedUsageValue = (value: number | null): string => (value === null ? messages().unknown : formatNumber(value));\n const usage = () => normalizedUsage(props.usage);\n const loopUsage = () => normalizedUsage(props.loopUsage);\n const total = () => usage().total ?? 0;\n const windowSize = () => finiteNonNegative(props.contextWindow);\n const reported = () => usage().reported;\n const percent = () => (reported() && windowSize() > 0 ? Math.min(100, Math.round((total() / windowSize()) * 100)) : null);\n const remaining = () => (reported() && windowSize() > 0 ? Math.max(0, windowSize() - total()) : null);\n const accessibleLabel = () => {\n if (!reported()) {\n return windowSize() > 0\n ? chatMessages().contextUsageUnavailableWithWindow({ window: formatNumber(windowSize()) })\n : chatMessages().contextUsageUnavailable;\n }\n return percent() === null\n ? chatMessages().tokensUsed({ total: formatNumber(total()) })\n : chatMessages().tokensUsedPercent({ total: formatNumber(total()), percent: percent()! });\n };\n\n return (\n <ChatContextPopup\n content={\n <ChatContextPanel title={chatMessages().lastRequestContext}>\n <Show when={percent() !== null}>\n <ProgressBar\n value={percent() ?? 0}\n size=\"xs\"\n tone={(percent() ?? 0) >= 85 ? \"danger\" : \"info\"}\n label={chatMessages().contextWindowUsed}\n />\n </Show>\n <dl>\n <Show when={props.modelLabel}>\n {(model) => (\n <div>\n <dt>{chatMessages().model}</dt>\n <dd>{model()}</dd>\n </div>\n )}\n </Show>\n <div>\n <dt>{chatMessages().input}</dt>\n <dd>{formattedUsageValue(usage().input)}</dd>\n </div>\n <div>\n <dt>{chatMessages().output}</dt>\n <dd>{formattedUsageValue(usage().output)}</dd>\n </div>\n <Show when={loopUsage().reported}>\n <div>\n <dt>{chatMessages().loopTotal}</dt>\n <dd>{formattedUsageValue(loopUsage().total)}</dd>\n </div>\n </Show>\n <div>\n <dt>{chatMessages().contextWindow}</dt>\n <dd>{windowSize() > 0 ? formatNumber(windowSize()) : chatMessages().notConfigured}</dd>\n </div>\n <Show when={remaining() !== null}>\n <div>\n <dt>{chatMessages().remaining}</dt>\n <dd>{remaining() === null ? messages().unknown : formatNumber(remaining()!)}</dd>\n </div>\n </Show>\n </dl>\n <Show when={props.action}>\n {(action) => (\n <Button size=\"xs\" variant=\"subtle\" disabled={action().disabled || busy()} onClick={() => void run()} aria-busy={busy()}>\n <i class={busy() ? \"ti ti-loader-2 k2b-spin\" : action().icon} aria-hidden=\"true\" />\n {action().label}\n </Button>\n )}\n </Show>\n </ChatContextPanel>\n }\n type=\"button\"\n class={`k2b-chat-context ${props.class ?? \"\"}`}\n data-warning={reported() && (percent() ?? 0) >= 85 ? \"true\" : undefined}\n aria-label={accessibleLabel()}\n >\n <i class=\"ti ti-brain\" aria-hidden=\"true\" />\n <span>{percent() === null ? \"–\" : `${percent()}%`}</span>\n </ChatContextPopup>\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["chat/ChatPrimitives.tsx"],"sourcesContent":["import {\n type Accessor,\n children,\n createContext,\n createRenderEffect,\n createSignal,\n createUniqueId,\n For,\n type JSX,\n onCleanup,\n Show,\n useContext,\n} from \"solid-js\";\nimport { Button } from \"../actions/Button\";\nimport { Dropdown, type DropdownItem } from \"../actions/Dropdown\";\nimport { Tooltip } from \"../feedback/Tooltip\";\nimport { useLocale } from \"../intl/locale\";\nimport { useUiMessages } from \"../intl/messages\";\nimport { ProgressBar } from \"../surfaces/ProgressBar\";\nimport { ChatContextPanel, ChatContextPopup } from \"./ChatContextPopup\";\nimport { executeChatAction } from \"./chat-behavior\";\nimport { type ChatMessages, useChatMessages } from \"./chat-messages\";\nimport type { ChatAction, ChatActivityTone, ChatAttachment, ChatContextUsageData, ChatMessageStatus, ChatRole } from \"./types\";\n\nexport type ChatMessageProps = {\n role: ChatRole;\n children?: JSX.Element;\n label?: string;\n createdAt?: string | Date;\n timeLabel?: string;\n status?: ChatMessageStatus;\n attachments?: readonly ChatAttachment[];\n actions?: readonly ChatAction[];\n actionDisplay?: \"auto\" | \"inline\" | \"menu\";\n anchorId?: string | number;\n onActionError?: (error: unknown) => void;\n class?: string;\n};\n\nexport type ChatActivityProps = {\n /** The step as text, or as a sentence with `ReferenceChip`s. */\n label: JSX.Element;\n /** Spelled-out name for an expandable row whose visible text abbreviates, such as durations. */\n ariaLabel?: string;\n description?: string;\n icon?: string;\n /** Optional host-owned leading visual rendered instead of the icon. */\n leading?: JSX.Element;\n /** Optional identity accent for the leading visual. Semantic tones still take precedence. */\n accent?: string;\n tone?: ChatActivityTone;\n /** Marks the activity as running with the shared accent sweep. */\n busy?: boolean;\n /** Lets label and description wrap instead of ending in an ellipsis, for a system line whose whole sentence matters. */\n wrap?: boolean;\n trailing?: JSX.Element;\n /** Controlled disclosure state. Omit to keep native details behavior. */\n open?: boolean;\n /** Reports disclosure changes when `open` is controlled by the host. */\n onOpenChange?: (open: boolean) => void;\n defaultOpen?: boolean;\n /** Set to false when the body is a peer list that should align with the activity row. */\n bodyInset?: boolean;\n anchorId?: string | number;\n children?: JSX.Element;\n /** Mount expensive details only while expanded. */\n renderBody?: () => JSX.Element;\n class?: string;\n};\n\nexport type ChatContextUsageProps = ChatContextUsageData & {\n action?: ChatAction;\n onActionError?: (error: unknown) => void;\n /** Host-owned number formatting. The default groups whole numbers in the inherited render locale. */\n formatNumber?: (value: number) => string;\n class?: string;\n};\n\nconst roleLabel = (role: ChatRole, messages: ChatMessages): string => {\n if (role === \"assistant\") return messages.assistant;\n if (role === \"user\") return messages.user;\n if (role === \"tool\") return messages.tool;\n return messages.system;\n};\n\nconst statusLabel = (status: ChatMessageStatus | undefined, messages: ChatMessages): string | null => {\n if (status === \"pending\") return messages.waiting;\n if (status === \"streaming\") return messages.generating;\n if (status === \"error\") return messages.failed;\n return null;\n};\n\nconst statusIcon = (status: ChatMessageStatus | undefined): string => {\n if (status === \"pending\") return \"ti ti-clock\";\n return \"ti ti-alert-circle\";\n};\n\nconst ChatProgressDots = () => (\n <span class=\"k2b-chat-progress-dots\" aria-hidden=\"true\">\n <span />\n <span />\n <span />\n </span>\n);\n\nconst attachmentIcon = (attachment: ChatAttachment): string =>\n attachment.icon ?? (attachment.kind === \"image\" ? \"ti ti-photo\" : attachment.kind === \"resource\" ? \"ti ti-link\" : \"ti ti-file\");\n\nconst finiteNonNegative = (value: number | undefined): number =>\n typeof value === \"number\" && Number.isFinite(value) ? Math.max(0, value) : 0;\n\nconst finiteUsageValue = (value: number | undefined): number | null =>\n typeof value === \"number\" && Number.isFinite(value) && value >= 0 ? value : null;\n\nconst normalizedUsage = (usage: ChatContextUsageData[\"usage\"]) => {\n const input = finiteUsageValue(usage?.input);\n const output = finiteUsageValue(usage?.output);\n const explicitTotal = finiteUsageValue(usage?.total);\n const total = explicitTotal ?? (input !== null || output !== null ? (input ?? 0) + (output ?? 0) : null);\n return { input, output, total, reported: total !== null };\n};\n\n/** Whole numbers in the render locale, so a German page reads 128.000 and an English one 128,000. */\nconst formatLocaleInteger = (value: number, locale: string): string =>\n new Intl.NumberFormat(locale, { maximumFractionDigits: 0 }).format(Math.round(finiteNonNegative(value)));\n\nexport const formatChatTokens = (tokens: number): string => {\n const value = finiteNonNegative(tokens);\n if (value >= 1_000_000) return `${(value / 1_000_000).toFixed(1)}M`;\n if (value >= 1_000) return `${(value / 1_000).toFixed(1)}k`;\n return String(Math.round(value));\n};\n\nconst dateTime = (value: string | Date | undefined): string | null => {\n if (!value) return null;\n const date = value instanceof Date ? value : new Date(value);\n return Number.isFinite(date.getTime()) ? date.toISOString() : null;\n};\n\nexport function ChatMessage(props: ChatMessageProps): JSX.Element {\n const chatMessages = useChatMessages();\n const [busyActionId, setBusyActionId] = createSignal<string | null>(null);\n const [completedActionId, setCompletedActionId] = createSignal<string | null>(null);\n let completedTimer: ReturnType<typeof setTimeout> | undefined;\n const status = () => statusLabel(props.status, chatMessages());\n const timestamp = () => dateTime(props.createdAt);\n // Locale and timezone are application policy. Requiring an explicit visible\n // label keeps SSR and hydration byte-stable while `createdAt` still supplies\n // the semantic machine-readable timestamp.\n const time = () => props.timeLabel ?? null;\n const actions = () => props.actions ?? [];\n const actionDisplay = () =>\n props.actionDisplay === \"auto\" || !props.actionDisplay ? (props.role === \"user\" ? \"menu\" : \"inline\") : props.actionDisplay;\n const hasMeta = () => props.status === \"streaming\" || status() !== null || Boolean(time()) || actions().length > 0;\n\n const runAction = async (action: ChatAction) => {\n if (action.disabled || busyActionId()) return;\n setBusyActionId(action.id);\n try {\n await executeChatAction(action);\n setCompletedActionId(action.id);\n if (completedTimer) clearTimeout(completedTimer);\n completedTimer = setTimeout(() => setCompletedActionId(null), 1400);\n } catch (error) {\n props.onActionError?.(error);\n } finally {\n setBusyActionId(null);\n }\n };\n\n const actionIcon = (action: ChatAction) =>\n busyActionId() === action.id\n ? \"ti ti-loader-2 k2b-spin\"\n : completedActionId() === action.id\n ? \"ti ti-check\"\n : (action.icon ?? \"ti ti-dots\");\n\n onCleanup(() => {\n if (completedTimer) clearTimeout(completedTimer);\n });\n\n const menuItems = (): readonly DropdownItem[] =>\n actions().map((action) => ({\n icon: actionIcon(action),\n label: action.label,\n variant: action.variant,\n disabled: action.disabled || Boolean(busyActionId()),\n action: () => void runAction(action),\n }));\n\n return (\n <article\n class={`k2b-chat-message ${props.class ?? \"\"}`}\n data-role={props.role}\n data-status={props.status ?? \"complete\"}\n data-chat-anchor={props.anchorId !== undefined ? String(props.anchorId) : undefined}\n aria-busy={props.status === \"pending\" || props.status === \"streaming\" ? \"true\" : undefined}\n >\n <span class=\"k2b-sr-only\">{props.label ?? roleLabel(props.role, chatMessages())}: </span>\n <Show when={(props.attachments?.length ?? 0) > 0}>\n <div class=\"k2b-chat-message__attachments\" role=\"list\" aria-label={chatMessages().attachments}>\n <For each={props.attachments}>\n {(attachment) => {\n // A preview that no longer loads, such as a deleted file, falls back to the attachment icon; a new URL tries again.\n const [failedPreviewUrl, setFailedPreviewUrl] = createSignal<string>();\n const content = () => (\n <>\n <Show\n when={attachment.kind === \"image\" && attachment.previewUrl && attachment.previewUrl !== failedPreviewUrl()}\n fallback={<i class={attachmentIcon(attachment)} aria-hidden=\"true\" />}\n >\n <img\n src={attachment.previewUrl}\n alt={attachment.alt ?? attachment.name}\n onError={() => setFailedPreviewUrl(attachment.previewUrl)}\n />\n </Show>\n <Show when={attachment.kind !== \"image\"}>\n <span>{attachment.name}</span>\n </Show>\n </>\n );\n return (\n <Show\n when={attachment.href}\n fallback={\n <div class=\"k2b-chat-message__attachment\" data-kind={attachment.kind} role=\"listitem\" title={attachment.name}>\n {content()}\n </div>\n }\n >\n {(href) => (\n <a\n class=\"k2b-chat-message__attachment\"\n data-kind={attachment.kind}\n role=\"listitem\"\n title={attachment.name}\n href={href()}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label={chatMessages().openInNewTab({ name: attachment.name })}\n >\n {content()}\n </a>\n )}\n </Show>\n );\n }}\n </For>\n </div>\n </Show>\n\n <Show when={props.children !== undefined && props.children !== null && props.children !== \"\"}>\n <div class=\"k2b-chat-message__bubble\">\n <div class=\"k2b-chat-message__content\">{props.children}</div>\n </div>\n </Show>\n\n <Show when={hasMeta()}>\n <footer class=\"k2b-chat-message__meta\">\n <Show\n when={props.status === \"streaming\"}\n fallback={\n <Show when={status()}>\n {(label) => (\n <span class=\"k2b-chat-message__status\" role={props.status === \"error\" ? \"alert\" : \"status\"}>\n <i class={statusIcon(props.status)} aria-hidden=\"true\" />\n {label()}\n </span>\n )}\n </Show>\n }\n >\n <span class=\"k2b-chat-message__status k2b-chat-message__status--streaming\" role=\"status\" aria-label={chatMessages().generating}>\n <ChatProgressDots />\n </span>\n </Show>\n <Show when={time()}>{(label) => <time dateTime={timestamp() ?? undefined}>{label()}</time>}</Show>\n <Show when={actions().length > 0 && actionDisplay() === \"inline\"}>\n <span class=\"k2b-chat-message__actions\" role=\"group\" aria-label={chatMessages().messageActions}>\n <For each={actions()}>\n {(action) => (\n <Tooltip.Trigger\n type=\"button\"\n aria-label={action.label}\n aria-pressed={action.pressed}\n data-pressed-tone={action.pressedTone}\n content={action.label}\n data-danger={action.variant === \"danger\" ? \"true\" : undefined}\n disabled={action.disabled || Boolean(busyActionId())}\n onClick={() => void runAction(action)}\n >\n <i class={actionIcon(action)} aria-hidden=\"true\" />\n </Tooltip.Trigger>\n )}\n </For>\n </span>\n </Show>\n <Show when={actions().length > 0 && actionDisplay() === \"menu\"}>\n <Dropdown.Root position=\"bottom-left\" label={chatMessages().messageActions} items={menuItems()}>\n <Dropdown.Trigger\n appearance=\"plain\"\n class=\"k2b-chat-message__menu\"\n label={chatMessages().messageActions}\n title={chatMessages().messageActions}\n >\n <i class=\"ti ti-dots\" aria-hidden=\"true\" />\n </Dropdown.Trigger>\n </Dropdown.Root>\n </Show>\n </footer>\n </Show>\n </article>\n );\n}\n\nconst ActivityContent = (props: ChatActivityProps & { label: JSX.Element; disclosure?: boolean }) => (\n <>\n <span class=\"k2b-chat-activity__leading\" aria-hidden=\"true\">\n <Show when={props.leading} fallback={<i class={props.icon ?? \"ti ti-sparkles\"} />}>\n {props.leading}\n </Show>\n </span>\n <span class=\"k2b-chat-activity__copy\">\n <strong>{props.label}</strong>\n <Show when={props.description}>{(description) => <small>{description()}</small>}</Show>\n </span>\n <Show when={props.trailing}>\n <span class=\"k2b-chat-activity__trailing\">{props.trailing}</span>\n </Show>\n <Show when={props.disclosure}>\n <i class=\"ti ti-chevron-right k2b-chat-activity__chevron\" aria-hidden=\"true\" />\n </Show>\n </>\n);\n\ntype ActivityDisclosure = {\n /** Whether the activity has a body this toggle can open. */\n expandable: Accessor<boolean>;\n open: Accessor<boolean>;\n toggle: () => void;\n bodyId: string;\n register: () => void;\n};\n\nconst ActivityDisclosureContext = createContext<ActivityDisclosure>();\n\nexport type ChatActivityToggleProps = {\n /** The words that open the body, usually the count, such as \"3 of 4 tasks\". */\n children: JSX.Element;\n};\n\n/**\n * The words of an activity label that open its body, with the chevron right after them. With a toggle in its label,\n * only these words are the disclosure, and the rest of the row, chips with links included, stays ordinary content.\n * Outside an activity with a body it renders its words as plain text.\n */\nexport function ChatActivityToggle(props: ChatActivityToggleProps): JSX.Element {\n const disclosure = useContext(ActivityDisclosureContext);\n disclosure?.register();\n return (\n <Show when={disclosure?.expandable() ? disclosure : undefined} fallback={props.children}>\n {(current) => (\n <button\n type=\"button\"\n class=\"k2b-chat-activity__toggle\"\n aria-expanded={current().open() ? \"true\" : \"false\"}\n aria-controls={current().bodyId}\n onClick={() => current().toggle()}\n >\n <span class=\"k2b-chat-activity__toggle-label\">{props.children}</span>\n <i class=\"ti ti-chevron-right k2b-chat-activity__chevron\" aria-hidden=\"true\" />\n </button>\n )}\n </Show>\n );\n}\n\nexport function ChatActivity(props: ChatActivityProps): JSX.Element {\n // The disclosure's real state. A controlled `open` sets it, and every toggle reports it, so the body renders whenever\n // the row is open, also when a host has not yet passed its new `open` back.\n const [expanded, setExpanded] = createSignal(props.open ?? props.defaultOpen ?? false);\n createRenderEffect(() => {\n const open = props.open;\n if (open !== undefined) setExpanded(open);\n });\n const open = expanded;\n const setOpen = (next: boolean) => {\n if (next === expanded()) return;\n setExpanded(next);\n props.onOpenChange?.(next);\n };\n const tone = () => props.tone ?? \"neutral\";\n const style = () => (props.accent ? { \"--k2b-chat-activity-accent\": props.accent } : undefined);\n const expandable = () => Boolean(props.renderBody || props.children);\n // A `Chat.Activity.Toggle` in the label registers while the label resolves, before the row picks its element, so the\n // server and the first browser frame agree on whether the whole row or only the toggle is the disclosure.\n const [toggles, setToggles] = createSignal(0);\n const bodyId = createUniqueId();\n const disclosure: ActivityDisclosure = {\n expandable,\n open,\n toggle: () => setOpen(!expanded()),\n bodyId,\n register: () => {\n setToggles((count) => count + 1);\n onCleanup(() => setToggles((count) => count - 1));\n },\n };\n const body = () =>\n props.renderBody ? <Show when={open() ? props.renderBody : undefined}>{(render) => render()()}</Show> : props.children;\n return (\n <ActivityDisclosureContext.Provider value={disclosure}>\n {(() => {\n const label = children(() => props.label);\n return (\n <Show\n when={expandable()}\n fallback={\n <div\n class={`k2b-chat-activity ${props.class ?? \"\"}`}\n data-tone={tone()}\n data-accent={props.accent ? \"true\" : undefined}\n data-busy={props.busy ? \"true\" : undefined}\n data-wrap={props.wrap ? \"true\" : undefined}\n data-chat-anchor={props.anchorId !== undefined ? String(props.anchorId) : undefined}\n style={style()}\n aria-busy={props.busy ? \"true\" : undefined}\n >\n <div class=\"k2b-chat-activity__row\">\n <ActivityContent {...props} label={label()} />\n </div>\n </div>\n }\n >\n <Show\n when={toggles() === 0}\n fallback={\n <div\n class={`k2b-chat-activity ${props.class ?? \"\"}`}\n data-tone={tone()}\n data-accent={props.accent ? \"true\" : undefined}\n data-busy={props.busy ? \"true\" : undefined}\n data-wrap={props.wrap ? \"true\" : undefined}\n data-body-inset={props.bodyInset === false ? \"false\" : undefined}\n data-open={open() ? \"true\" : \"false\"}\n data-chat-anchor={props.anchorId !== undefined ? String(props.anchorId) : undefined}\n style={style()}\n aria-busy={props.busy ? \"true\" : undefined}\n >\n <div class=\"k2b-chat-activity__row\">\n <ActivityContent {...props} label={label()} />\n </div>\n <div id={bodyId} class=\"k2b-chat-activity__body\" hidden={!open()}>\n {body()}\n </div>\n </div>\n }\n >\n <details\n class={`k2b-chat-activity ${props.class ?? \"\"}`}\n data-tone={tone()}\n data-accent={props.accent ? \"true\" : undefined}\n data-busy={props.busy ? \"true\" : undefined}\n data-wrap={props.wrap ? \"true\" : undefined}\n data-body-inset={props.bodyInset === false ? \"false\" : undefined}\n data-chat-anchor={props.anchorId !== undefined ? String(props.anchorId) : undefined}\n style={style()}\n open={open()}\n onToggle={(event) => {\n setExpanded(event.currentTarget.open);\n props.onOpenChange?.(event.currentTarget.open);\n }}\n aria-busy={props.busy ? \"true\" : undefined}\n >\n <summary class=\"k2b-chat-activity__row\" aria-label={props.ariaLabel}>\n <ActivityContent {...props} label={label()} disclosure />\n </summary>\n <div class=\"k2b-chat-activity__body\">{body()}</div>\n </details>\n </Show>\n </Show>\n );\n })()}\n </ActivityDisclosureContext.Provider>\n );\n}\n\nexport function ChatContextUsage(props: ChatContextUsageProps): JSX.Element {\n const [busy, setBusy] = createSignal(false);\n const run = async () => {\n const action = props.action;\n if (!action || action.disabled || busy()) return;\n setBusy(true);\n try {\n await executeChatAction(action);\n } catch (error) {\n props.onActionError?.(error);\n } finally {\n setBusy(false);\n }\n };\n const messages = useUiMessages();\n const chatMessages = useChatMessages();\n const locale = useLocale();\n const formatNumber = (value: number) => (props.formatNumber ? props.formatNumber(value) : formatLocaleInteger(value, locale()));\n const formattedUsageValue = (value: number | null): string => (value === null ? messages().unknown : formatNumber(value));\n const usage = () => normalizedUsage(props.usage);\n const loopUsage = () => normalizedUsage(props.loopUsage);\n const total = () => usage().total ?? 0;\n const windowSize = () => finiteNonNegative(props.contextWindow);\n const reported = () => usage().reported;\n const percent = () => (reported() && windowSize() > 0 ? Math.min(100, Math.round((total() / windowSize()) * 100)) : null);\n const remaining = () => (reported() && windowSize() > 0 ? Math.max(0, windowSize() - total()) : null);\n const accessibleLabel = () => {\n if (!reported()) {\n return windowSize() > 0\n ? chatMessages().contextUsageUnavailableWithWindow({ window: formatNumber(windowSize()) })\n : chatMessages().contextUsageUnavailable;\n }\n return percent() === null\n ? chatMessages().tokensUsed({ total: formatNumber(total()) })\n : chatMessages().tokensUsedPercent({ total: formatNumber(total()), percent: percent()! });\n };\n\n return (\n <ChatContextPopup\n content={\n <ChatContextPanel title={chatMessages().lastRequestContext}>\n <Show when={percent() !== null}>\n <ProgressBar\n value={percent() ?? 0}\n size=\"xs\"\n tone={(percent() ?? 0) >= 85 ? \"danger\" : \"info\"}\n label={chatMessages().contextWindowUsed}\n />\n </Show>\n <dl>\n <Show when={props.modelLabel}>\n {(model) => (\n <div>\n <dt>{chatMessages().model}</dt>\n <dd>{model()}</dd>\n </div>\n )}\n </Show>\n <div>\n <dt>{chatMessages().input}</dt>\n <dd>{formattedUsageValue(usage().input)}</dd>\n </div>\n <div>\n <dt>{chatMessages().output}</dt>\n <dd>{formattedUsageValue(usage().output)}</dd>\n </div>\n <Show when={loopUsage().reported}>\n <div>\n <dt>{chatMessages().loopTotal}</dt>\n <dd>{formattedUsageValue(loopUsage().total)}</dd>\n </div>\n </Show>\n <div>\n <dt>{chatMessages().contextWindow}</dt>\n <dd>{windowSize() > 0 ? formatNumber(windowSize()) : chatMessages().notConfigured}</dd>\n </div>\n <Show when={remaining() !== null}>\n <div>\n <dt>{chatMessages().remaining}</dt>\n <dd>{remaining() === null ? messages().unknown : formatNumber(remaining()!)}</dd>\n </div>\n </Show>\n </dl>\n <Show when={props.action}>\n {(action) => (\n <Button size=\"xs\" variant=\"subtle\" disabled={action().disabled || busy()} onClick={() => void run()} aria-busy={busy()}>\n <i class={busy() ? \"ti ti-loader-2 k2b-spin\" : action().icon} aria-hidden=\"true\" />\n {action().label}\n </Button>\n )}\n </Show>\n </ChatContextPanel>\n }\n type=\"button\"\n class={`k2b-chat-context ${props.class ?? \"\"}`}\n data-warning={reported() && (percent() ?? 0) >= 85 ? \"true\" : undefined}\n aria-label={accessibleLabel()}\n >\n <i class=\"ti ti-brain\" aria-hidden=\"true\" />\n <span>{percent() === null ? \"–\" : `${percent()}%`}</span>\n </ChatContextPopup>\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["chat/ChatTimeline.tsx"],"sourcesContent":["import { createEffect, createMemo, createSignal, For, type JSX, onCleanup, onMount, Show, untrack } from \"solid-js\";\nimport { createScrollFade } from \"../layout/scroll-fade\";\nimport Placeholder from \"../surfaces/Placeholder\";\nimport { ChatActivity, ChatMessage } from \"./ChatPrimitives\";\nimport { isChatNearBottom, restoredChatScrollTop } from \"./chat-behavior\";\nimport { useChatMessages } from \"./chat-messages\";\nimport type { ChatAction, ChatActivityTone, ChatAttachment, ChatMessageStatus, ChatRole } from \"./types\";\n\nexport type ChatMessageItem = {\n kind: \"message\";\n /** Unique within the timeline. A record with a known id updates its row in place instead of replacing it. */\n id: string;\n role: ChatRole;\n content?: JSX.Element;\n label?: string;\n createdAt?: string | Date;\n timeLabel?: string;\n status?: ChatMessageStatus;\n attachments?: readonly ChatAttachment[];\n actions?: readonly ChatAction[];\n actionDisplay?: \"auto\" | \"inline\" | \"menu\";\n anchorId?: string | number;\n class?: string;\n};\n\nexport type ChatActivityItem = {\n kind: \"activity\";\n /** Unique within the timeline. A record with a known id updates its row in place instead of replacing it. */\n id: string;\n label: string;\n description?: string;\n icon?: string;\n leading?: JSX.Element;\n accent?: string;\n tone?: ChatActivityTone;\n busy?: boolean;\n trailing?: JSX.Element;\n defaultOpen?: boolean;\n anchorId?: string | number;\n content?: JSX.Element;\n class?: string;\n};\n\nexport type ChatTimelineItem = ChatMessageItem | ChatActivityItem;\n\nexport type ChatTimelineProps = {\n scrollFade?: boolean;\n items: readonly ChatTimelineItem[];\n conversationKey?: string | null;\n loading?: boolean;\n hasMore?: boolean;\n loadingOlder?: boolean;\n onLoadOlder?: () => boolean | void | Promise<boolean | void>;\n emptyTitle?: string;\n emptyDescription?: string;\n navigation?: JSX.Element;\n onActionError?: (error: unknown) => void;\n viewportRef?: (element: HTMLDivElement) => void;\n contentRef?: (element: HTMLDivElement) => void;\n scrollToAnchorRef?: (scrollToAnchor: (anchorId: string | number) => boolean) => void;\n label?: string;\n followThreshold?: number;\n class?: string;\n};\n\nexport function ChatTimeline(props: ChatTimelineProps): JSX.Element {\n const chatMessages = useChatMessages();\n const [pinned, setPinned] = createSignal(true);\n const [loadingOlderInternally, setLoadingOlderInternally] = createSignal(false);\n const [historyError, setHistoryError] = createSignal<string | null>(null);\n let viewportRef: HTMLDivElement | undefined;\n createScrollFade(\n () => viewportRef,\n () => props.scrollFade !== false,\n );\n let contentRef: HTMLDivElement | undefined;\n let topSentinelRef: HTMLDivElement | undefined;\n let followFrame: number | undefined;\n let userScrollFrame: number | undefined;\n let userScrollingAway = false;\n /** Set while a row the reader toggled settles; the timeline does not follow the end meanwhile. */\n let disclosureHold = 0;\n let touchY: number | undefined;\n let lastConversationKey: string | null | undefined;\n\n const loadingOlder = () => Boolean(props.loadingOlder || loadingOlderInternally());\n const canLoadOlder = () => Boolean(props.onLoadOlder && props.hasMore && !loadingOlder());\n const hasHistoryControls = () => loadingOlder() || historyError() !== null || canLoadOlder();\n const hasContent = () => props.items.length > 0;\n const itemIds = createMemo(() => props.items.map((item) => item.id), undefined, {\n equals: (previous, next) => previous.length === next.length && previous.every((id, index) => id === next[index]),\n });\n const itemsById = createMemo(() => new Map(props.items.map((item) => [item.id, item])));\n const threshold = () => Math.max(0, props.followThreshold ?? 96);\n\n const cancelFollow = () => {\n if (followFrame !== undefined) cancelAnimationFrame(followFrame);\n followFrame = undefined;\n };\n\n props.scrollToAnchorRef?.((anchorId) => {\n const anchor = Array.from(contentRef?.querySelectorAll<HTMLElement>(\"[data-chat-anchor]\") ?? []).find(\n (element) => element.dataset.chatAnchor === String(anchorId),\n );\n if (!viewportRef || !anchor) return false;\n cancelFollow();\n setPinned(false);\n viewportRef.scrollTop = Math.max(\n 0,\n viewportRef.scrollTop + anchor.getBoundingClientRect().top - viewportRef.getBoundingClientRect().top - 16,\n );\n return true;\n });\n\n const noteUserScrollAway = () => {\n userScrollingAway = true;\n if (userScrollFrame !== undefined) cancelAnimationFrame(userScrollFrame);\n userScrollFrame = requestAnimationFrame(() => {\n userScrollFrame = undefined;\n userScrollingAway = false;\n });\n };\n\n const scrollToLatest = () => {\n if (!viewportRef) return;\n setPinned(true);\n viewportRef.scrollTop = viewportRef.scrollHeight;\n };\n\n const scheduleFollow = () => {\n if (!pinned() || disclosureHold !== 0 || followFrame !== undefined) return;\n followFrame = requestAnimationFrame(() => {\n followFrame = undefined;\n if (pinned()) scrollToLatest();\n });\n };\n\n const loadOlder = async () => {\n if (!props.onLoadOlder || !props.hasMore || loadingOlder()) return;\n const viewport = viewportRef;\n if (!viewport) return;\n const previousScrollTop = viewport.scrollTop;\n const previousScrollHeight = viewport.scrollHeight;\n setHistoryError(null);\n setLoadingOlderInternally(true);\n let prepended = false;\n try {\n prepended = (await props.onLoadOlder()) !== false;\n } catch (error) {\n setHistoryError(error instanceof Error ? error.message : chatMessages().couldNotLoadOlderMessages);\n } finally {\n setLoadingOlderInternally(false);\n }\n if (!prepended || viewportRef !== viewport) return;\n queueMicrotask(() => {\n requestAnimationFrame(() => {\n if (viewportRef !== viewport) return;\n viewport.scrollTop = restoredChatScrollTop(previousScrollTop, previousScrollHeight, viewport.scrollHeight);\n });\n });\n };\n\n // A reader who opens or closes a row reads there. The row stays where it was instead of following the newest message,\n // which would move it away from the pointer; once it has settled, the timeline keeps following only from the end.\n const holdForDisclosure = (event: MouseEvent) => {\n if (!(event.target instanceof Element) || !event.target.closest(\"summary\")) return;\n cancelFollow();\n const hold = ++disclosureHold;\n requestAnimationFrame(() =>\n requestAnimationFrame(() => {\n if (hold !== disclosureHold) return;\n disclosureHold = 0;\n if (viewportRef && !isChatNearBottom(viewportRef.scrollHeight, viewportRef.scrollTop, viewportRef.clientHeight, threshold()))\n setPinned(false);\n }),\n );\n };\n\n const updatePinned = () => {\n if (!viewportRef) return;\n const nearBottom = isChatNearBottom(viewportRef.scrollHeight, viewportRef.scrollTop, viewportRef.clientHeight, threshold());\n if (nearBottom) setPinned(true);\n else if (userScrollingAway || followFrame === undefined) {\n if (userScrollingAway) cancelFollow();\n setPinned(false);\n }\n if (viewportRef.scrollTop <= threshold()) void loadOlder();\n };\n\n onMount(() => {\n // Switch from CSS-only SSR anchoring to normal scroll coordinates before paint.\n viewportRef?.removeAttribute(\"data-initializing\");\n scrollToLatest();\n const resizeObserver = typeof ResizeObserver === \"undefined\" ? null : new ResizeObserver(() => scheduleFollow());\n if (contentRef) resizeObserver?.observe(contentRef);\n if (viewportRef) resizeObserver?.observe(viewportRef);\n\n const historyObserver =\n typeof IntersectionObserver === \"undefined\" || !topSentinelRef\n ? null\n : new IntersectionObserver(\n (entries) => {\n if (entries.some((entry) => entry.isIntersecting)) void loadOlder();\n },\n { root: viewportRef, rootMargin: \"160px 0px 0px\" },\n );\n if (topSentinelRef) historyObserver?.observe(topSentinelRef);\n // Keyboard activation of a row also arrives as a click.\n contentRef?.addEventListener(\"click\", holdForDisclosure);\n\n onCleanup(() => {\n cancelFollow();\n if (userScrollFrame !== undefined) cancelAnimationFrame(userScrollFrame);\n resizeObserver?.disconnect();\n historyObserver?.disconnect();\n contentRef?.removeEventListener(\"click\", holdForDisclosure);\n });\n });\n\n createEffect(() => {\n const key = props.conversationKey;\n if (key === lastConversationKey) return;\n lastConversationKey = key;\n setHistoryError(null);\n setPinned(true);\n queueMicrotask(scrollToLatest);\n });\n\n createEffect(() => {\n props.items.length;\n props.items.at(-1)?.id;\n untrack(scheduleFollow);\n });\n\n return (\n <section class={`k2b-chat-timeline ${props.class ?? \"\"}`} aria-label={props.label ?? chatMessages().conversation}>\n <div\n ref={(element) => {\n viewportRef = element;\n props.viewportRef?.(element);\n }}\n class=\"k2b-chat-timeline__viewport\"\n data-scroll-fade-mode={props.scrollFade !== false ? \"bottom\" : undefined}\n data-initializing=\"\"\n role=\"region\"\n aria-label={chatMessages().conversationMessages({ label: props.label ?? chatMessages().conversation })}\n tabIndex={0}\n onWheel={(event) => {\n if (event.deltaY < 0) noteUserScrollAway();\n }}\n onKeyDown={(event) => {\n if (event.target !== event.currentTarget) return;\n if (event.key === \"ArrowUp\" || event.key === \"PageUp\" || event.key === \"Home\" || (event.key === \" \" && event.shiftKey)) {\n noteUserScrollAway();\n }\n }}\n onTouchStart={(event) => {\n touchY = event.touches[0]?.clientY;\n }}\n onTouchMove={(event) => {\n const nextY = event.touches[0]?.clientY;\n if (nextY !== undefined && touchY !== undefined && nextY > touchY) noteUserScrollAway();\n touchY = nextY;\n }}\n onTouchEnd={() => {\n touchY = undefined;\n }}\n onScroll={updatePinned}\n >\n <Show when={props.navigation}>\n <div class=\"k2b-chat-timeline__navigation\" aria-live=\"off\">\n {props.navigation}\n </div>\n </Show>\n <div\n ref={(element) => {\n contentRef = element;\n props.contentRef?.(element);\n }}\n class=\"k2b-chat-timeline__content\"\n role=\"log\"\n aria-live=\"polite\"\n aria-relevant=\"additions text\"\n aria-busy={props.loading ? \"true\" : undefined}\n >\n <div ref={topSentinelRef} class=\"k2b-chat-timeline__sentinel\" aria-hidden=\"true\" />\n <Show when={hasHistoryControls()}>\n <div class=\"k2b-chat-timeline__history\" aria-live=\"off\">\n <Show when={canLoadOlder()}>\n <button type=\"button\" class=\"k2b-chat-timeline__older\" onClick={() => void loadOlder()}>\n <i class=\"ti ti-history\" aria-hidden=\"true\" />\n {chatMessages().loadOlderMessages}\n </button>\n </Show>\n <Show when={loadingOlder()}>\n <ChatActivity\n label={chatMessages().loadingOlderMessages}\n icon=\"ti ti-history\"\n trailing={<i class=\"ti ti-loader-2 k2b-spin\" aria-hidden=\"true\" />}\n />\n </Show>\n <Show when={historyError()}>\n {(message) => (\n <ChatActivity\n label={chatMessages().couldNotLoadOlderMessages}\n description={message()}\n icon=\"ti ti-alert-circle\"\n tone=\"danger\"\n trailing={\n <button\n type=\"button\"\n class=\"k2b-chat-timeline__retry\"\n aria-label={chatMessages().retryOlderMessages}\n onClick={() => void loadOlder()}\n >\n <i class=\"ti ti-refresh\" aria-hidden=\"true\" />\n </button>\n }\n />\n )}\n </Show>\n </div>\n </Show>\n <Show\n when={!props.loading && hasContent()}\n fallback={\n <Placeholder\n class=\"k2b-chat-timeline__placeholder\"\n state={props.loading ? \"loading\" : \"empty\"}\n icon={props.loading ? undefined : \"ti ti-sparkles\"}\n title={props.loading ? chatMessages().loadingConversation : (props.emptyTitle ?? chatMessages().startConversation)}\n description={!props.loading ? props.emptyDescription : undefined}\n />\n }\n >\n <For each={itemIds()}>\n {(id) => {\n // A row is keyed by its id, so an updated record with the same id keeps its DOM and component state.\n const item = () => itemsById().get(id);\n const message = () => {\n const value = item();\n return value?.kind === \"message\" ? value : undefined;\n };\n const activity = () => {\n const value = item();\n return value?.kind === \"activity\" ? value : undefined;\n };\n return (\n <Show\n when={message() !== undefined}\n fallback={\n <Show when={activity() !== undefined}>\n <ChatActivity\n label={activity()!.label}\n description={activity()!.description}\n icon={activity()!.icon}\n leading={activity()!.leading}\n accent={activity()!.accent}\n tone={activity()!.tone}\n busy={activity()!.busy}\n trailing={activity()!.trailing}\n defaultOpen={activity()!.defaultOpen}\n anchorId={activity()!.anchorId}\n class={activity()!.class}\n >\n {activity()!.content}\n </ChatActivity>\n </Show>\n }\n >\n <ChatMessage\n role={message()!.role}\n label={message()!.label}\n createdAt={message()!.createdAt}\n timeLabel={message()!.timeLabel}\n status={message()!.status}\n attachments={message()!.attachments}\n actions={message()!.actions}\n actionDisplay={message()!.actionDisplay}\n anchorId={message()!.anchorId}\n onActionError={props.onActionError}\n class={message()!.class}\n >\n {message()!.content}\n </ChatMessage>\n </Show>\n );\n }}\n </For>\n </Show>\n </div>\n </div>\n <Show when={!pinned() && hasContent()}>\n <button type=\"button\" class=\"k2b-chat-timeline__latest\" onClick={scrollToLatest}>\n <i class=\"ti ti-arrow-down\" aria-hidden=\"true\" />\n {chatMessages().jumpToLatest}\n </button>\n </Show>\n </section>\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["chat/ChatTimeline.tsx"],"sourcesContent":["import { createEffect, createMemo, createSignal, For, type JSX, onCleanup, onMount, Show, untrack } from \"solid-js\";\nimport { createScrollFade } from \"../layout/scroll-fade\";\nimport Placeholder from \"../surfaces/Placeholder\";\nimport { ChatActivity, ChatMessage } from \"./ChatPrimitives\";\nimport { isChatNearBottom, restoredChatScrollTop } from \"./chat-behavior\";\nimport { useChatMessages } from \"./chat-messages\";\nimport type { ChatAction, ChatActivityTone, ChatAttachment, ChatMessageStatus, ChatRole } from \"./types\";\n\nexport type ChatMessageItem = {\n kind: \"message\";\n /** Unique within the timeline. A record with a known id updates its row in place instead of replacing it. */\n id: string;\n role: ChatRole;\n content?: JSX.Element;\n label?: string;\n createdAt?: string | Date;\n timeLabel?: string;\n status?: ChatMessageStatus;\n attachments?: readonly ChatAttachment[];\n actions?: readonly ChatAction[];\n actionDisplay?: \"auto\" | \"inline\" | \"menu\";\n anchorId?: string | number;\n class?: string;\n};\n\nexport type ChatActivityItem = {\n kind: \"activity\";\n /** Unique within the timeline. A record with a known id updates its row in place instead of replacing it. */\n id: string;\n /** The step as text, or as a sentence with `ReferenceChip`s. */\n label: JSX.Element;\n description?: string;\n icon?: string;\n leading?: JSX.Element;\n accent?: string;\n tone?: ChatActivityTone;\n busy?: boolean;\n trailing?: JSX.Element;\n defaultOpen?: boolean;\n anchorId?: string | number;\n content?: JSX.Element;\n class?: string;\n};\n\nexport type ChatTimelineItem = ChatMessageItem | ChatActivityItem;\n\nexport type ChatTimelineProps = {\n scrollFade?: boolean;\n items: readonly ChatTimelineItem[];\n conversationKey?: string | null;\n loading?: boolean;\n hasMore?: boolean;\n loadingOlder?: boolean;\n onLoadOlder?: () => boolean | void | Promise<boolean | void>;\n emptyTitle?: string;\n emptyDescription?: string;\n navigation?: JSX.Element;\n onActionError?: (error: unknown) => void;\n viewportRef?: (element: HTMLDivElement) => void;\n contentRef?: (element: HTMLDivElement) => void;\n scrollToAnchorRef?: (scrollToAnchor: (anchorId: string | number) => boolean) => void;\n label?: string;\n followThreshold?: number;\n class?: string;\n};\n\nexport function ChatTimeline(props: ChatTimelineProps): JSX.Element {\n const chatMessages = useChatMessages();\n const [pinned, setPinned] = createSignal(true);\n const [loadingOlderInternally, setLoadingOlderInternally] = createSignal(false);\n const [historyError, setHistoryError] = createSignal<string | null>(null);\n let viewportRef: HTMLDivElement | undefined;\n createScrollFade(\n () => viewportRef,\n () => props.scrollFade !== false,\n );\n let contentRef: HTMLDivElement | undefined;\n let topSentinelRef: HTMLDivElement | undefined;\n let followFrame: number | undefined;\n let userScrollFrame: number | undefined;\n let userScrollingAway = false;\n /** Set while a row the reader toggled settles; the timeline does not follow the end meanwhile. */\n let disclosureHold = 0;\n let touchY: number | undefined;\n let lastConversationKey: string | null | undefined;\n\n const loadingOlder = () => Boolean(props.loadingOlder || loadingOlderInternally());\n const canLoadOlder = () => Boolean(props.onLoadOlder && props.hasMore && !loadingOlder());\n const hasHistoryControls = () => loadingOlder() || historyError() !== null || canLoadOlder();\n const hasContent = () => props.items.length > 0;\n const itemIds = createMemo(() => props.items.map((item) => item.id), undefined, {\n equals: (previous, next) => previous.length === next.length && previous.every((id, index) => id === next[index]),\n });\n const itemsById = createMemo(() => new Map(props.items.map((item) => [item.id, item])));\n const threshold = () => Math.max(0, props.followThreshold ?? 96);\n\n const cancelFollow = () => {\n if (followFrame !== undefined) cancelAnimationFrame(followFrame);\n followFrame = undefined;\n };\n\n props.scrollToAnchorRef?.((anchorId) => {\n const anchor = Array.from(contentRef?.querySelectorAll<HTMLElement>(\"[data-chat-anchor]\") ?? []).find(\n (element) => element.dataset.chatAnchor === String(anchorId),\n );\n if (!viewportRef || !anchor) return false;\n cancelFollow();\n setPinned(false);\n viewportRef.scrollTop = Math.max(\n 0,\n viewportRef.scrollTop + anchor.getBoundingClientRect().top - viewportRef.getBoundingClientRect().top - 16,\n );\n return true;\n });\n\n const noteUserScrollAway = () => {\n userScrollingAway = true;\n if (userScrollFrame !== undefined) cancelAnimationFrame(userScrollFrame);\n userScrollFrame = requestAnimationFrame(() => {\n userScrollFrame = undefined;\n userScrollingAway = false;\n });\n };\n\n const scrollToLatest = () => {\n if (!viewportRef) return;\n setPinned(true);\n viewportRef.scrollTop = viewportRef.scrollHeight;\n };\n\n const scheduleFollow = () => {\n if (!pinned() || disclosureHold !== 0 || followFrame !== undefined) return;\n followFrame = requestAnimationFrame(() => {\n followFrame = undefined;\n if (pinned()) scrollToLatest();\n });\n };\n\n const loadOlder = async () => {\n if (!props.onLoadOlder || !props.hasMore || loadingOlder()) return;\n const viewport = viewportRef;\n if (!viewport) return;\n const previousScrollTop = viewport.scrollTop;\n const previousScrollHeight = viewport.scrollHeight;\n setHistoryError(null);\n setLoadingOlderInternally(true);\n let prepended = false;\n try {\n prepended = (await props.onLoadOlder()) !== false;\n } catch (error) {\n setHistoryError(error instanceof Error ? error.message : chatMessages().couldNotLoadOlderMessages);\n } finally {\n setLoadingOlderInternally(false);\n }\n if (!prepended || viewportRef !== viewport) return;\n queueMicrotask(() => {\n requestAnimationFrame(() => {\n if (viewportRef !== viewport) return;\n viewport.scrollTop = restoredChatScrollTop(previousScrollTop, previousScrollHeight, viewport.scrollHeight);\n });\n });\n };\n\n // A reader who opens or closes a row reads there. The row stays where it was instead of following the newest message,\n // which would move it away from the pointer; once it has settled, the timeline keeps following only from the end.\n const holdForDisclosure = (event: MouseEvent) => {\n if (!(event.target instanceof Element) || !event.target.closest(\"summary\")) return;\n cancelFollow();\n const hold = ++disclosureHold;\n requestAnimationFrame(() =>\n requestAnimationFrame(() => {\n if (hold !== disclosureHold) return;\n disclosureHold = 0;\n if (viewportRef && !isChatNearBottom(viewportRef.scrollHeight, viewportRef.scrollTop, viewportRef.clientHeight, threshold()))\n setPinned(false);\n }),\n );\n };\n\n const updatePinned = () => {\n if (!viewportRef) return;\n const nearBottom = isChatNearBottom(viewportRef.scrollHeight, viewportRef.scrollTop, viewportRef.clientHeight, threshold());\n if (nearBottom) setPinned(true);\n else if (userScrollingAway || followFrame === undefined) {\n if (userScrollingAway) cancelFollow();\n setPinned(false);\n }\n if (viewportRef.scrollTop <= threshold()) void loadOlder();\n };\n\n onMount(() => {\n // Switch from CSS-only SSR anchoring to normal scroll coordinates before paint.\n viewportRef?.removeAttribute(\"data-initializing\");\n scrollToLatest();\n const resizeObserver = typeof ResizeObserver === \"undefined\" ? null : new ResizeObserver(() => scheduleFollow());\n if (contentRef) resizeObserver?.observe(contentRef);\n if (viewportRef) resizeObserver?.observe(viewportRef);\n\n const historyObserver =\n typeof IntersectionObserver === \"undefined\" || !topSentinelRef\n ? null\n : new IntersectionObserver(\n (entries) => {\n if (entries.some((entry) => entry.isIntersecting)) void loadOlder();\n },\n { root: viewportRef, rootMargin: \"160px 0px 0px\" },\n );\n if (topSentinelRef) historyObserver?.observe(topSentinelRef);\n // Keyboard activation of a row also arrives as a click.\n contentRef?.addEventListener(\"click\", holdForDisclosure);\n\n onCleanup(() => {\n cancelFollow();\n if (userScrollFrame !== undefined) cancelAnimationFrame(userScrollFrame);\n resizeObserver?.disconnect();\n historyObserver?.disconnect();\n contentRef?.removeEventListener(\"click\", holdForDisclosure);\n });\n });\n\n createEffect(() => {\n const key = props.conversationKey;\n if (key === lastConversationKey) return;\n lastConversationKey = key;\n setHistoryError(null);\n setPinned(true);\n queueMicrotask(scrollToLatest);\n });\n\n createEffect(() => {\n props.items.length;\n props.items.at(-1)?.id;\n untrack(scheduleFollow);\n });\n\n return (\n <section class={`k2b-chat-timeline ${props.class ?? \"\"}`} aria-label={props.label ?? chatMessages().conversation}>\n <div\n ref={(element) => {\n viewportRef = element;\n props.viewportRef?.(element);\n }}\n class=\"k2b-chat-timeline__viewport\"\n data-scroll-fade-mode={props.scrollFade !== false ? \"bottom\" : undefined}\n data-initializing=\"\"\n role=\"region\"\n aria-label={chatMessages().conversationMessages({ label: props.label ?? chatMessages().conversation })}\n tabIndex={0}\n onWheel={(event) => {\n if (event.deltaY < 0) noteUserScrollAway();\n }}\n onKeyDown={(event) => {\n if (event.target !== event.currentTarget) return;\n if (event.key === \"ArrowUp\" || event.key === \"PageUp\" || event.key === \"Home\" || (event.key === \" \" && event.shiftKey)) {\n noteUserScrollAway();\n }\n }}\n onTouchStart={(event) => {\n touchY = event.touches[0]?.clientY;\n }}\n onTouchMove={(event) => {\n const nextY = event.touches[0]?.clientY;\n if (nextY !== undefined && touchY !== undefined && nextY > touchY) noteUserScrollAway();\n touchY = nextY;\n }}\n onTouchEnd={() => {\n touchY = undefined;\n }}\n onScroll={updatePinned}\n >\n <Show when={props.navigation}>\n <div class=\"k2b-chat-timeline__navigation\" aria-live=\"off\">\n {props.navigation}\n </div>\n </Show>\n <div\n ref={(element) => {\n contentRef = element;\n props.contentRef?.(element);\n }}\n class=\"k2b-chat-timeline__content\"\n role=\"log\"\n aria-live=\"polite\"\n aria-relevant=\"additions text\"\n aria-busy={props.loading ? \"true\" : undefined}\n >\n <div ref={topSentinelRef} class=\"k2b-chat-timeline__sentinel\" aria-hidden=\"true\" />\n <Show when={hasHistoryControls()}>\n <div class=\"k2b-chat-timeline__history\" aria-live=\"off\">\n <Show when={canLoadOlder()}>\n <button type=\"button\" class=\"k2b-chat-timeline__older\" onClick={() => void loadOlder()}>\n <i class=\"ti ti-history\" aria-hidden=\"true\" />\n {chatMessages().loadOlderMessages}\n </button>\n </Show>\n <Show when={loadingOlder()}>\n <ChatActivity\n label={chatMessages().loadingOlderMessages}\n icon=\"ti ti-history\"\n trailing={<i class=\"ti ti-loader-2 k2b-spin\" aria-hidden=\"true\" />}\n />\n </Show>\n <Show when={historyError()}>\n {(message) => (\n <ChatActivity\n label={chatMessages().couldNotLoadOlderMessages}\n description={message()}\n icon=\"ti ti-alert-circle\"\n tone=\"danger\"\n trailing={\n <button\n type=\"button\"\n class=\"k2b-chat-timeline__retry\"\n aria-label={chatMessages().retryOlderMessages}\n onClick={() => void loadOlder()}\n >\n <i class=\"ti ti-refresh\" aria-hidden=\"true\" />\n </button>\n }\n />\n )}\n </Show>\n </div>\n </Show>\n <Show\n when={!props.loading && hasContent()}\n fallback={\n <Placeholder\n class=\"k2b-chat-timeline__placeholder\"\n state={props.loading ? \"loading\" : \"empty\"}\n icon={props.loading ? undefined : \"ti ti-sparkles\"}\n title={props.loading ? chatMessages().loadingConversation : (props.emptyTitle ?? chatMessages().startConversation)}\n description={!props.loading ? props.emptyDescription : undefined}\n />\n }\n >\n <For each={itemIds()}>\n {(id) => {\n // A row is keyed by its id, so an updated record with the same id keeps its DOM and component state.\n const item = () => itemsById().get(id);\n const message = () => {\n const value = item();\n return value?.kind === \"message\" ? value : undefined;\n };\n const activity = () => {\n const value = item();\n return value?.kind === \"activity\" ? value : undefined;\n };\n return (\n <Show\n when={message() !== undefined}\n fallback={\n <Show when={activity() !== undefined}>\n <ChatActivity\n label={activity()!.label}\n description={activity()!.description}\n icon={activity()!.icon}\n leading={activity()!.leading}\n accent={activity()!.accent}\n tone={activity()!.tone}\n busy={activity()!.busy}\n trailing={activity()!.trailing}\n defaultOpen={activity()!.defaultOpen}\n anchorId={activity()!.anchorId}\n class={activity()!.class}\n >\n {activity()!.content}\n </ChatActivity>\n </Show>\n }\n >\n <ChatMessage\n role={message()!.role}\n label={message()!.label}\n createdAt={message()!.createdAt}\n timeLabel={message()!.timeLabel}\n status={message()!.status}\n attachments={message()!.attachments}\n actions={message()!.actions}\n actionDisplay={message()!.actionDisplay}\n anchorId={message()!.anchorId}\n onActionError={props.onActionError}\n class={message()!.class}\n >\n {message()!.content}\n </ChatMessage>\n </Show>\n );\n }}\n </For>\n </Show>\n </div>\n </div>\n <Show when={!pinned() && hasContent()}>\n <button type=\"button\" class=\"k2b-chat-timeline__latest\" onClick={scrollToLatest}>\n <i class=\"ti ti-arrow-down\" aria-hidden=\"true\" />\n {chatMessages().jumpToLatest}\n </button>\n </Show>\n </section>\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -5,10 +5,17 @@ export const chatMessages = i18n.define({
|
|
|
5
5
|
messages: {
|
|
6
6
|
en: {
|
|
7
7
|
commandFailed: "That did not work.",
|
|
8
|
+
commandDraftChanged: "The text changed in the meantime, so nothing was inserted.",
|
|
9
|
+
markAdded: "new:",
|
|
10
|
+
markRemoved: "removed:",
|
|
11
|
+
commandOpening: "Opening …",
|
|
8
12
|
commandSelected: "selected",
|
|
9
13
|
attachments: "Attachments",
|
|
10
14
|
assistant: "Assistant",
|
|
11
15
|
addToChat: "Add to chat",
|
|
16
|
+
addMenu: "Add",
|
|
17
|
+
commandSearch: "Search",
|
|
18
|
+
commandSearchLabel: "Search entries",
|
|
12
19
|
attachFiles: "Attach files",
|
|
13
20
|
addGuidance: "Add guidance...",
|
|
14
21
|
chat: "Chat",
|
|
@@ -132,10 +139,17 @@ export const chatMessages = i18n.define({
|
|
|
132
139
|
},
|
|
133
140
|
de: {
|
|
134
141
|
commandFailed: "Das hat nicht geklappt.",
|
|
142
|
+
commandDraftChanged: "Der Text hat sich inzwischen geändert, darum wurde nichts eingefügt.",
|
|
143
|
+
markAdded: "neu:",
|
|
144
|
+
markRemoved: "weg:",
|
|
145
|
+
commandOpening: "Wird geöffnet …",
|
|
135
146
|
commandSelected: "gewählt",
|
|
136
147
|
attachments: "Anhänge",
|
|
137
148
|
assistant: "Assistent",
|
|
138
149
|
addToChat: "Zum Chat hinzufügen",
|
|
150
|
+
addMenu: "Hinzufügen",
|
|
151
|
+
commandSearch: "Suchen",
|
|
152
|
+
commandSearchLabel: "Einträge durchsuchen",
|
|
139
153
|
attachFiles: "Dateien anhängen",
|
|
140
154
|
addGuidance: "Hinweis hinzufügen...",
|
|
141
155
|
chat: "Chat",
|