@parallelworks/ui 0.50.0 → 0.52.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 (240) hide show
  1. package/README.md +204 -18
  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 +12 -0
  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 +4 -4
  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 +117 -56
  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 +81 -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 +21 -9
  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 +51 -24
  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 +51 -17
  63. package/dist/components/DescriptionList.js +117 -31
  64. package/dist/components/Disclosure.js +1 -1
  65. package/dist/components/Drawer.js +10 -16
  66. package/dist/components/Field.d.ts +15 -5
  67. package/dist/components/Field.js +41 -9
  68. package/dist/components/IconButton.d.ts +14 -5
  69. package/dist/components/IconButton.js +25 -14
  70. package/dist/components/InfoTip.d.ts +4 -1
  71. package/dist/components/InfoTip.js +2 -1
  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/MenuEntries.d.ts +43 -12
  76. package/dist/components/MenuEntries.js +34 -19
  77. package/dist/components/Meter.js +5 -4
  78. package/dist/components/Modal.d.ts +28 -4
  79. package/dist/components/Modal.js +37 -14
  80. package/dist/components/Overview.d.ts +20 -12
  81. package/dist/components/Overview.js +14 -9
  82. package/dist/components/PageHeader.d.ts +47 -65
  83. package/dist/components/PageHeader.js +275 -153
  84. package/dist/components/PageHeaderAction.d.ts +67 -0
  85. package/dist/components/PageHeaderAction.js +107 -0
  86. package/dist/components/Pagination.js +6 -16
  87. package/dist/components/Popover.js +3 -2
  88. package/dist/components/Provider.d.ts +79 -19
  89. package/dist/components/Provider.js +140 -130
  90. package/dist/components/Radio.js +2 -1
  91. package/dist/components/RefreshButton.js +7 -8
  92. package/dist/components/RequiredMark.js +1 -1
  93. package/dist/components/RunStatusIcon.js +2 -2
  94. package/dist/components/Section.js +1 -1
  95. package/dist/components/Select.d.ts +4 -9
  96. package/dist/components/Select.js +24 -11
  97. package/dist/components/SettingModeOption.d.ts +1 -1
  98. package/dist/components/SettingModeOption.js +7 -1
  99. package/dist/components/SettingsCard.d.ts +5 -3
  100. package/dist/components/SettingsCard.js +27 -20
  101. package/dist/components/Slider.js +1 -1
  102. package/dist/components/StatusBadge.js +2 -2
  103. package/dist/components/StatusIcons.js +2 -2
  104. package/dist/components/Switch.js +5 -4
  105. package/dist/components/Table.d.ts +30 -20
  106. package/dist/components/Table.js +50 -73
  107. package/dist/components/Tabs.d.ts +3 -7
  108. package/dist/components/Tabs.js +6 -10
  109. package/dist/components/ThemeEditor.js +24 -14
  110. package/dist/components/Toast.d.ts +11 -3
  111. package/dist/components/Toast.js +47 -22
  112. package/dist/components/buttonClasses.js +2 -2
  113. package/dist/components/comboboxItems.d.ts +4 -0
  114. package/dist/components/comboboxItems.js +6 -1
  115. package/dist/components/dismiss.d.ts +12 -0
  116. package/dist/components/dismiss.js +19 -0
  117. package/dist/components/fieldBox.d.ts +4 -0
  118. package/dist/components/fieldBox.js +7 -3
  119. package/dist/components/floating.d.ts +3 -3
  120. package/dist/components/floating.js +1 -1
  121. package/dist/components/markdownCodeBreaks.js +3 -4
  122. package/dist/components/pageHeaderStore.d.ts +41 -0
  123. package/dist/components/pageHeaderStore.js +67 -0
  124. package/dist/components/pathBreaks.d.ts +8 -0
  125. package/dist/components/pathBreaks.js +28 -0
  126. package/dist/components/segmented.js +1 -1
  127. package/dist/components/shortcutKey.d.ts +2 -1
  128. package/dist/components/shortcutKey.js +19 -2
  129. package/dist/components/splitter.js +1 -1
  130. package/dist/components/tone.d.ts +5 -2
  131. package/dist/components/tone.js +15 -6
  132. package/dist/components/useCssIsDark.js +40 -18
  133. package/dist/components/useTheme.js +9 -10
  134. package/dist/dev.d.ts +9 -0
  135. package/dist/dev.js +14 -0
  136. package/dist/editor/Editor.d.ts +3 -2
  137. package/dist/editor/Editor.js +11 -2
  138. package/dist/editor/EditorField.d.ts +2 -1
  139. package/dist/editor/EditorField.js +11 -29
  140. package/dist/editor/FormCodePanel.d.ts +7 -3
  141. package/dist/editor/FormCodePanel.js +14 -7
  142. package/dist/editor/Monaco.d.ts +14 -5
  143. package/dist/editor/Monaco.js +163 -112
  144. package/dist/editor/index.d.ts +5 -5
  145. package/dist/editor/index.js +3 -3
  146. package/dist/editor/themes.d.ts +8 -5
  147. package/dist/editor/themes.js +58 -30
  148. package/dist/editor/yaml.d.ts +6 -2
  149. package/dist/editor/yaml.js +11 -2
  150. package/dist/file-explorer/FileExplorer.js +143 -124
  151. package/dist/file-explorer/FileExplorerContext.js +1 -1
  152. package/dist/file-explorer/FilePreview/StreamedBadge.js +3 -1
  153. package/dist/file-explorer/FilePreview/Viewer.js +2 -2
  154. package/dist/file-explorer/FilePreview/index.js +4 -4
  155. package/dist/file-explorer/FileRow.js +1 -1
  156. package/dist/file-explorer/FileRowsWindow.js +34 -3
  157. package/dist/file-explorer/FileTable.js +3 -1
  158. package/dist/file-explorer/TreeView.js +37 -14
  159. package/dist/file-explorer/helpers.d.ts +2 -1
  160. package/dist/file-explorer/helpers.js +21 -20
  161. package/dist/file-explorer/toasts.js +27 -19
  162. package/dist/file-explorer/treeRows.d.ts +6 -0
  163. package/dist/file-explorer/treeRows.js +19 -1
  164. package/dist/file-explorer/useNearEnd.js +3 -6
  165. package/dist/form/Fields/CheckboxGroupField.js +12 -5
  166. package/dist/form/Fields/DurationField.js +1 -1
  167. package/dist/form/Fields/LabelField.js +1 -1
  168. package/dist/form/Fields/ObjectField.d.ts +1 -1
  169. package/dist/form/Fields/ObjectField.js +3 -2
  170. package/dist/form/Fields/StringField.js +16 -29
  171. package/dist/form/Fields/TextAreaField.js +3 -4
  172. package/dist/form/Form.js +3 -8
  173. package/dist/form/Wizard/WizardNavigation.js +1 -4
  174. package/dist/form/Wizard/WizardStepIndicator.js +1 -1
  175. package/dist/form/Wizard/utils.js +1 -1
  176. package/dist/form/fieldFrame.d.ts +1 -1
  177. package/dist/form/fieldFrame.js +2 -2
  178. package/dist/form/types/fieldComponentTypes.d.ts +2 -1
  179. package/dist/graph/AnnotationBanner.d.ts +1 -2
  180. package/dist/graph/AnnotationBanner.js +30 -32
  181. package/dist/graph/Connectors.js +4 -1
  182. package/dist/graph/DependencyGraph.js +2 -2
  183. package/dist/graph/GraphEditor.js +12 -10
  184. package/dist/graph/GraphEditorDialogs.js +2 -2
  185. package/dist/graph/GraphNode.js +7 -4
  186. package/dist/graph/InputDialog.js +1 -1
  187. package/dist/graph/InputsEditor.js +14 -11
  188. package/dist/graph/MatrixGroup.js +9 -3
  189. package/dist/graph/ProblemsButton.js +2 -2
  190. package/dist/graph/Reveal.js +18 -10
  191. package/dist/graph/ShortcutsButton.d.ts +11 -2
  192. package/dist/graph/ShortcutsButton.js +15 -4
  193. package/dist/graph/TreeView.js +35 -18
  194. package/dist/graph/WorkflowSettingsDialog.js +1 -1
  195. package/dist/graph/editorChrome.js +1 -1
  196. package/dist/graph/editorFields.js +1 -1
  197. package/dist/graph/editorRows.js +16 -10
  198. package/dist/graph/editorStrings.d.ts +7 -0
  199. package/dist/graph/editorStrings.js +8 -1
  200. package/dist/graph/fieldProblems.js +1 -1
  201. package/dist/graph/inputRefs.js +1 -1
  202. package/dist/graph/settingsViews.js +11 -18
  203. package/dist/graph/stepWith.js +2 -2
  204. package/dist/icons.d.ts +2 -0
  205. package/dist/icons.js +4 -2
  206. package/dist/index.d.ts +12 -12
  207. package/dist/index.js +16 -16
  208. package/dist/list/ActionToolbar.d.ts +44 -8
  209. package/dist/list/ActionToolbar.js +301 -102
  210. package/dist/list/ListPage.d.ts +15 -23
  211. package/dist/list/ListPage.js +46 -45
  212. package/dist/list/ListTable.d.ts +32 -7
  213. package/dist/list/ListTable.js +48 -12
  214. package/dist/list/ListViewControls.js +2 -2
  215. package/dist/list/UserHoverCard.js +7 -15
  216. package/dist/list/index.d.ts +2 -2
  217. package/dist/list/index.js +2 -2
  218. package/dist/list/listSearch.js +12 -10
  219. package/dist/list/listView.d.ts +10 -1
  220. package/dist/list/listView.js +15 -1
  221. package/dist/list/rowMenu.d.ts +2 -2
  222. package/dist/logviewer/LogViewer.d.ts +4 -2
  223. package/dist/logviewer/LogViewer.js +88 -70
  224. package/dist/logviewer/logviewer.css +3 -2
  225. package/dist/reducedMotion.d.ts +5 -0
  226. package/dist/reducedMotion.js +20 -0
  227. package/dist/safeUrl.d.ts +1 -1
  228. package/dist/safeUrl.js +4 -2
  229. package/dist/styles/theme.css +24 -10
  230. package/dist/styles.css +1 -1
  231. package/dist/theme/derive.d.ts +1 -1
  232. package/dist/theme/derive.js +46 -21
  233. package/dist/theme/fit.js +10 -4
  234. package/package.json +1 -1
  235. package/dist/components/Breadcrumbs.d.ts +0 -37
  236. package/dist/components/Breadcrumbs.js +0 -90
  237. package/dist/components/CopyToClipboard.d.ts +0 -17
  238. package/dist/components/CopyToClipboard.js +0 -66
  239. package/dist/components/Sort.d.ts +0 -9
  240. package/dist/components/Sort.js +0 -42
@@ -1,77 +1,84 @@
1
1
  import { cx } from "../cx.js";
2
- import { ChevronRightIcon } from "../icons.js";
3
2
  import { buttonClasses } from "./buttonClasses.js";
3
+ import { ChevronRightIcon } from "../icons.js";
4
4
  import { Loader } from "./Loader.js";
5
- import { useLink } from "./Provider.js";
5
+ import { AppLink } from "./AppLink.js";
6
6
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
7
  import { Button } from "@base-ui/react/button";
8
8
  //#region src/components/Button.tsx
9
9
  /** A button in the package's one look (see `buttonClasses`).
10
- * `focusableWhenDisabled` keeps a disabled button's tooltip reachable. A link
11
- * that looks like a button stays a link: give it `buttonClasses()`. */
12
- function Button$1({ variant, size = "md", iconOnly, icon, loading = false, disabled, className, children, ...props }) {
13
- return /* @__PURE__ */ jsxs(Button, {
10
+ * `focusableWhenDisabled` keeps a disabled button's tooltip reachable; a
11
+ * disabled link stays focusable on its own. */
12
+ function Button$1({ variant, size = "md", iconOnly, icon, loading = false, className, children, ...props }) {
13
+ const classes = cx(buttonClasses({
14
+ variant,
15
+ size,
16
+ iconOnly
17
+ }), className);
18
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [loading ? /* @__PURE__ */ jsx(Loader, {
19
+ inline: true,
20
+ decorative: true,
21
+ size: "1em"
22
+ }) : icon, children] });
23
+ if (props.href !== void 0) return /* @__PURE__ */ jsx(AppLink, {
14
24
  ...props,
15
- disabled: disabled || loading,
25
+ disabled: props.disabled || loading,
26
+ "aria-busy": loading || void 0,
27
+ className: classes,
28
+ children: content
29
+ });
30
+ return /* @__PURE__ */ jsx(Button, {
31
+ focusableWhenDisabled: loading || void 0,
32
+ ...props,
33
+ disabled: props.disabled || loading,
16
34
  "aria-busy": loading || void 0,
17
- className: cx(buttonClasses({
18
- variant,
19
- size,
20
- iconOnly
21
- }), className),
22
- children: [loading ? /* @__PURE__ */ jsx(Loader, {
23
- inline: true,
24
- decorative: true,
25
- size: "1em"
26
- }) : icon, children]
35
+ className: classes,
36
+ children: content
27
37
  });
28
38
  }
29
- function MethodButton({ icon, label, description, href, loading, disabled, className = "", ...props }) {
30
- const Link = useLink();
31
- const baseClasses = "flex items-center w-full p-4 bg-[var(--theme-muted-panel-bg)] border border-[var(--theme-border)] rounded-xl text-[var(--theme-app)] text-[0.9375rem] font-medium cursor-pointer transition-all duration-200 no-underline mb-3 last:mb-0 hover:not-disabled:bg-(--theme-border) hover:not-disabled:border-(--theme-muted-text-color) hover:not-disabled:-translate-y-0.5 active:translate-y-0";
32
- const disabledClasses = "disabled:opacity-60 disabled:cursor-not-allowed";
39
+ var methodClasses = "group flex w-full cursor-pointer items-center rounded-xl border border-(--theme-border) bg-(--theme-muted-panel-bg) p-4 text-[0.9375rem] font-medium text-(--theme-app) no-underline transition-[background-color,border-color,translate] duration-200 hover:not-disabled:not-aria-disabled:border-(--theme-muted-text-color) hover:not-disabled:not-aria-disabled:bg-(--theme-border) hover:not-disabled:not-aria-disabled:-translate-y-0.5 active:translate-y-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--theme-link) disabled:cursor-not-allowed disabled:opacity-60 aria-disabled:cursor-not-allowed aria-disabled:opacity-60 motion-reduce:transition-none motion-reduce:hover:translate-y-0";
40
+ /** One way to go on, such as a sign-in method: a large row with an icon, a
41
+ * label and a line under it. A list of them is spaced by its container. */
42
+ function MethodButton({ icon, label, description, href, loading = false, disabled = false, className, ...props }) {
33
43
  const content = /* @__PURE__ */ jsxs(Fragment, { children: [
34
44
  icon && /* @__PURE__ */ jsx("span", {
35
- className: "size-10 rounded-lg bg-gradient-to-br from-[var(--gradient-start,var(--theme-accent))] to-[var(--gradient-mid,var(--theme-link))] flex items-center justify-center shrink-0 mr-4 [&_svg]:size-5 [&_svg]:text-white",
45
+ className: "mr-4 flex size-10 shrink-0 items-center justify-center rounded-lg bg-linear-to-br from-(--gradient-start,var(--theme-accent)) to-(--gradient-mid,var(--theme-link)) [&_svg]:size-5 [&_svg]:text-(--theme-accent-text)",
36
46
  children: icon
37
47
  }),
38
48
  /* @__PURE__ */ jsxs("span", {
39
49
  className: "flex-1 text-left",
40
50
  children: [/* @__PURE__ */ jsx("span", {
41
- className: "block font-semibold text-[var(--theme-app)]",
51
+ className: "block font-semibold",
42
52
  children: label
43
53
  }), description && /* @__PURE__ */ jsx("span", {
44
- className: "block text-[0.8125rem] text-[var(--theme-muted-text-color)] font-normal mt-0.5",
54
+ className: "mt-0.5 block text-[0.8125rem] font-normal text-(--theme-muted-text-color)",
45
55
  children: description
46
56
  })]
47
57
  }),
48
58
  loading ? /* @__PURE__ */ jsx("span", {
49
- className: "ml-2 shrink-0 text-[var(--theme-muted-text-color)]",
59
+ className: "ml-2 shrink-0 text-(--theme-muted-text-color)",
50
60
  children: /* @__PURE__ */ jsx(Loader, {
51
61
  inline: true,
52
62
  decorative: true,
53
63
  size: 20,
54
64
  color: "currentColor"
55
65
  })
56
- }) : /* @__PURE__ */ jsx(ChevronRightIcon, { className: "size-5 text-[var(--theme-muted-text-color)] shrink-0 ml-2 transition-all duration-200 group-hover:translate-x-[3px] group-hover:text-[var(--theme-app)]" })
66
+ }) : /* @__PURE__ */ jsx(ChevronRightIcon, { className: "ml-2 size-5 shrink-0 text-(--theme-muted-text-color) transition-[translate,color] duration-200 group-hover:translate-x-[3px] group-hover:text-(--theme-app) motion-reduce:transition-none motion-reduce:group-hover:translate-x-0 rtl:-scale-x-100" })
57
67
  ] });
58
- if (href) {
59
- if (href.startsWith("/api/") || href.startsWith("http")) return /* @__PURE__ */ jsx("a", {
60
- href,
61
- className: cx("group", baseClasses, className),
62
- children: content
63
- });
64
- return /* @__PURE__ */ jsx(Link, {
65
- href,
66
- className: cx("group", baseClasses, className),
67
- children: content
68
- });
69
- }
68
+ if (href) return /* @__PURE__ */ jsx(AppLink, {
69
+ href,
70
+ reloadDocument: href.startsWith("/api/"),
71
+ disabled: disabled || loading,
72
+ "aria-busy": loading || void 0,
73
+ className: cx(methodClasses, className),
74
+ children: content
75
+ });
70
76
  return /* @__PURE__ */ jsx("button", {
71
77
  type: "button",
72
- className: cx("group", baseClasses, disabledClasses, className),
73
- disabled: disabled || loading,
74
78
  ...props,
79
+ disabled: disabled || loading,
80
+ "aria-busy": loading || void 0,
81
+ className: cx(methodClasses, className),
75
82
  children: content
76
83
  });
77
84
  }
@@ -1,7 +1,31 @@
1
- type CalloutType = 'warning' | 'info' | 'error';
2
- export default function Callout({ type, className, children, }: {
3
- type: CalloutType;
4
- className?: string;
5
- children: React.ReactNode;
6
- }): import("react").JSX.Element;
7
- export {};
1
+ import type { ReactNode } from 'react';
2
+ import { type Tone } from './tone.js';
3
+ /** A callout's tone: `default` for a plain note, or a status. */
4
+ export type CalloutTone = Extract<Tone, 'default' | 'info' | 'success' | 'warning' | 'error'>;
5
+ export interface CalloutProps {
6
+ tone?: CalloutTone | undefined;
7
+ /** A bold first line that says what happened; the children explain it. */
8
+ title?: ReactNode;
9
+ children?: ReactNode;
10
+ /** The one thing the reader can do about it, such as a retry button. */
11
+ action?: ReactNode;
12
+ /** Adds a close button, for a message the reader can put away. */
13
+ onDismiss?: (() => void) | undefined;
14
+ /** Replaces the tone's icon; false shows none. */
15
+ icon?: ReactNode;
16
+ /** `card` is a framed box among the content; `bar` runs the full width under
17
+ * a header, ruled off below, for a condition that holds across the surface. */
18
+ variant?: 'card' | 'bar' | undefined;
19
+ /** `sm` sits beside a compact control, such as a composer. */
20
+ size?: 'sm' | 'md' | undefined;
21
+ /** Announces it as it appears, for a message that arrives after the surface
22
+ * has loaded, such as a failed save. A callout that's there from the start
23
+ * is read in its place, with the content around it. */
24
+ live?: boolean | undefined;
25
+ className?: string | undefined;
26
+ testId?: string | undefined;
27
+ }
28
+ /** A message set into the page in a status's tone: guidance, a warning, an error
29
+ * or a success, and what to do about it. For a passing notice that floats over
30
+ * the page, use `toast`. */
31
+ export declare function Callout({ tone, title, children, action, onDismiss, icon, variant, size, live, className, testId, }: CalloutProps): import("react").JSX.Element;
@@ -1,30 +1,57 @@
1
1
  import { cx } from "../cx.js";
2
- import { InfoIcon, WarningIcon } from "../icons.js";
3
- import { toneSurface } from "./tone.js";
2
+ import { CloseIcon, ErrorIcon, InfoIcon, SuccessIcon, WarningIcon } from "../icons.js";
3
+ import { toneIcon, toneSurface } from "./tone.js";
4
+ import { useStrings } from "./Provider.js";
5
+ import { IconButton } from "./IconButton.js";
4
6
  import { jsx, jsxs } from "react/jsx-runtime";
5
7
  //#region src/components/Callout.tsx
6
- function CalloutIcon({ type }) {
7
- if (type === "warning" || type === "error") return /* @__PURE__ */ jsx(WarningIcon, {
8
- "aria-hidden": "true",
9
- className: "mr-3 h-5 w-5 shrink-0"
10
- });
11
- else return /* @__PURE__ */ jsx(InfoIcon, {
12
- "aria-hidden": "true",
13
- className: "mr-3 h-5 w-5 shrink-0"
14
- });
15
- }
16
- function Callout({ type, className = "", children }) {
17
- return /* @__PURE__ */ jsx("div", {
18
- className: cx(toneSurface[type], "my-4 rounded-xl border px-4 py-3", className),
19
- role: type === "info" ? "note" : "alert",
20
- children: /* @__PURE__ */ jsxs("div", {
21
- className: "flex text-sm",
22
- children: [/* @__PURE__ */ jsx(CalloutIcon, { type }), /* @__PURE__ */ jsx("div", {
23
- className: "min-w-0",
24
- children
25
- })]
26
- })
8
+ var toneIcons = {
9
+ default: InfoIcon,
10
+ info: InfoIcon,
11
+ success: SuccessIcon,
12
+ warning: WarningIcon,
13
+ error: ErrorIcon
14
+ };
15
+ /** A message set into the page in a status's tone: guidance, a warning, an error
16
+ * or a success, and what to do about it. For a passing notice that floats over
17
+ * the page, use `toast`. */
18
+ function Callout({ tone = "info", title, children, action, onDismiss, icon, variant = "card", size = "md", live = false, className, testId }) {
19
+ const { common } = useStrings();
20
+ const small = size === "sm";
21
+ const Icon = toneIcons[tone];
22
+ return /* @__PURE__ */ jsxs("div", {
23
+ "data-testid": testId,
24
+ ...live ? { role: tone === "error" ? "alert" : "status" } : {},
25
+ className: cx("flex items-start", toneSurface[tone], small ? "gap-2 px-3 py-2 text-xs leading-4" : "gap-3 px-4 py-3 text-sm leading-5", variant === "card" ? "rounded-xl border" : "border-0 border-b", className),
26
+ children: [
27
+ icon !== false && /* @__PURE__ */ jsx("span", {
28
+ "aria-hidden": "true",
29
+ className: cx("flex shrink-0 items-center", small ? "h-4 [&_svg]:size-4" : "h-5 [&_svg]:size-5", toneIcon[tone]),
30
+ children: icon ?? /* @__PURE__ */ jsx(Icon, {})
31
+ }),
32
+ /* @__PURE__ */ jsxs("div", {
33
+ className: "min-w-0 flex-1",
34
+ children: [title !== void 0 && /* @__PURE__ */ jsx("p", {
35
+ className: "m-0 font-medium",
36
+ children: title
37
+ }), children !== void 0 && /* @__PURE__ */ jsx("div", {
38
+ className: cx(title !== void 0 && "mt-0.5"),
39
+ children
40
+ })]
41
+ }),
42
+ action !== void 0 && /* @__PURE__ */ jsx("div", {
43
+ className: cx("flex shrink-0 items-center gap-2", small ? "h-4" : "h-5"),
44
+ children: action
45
+ }),
46
+ onDismiss && /* @__PURE__ */ jsx(IconButton, {
47
+ size: "xs",
48
+ icon: /* @__PURE__ */ jsx(CloseIcon, {}),
49
+ label: common.dismiss,
50
+ onClick: onDismiss,
51
+ className: small ? "-my-1 -me-1" : "-my-0.5 -me-1"
52
+ })
53
+ ]
27
54
  });
28
55
  }
29
56
  //#endregion
30
- export { Callout as default };
57
+ export { Callout };
@@ -1,29 +1,34 @@
1
1
  import type { ReactElement, ReactNode } from 'react';
2
+ import { type LinkTarget } from './AppLink.js';
2
3
  declare const sizeClasses: {
3
4
  sm: string;
4
5
  md: string;
5
6
  lg: string;
6
7
  };
7
- export interface CardProps {
8
+ export interface CardProps extends LinkTarget {
8
9
  children: ReactNode;
9
10
  /** Its width and padding: `sm` for a short form, `lg` for a wide one. */
10
11
  size?: keyof typeof sizeClasses | undefined;
11
12
  /** A stronger shadow, for a card standing alone on a page, such as sign-in. */
12
13
  elevated?: boolean | undefined;
13
- /** Renders the card as this element, such as a link or a button, which makes
14
- * the whole card pressable: it lifts on hover and shows focus. */
14
+ /** Renders the card as this element, such as a button, which makes the
15
+ * whole card pressable: it lifts on hover and shows focus. A card that
16
+ * navigates takes `href` instead, which makes it a link the same way. */
15
17
  render?: ReactElement | undefined;
16
18
  className?: string | undefined;
17
19
  }
18
20
  /** A raised surface holding one task, such as a sign-in form or a choice among
19
21
  * a few options. */
20
- export declare function Card({ children, size, elevated, render, className }: CardProps): ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
21
- interface CardHeaderProps {
22
+ export declare function Card({ children, size, elevated, render: renderProp, href, reloadDocument, target, className, }: CardProps): ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
23
+ export interface CardHeaderProps {
22
24
  badge?: ReactNode;
23
25
  title: string;
24
26
  description?: ReactNode;
25
27
  className?: string;
26
28
  align?: 'center' | 'left';
29
+ /** The title's level in the page's outline: 1 for a card that is the page, such
30
+ * as sign-in; 2 or 3 for a card among others under the page's own title. */
31
+ headingLevel?: 1 | 2 | 3 | undefined;
27
32
  }
28
- export declare function CardHeader({ badge, title, description, className, align, }: CardHeaderProps): import("react").JSX.Element;
33
+ export declare function CardHeader({ badge, title, description, className, align, headingLevel, }: CardHeaderProps): import("react").JSX.Element;
29
34
  export {};
@@ -1,4 +1,5 @@
1
1
  import { cx } from "../cx.js";
2
+ import { AppLink } from "./AppLink.js";
2
3
  import { jsx, jsxs } from "react/jsx-runtime";
3
4
  import { useRender } from "@base-ui/react/use-render";
4
5
  //#region src/components/Card.tsx
@@ -9,30 +10,35 @@ var sizeClasses = {
9
10
  };
10
11
  /** A raised surface holding one task, such as a sign-in form or a choice among
11
12
  * a few options. */
12
- function Card({ children, size = "md", elevated = false, render, className }) {
13
+ function Card({ children, size = "md", elevated = false, render: renderProp, href, reloadDocument, target, className }) {
14
+ const render = href === void 0 ? renderProp : /* @__PURE__ */ jsx(AppLink, {
15
+ href,
16
+ reloadDocument,
17
+ target
18
+ });
13
19
  return useRender({
14
20
  render: render ?? /* @__PURE__ */ jsx("div", {}),
15
21
  props: {
16
- className: cx("block w-full rounded-2xl border border-(--theme-border) bg-(--theme-panel-bg) backdrop-blur-xl", elevated ? "shadow-(--theme-shadow-xl)" : "shadow-(--theme-shadow)", sizeClasses[size], render && "cursor-pointer text-left transition-[background-color,box-shadow] duration-150 hover:bg-(--theme-panel-hover) hover:shadow-(--theme-shadow-lg) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--theme-link) motion-reduce:transition-none", className),
22
+ className: cx("block w-full rounded-2xl border border-(--theme-border) bg-(--theme-panel-bg) backdrop-blur-xl", elevated ? "shadow-(--theme-shadow-xl)" : "shadow-(--theme-shadow)", sizeClasses[size], render && "cursor-pointer text-left text-inherit no-underline transition-[background-color,box-shadow] duration-150 hover:bg-(--theme-panel-hover) hover:shadow-(--theme-shadow-lg) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--theme-link) motion-reduce:transition-none", className),
17
23
  children
18
24
  }
19
25
  });
20
26
  }
21
- function CardHeader({ badge, title, description, className = "", align = "center" }) {
27
+ function CardHeader({ badge, title, description, className = "", align = "center", headingLevel = 1 }) {
28
+ const Heading = `h${headingLevel}`;
22
29
  return /* @__PURE__ */ jsxs("div", {
23
30
  className: cx(align === "center" ? "text-center" : "text-left", "mb-6", className),
24
31
  children: [
25
32
  badge && /* @__PURE__ */ jsx("div", {
26
- className: "inline-flex items-center gap-1.5 py-1.5 px-3 text-xs font-medium bg-[var(--theme-muted-panel-bg)] border border-[var(--theme-border)] rounded-full text-[var(--theme-muted-text-color)] mb-4 transition-colors duration-200",
33
+ className: "mb-4 inline-flex items-center gap-1.5 rounded-full border border-(--theme-border) bg-(--theme-muted-panel-bg) px-3 py-1.5 text-xs font-medium text-(--theme-muted-text-color)",
27
34
  children: badge
28
35
  }),
29
- /* @__PURE__ */ jsx("h1", {
30
- className: "text-2xl font-bold tracking-tight text-[var(--theme-app)]",
31
- style: { letterSpacing: "-0.025em" },
36
+ /* @__PURE__ */ jsx(Heading, {
37
+ className: "text-2xl font-bold tracking-tight text-(--theme-app)",
32
38
  children: title
33
39
  }),
34
40
  description && /* @__PURE__ */ jsx("p", {
35
- className: "text-[var(--theme-muted-text-color)] text-sm leading-relaxed mt-2",
41
+ className: "mt-2 text-sm leading-relaxed text-(--theme-muted-text-color)",
36
42
  children: description
37
43
  })
38
44
  ]
@@ -1,5 +1,6 @@
1
1
  import { cx } from "../cx.js";
2
2
  import { CheckIcon, MinusIcon } from "../icons.js";
3
+ import { focusOutline } from "./fieldBox.js";
3
4
  import { jsx } from "react/jsx-runtime";
4
5
  import { Checkbox } from "@base-ui/react/checkbox";
5
6
  import { CheckboxGroup } from "@base-ui/react/checkbox-group";
@@ -10,7 +11,7 @@ import { CheckboxGroup } from "@base-ui/react/checkbox-group";
10
11
  function Checkbox$1({ className, ...props }) {
11
12
  return /* @__PURE__ */ jsx(Checkbox.Root, {
12
13
  ...props,
13
- className: cx("flex size-4 shrink-0 items-center justify-center rounded border border-(--theme-border) bg-(--theme-input-bg) text-(--theme-accent-text) cursor-pointer outline-none transition-colors", "data-checked:border-(--theme-accent) data-checked:bg-(--theme-accent)", "data-indeterminate:border-(--theme-accent) data-indeterminate:bg-(--theme-accent)", "focus-visible:ring-2 focus-visible:ring-(--theme-focus-ring) aria-invalid:border-(--theme-error)", "data-disabled:cursor-not-allowed data-disabled:opacity-50", className),
14
+ className: cx("flex size-4 shrink-0 items-center justify-center rounded border border-(--theme-border-strong) bg-(--theme-input-bg) text-(--theme-accent-text) cursor-pointer transition-colors motion-reduce:transition-none", focusOutline, "data-checked:border-(--theme-accent) data-checked:bg-(--theme-accent)", "data-indeterminate:border-(--theme-accent) data-indeterminate:bg-(--theme-accent)", "aria-invalid:border-(--theme-error)", "data-disabled:cursor-not-allowed data-disabled:opacity-50", className),
14
15
  children: /* @__PURE__ */ jsx(Checkbox.Indicator, {
15
16
  className: "flex",
16
17
  render: (indicatorProps, state) => /* @__PURE__ */ jsx("span", {
@@ -1,11 +1,12 @@
1
1
  import { cx } from "../cx.js";
2
2
  import { useStrings } from "./Provider.js";
3
+ import { fieldBox } from "./fieldBox.js";
3
4
  import { parseColor, toHex } from "../theme/color.js";
4
5
  import { ErrorText } from "./Field.js";
5
- import { fieldBox } from "./fieldBox.js";
6
6
  import { framed } from "./Input.js";
7
7
  import { jsx, jsxs } from "react/jsx-runtime";
8
8
  import { useId, useState } from "react";
9
+ import { Input } from "@base-ui/react/input";
9
10
  //#region src/components/ColorInput.tsx
10
11
  var swatchClassName = cx("shrink-0 cursor-pointer p-0.5", "[&::-webkit-color-swatch-wrapper]:p-0 [&::-webkit-color-swatch]:rounded [&::-webkit-color-swatch]:border-0", "[&::-moz-color-swatch]:rounded [&::-moz-color-swatch]:border-0");
11
12
  /**
@@ -25,7 +26,8 @@ function ColorInput({ value, onValueChange, label, hint, description, error, siz
25
26
  label,
26
27
  hint,
27
28
  description,
28
- error: error ?? (unparsed ? t.invalid : void 0)
29
+ error: error ?? (unparsed ? t.invalid : void 0),
30
+ size
29
31
  }, {
30
32
  id,
31
33
  required,
@@ -44,7 +46,7 @@ function ColorInput({ value, onValueChange, label, hint, description, error, siz
44
46
  onValueChange(e.target.value);
45
47
  },
46
48
  className: cx(fieldBox({ size }), swatchClassName, size === "sm" ? "w-8" : "w-10")
47
- }), /* @__PURE__ */ jsx("input", {
49
+ }), /* @__PURE__ */ jsx(Input, {
48
50
  id,
49
51
  name,
50
52
  "aria-label": ariaLabel,
@@ -1,17 +1,17 @@
1
1
  import { cx } from "../cx.js";
2
2
  import { AddIcon, CheckIcon, ChevronDownIcon, RemoveIcon } from "../icons.js";
3
- import { panelClassName, panelItemClassName, positionerClassName } from "./floating.js";
3
+ import { panelClassName, positionerClassName } from "./floating.js";
4
4
  import { Tooltip } from "./Tooltip.js";
5
5
  import { useStrings } from "./Provider.js";
6
6
  import { useQueryMatch } from "./search.js";
7
7
  import { fieldBox } from "./fieldBox.js";
8
- import { isComboboxGroup } from "./comboboxItems.js";
8
+ import { isComboboxGroup, pickerItemClassName } from "./comboboxItems.js";
9
9
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
- import { useCallback, useImperativeHandle, useMemo, useRef, useState } from "react";
10
+ import { useCallback, useId, useImperativeHandle, useMemo, useRef, useState } from "react";
11
+ import { dequal } from "dequal";
11
12
  import { Combobox } from "@base-ui/react/combobox";
12
13
  import { Autocomplete } from "@base-ui/react/autocomplete";
13
14
  import { useVirtualizer } from "@tanstack/react-virtual";
14
- import { dequal } from "dequal";
15
15
  //#region src/components/Combobox.tsx
16
16
  function toEntry(item, group) {
17
17
  const entry = typeof item === "string" ? {
@@ -82,9 +82,9 @@ function Combobox$1(props) {
82
82
  const { items, isItemEqualToValue = dequal, itemToStringLabel = String, className, placeholder, disabled, required, id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid, "aria-required": ariaRequired, trigger, triggerTooltip, size = "md" } = props;
83
83
  const entries = useEntries(items);
84
84
  const filter = useEntryFilter();
85
- const strings = useStrings();
86
- const t = strings.dropdown;
85
+ const t = useStrings().dropdown;
87
86
  const list = useRef(null);
87
+ const uid = useId();
88
88
  const [inputValue, setInputValue] = useState(null);
89
89
  const entryOf = (value) => entries.flat.find((entry) => isItemEqualToValue(entry.value, value)) ?? {
90
90
  value,
@@ -129,10 +129,17 @@ function Combobox$1(props) {
129
129
  value: entry,
130
130
  disabled: entry.disabled || full && !isChosen(entry),
131
131
  ...rowProps.props,
132
- className: itemClassName,
133
- children: [/* @__PURE__ */ jsx(ItemContent, { entry }), /* @__PURE__ */ jsx(Combobox.ItemIndicator, {
132
+ ...optionNaming(uid, rowProps.props.index, entry),
133
+ className: pickerItemClassName,
134
+ children: [/* @__PURE__ */ jsx(ItemContent, {
135
+ entry,
136
+ id: `${uid}${rowProps.props.index}`
137
+ }), /* @__PURE__ */ jsx(Combobox.ItemIndicator, {
134
138
  className: "ml-auto flex shrink-0 items-center",
135
- children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-3.5" })
139
+ children: /* @__PURE__ */ jsx(CheckIcon, {
140
+ "aria-hidden": "true",
141
+ className: "size-3.5"
142
+ })
136
143
  })]
137
144
  }, rowProps.key);
138
145
  const parts = trigger ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Tooltip, {
@@ -162,15 +169,18 @@ function Combobox$1(props) {
162
169
  className: cx(fieldClassName(size), className),
163
170
  children: [props.multiple ? /* @__PURE__ */ jsxs(Combobox.Chips, {
164
171
  className: cx("flex min-w-0 flex-1 flex-wrap items-center gap-1 pl-1", size === "sm" ? "py-0.5" : "py-1"),
165
- children: [/* @__PURE__ */ jsx(Combobox.Value, { children: (values) => values.map((entry) => /* @__PURE__ */ jsxs(Combobox.Chip, {
172
+ children: [/* @__PURE__ */ jsx(Combobox.Value, { children: (values) => values.map((entry, index) => /* @__PURE__ */ jsxs(Combobox.Chip, {
166
173
  "aria-label": entry.label,
167
174
  className: "flex items-center gap-1 rounded bg-(--theme-muted-panel-bg) py-0.5 pr-0.5 pl-1.5 text-xs outline-none data-highlighted:bg-(--theme-hover)",
168
175
  children: [entry.label, /* @__PURE__ */ jsx(Combobox.ChipRemove, {
169
- "aria-label": `${strings.common.remove} ${entry.label}`,
176
+ "aria-label": t.removeValue(entry.label),
170
177
  className: "flex size-4 items-center justify-center rounded hover:bg-(--theme-hover)",
171
- children: /* @__PURE__ */ jsx(RemoveIcon, { className: "size-3" })
178
+ children: /* @__PURE__ */ jsx(RemoveIcon, {
179
+ "aria-hidden": "true",
180
+ className: "size-3"
181
+ })
172
182
  })]
173
- }, entry.label)) }), input]
183
+ }, `${index}:${entry.label}`)) }), input]
174
184
  }) : /* @__PURE__ */ jsxs(Fragment, { children: [selectedIcon && /* @__PURE__ */ jsx("span", {
175
185
  className: cx("flex shrink-0 items-center", size === "sm" ? "pl-2" : "pl-3"),
176
186
  children: selectedIcon
@@ -178,7 +188,10 @@ function Combobox$1(props) {
178
188
  "aria-label": t.showOptions,
179
189
  "data-testid": "combobox-button",
180
190
  className: triggerClassName,
181
- children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-3" })
191
+ children: /* @__PURE__ */ jsx(ChevronDownIcon, {
192
+ "aria-hidden": "true",
193
+ className: "size-3"
194
+ })
182
195
  })]
183
196
  }), /* @__PURE__ */ jsx(ListPopup, {
184
197
  listRef: list,
@@ -222,6 +235,7 @@ function Autocomplete$1({ items, value, defaultValue, onValueChange, className,
222
235
  const filter = useEntryFilter();
223
236
  const t = useStrings().dropdown;
224
237
  const list = useRef(null);
238
+ const uid = useId();
225
239
  return /* @__PURE__ */ jsxs(Autocomplete.Root, {
226
240
  items: entries.items,
227
241
  filter,
@@ -250,7 +264,10 @@ function Autocomplete$1({ items, value, defaultValue, onValueChange, className,
250
264
  "aria-label": t.showOptions,
251
265
  "data-testid": "combobox-button",
252
266
  className: triggerClassName,
253
- children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-3" })
267
+ children: /* @__PURE__ */ jsx(ChevronDownIcon, {
268
+ "aria-hidden": "true",
269
+ className: "size-3"
270
+ })
254
271
  })]
255
272
  }), /* @__PURE__ */ jsx(ListPopup, {
256
273
  listRef: list,
@@ -258,14 +275,25 @@ function Autocomplete$1({ items, value, defaultValue, onValueChange, className,
258
275
  value: entry,
259
276
  disabled: entry.disabled,
260
277
  ...rowProps.props,
261
- className: itemClassName,
262
- children: /* @__PURE__ */ jsx(ItemContent, { entry })
278
+ ...optionNaming(uid, rowProps.props.index, entry),
279
+ className: pickerItemClassName,
280
+ children: /* @__PURE__ */ jsx(ItemContent, {
281
+ entry,
282
+ id: `${uid}${rowProps.props.index}`
283
+ })
263
284
  }, rowProps.key)
264
285
  })]
265
286
  });
266
287
  }
267
- var itemClassName = cx(panelItemClassName, "data-selected:font-medium");
268
- function ItemContent({ entry }) {
288
+ /** An option is named by its label, with its description read after it rather than as part of
289
+ * its name. */
290
+ function optionNaming(uid, index, entry) {
291
+ return {
292
+ "aria-labelledby": `${uid}${index}label`,
293
+ "aria-describedby": entry.description ? `${uid}${index}description` : void 0
294
+ };
295
+ }
296
+ function ItemContent({ entry, id }) {
269
297
  return /* @__PURE__ */ jsxs(Fragment, { children: [entry.icon && /* @__PURE__ */ jsx("span", {
270
298
  className: "flex shrink-0 items-center",
271
299
  children: entry.icon
@@ -275,10 +303,12 @@ function ItemContent({ entry }) {
275
303
  content: entry.label,
276
304
  overflowOnly: true,
277
305
  children: /* @__PURE__ */ jsx("span", {
306
+ id: `${id}label`,
278
307
  className: "truncate",
279
308
  children: entry.label
280
309
  })
281
310
  }), entry.description && /* @__PURE__ */ jsx("span", {
311
+ id: `${id}description`,
282
312
  className: "text-xs leading-snug text-(--theme-muted-text-color)",
283
313
  children: entry.description
284
314
  })]
@@ -1,17 +1,28 @@
1
1
  import type { ReactNode } from 'react';
2
- export declare function ConfirmModal({ open, onClose, title, description, children, confirmLabel, onConfirm, confirmDisabled, destructive, align, cancelLabel, closeOnConfirm, }: {
2
+ export interface ConfirmModalProps {
3
3
  open: boolean;
4
4
  onClose: () => void;
5
+ /** The question, which names the dialog: "Delete cluster?" */
5
6
  title: string;
7
+ /** What follows from confirming, which describes the dialog. */
6
8
  description?: ReactNode;
9
+ /** More to read or to choose before confirming, such as a field. */
7
10
  children?: ReactNode;
11
+ /** The verb that confirms, such as "Delete"; never "OK". */
8
12
  confirmLabel: string;
9
- /** An async handler keeps both buttons disabled until it settles. */
13
+ /** An async handler keeps both buttons disabled until it settles. One that
14
+ * rejects leaves the dialog open and rethrows, so report the error in the
15
+ * handler, such as with a toast. */
10
16
  onConfirm: () => void | Promise<unknown>;
11
- confirmDisabled?: boolean;
12
- destructive?: boolean;
13
- align?: 'top' | 'center';
14
- cancelLabel?: string;
17
+ confirmDisabled?: boolean | undefined;
18
+ /** An action that can't be undone: the confirm button reads as dangerous, and
19
+ * the dialog is an alertdialog that waits for an answer. */
20
+ destructive?: boolean | undefined;
21
+ align?: 'top' | 'center' | undefined;
22
+ cancelLabel?: string | undefined;
15
23
  /** When false, the dialog stays open after a successful confirm. */
16
- closeOnConfirm?: boolean;
17
- }): import("react").JSX.Element;
24
+ closeOnConfirm?: boolean | undefined;
25
+ }
26
+ /** Asks before an action: its title the question, its description what follows,
27
+ * and Cancel beside a confirm button named for the action. */
28
+ export declare function ConfirmModal({ open, onClose, title, description, children, confirmLabel, onConfirm, confirmDisabled, destructive, align, cancelLabel, closeOnConfirm, }: ConfirmModalProps): import("react").JSX.Element;