@parallelworks/ui 0.41.0 → 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 (280) hide show
  1. package/README.md +25 -0
  2. package/dist/ai/components/AllocationSelector.d.ts +3 -4
  3. package/dist/ai/components/AllocationSelector.js +37 -33
  4. package/dist/ai/components/AttachmentManager.js +7 -7
  5. package/dist/ai/components/AttachmentUpload.js +5 -5
  6. package/dist/ai/components/BranchNavigator.js +1 -1
  7. package/dist/ai/components/ChatEmptyState.js +2 -2
  8. package/dist/ai/components/ChatInput.js +10 -8
  9. package/dist/ai/components/ChatLayout.js +4 -5
  10. package/dist/ai/components/ChatMessage.js +12 -12
  11. package/dist/ai/components/ChatMessageList.js +9 -9
  12. package/dist/ai/components/ChatSidebar.js +8 -9
  13. package/dist/ai/components/ChatThread.js +4 -4
  14. package/dist/ai/components/ComposerChrome.d.ts +2 -2
  15. package/dist/ai/components/ComposerChrome.js +3 -6
  16. package/dist/ai/components/DragOverlay.js +2 -2
  17. package/dist/ai/components/ModelSelector.d.ts +5 -3
  18. package/dist/ai/components/ModelSelector.js +102 -339
  19. package/dist/ai/components/PastedText.js +11 -11
  20. package/dist/ai/components/ProviderIssueBanner.d.ts +2 -0
  21. package/dist/ai/components/ProviderIssueBanner.js +34 -16
  22. package/dist/ai/components/Reasoning.js +4 -4
  23. package/dist/ai/components/ShareDialog.js +43 -35
  24. package/dist/ai/components/SlashMenu.d.ts +12 -2
  25. package/dist/ai/components/SlashMenu.js +29 -13
  26. package/dist/ai/components/agent/ActivityLine.js +3 -3
  27. package/dist/ai/components/agent/AgentMessageParts.js +20 -20
  28. package/dist/ai/components/agent/PermissionPicker.js +13 -11
  29. package/dist/ai/components/conversationActions.d.ts +4 -6
  30. package/dist/ai/components/conversationActions.js +9 -13
  31. package/dist/ai/core/ChatProvider.js +1 -1
  32. package/dist/ai/core/config.js +1 -1
  33. package/dist/ai/core/providerIssues.d.ts +7 -0
  34. package/dist/ai/core/providerIssues.js +9 -1
  35. package/dist/ai/core/useKeyboardShortcuts.d.ts +4 -0
  36. package/dist/ai/core/useKeyboardShortcuts.js +8 -2
  37. package/dist/ai/index.d.ts +0 -1
  38. package/dist/ai/index.js +1 -2
  39. package/dist/ai/strings.d.ts +19 -0
  40. package/dist/ai/strings.js +18 -1
  41. package/dist/ai/ui/Avatar.js +5 -5
  42. package/dist/ai/ui/ConversationSidebar.d.ts +0 -1
  43. package/dist/ai/ui/ConversationSidebar.js +6 -7
  44. package/dist/ai/ui/Markdown.js +3 -3
  45. package/dist/ai/ui/Notice.js +6 -6
  46. package/dist/ai/ui/chip.d.ts +4 -0
  47. package/dist/ai/ui/chip.js +8 -0
  48. package/dist/ai/ui/sidebar.d.ts +6 -5
  49. package/dist/ai/ui/sidebar.js +39 -43
  50. package/dist/components/ActionMenu.d.ts +13 -0
  51. package/dist/components/ActionMenu.js +30 -0
  52. package/dist/components/Avatar.js +6 -6
  53. package/dist/components/Breadcrumbs.js +1 -1
  54. package/dist/components/Button.js +10 -10
  55. package/dist/components/Callout.js +2 -2
  56. package/dist/components/Card.js +3 -3
  57. package/dist/components/Combobox.d.ts +66 -0
  58. package/dist/components/Combobox.js +393 -0
  59. package/dist/components/ConfirmModal.js +11 -11
  60. package/dist/components/ContextMenu.d.ts +23 -0
  61. package/dist/components/ContextMenu.js +89 -0
  62. package/dist/components/CopyToClipboard.js +2 -2
  63. package/dist/components/CreateModal.d.ts +17 -36
  64. package/dist/components/CreateModal.js +97 -259
  65. package/dist/components/DescriptionList.js +8 -8
  66. package/dist/components/Filter.js +2 -2
  67. package/dist/components/FilterPill.js +2 -2
  68. package/dist/components/HoverCard.d.ts +14 -0
  69. package/dist/components/HoverCard.js +33 -0
  70. package/dist/components/IconButton.d.ts +5 -5
  71. package/dist/components/IconButton.js +18 -22
  72. package/dist/components/InfoTip.d.ts +15 -0
  73. package/dist/components/InfoTip.js +60 -0
  74. package/dist/components/Input.js +5 -5
  75. package/dist/components/LetterBadge.js +2 -2
  76. package/dist/components/Loader.js +3 -3
  77. package/dist/components/Markdown.js +1 -1
  78. package/dist/components/MarkdownImpl.js +2 -2
  79. package/dist/components/Menu.d.ts +33 -0
  80. package/dist/components/Menu.js +86 -0
  81. package/dist/components/MenuEntries.d.ts +56 -0
  82. package/dist/components/MenuEntries.js +123 -0
  83. package/dist/components/Modal.d.ts +29 -0
  84. package/dist/components/Modal.js +47 -0
  85. package/dist/components/Overview.js +11 -10
  86. package/dist/components/PageHeader.d.ts +10 -16
  87. package/dist/components/PageHeader.js +69 -95
  88. package/dist/components/Pagination.js +5 -5
  89. package/dist/components/Provider.d.ts +5 -11
  90. package/dist/components/Provider.js +11 -14
  91. package/dist/components/Radio.d.ts +8 -0
  92. package/dist/components/Radio.js +16 -0
  93. package/dist/components/SectionHeader.js +2 -2
  94. package/dist/components/SegmentedControl.d.ts +6 -5
  95. package/dist/components/SegmentedControl.js +34 -30
  96. package/dist/components/Select.d.ts +27 -0
  97. package/dist/components/Select.js +78 -0
  98. package/dist/components/SettingModeOption.d.ts +5 -8
  99. package/dist/components/SettingModeOption.js +10 -12
  100. package/dist/components/SettingRow.js +4 -4
  101. package/dist/components/SettingsCard.js +4 -4
  102. package/dist/components/SettingsGroup.js +2 -2
  103. package/dist/components/Sort.js +1 -1
  104. package/dist/components/StatusBadge.js +7 -7
  105. package/dist/components/StatusIcons.js +4 -4
  106. package/dist/components/Switch.d.ts +22 -0
  107. package/dist/components/Switch.js +28 -0
  108. package/dist/components/Table.js +11 -11
  109. package/dist/components/Tooltip.d.ts +24 -20
  110. package/dist/components/Tooltip.js +58 -76
  111. package/dist/components/floating.d.ts +14 -0
  112. package/dist/components/floating.js +21 -0
  113. package/dist/components/search.d.ts +2 -0
  114. package/dist/components/search.js +14 -0
  115. package/dist/editor/Editor.js +1 -1
  116. package/dist/editor/EditorField.js +16 -21
  117. package/dist/editor/FormCodePanel.js +19 -19
  118. package/dist/editor/Monaco.js +3 -3
  119. package/dist/file-explorer/FileExplorer.js +77 -81
  120. package/dist/file-explorer/FileExplorerContext.js +2 -2
  121. package/dist/file-explorer/FilePreview/CodePreviewEditor.js +1 -1
  122. package/dist/file-explorer/FilePreview/Inline.js +1 -1
  123. package/dist/file-explorer/FilePreview/StreamedBadge.js +5 -6
  124. package/dist/file-explorer/FilePreview/Viewer.js +8 -8
  125. package/dist/file-explorer/FilePreview/index.d.ts +1 -1
  126. package/dist/file-explorer/FilePreview/index.js +49 -83
  127. package/dist/file-explorer/FileRow.d.ts +4 -3
  128. package/dist/file-explorer/FileRow.js +32 -38
  129. package/dist/file-explorer/FileRowsWindow.d.ts +3 -2
  130. package/dist/file-explorer/FileRowsWindow.js +4 -4
  131. package/dist/file-explorer/FileTable.d.ts +3 -2
  132. package/dist/file-explorer/FileTable.js +3 -3
  133. package/dist/file-explorer/LoadMoreRow.js +1 -1
  134. package/dist/file-explorer/TreeView.js +11 -16
  135. package/dist/file-explorer/helpers.js +11 -12
  136. package/dist/file-explorer/toasts.js +11 -11
  137. package/dist/form/FieldGroup.d.ts +11 -0
  138. package/dist/form/FieldGroup.js +36 -0
  139. package/dist/form/FieldWrapper.js +4 -4
  140. package/dist/form/Fields/BooleanField.js +23 -33
  141. package/dist/form/Fields/CheckboxGroupField.d.ts +1 -1
  142. package/dist/form/Fields/CheckboxGroupField.js +9 -13
  143. package/dist/form/Fields/ColorField.d.ts +1 -2
  144. package/dist/form/Fields/ColorField.js +6 -11
  145. package/dist/form/Fields/DropdownField.d.ts +3 -13
  146. package/dist/form/Fields/DropdownField.js +40 -27
  147. package/dist/form/Fields/DurationField.d.ts +1 -2
  148. package/dist/form/Fields/DurationField.js +25 -32
  149. package/dist/form/Fields/LabelField.js +2 -2
  150. package/dist/form/Fields/MultiDropdownField.d.ts +6 -12
  151. package/dist/form/Fields/MultiDropdownField.js +31 -22
  152. package/dist/form/Fields/NumberField.d.ts +1 -1
  153. package/dist/form/Fields/NumberField.js +65 -35
  154. package/dist/form/Fields/ObjectField.d.ts +1 -1
  155. package/dist/form/Fields/ObjectField.js +12 -43
  156. package/dist/form/Fields/RadioField.d.ts +1 -1
  157. package/dist/form/Fields/RadioField.js +30 -41
  158. package/dist/form/Fields/RangeField.d.ts +1 -2
  159. package/dist/form/Fields/RangeField.js +23 -16
  160. package/dist/form/Fields/StringField.d.ts +1 -2
  161. package/dist/form/Fields/StringField.js +58 -26
  162. package/dist/form/Fields/TextAreaField.js +12 -10
  163. package/dist/form/Form.d.ts +30 -48
  164. package/dist/form/Form.js +306 -412
  165. package/dist/form/FormLayout.js +9 -9
  166. package/dist/form/Wizard/WizardContainer.d.ts +1 -4
  167. package/dist/form/Wizard/WizardContainer.js +40 -56
  168. package/dist/form/Wizard/WizardNavigation.js +1 -1
  169. package/dist/form/Wizard/WizardStepContent.d.ts +1 -5
  170. package/dist/form/Wizard/WizardStepContent.js +11 -16
  171. package/dist/form/Wizard/WizardStepIndicator.js +6 -6
  172. package/dist/form/Wizard/types.d.ts +0 -14
  173. package/dist/form/fieldRegistry.d.ts +1 -1
  174. package/dist/form/fieldRegistry.js +6 -6
  175. package/dist/form/formEditing.js +1 -1
  176. package/dist/form/index.d.ts +5 -4
  177. package/dist/form/index.js +6 -7
  178. package/dist/form/types/fieldComponentTypes.d.ts +8 -10
  179. package/dist/form/useChoiceField.d.ts +20 -0
  180. package/dist/form/useChoiceField.js +49 -0
  181. package/dist/form/useFieldValue.d.ts +7 -0
  182. package/dist/form/useFieldValue.js +20 -0
  183. package/dist/form/useParsedOpts.d.ts +3 -1
  184. package/dist/form/useParsedOpts.js +12 -17
  185. package/dist/form/utils/dependentOptions.d.ts +8 -4
  186. package/dist/form/utils/dependentOptions.js +25 -17
  187. package/dist/form/utils/fieldItems.d.ts +10 -0
  188. package/dist/form/utils/fieldItems.js +11 -0
  189. package/dist/form/utils/fieldPath.d.ts +10 -0
  190. package/dist/form/utils/fieldPath.js +20 -0
  191. package/dist/form/utils/shareEqual.d.ts +6 -0
  192. package/dist/form/utils/shareEqual.js +38 -0
  193. package/dist/graph/AnnotationBanner.js +8 -8
  194. package/dist/graph/Collapse.d.ts +1 -0
  195. package/dist/graph/Collapse.js +6 -27
  196. package/dist/graph/Connectors.js +5 -5
  197. package/dist/graph/DependencyGraph.js +20 -19
  198. package/dist/graph/GraphEditor.js +30 -41
  199. package/dist/graph/GraphEditorDialogs.js +17 -17
  200. package/dist/graph/GraphNode.js +1 -1
  201. package/dist/graph/InputDialog.js +19 -22
  202. package/dist/graph/InputsEditor.js +58 -66
  203. package/dist/graph/JobSummary.js +42 -39
  204. package/dist/graph/MatrixGroup.js +1 -1
  205. package/dist/graph/ProblemsButton.js +18 -19
  206. package/dist/graph/Reveal.js +1 -1
  207. package/dist/graph/ShortcutsButton.js +15 -18
  208. package/dist/graph/SuggestionInput.d.ts +5 -10
  209. package/dist/graph/SuggestionInput.js +14 -18
  210. package/dist/graph/ToolbarPopover.d.ts +11 -6
  211. package/dist/graph/ToolbarPopover.js +35 -67
  212. package/dist/graph/TreeView.js +24 -37
  213. package/dist/graph/WorkflowSettingsDialog.js +4 -4
  214. package/dist/graph/editorChrome.js +13 -12
  215. package/dist/graph/editorFields.js +29 -29
  216. package/dist/graph/editorPrimitives.d.ts +1 -1
  217. package/dist/graph/editorPrimitives.js +10 -7
  218. package/dist/graph/editorRows.js +103 -97
  219. package/dist/graph/fieldProblems.js +2 -2
  220. package/dist/graph/graphEditorState.d.ts +4 -3
  221. package/dist/graph/inputRefs.js +9 -9
  222. package/dist/graph/settingsViews.js +6 -7
  223. package/dist/graph/stepWith.js +6 -6
  224. package/dist/index.d.ts +14 -15
  225. package/dist/index.js +15 -14
  226. package/dist/list/ActionToolbar.d.ts +6 -14
  227. package/dist/list/ActionToolbar.js +48 -96
  228. package/dist/list/ListPage.d.ts +6 -12
  229. package/dist/list/ListPage.js +46 -29
  230. package/dist/list/ListPager.js +4 -4
  231. package/dist/list/ListTable.js +5 -5
  232. package/dist/list/ListViewControls.d.ts +5 -4
  233. package/dist/list/ListViewControls.js +177 -267
  234. package/dist/list/UserHoverCard.d.ts +3 -17
  235. package/dist/list/UserHoverCard.js +21 -45
  236. package/dist/list/index.d.ts +3 -4
  237. package/dist/list/index.js +3 -4
  238. package/dist/list/listSearch.js +12 -11
  239. package/dist/list/rowMenu.d.ts +63 -0
  240. package/dist/list/rowMenu.js +134 -0
  241. package/dist/logviewer/LogViewer.js +26 -26
  242. package/dist/styles.css +1 -1
  243. package/package.json +7 -13
  244. package/dist/ai/ui/Dropdown.d.ts +0 -31
  245. package/dist/ai/ui/Dropdown.js +0 -110
  246. package/dist/components/AddMenu.d.ts +0 -18
  247. package/dist/components/AddMenu.js +0 -46
  248. package/dist/components/BareModal.d.ts +0 -17
  249. package/dist/components/BareModal.js +0 -77
  250. package/dist/components/CollapsiblePanel.d.ts +0 -27
  251. package/dist/components/CollapsiblePanel.js +0 -77
  252. package/dist/components/Dropdown.d.ts +0 -28
  253. package/dist/components/Dropdown.js +0 -355
  254. package/dist/components/Listbox.d.ts +0 -21
  255. package/dist/components/Listbox.js +0 -119
  256. package/dist/components/MultiSelect.d.ts +0 -22
  257. package/dist/components/MultiSelect.js +0 -168
  258. package/dist/components/SwitchToggle.d.ts +0 -15
  259. package/dist/components/SwitchToggle.js +0 -57
  260. package/dist/components/SwitchToggleSmall.d.ts +0 -6
  261. package/dist/components/SwitchToggleSmall.js +0 -14
  262. package/dist/components/Toggle.d.ts +0 -6
  263. package/dist/components/Toggle.js +0 -20
  264. package/dist/components/dropdownUtils.d.ts +0 -37
  265. package/dist/components/dropdownUtils.js +0 -99
  266. package/dist/form/SpecialTypes/DropdownWrapper.d.ts +0 -25
  267. package/dist/form/SpecialTypes/DropdownWrapper.js +0 -28
  268. package/dist/form/SpecialTypes/FormikCustomDropdown.d.ts +0 -51
  269. package/dist/form/SpecialTypes/FormikCustomDropdown.js +0 -119
  270. package/dist/form/SpecialTypes/FormikCustomInput.d.ts +0 -19
  271. package/dist/form/SpecialTypes/FormikCustomInput.js +0 -121
  272. package/dist/form/SpecialTypes/FormikMultiSelectDropdown.d.ts +0 -13
  273. package/dist/form/SpecialTypes/FormikMultiSelectDropdown.js +0 -31
  274. package/dist/form/SpecialTypes/FormikNumericInput.d.ts +0 -9
  275. package/dist/form/SpecialTypes/FormikNumericInput.js +0 -60
  276. package/dist/form/SpecialTypes/index.d.ts +0 -3
  277. package/dist/list/HoverCard.d.ts +0 -24
  278. package/dist/list/HoverCard.js +0 -73
  279. package/dist/list/RowContextMenu.d.ts +0 -127
  280. package/dist/list/RowContextMenu.js +0 -515
@@ -1,8 +1,8 @@
1
1
  import { layoutBreakpoints, responsiveLayoutValues } from "./layout.js";
2
2
  import { resolveLayoutCSS } from "./layoutCSS.js";
3
- import cx from "classnames";
4
- import { createContext, useContext, useId, useMemo } from "react";
3
+ import { clsx } from "clsx";
5
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
+ import { createContext, useContext, useId, useMemo } from "react";
6
6
  //#region src/form/FormLayout.tsx
7
7
  var LayoutCSSContext = createContext(false);
8
8
  var gaps = {
@@ -20,7 +20,7 @@ function FormLayout({ layout, renderField }) {
20
20
  const allowCSS = useContext(LayoutCSSContext);
21
21
  return /* @__PURE__ */ jsx("div", {
22
22
  "data-layout-boundary": true,
23
- className: cx("min-w-0 max-w-full", allowCSS && "isolate [contain:paint] p-0.5"),
23
+ className: clsx("min-w-0 max-w-full", allowCSS && "isolate [contain:paint] p-0.5"),
24
24
  children: /* @__PURE__ */ jsx(LayoutNode, {
25
25
  node: layout,
26
26
  renderField
@@ -47,7 +47,7 @@ function LayoutNode({ node, renderField, sharedRows }) {
47
47
  const style = Object.fromEntries(layoutBreakpoints.flatMap((key) => [[`--layout-span-${key}`, Math.min(spans[key], trackCount(columns[key]))], [`--layout-slot-${key}`, sharedRows?.[key] ? index + 2 : "auto"]]));
48
48
  return /* @__PURE__ */ jsx("div", {
49
49
  "data-layout-item": true,
50
- className: cx("min-w-0 text-sm", visible, sharedRows && slotClass, alignRows && sharedRowsClass, node.type === "grid" && "col-span-(--layout-span-base) @min-[24rem]/layout:col-span-(--layout-span-sm) @min-[40rem]/layout:col-span-(--layout-span-md) @min-[64rem]/layout:col-span-(--layout-span-lg)"),
50
+ className: clsx("min-w-0 text-sm", visible, sharedRows && slotClass, alignRows && sharedRowsClass, node.type === "grid" && "col-span-(--layout-span-base) @min-[24rem]/layout:col-span-(--layout-span-sm) @min-[40rem]/layout:col-span-(--layout-span-md) @min-[64rem]/layout:col-span-(--layout-span-lg)"),
51
51
  style,
52
52
  children: /* @__PURE__ */ jsx(LayoutNode, {
53
53
  node: child,
@@ -75,9 +75,9 @@ function LayoutNode({ node, renderField, sharedRows }) {
75
75
  };
76
76
  return /* @__PURE__ */ jsx("div", {
77
77
  "data-layout-grid": true,
78
- className: cx("@container/layout min-w-0 max-w-full", visible),
78
+ className: clsx("@container/layout min-w-0 max-w-full", visible),
79
79
  children: /* @__PURE__ */ jsx("div", {
80
- className: cx("grid gap-(--layout-gap) grid-cols-(--layout-columns-base) @min-[24rem]/layout:grid-cols-(--layout-columns-sm) @min-[40rem]/layout:grid-cols-(--layout-columns-md) @min-[64rem]/layout:grid-cols-(--layout-columns-lg)", !alignRows && "items-start"),
80
+ className: clsx("grid gap-(--layout-gap) grid-cols-(--layout-columns-base) @min-[24rem]/layout:grid-cols-(--layout-columns-sm) @min-[40rem]/layout:grid-cols-(--layout-columns-md) @min-[64rem]/layout:grid-cols-(--layout-columns-lg)", !alignRows && "items-start"),
81
81
  style,
82
82
  children
83
83
  })
@@ -88,7 +88,7 @@ function LayoutNode({ node, renderField, sharedRows }) {
88
88
  "aria-labelledby": labelId,
89
89
  "aria-describedby": node.description ? descriptionId : void 0,
90
90
  "data-layout-section": true,
91
- className: cx("min-w-0 max-w-full text-sm gap-(--layout-gap)", sharedRowsClass, visible),
91
+ className: clsx("min-w-0 max-w-full text-sm gap-(--layout-gap)", sharedRowsClass, visible),
92
92
  style: customStyle,
93
93
  children: [/* @__PURE__ */ jsxs("div", {
94
94
  "data-layout-header": true,
@@ -118,7 +118,7 @@ function LayoutNode({ node, renderField, sharedRows }) {
118
118
  });
119
119
  if (node.type === "section") return /* @__PURE__ */ jsxs("fieldset", {
120
120
  "data-layout-section": true,
121
- className: cx("min-w-0 max-w-full border-0 p-0", visible),
121
+ className: clsx("min-w-0 max-w-full border-0 p-0", visible),
122
122
  "aria-describedby": node.description ? descriptionId : void 0,
123
123
  style: customStyle,
124
124
  children: [/* @__PURE__ */ jsx("legend", {
@@ -136,7 +136,7 @@ function LayoutNode({ node, renderField, sharedRows }) {
136
136
  });
137
137
  return /* @__PURE__ */ jsx("div", {
138
138
  "data-layout-stack": true,
139
- className: cx("min-w-0 max-w-full", visible),
139
+ className: clsx("min-w-0 max-w-full", visible),
140
140
  children: body
141
141
  });
142
142
  }
@@ -1,5 +1,2 @@
1
1
  import type { WizardContainerProps } from './types.js';
2
- export declare function WizardContainer({ wizardConfig, values, onChange, onSubmit, className, labelPosition, missingFields, spaceCompact, workflowForm, nested, fieldNamePrefix, setFieldValue, setFieldTouched, }: WizardContainerProps & {
3
- setFieldValue: (field: string, value: unknown, shouldValidate?: boolean) => void;
4
- setFieldTouched: (field: string, touched?: boolean, shouldValidate?: boolean) => void;
5
- }): import("react").JSX.Element;
2
+ export declare function WizardContainer({ wizardConfig, onSubmit, className, labelPosition, spaceCompact, nested, fieldNamePrefix, }: WizardContainerProps): import("react").JSX.Element;
@@ -1,25 +1,40 @@
1
1
  import { useStrings, useWorkflowEngine } from "../../components/Provider.js";
2
2
  import { copyBounds, stepText } from "./utils.js";
3
3
  import { initializeValues } from "../lib.js";
4
- import { getValueUsingPath } from "../utils/getValueUsingPath.js";
5
4
  import { useFormEditing } from "../formEditing.js";
5
+ import { fieldPath } from "../utils/fieldPath.js";
6
+ import { getValueUsingPath } from "../utils/getValueUsingPath.js";
6
7
  import { useWizardState } from "./useWizardState.js";
7
8
  import { WizardNavigation } from "./WizardNavigation.js";
8
9
  import { WizardStepContent } from "./WizardStepContent.js";
9
10
  import { WizardStepIndicator } from "./WizardStepIndicator.js";
10
11
  import { WizardPagesContext } from "./wizardPages.js";
11
- import { useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
12
12
  import { jsx, jsxs } from "react/jsx-runtime";
13
- import { useFormikContext } from "formik";
13
+ import { useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
14
+ import { useFormContext, useWatch } from "react-hook-form";
14
15
  //#region src/form/Wizard/WizardContainer.tsx
15
- function WizardContainer({ wizardConfig, values, onChange, onSubmit, className = "", labelPosition = "left", missingFields = [], spaceCompact = false, workflowForm = false, nested = false, fieldNamePrefix = "", setFieldValue, setFieldTouched }) {
16
- const { validateForm, setTouched, touched, initialValues } = useFormikContext();
16
+ function WizardContainer({ wizardConfig, onSubmit, className = "", labelPosition = "left", spaceCompact = false, nested = false, fieldNamePrefix = "" }) {
17
+ const form = useFormContext();
18
+ const { control, getValues, getFieldState, subscribe } = form;
17
19
  const editing = useFormEditing();
18
20
  const pages = useContext(WizardPagesContext);
19
21
  const [ownPage, setOwnPage] = useState(0);
20
22
  const { form: strings } = useStrings();
21
23
  const engine = useWorkflowEngine();
22
24
  const { config, steps, stepOrder } = wizardConfig;
25
+ const titleReads = useMemo(() => {
26
+ const texts = Object.values(steps).flatMap((step) => [step.title, step.description].flat().filter((text) => text?.includes("${{")));
27
+ return [...new Set(texts.flatMap((text) => [...engine.inputDependencies(text).inputDeps]))];
28
+ }, [steps, engine]);
29
+ useWatch({
30
+ control,
31
+ compute: (values) => JSON.stringify([stepOrder.map((step) => {
32
+ const rows = getValueUsingPath(values, `${fieldNamePrefix}${step}`);
33
+ return Array.isArray(rows) ? rows.length : -1;
34
+ }), titleReads.map((dep) => getValueUsingPath(values, dep))])
35
+ });
36
+ const values = getValues();
37
+ const setFieldValue = useCallback((name, value) => form.setValue(fieldPath(name), value, { shouldDirty: true }), [form]);
23
38
  const reads = useRef(/* @__PURE__ */ new Map());
24
39
  const perCopy = useCallback((value, copy, numbered) => {
25
40
  if (Array.isArray(value)) return value[copy] ?? (numbered ? strings.copyTitle(value[0] ?? "", copy + 1) : "");
@@ -113,8 +128,15 @@ function WizardContainer({ wizardConfig, values, onChange, onSubmit, className =
113
128
  ]);
114
129
  const setAside = useRef({});
115
130
  useEffect(() => {
116
- setAside.current = {};
117
- }, [initialValues]);
131
+ let loaded;
132
+ return subscribe({
133
+ formState: { values: true },
134
+ callback: ({ defaultValues }) => {
135
+ if (loaded !== void 0 && defaultValues !== loaded) setAside.current = {};
136
+ loaded = defaultValues;
137
+ }
138
+ });
139
+ }, [subscribe]);
118
140
  useEffect(() => {
119
141
  for (const step of stepOrder) {
120
142
  const stepConfig = steps[step];
@@ -144,28 +166,12 @@ function WizardContainer({ wizardConfig, values, onChange, onSubmit, className =
144
166
  const page = shown.byKey[pageKey];
145
167
  if (!page?.config.options) return true;
146
168
  const stepPrefix = page.copy !== void 0 ? `${fieldNamePrefix}${page.step}[${page.copy}].` : config.flatten !== false ? fieldNamePrefix : `${fieldNamePrefix}${page.step}.`;
147
- const stepFieldPaths = Object.keys(page.config.options).map((name) => `${stepPrefix}${name}`);
148
- const errors = await validateForm();
149
- const hasStepErrors = stepFieldPaths.some((path) => getValueUsingPath(errors, path));
150
- if (hasStepErrors) {
151
- if (stepPrefix) for (const path of stepFieldPaths) setFieldTouched(path, true, false);
152
- else {
153
- const touchedFields = Object.fromEntries(stepFieldPaths.map((path) => [path, true]));
154
- setTouched({
155
- ...touched,
156
- ...touchedFields
157
- }, false);
158
- }
159
- }
160
- return !hasStepErrors;
169
+ return !Object.keys(page.config.options).map((name) => `${stepPrefix}${name}`).some((path) => getFieldState(fieldPath(path)).invalid);
161
170
  }, [
162
171
  shown,
163
172
  config,
164
173
  fieldNamePrefix,
165
- validateForm,
166
- setTouched,
167
- setFieldTouched,
168
- touched
174
+ getFieldState
169
175
  ]);
170
176
  const { currentStep, visitedSteps, invalidSteps, isLastStep, canGoBack, goToNext, goToPrevious, jumpToStep, showStep } = useWizardState({
171
177
  stepOrder: shown.order,
@@ -173,33 +179,17 @@ function WizardContainer({ wizardConfig, values, onChange, onSubmit, className =
173
179
  validateStep: validateCurrentStep
174
180
  });
175
181
  const navigation = config.navigation ?? {};
176
- const handleGoToNext = useCallback(async () => {
177
- const success = await goToNext();
178
- if (success) onChange?.(values);
179
- return success;
180
- }, [
181
- goToNext,
182
- values,
183
- onChange
184
- ]);
185
182
  const handleSubmit = useCallback(async () => {
186
183
  if (!isLastStep) return;
187
- const errors = await validateForm();
188
- if (Object.keys(errors).length > 0) {
189
- const touchedFields = Object.fromEntries(Object.keys(values).map((name) => [name, true]));
190
- setTouched({
191
- ...touched,
192
- ...touchedFields
193
- }, false);
194
- throw new Error("Please fix errors before submitting");
195
- }
196
- await onSubmit?.(values);
184
+ let submitted = false;
185
+ await form.handleSubmit(async (values) => {
186
+ submitted = true;
187
+ await onSubmit?.(values);
188
+ })();
189
+ if (!submitted) throw new Error("Please fix errors before submitting");
197
190
  }, [
198
191
  isLastStep,
199
- validateForm,
200
- values,
201
- setTouched,
202
- touched,
192
+ form,
203
193
  onSubmit
204
194
  ]);
205
195
  const last = Math.max(shown.order.length - 1, 0);
@@ -279,16 +269,10 @@ function WizardContainer({ wizardConfig, values, onChange, onSubmit, className =
279
269
  currentStep: page.step,
280
270
  stepConfig: page.config,
281
271
  flatten: config.flatten,
282
- values,
283
272
  labelPosition,
284
- missingFields,
285
273
  spaceCompact,
286
- setFormDirty: () => onChange?.(values),
287
- workflowForm,
288
274
  fieldNamePrefix,
289
- copy: page.copy,
290
- setFieldValue,
291
- setFieldTouched
275
+ copy: page.copy
292
276
  }), copies]
293
277
  }) : null;
294
278
  if (editing) return /* @__PURE__ */ jsxs("div", {
@@ -345,7 +329,7 @@ function WizardContainer({ wizardConfig, values, onChange, onSubmit, className =
345
329
  nextLabel: page?.config.nextLabel,
346
330
  prevLabel: page?.config.prevLabel,
347
331
  submitLabel: config.submitLabel || "Execute",
348
- onNext: handleGoToNext,
332
+ onNext: goToNext,
349
333
  onPrevious: goToPrevious,
350
334
  onSubmit: nested ? void 0 : handleSubmit
351
335
  })
@@ -1,6 +1,6 @@
1
1
  import Loader from "../../components/Loader.js";
2
- import { useState } from "react";
3
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useState } from "react";
4
4
  //#region src/form/Wizard/WizardNavigation.tsx
5
5
  function WizardNavigation({ isLastStep, canGoBack, isCurrentStepValid, nextLabel, prevLabel, submitLabel = "Submit", onNext, onPrevious, onSubmit }) {
6
6
  const [isLoading, setIsLoading] = useState(false);
@@ -1,8 +1,4 @@
1
- import type { TSetFormDirty } from '../Form.js';
2
1
  import type { WizardStepContentProps } from './types.js';
3
- export declare function WizardStepContent({ currentStep, stepConfig, flatten, values, setFormDirty, setFieldValue, setFieldTouched, fieldNamePrefix, copy, ...fieldsProps }: WizardStepContentProps & {
4
- setFormDirty: TSetFormDirty;
5
- setFieldValue: (field: string, value: unknown, shouldValidate?: boolean) => void;
6
- setFieldTouched: (field: string, touched?: boolean, shouldValidate?: boolean) => void;
2
+ export declare function WizardStepContent({ currentStep, stepConfig, flatten, fieldNamePrefix, copy, ...fieldsProps }: WizardStepContentProps & {
7
3
  flatten?: boolean | undefined;
8
4
  }): import("react").JSX.Element | null;
@@ -2,22 +2,21 @@ import { stepText } from "./utils.js";
2
2
  import { EditingScope, useFormEditing } from "../formEditing.js";
3
3
  import { FieldsFromOptions } from "../Form.js";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
+ import { useMemo } from "react";
5
6
  //#region src/form/Wizard/WizardStepContent.tsx
6
- function WizardStepContent({ currentStep, stepConfig, flatten = true, values, setFormDirty, setFieldValue, setFieldTouched, fieldNamePrefix = "", copy, ...fieldsProps }) {
7
+ function WizardStepContent({ currentStep, stepConfig, flatten = true, fieldNamePrefix = "", copy, ...fieldsProps }) {
7
8
  const editing = useFormEditing();
8
- if (!stepConfig.options) return null;
9
- const path = editing ? [...editing.parent, currentStep] : null;
10
- const parentInfo = copy !== void 0 ? {
11
- parentName: currentStep,
9
+ const parentInfo = useMemo(() => copy !== void 0 ? {
12
10
  fieldNamePrefix: `${fieldNamePrefix}${currentStep}[${copy}].`,
13
11
  arrayIndex: copy
14
- } : flatten === false ? {
15
- parentName: currentStep,
16
- fieldNamePrefix: `${fieldNamePrefix}${currentStep}.`
17
- } : fieldNamePrefix ? {
18
- parentName: fieldNamePrefix.slice(0, -1),
19
- fieldNamePrefix
20
- } : void 0;
12
+ } : flatten === false ? { fieldNamePrefix: `${fieldNamePrefix}${currentStep}.` } : fieldNamePrefix ? { fieldNamePrefix } : void 0, [
13
+ copy,
14
+ flatten,
15
+ fieldNamePrefix,
16
+ currentStep
17
+ ]);
18
+ if (!stepConfig.options) return null;
19
+ const path = editing ? [...editing.parent, currentStep] : null;
21
20
  const content = /* @__PURE__ */ jsxs("div", {
22
21
  className: "mb-4 w-full",
23
22
  children: [
@@ -36,10 +35,6 @@ function WizardStepContent({ currentStep, stepConfig, flatten = true, values, se
36
35
  path,
37
36
  children: /* @__PURE__ */ jsx(FieldsFromOptions, {
38
37
  options: stepConfig.options,
39
- values,
40
- setFormDirty,
41
- setFieldValue,
42
- setFieldTouched,
43
38
  ...parentInfo ? { parentInfo } : {},
44
39
  ...fieldsProps
45
40
  }, copy === void 0 ? currentStep : `${currentStep}[${copy}]`)
@@ -1,8 +1,8 @@
1
1
  import { useStrings } from "../../components/Provider.js";
2
2
  import { stepText } from "./utils.js";
3
- import cx from "classnames";
4
- import { useEffect, useRef, useState } from "react";
3
+ import { clsx } from "clsx";
5
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
+ import { useEffect, useRef, useState } from "react";
6
6
  //#region src/form/Wizard/WizardStepIndicator.tsx
7
7
  function WizardStepIndicator({ stepOrder, currentStep, steps, visitedSteps, invalidSteps, onStepClick, allowJump = false, hideStepNumbers = false }) {
8
8
  const { form: strings } = useStrings();
@@ -52,7 +52,7 @@ function WizardStepIndicator({ stepOrder, currentStep, steps, visitedSteps, inva
52
52
  onClick: () => onStepClick(stepKey),
53
53
  disabled: !isClickable,
54
54
  "aria-current": isDotActive ? "step" : void 0,
55
- className: cx("w-12 h-12 rounded-full border-3 flex items-center justify-center font-bold text-base transition-all duration-300 flex-shrink-0 relative", {
55
+ className: clsx("w-12 h-12 rounded-full border-3 flex items-center justify-center font-bold text-base transition-all duration-300 flex-shrink-0 relative", {
56
56
  "cursor-pointer": isClickable,
57
57
  "cursor-not-allowed": !isClickable
58
58
  }, {
@@ -71,7 +71,7 @@ function WizardStepIndicator({ stepOrder, currentStep, steps, visitedSteps, inva
71
71
  "aria-label": `Step ${index + 1}: ${stepText(stepConfig?.title)}`,
72
72
  title: stepText(stepConfig?.title),
73
73
  children: [!hideStepNumbers && /* @__PURE__ */ jsx("span", {
74
- className: cx({ hidden: status === "completed" }),
74
+ className: clsx({ hidden: status === "completed" }),
75
75
  children: index + 1
76
76
  }), status === "completed" && /* @__PURE__ */ jsx("svg", {
77
77
  "aria-hidden": "true",
@@ -88,7 +88,7 @@ function WizardStepIndicator({ stepOrder, currentStep, steps, visitedSteps, inva
88
88
  })]
89
89
  }),
90
90
  index < stepOrder.length - 1 && /* @__PURE__ */ jsx("div", {
91
- className: cx("absolute h-1 transition-all duration-300", {
91
+ className: clsx("absolute h-1 transition-all duration-300", {
92
92
  "bg-green-500": index < currentIndex,
93
93
  "bg-(--theme-border)": index >= currentIndex,
94
94
  "opacity-25": index >= currentIndex
@@ -104,7 +104,7 @@ function WizardStepIndicator({ stepOrder, currentStep, steps, visitedSteps, inva
104
104
  /* @__PURE__ */ jsxs("div", {
105
105
  className: "mt-2 text-center",
106
106
  children: [/* @__PURE__ */ jsx("div", {
107
- className: cx("text-sm text-center transition-colors duration-300 max-w-30", {
107
+ className: clsx("text-sm text-center transition-colors duration-300 max-w-30", {
108
108
  "font-bold text-green-600": isDotCompleted && !isInvalid,
109
109
  "font-bold text-red-600": isInvalid && status !== "active",
110
110
  "font-semibold theme-muted-text": !isDotActive && !isDotCompleted && !isInvalid,
@@ -58,22 +58,14 @@ export interface ParsedWizardConfig {
58
58
  export interface WizardContainerProps {
59
59
  /** Parsed wizard configuration and steps */
60
60
  wizardConfig: ParsedWizardConfig;
61
- /** Current form values */
62
- values: Record<string, unknown>;
63
- /** Callback when values change */
64
- onChange?: (values: Record<string, unknown>) => void;
65
61
  /** Callback when wizard is submitted */
66
62
  onSubmit?: ((values: Record<string, unknown>) => void) | undefined;
67
63
  /** Additional CSS classes */
68
64
  className?: string;
69
65
  /** Label position for fields */
70
66
  labelPosition?: 'left' | 'top' | undefined;
71
- /** Missing fields list */
72
- missingFields?: string[];
73
67
  /** Space compact mode */
74
68
  spaceCompact?: boolean;
75
- /** Workflow form mode */
76
- workflowForm?: boolean;
77
69
  /** A wizard inside a group submits with the form around it, so its last step has no submit. */
78
70
  nested?: boolean;
79
71
  /** Where the fields' values sit when the wizard is inside a group that keeps its own values. */
@@ -131,16 +123,10 @@ export interface WizardStepContentProps {
131
123
  currentStep: string;
132
124
  /** Current step configuration */
133
125
  stepConfig: StepFieldConfig;
134
- /** Form values */
135
- values: Record<string, unknown>;
136
126
  /** Label position for fields */
137
127
  labelPosition?: LabelPosition | undefined;
138
- /** Missing fields list */
139
- missingFields?: string[];
140
128
  /** Space compact mode */
141
129
  spaceCompact?: boolean;
142
- /** Workflow form mode */
143
- workflowForm?: boolean;
144
130
  /** Where the fields' values sit when the wizard is inside a group that keeps its own values. */
145
131
  fieldNamePrefix?: string | undefined;
146
132
  /** Which copy of a repeated page this is; its fields' values sit in that row of the page's list. */
@@ -1,6 +1,6 @@
1
1
  import type React from 'react';
2
2
  import type { FieldComponentProps } from './types/fieldComponentTypes.js';
3
- export type FieldComponent = React.ComponentType<FieldComponentProps<any, any>>;
3
+ export type FieldComponent = React.ComponentType<FieldComponentProps<any>>;
4
4
  export declare const FieldRegistryContext: React.Context<Record<string, FieldComponent>>;
5
5
  /** Returns null for field types no registry knows. Per-form `fields` win over
6
6
  * the provider's `slots.formFields`, which win over the core registry. */
@@ -3,7 +3,7 @@ import BooleanField from "./Fields/BooleanField.js";
3
3
  import CheckboxGroupField from "./Fields/CheckboxGroupField.js";
4
4
  import ColorField from "./Fields/ColorField.js";
5
5
  import DropdownField from "./Fields/DropdownField.js";
6
- import DurationField_default from "./Fields/DurationField.js";
6
+ import DurationField from "./Fields/DurationField.js";
7
7
  import LabelField from "./Fields/LabelField.js";
8
8
  import MultiDropdownField from "./Fields/MultiDropdownField.js";
9
9
  import NumberField from "./Fields/NumberField.js";
@@ -11,20 +11,20 @@ import ObjectField from "./Fields/ObjectField.js";
11
11
  import RadioField from "./Fields/RadioField.js";
12
12
  import RangeField from "./Fields/RangeField.js";
13
13
  import StepField from "./Fields/StepField.js";
14
- import StringField_default from "./Fields/StringField.js";
14
+ import StringField from "./Fields/StringField.js";
15
15
  import TextAreaField from "./Fields/TextAreaField.js";
16
- import { Suspense, createContext, useContext } from "react";
17
16
  import { jsx } from "react/jsx-runtime";
17
+ import { Suspense, createContext, useContext } from "react";
18
18
  //#region src/form/fieldRegistry.tsx
19
19
  var CORE_FIELD_COMPONENTS = {
20
- string: StringField_default,
21
- password: StringField_default,
20
+ string: StringField,
21
+ password: StringField,
22
22
  number: NumberField,
23
23
  boolean: BooleanField,
24
24
  dropdown: DropdownField,
25
25
  textarea: TextAreaField,
26
26
  range: RangeField,
27
- duration: DurationField_default,
27
+ duration: DurationField,
28
28
  radio: RadioField,
29
29
  label: LabelField,
30
30
  color: ColorField,
@@ -1,5 +1,5 @@
1
- import { createContext, useContext } from "react";
2
1
  import { jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext } from "react";
3
3
  //#region src/form/formEditing.tsx
4
4
  var FormEditingContext = createContext(null);
5
5
  function useFormEditing() {
@@ -1,19 +1,20 @@
1
+ export { FieldGroup } from './FieldGroup.js';
1
2
  export { getInvalidDurationPaths, setDurationValidity, } from './Fields/durationValidity.js';
2
3
  export { default as NumberField, type INumberField, } from './Fields/NumberField.js';
3
4
  export { ResourceOptionIcon } from './Fields/ResourceOptionIcon.js';
4
5
  export { type FieldLabelBinding, FieldWrapper } from './FieldWrapper.js';
5
- export { collectFieldsWithDefaults, DynamicDefaultsSync, DynamicForm, type DynamicFormProps, FieldsFromOptions, findSelfReferencingFieldNames, GroupHeader, MultiSelectionDropdown, resolveMetaOverrides, type TSetFormDirty, useDynamicDefaultsSync, } from './Form.js';
6
+ export { collectFieldsWithDefaults, DynamicDefaultsSync, DynamicForm, type DynamicFormProps, FieldsFromOptions, type FormValues, findSelfReferencingFieldNames, type ParentInfo, resolveMetaOverrides, useDynamicDefaultsSync, } from './Form.js';
6
7
  export { type FieldContextValue, FieldProvider, useFieldControlProps, useFieldLabelledByProps, useFieldRequired, } from './fieldContext.js';
7
8
  export { type FieldComponent, FieldRegistryContext, Registry, } from './fieldRegistry.js';
8
9
  export { type FormLayoutIssue, type FormLayoutNode, type LayoutBreakpoint, type LayoutGap, type LayoutTracks, type ResponsiveLayout, resolveFormLayout, } from './layout.js';
9
10
  export { type LayoutCSSIssue, resolveLayoutCSS, } from './layoutCSS.js';
10
11
  export { enforceOneMustBeTrue, flattenGroups, impureSetValueFromPath, initializeValues, resolvedFlag, } from './lib.js';
11
- export { default as DropdownWrapper } from './SpecialTypes/DropdownWrapper.js';
12
- export { default as FormikMultiSelectDropdown } from './SpecialTypes/FormikMultiSelectDropdown.js';
13
- export { FormikCustomDropdown, FormikCustomInput, FormikNumericInput, } from './SpecialTypes/index.js';
14
12
  export * from './types/fieldComponentTypes.js';
15
13
  export * from './types/fieldTypes.js';
14
+ export { type ChoiceItem, useChoiceField } from './useChoiceField.js';
15
+ export { useFieldValue } from './useFieldValue.js';
16
16
  export { useParsedOpts } from './useParsedOpts.js';
17
+ export { useDependentOptions, useFieldAt } from './utils/dependentOptions.js';
17
18
  export { collectPartitionDurationIssues, FLEX_MAX_DURATION_RANGE, FLEX_WAIT_TIME_RANGE, formatDuration, parseDuration, STANDARD_MAX_DURATION_RANGE, } from './utils/duration.js';
18
19
  export { getPlaceholder } from './utils/getPlaceholder.js';
19
20
  export { applySecondaryField, findSecondaryOption, } from './utils/secondaryField.js';
@@ -1,20 +1,19 @@
1
1
  import { applySecondaryField, findSecondaryOption } from "./utils/secondaryField.js";
2
2
  import { enforceOneMustBeTrue, flattenGroups, impureSetValueFromPath, initializeValues, resolvedFlag } from "./lib.js";
3
+ import { FieldGroup } from "./FieldGroup.js";
3
4
  import { resolveFormLayout } from "./layout.js";
4
5
  import { resolveLayoutCSS } from "./layoutCSS.js";
5
6
  import { FieldProvider, useFieldControlProps, useFieldLabelledByProps, useFieldRequired } from "./fieldContext.js";
6
7
  import { FieldWrapper } from "./FieldWrapper.js";
7
- import FormikCustomDropdown_default from "./SpecialTypes/FormikCustomDropdown.js";
8
- import FormikCustomInput from "./SpecialTypes/FormikCustomInput.js";
9
- import FormikNumericInput from "./SpecialTypes/FormikNumericInput.js";
8
+ import { useFieldValue } from "./useFieldValue.js";
9
+ import { useChoiceField } from "./useChoiceField.js";
10
+ import { useDependentOptions, useFieldAt } from "./utils/dependentOptions.js";
10
11
  import { getPlaceholder } from "./utils/getPlaceholder.js";
11
12
  import { FLEX_MAX_DURATION_RANGE, FLEX_WAIT_TIME_RANGE, STANDARD_MAX_DURATION_RANGE, collectPartitionDurationIssues, formatDuration, parseDuration } from "./utils/duration.js";
12
13
  import { getInvalidDurationPaths, setDurationValidity } from "./Fields/durationValidity.js";
13
14
  import NumberField from "./Fields/NumberField.js";
14
15
  import { FieldRegistryContext, Registry } from "./fieldRegistry.js";
15
16
  import { useParsedOpts } from "./useParsedOpts.js";
16
- import { DynamicDefaultsSync, DynamicForm, FieldsFromOptions, GroupHeader, MultiSelectionDropdown, collectFieldsWithDefaults, findSelfReferencingFieldNames, resolveMetaOverrides, useDynamicDefaultsSync } from "./Form.js";
17
+ import { DynamicDefaultsSync, DynamicForm, FieldsFromOptions, collectFieldsWithDefaults, findSelfReferencingFieldNames, resolveMetaOverrides, useDynamicDefaultsSync } from "./Form.js";
17
18
  import { ResourceOptionIcon } from "./Fields/ResourceOptionIcon.js";
18
- import DropdownWrapper from "./SpecialTypes/DropdownWrapper.js";
19
- import FormikMultiSelectDropdown from "./SpecialTypes/FormikMultiSelectDropdown.js";
20
- export { DropdownWrapper, DynamicDefaultsSync, DynamicForm, FLEX_MAX_DURATION_RANGE, FLEX_WAIT_TIME_RANGE, FieldProvider, FieldRegistryContext, FieldWrapper, FieldsFromOptions, FormikCustomDropdown_default as FormikCustomDropdown, FormikCustomInput, FormikMultiSelectDropdown, FormikNumericInput, GroupHeader, MultiSelectionDropdown, NumberField, Registry, ResourceOptionIcon, STANDARD_MAX_DURATION_RANGE, applySecondaryField, collectFieldsWithDefaults, collectPartitionDurationIssues, enforceOneMustBeTrue, findSecondaryOption, findSelfReferencingFieldNames, flattenGroups, formatDuration, getInvalidDurationPaths, getPlaceholder, impureSetValueFromPath, initializeValues, parseDuration, resolveFormLayout, resolveLayoutCSS, resolveMetaOverrides, resolvedFlag, setDurationValidity, useDynamicDefaultsSync, useFieldControlProps, useFieldLabelledByProps, useFieldRequired, useParsedOpts };
19
+ export { DynamicDefaultsSync, DynamicForm, FLEX_MAX_DURATION_RANGE, FLEX_WAIT_TIME_RANGE, FieldGroup, FieldProvider, FieldRegistryContext, FieldWrapper, FieldsFromOptions, NumberField, Registry, ResourceOptionIcon, STANDARD_MAX_DURATION_RANGE, applySecondaryField, collectFieldsWithDefaults, collectPartitionDurationIssues, enforceOneMustBeTrue, findSecondaryOption, findSelfReferencingFieldNames, flattenGroups, formatDuration, getInvalidDurationPaths, getPlaceholder, impureSetValueFromPath, initializeValues, parseDuration, resolveFormLayout, resolveLayoutCSS, resolveMetaOverrides, resolvedFlag, setDurationValidity, useChoiceField, useDependentOptions, useDynamicDefaultsSync, useFieldAt, useFieldControlProps, useFieldLabelledByProps, useFieldRequired, useFieldValue, useParsedOpts };
@@ -1,4 +1,3 @@
1
- import type { TSetFormDirty } from '../Form.js';
2
1
  import type { BaseField, LabelPosition, RuntimeFieldExtensions } from './fieldTypes.js';
3
2
  /** Intentionally loose to allow both manual types and schema-generated types. */
4
3
  interface FieldBase {
@@ -11,24 +10,23 @@ interface FieldBase {
11
10
  tooltip?: string | string[];
12
11
  default?: unknown;
13
12
  }
14
- export interface FieldComponentProps<TField extends FieldBase = FieldBase, TValue = unknown> {
13
+ /**
14
+ * What the form hands a field component. The field binds to its own value by `field.name`, with
15
+ * `useFieldValue` or react-hook-form's `useController`, and reads any other with `useWatch`, so it
16
+ * renders again only when what it reads changes.
17
+ */
18
+ export interface FieldComponentProps<TField extends FieldBase = FieldBase> {
15
19
  field: TField;
16
20
  label: string;
17
21
  labelPosition: LabelPosition;
22
+ /** The form marks the field as missing a value. */
18
23
  missing: boolean;
19
- missingFields: string[];
20
- values: Record<string, unknown>;
21
- setFormDirty: TSetFormDirty;
22
24
  onChange?: ((val: unknown) => void) | undefined;
23
25
  disabled: boolean;
24
26
  computeOn?: boolean | undefined;
25
27
  spaceCompact?: boolean;
26
28
  tooltipComponent?: React.ReactNode;
27
- workflowForm?: boolean;
28
- currentValue: TValue;
29
- setFieldValue?: (field: string, value: unknown, shouldValidate?: boolean) => void;
30
- setFieldTouched?: (field: string, isTouched?: boolean, shouldValidate?: boolean) => void;
31
29
  }
32
30
  /** Props for a field component, given the field definition it renders. */
33
- export type FieldProps<TField extends FieldBase = BaseField, TValue = unknown> = FieldComponentProps<TField & RuntimeFieldExtensions, TValue>;
31
+ export type FieldProps<TField extends FieldBase = BaseField> = FieldComponentProps<TField & RuntimeFieldExtensions>;
34
32
  export {};
@@ -0,0 +1,20 @@
1
+ import type { ComboboxItem, ComboboxItems } from '../components/Combobox.js';
2
+ /** An item that also sets other fields when chosen, through `secondaryField`. */
3
+ export type ChoiceItem = ComboboxItem<unknown> & {
4
+ secondaryValue?: unknown;
5
+ };
6
+ /**
7
+ * A field that picks one of `items`: its value, and the choice the person makes, which also sets the
8
+ * fields its `secondaryField` names from the item's `secondaryValue`.
9
+ *
10
+ * With `autoselect`, the first enabled item is picked whenever the items change; unset, an only item
11
+ * is. A value the form already holds stays on the first pass. The items change when their values or
12
+ * which are enabled do, so a field may rebuild them every render.
13
+ */
14
+ export declare function useChoiceField({ name, items, autoselect, secondaryField, onChange, }: {
15
+ name: string;
16
+ items: ComboboxItems<unknown>;
17
+ autoselect?: boolean | undefined;
18
+ secondaryField?: string | string[] | undefined;
19
+ onChange?: ((value: unknown) => void) | undefined;
20
+ }): [unknown, (value: unknown) => void];
@@ -0,0 +1,49 @@
1
+ import { applySecondaryField } from "./utils/secondaryField.js";
2
+ import { useFieldValue } from "./useFieldValue.js";
3
+ import { useEffect, useEffectEvent, useRef } from "react";
4
+ import { dequal } from "dequal";
5
+ import { useFormContext } from "react-hook-form";
6
+ //#region src/form/useChoiceField.ts
7
+ function leaves(items) {
8
+ return items.flatMap((item) => typeof item === "object" && "items" in item ? item.items : [item]);
9
+ }
10
+ var itemValue = (item) => typeof item === "string" ? item : item.value;
11
+ /**
12
+ * A field that picks one of `items`: its value, and the choice the person makes, which also sets the
13
+ * fields its `secondaryField` names from the item's `secondaryValue`.
14
+ *
15
+ * With `autoselect`, the first enabled item is picked whenever the items change; unset, an only item
16
+ * is. A value the form already holds stays on the first pass. The items change when their values or
17
+ * which are enabled do, so a field may rebuild them every render.
18
+ */
19
+ function useChoiceField({ name, items, autoselect, secondaryField, onChange }) {
20
+ const [value, change] = useFieldValue(name);
21
+ const { setValue } = useFormContext();
22
+ const choose = (next) => {
23
+ const chosen = leaves(items).find((item) => typeof item === "object" && dequal(item.value, next));
24
+ applySecondaryField(secondaryField, chosen?.secondaryValue, (field, secondary) => setValue(field, secondary, { shouldDirty: true }));
25
+ onChange?.(next);
26
+ change(next);
27
+ };
28
+ const first = useRef(true);
29
+ const select = useEffectEvent((items, autoselect) => {
30
+ const preset = first.current && value != null;
31
+ first.current = false;
32
+ if (preset || autoselect === false) return;
33
+ const all = leaves(items);
34
+ if (all.length === 0 || autoselect === void 0 && all.length !== 1) return;
35
+ if (!autoselect && all.some((item) => dequal(itemValue(item), value))) return;
36
+ const pick = all.find((item) => typeof item === "string" || !item.disabled);
37
+ if (pick !== void 0) choose(itemValue(pick));
38
+ });
39
+ const shape = [autoselect, leaves(items).map((item) => typeof item === "string" ? item : [item.value, Boolean(item.disabled)])];
40
+ const lastShape = useRef(void 0);
41
+ useEffect(() => {
42
+ if (dequal(lastShape.current, shape)) return;
43
+ lastShape.current = shape;
44
+ select(items, autoselect);
45
+ });
46
+ return [value, choose];
47
+ }
48
+ //#endregion
49
+ export { useChoiceField };
@@ -0,0 +1,7 @@
1
+ /**
2
+ * A field's value in the form, and how the person changes it. The field renders again when its own
3
+ * value changes, not when another field's does. A change marks the field touched as well as dirty: the
4
+ * form stops writing a computed default into a field once the person has set it, and a pick from a list
5
+ * sets a value without the blur that would otherwise mark it.
6
+ */
7
+ export declare function useFieldValue<T>(name: string): [T, (value: T) => void];
@@ -0,0 +1,20 @@
1
+ import { useCallback } from "react";
2
+ import { useController, useFormContext } from "react-hook-form";
3
+ //#region src/form/useFieldValue.ts
4
+ /**
5
+ * A field's value in the form, and how the person changes it. The field renders again when its own
6
+ * value changes, not when another field's does. A change marks the field touched as well as dirty: the
7
+ * form stops writing a computed default into a field once the person has set it, and a pick from a list
8
+ * sets a value without the blur that would otherwise mark it.
9
+ */
10
+ function useFieldValue(name) {
11
+ const { field } = useController({ name });
12
+ const { setValue } = useFormContext();
13
+ const change = useCallback((value) => setValue(name, value, {
14
+ shouldDirty: true,
15
+ shouldTouch: true
16
+ }), [name, setValue]);
17
+ return [field.value, change];
18
+ }
19
+ //#endregion
20
+ export { useFieldValue };