@parallelworks/ui 0.41.0 → 0.43.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.
- package/README.md +25 -0
- package/dist/ai/components/AllocationSelector.d.ts +3 -4
- package/dist/ai/components/AllocationSelector.js +37 -33
- package/dist/ai/components/AttachmentManager.js +7 -7
- package/dist/ai/components/AttachmentUpload.js +5 -5
- package/dist/ai/components/BranchNavigator.js +1 -1
- package/dist/ai/components/ChatEmptyState.js +2 -2
- package/dist/ai/components/ChatInput.js +10 -8
- package/dist/ai/components/ChatLayout.js +4 -5
- package/dist/ai/components/ChatMessage.js +12 -12
- package/dist/ai/components/ChatMessageList.js +9 -9
- package/dist/ai/components/ChatSidebar.js +8 -9
- package/dist/ai/components/ChatThread.js +4 -4
- package/dist/ai/components/ComposerChrome.d.ts +2 -2
- package/dist/ai/components/ComposerChrome.js +3 -6
- package/dist/ai/components/DragOverlay.js +2 -2
- package/dist/ai/components/ModelSelector.d.ts +5 -3
- package/dist/ai/components/ModelSelector.js +102 -339
- package/dist/ai/components/PastedText.js +11 -11
- package/dist/ai/components/ProviderIssueBanner.d.ts +2 -0
- package/dist/ai/components/ProviderIssueBanner.js +34 -16
- package/dist/ai/components/Reasoning.js +4 -4
- package/dist/ai/components/ShareDialog.js +43 -35
- package/dist/ai/components/SlashMenu.d.ts +12 -2
- package/dist/ai/components/SlashMenu.js +29 -13
- package/dist/ai/components/agent/ActivityLine.js +3 -3
- package/dist/ai/components/agent/AgentMessageParts.js +20 -20
- package/dist/ai/components/agent/PermissionPicker.js +13 -11
- package/dist/ai/components/conversationActions.d.ts +4 -6
- package/dist/ai/components/conversationActions.js +9 -13
- package/dist/ai/core/ChatProvider.js +1 -1
- package/dist/ai/core/config.js +1 -1
- package/dist/ai/core/providerIssues.d.ts +7 -0
- package/dist/ai/core/providerIssues.js +9 -1
- package/dist/ai/core/useKeyboardShortcuts.d.ts +4 -0
- package/dist/ai/core/useKeyboardShortcuts.js +8 -2
- package/dist/ai/index.d.ts +0 -1
- package/dist/ai/index.js +1 -2
- package/dist/ai/strings.d.ts +19 -0
- package/dist/ai/strings.js +18 -1
- package/dist/ai/ui/Avatar.js +5 -5
- package/dist/ai/ui/ConversationSidebar.d.ts +0 -1
- package/dist/ai/ui/ConversationSidebar.js +6 -7
- package/dist/ai/ui/Markdown.js +3 -3
- package/dist/ai/ui/Notice.js +6 -6
- package/dist/ai/ui/chip.d.ts +4 -0
- package/dist/ai/ui/chip.js +8 -0
- package/dist/ai/ui/sidebar.d.ts +6 -5
- package/dist/ai/ui/sidebar.js +39 -43
- package/dist/components/ActionMenu.d.ts +13 -0
- package/dist/components/ActionMenu.js +30 -0
- package/dist/components/Avatar.js +6 -6
- package/dist/components/Breadcrumbs.js +1 -1
- package/dist/components/Button.js +10 -10
- package/dist/components/Callout.js +2 -2
- package/dist/components/Card.js +3 -3
- package/dist/components/Combobox.d.ts +49 -0
- package/dist/components/Combobox.js +405 -0
- package/dist/components/ConfirmModal.js +11 -11
- package/dist/components/ContextMenu.d.ts +23 -0
- package/dist/components/ContextMenu.js +89 -0
- package/dist/components/CopyToClipboard.js +2 -2
- package/dist/components/CreateModal.d.ts +19 -38
- package/dist/components/CreateModal.js +116 -267
- package/dist/components/DescriptionList.js +8 -8
- package/dist/components/Filter.js +2 -2
- package/dist/components/FilterPill.js +2 -2
- package/dist/components/HoverCard.d.ts +14 -0
- package/dist/components/HoverCard.js +33 -0
- package/dist/components/IconButton.d.ts +5 -5
- package/dist/components/IconButton.js +18 -22
- package/dist/components/InfoTip.d.ts +15 -0
- package/dist/components/InfoTip.js +60 -0
- package/dist/components/Input.js +5 -5
- package/dist/components/LetterBadge.js +2 -2
- package/dist/components/Loader.js +3 -3
- package/dist/components/Markdown.js +1 -1
- package/dist/components/MarkdownImpl.js +2 -2
- package/dist/components/Menu.d.ts +33 -0
- package/dist/components/Menu.js +86 -0
- package/dist/components/MenuEntries.d.ts +56 -0
- package/dist/components/MenuEntries.js +123 -0
- package/dist/components/Modal.d.ts +29 -0
- package/dist/components/Modal.js +47 -0
- package/dist/components/Overview.js +11 -10
- package/dist/components/PageHeader.d.ts +10 -16
- package/dist/components/PageHeader.js +69 -95
- package/dist/components/Pagination.js +5 -5
- package/dist/components/Provider.d.ts +5 -11
- package/dist/components/Provider.js +11 -14
- package/dist/components/Radio.d.ts +8 -0
- package/dist/components/Radio.js +16 -0
- package/dist/components/SectionHeader.js +2 -2
- package/dist/components/SegmentedControl.d.ts +6 -5
- package/dist/components/SegmentedControl.js +34 -30
- package/dist/components/Select.d.ts +27 -0
- package/dist/components/Select.js +78 -0
- package/dist/components/SettingModeOption.d.ts +5 -8
- package/dist/components/SettingModeOption.js +10 -12
- package/dist/components/SettingRow.js +4 -4
- package/dist/components/SettingsCard.js +4 -4
- package/dist/components/SettingsGroup.js +2 -2
- package/dist/components/Sort.js +1 -1
- package/dist/components/StatusBadge.js +7 -7
- package/dist/components/StatusIcons.js +4 -4
- package/dist/components/Switch.d.ts +22 -0
- package/dist/components/Switch.js +28 -0
- package/dist/components/Table.js +11 -11
- package/dist/components/Tooltip.d.ts +24 -20
- package/dist/components/Tooltip.js +58 -76
- package/dist/components/comboboxItems.d.ts +24 -0
- package/dist/components/comboboxItems.js +10 -0
- package/dist/components/floating.d.ts +14 -0
- package/dist/components/floating.js +21 -0
- package/dist/components/search.d.ts +2 -0
- package/dist/components/search.js +14 -0
- package/dist/editor/Editor.js +1 -1
- package/dist/editor/EditorField.js +16 -21
- package/dist/editor/FormCodePanel.js +19 -19
- package/dist/editor/Monaco.js +3 -3
- package/dist/file-explorer/FileExplorer.js +77 -81
- package/dist/file-explorer/FileExplorerContext.js +2 -2
- package/dist/file-explorer/FilePreview/CodePreviewEditor.js +1 -1
- package/dist/file-explorer/FilePreview/Inline.js +1 -1
- package/dist/file-explorer/FilePreview/StreamedBadge.js +5 -6
- package/dist/file-explorer/FilePreview/Viewer.js +8 -8
- package/dist/file-explorer/FilePreview/index.d.ts +1 -1
- package/dist/file-explorer/FilePreview/index.js +49 -83
- package/dist/file-explorer/FileRow.d.ts +4 -3
- package/dist/file-explorer/FileRow.js +32 -38
- package/dist/file-explorer/FileRowsWindow.d.ts +3 -2
- package/dist/file-explorer/FileRowsWindow.js +4 -4
- package/dist/file-explorer/FileTable.d.ts +3 -2
- package/dist/file-explorer/FileTable.js +3 -3
- package/dist/file-explorer/LoadMoreRow.js +1 -1
- package/dist/file-explorer/TreeView.js +11 -16
- package/dist/file-explorer/helpers.js +11 -12
- package/dist/file-explorer/toasts.js +11 -11
- package/dist/form/FieldGroup.d.ts +11 -0
- package/dist/form/FieldGroup.js +36 -0
- package/dist/form/FieldWrapper.js +4 -4
- package/dist/form/Fields/BooleanField.js +23 -33
- package/dist/form/Fields/CheckboxGroupField.d.ts +1 -1
- package/dist/form/Fields/CheckboxGroupField.js +9 -13
- package/dist/form/Fields/ColorField.d.ts +1 -2
- package/dist/form/Fields/ColorField.js +6 -11
- package/dist/form/Fields/DropdownField.d.ts +3 -13
- package/dist/form/Fields/DropdownField.js +40 -27
- package/dist/form/Fields/DurationField.d.ts +1 -2
- package/dist/form/Fields/DurationField.js +25 -32
- package/dist/form/Fields/LabelField.js +2 -2
- package/dist/form/Fields/MultiDropdownField.d.ts +6 -12
- package/dist/form/Fields/MultiDropdownField.js +31 -22
- package/dist/form/Fields/NumberField.d.ts +1 -1
- package/dist/form/Fields/NumberField.js +65 -35
- package/dist/form/Fields/ObjectField.d.ts +1 -1
- package/dist/form/Fields/ObjectField.js +12 -43
- package/dist/form/Fields/RadioField.d.ts +1 -1
- package/dist/form/Fields/RadioField.js +30 -41
- package/dist/form/Fields/RangeField.d.ts +1 -2
- package/dist/form/Fields/RangeField.js +23 -16
- package/dist/form/Fields/StringField.d.ts +1 -2
- package/dist/form/Fields/StringField.js +58 -26
- package/dist/form/Fields/TextAreaField.js +12 -10
- package/dist/form/Form.d.ts +30 -48
- package/dist/form/Form.js +306 -412
- package/dist/form/FormLayout.js +9 -9
- package/dist/form/Wizard/WizardContainer.d.ts +1 -4
- package/dist/form/Wizard/WizardContainer.js +40 -56
- package/dist/form/Wizard/WizardNavigation.js +1 -1
- package/dist/form/Wizard/WizardStepContent.d.ts +1 -5
- package/dist/form/Wizard/WizardStepContent.js +11 -16
- package/dist/form/Wizard/WizardStepIndicator.js +6 -6
- package/dist/form/Wizard/types.d.ts +0 -14
- package/dist/form/fieldRegistry.d.ts +1 -1
- package/dist/form/fieldRegistry.js +6 -6
- package/dist/form/formEditing.js +1 -1
- package/dist/form/index.d.ts +5 -4
- package/dist/form/index.js +6 -7
- package/dist/form/lib.js +3 -2
- package/dist/form/types/fieldComponentTypes.d.ts +8 -10
- package/dist/form/useChoiceField.d.ts +18 -0
- package/dist/form/useChoiceField.js +46 -0
- package/dist/form/useFieldValue.d.ts +7 -0
- package/dist/form/useFieldValue.js +20 -0
- package/dist/form/useParsedOpts.d.ts +3 -1
- package/dist/form/useParsedOpts.js +12 -17
- package/dist/form/utils/dependentOptions.d.ts +8 -4
- package/dist/form/utils/dependentOptions.js +25 -17
- package/dist/form/utils/fieldItems.d.ts +32 -0
- package/dist/form/utils/fieldItems.js +32 -0
- package/dist/form/utils/fieldPath.d.ts +10 -0
- package/dist/form/utils/fieldPath.js +20 -0
- package/dist/form/utils/shareEqual.d.ts +6 -0
- package/dist/form/utils/shareEqual.js +38 -0
- package/dist/graph/AnnotationBanner.js +8 -8
- package/dist/graph/Collapse.d.ts +1 -0
- package/dist/graph/Collapse.js +6 -27
- package/dist/graph/Connectors.js +5 -5
- package/dist/graph/DependencyGraph.js +20 -19
- package/dist/graph/GraphEditor.js +30 -41
- package/dist/graph/GraphEditorDialogs.js +17 -17
- package/dist/graph/GraphNode.js +1 -1
- package/dist/graph/InputDialog.js +19 -22
- package/dist/graph/InputsEditor.js +58 -66
- package/dist/graph/JobSummary.js +42 -39
- package/dist/graph/MatrixGroup.js +1 -1
- package/dist/graph/ProblemsButton.js +18 -19
- package/dist/graph/Reveal.js +1 -1
- package/dist/graph/ShortcutsButton.js +15 -18
- package/dist/graph/SuggestionInput.d.ts +5 -10
- package/dist/graph/SuggestionInput.js +14 -18
- package/dist/graph/ToolbarPopover.d.ts +11 -6
- package/dist/graph/ToolbarPopover.js +35 -67
- package/dist/graph/TreeView.js +24 -37
- package/dist/graph/WorkflowSettingsDialog.js +4 -4
- package/dist/graph/editorChrome.js +13 -12
- package/dist/graph/editorFields.js +29 -29
- package/dist/graph/editorPrimitives.d.ts +1 -1
- package/dist/graph/editorPrimitives.js +10 -7
- package/dist/graph/editorRows.js +103 -97
- package/dist/graph/fieldProblems.js +2 -2
- package/dist/graph/graphEditorState.d.ts +4 -3
- package/dist/graph/inputRefs.js +9 -9
- package/dist/graph/settingsViews.js +6 -7
- package/dist/graph/stepWith.js +6 -6
- package/dist/index.d.ts +14 -15
- package/dist/index.js +15 -14
- package/dist/list/ActionToolbar.d.ts +6 -14
- package/dist/list/ActionToolbar.js +48 -96
- package/dist/list/ListPage.d.ts +6 -12
- package/dist/list/ListPage.js +46 -29
- package/dist/list/ListPager.js +4 -4
- package/dist/list/ListTable.js +5 -5
- package/dist/list/ListViewControls.d.ts +5 -4
- package/dist/list/ListViewControls.js +177 -267
- package/dist/list/UserHoverCard.d.ts +3 -17
- package/dist/list/UserHoverCard.js +21 -45
- package/dist/list/index.d.ts +3 -4
- package/dist/list/index.js +3 -4
- package/dist/list/listSearch.js +12 -11
- package/dist/list/rowMenu.d.ts +68 -0
- package/dist/list/rowMenu.js +136 -0
- package/dist/logviewer/LogViewer.js +26 -26
- package/dist/styles.css +1 -1
- package/package.json +7 -13
- package/dist/ai/ui/Dropdown.d.ts +0 -31
- package/dist/ai/ui/Dropdown.js +0 -110
- package/dist/components/AddMenu.d.ts +0 -18
- package/dist/components/AddMenu.js +0 -46
- package/dist/components/BareModal.d.ts +0 -17
- package/dist/components/BareModal.js +0 -77
- package/dist/components/CollapsiblePanel.d.ts +0 -27
- package/dist/components/CollapsiblePanel.js +0 -77
- package/dist/components/Dropdown.d.ts +0 -28
- package/dist/components/Dropdown.js +0 -355
- package/dist/components/Listbox.d.ts +0 -21
- package/dist/components/Listbox.js +0 -119
- package/dist/components/MultiSelect.d.ts +0 -22
- package/dist/components/MultiSelect.js +0 -168
- package/dist/components/SwitchToggle.d.ts +0 -15
- package/dist/components/SwitchToggle.js +0 -57
- package/dist/components/SwitchToggleSmall.d.ts +0 -6
- package/dist/components/SwitchToggleSmall.js +0 -14
- package/dist/components/Toggle.d.ts +0 -6
- package/dist/components/Toggle.js +0 -20
- package/dist/components/dropdownUtils.d.ts +0 -37
- package/dist/components/dropdownUtils.js +0 -99
- package/dist/form/SpecialTypes/DropdownWrapper.d.ts +0 -25
- package/dist/form/SpecialTypes/DropdownWrapper.js +0 -28
- package/dist/form/SpecialTypes/FormikCustomDropdown.d.ts +0 -51
- package/dist/form/SpecialTypes/FormikCustomDropdown.js +0 -119
- package/dist/form/SpecialTypes/FormikCustomInput.d.ts +0 -19
- package/dist/form/SpecialTypes/FormikCustomInput.js +0 -121
- package/dist/form/SpecialTypes/FormikMultiSelectDropdown.d.ts +0 -13
- package/dist/form/SpecialTypes/FormikMultiSelectDropdown.js +0 -31
- package/dist/form/SpecialTypes/FormikNumericInput.d.ts +0 -9
- package/dist/form/SpecialTypes/FormikNumericInput.js +0 -60
- package/dist/form/SpecialTypes/index.d.ts +0 -3
- package/dist/list/HoverCard.d.ts +0 -24
- package/dist/list/HoverCard.js +0 -73
- package/dist/list/RowContextMenu.d.ts +0 -127
- package/dist/list/RowContextMenu.js +0 -515
package/dist/form/FormLayout.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { layoutBreakpoints, responsiveLayoutValues } from "./layout.js";
|
|
2
2
|
import { resolveLayoutCSS } from "./layoutCSS.js";
|
|
3
|
-
import
|
|
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:
|
|
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:
|
|
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:
|
|
78
|
+
className: clsx("@container/layout min-w-0 max-w-full", visible),
|
|
79
79
|
children: /* @__PURE__ */ jsx("div", {
|
|
80
|
-
className:
|
|
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:
|
|
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:
|
|
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:
|
|
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,
|
|
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 {
|
|
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,
|
|
16
|
-
const
|
|
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
|
-
|
|
117
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
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
|
-
|
|
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:
|
|
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,
|
|
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,
|
|
7
|
+
function WizardStepContent({ currentStep, stepConfig, flatten = true, fieldNamePrefix = "", copy, ...fieldsProps }) {
|
|
7
8
|
const editing = useFormEditing();
|
|
8
|
-
|
|
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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
21
|
-
password:
|
|
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:
|
|
27
|
+
duration: DurationField,
|
|
28
28
|
radio: RadioField,
|
|
29
29
|
label: LabelField,
|
|
30
30
|
color: ColorField,
|
package/dist/form/formEditing.js
CHANGED
package/dist/form/index.d.ts
CHANGED
|
@@ -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,
|
|
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';
|
package/dist/form/index.js
CHANGED
|
@@ -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
|
|
8
|
-
import
|
|
9
|
-
import
|
|
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,
|
|
17
|
+
import { DynamicDefaultsSync, DynamicForm, FieldsFromOptions, collectFieldsWithDefaults, findSelfReferencingFieldNames, resolveMetaOverrides, useDynamicDefaultsSync } from "./Form.js";
|
|
17
18
|
import { ResourceOptionIcon } from "./Fields/ResourceOptionIcon.js";
|
|
18
|
-
|
|
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 };
|
package/dist/form/lib.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { findChoice, toFieldItems } from "./utils/fieldItems.js";
|
|
2
|
+
import { applySecondaryField } from "./utils/secondaryField.js";
|
|
2
3
|
import { copyBounds } from "./Wizard/utils.js";
|
|
3
4
|
//#region src/form/lib.ts
|
|
4
5
|
var EMPTY_ENTRY = {};
|
|
@@ -107,7 +108,7 @@ function initializeValues(options, srcData = {}, blankDefault) {
|
|
|
107
108
|
if (data[field] !== void 0) {
|
|
108
109
|
acc[field] = data[field];
|
|
109
110
|
if ((fieldSchema.type === "dropdown" || fieldSchema.type === "storage") && fieldSchema.secondaryField && Array.isArray(fieldSchema.options)) {
|
|
110
|
-
const option =
|
|
111
|
+
const option = findChoice(toFieldItems(fieldSchema.options), data[field]);
|
|
111
112
|
applySecondaryField(fieldSchema.secondaryField, option?.secondaryValue, (secondaryField, secondaryValue) => {
|
|
112
113
|
if (!(fieldSchema.type === "storage" && Object.hasOwn(options, secondaryField) && source[secondaryField] !== void 0)) impureSetValueFromPath(acc, secondaryField, secondaryValue);
|
|
113
114
|
});
|
|
@@ -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
|
-
|
|
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
|
|
31
|
+
export type FieldProps<TField extends FieldBase = BaseField> = FieldComponentProps<TField & RuntimeFieldExtensions>;
|
|
34
32
|
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ComboboxItems } from '../components/Combobox.js';
|
|
2
|
+
import { type ChoiceItem } from './utils/fieldItems.js';
|
|
3
|
+
export type { ChoiceItem };
|
|
4
|
+
/**
|
|
5
|
+
* A field that picks one of `items`: its value, and the choice the person makes, which also sets the
|
|
6
|
+
* fields its `secondaryField` names from the item's `secondaryValue`.
|
|
7
|
+
*
|
|
8
|
+
* With `autoselect`, the first enabled item is picked whenever the items change; unset, an only item
|
|
9
|
+
* is. A value the form already holds stays on the first pass. The items change when their values or
|
|
10
|
+
* which are enabled do, so a field may rebuild them every render.
|
|
11
|
+
*/
|
|
12
|
+
export declare function useChoiceField({ name, items, autoselect, secondaryField, onChange, }: {
|
|
13
|
+
name: string;
|
|
14
|
+
items: ComboboxItems<unknown>;
|
|
15
|
+
autoselect?: boolean | undefined;
|
|
16
|
+
secondaryField?: string | string[] | undefined;
|
|
17
|
+
onChange?: ((value: unknown) => void) | undefined;
|
|
18
|
+
}): [unknown, (value: unknown) => void];
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { itemValue, leaves } from "./utils/fieldItems.js";
|
|
2
|
+
import { applySecondaryField } from "./utils/secondaryField.js";
|
|
3
|
+
import { useFieldValue } from "./useFieldValue.js";
|
|
4
|
+
import { useEffect, useEffectEvent, useRef } from "react";
|
|
5
|
+
import { dequal } from "dequal";
|
|
6
|
+
import { useFormContext } from "react-hook-form";
|
|
7
|
+
//#region src/form/useChoiceField.ts
|
|
8
|
+
/**
|
|
9
|
+
* A field that picks one of `items`: its value, and the choice the person makes, which also sets the
|
|
10
|
+
* fields its `secondaryField` names from the item's `secondaryValue`.
|
|
11
|
+
*
|
|
12
|
+
* With `autoselect`, the first enabled item is picked whenever the items change; unset, an only item
|
|
13
|
+
* is. A value the form already holds stays on the first pass. The items change when their values or
|
|
14
|
+
* which are enabled do, so a field may rebuild them every render.
|
|
15
|
+
*/
|
|
16
|
+
function useChoiceField({ name, items, autoselect, secondaryField, onChange }) {
|
|
17
|
+
const [value, change] = useFieldValue(name);
|
|
18
|
+
const { setValue } = useFormContext();
|
|
19
|
+
const choose = (next) => {
|
|
20
|
+
const chosen = leaves(items).find((item) => typeof item === "object" && dequal(item.value, next));
|
|
21
|
+
applySecondaryField(secondaryField, chosen?.secondaryValue, (field, secondary) => setValue(field, secondary, { shouldDirty: true }));
|
|
22
|
+
onChange?.(next);
|
|
23
|
+
change(next);
|
|
24
|
+
};
|
|
25
|
+
const first = useRef(true);
|
|
26
|
+
const select = useEffectEvent((items, autoselect) => {
|
|
27
|
+
const preset = first.current && value != null;
|
|
28
|
+
first.current = false;
|
|
29
|
+
if (preset || autoselect === false) return;
|
|
30
|
+
const all = leaves(items);
|
|
31
|
+
if (all.length === 0 || autoselect === void 0 && all.length !== 1) return;
|
|
32
|
+
if (!autoselect && all.some((item) => dequal(itemValue(item), value))) return;
|
|
33
|
+
const pick = all.find((item) => typeof item === "string" || !item.disabled);
|
|
34
|
+
if (pick !== void 0) choose(itemValue(pick));
|
|
35
|
+
});
|
|
36
|
+
const shape = [autoselect, leaves(items).map((item) => typeof item === "string" ? item : [item.value, Boolean(item.disabled)])];
|
|
37
|
+
const lastShape = useRef(void 0);
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (dequal(lastShape.current, shape)) return;
|
|
40
|
+
lastShape.current = shape;
|
|
41
|
+
select(items, autoselect);
|
|
42
|
+
});
|
|
43
|
+
return [value, choose];
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
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];
|