@dynamic-field-kit/react 1.6.0 → 1.7.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/CHANGELOG.md +58 -0
- package/README.md +101 -22
- package/dist/index.d.mts +37 -4
- package/dist/index.d.ts +37 -4
- package/dist/index.js +178 -55
- package/dist/index.mjs +191 -63
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -32,29 +32,30 @@ var index_exports = {};
|
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
DynamicFormDevTools: () => DynamicFormDevTools,
|
|
34
34
|
DynamicInput: () => DynamicInput_default,
|
|
35
|
-
FIELD_RENDERER_PROP_KEYS: () =>
|
|
35
|
+
FIELD_RENDERER_PROP_KEYS: () => import_core8.FIELD_RENDERER_PROP_KEYS,
|
|
36
36
|
FieldInput: () => FieldInput_default,
|
|
37
|
-
FieldRegistry: () =>
|
|
37
|
+
FieldRegistry: () => import_core7.FieldRegistry,
|
|
38
38
|
FieldRegistryProvider: () => FieldRegistryProvider,
|
|
39
39
|
MultiFieldInput: () => MultiFieldInput_default,
|
|
40
|
-
buildFieldRendererProps: () =>
|
|
41
|
-
collectFieldPaths: () =>
|
|
40
|
+
buildFieldRendererProps: () => import_core8.buildFieldRendererProps,
|
|
41
|
+
collectFieldPaths: () => import_core9.collectFieldPaths,
|
|
42
42
|
defaultRenderersMap: () => defaultRenderersMap,
|
|
43
43
|
fieldRegistry: () => fieldRegistry,
|
|
44
44
|
getDefaultRenderer: () => getDefaultRenderer,
|
|
45
|
-
indexGroupPathMap: () =>
|
|
45
|
+
indexGroupPathMap: () => import_core9.indexGroupPathMap,
|
|
46
46
|
layoutRegistry: () => layoutRegistry,
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
makeErrorId: () => import_core8.makeErrorId,
|
|
48
|
+
makeFieldId: () => import_core8.makeFieldId,
|
|
49
|
+
resolveDisabled: () => import_core9.resolveDisabled,
|
|
50
|
+
resolveOptions: () => import_core9.resolveOptions,
|
|
51
|
+
resolveReadOnly: () => import_core9.resolveReadOnly,
|
|
51
52
|
useDynamicForm: () => useDynamicForm,
|
|
52
53
|
useFieldRegistry: () => useFieldRegistry,
|
|
53
|
-
validateField: () =>
|
|
54
|
-
validateFieldAsync: () =>
|
|
55
|
-
validateFields: () =>
|
|
56
|
-
validateFieldsAsync: () =>
|
|
57
|
-
validators: () =>
|
|
54
|
+
validateField: () => import_core9.validateField,
|
|
55
|
+
validateFieldAsync: () => import_core9.validateFieldAsync,
|
|
56
|
+
validateFields: () => import_core9.validateFields,
|
|
57
|
+
validateFieldsAsync: () => import_core9.validateFieldsAsync,
|
|
58
|
+
validators: () => import_core9.validators
|
|
58
59
|
});
|
|
59
60
|
module.exports = __toCommonJS(index_exports);
|
|
60
61
|
|
|
@@ -171,6 +172,7 @@ layoutRegistry.register("responsive", ({ children, config }) => {
|
|
|
171
172
|
});
|
|
172
173
|
|
|
173
174
|
// src/components/DynamicInput.tsx
|
|
175
|
+
var import_core2 = require("@dynamic-field-kit/core");
|
|
174
176
|
var import_react3 = __toESM(require("react"));
|
|
175
177
|
|
|
176
178
|
// src/defaultRenderers.tsx
|
|
@@ -499,25 +501,39 @@ var DynamicInputInner = ({
|
|
|
499
501
|
onChange,
|
|
500
502
|
onBlur,
|
|
501
503
|
extraProps,
|
|
504
|
+
onOptionsQuery,
|
|
502
505
|
...rendererProps
|
|
503
506
|
}) => {
|
|
504
507
|
const registry = useFieldRegistry();
|
|
505
|
-
const Renderer = (0, import_react3.useMemo)(
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
508
|
+
const { Renderer, isDefault } = (0, import_react3.useMemo)(() => {
|
|
509
|
+
const registered = registry.get(type);
|
|
510
|
+
return {
|
|
511
|
+
Renderer: registered ?? getDefaultRenderer(type),
|
|
512
|
+
isDefault: !registered
|
|
513
|
+
};
|
|
514
|
+
}, [registry, type]);
|
|
509
515
|
if (!Renderer) {
|
|
510
516
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
|
|
511
517
|
"Unknown field type: ",
|
|
512
518
|
type
|
|
513
519
|
] });
|
|
514
520
|
}
|
|
515
|
-
|
|
521
|
+
const { error, id } = rendererProps;
|
|
522
|
+
const control = import_react3.default.createElement(Renderer, {
|
|
516
523
|
...extraProps,
|
|
517
524
|
...rendererProps,
|
|
518
525
|
onValueChange: onChange,
|
|
519
|
-
onBlur
|
|
526
|
+
onBlur,
|
|
527
|
+
onOptionsQuery
|
|
520
528
|
});
|
|
529
|
+
const firstError = Array.isArray(error) ? error[0] : error;
|
|
530
|
+
if (!isDefault || !firstError || !id) {
|
|
531
|
+
return control;
|
|
532
|
+
}
|
|
533
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
534
|
+
control,
|
|
535
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { id: (0, import_core2.makeErrorId)(id), className: "dfk-field-error", role: "alert", children: firstError })
|
|
536
|
+
] });
|
|
521
537
|
};
|
|
522
538
|
var DynamicInput = /* @__PURE__ */ import_react3.default.memo(
|
|
523
539
|
DynamicInputInner
|
|
@@ -525,15 +541,15 @@ var DynamicInput = /* @__PURE__ */ import_react3.default.memo(
|
|
|
525
541
|
var DynamicInput_default = DynamicInput;
|
|
526
542
|
|
|
527
543
|
// src/components/FieldInput.tsx
|
|
528
|
-
var
|
|
544
|
+
var import_core5 = require("@dynamic-field-kit/core");
|
|
529
545
|
var import_react6 = __toESM(require("react"));
|
|
530
546
|
|
|
531
547
|
// src/components/FieldGroupInput.tsx
|
|
532
|
-
var
|
|
548
|
+
var import_core4 = require("@dynamic-field-kit/core");
|
|
533
549
|
var import_react5 = require("react");
|
|
534
550
|
|
|
535
551
|
// src/components/MultiFieldInput.tsx
|
|
536
|
-
var
|
|
552
|
+
var import_core3 = require("@dynamic-field-kit/core");
|
|
537
553
|
var import_react4 = __toESM(require("react"));
|
|
538
554
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
539
555
|
function resolveLayout(layout) {
|
|
@@ -551,6 +567,7 @@ var MultiFieldInputInner = ({
|
|
|
551
567
|
onChange,
|
|
552
568
|
layout,
|
|
553
569
|
idPrefix,
|
|
570
|
+
initialProperties,
|
|
554
571
|
rootData,
|
|
555
572
|
onValidityChange,
|
|
556
573
|
onBlurField,
|
|
@@ -566,7 +583,13 @@ var MultiFieldInputInner = ({
|
|
|
566
583
|
const effectiveErrors = errorsProp ?? form?.errors;
|
|
567
584
|
const [data, setData] = (0, import_react4.useState)({});
|
|
568
585
|
const [internalTouched, setInternalTouched] = (0, import_react4.useState)({});
|
|
569
|
-
const
|
|
586
|
+
const fallbackBaselineRef = (0, import_react4.useRef)(
|
|
587
|
+
effectiveProperties
|
|
588
|
+
);
|
|
589
|
+
if (fallbackBaselineRef.current === void 0) {
|
|
590
|
+
fallbackBaselineRef.current = effectiveProperties;
|
|
591
|
+
}
|
|
592
|
+
const baseline = initialProperties ?? form?.baselineValues ?? fallbackBaselineRef.current ?? {};
|
|
570
593
|
const autoId = (0, import_react4.useId)().replace(/[^a-zA-Z0-9]/g, "");
|
|
571
594
|
const effectiveIdPrefix = idPrefix ?? `dfk-${autoId}`;
|
|
572
595
|
const isTouchedControlled = controlledTouched !== void 0;
|
|
@@ -574,7 +597,7 @@ var MultiFieldInputInner = ({
|
|
|
574
597
|
(0, import_react4.useEffect)(() => {
|
|
575
598
|
if (effectiveProperties) {
|
|
576
599
|
setData(
|
|
577
|
-
(0,
|
|
600
|
+
(0, import_core3.applyComputedValues)(fieldDescriptions, effectiveProperties, rootData)
|
|
578
601
|
);
|
|
579
602
|
}
|
|
580
603
|
}, [effectiveProperties]);
|
|
@@ -605,12 +628,12 @@ var MultiFieldInputInner = ({
|
|
|
605
628
|
effectiveTouchedRef.current = effectiveTouched;
|
|
606
629
|
(0, import_react4.useEffect)(() => {
|
|
607
630
|
onValidityChangeRef.current?.(
|
|
608
|
-
(0,
|
|
631
|
+
(0, import_core3.validateFields)(fieldDescriptions, data, rootData)
|
|
609
632
|
);
|
|
610
633
|
}, [data, fieldDescriptions, rootData]);
|
|
611
634
|
const handleValueChangeField = (0, import_react4.useCallback)((value, key) => {
|
|
612
635
|
const merged = { ...dataRef.current, [key]: value };
|
|
613
|
-
const next = (0,
|
|
636
|
+
const next = (0, import_core3.applyComputedValues)(
|
|
614
637
|
fieldDescriptionsRef.current,
|
|
615
638
|
merged,
|
|
616
639
|
rootDataRef.current
|
|
@@ -665,9 +688,9 @@ var MultiFieldInputInner = ({
|
|
|
665
688
|
rootData: effectiveRoot,
|
|
666
689
|
idPrefix: effectiveIdPrefix,
|
|
667
690
|
touched: Boolean(effectiveTouched[f.name]),
|
|
668
|
-
touchedMap: (0,
|
|
691
|
+
touchedMap: (0, import_core3.isFieldGroup)(f) ? effectiveTouched : void 0,
|
|
669
692
|
errors: effectiveErrors,
|
|
670
|
-
dirty: data[f.name]
|
|
693
|
+
dirty: !Object.is(data[f.name], baseline[f.name]),
|
|
671
694
|
onBlurField: handleBlurField,
|
|
672
695
|
onValueChangeField: handleValueChangeField
|
|
673
696
|
},
|
|
@@ -702,11 +725,11 @@ var FieldGroupInput = ({
|
|
|
702
725
|
const removeText = removeLabel ?? "Remove";
|
|
703
726
|
const groupName = label ?? fieldDescription.name;
|
|
704
727
|
const errorsByItem = (0, import_react5.useMemo)(
|
|
705
|
-
() => (0,
|
|
728
|
+
() => (0, import_core4.indexGroupPathMap)(errors, fieldDescription.name),
|
|
706
729
|
[errors, fieldDescription.name]
|
|
707
730
|
);
|
|
708
731
|
const touchedByItem = (0, import_react5.useMemo)(
|
|
709
|
-
() => (0,
|
|
732
|
+
() => (0, import_core4.indexGroupPathMap)(touched, fieldDescription.name),
|
|
710
733
|
[touched, fieldDescription.name]
|
|
711
734
|
);
|
|
712
735
|
const handleItemChange = (0, import_react5.useCallback)(
|
|
@@ -718,14 +741,14 @@ var FieldGroupInput = ({
|
|
|
718
741
|
[items, onChange]
|
|
719
742
|
);
|
|
720
743
|
const handleAdd = (0, import_react5.useCallback)(() => {
|
|
721
|
-
if (!(0,
|
|
744
|
+
if (!(0, import_core4.canAddGroupItem)(fieldDescription, items)) {
|
|
722
745
|
return;
|
|
723
746
|
}
|
|
724
|
-
onChange([...items, (0,
|
|
747
|
+
onChange([...items, (0, import_core4.createGroupItem)(fieldDescription)]);
|
|
725
748
|
}, [fieldDescription, items, onChange]);
|
|
726
749
|
const handleRemove = (0, import_react5.useCallback)(
|
|
727
750
|
(index) => {
|
|
728
|
-
if (!(0,
|
|
751
|
+
if (!(0, import_core4.canRemoveGroupItem)(fieldDescription, items)) {
|
|
729
752
|
return;
|
|
730
753
|
}
|
|
731
754
|
onChange(items.filter((_, i) => i !== index));
|
|
@@ -757,7 +780,7 @@ var FieldGroupInput = ({
|
|
|
757
780
|
type: "button",
|
|
758
781
|
"aria-label": `${removeText} ${groupName} ${index + 1}`,
|
|
759
782
|
onClick: () => handleRemove(index),
|
|
760
|
-
disabled: !(0,
|
|
783
|
+
disabled: !(0, import_core4.canRemoveGroupItem)(fieldDescription, items),
|
|
761
784
|
children: removeText
|
|
762
785
|
}
|
|
763
786
|
)
|
|
@@ -771,7 +794,7 @@ var FieldGroupInput = ({
|
|
|
771
794
|
type: "button",
|
|
772
795
|
"aria-label": `${addText} ${groupName}`,
|
|
773
796
|
onClick: handleAdd,
|
|
774
|
-
disabled: !(0,
|
|
797
|
+
disabled: !(0, import_core4.canAddGroupItem)(fieldDescription, items),
|
|
775
798
|
children: addText
|
|
776
799
|
}
|
|
777
800
|
)
|
|
@@ -794,6 +817,41 @@ var FieldInputInner = ({
|
|
|
794
817
|
onValueChangeField
|
|
795
818
|
}) => {
|
|
796
819
|
const { name, fields } = fieldDescription;
|
|
820
|
+
const isAsync = (0, import_core5.isAsyncOptions)(fieldDescription);
|
|
821
|
+
const [optionsState, setOptionsState] = (0, import_react6.useState)(
|
|
822
|
+
isAsync ? { status: "idle" } : void 0
|
|
823
|
+
);
|
|
824
|
+
const loaderRef = (0, import_react6.useRef)(void 0);
|
|
825
|
+
const fieldRef = (0, import_react6.useRef)(fieldDescription);
|
|
826
|
+
fieldRef.current = fieldDescription;
|
|
827
|
+
const ensureLoader = (0, import_react6.useCallback)(() => {
|
|
828
|
+
if (!(0, import_core5.isAsyncOptions)(fieldRef.current)) {
|
|
829
|
+
return void 0;
|
|
830
|
+
}
|
|
831
|
+
if (!loaderRef.current) {
|
|
832
|
+
loaderRef.current = (0, import_core5.createOptionsLoader)(
|
|
833
|
+
fieldRef.current,
|
|
834
|
+
setOptionsState
|
|
835
|
+
);
|
|
836
|
+
}
|
|
837
|
+
return loaderRef.current;
|
|
838
|
+
}, []);
|
|
839
|
+
(0, import_react6.useEffect)(
|
|
840
|
+
() => () => {
|
|
841
|
+
loaderRef.current?.dispose();
|
|
842
|
+
loaderRef.current = void 0;
|
|
843
|
+
},
|
|
844
|
+
[]
|
|
845
|
+
);
|
|
846
|
+
(0, import_react6.useEffect)(() => {
|
|
847
|
+
ensureLoader()?.update(renderInfos, rootData);
|
|
848
|
+
});
|
|
849
|
+
const handleOptionsQuery = (0, import_react6.useCallback)(
|
|
850
|
+
(query) => {
|
|
851
|
+
ensureLoader()?.setQuery(query);
|
|
852
|
+
},
|
|
853
|
+
[ensureLoader]
|
|
854
|
+
);
|
|
797
855
|
const handleChange = (0, import_react6.useCallback)(
|
|
798
856
|
(v) => onValueChangeField(v, name),
|
|
799
857
|
[onValueChangeField, name]
|
|
@@ -817,14 +875,15 @@ var FieldInputInner = ({
|
|
|
817
875
|
}
|
|
818
876
|
);
|
|
819
877
|
}
|
|
820
|
-
const rendererProps = (0,
|
|
878
|
+
const rendererProps = (0, import_core5.buildFieldRendererProps)({
|
|
821
879
|
fieldDescription,
|
|
822
880
|
data: renderInfos,
|
|
823
881
|
rootData,
|
|
824
|
-
id: (0,
|
|
882
|
+
id: (0, import_core5.makeFieldId)(fieldDescription, idPrefix),
|
|
825
883
|
touched,
|
|
826
884
|
dirty,
|
|
827
|
-
validationErrors: errors === void 0 ? void 0 : errors[name] ?? []
|
|
885
|
+
validationErrors: errors === void 0 ? void 0 : errors[name] ?? [],
|
|
886
|
+
optionsState
|
|
828
887
|
});
|
|
829
888
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
830
889
|
DynamicInput_default,
|
|
@@ -832,12 +891,16 @@ var FieldInputInner = ({
|
|
|
832
891
|
...rendererProps,
|
|
833
892
|
description: rendererProps.description,
|
|
834
893
|
onChange: handleChange,
|
|
835
|
-
onBlur: handleBlur
|
|
894
|
+
onBlur: handleBlur,
|
|
895
|
+
onOptionsQuery: isAsync ? handleOptionsQuery : void 0
|
|
836
896
|
}
|
|
837
897
|
);
|
|
838
898
|
};
|
|
839
899
|
var FieldInput = /* @__PURE__ */ import_react6.default.memo(FieldInputInner, (prev, next) => {
|
|
840
900
|
const name = prev.fieldDescription.name;
|
|
901
|
+
if ((0, import_core5.isAsyncOptions)(prev.fieldDescription) && prev.renderInfos !== next.renderInfos) {
|
|
902
|
+
return false;
|
|
903
|
+
}
|
|
841
904
|
return prev.fieldDescription === next.fieldDescription && prev.onValueChangeField === next.onValueChangeField && prev.onBlurField === next.onBlurField && prev.rootData === next.rootData && prev.idPrefix === next.idPrefix && prev.touched === next.touched && prev.touchedMap === next.touchedMap && prev.dirty === next.dirty && prev.errors === next.errors && prev.renderInfos[name] === next.renderInfos[name];
|
|
842
905
|
});
|
|
843
906
|
var FieldInput_default = FieldInput;
|
|
@@ -1043,7 +1106,7 @@ var DynamicFormDevTools = ({
|
|
|
1043
1106
|
};
|
|
1044
1107
|
|
|
1045
1108
|
// src/useDynamicForm.ts
|
|
1046
|
-
var
|
|
1109
|
+
var import_core6 = require("@dynamic-field-kit/core");
|
|
1047
1110
|
var import_react8 = require("react");
|
|
1048
1111
|
function sameStringMap(left, right) {
|
|
1049
1112
|
const keys = Object.keys(left);
|
|
@@ -1058,10 +1121,15 @@ function useDynamicForm({
|
|
|
1058
1121
|
fields,
|
|
1059
1122
|
initialValues = {},
|
|
1060
1123
|
validateOnBlur = true,
|
|
1061
|
-
validateOnChange = false
|
|
1124
|
+
validateOnChange = false,
|
|
1125
|
+
messages
|
|
1062
1126
|
}) {
|
|
1127
|
+
const validationContextRef = (0, import_react8.useRef)({
|
|
1128
|
+
t: (0, import_core6.createMessageResolver)(messages)
|
|
1129
|
+
});
|
|
1130
|
+
validationContextRef.current.t = (0, import_core6.createMessageResolver)(messages);
|
|
1063
1131
|
const [data, setData] = (0, import_react8.useState)(
|
|
1064
|
-
() => (0,
|
|
1132
|
+
() => (0, import_core6.applyComputedValues)(fields, initialValues)
|
|
1065
1133
|
);
|
|
1066
1134
|
const [errors, setErrors] = (0, import_react8.useState)({});
|
|
1067
1135
|
const [isDirty, setIsDirty] = (0, import_react8.useState)(false);
|
|
@@ -1069,7 +1137,7 @@ function useDynamicForm({
|
|
|
1069
1137
|
const [isSubmitting, setIsSubmitting] = (0, import_react8.useState)(false);
|
|
1070
1138
|
const [isSubmitted, setIsSubmitted] = (0, import_react8.useState)(false);
|
|
1071
1139
|
const [validationResult, setValidationResult] = (0, import_react8.useState)(
|
|
1072
|
-
() => (0,
|
|
1140
|
+
() => (0, import_core6.validateFields)(fields, data, void 0, validationContextRef.current)
|
|
1073
1141
|
);
|
|
1074
1142
|
const [isValidating, setIsValidating] = (0, import_react8.useState)(false);
|
|
1075
1143
|
const validationRunRef = (0, import_react8.useRef)(0);
|
|
@@ -1078,14 +1146,30 @@ function useDynamicForm({
|
|
|
1078
1146
|
const submitAbortRef = (0, import_react8.useRef)(void 0);
|
|
1079
1147
|
const dataRef = (0, import_react8.useRef)(data);
|
|
1080
1148
|
dataRef.current = data;
|
|
1149
|
+
const baselineRef = (0, import_react8.useRef)(dataRef.current);
|
|
1150
|
+
const [baselineValues, setBaselineValues] = (0, import_react8.useState)(
|
|
1151
|
+
() => baselineRef.current
|
|
1152
|
+
);
|
|
1081
1153
|
const commitSyncResult = (0, import_react8.useCallback)((res) => {
|
|
1082
1154
|
setValidationResult(
|
|
1083
1155
|
(previous) => sameValidationResult(previous, res) ? previous : res
|
|
1084
1156
|
);
|
|
1085
1157
|
return res.valid;
|
|
1086
1158
|
}, []);
|
|
1159
|
+
const lastValidatedRef = (0, import_react8.useRef)(void 0);
|
|
1160
|
+
const fieldsRef = (0, import_react8.useRef)(fields);
|
|
1161
|
+
if (fieldsRef.current !== fields) {
|
|
1162
|
+
fieldsRef.current = fields;
|
|
1163
|
+
lastValidatedRef.current = void 0;
|
|
1164
|
+
}
|
|
1087
1165
|
(0, import_react8.useEffect)(() => {
|
|
1088
|
-
|
|
1166
|
+
if (lastValidatedRef.current === data) {
|
|
1167
|
+
return;
|
|
1168
|
+
}
|
|
1169
|
+
lastValidatedRef.current = data;
|
|
1170
|
+
commitSyncResult(
|
|
1171
|
+
(0, import_core6.validateFields)(fields, data, void 0, validationContextRef.current)
|
|
1172
|
+
);
|
|
1089
1173
|
}, [fields, data, commitSyncResult]);
|
|
1090
1174
|
(0, import_react8.useEffect)(
|
|
1091
1175
|
() => () => {
|
|
@@ -1095,7 +1179,12 @@ function useDynamicForm({
|
|
|
1095
1179
|
[]
|
|
1096
1180
|
);
|
|
1097
1181
|
const validate = (0, import_react8.useCallback)(() => {
|
|
1098
|
-
const res = (0,
|
|
1182
|
+
const res = (0, import_core6.validateFields)(
|
|
1183
|
+
fields,
|
|
1184
|
+
data,
|
|
1185
|
+
void 0,
|
|
1186
|
+
validationContextRef.current
|
|
1187
|
+
);
|
|
1099
1188
|
setErrors(res.errors);
|
|
1100
1189
|
return commitSyncResult(res);
|
|
1101
1190
|
}, [fields, data, commitSyncResult]);
|
|
@@ -1107,7 +1196,8 @@ function useDynamicForm({
|
|
|
1107
1196
|
const snapshot = data;
|
|
1108
1197
|
setIsValidating(true);
|
|
1109
1198
|
try {
|
|
1110
|
-
const res = await (0,
|
|
1199
|
+
const res = await (0, import_core6.validateFieldsAsync)(fields, snapshot, snapshot, {
|
|
1200
|
+
...validationContextRef.current,
|
|
1111
1201
|
signal: controller.signal
|
|
1112
1202
|
});
|
|
1113
1203
|
if (run !== validationRunRef.current || dataRef.current !== snapshot) {
|
|
@@ -1124,14 +1214,20 @@ function useDynamicForm({
|
|
|
1124
1214
|
}, [fields, data]);
|
|
1125
1215
|
const handleChange = (0, import_react8.useCallback)(
|
|
1126
1216
|
(newData) => {
|
|
1127
|
-
const next = (0,
|
|
1217
|
+
const next = (0, import_core6.applyComputedValues)(fields, newData);
|
|
1128
1218
|
setData(next);
|
|
1129
1219
|
dataRef.current = next;
|
|
1130
1220
|
setIsDirty(true);
|
|
1131
1221
|
validationAbortRef.current?.abort();
|
|
1132
1222
|
validationRunRef.current += 1;
|
|
1133
1223
|
setIsValidating(false);
|
|
1134
|
-
|
|
1224
|
+
lastValidatedRef.current = next;
|
|
1225
|
+
const res = (0, import_core6.validateFields)(
|
|
1226
|
+
fields,
|
|
1227
|
+
next,
|
|
1228
|
+
void 0,
|
|
1229
|
+
validationContextRef.current
|
|
1230
|
+
);
|
|
1135
1231
|
commitSyncResult(res);
|
|
1136
1232
|
if (validateOnChange) {
|
|
1137
1233
|
setErrors(res.errors);
|
|
@@ -1151,16 +1247,32 @@ function useDynamicForm({
|
|
|
1151
1247
|
const touchAll = (0, import_react8.useCallback)(() => {
|
|
1152
1248
|
setTouched(
|
|
1153
1249
|
Object.fromEntries(
|
|
1154
|
-
(0,
|
|
1250
|
+
(0, import_core6.collectFieldPaths)(fields, data).map((path) => [path, true])
|
|
1155
1251
|
)
|
|
1156
1252
|
);
|
|
1157
1253
|
}, [fields, data]);
|
|
1158
1254
|
const resetTouched = (0, import_react8.useCallback)(() => setTouched({}), []);
|
|
1255
|
+
const getDirtyValues = (0, import_react8.useCallback)(() => {
|
|
1256
|
+
const baseline = baselineRef.current;
|
|
1257
|
+
const current = dataRef.current;
|
|
1258
|
+
const dirty = {};
|
|
1259
|
+
for (const key of Object.keys(current)) {
|
|
1260
|
+
if (!Object.is(current[key], baseline[key])) {
|
|
1261
|
+
dirty[key] = current[key];
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
return dirty;
|
|
1265
|
+
}, []);
|
|
1159
1266
|
const handleBlur = (0, import_react8.useCallback)(
|
|
1160
1267
|
(fieldName) => {
|
|
1161
1268
|
setFieldTouched(fieldName, true);
|
|
1162
1269
|
if (validateOnBlur) {
|
|
1163
|
-
const res = (0,
|
|
1270
|
+
const res = (0, import_core6.validateFields)(
|
|
1271
|
+
fields,
|
|
1272
|
+
data,
|
|
1273
|
+
void 0,
|
|
1274
|
+
validationContextRef.current
|
|
1275
|
+
);
|
|
1164
1276
|
setErrors(res.errors);
|
|
1165
1277
|
commitSyncResult(res);
|
|
1166
1278
|
}
|
|
@@ -1170,9 +1282,11 @@ function useDynamicForm({
|
|
|
1170
1282
|
const reset = (0, import_react8.useCallback)(
|
|
1171
1283
|
(newValues) => {
|
|
1172
1284
|
const seed = newValues ?? initialValues;
|
|
1173
|
-
const next = (0,
|
|
1285
|
+
const next = (0, import_core6.applyComputedValues)(fields, seed);
|
|
1174
1286
|
setData(next);
|
|
1175
1287
|
dataRef.current = next;
|
|
1288
|
+
baselineRef.current = next;
|
|
1289
|
+
setBaselineValues(next);
|
|
1176
1290
|
setErrors({});
|
|
1177
1291
|
setIsDirty(false);
|
|
1178
1292
|
setTouched({});
|
|
@@ -1200,7 +1314,8 @@ function useDynamicForm({
|
|
|
1200
1314
|
submitAbortRef.current = controller;
|
|
1201
1315
|
const snapshot = data;
|
|
1202
1316
|
setIsValidating(true);
|
|
1203
|
-
const res = await (0,
|
|
1317
|
+
const res = await (0, import_core6.validateFieldsAsync)(fields, snapshot, snapshot, {
|
|
1318
|
+
...validationContextRef.current,
|
|
1204
1319
|
signal: controller.signal
|
|
1205
1320
|
});
|
|
1206
1321
|
if (submitRun !== submitRunRef.current) {
|
|
@@ -1210,7 +1325,12 @@ function useDynamicForm({
|
|
|
1210
1325
|
setErrors(res.errors);
|
|
1211
1326
|
setValidationResult(res);
|
|
1212
1327
|
} else {
|
|
1213
|
-
const live = (0,
|
|
1328
|
+
const live = (0, import_core6.validateFields)(
|
|
1329
|
+
fields,
|
|
1330
|
+
dataRef.current,
|
|
1331
|
+
void 0,
|
|
1332
|
+
validationContextRef.current
|
|
1333
|
+
);
|
|
1214
1334
|
setErrors(live.errors);
|
|
1215
1335
|
commitSyncResult(live);
|
|
1216
1336
|
}
|
|
@@ -1239,6 +1359,8 @@ function useDynamicForm({
|
|
|
1239
1359
|
isValidationComplete: validationResult.complete && !isValidating,
|
|
1240
1360
|
validationStatus: isValidating ? "pending" : validationResult.status,
|
|
1241
1361
|
isDirty,
|
|
1362
|
+
baselineValues,
|
|
1363
|
+
getDirtyValues,
|
|
1242
1364
|
isSubmitting,
|
|
1243
1365
|
isSubmitted,
|
|
1244
1366
|
touched,
|
|
@@ -1258,9 +1380,9 @@ function useDynamicForm({
|
|
|
1258
1380
|
}
|
|
1259
1381
|
|
|
1260
1382
|
// src/index.ts
|
|
1261
|
-
var import_core6 = require("@dynamic-field-kit/core");
|
|
1262
1383
|
var import_core7 = require("@dynamic-field-kit/core");
|
|
1263
1384
|
var import_core8 = require("@dynamic-field-kit/core");
|
|
1385
|
+
var import_core9 = require("@dynamic-field-kit/core");
|
|
1264
1386
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1265
1387
|
0 && (module.exports = {
|
|
1266
1388
|
DynamicFormDevTools,
|
|
@@ -1277,6 +1399,7 @@ var import_core8 = require("@dynamic-field-kit/core");
|
|
|
1277
1399
|
getDefaultRenderer,
|
|
1278
1400
|
indexGroupPathMap,
|
|
1279
1401
|
layoutRegistry,
|
|
1402
|
+
makeErrorId,
|
|
1280
1403
|
makeFieldId,
|
|
1281
1404
|
resolveDisabled,
|
|
1282
1405
|
resolveOptions,
|