@parallelworks/ui 0.19.0 → 0.19.1

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 (217) hide show
  1. package/dist/{chunks/memoryStore-CC91S5LP.js → ai/adapter/memoryStore.js} +2 -2
  2. package/dist/ai/adapter/mock/index.js +2 -80
  3. package/dist/ai/adapter/mock/mockAdapter.js +81 -0
  4. package/dist/ai/adapter/openai/createOpenAIStream.js +33 -0
  5. package/dist/ai/adapter/openai/errors.js +37 -0
  6. package/dist/ai/adapter/openai/index.js +5 -333
  7. package/dist/ai/adapter/openai/openaiAdapter.js +54 -0
  8. package/dist/ai/adapter/openai/responses.js +108 -0
  9. package/dist/ai/adapter/openai/sse.js +112 -0
  10. package/dist/{chunks/types-Yy0NrerF.js → ai/adapter/types.js} +1 -1
  11. package/dist/ai/agent/classifier.js +12 -0
  12. package/dist/ai/agent/diff.js +223 -0
  13. package/dist/ai/agent/diffHighlight.js +101 -0
  14. package/dist/ai/agent/permissions.js +29 -0
  15. package/dist/ai/agent/toolfmt.js +383 -0
  16. package/dist/ai/agent/transcript.js +127 -0
  17. package/dist/ai/components/AllocationSelector.js +56 -0
  18. package/dist/ai/components/AttachmentManager.js +144 -0
  19. package/dist/ai/components/AttachmentUpload.js +179 -0
  20. package/dist/ai/components/BlockedGroupBanner.js +29 -0
  21. package/dist/ai/components/BranchNavigator.js +57 -0
  22. package/dist/ai/components/ChatEmptyState.js +171 -0
  23. package/dist/ai/components/ChatInput.js +265 -0
  24. package/dist/ai/components/ChatLayout.js +15 -0
  25. package/dist/ai/components/ChatMessage.js +338 -0
  26. package/dist/ai/components/ChatMessageList.js +301 -0
  27. package/dist/ai/components/ChatSidebar.js +345 -0
  28. package/dist/ai/components/ChatThread.js +198 -0
  29. package/dist/ai/components/ComposerChrome.js +50 -0
  30. package/dist/ai/components/ComposerFrame.js +33 -0
  31. package/dist/ai/components/DragOverlay.js +20 -0
  32. package/dist/ai/components/ModelSelector.js +343 -0
  33. package/dist/ai/components/ShareDialog.js +260 -0
  34. package/dist/ai/components/SlashMenu.js +91 -0
  35. package/dist/ai/components/agent/ActivityLine.js +151 -0
  36. package/dist/ai/components/agent/AgentMessageParts.js +721 -0
  37. package/dist/ai/components/agent/PermissionPicker.js +38 -0
  38. package/dist/ai/components/attachmentKeys.js +10 -0
  39. package/dist/ai/core/ChatProvider.js +848 -0
  40. package/dist/ai/core/KeyboardShortcutsProvider.js +9 -0
  41. package/dist/ai/core/chatReducer.js +223 -0
  42. package/dist/ai/core/config.js +45 -0
  43. package/dist/ai/core/events.js +4 -0
  44. package/dist/ai/core/exportConversation.js +42 -0
  45. package/dist/ai/core/greeting.js +38 -0
  46. package/dist/ai/core/parts.js +84 -0
  47. package/dist/ai/core/useDragDrop.js +36 -0
  48. package/dist/ai/core/useKeyboardShortcuts.js +77 -0
  49. package/dist/ai/core/useSSEStream.js +98 -0
  50. package/dist/ai/index.js +43 -6644
  51. package/dist/ai/strings.js +175 -0
  52. package/dist/ai/ui/Avatar.js +35 -0
  53. package/dist/ai/ui/Dropdown.js +110 -0
  54. package/dist/ai/ui/Markdown.js +79 -0
  55. package/dist/ai/ui/Notice.js +77 -0
  56. package/dist/ai/ui/codeBreaks.js +36 -0
  57. package/dist/ai/ui/prose.js +13 -0
  58. package/dist/ai/ui/sidebar.js +148 -0
  59. package/dist/ai/utils.js +23 -0
  60. package/dist/components/AddMenu.js +46 -0
  61. package/dist/components/Avatar.js +46 -0
  62. package/dist/{chunks/BareModal-BtRiQezg.js → components/BareModal.js} +1 -1
  63. package/dist/components/Breadcrumbs.js +83 -0
  64. package/dist/components/Button.js +83 -0
  65. package/dist/components/Callout.js +23 -0
  66. package/dist/components/Card.js +31 -0
  67. package/dist/components/CollapsiblePanel.js +77 -0
  68. package/dist/{chunks/ConfirmModal-aOR4O1QE.js → components/ConfirmModal.js} +4 -9
  69. package/dist/components/CopyToClipboard.js +81 -0
  70. package/dist/{chunks/Markdown-CM-FenNE.js → components/CreateModal.js} +9 -116
  71. package/dist/components/DescriptionList.js +42 -0
  72. package/dist/components/Dropdown.js +349 -0
  73. package/dist/components/EmptyState.js +27 -0
  74. package/dist/components/Filter.js +32 -0
  75. package/dist/components/FilterPill.js +13 -0
  76. package/dist/components/IconButton.js +34 -0
  77. package/dist/{chunks/Indicator-hBSIxOPK.js → components/Indicator.js} +1 -1
  78. package/dist/components/Input.js +88 -0
  79. package/dist/components/LetterBadge.js +13 -0
  80. package/dist/components/Listbox.js +123 -0
  81. package/dist/{chunks/Loader-BXoXTZGc.js → components/Loader.js} +1 -1
  82. package/dist/components/Markdown.js +15 -0
  83. package/dist/components/MultiSelect.js +171 -0
  84. package/dist/components/Overview.js +39 -0
  85. package/dist/components/PageHeader.js +194 -0
  86. package/dist/components/Pagination.js +35 -0
  87. package/dist/{chunks/Provider-CDYurraE.js → components/Provider.js} +1 -1
  88. package/dist/{chunks/RequiredMark-DfLdYbYZ.js → components/RequiredMark.js} +1 -1
  89. package/dist/components/SectionHeader.js +11 -0
  90. package/dist/components/SettingModeOption.js +30 -0
  91. package/dist/components/SettingRow.js +35 -0
  92. package/dist/components/SettingsCard.js +31 -0
  93. package/dist/components/SettingsGroup.js +17 -0
  94. package/dist/components/Sort.js +42 -0
  95. package/dist/components/StatusBadge.js +63 -0
  96. package/dist/components/SwitchToggle.js +59 -0
  97. package/dist/{chunks/SwitchToggleSmall-FcsaYSTs.js → components/SwitchToggleSmall.js} +1 -1
  98. package/dist/{chunks/Table-DU2MW8xz.js → components/Table.js} +3 -3
  99. package/dist/components/Toggle.js +20 -0
  100. package/dist/{chunks/Tooltip-K5HJr4_p.js → components/Tooltip.js} +2 -27
  101. package/dist/{chunks/StatusBadge-C1Blx_cW.js → components/dropdownUtils.js} +2 -63
  102. package/dist/{chunks/focus-D_iZJTW1.js → components/focus.js} +1 -1
  103. package/dist/components/ghostButton.js +7 -0
  104. package/dist/components/inputClasses.js +4 -0
  105. package/dist/components/keys.js +27 -0
  106. package/dist/components/relativeTime.js +32 -0
  107. package/dist/{chunks/useCssIsDark-DHr05dG2.js → components/useCssIsDark.js} +1 -1
  108. package/dist/{chunks/duration-BOv8Phl8.js → duration.js} +1 -1
  109. package/dist/editor/Editor.js +13 -0
  110. package/dist/editor/EditorField.js +53 -0
  111. package/dist/editor/FormCodePanel.js +173 -0
  112. package/dist/{chunks/Monaco-DJ8MW-Dq.js → editor/Monaco.js} +4 -2
  113. package/dist/editor/index.js +6 -1
  114. package/dist/editor/themes.js +91 -0
  115. package/dist/editor/workers.js +29 -0
  116. package/dist/editor/yaml.js +15 -0
  117. package/dist/file-explorer/FileExplorer.js +1402 -0
  118. package/dist/file-explorer/FileExplorerContext.js +370 -0
  119. package/dist/{chunks/CodePreviewEditor-YqQBz1YL.js → file-explorer/FilePreview/CodePreviewEditor.js} +3 -2
  120. package/dist/file-explorer/FilePreview/Inline.js +45 -0
  121. package/dist/file-explorer/FilePreview/StreamedBadge.js +16 -0
  122. package/dist/file-explorer/FilePreview/Viewer.js +526 -0
  123. package/dist/file-explorer/FilePreview/index.js +266 -0
  124. package/dist/file-explorer/FilePreview/parse.js +63 -0
  125. package/dist/file-explorer/FilePreview/previewCache.js +98 -0
  126. package/dist/file-explorer/FilePreview/previewType.js +151 -0
  127. package/dist/file-explorer/FilePreview/readCappedBytes.js +196 -0
  128. package/dist/file-explorer/FilePreview/useObjectBlobUrl.js +95 -0
  129. package/dist/file-explorer/FilePreview/useObjectText.js +109 -0
  130. package/dist/file-explorer/FilePreview/usePresignedUrl.js +73 -0
  131. package/dist/file-explorer/FileRow.js +165 -0
  132. package/dist/file-explorer/FileRowsWindow.js +92 -0
  133. package/dist/file-explorer/FileTable.js +172 -0
  134. package/dist/file-explorer/FileTableHeaders.js +49 -0
  135. package/dist/file-explorer/LoadMoreRow.js +46 -0
  136. package/dist/file-explorer/TreeView.js +376 -0
  137. package/dist/file-explorer/helpers.js +537 -0
  138. package/dist/file-explorer/index.js +7 -5671
  139. package/dist/file-explorer/lib/batch.js +39 -0
  140. package/dist/file-explorer/lib/errors.js +9 -0
  141. package/dist/file-explorer/lib/paging.js +124 -0
  142. package/dist/file-explorer/lib/utils.js +322 -0
  143. package/dist/file-explorer/toasts.js +400 -0
  144. package/dist/file-explorer/treeRows.js +73 -0
  145. package/dist/file-explorer/useNearEnd.js +27 -0
  146. package/dist/form/FieldWrapper.js +54 -0
  147. package/dist/form/Fields/BooleanField.js +51 -0
  148. package/dist/form/Fields/CheckboxGroupField.js +72 -0
  149. package/dist/form/Fields/ColorField.js +33 -0
  150. package/dist/form/Fields/DropdownField.js +49 -0
  151. package/dist/form/Fields/DurationField.js +130 -0
  152. package/dist/form/Fields/LabelField.js +19 -0
  153. package/dist/form/Fields/MultiDropdownField.js +40 -0
  154. package/dist/form/Fields/NumberField.js +51 -0
  155. package/dist/form/Fields/ObjectField.js +54 -0
  156. package/dist/form/Fields/RadioField.js +49 -0
  157. package/dist/form/Fields/RangeField.js +58 -0
  158. package/dist/form/Fields/ResourceOptionIcon.js +21 -0
  159. package/dist/form/Fields/StepField.js +6 -0
  160. package/dist/form/Fields/StringField.js +37 -0
  161. package/dist/form/Fields/TextAreaField.js +31 -0
  162. package/dist/form/Fields/durationValidity.js +11 -0
  163. package/dist/form/Form.js +643 -0
  164. package/dist/form/SpecialTypes/DropdownWrapper.js +30 -0
  165. package/dist/form/SpecialTypes/FormikCustomDropdown.js +122 -0
  166. package/dist/form/SpecialTypes/FormikCustomInput.js +111 -0
  167. package/dist/form/SpecialTypes/FormikMultiSelectDropdown.js +31 -0
  168. package/dist/form/SpecialTypes/FormikNumericInput.js +60 -0
  169. package/dist/form/Wizard/WizardContainer.js +138 -0
  170. package/dist/form/Wizard/WizardNavigation.js +92 -0
  171. package/dist/form/Wizard/WizardStepContent.js +35 -0
  172. package/dist/form/Wizard/WizardStepIndicator.js +108 -0
  173. package/dist/form/Wizard/useWizardState.js +118 -0
  174. package/dist/form/Wizard/utils.js +34 -0
  175. package/dist/form/fieldContext.js +26 -0
  176. package/dist/form/fieldRegistry.js +50 -0
  177. package/dist/form/index.js +17 -2321
  178. package/dist/{chunks/FieldWrapper-Cszwg-4B.js → form/lib.js} +2 -97
  179. package/dist/form/useParsedOpts.js +62 -0
  180. package/dist/form/usePrevious.js +11 -0
  181. package/dist/form/utils/checkShowIfObject.js +14 -0
  182. package/dist/form/utils/duration.js +69 -0
  183. package/dist/form/utils/getParentValue.js +23 -0
  184. package/dist/form/utils/getPlaceholder.js +9 -0
  185. package/dist/form/utils/getValueUsingPath.js +23 -0
  186. package/dist/form/utils/secondaryField.js +22 -0
  187. package/dist/graph/AnnotationBanner.js +141 -0
  188. package/dist/graph/Collapse.js +41 -0
  189. package/dist/graph/DependencyGraph.js +1398 -0
  190. package/dist/graph/JobSummary.js +104 -0
  191. package/dist/graph/MatrixGroup.js +107 -0
  192. package/dist/graph/Reveal.js +57 -0
  193. package/dist/graph/TreeView.js +711 -0
  194. package/dist/graph/index.js +1 -2519
  195. package/dist/graph/types.js +6 -0
  196. package/dist/index.js +46 -599
  197. package/dist/list/ActionToolbar.js +184 -0
  198. package/dist/list/HoverCard.js +73 -0
  199. package/dist/list/ListPage.js +145 -0
  200. package/dist/list/ListPager.js +59 -0
  201. package/dist/list/ListTable.js +163 -0
  202. package/dist/list/ListViewControls.js +372 -0
  203. package/dist/list/RowContextMenu.js +350 -0
  204. package/dist/list/UserHoverCard.js +117 -0
  205. package/dist/list/index.js +11 -2
  206. package/dist/list/listSearch.js +137 -0
  207. package/dist/list/listView.js +210 -0
  208. package/dist/list/textEntry.js +10 -0
  209. package/dist/{chunks/logviewer-BTKuQWzw.js → logviewer/LogViewer.js} +4 -82
  210. package/dist/logviewer/index.js +2 -1
  211. package/dist/logviewer/segments.js +80 -0
  212. package/package.json +1 -1
  213. package/dist/chunks/PageHeader-0kG_iypP.js +0 -692
  214. package/dist/chunks/SwitchToggle-DShNdcao.js +0 -758
  215. package/dist/chunks/editor-Dk1rbV75.js +0 -361
  216. package/dist/chunks/list-CJm875m7.js +0 -1418
  217. /package/dist/{chunks/MarkdownImpl-CyeTVvSt.js → components/MarkdownImpl.js} +0 -0
@@ -0,0 +1,122 @@
1
+ import { isCategory } from "../../components/dropdownUtils.js";
2
+ import Dropdown from "../../components/Dropdown.js";
3
+ import { useFieldControlProps, useFieldRequired } from "../fieldContext.js";
4
+ import { applySecondaryField, findSecondaryOption } from "../utils/secondaryField.js";
5
+ import cx from "classnames";
6
+ import { memo, useEffect, useEffectEvent, useRef } from "react";
7
+ import { jsx } from "react/jsx-runtime";
8
+ import deepEqual from "fast-deep-equal";
9
+ //#region src/form/SpecialTypes/FormikCustomDropdown.tsx
10
+ function toComparableOptions(options) {
11
+ return options?.map((option) => {
12
+ if (typeof option === "string") return option;
13
+ if (isCategory(option)) return {
14
+ category: option.category,
15
+ options: option.options.map((o) => {
16
+ const base = {
17
+ label: o.label,
18
+ value: o.value,
19
+ disabled: o.disabled
20
+ };
21
+ return o.description !== void 0 ? {
22
+ ...base,
23
+ description: o.description
24
+ } : base;
25
+ })
26
+ };
27
+ const base = {
28
+ label: option.label,
29
+ value: option.value,
30
+ disabled: option.disabled
31
+ };
32
+ return option.description !== void 0 ? {
33
+ ...base,
34
+ description: option.description
35
+ } : base;
36
+ });
37
+ }
38
+ function arePropsEqual(prev, next) {
39
+ for (const key of Object.keys(next)) if (key === "options") {
40
+ if (!deepEqual(toComparableOptions(prev.options), toComparableOptions(next.options))) return false;
41
+ } else if (prev[key] !== next[key]) return false;
42
+ return true;
43
+ }
44
+ var FormikCustomDropdown_default = memo(function FormikCustomDropdown({ name, ariaLabel, options, setFormDirty, onChange, parentValue, className, secondaryField, disabled = false, loading = false, invalid = false, autoselect, value, allowCustomValue = false, customValueLabel, placeholder, currentValue, setFieldValue, setFieldTouched }) {
45
+ const required = useFieldRequired();
46
+ const controlProps = useFieldControlProps();
47
+ const prevParentRef = useRef(parentValue);
48
+ const handleChange = (val) => {
49
+ if (secondaryField && typeof options[0] !== "string") {
50
+ const option = findSecondaryOption(options, val);
51
+ if (option) applySecondaryField(secondaryField, option.secondaryValue, setFieldValue);
52
+ }
53
+ if (onChange) onChange(val);
54
+ setFieldValue(name, val);
55
+ setFieldTouched(name, true);
56
+ setFormDirty(true);
57
+ };
58
+ useEffect(() => {
59
+ prevParentRef.current = parentValue;
60
+ });
61
+ const prevOptions = useRef(null);
62
+ const syncAutoselect = useEffectEvent((options, autoselect) => {
63
+ if (deepEqual(prevOptions.current, toComparableOptions(options))) return;
64
+ if (prevOptions.current === null && currentValue !== void 0 && currentValue !== null) {
65
+ prevOptions.current = toComparableOptions(options);
66
+ return;
67
+ }
68
+ prevOptions.current = toComparableOptions(options);
69
+ if (autoselect === false || !options?.length) return;
70
+ if (autoselect === void 0) {
71
+ if (options.length && isCategory(options[0])) {
72
+ let optionCount = 0;
73
+ for (const category of options) {
74
+ if (isCategory(category)) optionCount += category.options.length;
75
+ if (optionCount > 1) return;
76
+ }
77
+ } else if (options.length !== 1) return;
78
+ }
79
+ if (!options?.find((option) => {
80
+ if (typeof option === "string") return option === currentValue;
81
+ else if (isCategory(option)) return option.options.some((subOption) => {
82
+ return subOption.value === currentValue;
83
+ });
84
+ return option.value === currentValue;
85
+ }) || autoselect) {
86
+ let val;
87
+ for (const option of options) if (typeof option === "string") {
88
+ val = option;
89
+ break;
90
+ } else if (isCategory(option)) {
91
+ const enabled = option.options.find((o) => !o.disabled);
92
+ if (enabled) {
93
+ val = enabled.value;
94
+ break;
95
+ }
96
+ } else if (!option.disabled) {
97
+ val = option.value;
98
+ break;
99
+ }
100
+ if (val !== void 0) handleChange(val);
101
+ }
102
+ });
103
+ useEffect(() => {
104
+ syncAutoselect(options, autoselect);
105
+ }, [options, autoselect]);
106
+ return /* @__PURE__ */ jsx(Dropdown, {
107
+ ...controlProps,
108
+ textBoxClassName: cx(className, invalid && "invalid"),
109
+ ariaLabel,
110
+ required,
111
+ onChange: (val) => handleChange(val),
112
+ value: options?.length === 0 && !allowCustomValue ? value : currentValue,
113
+ options,
114
+ placeholder,
115
+ disabled,
116
+ loading,
117
+ allowCustomValue,
118
+ customValueLabel
119
+ });
120
+ }, arePropsEqual);
121
+ //#endregion
122
+ export { FormikCustomDropdown_default as default };
@@ -0,0 +1,111 @@
1
+ import { EyeIcon, EyeOffIcon } from "../../icons.js";
2
+ import { useFieldControlProps, useFieldRequired } from "../fieldContext.js";
3
+ import cx from "classnames";
4
+ import { useCallback, useEffect, useRef, useState } from "react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { useField, useFormikContext } from "formik";
7
+ //#region src/form/SpecialTypes/FormikCustomInput.tsx
8
+ var DEBOUNCE_MS = 500;
9
+ function FormikCustomInput({ name, type, step, placeholder, onChange, disabled, min, max, sanitize, invalid = false, lowercase = false, minLength, maxLength, defaultValue = "", value }) {
10
+ const [field] = useField(name);
11
+ const required = useFieldRequired();
12
+ const controlProps = useFieldControlProps();
13
+ const { setFieldValue, setFieldTouched } = useFormikContext();
14
+ const [showPassword, setShowPassword] = useState(false);
15
+ const isPassword = type === "password";
16
+ const [localValue, setLocalValue] = useState(value ?? field.value);
17
+ const isFocused = useRef(false);
18
+ const debounceRef = useRef(null);
19
+ useEffect(() => {
20
+ if (!isFocused.current) setLocalValue(value ?? field.value);
21
+ }, [field.value, value]);
22
+ const sanitizeName = useCallback((val) => {
23
+ if (sanitize === void 0) return lowercase ? val.toLowerCase() : val;
24
+ try {
25
+ const regexp = new RegExp(sanitize);
26
+ if (lowercase) val = val.toLowerCase();
27
+ return val.replace(regexp, "");
28
+ } catch {
29
+ console.error("Invalid regex for sanitization:", sanitize);
30
+ }
31
+ return val;
32
+ }, [sanitize, lowercase]);
33
+ const flushToFormik = useCallback((val) => {
34
+ if (onChange) onChange(val);
35
+ setFieldTouched(name, true);
36
+ setFieldValue(name, val);
37
+ }, [
38
+ name,
39
+ onChange,
40
+ setFieldTouched,
41
+ setFieldValue
42
+ ]);
43
+ const handleChange = (e) => {
44
+ const text = sanitize ? sanitizeName(e.target.value) : e.target.value;
45
+ let val = text;
46
+ if (type === "number") {
47
+ const parsed = parseFloat(text);
48
+ val = isNaN(parsed) ? void 0 : parsed;
49
+ }
50
+ if (type === "password" && val === "") val = defaultValue;
51
+ setLocalValue(val);
52
+ clearTimeout(debounceRef.current ?? void 0);
53
+ debounceRef.current = setTimeout(() => flushToFormik(val), DEBOUNCE_MS);
54
+ };
55
+ const handleFocus = () => {
56
+ isFocused.current = true;
57
+ };
58
+ const handleBlur = () => {
59
+ isFocused.current = false;
60
+ clearTimeout(debounceRef.current ?? void 0);
61
+ const current = localValue;
62
+ if (current === void 0 || current === null) return;
63
+ const text = current.toString();
64
+ let val = text;
65
+ if (type === "number") {
66
+ const parsed = parseFloat(text);
67
+ if (Number.isNaN(parsed)) val = void 0;
68
+ else if (min !== void 0 && parsed < min) val = min;
69
+ else if (max !== void 0 && parsed > max) val = max;
70
+ else val = parsed;
71
+ }
72
+ setLocalValue(val);
73
+ flushToFormik(val);
74
+ };
75
+ const displayValue = isPassword && localValue === defaultValue ? "" : localValue ?? "";
76
+ const resolvedType = isPassword ? showPassword ? "text" : "password" : type === "string" ? "text" : type;
77
+ const input = /* @__PURE__ */ jsx("input", {
78
+ ...controlProps,
79
+ "data-1p-ignore": true,
80
+ className: cx("w-full", disabled && "disabled", invalid && "invalid", isPassword && "pr-8"),
81
+ name,
82
+ value: displayValue,
83
+ type: resolvedType,
84
+ "aria-required": required || void 0,
85
+ disabled,
86
+ placeholder,
87
+ minLength,
88
+ maxLength,
89
+ onChange: handleChange,
90
+ onFocus: handleFocus,
91
+ onBlur: handleBlur,
92
+ min,
93
+ max,
94
+ step
95
+ });
96
+ if (!isPassword) return input;
97
+ return /* @__PURE__ */ jsxs("div", {
98
+ className: "relative w-full",
99
+ children: [input, /* @__PURE__ */ jsx("button", {
100
+ type: "button",
101
+ className: "absolute right-2 top-1/2 -translate-y-1/2 theme-muted-text",
102
+ onClick: () => setShowPassword((prev) => !prev),
103
+ disabled,
104
+ tabIndex: -1,
105
+ "aria-label": showPassword ? "Hide value" : "Show value",
106
+ children: showPassword ? /* @__PURE__ */ jsx(EyeOffIcon, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(EyeIcon, { className: "h-4 w-4" })
107
+ })]
108
+ });
109
+ }
110
+ //#endregion
111
+ export { FormikCustomInput as default };
@@ -0,0 +1,31 @@
1
+ import MultiSelectDropdown from "../../components/MultiSelect.js";
2
+ import { useFieldLabelledByProps, useFieldRequired } from "../fieldContext.js";
3
+ import { jsx } from "react/jsx-runtime";
4
+ import { useField, useFormikContext } from "formik";
5
+ //#region src/form/SpecialTypes/FormikMultiSelectDropdown.tsx
6
+ function FormikMultiSelectDropdown({ name, options, setFormDirty, onChange, disabled = false, loading = false, invalid = false, placeholder, compareBy }) {
7
+ const [field] = useField(name);
8
+ const required = useFieldRequired();
9
+ const labelledByProps = useFieldLabelledByProps();
10
+ const { setFieldValue, setFieldTouched } = useFormikContext();
11
+ const handleChange = (next) => {
12
+ setFieldValue(name, next);
13
+ setFieldTouched(name, true);
14
+ setFormDirty(true);
15
+ onChange?.(next);
16
+ };
17
+ return /* @__PURE__ */ jsx(MultiSelectDropdown, {
18
+ ...labelledByProps,
19
+ textBoxClassName: invalid ? "invalid" : void 0,
20
+ options,
21
+ required,
22
+ value: Array.isArray(field.value) ? field.value : [],
23
+ onChange: handleChange,
24
+ disabled,
25
+ loading,
26
+ placeholder,
27
+ compareBy
28
+ });
29
+ }
30
+ //#endregion
31
+ export { FormikMultiSelectDropdown as default };
@@ -0,0 +1,60 @@
1
+ import { useFieldControlProps, useFieldRequired } from "../fieldContext.js";
2
+ import cx from "classnames";
3
+ import { useEffect, useRef, useState } from "react";
4
+ import { jsx } from "react/jsx-runtime";
5
+ import { useField, useFormikContext } from "formik";
6
+ import { NumericFormat } from "react-number-format";
7
+ //#region src/form/SpecialTypes/FormikNumericInput.tsx
8
+ var DEBOUNCE_MS = 500;
9
+ function FormikNumericInput({ name, placeholder, onChange, disabled, min, max, invalid = false }) {
10
+ const [field] = useField(name);
11
+ const required = useFieldRequired();
12
+ const controlProps = useFieldControlProps();
13
+ const { setFieldValue, setFieldTouched } = useFormikContext();
14
+ const [localValue, setLocalValue] = useState(field.value);
15
+ const isFocused = useRef(false);
16
+ const debounceRef = useRef(null);
17
+ useEffect(() => {
18
+ if (!isFocused.current) setLocalValue(field.value);
19
+ }, [field.value]);
20
+ const flush = (val) => {
21
+ onChange?.(val);
22
+ setFieldTouched(name, true);
23
+ setFieldValue(name, val);
24
+ };
25
+ const handleBlur = () => {
26
+ isFocused.current = false;
27
+ clearTimeout(debounceRef.current ?? void 0);
28
+ let val = localValue;
29
+ if (val !== void 0) {
30
+ if (min !== void 0 && val < min) val = min;
31
+ if (max !== void 0 && val > max) val = max;
32
+ }
33
+ setLocalValue(val);
34
+ flush(val);
35
+ };
36
+ return /* @__PURE__ */ jsx(NumericFormat, {
37
+ ...controlProps,
38
+ "data-1p-ignore": true,
39
+ className: cx("w-full", disabled && "disabled", invalid && "invalid"),
40
+ name,
41
+ ...localValue === void 0 ? {} : { value: localValue },
42
+ "aria-required": required || void 0,
43
+ thousandSeparator: ",",
44
+ decimalScale: 20,
45
+ allowNegative: true,
46
+ disabled,
47
+ placeholder,
48
+ onValueChange: (v) => {
49
+ setLocalValue(v.floatValue);
50
+ clearTimeout(debounceRef.current ?? void 0);
51
+ debounceRef.current = setTimeout(() => flush(v.floatValue), DEBOUNCE_MS);
52
+ },
53
+ onFocus: () => {
54
+ isFocused.current = true;
55
+ },
56
+ onBlur: handleBlur
57
+ });
58
+ }
59
+ //#endregion
60
+ export { FormikNumericInput as default };
@@ -0,0 +1,138 @@
1
+ import { useWizardState } from "./useWizardState.js";
2
+ import { WizardNavigation } from "./WizardNavigation.js";
3
+ import { WizardStepContent } from "./WizardStepContent.js";
4
+ import { WizardStepIndicator } from "./WizardStepIndicator.js";
5
+ import { useCallback } from "react";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { useFormikContext } from "formik";
8
+ //#region src/form/Wizard/WizardContainer.tsx
9
+ function hasNestedError(stepErrors, fieldName) {
10
+ return typeof stepErrors === "object" && stepErrors !== null && fieldName in stepErrors;
11
+ }
12
+ function WizardContainer({ wizardConfig, values, onChange, onSubmit, className = "", labelPosition = "left", missingFields = [], spaceCompact = false, workflowForm = false, setFieldValue, setFieldTouched }) {
13
+ const { validateForm, setTouched, touched } = useFormikContext();
14
+ const { config, steps, stepOrder } = wizardConfig;
15
+ const validateCurrentStep = useCallback(async (stepKey) => {
16
+ const stepConfig = steps[stepKey];
17
+ if (!stepConfig?.options) return true;
18
+ const stepFieldNames = Object.keys(stepConfig.options);
19
+ const shouldFlatten = config.flatten !== false;
20
+ const errors = await validateForm();
21
+ const hasStepErrors = shouldFlatten ? stepFieldNames.some((fieldName) => errors[fieldName]) : stepFieldNames.some((fieldName) => hasNestedError(errors[stepKey], fieldName));
22
+ if (hasStepErrors) {
23
+ const touchedFields = stepFieldNames.reduce((acc, fieldName) => {
24
+ acc[fieldName] = true;
25
+ return acc;
26
+ }, {});
27
+ if (shouldFlatten) setTouched({
28
+ ...touched,
29
+ ...touchedFields
30
+ }, false);
31
+ else setTouched({
32
+ ...touched,
33
+ [stepKey]: touchedFields
34
+ }, false);
35
+ }
36
+ return !hasStepErrors;
37
+ }, [
38
+ steps,
39
+ config,
40
+ validateForm,
41
+ setTouched,
42
+ touched
43
+ ]);
44
+ const { currentStep, visitedSteps, invalidSteps, isLastStep, canGoBack, goToNext, goToPrevious, jumpToStep } = useWizardState({
45
+ stepOrder,
46
+ steps,
47
+ validateStep: validateCurrentStep
48
+ });
49
+ const currentStepConfig = steps[currentStep];
50
+ const config_ = config.navigation || {};
51
+ const handleGoToNext = useCallback(async () => {
52
+ const success = await goToNext();
53
+ if (success) onChange?.(values);
54
+ return success;
55
+ }, [
56
+ goToNext,
57
+ values,
58
+ onChange
59
+ ]);
60
+ const handleJumpToStep = useCallback((stepKey) => {
61
+ if (!config_.allowJump || !visitedSteps.has(stepKey)) return false;
62
+ return jumpToStep(stepKey);
63
+ }, [
64
+ jumpToStep,
65
+ config_.allowJump,
66
+ visitedSteps
67
+ ]);
68
+ const handleSubmit = useCallback(async () => {
69
+ if (!isLastStep) return;
70
+ const errors = await validateForm();
71
+ if (Object.keys(errors).length > 0) {
72
+ const touchedFields = Object.keys(values).reduce((acc, fieldName) => {
73
+ acc[fieldName] = true;
74
+ return acc;
75
+ }, {});
76
+ setTouched({
77
+ ...touched,
78
+ ...touchedFields
79
+ }, false);
80
+ throw new Error("Please fix errors before submitting");
81
+ }
82
+ await onSubmit?.(values);
83
+ }, [
84
+ isLastStep,
85
+ validateForm,
86
+ values,
87
+ setTouched,
88
+ touched,
89
+ onSubmit
90
+ ]);
91
+ return /* @__PURE__ */ jsxs("div", {
92
+ className,
93
+ children: [
94
+ config_.showSteps !== false && /* @__PURE__ */ jsx(WizardStepIndicator, {
95
+ stepOrder,
96
+ currentStep,
97
+ steps,
98
+ visitedSteps,
99
+ invalidSteps,
100
+ onStepClick: handleJumpToStep,
101
+ allowJump: config_.allowJump,
102
+ hideStepNumbers: config_.hideStepNumbers
103
+ }),
104
+ currentStepConfig && /* @__PURE__ */ jsx("div", {
105
+ className: "mb-4",
106
+ children: /* @__PURE__ */ jsx(WizardStepContent, {
107
+ currentStep,
108
+ stepConfig: currentStepConfig,
109
+ flatten: config.flatten,
110
+ values,
111
+ onValuesChange: onChange,
112
+ labelPosition,
113
+ missingFields,
114
+ spaceCompact,
115
+ setFormDirty: () => onChange?.(values),
116
+ workflowForm,
117
+ setFieldValue,
118
+ setFieldTouched
119
+ })
120
+ }),
121
+ /* @__PURE__ */ jsx(WizardNavigation, {
122
+ currentStep,
123
+ stepOrder,
124
+ canGoToNext: !isLastStep,
125
+ canGoBack,
126
+ isCurrentStepValid: !invalidSteps.has(currentStep),
127
+ nextLabel: currentStepConfig?.nextLabel,
128
+ prevLabel: currentStepConfig?.prevLabel,
129
+ submitLabel: config.submitLabel || "Execute",
130
+ onNext: handleGoToNext,
131
+ onPrevious: goToPrevious,
132
+ onSubmit: handleSubmit
133
+ })
134
+ ]
135
+ });
136
+ }
137
+ //#endregion
138
+ export { WizardContainer };
@@ -0,0 +1,92 @@
1
+ import Loader from "../../components/Loader.js";
2
+ import { useState } from "react";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ //#region src/form/Wizard/WizardNavigation.tsx
5
+ function WizardNavigation({ currentStep, stepOrder, canGoToNext, canGoBack, isCurrentStepValid, nextLabel, prevLabel, submitLabel = "Submit", onNext, onPrevious, onSubmit }) {
6
+ const [isLoading, setIsLoading] = useState(false);
7
+ const [error, setError] = useState(null);
8
+ const isLastStep = stepOrder.indexOf(currentStep) === stepOrder.length - 1;
9
+ const handleNext = async () => {
10
+ setIsLoading(true);
11
+ setError(null);
12
+ try {
13
+ if (!await onNext()) setError("Please fix errors before proceeding");
14
+ } catch (err) {
15
+ setError(err instanceof Error ? err.message : "An error occurred");
16
+ } finally {
17
+ setIsLoading(false);
18
+ }
19
+ };
20
+ const handleSubmit = async () => {
21
+ setIsLoading(true);
22
+ setError(null);
23
+ try {
24
+ await onSubmit();
25
+ } catch (err) {
26
+ setError(err instanceof Error ? err.message : "An error occurred");
27
+ } finally {
28
+ setIsLoading(false);
29
+ }
30
+ };
31
+ return /* @__PURE__ */ jsxs("div", { children: [error && /* @__PURE__ */ jsx("div", {
32
+ className: "mb-4 p-3 bg-red-50 border border-red-200 rounded text-sm text-red-700",
33
+ children: error
34
+ }), /* @__PURE__ */ jsxs("div", {
35
+ className: "flex gap-3 justify-between pt-4",
36
+ children: [/* @__PURE__ */ jsx("button", {
37
+ type: "button",
38
+ onClick: onPrevious,
39
+ disabled: !canGoBack || isLoading,
40
+ className: "px-6 py-3 rounded-lg font-medium transition-all duration-200 border flex items-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed",
41
+ style: {
42
+ color: "var(--theme-app)",
43
+ borderColor: "var(--theme-border)",
44
+ backgroundColor: "var(--theme-app-bg)"
45
+ },
46
+ onMouseEnter: (e) => {
47
+ if (!(!canGoBack || isLoading)) e.currentTarget.style.backgroundColor = "var(--theme-hover)";
48
+ },
49
+ onMouseLeave: (e) => {
50
+ e.currentTarget.style.backgroundColor = "var(--theme-app-bg)";
51
+ },
52
+ "aria-label": "Go to previous step",
53
+ children: prevLabel || "← Previous"
54
+ }), isLastStep ? /* @__PURE__ */ jsxs("button", {
55
+ type: "button",
56
+ onClick: handleSubmit,
57
+ disabled: !isCurrentStepValid || isLoading,
58
+ className: "px-8 py-3 rounded-lg font-medium transition-all duration-200 text-white flex items-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed shadow-md hover:shadow-lg",
59
+ style: { backgroundColor: "var(--theme-element)" },
60
+ onMouseEnter: (e) => {
61
+ if (!(!isCurrentStepValid || isLoading)) e.currentTarget.style.filter = "brightness(0.9)";
62
+ },
63
+ onMouseLeave: (e) => {
64
+ e.currentTarget.style.filter = "brightness(1)";
65
+ },
66
+ "aria-label": submitLabel,
67
+ children: [isLoading && /* @__PURE__ */ jsx(Loader, {
68
+ size: 16,
69
+ full: false
70
+ }), submitLabel]
71
+ }) : /* @__PURE__ */ jsxs("button", {
72
+ type: "button",
73
+ onClick: handleNext,
74
+ disabled: !canGoToNext || isLoading,
75
+ className: "px-8 py-3 rounded-lg font-medium transition-all duration-200 text-white flex items-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed shadow-md hover:shadow-lg",
76
+ style: { backgroundColor: "var(--theme-element)" },
77
+ onMouseEnter: (e) => {
78
+ if (!(!canGoToNext || isLoading)) e.currentTarget.style.filter = "brightness(0.9)";
79
+ },
80
+ onMouseLeave: (e) => {
81
+ e.currentTarget.style.filter = "brightness(1)";
82
+ },
83
+ "aria-label": "Go to next step",
84
+ children: [isLoading && /* @__PURE__ */ jsx(Loader, {
85
+ size: 16,
86
+ full: false
87
+ }), nextLabel || "Next →"]
88
+ })]
89
+ })] });
90
+ }
91
+ //#endregion
92
+ export { WizardNavigation };
@@ -0,0 +1,35 @@
1
+ import { FieldsFromOptions } from "../Form.js";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ //#region src/form/Wizard/WizardStepContent.tsx
4
+ function WizardStepContent({ currentStep, stepConfig, flatten = true, values, onValuesChange, setFormDirty, setFieldValue, setFieldTouched, ...fieldsProps }) {
5
+ if (!stepConfig?.options) return null;
6
+ return /* @__PURE__ */ jsxs("div", {
7
+ className: "mb-4 w-full",
8
+ children: [
9
+ stepConfig.title && /* @__PURE__ */ jsx("h2", {
10
+ className: "text-2xl font-bold mb-2",
11
+ style: { color: "var(--theme-app)" },
12
+ children: stepConfig.title
13
+ }),
14
+ stepConfig.description && /* @__PURE__ */ jsx("p", {
15
+ className: "mb-4 leading-relaxed",
16
+ style: { color: "var(--theme-muted-text-color)" },
17
+ children: stepConfig.description
18
+ }),
19
+ /* @__PURE__ */ jsx(FieldsFromOptions, {
20
+ options: stepConfig.options,
21
+ values,
22
+ setFormDirty,
23
+ setFieldValue,
24
+ setFieldTouched,
25
+ ...flatten === false ? { parentInfo: {
26
+ parentName: currentStep,
27
+ fieldNamePrefix: `${currentStep}.`
28
+ } } : {},
29
+ ...fieldsProps
30
+ }, currentStep)
31
+ ]
32
+ });
33
+ }
34
+ //#endregion
35
+ export { WizardStepContent };