@parallelworks/ui 0.51.0 → 0.53.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.
Files changed (250) hide show
  1. package/README.md +197 -17
  2. package/dist/ai/agent/toolStrings.d.ts +2 -0
  3. package/dist/ai/agent/toolStrings.js +20 -18
  4. package/dist/ai/ai.css +17 -3
  5. package/dist/ai/components/AllocationSelector.js +5 -1
  6. package/dist/ai/components/AttachmentManager.js +51 -42
  7. package/dist/ai/components/AttachmentUpload.d.ts +4 -2
  8. package/dist/ai/components/AttachmentUpload.js +9 -9
  9. package/dist/ai/components/BlockedGroupBanner.js +8 -14
  10. package/dist/ai/components/BranchNavigator.js +11 -12
  11. package/dist/ai/components/ChatEmptyState.js +12 -19
  12. package/dist/ai/components/ChatInput.d.ts +4 -3
  13. package/dist/ai/components/ChatInput.js +27 -13
  14. package/dist/ai/components/ChatMessage.js +45 -121
  15. package/dist/ai/components/ChatMessageList.d.ts +5 -2
  16. package/dist/ai/components/ChatMessageList.js +89 -51
  17. package/dist/ai/components/ChatSidebar.js +11 -7
  18. package/dist/ai/components/ChatThread.js +1 -13
  19. package/dist/ai/components/DragOverlay.js +3 -3
  20. package/dist/ai/components/MessageAttachments.d.ts +10 -0
  21. package/dist/ai/components/MessageAttachments.js +78 -0
  22. package/dist/ai/components/ModelSelector.js +3 -3
  23. package/dist/ai/components/PastedText.js +2 -2
  24. package/dist/ai/components/ProviderIssueBanner.js +19 -23
  25. package/dist/ai/components/ShareDialog.js +2 -2
  26. package/dist/ai/components/agent/ActivityLine.d.ts +0 -2
  27. package/dist/ai/components/agent/ActivityLine.js +8 -51
  28. package/dist/ai/components/agent/AgentMessageParts.js +114 -53
  29. package/dist/ai/core/ChatProvider.d.ts +16 -5
  30. package/dist/ai/core/ChatProvider.js +41 -8
  31. package/dist/ai/core/config.js +4 -3
  32. package/dist/ai/index.d.ts +1 -1
  33. package/dist/ai/index.js +3 -3
  34. package/dist/ai/strings.d.ts +29 -3
  35. package/dist/ai/strings.js +80 -26
  36. package/dist/ai/types.d.ts +4 -0
  37. package/dist/ai/ui/Notice.d.ts +2 -2
  38. package/dist/ai/ui/Notice.js +29 -62
  39. package/dist/ai/ui/sidebar.d.ts +5 -3
  40. package/dist/ai/ui/sidebar.js +22 -10
  41. package/dist/components/ActionMenu.d.ts +1 -0
  42. package/dist/components/ActionMenu.js +6 -1
  43. package/dist/components/AppLink.d.ts +26 -0
  44. package/dist/components/AppLink.js +51 -0
  45. package/dist/components/Avatar.d.ts +2 -1
  46. package/dist/components/Avatar.js +4 -2
  47. package/dist/components/Button.d.ts +15 -5
  48. package/dist/components/Button.js +47 -40
  49. package/dist/components/Callout.d.ts +31 -7
  50. package/dist/components/Callout.js +50 -19
  51. package/dist/components/Card.d.ts +11 -6
  52. package/dist/components/Card.js +14 -8
  53. package/dist/components/Checkbox.js +2 -1
  54. package/dist/components/ColorInput.js +5 -3
  55. package/dist/components/Combobox.js +49 -19
  56. package/dist/components/ConfirmModal.d.ts +19 -8
  57. package/dist/components/ConfirmModal.js +31 -53
  58. package/dist/components/CopyButton.d.ts +38 -0
  59. package/dist/components/CopyButton.js +68 -0
  60. package/dist/components/CreateModal.js +118 -111
  61. package/dist/components/DatePicker.js +12 -8
  62. package/dist/components/DescriptionList.d.ts +25 -5
  63. package/dist/components/DescriptionList.js +56 -22
  64. package/dist/components/Disclosure.js +1 -1
  65. package/dist/components/Drawer.js +10 -16
  66. package/dist/components/Field.d.ts +16 -5
  67. package/dist/components/Field.js +63 -8
  68. package/dist/components/IconButton.d.ts +14 -5
  69. package/dist/components/IconButton.js +25 -14
  70. package/dist/components/InfoTip.d.ts +12 -1
  71. package/dist/components/InfoTip.js +13 -2
  72. package/dist/components/Input.d.ts +14 -8
  73. package/dist/components/Input.js +46 -31
  74. package/dist/components/Loader.js +1 -1
  75. package/dist/components/MarkdownImpl.d.ts +1 -0
  76. package/dist/components/MarkdownImpl.js +1 -0
  77. package/dist/components/MenuEntries.d.ts +4 -0
  78. package/dist/components/MenuEntries.js +11 -12
  79. package/dist/components/Meter.js +5 -4
  80. package/dist/components/Modal.d.ts +28 -4
  81. package/dist/components/Modal.js +37 -14
  82. package/dist/components/Overview.d.ts +20 -12
  83. package/dist/components/Overview.js +14 -9
  84. package/dist/components/PageHeader.d.ts +47 -65
  85. package/dist/components/PageHeader.js +275 -153
  86. package/dist/components/PageHeaderAction.d.ts +67 -0
  87. package/dist/components/PageHeaderAction.js +107 -0
  88. package/dist/components/Pagination.js +6 -16
  89. package/dist/components/Popover.d.ts +4 -1
  90. package/dist/components/Popover.js +5 -3
  91. package/dist/components/Provider.d.ts +79 -19
  92. package/dist/components/Provider.js +140 -130
  93. package/dist/components/Radio.js +2 -1
  94. package/dist/components/RefreshButton.js +7 -8
  95. package/dist/components/RequiredMark.js +1 -1
  96. package/dist/components/Section.js +1 -1
  97. package/dist/components/Select.d.ts +4 -9
  98. package/dist/components/Select.js +24 -11
  99. package/dist/components/SettingModeOption.d.ts +1 -1
  100. package/dist/components/SettingModeOption.js +7 -1
  101. package/dist/components/SettingsCard.d.ts +5 -3
  102. package/dist/components/SettingsCard.js +27 -20
  103. package/dist/components/Slider.js +1 -1
  104. package/dist/components/StatusBadge.js +2 -2
  105. package/dist/components/Switch.js +5 -4
  106. package/dist/components/Table.d.ts +30 -20
  107. package/dist/components/Table.js +50 -73
  108. package/dist/components/Tabs.d.ts +3 -7
  109. package/dist/components/Tabs.js +6 -10
  110. package/dist/components/ThemeEditor.js +18 -8
  111. package/dist/components/Toast.d.ts +11 -3
  112. package/dist/components/Toast.js +45 -20
  113. package/dist/components/buttonClasses.js +1 -1
  114. package/dist/components/comboboxItems.d.ts +4 -0
  115. package/dist/components/comboboxItems.js +6 -1
  116. package/dist/components/dismiss.d.ts +12 -0
  117. package/dist/components/dismiss.js +19 -0
  118. package/dist/components/fieldBox.d.ts +4 -0
  119. package/dist/components/fieldBox.js +7 -3
  120. package/dist/components/floating.d.ts +3 -3
  121. package/dist/components/floating.js +1 -1
  122. package/dist/components/focus.d.ts +5 -0
  123. package/dist/components/focus.js +21 -1
  124. package/dist/components/markdownCodeBreaks.js +3 -4
  125. package/dist/components/pageHeaderStore.d.ts +41 -0
  126. package/dist/components/pageHeaderStore.js +67 -0
  127. package/dist/components/pathBreaks.d.ts +8 -0
  128. package/dist/components/pathBreaks.js +28 -0
  129. package/dist/components/segmented.js +1 -1
  130. package/dist/components/shortcutKey.d.ts +2 -1
  131. package/dist/components/shortcutKey.js +19 -2
  132. package/dist/components/splitter.js +1 -1
  133. package/dist/components/useCssIsDark.js +40 -18
  134. package/dist/components/useTheme.js +9 -10
  135. package/dist/dev.d.ts +9 -0
  136. package/dist/dev.js +14 -0
  137. package/dist/editor/Editor.d.ts +3 -2
  138. package/dist/editor/Editor.js +24 -5
  139. package/dist/editor/EditorField.d.ts +2 -1
  140. package/dist/editor/EditorField.js +11 -29
  141. package/dist/editor/FormCodePanel.d.ts +7 -3
  142. package/dist/editor/FormCodePanel.js +14 -7
  143. package/dist/editor/Monaco.d.ts +22 -6
  144. package/dist/editor/Monaco.js +177 -113
  145. package/dist/editor/editorModel.d.ts +1 -1
  146. package/dist/editor/editorModel.js +1 -1
  147. package/dist/editor/index.d.ts +6 -5
  148. package/dist/editor/index.js +5 -4
  149. package/dist/editor/languages.d.ts +24 -0
  150. package/dist/editor/languages.js +31 -0
  151. package/dist/editor/monacoFeatures.d.ts +7 -0
  152. package/dist/editor/monacoFeatures.js +19 -0
  153. package/dist/editor/themes.d.ts +8 -5
  154. package/dist/editor/themes.js +65 -32
  155. package/dist/editor/workers.d.ts +3 -3
  156. package/dist/editor/workers.js +8 -4
  157. package/dist/editor/yaml.d.ts +6 -2
  158. package/dist/editor/yaml.js +11 -2
  159. package/dist/editor/yamlLanguage.js +55 -38
  160. package/dist/file-explorer/FileExplorer.d.ts +18 -4
  161. package/dist/file-explorer/FileExplorer.js +204 -142
  162. package/dist/file-explorer/FileExplorerContext.js +1 -1
  163. package/dist/file-explorer/FilePreview/StreamedBadge.js +3 -1
  164. package/dist/file-explorer/FilePreview/Viewer.js +14 -10
  165. package/dist/file-explorer/FilePreview/index.js +4 -4
  166. package/dist/file-explorer/FileRow.d.ts +6 -2
  167. package/dist/file-explorer/FileRow.js +35 -17
  168. package/dist/file-explorer/FileRowsWindow.d.ts +2 -1
  169. package/dist/file-explorer/FileRowsWindow.js +36 -4
  170. package/dist/file-explorer/FileTable.d.ts +3 -1
  171. package/dist/file-explorer/FileTable.js +6 -3
  172. package/dist/file-explorer/TreeView.d.ts +5 -1
  173. package/dist/file-explorer/TreeView.js +86 -39
  174. package/dist/file-explorer/helpers.d.ts +2 -1
  175. package/dist/file-explorer/helpers.js +24 -23
  176. package/dist/file-explorer/lib/utils.d.ts +3 -0
  177. package/dist/file-explorer/lib/utils.js +6 -1
  178. package/dist/file-explorer/toasts.js +27 -19
  179. package/dist/file-explorer/treeRows.d.ts +6 -0
  180. package/dist/file-explorer/treeRows.js +19 -1
  181. package/dist/file-explorer/useNearEnd.js +3 -6
  182. package/dist/form/Fields/CheckboxGroupField.js +12 -5
  183. package/dist/form/Fields/DurationField.js +1 -1
  184. package/dist/form/Fields/LabelField.js +1 -1
  185. package/dist/form/Fields/ObjectField.d.ts +1 -1
  186. package/dist/form/Fields/ObjectField.js +3 -2
  187. package/dist/form/Fields/StringField.js +16 -29
  188. package/dist/form/Fields/TextAreaField.js +3 -4
  189. package/dist/form/Form.js +3 -8
  190. package/dist/form/Wizard/WizardNavigation.js +0 -3
  191. package/dist/form/Wizard/utils.js +2 -1
  192. package/dist/form/fieldFrame.d.ts +1 -1
  193. package/dist/form/fieldFrame.js +2 -2
  194. package/dist/form/types/fieldComponentTypes.d.ts +2 -1
  195. package/dist/graph/AnnotationBanner.d.ts +1 -2
  196. package/dist/graph/AnnotationBanner.js +30 -32
  197. package/dist/graph/Connectors.js +4 -1
  198. package/dist/graph/DependencyGraph.js +2 -2
  199. package/dist/graph/GraphEditor.js +11 -9
  200. package/dist/graph/GraphEditorDialogs.js +1 -1
  201. package/dist/graph/GraphNode.js +7 -4
  202. package/dist/graph/InputDialog.js +1 -1
  203. package/dist/graph/InputsEditor.js +14 -11
  204. package/dist/graph/MatrixGroup.js +9 -3
  205. package/dist/graph/Reveal.js +18 -10
  206. package/dist/graph/ShortcutsButton.d.ts +11 -2
  207. package/dist/graph/ShortcutsButton.js +14 -3
  208. package/dist/graph/TreeView.js +35 -18
  209. package/dist/graph/WorkflowSettingsDialog.js +1 -1
  210. package/dist/graph/editorFields.js +1 -1
  211. package/dist/graph/editorRows.js +16 -10
  212. package/dist/graph/editorStrings.d.ts +7 -0
  213. package/dist/graph/editorStrings.js +8 -1
  214. package/dist/graph/inputRefs.js +1 -1
  215. package/dist/graph/settingsViews.js +11 -18
  216. package/dist/graph/stepWith.js +1 -1
  217. package/dist/icons.d.ts +2 -0
  218. package/dist/icons.js +4 -2
  219. package/dist/index.d.ts +12 -12
  220. package/dist/index.js +16 -16
  221. package/dist/list/ActionToolbar.d.ts +42 -6
  222. package/dist/list/ActionToolbar.js +298 -101
  223. package/dist/list/ListPage.d.ts +15 -23
  224. package/dist/list/ListPage.js +42 -43
  225. package/dist/list/ListTable.d.ts +37 -7
  226. package/dist/list/ListTable.js +52 -12
  227. package/dist/list/ListViewControls.js +1 -1
  228. package/dist/list/UserHoverCard.js +7 -15
  229. package/dist/list/index.d.ts +2 -2
  230. package/dist/list/index.js +2 -2
  231. package/dist/list/listSearch.js +12 -10
  232. package/dist/list/listView.d.ts +10 -1
  233. package/dist/list/listView.js +15 -1
  234. package/dist/logviewer/LogViewer.d.ts +4 -2
  235. package/dist/logviewer/LogViewer.js +87 -69
  236. package/dist/logviewer/logviewer.css +3 -2
  237. package/dist/reducedMotion.d.ts +5 -0
  238. package/dist/reducedMotion.js +20 -0
  239. package/dist/safeUrl.d.ts +1 -1
  240. package/dist/safeUrl.js +4 -2
  241. package/dist/styles.css +1 -1
  242. package/package.json +5 -2
  243. package/dist/components/Breadcrumbs.d.ts +0 -37
  244. package/dist/components/Breadcrumbs.js +0 -90
  245. package/dist/components/CopyToClipboard.d.ts +0 -17
  246. package/dist/components/CopyToClipboard.js +0 -66
  247. package/dist/components/Sort.d.ts +0 -9
  248. package/dist/components/Sort.js +0 -42
  249. package/dist/file-explorer/FilePreview/CodePreviewEditor.d.ts +0 -6
  250. package/dist/file-explorer/FilePreview/CodePreviewEditor.js +0 -64
@@ -1,14 +1,14 @@
1
1
  import { cx } from "../cx.js";
2
- import { ArrowDownIcon, ArrowUpIcon, CheckIcon, ChevronDownIcon, ChevronRightIcon, ClockIcon, CloseIcon, CopyIcon, DownloadIcon, ExpandIcon, ShrinkIcon } from "../icons.js";
3
2
  import { buttonClasses } from "../components/buttonClasses.js";
3
+ import { ArrowDownIcon, ArrowUpIcon, CheckIcon, ChevronDownIcon, ChevronRightIcon, ClockIcon, CloseIcon, CopyIcon, DownloadIcon, ExpandIcon, ShrinkIcon } from "../icons.js";
4
4
  import { Loader } from "../components/Loader.js";
5
5
  import { useOptionalWorkflowEngine, useStrings } from "../components/Provider.js";
6
6
  import { useCopy } from "../components/useCopy.js";
7
7
  import { Button } from "../components/Button.js";
8
- import { DatePicker } from "../components/DatePicker.js";
9
8
  import { IconButton } from "../components/IconButton.js";
10
9
  import { Popover } from "../components/Popover.js";
11
10
  import { InfoTip } from "../components/InfoTip.js";
11
+ import { DatePicker } from "../components/DatePicker.js";
12
12
  import { SearchInput } from "../components/SearchInput.js";
13
13
  import { highlightSegments, parseAnsiSegments, plainSegments } from "./segments.js";
14
14
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -26,55 +26,51 @@ function LogSegments({ segments }) {
26
26
  children: segment.content
27
27
  }, i) : /* @__PURE__ */ jsx(Fragment$1, { children: segment.content }, i));
28
28
  }
29
- var LogLine = memo(function LogLine({ index, segments, lineNumbers, isSelected, lineHeight, onLineClick, searchTerm, command, groupDepth = 0, isGroupCollapsed, onGroupToggle, annotationLabels }) {
29
+ var ANNOTATION_TONES = {
30
+ error: {
31
+ label: "text-(--theme-error-text)",
32
+ row: "bg-(--theme-error-muted)",
33
+ edge: "border-l-2 border-l-(color:--theme-error)"
34
+ },
35
+ warning: {
36
+ label: "text-(--theme-warning-text)",
37
+ row: "bg-(--theme-warning-muted)",
38
+ edge: "border-l-2 border-l-(color:--theme-warning)"
39
+ },
40
+ notice: {
41
+ label: "text-(--theme-info-text)",
42
+ row: "bg-(--theme-info-muted)",
43
+ edge: "border-l-2 border-l-(color:--theme-info)"
44
+ }
45
+ };
46
+ var LogLine = memo(function LogLine({ index, segments, lineNumbers, isSelected, lineHeight, onLineClick, searchTerm, command, groupDepth = 0, isGroupCollapsed, onGroupToggle, annotationLabels, selectLineLabel }) {
47
+ const annotation = command?.type ? ANNOTATION_TONES[command.type] : void 0;
30
48
  const displaySegments = useMemo(() => highlightSegments(command?.message ? plainSegments(command.message) : segments, searchTerm), [
31
49
  segments,
32
50
  searchTerm,
33
51
  command
34
52
  ]);
35
- const annotationLabel = useMemo(() => {
36
- if (command?.type === "error") return /* @__PURE__ */ jsx("span", {
37
- className: "text-red-500 font-semibold mr-1",
38
- children: annotationLabels.error
39
- });
40
- if (command?.type === "warning") return /* @__PURE__ */ jsx("span", {
41
- className: "text-yellow-500 font-semibold mr-1",
42
- children: annotationLabels.warning
43
- });
44
- if (command?.type === "notice") return /* @__PURE__ */ jsx("span", {
45
- className: "text-blue-500 font-semibold mr-1",
46
- children: annotationLabels.notice
47
- });
48
- return null;
49
- }, [command?.type, annotationLabels]);
53
+ const annotationLabel = annotation && command && /* @__PURE__ */ jsx("span", {
54
+ className: cx("mr-1 font-semibold", annotation.label),
55
+ children: annotationLabels[command.type]
56
+ });
50
57
  const groupToggle = command?.type === "group" && onGroupToggle ? () => {
51
58
  if (window.getSelection()?.isCollapsed === false) return;
52
59
  onGroupToggle(index);
53
60
  } : null;
54
- const groupToggleProps = groupToggle ? {
55
- role: "button",
56
- tabIndex: 0,
57
- "aria-expanded": !isGroupCollapsed,
58
- onClick: groupToggle,
59
- onKeyDown: (e) => {
60
- if (e.target !== e.currentTarget) return;
61
- if (e.key === "Enter" || e.key === " ") {
62
- e.preventDefault();
63
- groupToggle();
64
- }
65
- }
66
- } : void 0;
61
+ const titleId = useId();
67
62
  return /* @__PURE__ */ jsxs("div", {
68
63
  "data-line-number": index + 1,
69
- ...groupToggleProps,
70
- className: cx("flex items-start text-sm font-mono group", isSelected ? "bg-(--theme-link)/15" : "hover:bg-(--theme-hover)", "text-(--theme-app)", command?.type === "error" && "bg-red-500/10", command?.type === "warning" && "bg-yellow-500/10", command?.type === "notice" && "bg-blue-500/10", command?.type === "debug" && "opacity-60", command?.type === "group" && "bg-(--theme-hover) cursor-pointer"),
64
+ onClick: groupToggle ?? void 0,
65
+ className: cx("flex items-start text-sm font-mono group", isSelected ? "bg-(--theme-link)/15" : "hover:bg-(--theme-hover)", "text-(--theme-app)", !isSelected && annotation?.row, command?.type === "debug" && "opacity-60", command?.type === "group" && "bg-(--theme-hover) cursor-pointer"),
71
66
  style: {
72
67
  minHeight: `${lineHeight}px`,
73
- lineHeight: `${lineHeight}px`,
74
- paddingLeft: groupDepth > 0 ? `${groupDepth * 16}px` : void 0
68
+ lineHeight: `${lineHeight}px`
75
69
  },
76
70
  children: [lineNumbers && /* @__PURE__ */ jsx("button", {
77
71
  type: "button",
72
+ "aria-label": selectLineLabel(index + 1),
73
+ "aria-pressed": isSelected,
78
74
  onClick: (e) => {
79
75
  e.stopPropagation();
80
76
  onLineClick(index + 1, e);
@@ -82,14 +78,28 @@ var LogLine = memo(function LogLine({ index, segments, lineNumbers, isSelected,
82
78
  className: cx("inline-flex items-center justify-end w-14 pr-3 shrink-0 cursor-pointer select-none", "hover:underline hover:text-(--theme-link) transition-colors", "text-(--theme-muted-text-color)", isSelected && "text-(--theme-link)"),
83
79
  children: index + 1
84
80
  }), /* @__PURE__ */ jsxs("pre", {
85
- className: cx("grow text-left whitespace-pre m-0 py-0.5 pr-2 flex items-center", lineNumbers && "pl-2 border-l border-(--theme-border)", command?.type === "error" && "border-l-red-500 border-l-2", command?.type === "warning" && "border-l-yellow-500 border-l-2", command?.type === "notice" && "border-l-blue-500 border-l-2", command?.type === "group" && "font-bold"),
81
+ className: cx("grow text-left whitespace-pre m-0 py-0.5 pr-2 flex items-center", lineNumbers && "pl-2 border-l border-l-(color:--theme-border)", annotation?.edge, command?.type === "group" && "font-bold"),
82
+ style: groupDepth > 0 ? { paddingInlineStart: `calc(${lineNumbers ? "0.5rem + " : ""}${groupDepth * 16}px)` } : void 0,
86
83
  children: [
87
- command?.type === "group" && /* @__PURE__ */ jsx("span", {
84
+ command?.type === "group" && (onGroupToggle ? /* @__PURE__ */ jsx("button", {
85
+ type: "button",
86
+ "aria-expanded": !isGroupCollapsed,
87
+ "aria-labelledby": titleId,
88
+ onClick: (e) => {
89
+ e.stopPropagation();
90
+ onGroupToggle(index);
91
+ },
92
+ className: "mr-1 inline-flex shrink-0 cursor-pointer items-center rounded focus-visible:outline-2 focus-visible:outline-(--theme-focus)",
93
+ children: isGroupCollapsed ? /* @__PURE__ */ jsx(ChevronRightIcon, { className: "w-3 h-3 rtl:rotate-180" }) : /* @__PURE__ */ jsx(ChevronDownIcon, { className: "w-3 h-3" })
94
+ }) : /* @__PURE__ */ jsx("span", {
88
95
  className: "mr-1 shrink-0 inline-flex items-center",
89
- children: isGroupCollapsed ? /* @__PURE__ */ jsx(ChevronRightIcon, { className: "w-3 h-3" }) : /* @__PURE__ */ jsx(ChevronDownIcon, { className: "w-3 h-3" })
90
- }),
96
+ children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "w-3 h-3" })
97
+ })),
91
98
  annotationLabel,
92
- /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(LogSegments, { segments: displaySegments }) })
99
+ /* @__PURE__ */ jsx("span", {
100
+ id: titleId,
101
+ children: /* @__PURE__ */ jsx(LogSegments, { segments: displaySegments })
102
+ })
93
103
  ]
94
104
  })]
95
105
  });
@@ -127,7 +137,7 @@ var TopPaginationBanner = memo(function TopPaginationBanner({ endOfLog, loadingT
127
137
  children: t.loadOlderEntries
128
138
  });
129
139
  });
130
- function LogViewer({ log, height = "unset", width, roundedBottom = false, lineNumbers = true, additionalLeftBarComponents = null, additionalRightBarComponents = null, additionalBottomLeftBarComponents = null, additionalBottomRightBarComponents = null, hideExpand = false, inline = false, contentClassName, enableWorkflowCommands: workflowCommandsRequested = false, onReachTop, loadingTop = false, endOfLog = false, prependedSignal = 0, enableTimeRangeFilter = false, onTimeRangeChange, initialTimeRangeFrom = "", initialTimeRangeTo = "" }) {
140
+ function LogViewer({ log, height = "unset", width, downloadName = "log.txt", roundedBottom = false, lineNumbers = true, additionalLeftBarComponents = null, additionalRightBarComponents = null, additionalBottomLeftBarComponents = null, additionalBottomRightBarComponents = null, hideExpand = false, inline = false, contentClassName, enableWorkflowCommands: workflowCommandsRequested = false, onReachTop, loadingTop = false, endOfLog = false, prependedSignal = 0, enableTimeRangeFilter = false, onTimeRangeChange, initialTimeRangeFrom = "", initialTimeRangeTo = "" }) {
131
141
  const engine = useOptionalWorkflowEngine(workflowCommandsRequested);
132
142
  const enableWorkflowCommands = workflowCommandsRequested && engine !== void 0;
133
143
  const { common, logviewer: t } = useStrings();
@@ -143,7 +153,6 @@ function LogViewer({ log, height = "unset", width, roundedBottom = false, lineNu
143
153
  followRef.current = value;
144
154
  _setFollow(value);
145
155
  }, []);
146
- const [logUrl, setLogUrl] = useState("");
147
156
  const [fullParsedLog, setFullParsedLog] = useState([]);
148
157
  const [processedLines, setProcessedLines] = useState([]);
149
158
  const [rawLines, setRawLines] = useState([]);
@@ -329,10 +338,6 @@ function LogViewer({ log, height = "unset", width, roundedBottom = false, lineNu
329
338
  setFullParsedLog(processed);
330
339
  if (enableWorkflowCommands && engine) setProcessedLines(engine.processLogLines(processed, cleanedLines));
331
340
  if (followRef.current && isAppending) requestAnimationFrame(scrollToEnd);
332
- const file = new Blob([log], { type: "text/plaintext" });
333
- const url = URL.createObjectURL(file);
334
- setLogUrl(url);
335
- return () => URL.revokeObjectURL(url);
336
341
  }, [
337
342
  log,
338
343
  scrollToEnd,
@@ -363,6 +368,22 @@ function LogViewer({ log, height = "unset", width, roundedBottom = false, lineNu
363
368
  useLayoutEffect(() => {
364
369
  if (logContainerRef.current) prevScrollHeightRef.current = logContainerRef.current.scrollHeight;
365
370
  });
371
+ const downloadLog = () => {
372
+ const url = URL.createObjectURL(new Blob([log], { type: "text/plain" }));
373
+ const a = document.createElement("a");
374
+ a.href = url;
375
+ a.download = downloadName;
376
+ a.click();
377
+ setTimeout(() => URL.revokeObjectURL(url));
378
+ };
379
+ useEffect(() => {
380
+ if (!fullscreen) return;
381
+ const onKey = (e) => {
382
+ if (e.key === "Escape" && !e.defaultPrevented) setFullscreen(false);
383
+ };
384
+ window.addEventListener("keydown", onKey);
385
+ return () => window.removeEventListener("keydown", onKey);
386
+ }, [fullscreen]);
366
387
  const handleFilterChange = (newFilter) => {
367
388
  setFilter(newFilter);
368
389
  updateFollow(false);
@@ -421,27 +442,24 @@ function LogViewer({ log, height = "unset", width, roundedBottom = false, lineNu
421
442
  children: follow ? t.following : t.follow
422
443
  })] }),
423
444
  selectedLines.size > 0 ? /* @__PURE__ */ jsxs("div", {
424
- className: "relative flex items-center h-full",
445
+ className: "flex items-center gap-1",
425
446
  children: [/* @__PURE__ */ jsx(Button, {
426
447
  variant: "secondary",
427
448
  size: "sm",
428
- icon: copied ? /* @__PURE__ */ jsx(CheckIcon, { className: "text-green-500" }) : /* @__PURE__ */ jsx(CopyIcon, {}),
449
+ icon: copied ? /* @__PURE__ */ jsx(CheckIcon, { className: "text-(--theme-success)" }) : /* @__PURE__ */ jsx(CopyIcon, {}),
429
450
  onClick: copySelectedLines,
430
451
  children: copied ? common.copied : t.copyLines(selectedLines.size)
431
- }), /* @__PURE__ */ jsx("span", {
432
- className: "absolute -top-2 -right-2 z-10 rounded-md shadow-sm",
433
- children: /* @__PURE__ */ jsx(IconButton, {
434
- variant: "secondary",
435
- size: "xs",
436
- label: t.clearSelection,
437
- icon: /* @__PURE__ */ jsx(CloseIcon, {}),
438
- onClick: () => setSelectedLines(/* @__PURE__ */ new Set())
439
- })
452
+ }), /* @__PURE__ */ jsx(IconButton, {
453
+ variant: "ghost",
454
+ size: "sm",
455
+ label: t.clearSelection,
456
+ icon: /* @__PURE__ */ jsx(CloseIcon, {}),
457
+ onClick: () => setSelectedLines(/* @__PURE__ */ new Set())
440
458
  })]
441
459
  }) : /* @__PURE__ */ jsx(Button, {
442
460
  variant: "secondary",
443
461
  size: "sm",
444
- icon: copied ? /* @__PURE__ */ jsx(CheckIcon, { className: "text-green-500" }) : /* @__PURE__ */ jsx(CopyIcon, {}),
462
+ icon: copied ? /* @__PURE__ */ jsx(CheckIcon, { className: "text-(--theme-success)" }) : /* @__PURE__ */ jsx(CopyIcon, {}),
445
463
  onClick: copyAllLogs,
446
464
  children: copied ? common.copied : t.copyAll
447
465
  }),
@@ -510,7 +528,8 @@ function LogViewer({ log, height = "unset", width, roundedBottom = false, lineNu
510
528
  })]
511
529
  }),
512
530
  timeRangeError !== "" && /* @__PURE__ */ jsx("span", {
513
- className: "text-[11px] text-red-500",
531
+ role: "alert",
532
+ className: "text-[11px] text-(--theme-error-text)",
514
533
  children: t[timeRangeError]
515
534
  }),
516
535
  /* @__PURE__ */ jsxs("div", {
@@ -548,15 +567,13 @@ function LogViewer({ log, height = "unset", width, roundedBottom = false, lineNu
548
567
  onValueChange: handleFilterChange,
549
568
  className: "w-48"
550
569
  }),
551
- /* @__PURE__ */ jsxs("a", {
552
- href: logUrl || void 0,
553
- "aria-disabled": !logUrl || void 0,
554
- className: buttonClasses({
555
- variant: "secondary",
556
- size: "sm"
557
- }),
558
- download: true,
559
- children: [/* @__PURE__ */ jsx(DownloadIcon, {}), common.download]
570
+ /* @__PURE__ */ jsx(Button, {
571
+ variant: "secondary",
572
+ size: "sm",
573
+ icon: /* @__PURE__ */ jsx(DownloadIcon, {}),
574
+ disabled: !log,
575
+ onClick: downloadLog,
576
+ children: common.download
560
577
  }),
561
578
  !hideExpand && /* @__PURE__ */ jsx(Button, {
562
579
  variant: "secondary",
@@ -606,7 +623,8 @@ function LogViewer({ log, height = "unset", width, roundedBottom = false, lineNu
606
623
  groupDepth: enableWorkflowCommands ? item.groupDepth : 0,
607
624
  isGroupCollapsed: enableWorkflowCommands && item.command?.type === "group" ? collapsedGroups.has(item.index) : void 0,
608
625
  onGroupToggle: enableWorkflowCommands ? handleGroupToggle : void 0,
609
- annotationLabels
626
+ annotationLabels,
627
+ selectLineLabel: t.selectLine
610
628
  })
611
629
  }, item.index))
612
630
  })
@@ -1,6 +1,7 @@
1
- /* Log viewer search highlighting */
1
+ /* A match the filter found: the theme's warning shade, the usual find-in-page
2
+ * yellow, mixed toward the surface so the text keeps its own color. */
2
3
  mark.search-highlight {
3
- background-color: rgba(251, 191, 36, 0.4);
4
+ background-color: color-mix(in oklab, var(--theme-warning) 35%, transparent);
4
5
  color: inherit;
5
6
  padding: 0 2px;
6
7
  border-radius: 2px;
@@ -0,0 +1,5 @@
1
+ /** Whether the person asked for less motion, read once where it is needed, such as before a scroll. */
2
+ export declare function prefersReducedMotion(): boolean;
3
+ /** Whether the person asked for less motion, following the setting as it changes. For motion a
4
+ * `motion-reduce:` class can't reach, such as a transition a component waits on. */
5
+ export declare function useReducedMotion(): boolean;
@@ -0,0 +1,20 @@
1
+ import { useSyncExternalStore } from "react";
2
+ //#region src/reducedMotion.ts
3
+ var QUERY = "(prefers-reduced-motion: reduce)";
4
+ /** Whether the person asked for less motion, read once where it is needed, such as before a scroll. */
5
+ function prefersReducedMotion() {
6
+ return typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia(QUERY).matches : false;
7
+ }
8
+ function subscribe(onChange) {
9
+ if (typeof window === "undefined" || typeof window.matchMedia !== "function") return () => {};
10
+ const media = window.matchMedia(QUERY);
11
+ media.addEventListener("change", onChange);
12
+ return () => media.removeEventListener("change", onChange);
13
+ }
14
+ /** Whether the person asked for less motion, following the setting as it changes. For motion a
15
+ * `motion-reduce:` class can't reach, such as a transition a component waits on. */
16
+ function useReducedMotion() {
17
+ return useSyncExternalStore(subscribe, prefersReducedMotion, () => false);
18
+ }
19
+ //#endregion
20
+ export { prefersReducedMotion, useReducedMotion };
package/dist/safeUrl.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Returns url when following it cannot run script in the app's origin: a
3
- * relative path or an http, https or blob URL. Hosts and servers supply these
3
+ * relative path, an http, https or blob URL, or a mailto: or tel: link. Hosts and servers supply these
4
4
  * URLs, so a javascript: URL from either would otherwise run when clicked.
5
5
  */
6
6
  export declare function safeUrl(url: string | null | undefined): string | undefined;
package/dist/safeUrl.js CHANGED
@@ -2,11 +2,13 @@
2
2
  var SAFE_PROTOCOLS = /* @__PURE__ */ new Set([
3
3
  "http:",
4
4
  "https:",
5
- "blob:"
5
+ "blob:",
6
+ "mailto:",
7
+ "tel:"
6
8
  ]);
7
9
  /**
8
10
  * Returns url when following it cannot run script in the app's origin: a
9
- * relative path or an http, https or blob URL. Hosts and servers supply these
11
+ * relative path, an http, https or blob URL, or a mailto: or tel: link. Hosts and servers supply these
10
12
  * URLs, so a javascript: URL from either would otherwise run when clicked.
11
13
  */
12
14
  function safeUrl(url) {