@parallelworks/ui 0.40.1 → 0.42.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 (289) hide show
  1. package/README.md +25 -0
  2. package/dist/ai/adapter/memoryStore.js +7 -0
  3. package/dist/ai/adapter/mock/mockAdapter.js +52 -17
  4. package/dist/ai/adapter/openai/createOpenAIStream.js +1 -1
  5. package/dist/ai/adapter/openai/index.d.ts +1 -1
  6. package/dist/ai/adapter/openai/sse.d.ts +8 -2
  7. package/dist/ai/adapter/openai/sse.js +40 -4
  8. package/dist/ai/adapter/openai/wire.d.ts +6 -0
  9. package/dist/ai/components/AllocationSelector.d.ts +3 -4
  10. package/dist/ai/components/AllocationSelector.js +37 -33
  11. package/dist/ai/components/AttachmentManager.js +7 -7
  12. package/dist/ai/components/AttachmentUpload.js +5 -5
  13. package/dist/ai/components/BranchNavigator.js +1 -1
  14. package/dist/ai/components/ChatEmptyState.js +2 -2
  15. package/dist/ai/components/ChatInput.js +10 -8
  16. package/dist/ai/components/ChatLayout.js +4 -5
  17. package/dist/ai/components/ChatMessage.js +12 -12
  18. package/dist/ai/components/ChatMessageList.js +9 -9
  19. package/dist/ai/components/ChatSidebar.js +8 -9
  20. package/dist/ai/components/ChatThread.js +4 -4
  21. package/dist/ai/components/ComposerChrome.d.ts +2 -2
  22. package/dist/ai/components/ComposerChrome.js +3 -6
  23. package/dist/ai/components/DragOverlay.js +2 -2
  24. package/dist/ai/components/ModelSelector.d.ts +5 -3
  25. package/dist/ai/components/ModelSelector.js +102 -339
  26. package/dist/ai/components/PastedText.js +11 -11
  27. package/dist/ai/components/ProviderIssueBanner.d.ts +2 -0
  28. package/dist/ai/components/ProviderIssueBanner.js +34 -16
  29. package/dist/ai/components/Reasoning.js +4 -4
  30. package/dist/ai/components/ShareDialog.js +43 -35
  31. package/dist/ai/components/SlashMenu.d.ts +12 -2
  32. package/dist/ai/components/SlashMenu.js +29 -13
  33. package/dist/ai/components/agent/ActivityLine.js +3 -3
  34. package/dist/ai/components/agent/AgentMessageParts.js +20 -20
  35. package/dist/ai/components/agent/PermissionPicker.js +13 -11
  36. package/dist/ai/components/conversationActions.d.ts +4 -6
  37. package/dist/ai/components/conversationActions.js +9 -13
  38. package/dist/ai/core/ChatProvider.js +4 -4
  39. package/dist/ai/core/config.js +1 -1
  40. package/dist/ai/core/parts.d.ts +5 -0
  41. package/dist/ai/core/parts.js +28 -1
  42. package/dist/ai/core/providerIssues.d.ts +7 -0
  43. package/dist/ai/core/providerIssues.js +9 -1
  44. package/dist/ai/core/useKeyboardShortcuts.d.ts +4 -0
  45. package/dist/ai/core/useKeyboardShortcuts.js +8 -2
  46. package/dist/ai/index.d.ts +0 -1
  47. package/dist/ai/index.js +1 -2
  48. package/dist/ai/strings.d.ts +19 -0
  49. package/dist/ai/strings.js +18 -1
  50. package/dist/ai/ui/Avatar.js +5 -5
  51. package/dist/ai/ui/ConversationSidebar.d.ts +0 -1
  52. package/dist/ai/ui/ConversationSidebar.js +6 -7
  53. package/dist/ai/ui/Markdown.js +3 -3
  54. package/dist/ai/ui/Notice.js +6 -6
  55. package/dist/ai/ui/chip.d.ts +4 -0
  56. package/dist/ai/ui/chip.js +8 -0
  57. package/dist/ai/ui/sidebar.d.ts +6 -5
  58. package/dist/ai/ui/sidebar.js +39 -43
  59. package/dist/components/ActionMenu.d.ts +13 -0
  60. package/dist/components/ActionMenu.js +30 -0
  61. package/dist/components/Avatar.js +6 -6
  62. package/dist/components/Breadcrumbs.js +1 -1
  63. package/dist/components/Button.js +10 -10
  64. package/dist/components/Callout.js +2 -2
  65. package/dist/components/Card.js +3 -3
  66. package/dist/components/Combobox.d.ts +66 -0
  67. package/dist/components/Combobox.js +393 -0
  68. package/dist/components/ConfirmModal.js +11 -11
  69. package/dist/components/ContextMenu.d.ts +23 -0
  70. package/dist/components/ContextMenu.js +89 -0
  71. package/dist/components/CopyToClipboard.js +2 -2
  72. package/dist/components/CreateModal.d.ts +17 -36
  73. package/dist/components/CreateModal.js +97 -259
  74. package/dist/components/DescriptionList.js +8 -8
  75. package/dist/components/Filter.js +2 -2
  76. package/dist/components/FilterPill.js +2 -2
  77. package/dist/components/HoverCard.d.ts +14 -0
  78. package/dist/components/HoverCard.js +33 -0
  79. package/dist/components/IconButton.d.ts +5 -5
  80. package/dist/components/IconButton.js +18 -22
  81. package/dist/components/InfoTip.d.ts +15 -0
  82. package/dist/components/InfoTip.js +60 -0
  83. package/dist/components/Input.js +5 -5
  84. package/dist/components/LetterBadge.js +2 -2
  85. package/dist/components/Loader.js +3 -3
  86. package/dist/components/Markdown.js +1 -1
  87. package/dist/components/MarkdownImpl.js +2 -2
  88. package/dist/components/Menu.d.ts +33 -0
  89. package/dist/components/Menu.js +86 -0
  90. package/dist/components/MenuEntries.d.ts +56 -0
  91. package/dist/components/MenuEntries.js +123 -0
  92. package/dist/components/Modal.d.ts +29 -0
  93. package/dist/components/Modal.js +47 -0
  94. package/dist/components/Overview.js +11 -10
  95. package/dist/components/PageHeader.d.ts +10 -16
  96. package/dist/components/PageHeader.js +69 -95
  97. package/dist/components/Pagination.js +5 -5
  98. package/dist/components/Provider.d.ts +5 -11
  99. package/dist/components/Provider.js +11 -14
  100. package/dist/components/Radio.d.ts +8 -0
  101. package/dist/components/Radio.js +16 -0
  102. package/dist/components/SectionHeader.js +2 -2
  103. package/dist/components/SegmentedControl.d.ts +6 -5
  104. package/dist/components/SegmentedControl.js +34 -30
  105. package/dist/components/Select.d.ts +27 -0
  106. package/dist/components/Select.js +78 -0
  107. package/dist/components/SettingModeOption.d.ts +5 -8
  108. package/dist/components/SettingModeOption.js +10 -12
  109. package/dist/components/SettingRow.js +4 -4
  110. package/dist/components/SettingsCard.js +4 -4
  111. package/dist/components/SettingsGroup.js +2 -2
  112. package/dist/components/Sort.js +1 -1
  113. package/dist/components/StatusBadge.js +7 -7
  114. package/dist/components/StatusIcons.js +4 -4
  115. package/dist/components/Switch.d.ts +22 -0
  116. package/dist/components/Switch.js +28 -0
  117. package/dist/components/Table.js +11 -11
  118. package/dist/components/Tooltip.d.ts +24 -20
  119. package/dist/components/Tooltip.js +58 -76
  120. package/dist/components/floating.d.ts +14 -0
  121. package/dist/components/floating.js +21 -0
  122. package/dist/components/search.d.ts +2 -0
  123. package/dist/components/search.js +14 -0
  124. package/dist/editor/Editor.js +1 -1
  125. package/dist/editor/EditorField.js +16 -21
  126. package/dist/editor/FormCodePanel.js +19 -19
  127. package/dist/editor/Monaco.js +3 -3
  128. package/dist/file-explorer/FileExplorer.js +77 -81
  129. package/dist/file-explorer/FileExplorerContext.js +2 -2
  130. package/dist/file-explorer/FilePreview/CodePreviewEditor.js +1 -1
  131. package/dist/file-explorer/FilePreview/Inline.js +1 -1
  132. package/dist/file-explorer/FilePreview/StreamedBadge.js +5 -6
  133. package/dist/file-explorer/FilePreview/Viewer.js +8 -8
  134. package/dist/file-explorer/FilePreview/index.d.ts +1 -1
  135. package/dist/file-explorer/FilePreview/index.js +49 -83
  136. package/dist/file-explorer/FileRow.d.ts +4 -3
  137. package/dist/file-explorer/FileRow.js +32 -38
  138. package/dist/file-explorer/FileRowsWindow.d.ts +3 -2
  139. package/dist/file-explorer/FileRowsWindow.js +4 -4
  140. package/dist/file-explorer/FileTable.d.ts +3 -2
  141. package/dist/file-explorer/FileTable.js +3 -3
  142. package/dist/file-explorer/LoadMoreRow.js +1 -1
  143. package/dist/file-explorer/TreeView.js +11 -16
  144. package/dist/file-explorer/helpers.js +11 -12
  145. package/dist/file-explorer/toasts.js +11 -11
  146. package/dist/form/FieldGroup.d.ts +11 -0
  147. package/dist/form/FieldGroup.js +36 -0
  148. package/dist/form/FieldWrapper.js +4 -4
  149. package/dist/form/Fields/BooleanField.js +23 -33
  150. package/dist/form/Fields/CheckboxGroupField.d.ts +1 -1
  151. package/dist/form/Fields/CheckboxGroupField.js +9 -13
  152. package/dist/form/Fields/ColorField.d.ts +1 -2
  153. package/dist/form/Fields/ColorField.js +6 -11
  154. package/dist/form/Fields/DropdownField.d.ts +3 -13
  155. package/dist/form/Fields/DropdownField.js +40 -27
  156. package/dist/form/Fields/DurationField.d.ts +1 -2
  157. package/dist/form/Fields/DurationField.js +25 -32
  158. package/dist/form/Fields/LabelField.js +2 -2
  159. package/dist/form/Fields/MultiDropdownField.d.ts +6 -12
  160. package/dist/form/Fields/MultiDropdownField.js +31 -22
  161. package/dist/form/Fields/NumberField.d.ts +1 -1
  162. package/dist/form/Fields/NumberField.js +65 -35
  163. package/dist/form/Fields/ObjectField.d.ts +1 -1
  164. package/dist/form/Fields/ObjectField.js +12 -43
  165. package/dist/form/Fields/RadioField.d.ts +1 -1
  166. package/dist/form/Fields/RadioField.js +30 -41
  167. package/dist/form/Fields/RangeField.d.ts +1 -2
  168. package/dist/form/Fields/RangeField.js +23 -16
  169. package/dist/form/Fields/StringField.d.ts +1 -2
  170. package/dist/form/Fields/StringField.js +58 -26
  171. package/dist/form/Fields/TextAreaField.js +12 -10
  172. package/dist/form/Form.d.ts +30 -48
  173. package/dist/form/Form.js +306 -412
  174. package/dist/form/FormLayout.js +9 -9
  175. package/dist/form/Wizard/WizardContainer.d.ts +1 -4
  176. package/dist/form/Wizard/WizardContainer.js +40 -56
  177. package/dist/form/Wizard/WizardNavigation.js +1 -1
  178. package/dist/form/Wizard/WizardStepContent.d.ts +1 -5
  179. package/dist/form/Wizard/WizardStepContent.js +11 -16
  180. package/dist/form/Wizard/WizardStepIndicator.js +6 -6
  181. package/dist/form/Wizard/types.d.ts +0 -14
  182. package/dist/form/fieldRegistry.d.ts +1 -1
  183. package/dist/form/fieldRegistry.js +6 -6
  184. package/dist/form/formEditing.js +1 -1
  185. package/dist/form/index.d.ts +5 -4
  186. package/dist/form/index.js +6 -7
  187. package/dist/form/types/fieldComponentTypes.d.ts +8 -10
  188. package/dist/form/useChoiceField.d.ts +20 -0
  189. package/dist/form/useChoiceField.js +49 -0
  190. package/dist/form/useFieldValue.d.ts +7 -0
  191. package/dist/form/useFieldValue.js +20 -0
  192. package/dist/form/useParsedOpts.d.ts +3 -1
  193. package/dist/form/useParsedOpts.js +12 -17
  194. package/dist/form/utils/dependentOptions.d.ts +8 -4
  195. package/dist/form/utils/dependentOptions.js +25 -17
  196. package/dist/form/utils/fieldItems.d.ts +10 -0
  197. package/dist/form/utils/fieldItems.js +11 -0
  198. package/dist/form/utils/fieldPath.d.ts +10 -0
  199. package/dist/form/utils/fieldPath.js +20 -0
  200. package/dist/form/utils/shareEqual.d.ts +6 -0
  201. package/dist/form/utils/shareEqual.js +38 -0
  202. package/dist/graph/AnnotationBanner.js +8 -8
  203. package/dist/graph/Collapse.d.ts +1 -0
  204. package/dist/graph/Collapse.js +6 -27
  205. package/dist/graph/Connectors.js +5 -5
  206. package/dist/graph/DependencyGraph.js +20 -19
  207. package/dist/graph/GraphEditor.js +30 -41
  208. package/dist/graph/GraphEditorDialogs.js +17 -17
  209. package/dist/graph/GraphNode.js +1 -1
  210. package/dist/graph/InputDialog.js +19 -22
  211. package/dist/graph/InputsEditor.js +58 -66
  212. package/dist/graph/JobSummary.js +42 -39
  213. package/dist/graph/MatrixGroup.js +1 -1
  214. package/dist/graph/ProblemsButton.js +18 -19
  215. package/dist/graph/Reveal.js +1 -1
  216. package/dist/graph/ShortcutsButton.js +15 -18
  217. package/dist/graph/SuggestionInput.d.ts +5 -10
  218. package/dist/graph/SuggestionInput.js +14 -18
  219. package/dist/graph/ToolbarPopover.d.ts +11 -6
  220. package/dist/graph/ToolbarPopover.js +35 -67
  221. package/dist/graph/TreeView.js +24 -37
  222. package/dist/graph/WorkflowSettingsDialog.js +4 -4
  223. package/dist/graph/editorChrome.js +13 -12
  224. package/dist/graph/editorFields.js +29 -29
  225. package/dist/graph/editorPrimitives.d.ts +1 -1
  226. package/dist/graph/editorPrimitives.js +10 -7
  227. package/dist/graph/editorRows.js +103 -97
  228. package/dist/graph/fieldProblems.js +2 -2
  229. package/dist/graph/graphEditorState.d.ts +4 -3
  230. package/dist/graph/inputRefs.js +9 -9
  231. package/dist/graph/settingsViews.js +6 -7
  232. package/dist/graph/stepWith.js +6 -6
  233. package/dist/index.d.ts +14 -15
  234. package/dist/index.js +15 -14
  235. package/dist/list/ActionToolbar.d.ts +6 -14
  236. package/dist/list/ActionToolbar.js +48 -96
  237. package/dist/list/ListPage.d.ts +6 -12
  238. package/dist/list/ListPage.js +46 -29
  239. package/dist/list/ListPager.js +4 -4
  240. package/dist/list/ListTable.js +5 -5
  241. package/dist/list/ListViewControls.d.ts +5 -4
  242. package/dist/list/ListViewControls.js +177 -267
  243. package/dist/list/UserHoverCard.d.ts +3 -17
  244. package/dist/list/UserHoverCard.js +21 -45
  245. package/dist/list/index.d.ts +3 -4
  246. package/dist/list/index.js +3 -4
  247. package/dist/list/listSearch.js +12 -11
  248. package/dist/list/rowMenu.d.ts +63 -0
  249. package/dist/list/rowMenu.js +134 -0
  250. package/dist/logviewer/LogViewer.js +26 -26
  251. package/dist/styles.css +1 -1
  252. package/package.json +7 -13
  253. package/dist/ai/ui/Dropdown.d.ts +0 -31
  254. package/dist/ai/ui/Dropdown.js +0 -110
  255. package/dist/components/AddMenu.d.ts +0 -18
  256. package/dist/components/AddMenu.js +0 -46
  257. package/dist/components/BareModal.d.ts +0 -17
  258. package/dist/components/BareModal.js +0 -77
  259. package/dist/components/CollapsiblePanel.d.ts +0 -27
  260. package/dist/components/CollapsiblePanel.js +0 -77
  261. package/dist/components/Dropdown.d.ts +0 -28
  262. package/dist/components/Dropdown.js +0 -355
  263. package/dist/components/Listbox.d.ts +0 -21
  264. package/dist/components/Listbox.js +0 -119
  265. package/dist/components/MultiSelect.d.ts +0 -22
  266. package/dist/components/MultiSelect.js +0 -168
  267. package/dist/components/SwitchToggle.d.ts +0 -15
  268. package/dist/components/SwitchToggle.js +0 -57
  269. package/dist/components/SwitchToggleSmall.d.ts +0 -6
  270. package/dist/components/SwitchToggleSmall.js +0 -14
  271. package/dist/components/Toggle.d.ts +0 -6
  272. package/dist/components/Toggle.js +0 -20
  273. package/dist/components/dropdownUtils.d.ts +0 -37
  274. package/dist/components/dropdownUtils.js +0 -99
  275. package/dist/form/SpecialTypes/DropdownWrapper.d.ts +0 -25
  276. package/dist/form/SpecialTypes/DropdownWrapper.js +0 -28
  277. package/dist/form/SpecialTypes/FormikCustomDropdown.d.ts +0 -51
  278. package/dist/form/SpecialTypes/FormikCustomDropdown.js +0 -119
  279. package/dist/form/SpecialTypes/FormikCustomInput.d.ts +0 -19
  280. package/dist/form/SpecialTypes/FormikCustomInput.js +0 -121
  281. package/dist/form/SpecialTypes/FormikMultiSelectDropdown.d.ts +0 -13
  282. package/dist/form/SpecialTypes/FormikMultiSelectDropdown.js +0 -31
  283. package/dist/form/SpecialTypes/FormikNumericInput.d.ts +0 -9
  284. package/dist/form/SpecialTypes/FormikNumericInput.js +0 -60
  285. package/dist/form/SpecialTypes/index.d.ts +0 -3
  286. package/dist/list/HoverCard.d.ts +0 -24
  287. package/dist/list/HoverCard.js +0 -73
  288. package/dist/list/RowContextMenu.d.ts +0 -127
  289. package/dist/list/RowContextMenu.js +0 -515
@@ -1,9 +1,9 @@
1
- import { useLink } from "./Provider.js";
2
1
  import { FaAngleRight } from "../icons/fa/FaAngleRight.js";
3
2
  import { LoaderIcon } from "./StatusIcons.js";
4
- import cx from "classnames";
3
+ import { useLink } from "./Provider.js";
4
+ import { clsx } from "clsx";
5
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
6
  import { forwardRef } from "react";
6
- import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
7
7
  //#region src/components/Button.tsx
8
8
  var Button = forwardRef(({ children, variant = "primary", size = "default", loading, icon, iconPosition = "right", fullWidth = true, className = "", disabled, ...props }, ref) => {
9
9
  const baseClasses = "inline-flex items-center justify-center gap-2 font-semibold rounded-lg transition-all duration-200 cursor-pointer border-none mt-2 disabled:opacity-50 disabled:cursor-not-allowed";
@@ -23,9 +23,9 @@ var Button = forwardRef(({ children, variant = "primary", size = "default", load
23
23
  ref,
24
24
  type: "button",
25
25
  disabled: disabled || loading,
26
- className: cx(baseClasses, variantClasses[variant], sizeClasses[size], widthClass, className),
26
+ className: clsx(baseClasses, variantClasses[variant], sizeClasses[size], widthClass, className),
27
27
  ...props,
28
- children: loading ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(LoaderIcon, { className: "size-[18px]" }), children] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
28
+ children: loading ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(LoaderIcon, { className: "size-[18px]" }), children] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
29
29
  icon && iconPosition === "left" && /* @__PURE__ */ jsx("span", {
30
30
  className: "flex items-center",
31
31
  children: icon
@@ -43,7 +43,7 @@ function MethodButton({ icon, label, description, href, loading, disabled, class
43
43
  const Link = useLink();
44
44
  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:bg-[var(--theme-border)] hover:border-[var(--theme-muted-text-color)] hover:-translate-y-0.5 active:translate-y-0";
45
45
  const disabledClasses = "disabled:opacity-60 disabled:cursor-not-allowed disabled:hover:bg-[var(--ds-muted)] disabled:hover:border-[var(--ds-border)] disabled:hover:translate-y-0";
46
- const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [
46
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [
47
47
  icon && /* @__PURE__ */ jsx("span", {
48
48
  className: "size-10 rounded-lg bg-gradient-to-br from-[var(--gradient-start,var(--theme-element))] to-[var(--gradient-mid,var(--theme-link))] flex items-center justify-center shrink-0 mr-4 [&_svg]:size-5 [&_svg]:text-white",
49
49
  children: icon
@@ -63,18 +63,18 @@ function MethodButton({ icon, label, description, href, loading, disabled, class
63
63
  if (href) {
64
64
  if (href.startsWith("/api/") || href.startsWith("http")) return /* @__PURE__ */ jsx("a", {
65
65
  href,
66
- className: cx("group", baseClasses, className),
66
+ className: clsx("group", baseClasses, className),
67
67
  children: content
68
68
  });
69
69
  return /* @__PURE__ */ jsx(Link, {
70
- to: href,
71
- className: cx("group", baseClasses, className),
70
+ href,
71
+ className: clsx("group", baseClasses, className),
72
72
  children: content
73
73
  });
74
74
  }
75
75
  return /* @__PURE__ */ jsx("button", {
76
76
  type: "button",
77
- className: cx("group", baseClasses, disabledClasses, className),
77
+ className: clsx("group", baseClasses, disabledClasses, className),
78
78
  disabled: disabled || loading,
79
79
  ...props,
80
80
  children: content
@@ -1,6 +1,6 @@
1
1
  import { FaInfoCircle } from "../icons/fa/FaInfoCircle.js";
2
2
  import { TbAlertTriangle } from "../icons/tb/TbAlertTriangle.js";
3
- import cx from "classnames";
3
+ import { clsx } from "clsx";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
5
  //#region src/components/Callout.tsx
6
6
  function CalloutIcon({ type }) {
@@ -9,7 +9,7 @@ function CalloutIcon({ type }) {
9
9
  }
10
10
  function Callout({ type, className = "", children }) {
11
11
  return /* @__PURE__ */ jsx("div", {
12
- className: cx(className, type === "warning" && "bg-orange-100 border-orange-500 text-orange-700", type === "error" && "bg-red-100 border-red-500 text-red-700", type === "info" && "bg-blue-100 border-blue-500 text-blue-700", "border-t-4 rounded-b px-4 py-3 shadow-md my-4"),
12
+ className: clsx(className, type === "warning" && "bg-orange-100 border-orange-500 text-orange-700", type === "error" && "bg-red-100 border-red-500 text-red-700", type === "info" && "bg-blue-100 border-blue-500 text-blue-700", "border-t-4 rounded-b px-4 py-3 shadow-md my-4"),
13
13
  role: "alert",
14
14
  children: /* @__PURE__ */ jsxs("div", {
15
15
  className: "flex",
@@ -1,15 +1,15 @@
1
- import cx from "classnames";
1
+ import { clsx } from "clsx";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  //#region src/components/Card.tsx
4
4
  function Card({ children, className = "", wide, compact, interactive, authShadow }) {
5
5
  return /* @__PURE__ */ jsx("div", {
6
- className: cx("w-full bg-[var(--theme-card-bg)] backdrop-blur-xl border border-[var(--theme-border)] rounded-2xl", authShadow ? "shadow-[var(--theme-auth-shadow)]" : "shadow-[var(--theme-shadow)]", wide && "max-w-[560px] p-8", compact && "max-w-[400px] p-6", !wide && !compact && "max-w-[520px] p-10", interactive && "ds-card-interactive cursor-pointer", className),
6
+ className: clsx("w-full bg-[var(--theme-card-bg)] backdrop-blur-xl border border-[var(--theme-border)] rounded-2xl", authShadow ? "shadow-[var(--theme-auth-shadow)]" : "shadow-[var(--theme-shadow)]", wide && "max-w-[560px] p-8", compact && "max-w-[400px] p-6", !wide && !compact && "max-w-[520px] p-10", interactive && "ds-card-interactive cursor-pointer", className),
7
7
  children
8
8
  });
9
9
  }
10
10
  function CardHeader({ badge, title, description, className = "", align = "center" }) {
11
11
  return /* @__PURE__ */ jsxs("div", {
12
- className: cx(align === "center" ? "text-center" : "text-left", "mb-6", className),
12
+ className: clsx(align === "center" ? "text-center" : "text-left", "mb-6", className),
13
13
  children: [
14
14
  badge && /* @__PURE__ */ jsx("div", {
15
15
  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",
@@ -0,0 +1,66 @@
1
+ import { type ReactElement, type ReactNode } from 'react';
2
+ export interface ComboboxItem<Value = string> {
3
+ value: Value;
4
+ label: string;
5
+ description?: string | undefined;
6
+ icon?: ReactNode;
7
+ disabled?: boolean | undefined;
8
+ }
9
+ export interface ComboboxGroup<Value = string> {
10
+ label: string;
11
+ /** Leads the heading, such as a provider's logo. */
12
+ icon?: ReactNode;
13
+ /** Follows the label, such as who shared the group or a status like "Not responding". */
14
+ description?: string | undefined;
15
+ /** Empty for a group that only reports a status; a search finds it by its heading. */
16
+ items: readonly (ComboboxItem<Value> | (Value & string))[];
17
+ }
18
+ /** A flat list, or groups under headings. A bare string is an item labelled by its value. */
19
+ export type ComboboxItems<Value = string> = readonly (ComboboxItem<Value> | (Value & string))[] | readonly ComboboxGroup<Value>[];
20
+ interface FieldProps {
21
+ id?: string | undefined;
22
+ placeholder?: string | undefined;
23
+ disabled?: boolean | undefined;
24
+ required?: boolean | undefined;
25
+ 'aria-label'?: string | undefined;
26
+ 'aria-labelledby'?: string | undefined;
27
+ 'aria-describedby'?: string | undefined;
28
+ 'aria-invalid'?: boolean | undefined;
29
+ /** Classes for the field box: border, background, size. */
30
+ className?: string | undefined;
31
+ }
32
+ type SelectionProps<Value> = {
33
+ multiple?: false | undefined;
34
+ value?: Value | null | undefined;
35
+ defaultValue?: Value | null | undefined;
36
+ onValueChange?: ((value: NoInfer<Value> | null) => void) | undefined;
37
+ } | {
38
+ multiple: true;
39
+ value?: readonly Value[] | undefined;
40
+ defaultValue?: readonly Value[] | undefined;
41
+ onValueChange?: ((value: NoInfer<Value>[]) => void) | undefined;
42
+ };
43
+ export type ComboboxProps<Value = string> = FieldProps & SelectionProps<Value> & {
44
+ items: ComboboxItems<Value>;
45
+ /** Matches a value to its item. Defaults to deep equality, so object values can be recreated. */
46
+ isItemEqualToValue?: ((itemValue: Value, value: Value) => boolean) | undefined;
47
+ /** Labels a selected value that no item has, such as a saved choice the list no longer offers. */
48
+ itemToStringLabel?: ((value: Value) => string) | undefined;
49
+ /** Renders the field as this button, with the search input inside the popup, for compact
50
+ * pickers such as a toolbar pill. The button shows the selection itself. */
51
+ trigger?: ReactElement | undefined;
52
+ /** A hint on the trigger button. */
53
+ triggerTooltip?: ReactNode;
54
+ };
55
+ export interface AutocompleteProps extends FieldProps {
56
+ /** Suggestions; any typed text is also a valid value. */
57
+ items: ComboboxItems<string>;
58
+ value?: string | undefined;
59
+ defaultValue?: string | undefined;
60
+ onValueChange?: ((value: string) => void) | undefined;
61
+ }
62
+ /** A pick-from-the-list field: one value, or several with `multiple`. Typing filters the list. */
63
+ export declare function Combobox<Value = string>(props: ComboboxProps<Value>): import("react").JSX.Element;
64
+ /** A free-text field that suggests values as you type. */
65
+ export declare function Autocomplete({ items, value, defaultValue, onValueChange, className, placeholder, disabled, required, id, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, 'aria-describedby': ariaDescribedBy, 'aria-invalid': ariaInvalid, }: AutocompleteProps): import("react").JSX.Element;
66
+ export {};
@@ -0,0 +1,393 @@
1
+ import { FaCaretDown } from "../icons/fa/FaCaretDown.js";
2
+ import { FaCheck } from "../icons/fa/FaCheck.js";
3
+ import { FiX } from "../icons/fi/FiX.js";
4
+ import { panelClassName, panelItemClassName, portalContainer, positionerClassName } from "./floating.js";
5
+ import { Tooltip } from "./Tooltip.js";
6
+ import { useStrings } from "./Provider.js";
7
+ import { useQueryMatch } from "./search.js";
8
+ import { clsx } from "clsx";
9
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
+ import { useCallback, useImperativeHandle, useMemo, useRef, useState } from "react";
11
+ import { Combobox } from "@base-ui/react/combobox";
12
+ import { Autocomplete } from "@base-ui/react/autocomplete";
13
+ import { useVirtualizer } from "@tanstack/react-virtual";
14
+ import { dequal } from "dequal";
15
+ //#region src/components/Combobox.tsx
16
+ function isGroup(item) {
17
+ return typeof item === "object" && "items" in item;
18
+ }
19
+ function toEntry(item, group) {
20
+ const entry = typeof item === "string" ? {
21
+ value: item,
22
+ label: item
23
+ } : item;
24
+ return group === void 0 ? entry : {
25
+ ...entry,
26
+ group
27
+ };
28
+ }
29
+ /** Base UI takes either flat items or groups, and filters and navigates by the leaf items. */
30
+ function useEntries(items) {
31
+ return useMemo(() => {
32
+ const [first] = items;
33
+ if (first !== void 0 && isGroup(first)) {
34
+ const groups = items.map((g, order) => ({
35
+ label: g.label,
36
+ icon: g.icon,
37
+ description: g.description,
38
+ items: g.items.map((item) => toEntry(item, g.label)),
39
+ order
40
+ }));
41
+ return {
42
+ items: groups,
43
+ flat: groups.flatMap((g) => g.items),
44
+ statusGroups: groups.filter((g) => g.items.length === 0)
45
+ };
46
+ }
47
+ const flat = items.map((item) => toEntry(item));
48
+ return {
49
+ items: flat,
50
+ flat,
51
+ statusGroups: []
52
+ };
53
+ }, [items]);
54
+ }
55
+ function useEntryFilter() {
56
+ const match = useQueryMatch();
57
+ return useCallback((entry, query) => match(query, entry.label, typeof entry.value === "string" ? entry.value : void 0, entry.group), [match]);
58
+ }
59
+ var entryLabel = (entry) => entry?.label ?? "";
60
+ var fieldClassName = "theme-input relative flex min-h-8 w-full items-center gap-1 rounded-md border text-sm focus-within:border-(--theme-element) focus-within:ring-1 focus-within:ring-(--theme-element) has-[[aria-invalid=true]]:border-(--theme-error) has-[input:disabled]:cursor-not-allowed has-[input:disabled]:bg-(--theme-input-disabled-bg) has-[input:disabled]:text-(--theme-input-disabled-text)";
61
+ var inputClassName = "h-full min-w-12 flex-1 self-stretch border-0 bg-transparent py-1.5 pl-3 text-inherit outline-none placeholder:text-(--theme-muted-text-color) disabled:cursor-not-allowed";
62
+ var triggerClassName = "flex shrink-0 items-center self-stretch px-2 text-(--theme-muted-text-color) disabled:cursor-not-allowed";
63
+ var popupInputClassName = "theme-input h-7 w-full rounded-md border px-2 text-sm outline-none placeholder:text-(--theme-muted-text-color) focus:border-(--theme-element)";
64
+ /** A pick-from-the-list field: one value, or several with `multiple`. Typing filters the list. */
65
+ function Combobox$1(props) {
66
+ const { items, isItemEqualToValue = dequal, itemToStringLabel = String, className, placeholder, disabled, required, id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid, trigger, triggerTooltip } = props;
67
+ const entries = useEntries(items);
68
+ const filter = useEntryFilter();
69
+ const strings = useStrings();
70
+ const t = strings.dropdown;
71
+ const list = useRef(null);
72
+ const [inputValue, setInputValue] = useState(null);
73
+ const entryOf = (value) => entries.flat.find((entry) => isItemEqualToValue(entry.value, value)) ?? {
74
+ value,
75
+ label: itemToStringLabel(value)
76
+ };
77
+ const toEntries = (values) => values?.map(entryOf);
78
+ const toSingle = (value) => value === void 0 ? void 0 : value === null ? null : entryOf(value);
79
+ const selected = props.multiple ? void 0 : toSingle(props.value);
80
+ const selectedIcon = selected?.icon && (inputValue === null || inputValue === selected.label) ? selected.icon : null;
81
+ const input = /* @__PURE__ */ jsx(Combobox.Input, {
82
+ id: trigger ? void 0 : id,
83
+ placeholder,
84
+ "aria-label": ariaLabel || void 0,
85
+ "aria-labelledby": ariaLabelledBy,
86
+ "aria-describedby": ariaDescribedBy,
87
+ "aria-invalid": ariaInvalid || void 0,
88
+ autoComplete: "off",
89
+ className: trigger ? popupInputClassName : inputClassName
90
+ });
91
+ const itemRow = (entry, rowProps) => /* @__PURE__ */ jsxs(Combobox.Item, {
92
+ value: entry,
93
+ disabled: entry.disabled,
94
+ ...rowProps.props,
95
+ className: itemClassName,
96
+ children: [/* @__PURE__ */ jsx(ItemContent, { entry }), /* @__PURE__ */ jsx(Combobox.ItemIndicator, {
97
+ className: "ml-auto flex shrink-0 items-center",
98
+ children: /* @__PURE__ */ jsx(FaCheck, { className: "size-3.5" })
99
+ })]
100
+ }, rowProps.key);
101
+ const parts = trigger ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Tooltip, {
102
+ content: triggerTooltip,
103
+ children: /* @__PURE__ */ jsx(Combobox.Trigger, {
104
+ id,
105
+ "aria-label": ariaLabel || void 0,
106
+ "aria-labelledby": ariaLabelledBy,
107
+ "aria-describedby": ariaDescribedBy,
108
+ "aria-invalid": ariaInvalid || void 0,
109
+ render: trigger
110
+ })
111
+ }), /* @__PURE__ */ jsx(ListPopup, {
112
+ listRef: list,
113
+ empty: t.noOptionsFound,
114
+ statusGroups: entries.statusGroups,
115
+ query: inputValue ?? "",
116
+ header: /* @__PURE__ */ jsx("div", {
117
+ className: "border-b border-(--theme-border) p-1.5",
118
+ children: input
119
+ }),
120
+ className: "w-max min-w-(--anchor-width) max-w-[min(28rem,var(--available-width))]",
121
+ renderItem: itemRow
122
+ })] }) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs(Combobox.InputGroup, {
123
+ "data-testid": "combobox",
124
+ className: clsx(fieldClassName, className),
125
+ children: [props.multiple ? /* @__PURE__ */ jsxs(Combobox.Chips, {
126
+ className: "flex min-w-0 flex-1 flex-wrap items-center gap-1 py-1 pl-1",
127
+ children: [/* @__PURE__ */ jsx(Combobox.Value, { children: (values) => values.map((entry) => /* @__PURE__ */ jsxs(Combobox.Chip, {
128
+ "aria-label": entry.label,
129
+ 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)",
130
+ children: [entry.label, /* @__PURE__ */ jsx(Combobox.ChipRemove, {
131
+ "aria-label": `${strings.common.remove} ${entry.label}`,
132
+ className: "flex size-4 items-center justify-center rounded hover:bg-(--theme-hover)",
133
+ children: /* @__PURE__ */ jsx(FiX, { className: "size-3" })
134
+ })]
135
+ }, entry.label)) }), input]
136
+ }) : /* @__PURE__ */ jsxs(Fragment, { children: [selectedIcon && /* @__PURE__ */ jsx("span", {
137
+ className: "flex shrink-0 items-center pl-3",
138
+ children: selectedIcon
139
+ }), input] }), /* @__PURE__ */ jsx(Combobox.Trigger, {
140
+ "aria-label": t.showOptions,
141
+ "data-testid": "combobox-button",
142
+ className: triggerClassName,
143
+ children: /* @__PURE__ */ jsx(FaCaretDown, { className: "size-3" })
144
+ })]
145
+ }), /* @__PURE__ */ jsx(ListPopup, {
146
+ listRef: list,
147
+ empty: t.noOptionsFound,
148
+ statusGroups: entries.statusGroups,
149
+ query: inputValue ?? "",
150
+ renderItem: itemRow
151
+ })] });
152
+ const root = {
153
+ items: entries.items,
154
+ filter,
155
+ isItemEqualToValue: (a, b) => isItemEqualToValue(a.value, b.value),
156
+ itemToStringLabel: entryLabel,
157
+ onInputValueChange: setInputValue,
158
+ onItemHighlighted: (_, { index, reason }) => list.current?.reveal(index, reason),
159
+ disabled,
160
+ required,
161
+ virtualized: true,
162
+ children: parts
163
+ };
164
+ return props.multiple ? /* @__PURE__ */ jsx(Combobox.Root, {
165
+ ...root,
166
+ multiple: true,
167
+ value: toEntries(props.value),
168
+ defaultValue: toEntries(props.defaultValue),
169
+ onValueChange: (next) => props.onValueChange?.(next.map((entry) => entry.value))
170
+ }) : /* @__PURE__ */ jsx(Combobox.Root, {
171
+ ...root,
172
+ value: selected,
173
+ defaultValue: toSingle(props.defaultValue),
174
+ onValueChange: (next) => props.onValueChange?.(next?.value ?? null)
175
+ });
176
+ }
177
+ /** A free-text field that suggests values as you type. */
178
+ function Autocomplete$1({ items, value, defaultValue, onValueChange, className, placeholder, disabled, required, id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid }) {
179
+ const entries = useEntries(items);
180
+ const filter = useEntryFilter();
181
+ const t = useStrings().dropdown;
182
+ const list = useRef(null);
183
+ return /* @__PURE__ */ jsxs(Autocomplete.Root, {
184
+ items: entries.items,
185
+ filter,
186
+ itemToStringValue: (entry) => entry.value,
187
+ value,
188
+ defaultValue,
189
+ onValueChange: (next) => onValueChange?.(next),
190
+ onItemHighlighted: (_, { index, reason }) => list.current?.reveal(index, reason),
191
+ disabled,
192
+ required,
193
+ virtualized: true,
194
+ children: [/* @__PURE__ */ jsxs(Autocomplete.InputGroup, {
195
+ "data-testid": "combobox",
196
+ className: clsx(fieldClassName, className),
197
+ children: [/* @__PURE__ */ jsx(Autocomplete.Input, {
198
+ id,
199
+ placeholder,
200
+ "aria-label": ariaLabel || void 0,
201
+ "aria-labelledby": ariaLabelledBy,
202
+ "aria-describedby": ariaDescribedBy,
203
+ "aria-invalid": ariaInvalid || void 0,
204
+ autoComplete: "off",
205
+ className: inputClassName
206
+ }), entries.flat.length > 0 && /* @__PURE__ */ jsx(Autocomplete.Trigger, {
207
+ "aria-label": t.showOptions,
208
+ "data-testid": "combobox-button",
209
+ className: triggerClassName,
210
+ children: /* @__PURE__ */ jsx(FaCaretDown, { className: "size-3" })
211
+ })]
212
+ }), /* @__PURE__ */ jsx(ListPopup, {
213
+ listRef: list,
214
+ renderItem: (entry, rowProps) => /* @__PURE__ */ jsx(Autocomplete.Item, {
215
+ value: entry,
216
+ disabled: entry.disabled,
217
+ ...rowProps.props,
218
+ className: itemClassName,
219
+ children: /* @__PURE__ */ jsx(ItemContent, { entry })
220
+ }, rowProps.key)
221
+ })]
222
+ });
223
+ }
224
+ var itemClassName = clsx(panelItemClassName, "data-selected:font-medium");
225
+ function ItemContent({ entry }) {
226
+ return /* @__PURE__ */ jsxs(Fragment, { children: [entry.icon && /* @__PURE__ */ jsx("span", {
227
+ className: "flex shrink-0 items-center",
228
+ children: entry.icon
229
+ }), /* @__PURE__ */ jsxs("span", {
230
+ className: "flex min-w-0 flex-col",
231
+ children: [/* @__PURE__ */ jsx(Tooltip, {
232
+ content: entry.label,
233
+ overflowOnly: true,
234
+ children: /* @__PURE__ */ jsx("span", {
235
+ className: "truncate",
236
+ children: entry.label
237
+ })
238
+ }), entry.description && /* @__PURE__ */ jsx("span", {
239
+ className: "text-xs leading-snug text-(--theme-muted-text-color)",
240
+ children: entry.description
241
+ })]
242
+ })] });
243
+ }
244
+ function GroupHeading({ group }) {
245
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
246
+ group.icon && /* @__PURE__ */ jsx("span", {
247
+ className: "flex shrink-0 items-center",
248
+ children: group.icon
249
+ }),
250
+ /* @__PURE__ */ jsx("span", {
251
+ className: "shrink-0 font-semibold",
252
+ children: group.label
253
+ }),
254
+ group.description && /* @__PURE__ */ jsx(Tooltip, {
255
+ content: group.description,
256
+ overflowOnly: true,
257
+ children: /* @__PURE__ */ jsxs("span", {
258
+ className: "min-w-0 truncate",
259
+ children: ["· ", group.description]
260
+ })
261
+ })
262
+ ] });
263
+ }
264
+ /** Portal, positioner and popup shared by Combobox and Autocomplete; both use the same parts. */
265
+ function ListPopup({ listRef, empty, statusGroups = [], query = "", header, className = "w-(--anchor-width) max-w-(--available-width)", renderItem }) {
266
+ return /* @__PURE__ */ jsx(Combobox.Portal, {
267
+ container: portalContainer(),
268
+ children: /* @__PURE__ */ jsx(Combobox.Positioner, {
269
+ align: "start",
270
+ sideOffset: 4,
271
+ className: positionerClassName,
272
+ children: /* @__PURE__ */ jsxs(Combobox.Popup, {
273
+ className: clsx("overflow-hidden", className, panelClassName),
274
+ children: [
275
+ header,
276
+ empty && statusGroups.length === 0 && /* @__PURE__ */ jsx(Combobox.Empty, {
277
+ className: "px-3 py-2 text-(--theme-muted-text-color) empty:hidden",
278
+ children: empty
279
+ }),
280
+ /* @__PURE__ */ jsx(Combobox.List, { children: /* @__PURE__ */ jsx(VirtualList, {
281
+ ref: listRef,
282
+ statusGroups,
283
+ query,
284
+ renderItem
285
+ }) })
286
+ ]
287
+ })
288
+ })
289
+ });
290
+ }
291
+ function toRows(filtered, statusGroups) {
292
+ const nodes = statusGroups.length ? [...filtered, ...statusGroups].sort((a, b) => ("order" in a ? a.order : 0) - ("order" in b ? b.order : 0)) : filtered;
293
+ const rows = [];
294
+ const rowOfItem = [];
295
+ for (const node of nodes) {
296
+ const leaves = "items" in node ? node.items : [node];
297
+ if ("items" in node) rows.push({
298
+ kind: "group",
299
+ group: node
300
+ });
301
+ for (const entry of leaves) {
302
+ rowOfItem.push(rows.length);
303
+ rows.push({
304
+ kind: "item",
305
+ entry,
306
+ index: rowOfItem.length - 1
307
+ });
308
+ }
309
+ }
310
+ return {
311
+ rows,
312
+ rowOfItem
313
+ };
314
+ }
315
+ function VirtualList({ ref, statusGroups, query, renderItem }) {
316
+ const filtered = Combobox.useFilteredItems();
317
+ const match = useQueryMatch();
318
+ const { rows, rowOfItem } = useMemo(() => {
319
+ const q = query.trim();
320
+ const shown = q ? statusGroups.filter((g) => match(q, g.label, g.description)) : statusGroups;
321
+ return toRows(filtered, shown);
322
+ }, [
323
+ filtered,
324
+ statusGroups,
325
+ query,
326
+ match
327
+ ]);
328
+ const scroller = useRef(null);
329
+ const virtualizer = useVirtualizer({
330
+ count: rows.length,
331
+ getScrollElement: () => scroller.current,
332
+ estimateSize: (i) => rows[i]?.kind === "group" ? 28 : 36,
333
+ overscan: 10,
334
+ paddingStart: 4,
335
+ paddingEnd: 4,
336
+ scrollPaddingStart: 4,
337
+ scrollPaddingEnd: 4
338
+ });
339
+ useImperativeHandle(ref, () => ({ reveal(index, reason) {
340
+ const row = index === void 0 ? void 0 : rowOfItem[index];
341
+ if (row === void 0 || reason === "pointer") return;
342
+ queueMicrotask(() => virtualizer.scrollToIndex(row, { align: "auto" }));
343
+ } }), [rowOfItem, virtualizer]);
344
+ const scrollerRef = useCallback((element) => {
345
+ scroller.current = element;
346
+ if (element) virtualizer.measure();
347
+ }, [virtualizer]);
348
+ if (rows.length === 0) return null;
349
+ const total = virtualizer.getTotalSize();
350
+ return /* @__PURE__ */ jsx("div", {
351
+ role: "presentation",
352
+ ref: scrollerRef,
353
+ className: "max-h-[min(15rem,var(--available-height))] overflow-auto overscroll-contain",
354
+ style: { height: total },
355
+ children: /* @__PURE__ */ jsx("div", {
356
+ role: "presentation",
357
+ className: "relative w-full",
358
+ style: { height: total },
359
+ children: virtualizer.getVirtualItems().map((virtual) => {
360
+ const row = rows[virtual.index];
361
+ const style = {
362
+ position: "absolute",
363
+ top: 0,
364
+ left: 0,
365
+ width: "100%",
366
+ transform: `translateY(${virtual.start}px)`
367
+ };
368
+ if (!row) return null;
369
+ if (row.kind === "group") return /* @__PURE__ */ jsx("div", {
370
+ role: "presentation",
371
+ "data-index": virtual.index,
372
+ ref: virtualizer.measureElement,
373
+ style,
374
+ className: "flex items-center gap-1.5 px-3 pt-2 pb-1 text-xs text-(--theme-muted-text-color)",
375
+ children: /* @__PURE__ */ jsx(GroupHeading, { group: row.group })
376
+ }, virtual.key);
377
+ return renderItem(row.entry, {
378
+ key: virtual.key,
379
+ props: {
380
+ index: row.index,
381
+ ref: virtualizer.measureElement,
382
+ "data-index": virtual.index,
383
+ "aria-setsize": rowOfItem.length,
384
+ "aria-posinset": row.index + 1,
385
+ style
386
+ }
387
+ });
388
+ })
389
+ })
390
+ });
391
+ }
392
+ //#endregion
393
+ export { Autocomplete$1 as Autocomplete, Combobox$1 as Combobox };
@@ -1,9 +1,9 @@
1
1
  import { useStrings } from "./Provider.js";
2
- import { BareModal, modalPanelClasses } from "./BareModal.js";
3
2
  import { dangerButtonClasses, ghostButtonClasses, primaryButtonClasses } from "./ghostButton.js";
4
- import cx from "classnames";
5
- import { useCallback, useEffect, useRef, useState } from "react";
3
+ import { Modal, ModalDescription, ModalTitle } from "./Modal.js";
4
+ import { clsx } from "clsx";
6
5
  import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { useCallback, useEffect, useRef, useState } from "react";
7
7
  //#region src/components/ConfirmModal.tsx
8
8
  function ConfirmModal({ open, onClose, title, description, children, confirmLabel, onConfirm, confirmDisabled = false, destructive = false, align = "top", cancelLabel, closeOnConfirm = true }) {
9
9
  const strings = useStrings();
@@ -29,21 +29,21 @@ function ConfirmModal({ open, onClose, title, description, children, confirmLabe
29
29
  setPending(false);
30
30
  }
31
31
  }, [onConfirm, closeOnConfirm]);
32
- return /* @__PURE__ */ jsxs(BareModal, {
32
+ return /* @__PURE__ */ jsxs(Modal, {
33
+ alert: destructive,
33
34
  open,
34
35
  onClose,
35
- ariaLabel: title,
36
36
  align,
37
- preventClose: pending,
38
- className: cx(modalPanelClasses, "w-[480px] max-w-full"),
37
+ dismissible: !pending,
38
+ className: "w-[480px] max-w-full",
39
39
  children: [/* @__PURE__ */ jsxs("div", {
40
40
  className: "px-5 pt-5",
41
41
  children: [
42
- /* @__PURE__ */ jsx("h2", {
42
+ /* @__PURE__ */ jsx(ModalTitle, {
43
43
  className: "text-lg font-semibold text-(--theme-app)",
44
44
  children: title
45
45
  }),
46
- description !== null && description !== void 0 && /* @__PURE__ */ jsx("p", {
46
+ description !== null && description !== void 0 && /* @__PURE__ */ jsx(ModalDescription, {
47
47
  className: "mt-1.5 text-sm text-(--theme-muted-text-color)",
48
48
  children: description
49
49
  }),
@@ -58,13 +58,13 @@ function ConfirmModal({ open, onClose, title, description, children, confirmLabe
58
58
  type: "button",
59
59
  onClick: onClose,
60
60
  disabled: pending,
61
- className: cx(ghostButtonClasses, pending && "cursor-wait"),
61
+ className: clsx(ghostButtonClasses, pending && "cursor-wait"),
62
62
  children: cancelLabel ?? strings.modal.cancel
63
63
  }), /* @__PURE__ */ jsx("button", {
64
64
  type: "button",
65
65
  onClick: runConfirm,
66
66
  disabled: confirmDisabled || pending,
67
- className: cx(destructive ? dangerButtonClasses : primaryButtonClasses, "disabled:cursor-not-allowed disabled:opacity-50", pending && "cursor-wait"),
67
+ className: clsx(destructive ? dangerButtonClasses : primaryButtonClasses, "disabled:cursor-not-allowed disabled:opacity-50", pending && "cursor-wait"),
68
68
  children: confirmLabel
69
69
  })]
70
70
  })]
@@ -0,0 +1,23 @@
1
+ import { type MenuEntry, type MenuSearch } from './MenuEntries.js';
2
+ /** Where a menu opens: under an element, such as the button that opened it, or
3
+ * at a pointer event's point, which then moves with the element it landed on. */
4
+ export type MenuAnchor = Element | {
5
+ clientX: number;
6
+ clientY: number;
7
+ currentTarget?: EventTarget | null;
8
+ };
9
+ export interface OpenMenuOptions {
10
+ search?: MenuSearch | undefined;
11
+ /** Called once the menu closes, or another menu replaces it. */
12
+ onClose?: (() => void) | undefined;
13
+ }
14
+ export type OpenMenu = (at: MenuAnchor, items: MenuEntry[], options?: OpenMenuOptions) => void;
15
+ /**
16
+ * One menu that any number of rows, buttons or a canvas open with their own
17
+ * items, so a long list holds a single menu rather than one per row. Render
18
+ * `contextMenu` once.
19
+ */
20
+ export declare function useContextMenu(): {
21
+ openMenu: OpenMenu;
22
+ contextMenu: import("react").JSX.Element | null;
23
+ };