@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,39 +1,52 @@
1
1
  import { cx } from "../cx.js";
2
- import { Field, RevealToggle } from "./Field.js";
3
2
  import { fieldBox } from "./fieldBox.js";
3
+ import { Field, RevealToggle } from "./Field.js";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
- import { forwardRef, useState } from "react";
5
+ import { useState } from "react";
6
+ import { Input } from "@base-ui/react/input";
6
7
  //#region src/components/Input.tsx
7
8
  /** The Field around a control when it has a label; the control alone when it doesn't. */
8
- function framed({ label, hint, description, error }, { id, required, disabled }, control) {
9
+ function framed({ label, hint, help, description, error, size }, { id, required, disabled }, control) {
9
10
  if (label === void 0) return control(error ? { "aria-invalid": true } : {});
10
11
  return /* @__PURE__ */ jsx(Field, {
11
12
  label,
12
13
  hint,
14
+ help,
13
15
  description,
14
16
  error,
15
17
  required,
16
18
  disabled,
19
+ size,
17
20
  id,
18
21
  children: control
19
22
  });
20
23
  }
21
- /** A single-line text field. `type="password"` adds a button that shows what was typed. */
22
- var Input = forwardRef(({ label, hint, description, error, className, mono, size, type, ...props }, ref) => {
24
+ /** The control props joined with the element's own: its own `aria-describedby` stays beside the
25
+ * field's, and its own invalid mark holds when the field sets none. */
26
+ function joined(control, own) {
27
+ return {
28
+ ...control,
29
+ "aria-invalid": control["aria-invalid"] ?? own["aria-invalid"],
30
+ "aria-describedby": [own["aria-describedby"], control["aria-describedby"]].filter(Boolean).join(" ") || void 0
31
+ };
32
+ }
33
+ /** A single-line text field. `type="password"` adds a button that shows what was typed. Placed in
34
+ * a Field, it takes the Field's label, description and invalid state. */
35
+ function Input$1({ label, hint, help, description, error, className, mono, size, type, ref, ...props }) {
23
36
  const [revealed, setRevealed] = useState(false);
24
37
  const secret = type === "password";
25
38
  return framed({
26
39
  label,
27
40
  hint,
41
+ help,
28
42
  description,
29
- error
43
+ error,
44
+ size
30
45
  }, props, (control) => {
31
- const input = /* @__PURE__ */ jsx("input", {
46
+ const input = /* @__PURE__ */ jsx(Input, {
32
47
  ref,
33
48
  ...props,
34
- ...control,
35
- "aria-invalid": control["aria-invalid"] ?? props["aria-invalid"],
36
- "aria-describedby": [props["aria-describedby"], control["aria-describedby"]].filter(Boolean).join(" ") || void 0,
49
+ ...joined(control, props),
37
50
  type: secret && revealed ? "text" : type,
38
51
  className: cx(fieldBox({ size }), mono && "font-mono", secret && "pr-9", className)
39
52
  });
@@ -46,25 +59,27 @@ var Input = forwardRef(({ label, hint, description, error, className, mono, size
46
59
  })]
47
60
  }) : input;
48
61
  });
49
- });
50
- Input.displayName = "Input";
51
- /** A multi-line text field that grows by hand. */
52
- var Textarea = forwardRef(({ label, hint, description, error, className, mono, size, ...props }, ref) => framed({
53
- label,
54
- hint,
55
- description,
56
- error
57
- }, props, (control) => /* @__PURE__ */ jsx("textarea", {
58
- ref,
59
- ...props,
60
- ...control,
61
- "aria-invalid": control["aria-invalid"] ?? props["aria-invalid"],
62
- "aria-describedby": [props["aria-describedby"], control["aria-describedby"]].filter(Boolean).join(" ") || void 0,
63
- className: cx(fieldBox({
64
- size,
65
- multiline: true
66
- }), size === "sm" ? "min-h-16" : "min-h-24", "resize-y", mono && "font-mono", className)
67
- })));
68
- Textarea.displayName = "Textarea";
62
+ }
63
+ /** A multi-line text field that grows by hand. Placed in a Field, it takes the Field's label,
64
+ * description and invalid state. */
65
+ function Textarea({ label, hint, help, description, error, className, mono, size, ref, ...props }) {
66
+ return framed({
67
+ label,
68
+ hint,
69
+ help,
70
+ description,
71
+ error,
72
+ size
73
+ }, props, (control) => /* @__PURE__ */ jsx(Input, {
74
+ ...props,
75
+ ...joined(control, props),
76
+ ref,
77
+ render: /* @__PURE__ */ jsx("textarea", {}),
78
+ className: cx(fieldBox({
79
+ size,
80
+ multiline: true
81
+ }), size === "sm" ? "min-h-16" : "min-h-24", "resize-y", mono && "font-mono", className)
82
+ }));
83
+ }
69
84
  //#endregion
70
- export { Input, Textarea, framed };
85
+ export { Input$1 as Input, Textarea, framed };
@@ -31,7 +31,7 @@ function Loader({ size = 48, label, variant = "spinner", inline = false, color,
31
31
  "aria-label": label || loading,
32
32
  className: cx("items-center", inline ? "inline-flex gap-2" : "flex w-full flex-col justify-center gap-y-1"),
33
33
  children: [/* @__PURE__ */ jsx("span", {
34
- className: cx("inline-flex", !color && "text-(--theme-accent,#3b82f6)"),
34
+ className: cx("inline-flex", !color && "text-(--theme-accent)"),
35
35
  style: color ? { color } : void 0,
36
36
  children: variant === "logo" ? /* @__PURE__ */ jsx("svg", {
37
37
  viewBox: "0 0 64.29 64.29",
@@ -1,2 +1,3 @@
1
+ import 'katex/dist/katex.min.css';
1
2
  import type { MarkdownProps } from './Markdown.js';
2
3
  export default function MarkdownImpl({ children, isStreaming, controls, components, }: MarkdownProps): import("react").JSX.Element;
@@ -7,6 +7,7 @@ import { jsx } from "react/jsx-runtime";
7
7
  import { useEffect, useState } from "react";
8
8
  import { code } from "@streamdown/code";
9
9
  import { math } from "@streamdown/math";
10
+ import "katex/dist/katex.min.css";
10
11
  import { Streamdown, defaultRehypePlugins } from "streamdown";
11
12
  //#region src/components/MarkdownImpl.tsx
12
13
  var basePlugins = {
@@ -16,6 +16,7 @@ interface MenuClickAction extends MenuActionBase {
16
16
  checked?: boolean | undefined;
17
17
  href?: never;
18
18
  reloadDocument?: never;
19
+ target?: never;
19
20
  copy?: never;
20
21
  }
21
22
  /** Navigates to `href`. */
@@ -23,6 +24,8 @@ interface MenuLinkAction extends MenuActionBase {
23
24
  href: string;
24
25
  /** Loads the page instead of routing, for paths the host's router doesn't serve. */
25
26
  reloadDocument?: boolean | undefined;
27
+ /** `_blank` opens it in a new tab, such as a page outside the app. */
28
+ target?: '_blank' | undefined;
26
29
  onClick?: never;
27
30
  checked?: never;
28
31
  copy?: never;
@@ -37,6 +40,7 @@ interface MenuCopyAction extends MenuActionBase {
37
40
  checked?: never;
38
41
  href?: never;
39
42
  reloadDocument?: never;
43
+ target?: never;
40
44
  }
41
45
  /** Something a menu row does: runs `onClick`, navigates to `href`, or copies
42
46
  * `copy`. Exactly one, so a row that does nothing when chosen doesn't compile.
@@ -1,10 +1,10 @@
1
1
  import { cx } from "../cx.js";
2
2
  import { MenuCheckboxItem, MenuItem, MenuLinkItem, MenuPopup, MenuSeparator, MenuSubmenuTrigger } from "./Menu.js";
3
- import { safeUrl } from "../safeUrl.js";
4
- import { EmptyState } from "./EmptyState.js";
3
+ import { isDev } from "../dev.js";
5
4
  import { keyedByContent } from "./keys.js";
6
5
  import { Tooltip } from "./Tooltip.js";
7
- import { useLink } from "./Provider.js";
6
+ import { AppLink } from "./AppLink.js";
7
+ import { EmptyState } from "./EmptyState.js";
8
8
  import { useQueryMatch } from "./search.js";
9
9
  import { useCopy } from "./useCopy.js";
10
10
  import { Menu } from "@base-ui/react/menu";
@@ -38,7 +38,7 @@ function MenuEntries({ entries, search, query = "" }) {
38
38
  children: /* @__PURE__ */ jsx(Menu.Input, {
39
39
  "aria-label": search.placeholder,
40
40
  placeholder: search.placeholder,
41
- className: "w-full rounded-md border border-(--theme-border) bg-(--theme-muted-panel-bg) px-2 py-1 text-[13px] text-(--theme-app) outline-none placeholder:text-(--theme-placeholder) focus:border-(--theme-accent)"
41
+ className: "w-full rounded-md border border-(--theme-border) bg-(--theme-muted-panel-bg) px-2 py-1 text-[13px] text-(--theme-app) outline-none placeholder:text-(--theme-placeholder) focus:border-(--theme-focus)"
42
42
  })
43
43
  }),
44
44
  /* @__PURE__ */ jsx(Menu.List, { children: /* @__PURE__ */ jsx(EntryRows, { entries: shown }) }),
@@ -79,7 +79,7 @@ var warnedInert = /* @__PURE__ */ new Set();
79
79
  * out, but a JavaScript caller or a cast still can, and its row renders fine
80
80
  * and silently does nothing. */
81
81
  function warnIfInert(action, where) {
82
- if (process.env.NODE_ENV === "production") return;
82
+ if (!isDev()) return;
83
83
  if (action.onClick || action.href || action.copy || warnedInert.has(action.label)) return;
84
84
  warnedInert.add(action.label);
85
85
  console.warn(`${where}: the action "${action.label}" has no onClick, href or copy, so choosing it does nothing.`);
@@ -94,16 +94,15 @@ function useRunAction() {
94
94
  }
95
95
  function ActionRow({ action }) {
96
96
  warnIfInert(action, "MenuEntries");
97
- const Link = useLink();
98
97
  const runAction = useRunAction();
99
98
  const className = cx(action.destructive && destructiveClassName);
100
99
  const content = /* @__PURE__ */ jsxs(Fragment, { children: [action.icon, action.label] });
101
- if (action.href && !action.disabled) return action.reloadDocument ? /* @__PURE__ */ jsx(MenuLinkItem, {
102
- href: safeUrl(action.href),
103
- className,
104
- children: content
105
- }) : /* @__PURE__ */ jsx(MenuLinkItem, {
106
- render: /* @__PURE__ */ jsx(Link, { href: action.href }),
100
+ if (action.href && !action.disabled) return /* @__PURE__ */ jsx(MenuLinkItem, {
101
+ render: /* @__PURE__ */ jsx(AppLink, {
102
+ href: action.href,
103
+ reloadDocument: action.reloadDocument,
104
+ target: action.target
105
+ }),
107
106
  className,
108
107
  children: content
109
108
  });
@@ -1,4 +1,5 @@
1
1
  import { cx } from "../cx.js";
2
+ import { toneFill } from "./tone.js";
2
3
  import { Tooltip } from "./Tooltip.js";
3
4
  import { jsx, jsxs } from "react/jsx-runtime";
4
5
  import { Meter } from "@base-ui/react/meter";
@@ -6,10 +7,10 @@ import { Progress } from "@base-ui/react/progress";
6
7
  //#region src/components/Meter.tsx
7
8
  var fillClassName = {
8
9
  accent: "bg-(--theme-accent)",
9
- success: "bg-(--theme-success)",
10
- warning: "bg-(--theme-warning)",
11
- error: "bg-(--theme-error)",
12
- muted: "bg-(--theme-muted-text-color)"
10
+ success: toneFill.success,
11
+ warning: toneFill.warning,
12
+ error: toneFill.error,
13
+ muted: toneFill.muted
13
14
  };
14
15
  var trackClassName = {
15
16
  sm: "h-1",
@@ -6,9 +6,27 @@ export declare const modalPanelClassName = "rounded-xl border border-(--theme-bo
6
6
  export declare const ModalTitle: import("react").ForwardRefExoticComponent<Omit<import("@base-ui/react").DialogTitleProps, "ref"> & import("react").RefAttributes<HTMLHeadingElement>>;
7
7
  /** Describes the modal for assistive technology; renders a `<p>`. */
8
8
  export declare const ModalDescription: import("react").ForwardRefExoticComponent<Omit<import("@base-ui/react").DialogDescriptionProps, "ref"> & import("react").RefAttributes<HTMLParagraphElement>>;
9
- export interface ModalProps extends Omit<Dialog.Popup.Props, 'className' | 'children' | 'render'> {
9
+ declare const sizeClasses: {
10
+ readonly sm: 'w-[400px]';
11
+ readonly md: 'w-[480px]';
12
+ readonly lg: 'w-[560px]';
13
+ readonly xl: 'w-[672px]';
14
+ };
15
+ export type ModalSize = keyof typeof sizeClasses;
16
+ export interface ModalProps extends Omit<Dialog.Popup.Props, 'className' | 'children' | 'render' | 'title'> {
10
17
  open: boolean;
11
18
  onClose: () => void;
19
+ /** The header's heading, which names the modal. Without one, name it with
20
+ * `aria-label`, or with a `ModalTitle` among the children. */
21
+ title?: ReactNode;
22
+ /** A line under the title, which describes the modal. */
23
+ description?: ReactNode;
24
+ /** Actions along the bottom edge, such as Cancel and Save, ruled off from the
25
+ * body; they stay in view as a tall body scrolls. */
26
+ footer?: ReactNode;
27
+ /** Its width, which narrows to fit a small window. Without one, it's as wide
28
+ * as its content. */
29
+ size?: ModalSize | undefined;
12
30
  /** A confirmation the person must answer: it takes the alertdialog role and the
13
31
  * backdrop doesn't close it. Escape still cancels while it's dismissible. */
14
32
  alert?: boolean | undefined;
@@ -21,9 +39,15 @@ export interface ModalProps extends Omit<Dialog.Popup.Props, 'className' | 'chil
21
39
  panel?: boolean;
22
40
  /** The backdrop's dimming, for a modal that needs a darker or blurred stage. */
23
41
  backdropClassName?: string;
42
+ /** On the panel. */
24
43
  className?: string;
25
- children: ReactNode;
44
+ /** The body. With a title or a footer it sits padded between them and scrolls
45
+ * when the window is short; without either, it is the whole panel. */
46
+ children?: ReactNode;
26
47
  }
27
48
  /** A modal dialog: focus stays inside, the page behind is inert and doesn't scroll,
28
- * and focus returns to where it was on close. Name it with `ModalTitle` or `aria-label`. */
29
- export declare function Modal({ open, onClose, alert, dismissible, align, panel, backdropClassName, className, children, ...popupProps }: ModalProps): import("react").JSX.Element;
49
+ * and focus returns to where it was on close. Give it a `title`, a `description`
50
+ * and a `footer` for the standard layout, as a Drawer has, or lay out the whole
51
+ * panel with the children. */
52
+ export declare function Modal({ open, onClose, title, description, footer, size, alert, dismissible, align, panel, backdropClassName, className, children, ...popupProps }: ModalProps): import("react").JSX.Element;
53
+ export {};
@@ -1,6 +1,6 @@
1
1
  import { cx } from "../cx.js";
2
- import { pressedToast } from "./Toast.js";
3
- import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { closeHandler } from "./dismiss.js";
3
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
4
  import { AlertDialog } from "@base-ui/react/alert-dialog";
5
5
  import { Dialog } from "@base-ui/react/dialog";
6
6
  //#region src/components/Modal.tsx
@@ -10,23 +10,46 @@ var modalPanelClassName = "rounded-xl border border-(--theme-border) bg-(--theme
10
10
  var ModalTitle = Dialog.Title;
11
11
  /** Describes the modal for assistive technology; renders a `<p>`. */
12
12
  var ModalDescription = Dialog.Description;
13
+ var sizeClasses = {
14
+ sm: "w-[400px]",
15
+ md: "w-[480px]",
16
+ lg: "w-[560px]",
17
+ xl: "w-[672px]"
18
+ };
13
19
  /** A modal dialog: focus stays inside, the page behind is inert and doesn't scroll,
14
- * and focus returns to where it was on close. Name it with `ModalTitle` or `aria-label`. */
15
- function Modal({ open, onClose, alert = false, dismissible = true, align = "top", panel = true, backdropClassName = "bg-black/40", className, children, ...popupProps }) {
16
- const onOpenChange = (next, details) => {
17
- if (next) return;
18
- if (!dismissible && details.reason === "escape-key" || details.reason === "outside-press" && pressedToast(details.event)) {
19
- details.cancel();
20
- return;
21
- }
22
- onClose();
23
- };
20
+ * and focus returns to where it was on close. Give it a `title`, a `description`
21
+ * and a `footer` for the standard layout, as a Drawer has, or lay out the whole
22
+ * panel with the children. */
23
+ function Modal({ open, onClose, title, description, footer, size, alert = false, dismissible = true, align = "top", panel = true, backdropClassName = "bg-black/40", className, children, ...popupProps }) {
24
+ const onOpenChange = closeHandler(dismissible, onClose);
25
+ const header = title !== void 0 || description !== void 0;
26
+ const body = children !== void 0 && children !== null && children !== false;
27
+ const laidOut = header || footer !== void 0;
24
28
  const content = /* @__PURE__ */ jsxs(Dialog.Portal, { children: [/* @__PURE__ */ jsx(Dialog.Backdrop, { className: cx("fixed inset-0 z-(--layer-modal)", backdropClassName) }), /* @__PURE__ */ jsx(Dialog.Viewport, {
25
29
  className: cx("fixed inset-0 z-(--layer-modal) flex justify-center px-4 pt-20 pb-8", align === "center" ? "items-center" : "items-start sm:pt-[max(14vh,5rem)]"),
26
30
  children: /* @__PURE__ */ jsx(Dialog.Popup, {
27
31
  ...popupProps,
28
- className: cx(panel && "rounded-xl border border-(--theme-border) bg-(--theme-app-bg) text-(--theme-app) shadow-2xl", "outline-none", className),
29
- children
32
+ className: cx(panel && "rounded-xl border border-(--theme-border) bg-(--theme-app-bg) text-(--theme-app) shadow-2xl", size && [sizeClasses[size], "max-w-full"], laidOut && "flex max-h-full flex-col", "outline-none", className),
33
+ children: laidOut ? /* @__PURE__ */ jsxs(Fragment, { children: [
34
+ header && /* @__PURE__ */ jsxs("div", {
35
+ className: cx("shrink-0 px-5 pt-5", !body && "pb-5"),
36
+ children: [title !== void 0 && /* @__PURE__ */ jsx(ModalTitle, {
37
+ className: "m-0 text-lg font-semibold",
38
+ children: title
39
+ }), description !== void 0 && /* @__PURE__ */ jsx(ModalDescription, {
40
+ className: "m-0 mt-1.5 text-sm text-(--theme-muted-text-color)",
41
+ children: description
42
+ })]
43
+ }),
44
+ body && /* @__PURE__ */ jsx("div", {
45
+ className: "min-h-0 flex-1 overflow-y-auto overscroll-contain px-5 py-4",
46
+ children
47
+ }),
48
+ footer !== void 0 && /* @__PURE__ */ jsx("div", {
49
+ className: "flex shrink-0 items-center justify-end gap-2 border-t border-(--theme-border) px-5 py-3",
50
+ children: footer
51
+ })
52
+ ] }) : children
30
53
  })
31
54
  })] });
32
55
  return alert ? /* @__PURE__ */ jsx(AlertDialog.Root, {
@@ -1,12 +1,20 @@
1
- export declare function Overview({ Icon, name, type, children, right, className, loading, iconSize, }: {
2
- Icon: React.ReactNode;
3
- name: string | React.ReactNode;
4
- type?: string | React.ReactNode;
5
- children?: React.ReactNode;
6
- /** Right-aligned content on the header row (e.g. a detail-page action bar),
7
- * vertically centered against the name block. */
8
- right?: React.ReactNode;
9
- className?: string;
10
- loading?: boolean;
11
- iconSize?: number;
12
- }): import("react").JSX.Element;
1
+ import type { ReactNode } from 'react';
2
+ export interface OverviewProps {
3
+ /** The thing's mark, such as its type's icon or an avatar. */
4
+ icon: ReactNode;
5
+ name: ReactNode;
6
+ /** Under the name, such as its kind. */
7
+ type?: ReactNode;
8
+ /** A row under the type, such as badges. */
9
+ children?: ReactNode;
10
+ /** At the row's end, centered against the name block, such as actions. */
11
+ actions?: ReactNode;
12
+ /** Sketches the icon and two lines while the thing loads. */
13
+ loading?: boolean | undefined;
14
+ /** The loading sketch's icon size, in pixels, to match the icon that replaces it. */
15
+ iconSize?: number | undefined;
16
+ className?: string | undefined;
17
+ }
18
+ /** A thing's summary at the top of its page: its mark, its name and kind, and
19
+ * what to do with it. */
20
+ export declare function Overview({ icon, name, type, children, actions, className, loading, iconSize, }: OverviewProps): import("react").JSX.Element;
@@ -2,17 +2,19 @@ import { cx } from "../cx.js";
2
2
  import { LoadingRegion, Skeleton } from "./Skeleton.js";
3
3
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
4
  //#region src/components/Overview.tsx
5
- function Overview({ Icon, name, type, children, right, className, loading, iconSize = 75 }) {
5
+ /** A thing's summary at the top of its page: its mark, its name and kind, and
6
+ * what to do with it. */
7
+ function Overview({ icon, name, type, children, actions, className, loading = false, iconSize = 75 }) {
6
8
  return /* @__PURE__ */ jsxs("div", {
7
- className: cx("flex items-center w-full", className),
9
+ className: cx("flex w-full items-center gap-3", className),
8
10
  children: [
9
11
  loading ? /* @__PURE__ */ jsx(Skeleton, {
10
12
  circle: true,
11
13
  height: iconSize,
12
14
  className: "shrink-0"
13
- }) : Icon,
15
+ }) : icon,
14
16
  /* @__PURE__ */ jsx("div", {
15
- className: "flex flex-col min-w-0 flex-1",
17
+ className: "flex min-w-0 flex-1 flex-col",
16
18
  children: loading ? /* @__PURE__ */ jsx(LoadingRegion, {
17
19
  className: "space-y-1",
18
20
  children: /* @__PURE__ */ jsx(Skeleton, {
@@ -21,19 +23,22 @@ function Overview({ Icon, name, type, children, right, className, loading, iconS
21
23
  })
22
24
  }) : /* @__PURE__ */ jsxs(Fragment, { children: [
23
25
  /* @__PURE__ */ jsx("div", {
24
- className: "font-semibold text-xl tracking-tight",
26
+ className: "text-xl font-semibold tracking-tight",
25
27
  children: name
26
28
  }),
27
- type && /* @__PURE__ */ jsx("p", { children: type }),
28
- /* @__PURE__ */ jsx("div", {
29
+ type && /* @__PURE__ */ jsx("p", {
30
+ className: "m-0 text-sm text-(--theme-muted-text-color)",
31
+ children: type
32
+ }),
33
+ children && /* @__PURE__ */ jsx("div", {
29
34
  className: "flex flex-row gap-x-2",
30
35
  children
31
36
  })
32
37
  ] })
33
38
  }),
34
- right && /* @__PURE__ */ jsx("div", {
39
+ actions && /* @__PURE__ */ jsx("div", {
35
40
  className: "shrink-0 self-center",
36
- children: right
41
+ children: actions
37
42
  })
38
43
  ]
39
44
  });
@@ -1,70 +1,52 @@
1
- import type { ComponentType, ReactNode } from 'react';
2
- import type { MenuEntry } from './MenuEntries.js';
3
- export interface PageHeaderBreadcrumb {
4
- label: string;
5
- href?: string;
6
- }
7
- /** A rendered crumb row entry, as handed to the breadcrumbPin slot. */
8
- export interface PageHeaderCrumb {
9
- label: ReactNode;
10
- href?: string;
11
- }
12
- /** With menu, the plus opens a chooser; otherwise navigates to or calls the
13
- * single action. `word` is the visible verb; `label` stays the full action for
14
- * the tooltip and screen readers. */
15
- export declare function HeaderAddButton({ href, onClick, label, word, menu, disabled, disabledHint, }: {
16
- href?: string;
17
- onClick?: () => void;
18
- label: string;
19
- word?: 'add' | 'create';
20
- menu?: MenuEntry[];
21
- /** Button mode only. */
22
- disabled?: boolean;
23
- disabledHint?: string;
24
- }): import("react").JSX.Element;
25
- /** The header's "…" menu of actions on the page's subject. */
26
- export declare function HeaderActionMenu({ items, label }: {
27
- items: MenuEntry[];
28
- label?: string;
29
- }): import("react").JSX.Element | null;
30
- export declare function HeaderEditButton({ href, onClick, label: labelProp, disabled, tooltip, }: {
31
- href?: string;
32
- onClick?: () => void;
33
- label?: string;
34
- disabled?: boolean;
35
- tooltip?: string | undefined;
36
- }): import("react").JSX.Element;
37
- /** Renders nothing when the modern breadcrumb strip isn't mounted (classic chrome or self-headered pages). */
38
- export declare function BreadcrumbsTitleAction({ children }: {
39
- children: ReactNode;
40
- }): import("react").ReactPortal | null;
41
- export declare function BreadcrumbsRightAction({ children }: {
1
+ import type { ReactNode } from 'react';
2
+ import { type Breadcrumb } from './pageHeaderStore.js';
3
+ export type { Breadcrumb } from './pageHeaderStore.js';
4
+ /**
5
+ * Holds the header the current page declares, for the `PageHeaderBar` the
6
+ * shell renders. Wrap the shell, above both the bar and the routes.
7
+ */
8
+ export declare function PageHeaderProvider({ children }: {
42
9
  children: ReactNode;
43
- }): import("react").ReactPortal | null;
44
- export declare function BreadcrumbsActionButton({ icon: Icon, label, ariaLabel, href, onClick, disabled, tooltip, destructive, }: {
45
- icon: ComponentType<{
46
- className?: string;
47
- }>;
48
- label: string;
49
- ariaLabel?: string;
50
- href?: string;
51
- onClick?: (() => void) | undefined;
52
- disabled?: boolean;
53
- tooltip?: string | undefined;
54
- /** In the error color, as a destructive menu entry is, for an action that removes or breaks
55
- * something. */
56
- destructive?: boolean | undefined;
57
10
  }): import("react").JSX.Element;
58
- interface PageHeaderProps {
59
- breadcrumbs?: PageHeaderBreadcrumb[] | undefined;
60
- title?: ReactNode;
61
- titleAction?: ReactNode;
11
+ export interface PageHeaderProps {
12
+ /** The trail to this page, ending with the page itself, which becomes its
13
+ * `h1`. A crumb with an empty label, such as a name still loading, shows a
14
+ * placeholder. */
15
+ breadcrumbs?: readonly Breadcrumb[] | undefined;
16
+ /** Beside the title: actions on the page's subject, such as edit, rename or
17
+ * favorite, or its `PageHeaderMenu`. */
18
+ titleActions?: ReactNode;
19
+ /** At the end of the bar: the page's commands, such as Save or "+ Create". */
62
20
  actions?: ReactNode;
21
+ /** A row under the bar, such as tabs or a time range, that stays put while
22
+ * the page scrolls. */
63
23
  toolbar?: ReactNode;
64
- className?: string;
65
- sticky?: boolean;
66
- /** Negative offset (e.g. -top-4) prevents rows peeking above the header when the container has top padding. */
67
- stickyTopClassName?: string;
24
+ /** Takes the bar away, for a page that fills the window. */
25
+ hidden?: boolean | undefined;
26
+ }
27
+ /**
28
+ * Declares the page's header: its breadcrumbs, title actions, actions and
29
+ * toolbar. Under a `PageHeaderProvider` it renders nothing in place: the
30
+ * shell's `PageHeaderBar` shows it, while the actions stay in the page's React
31
+ * tree, with its context and state. Without a provider it renders the bar
32
+ * itself, for a page with no shell.
33
+ *
34
+ * Any component may render one, such as a form adding its Save button: the bar
35
+ * shows the actions of all of them, outermost first, and the trail of the last
36
+ * one rendered that has one, so a page's trail replaces its layout's.
37
+ */
38
+ export declare function PageHeader(props: PageHeaderProps): import("react").JSX.Element | null;
39
+ export interface PageHeaderBarProps {
40
+ /** A shorter bar, for a page that gives the window to an embedded app. */
41
+ compact?: boolean | undefined;
42
+ /** Keep the bar when the page declares nothing, such as on a narrow screen
43
+ * where it holds the navigation toggle. A page's `hidden` still wins. */
44
+ persistent?: boolean | undefined;
45
+ className?: string | undefined;
68
46
  }
69
- export declare function PageHeader({ breadcrumbs, title, titleAction, actions, toolbar, className, sticky, stickyTopClassName, }: PageHeaderProps): import("react").JSX.Element;
70
- export {};
47
+ /**
48
+ * The bar showing what the current page declares with `PageHeader`. The shell
49
+ * renders one, inside a `PageHeaderProvider`, wherever its chrome puts it. It
50
+ * renders nothing while the page declares nothing.
51
+ */
52
+ export declare function PageHeaderBar({ compact, persistent, className, }: PageHeaderBarProps): import("react").JSX.Element | null;