@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,15 +1,14 @@
1
- import { defaultToolStrings } from "./agent/toolStrings.js";
1
+ import { countOf, defaultToolStrings } from "./agent/toolStrings.js";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
- //#region src/ai/strings.tsx
4
3
  var defaultChatStrings = {
5
4
  shareConversation: {
6
- title: "Share Conversation",
5
+ title: "Share conversation",
7
6
  loadError: "Failed to load sharing settings",
8
7
  saveSuccess: "Sharing settings saved",
9
- orgAccess: "Organization Access",
8
+ orgAccess: "Organization access",
10
9
  orgCanView: "Anyone in the organization can view",
11
10
  allowCollaboration: "Allow collaboration (edit messages)",
12
- groupAccess: "Group Access",
11
+ groupAccess: "Group access",
13
12
  noGroups: "No groups have access yet",
14
13
  viewOnly: "View only",
15
14
  canCollaborate: "Can collaborate",
@@ -24,7 +23,7 @@ var defaultChatStrings = {
24
23
  shareButton: "Share conversation"
25
24
  },
26
25
  blockedGroup: {
27
- title: "Billing group \"{group}\" is over its allocation",
26
+ title: (group) => `Billing group \u201c${group}\u201d is over its allocation`,
28
27
  message: "It has reached its allocation limit. Messages to this provider are paused until your administrator increases the allocation."
29
28
  },
30
29
  queue: {
@@ -61,7 +60,48 @@ var defaultChatStrings = {
61
60
  },
62
61
  activity: {
63
62
  tokens: (input, output) => `↑${input} ↓${output} tokens`,
64
- stop: "Stop"
63
+ stop: "Stop",
64
+ words: [
65
+ "Thinking",
66
+ "Cogitating",
67
+ "Pondering",
68
+ "Percolating",
69
+ "Ruminating",
70
+ "Noodling",
71
+ "Conjuring",
72
+ "Simmering",
73
+ "Marinating",
74
+ "Tinkering",
75
+ "Scheming",
76
+ "Brewing",
77
+ "Wrangling",
78
+ "Finagling",
79
+ "Spelunking",
80
+ "Puttering",
81
+ "Composing",
82
+ "Synthesizing",
83
+ "Deliberating",
84
+ "Mulling",
85
+ "Contemplating",
86
+ "Vibing",
87
+ "Whittling",
88
+ "Concocting",
89
+ "Formulating",
90
+ "Hatching",
91
+ "Herding",
92
+ "Ideating",
93
+ "Manifesting",
94
+ "Moseying",
95
+ "Musing",
96
+ "Reticulating",
97
+ "Schlepping",
98
+ "Stewing",
99
+ "Transmuting",
100
+ "Wibbling",
101
+ "Crunching",
102
+ "Forging",
103
+ "Cooking"
104
+ ]
65
105
  },
66
106
  emptyState: {
67
107
  greeting: null,
@@ -78,33 +118,36 @@ var defaultChatStrings = {
78
118
  },
79
119
  input: {
80
120
  placeholder: "Ask anything",
81
- placeholderLoading: "Loading models...",
121
+ placeholderLoading: "Loading models…",
82
122
  placeholderNoProviders: "Add an AI provider to start chatting",
83
123
  attachFiles: "Attach files",
84
124
  stopGenerating: "Stop generating (Escape)",
85
125
  sendMessage: "Send message (Enter)",
86
- filesAttached: (count) => count === 1 ? "1 file attached" : `${count.toLocaleString()} files attached`
126
+ filesAttached: (count) => `${countOf(count, "file", "files")} attached`
87
127
  },
88
128
  paste: {
89
129
  title: "Pasted text",
90
- lines: (count) => count === 1 ? "1 line" : `${count.toLocaleString()} lines`,
130
+ lines: (count) => countOf(count, "line", "lines"),
91
131
  saving: "Saving…",
92
132
  remove: "Remove paste"
93
133
  },
94
134
  thinking: {
95
135
  label: "Thinking",
96
- ellipsis: "Thinking...",
136
+ ellipsis: "Thinking…",
97
137
  thoughtFor: (duration) => `Thought for ${duration}`,
98
138
  thoughtProcess: "Thought process",
99
139
  activity: "Activity",
100
- ranToolCalls: (count) => count === 1 ? "Ran 1 tool call" : `Ran ${count.toLocaleString()} tool calls`
140
+ ranToolCalls: (count) => `Ran ${countOf(count, "tool call", "tool calls")}`
141
+ },
142
+ thread: {
143
+ viewOnly: "You have view only access",
144
+ label: "Conversation"
101
145
  },
102
- thread: { viewOnly: "You have view only access" },
103
146
  sidebar: {
104
147
  groupToday: "Today",
105
148
  groupYesterday: "Yesterday",
106
- groupThisWeek: "This Week",
107
- groupThisMonth: "This Month",
149
+ groupThisWeek: "This week",
150
+ groupThisMonth: "This month",
108
151
  groupOlder: "Older",
109
152
  untitled: "Untitled",
110
153
  sharedWithYou: "Shared with you",
@@ -115,18 +158,18 @@ var defaultChatStrings = {
115
158
  resizeHint: "Drag to resize; double-click to reset",
116
159
  newChat: "New chat",
117
160
  attachments: "Attachments",
118
- connectTools: "Connect Tools",
119
- manageProviders: "Manage Providers",
161
+ connectTools: "Connect tools",
162
+ manageProviders: "Manage providers",
120
163
  noConversations: "No conversations yet",
121
- deleteTitle: "Delete Conversation",
164
+ deleteTitle: "Delete conversation",
122
165
  deleteBody: "Are you sure you want to delete this conversation? This action cannot be undone.",
123
- renameTitle: "Rename Conversation",
166
+ renameTitle: "Rename conversation",
124
167
  renameLabel: "Conversation title",
125
168
  renamePlaceholder: "Enter a new title"
126
169
  },
127
170
  attachmentUpload: {
128
171
  fileTooLarge: (maxSize) => `File too large. Maximum size is ${maxSize}`,
129
- maxFilesAllowed: (max) => `Maximum ${max} files allowed`,
172
+ maxFilesAllowed: (max) => `Maximum ${countOf(max, "file", "files")} allowed`,
130
173
  dropFilesHere: "Drop files here",
131
174
  releaseToUpload: "Release to upload",
132
175
  addFiles: "Add files (drag or click)",
@@ -135,7 +178,12 @@ var defaultChatStrings = {
135
178
  },
136
179
  attachmentManager: {
137
180
  title: "Attachments",
138
- empty: "No attachments yet"
181
+ empty: "No attachments yet",
182
+ unnamedImage: "Image attachment",
183
+ unnamedFile: "File",
184
+ open: (name) => `Open ${name}`,
185
+ download: (name) => `Download ${name}`,
186
+ remove: (name) => `Delete ${name}`
139
187
  },
140
188
  branch: {
141
189
  previous: "Previous branch",
@@ -151,12 +199,12 @@ var defaultChatStrings = {
151
199
  },
152
200
  messageMeta: {
153
201
  stopped: "Stopped",
154
- tokens: (total) => `${total.toLocaleString()} tokens`,
202
+ tokens: (total) => countOf(total, "token", "tokens"),
155
203
  tokensBreakdown: (prompt, completion) => `${prompt.toLocaleString()} in · ${completion.toLocaleString()} out`,
156
- copy: "Copy message",
204
+ copyLabel: "message",
157
205
  edit: "Edit message",
158
206
  regenerate: "Regenerate response",
159
- editPlaceholder: "Edit your message..."
207
+ editPlaceholder: "Edit your message…"
160
208
  },
161
209
  permissions: {
162
210
  choose: "Choose what the agent may do",
@@ -178,7 +226,7 @@ var defaultChatStrings = {
178
226
  interrupted: "Interrupted",
179
227
  noOutput: "(no output)",
180
228
  diffTruncated: "Diff truncated",
181
- moreLines: "+{count} more lines",
229
+ moreLines: (count) => `+${countOf(count, "more line", "more lines")}`,
182
230
  allowOnce: "Yes, allow this command",
183
231
  allowDirectory: "Yes, and allow this directory for the session",
184
232
  deny: "No, deny this command",
@@ -196,7 +244,13 @@ var defaultChatStrings = {
196
244
  tasks: "Tasks",
197
245
  planPending: "Plan awaiting approval in the terminal",
198
246
  approvalPending: "Waiting for an answer in the terminal",
199
- approvalOptions: "Offered choices"
247
+ approvalOptions: "Offered choices",
248
+ approvalLabel: "Waiting for your answer",
249
+ feedbackLabel: "Feedback for the agent",
250
+ ownAnswerLabel: "Your answer",
251
+ todoPending: "To do",
252
+ todoInProgress: "In progress",
253
+ todoCompleted: "Done"
200
254
  },
201
255
  tools: defaultToolStrings
202
256
  };
@@ -243,6 +243,10 @@ export interface ShareGroup {
243
243
  export type ChatLinkTarget = {
244
244
  kind: 'conversation';
245
245
  id: string;
246
+ }
247
+ /** Where `ChatNavigation.toNewChat` goes, for the sidebar's new chat link. */
248
+ | {
249
+ kind: 'newChat';
246
250
  } | {
247
251
  kind: 'attachments';
248
252
  } | {
@@ -20,10 +20,10 @@ export declare function OutputCard({ title, text, onDismiss, dismissLabel, testI
20
20
  }): import("react").JSX.Element;
21
21
  /** An inline notice next to the composer. One with no dismiss states a fact
22
22
  * that is still true; one with a dismiss is a message the reader can put away. */
23
- export declare function NoticeCard({ tone, children, onDismiss, dismissLabel, testId, }: {
23
+ export declare function NoticeCard({ tone, children, onDismiss, testId, }: {
24
24
  tone?: NoticeTone;
25
25
  children: ReactNode;
26
+ /** Adds a close button, named by the provider's `dismiss` string. */
26
27
  onDismiss?: () => void;
27
- dismissLabel?: string;
28
28
  testId?: string;
29
29
  }): import("react").JSX.Element;
@@ -1,57 +1,31 @@
1
1
  import { cx } from "../../cx.js";
2
- import { CloseIcon, ErrorIcon, InfoIcon } from "../../icons.js";
2
+ import { CloseIcon } from "../../icons.js";
3
+ import { Button } from "../../components/Button.js";
4
+ import { Callout } from "../../components/Callout.js";
3
5
  import { jsx, jsxs } from "react/jsx-runtime";
4
6
  //#region src/ai/ui/Notice.tsx
5
- var barTone = {
6
- neutral: "theme-border theme-muted-panel",
7
- info: "border-blue-500/30 bg-blue-500/10",
8
- warning: "border-amber-500/40 bg-amber-500/10",
9
- danger: "border-red-500/30 bg-red-500/10"
10
- };
11
- var iconTone = {
12
- neutral: "theme-muted-text",
13
- info: "text-blue-600 dark:text-blue-400",
14
- warning: "text-amber-600 dark:text-amber-400",
15
- danger: "text-red-600 dark:text-red-400"
16
- };
17
- var titleTone = {
18
- neutral: "theme-text",
19
- info: "text-blue-700 dark:text-blue-300",
20
- warning: "text-amber-700 dark:text-amber-300",
21
- danger: "text-red-700 dark:text-red-300"
22
- };
23
- var cardTone = {
24
- neutral: "theme-border theme-muted-panel theme-muted-text",
25
- info: "border-blue-500/40 bg-blue-500/10 text-blue-800 dark:text-blue-200",
26
- warning: "border-amber-500/40 bg-amber-500/10 text-amber-800 dark:text-amber-200",
27
- danger: "border-red-500/40 bg-red-500/10 text-red-700 dark:text-red-300"
7
+ var calloutTone = {
8
+ neutral: "default",
9
+ info: "info",
10
+ warning: "warning",
11
+ danger: "error"
28
12
  };
29
13
  /** A standing condition on the surface: a full-width bar under the header
30
14
  * with a title, an explanation, and the one thing the reader can do about it. */
31
15
  function NoticeBar({ tone, title, children, action, onAction, testId }) {
32
- const Icon = tone === "danger" || tone === "warning" ? ErrorIcon : InfoIcon;
33
- return /* @__PURE__ */ jsxs("div", {
34
- "data-testid": testId,
35
- className: cx("flex shrink-0 items-start gap-3 border-b px-6 py-3", barTone[tone]),
36
- children: [
37
- /* @__PURE__ */ jsx(Icon, { className: cx("mt-0.5 h-4 w-4 shrink-0", iconTone[tone]) }),
38
- /* @__PURE__ */ jsxs("div", {
39
- className: "min-w-0 flex-1",
40
- children: [/* @__PURE__ */ jsx("p", {
41
- className: cx("text-sm font-medium", titleTone[tone]),
42
- children: title
43
- }), children && /* @__PURE__ */ jsx("p", {
44
- className: "mt-0.5 text-xs theme-muted-text",
45
- children
46
- })]
47
- }),
48
- action && onAction && /* @__PURE__ */ jsx("button", {
49
- type: "button",
50
- onClick: onAction,
51
- className: "shrink-0 rounded-lg border theme-border bg-(--theme-panel-bg) px-3 py-1.5 text-xs theme-text hover:theme-hover",
52
- children: action
53
- })
54
- ]
16
+ return /* @__PURE__ */ jsx(Callout, {
17
+ tone: calloutTone[tone],
18
+ variant: "bar",
19
+ title,
20
+ testId,
21
+ className: "shrink-0 px-6",
22
+ ...action && onAction ? { action: /* @__PURE__ */ jsx(Button, {
23
+ size: "sm",
24
+ variant: "outline",
25
+ onClick: onAction,
26
+ children: action
27
+ }) } : {},
28
+ children
55
29
  });
56
30
  }
57
31
  /** What a command printed, kept verbatim under the command that printed it. */
@@ -82,21 +56,14 @@ function OutputCard({ title, text, onDismiss, dismissLabel, testId }) {
82
56
  }
83
57
  /** An inline notice next to the composer. One with no dismiss states a fact
84
58
  * that is still true; one with a dismiss is a message the reader can put away. */
85
- function NoticeCard({ tone = "neutral", children, onDismiss, dismissLabel, testId }) {
86
- return /* @__PURE__ */ jsxs("div", {
87
- "data-testid": testId,
88
- className: cx("flex items-start gap-2 rounded-lg border px-3 py-2 text-xs", cardTone[tone]),
89
- children: [/* @__PURE__ */ jsx("span", {
90
- className: "flex-1",
91
- children
92
- }), onDismiss && /* @__PURE__ */ jsx("button", {
93
- type: "button",
94
- onClick: onDismiss,
95
- "aria-label": dismissLabel,
96
- title: dismissLabel,
97
- className: "shrink-0 rounded p-0.5 hover:theme-hover",
98
- children: /* @__PURE__ */ jsx(CloseIcon, { className: "h-3 w-3" })
99
- })]
59
+ function NoticeCard({ tone = "neutral", children, onDismiss, testId }) {
60
+ return /* @__PURE__ */ jsx(Callout, {
61
+ tone: calloutTone[tone],
62
+ size: "sm",
63
+ icon: false,
64
+ onDismiss,
65
+ testId,
66
+ children
100
67
  });
101
68
  }
102
69
  //#endregion
@@ -44,12 +44,14 @@ export declare function SidebarRow({ selected, menuItems, openMenu, className, c
44
44
  children: ReactNode;
45
45
  }): import("react").JSX.Element;
46
46
  /** One entry in the collapsed rail: a square the size of the toggle, with the
47
- * same highlight as a row, holding whatever stands in for the item. */
48
- export declare function SidebarRailItem({ selected, label, onSelect, testId, children, }: {
47
+ * same highlight as a row, holding whatever stands in for the item. With
48
+ * `href` it is a link to the item, and `onSelect` runs only for a plain click. */
49
+ export declare function SidebarRailItem({ selected, label, href, onSelect, testId, children, }: {
49
50
  selected: boolean;
50
51
  /** Names the icon-only button, and shows beside it on hover. */
51
52
  label: string;
52
- onSelect: () => void;
53
+ href?: string | undefined;
54
+ onSelect?: (() => void) | undefined;
53
55
  testId?: string;
54
56
  children: ReactNode;
55
57
  }): import("react").JSX.Element;
@@ -1,11 +1,12 @@
1
1
  import { cx } from "../../cx.js";
2
2
  import { SidebarIcon } from "../../icons.js";
3
3
  import { Tooltip } from "../../components/Tooltip.js";
4
+ import { AppLink, isPlainClick } from "../../components/AppLink.js";
5
+ import { IconButton } from "../../components/IconButton.js";
4
6
  import { fieldBox } from "../../components/fieldBox.js";
7
+ import { focusOnMount } from "../../components/focus.js";
5
8
  import { ConfirmModal } from "../../components/ConfirmModal.js";
6
- import { IconButton } from "../../components/IconButton.js";
7
9
  import { MoreButton, rowContextMenuProps, useRowMenuActive } from "../../list/rowMenu.js";
8
- import { focusOnMount } from "../../components/focus.js";
9
10
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
11
  import { useState } from "react";
11
12
  //#region src/ai/ui/sidebar.tsx
@@ -37,7 +38,7 @@ function SidebarToggle({ collapsed, onToggle, openLabel, closeLabel, className }
37
38
  function SidebarGroupHeading({ children, tone = "default", testId }) {
38
39
  return /* @__PURE__ */ jsx("h4", {
39
40
  "data-testid": testId,
40
- className: cx("mt-5 mb-1 whitespace-nowrap px-2 text-xs font-medium", tone === "attention" ? "text-amber-700 dark:text-amber-300" : "theme-muted-text"),
41
+ className: cx("mt-5 mb-1 whitespace-nowrap px-2 text-xs font-medium", tone === "attention" ? "text-(--theme-warning-text)" : "theme-muted-text"),
41
42
  children
42
43
  });
43
44
  }
@@ -69,18 +70,29 @@ function SidebarRow({ selected, menuItems, openMenu, className, children }) {
69
70
  });
70
71
  }
71
72
  /** One entry in the collapsed rail: a square the size of the toggle, with the
72
- * same highlight as a row, holding whatever stands in for the item. */
73
- function SidebarRailItem({ selected, label, onSelect, testId, children }) {
73
+ * same highlight as a row, holding whatever stands in for the item. With
74
+ * `href` it is a link to the item, and `onSelect` runs only for a plain click. */
75
+ function SidebarRailItem({ selected, label, href, onSelect, testId, children }) {
76
+ const props = {
77
+ "data-testid": testId,
78
+ "aria-label": label,
79
+ "aria-current": selected ? "page" : void 0,
80
+ className: cx("flex h-7 w-7 items-center justify-center rounded-md transition-colors", HIGHLIGHT_HOVER, selected && HIGHLIGHT_SELECTED)
81
+ };
74
82
  return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(Tooltip, {
75
83
  content: label,
76
84
  side: "right",
77
- children: /* @__PURE__ */ jsx("button", {
85
+ children: href ? /* @__PURE__ */ jsx(AppLink, {
86
+ href,
87
+ onClick: (e) => {
88
+ if (isPlainClick(e)) onSelect?.();
89
+ },
90
+ ...props,
91
+ children
92
+ }) : /* @__PURE__ */ jsx("button", {
78
93
  type: "button",
79
- "data-testid": testId,
80
- "aria-label": label,
81
- "aria-current": selected ? "page" : void 0,
82
94
  onClick: onSelect,
83
- className: cx("flex h-7 w-7 items-center justify-center rounded-md transition-colors", HIGHLIGHT_HOVER, selected && HIGHLIGHT_SELECTED),
95
+ ...props,
84
96
  children
85
97
  })
86
98
  }) });
@@ -7,6 +7,7 @@ export declare function ActionMenu({ items, label, search, align, triggerClassNa
7
7
  label: string;
8
8
  search?: MenuSearch | undefined;
9
9
  align?: 'start' | 'center' | 'end';
10
+ /** Styles the trigger; without it the trigger is a ghost icon button. */
10
11
  triggerClassName?: string | undefined;
11
12
  /** The trigger's content. */
12
13
  children: ReactNode;
@@ -1,3 +1,4 @@
1
+ import { buttonClasses } from "./buttonClasses.js";
1
2
  import { MenuPopup } from "./Menu.js";
2
3
  import { Tooltip } from "./Tooltip.js";
3
4
  import { MenuEntries, MenuFilter } from "./MenuEntries.js";
@@ -12,7 +13,11 @@ function ActionMenu({ items, label, search, align, triggerClassName, children })
12
13
  content: label,
13
14
  children: /* @__PURE__ */ jsx(Menu.Trigger, {
14
15
  "aria-label": label,
15
- className: triggerClassName,
16
+ className: triggerClassName ?? buttonClasses({
17
+ variant: "ghost",
18
+ size: "sm",
19
+ iconOnly: true
20
+ }),
16
21
  children
17
22
  })
18
23
  }), /* @__PURE__ */ jsx(MenuPopup, {
@@ -0,0 +1,26 @@
1
+ import type { ComponentPropsWithRef, MouseEvent } from 'react';
2
+ /** Where a control navigates, for any component that can be a link instead of a button. */
3
+ export interface LinkTarget {
4
+ /** Navigates there: a plain click goes through the host's router, and a
5
+ * modified or middle click opens it as any link would. */
6
+ href?: string | undefined;
7
+ /** Loads the page instead of routing, for paths the host's router doesn't serve. */
8
+ reloadDocument?: boolean | undefined;
9
+ /** Such as `_blank`, which also cuts the opened page's hold on this one. */
10
+ target?: string | undefined;
11
+ }
12
+ export type AppLinkProps = Omit<ComponentPropsWithRef<'a'>, 'href' | 'target'> & LinkTarget & {
13
+ /** Keeps it a link that goes nowhere: no href, `aria-disabled`, still
14
+ * focusable so a tooltip saying why stays reachable. */
15
+ disabled?: boolean | undefined;
16
+ };
17
+ /** True for a click the browser would open in place: the primary button with
18
+ * no modifier. A link's own onClick work, such as closing a drawer or clearing
19
+ * state, belongs to that click only; the others open a new tab or window and
20
+ * leave this page as it is. */
21
+ export declare function isPlainClick(event: MouseEvent<Element>): boolean;
22
+ /** A link through the host's router (`useLink`): the one way a component
23
+ * renders an `href`. In-app paths route client-side; `reloadDocument` and
24
+ * URLs that leave the app get a plain anchor. Every href passes `safeUrl`,
25
+ * and one that doesn't, or a disabled link, renders without an href. */
26
+ export declare function AppLink({ href, reloadDocument, target, disabled, rel, onClick, children, ...props }: AppLinkProps): import("react").JSX.Element;
@@ -0,0 +1,51 @@
1
+ import { safeUrl } from "../safeUrl.js";
2
+ import { useLink, useStrings } from "./Provider.js";
3
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
+ //#region src/components/AppLink.tsx
5
+ function leavesApp(url) {
6
+ if (!/^([a-z][a-z\d+.-]*:|\/\/)/i.test(url)) return false;
7
+ if (typeof window === "undefined") return true;
8
+ return new URL(url, window.location.href).origin !== window.location.origin;
9
+ }
10
+ /** True for a click the browser would open in place: the primary button with
11
+ * no modifier. A link's own onClick work, such as closing a drawer or clearing
12
+ * state, belongs to that click only; the others open a new tab or window and
13
+ * leave this page as it is. */
14
+ function isPlainClick(event) {
15
+ return event.button === 0 && !event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey && event.currentTarget.getAttribute("target") !== "_blank";
16
+ }
17
+ /** A link through the host's router (`useLink`): the one way a component
18
+ * renders an `href`. In-app paths route client-side; `reloadDocument` and
19
+ * URLs that leave the app get a plain anchor. Every href passes `safeUrl`,
20
+ * and one that doesn't, or a disabled link, renders without an href. */
21
+ function AppLink({ href, reloadDocument = false, target, disabled = false, rel, onClick, children, ...props }) {
22
+ const Link = useLink();
23
+ const { common } = useStrings();
24
+ const url = disabled ? void 0 : safeUrl(href);
25
+ if (!url) return /* @__PURE__ */ jsx("a", {
26
+ ...props,
27
+ role: "link",
28
+ "aria-disabled": "true",
29
+ tabIndex: props.tabIndex ?? 0,
30
+ children
31
+ });
32
+ const linkProps = {
33
+ ...props,
34
+ target,
35
+ rel: rel ?? (target === "_blank" ? "noopener noreferrer" : void 0),
36
+ onClick,
37
+ children: target === "_blank" ? /* @__PURE__ */ jsxs(Fragment, { children: [children, /* @__PURE__ */ jsxs("span", {
38
+ className: "sr-only",
39
+ children: [" ", common.opensInNewTab]
40
+ })] }) : children
41
+ };
42
+ return reloadDocument || leavesApp(url) ? /* @__PURE__ */ jsx("a", {
43
+ ...linkProps,
44
+ href: url
45
+ }) : /* @__PURE__ */ jsx(Link, {
46
+ ...linkProps,
47
+ href: url
48
+ });
49
+ }
50
+ //#endregion
51
+ export { AppLink, isPlainClick };
@@ -11,5 +11,6 @@ export interface AvatarProps {
11
11
  /** Up to two initials: the first and last word of a name split on spaces and dots. */
12
12
  export declare function avatarInitials(name: string | undefined): string;
13
13
  /** A person's picture, or their initials while it loads or when it fails. It is
14
- * one image to assistive technology, named for the person, whichever shows. */
14
+ * one image to assistive technology, named for the person, whichever shows,
15
+ * and their presence when it has a status dot. */
15
16
  export declare function Avatar({ src, name, size, status, className }: AvatarProps): import("react").JSX.Element;
@@ -26,12 +26,14 @@ function avatarInitials(name) {
26
26
  return first?.toUpperCase() || "?";
27
27
  }
28
28
  /** A person's picture, or their initials while it loads or when it fails. It is
29
- * one image to assistive technology, named for the person, whichever shows. */
29
+ * one image to assistive technology, named for the person, whichever shows,
30
+ * and their presence when it has a status dot. */
30
31
  function Avatar$1({ src, name, size = "md", status, className }) {
31
32
  const { common } = useStrings();
33
+ const who = name || common.userAvatar;
32
34
  return /* @__PURE__ */ jsxs("span", {
33
35
  role: "img",
34
- "aria-label": name || common.userAvatar,
36
+ "aria-label": status ? common.withPresence(who, common.presence[status]) : who,
35
37
  className: cx("relative inline-flex shrink-0", className),
36
38
  children: [/* @__PURE__ */ jsxs(Avatar.Root, {
37
39
  className: cx("relative inline-flex items-center justify-center overflow-hidden rounded-full font-medium select-none", SIZE_CLASSES[size]),
@@ -1,7 +1,8 @@
1
1
  import { Button as BaseButton } from '@base-ui/react/button';
2
2
  import type { ButtonHTMLAttributes, ReactNode } from 'react';
3
+ import { type AppLinkProps, type LinkTarget } from './AppLink.js';
3
4
  import { type ButtonStyle } from './buttonClasses.js';
4
- export interface ButtonProps extends Omit<BaseButton.Props, 'className'>, ButtonStyle {
5
+ interface ButtonOwnProps extends ButtonStyle {
5
6
  className?: string | undefined;
6
7
  /** Before the label. */
7
8
  icon?: ReactNode;
@@ -9,16 +10,25 @@ export interface ButtonProps extends Omit<BaseButton.Props, 'className'>, Button
9
10
  * be pressed again until done. */
10
11
  loading?: boolean | undefined;
11
12
  }
13
+ /** A button, or with `href` a link that looks like one: navigation stays a
14
+ * link, so it opens in a new tab and shows its URL like any other. */
15
+ export type ButtonProps = ButtonOwnProps & ((Omit<BaseButton.Props, 'className'> & {
16
+ href?: undefined;
17
+ }) | (Omit<AppLinkProps, 'className'> & LinkTarget & {
18
+ href: string;
19
+ }));
12
20
  /** A button in the package's one look (see `buttonClasses`).
13
- * `focusableWhenDisabled` keeps a disabled button's tooltip reachable. A link
14
- * that looks like a button stays a link: give it `buttonClasses()`. */
15
- export declare function Button({ variant, size, iconOnly, icon, loading, disabled, className, children, ...props }: ButtonProps): import("react").JSX.Element;
16
- interface MethodButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
21
+ * `focusableWhenDisabled` keeps a disabled button's tooltip reachable; a
22
+ * disabled link stays focusable on its own. */
23
+ export declare function Button({ variant, size, iconOnly, icon, loading, className, children, ...props }: ButtonProps): import("react").JSX.Element;
24
+ interface MethodButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {
17
25
  icon?: ReactNode;
18
26
  label: string;
19
27
  description?: string;
20
28
  href?: string;
21
29
  loading?: boolean;
22
30
  }
31
+ /** One way to go on, such as a sign-in method: a large row with an icon, a
32
+ * label and a line under it. A list of them is spaced by its container. */
23
33
  export declare function MethodButton({ icon, label, description, href, loading, disabled, className, ...props }: MethodButtonProps): import("react").JSX.Element;
24
34
  export {};