react-form-manage 1.0.8-beta.24 → 1.0.8-beta.26
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 +14 -0
- package/dist/hooks/useFormListControl.js +10 -12
- package/dist/providers/Form.js +4 -5
- package/dist/stores/formStore.js +13 -0
- package/package.json +1 -1
- package/src/hooks/useFormListControl.ts +28 -31
- package/src/providers/Form.tsx +0 -3
- package/src/stores/formStore.ts +24 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,18 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.0.8-beta.25] - 2026-02-04
|
|
6
|
+
|
|
7
|
+
### Changes
|
|
8
|
+
|
|
9
|
+
- Remove cleanup stack execution for clearing form items and array values
|
|
10
|
+
|
|
5
11
|
## [1.0.8-beta.24] - 2026-02-04
|
|
6
12
|
|
|
7
13
|
### Fixes
|
|
14
|
+
|
|
8
15
|
- Fix cleanup item execution for proper FormItem unmounting
|
|
9
16
|
|
|
10
17
|
### Features
|
|
18
|
+
|
|
11
19
|
- Add `Component` prop to FormItem for wrapping input with custom elements
|
|
12
20
|
- Support custom wrapper components in FormItem
|
|
13
21
|
|
|
14
22
|
## [1.0.8-beta.23] - 2026-02-04
|
|
15
23
|
|
|
16
24
|
### Features
|
|
25
|
+
|
|
17
26
|
- Add `hidden` prop to FormItem for conditional visibility control
|
|
18
27
|
- Add `collectHiddenValue` option to control whether hidden form items contribute to form data collection
|
|
19
28
|
- FormItem can now be retrieved from Form instance
|
|
@@ -22,26 +31,31 @@ All notable changes to this project will be documented in this file.
|
|
|
22
31
|
## [1.0.8-beta.22] - 2026-02-02
|
|
23
32
|
|
|
24
33
|
### Changes
|
|
34
|
+
|
|
25
35
|
- Refactor: Adjust useFormItemControl and main.tsx for better performance
|
|
26
36
|
|
|
27
37
|
## [1.0.8-beta.21] - 2026-02-02
|
|
28
38
|
|
|
29
39
|
### Fixes
|
|
40
|
+
|
|
30
41
|
- Patch: Minor adjustments in useFormItemControl
|
|
31
42
|
|
|
32
43
|
## [1.0.8-beta.20] - 2026-02-02
|
|
33
44
|
|
|
34
45
|
### Features
|
|
46
|
+
|
|
35
47
|
- Trigger `initied` flag for onChange in `useFormItemControl` to properly mark form items as initialized
|
|
36
48
|
|
|
37
49
|
## [1.0.8-beta.19] - 2026-02-02
|
|
38
50
|
|
|
39
51
|
### Features
|
|
52
|
+
|
|
40
53
|
- Trigger `initied` flag for onChange in `useFormItemControl` to properly mark form items as initialized
|
|
41
54
|
|
|
42
55
|
## [1.0.8-beta.18] - 2026-02-01
|
|
43
56
|
|
|
44
57
|
### Features
|
|
58
|
+
|
|
45
59
|
- Avoid deep traversal into class instances/functions in path collection
|
|
46
60
|
- `getAllNoneObjStringPath` now skips non-plain objects and functions, only traverses arrays and plain objects
|
|
47
61
|
- Improves performance and prevents accidental property access on class instances
|
|
@@ -9,17 +9,16 @@ function useFormListControl({ name, form, initialValues, formName }) {
|
|
|
9
9
|
const contextForm = useFormContext();
|
|
10
10
|
const getFormValues = useFormStore((state) => state.getFormValues);
|
|
11
11
|
const [listFormInitValues, setListFormInitValues] = useState(void 0);
|
|
12
|
-
const { clearCacheData, setCacheData, setListener, getListener } = useFormStore(useShallow((state) => ({
|
|
12
|
+
const { clearCacheData, setCacheData, setListener, getListener, clearArrItems } = useFormStore(useShallow((state) => ({
|
|
13
13
|
// Cache
|
|
14
14
|
cacheData: state.cacheData,
|
|
15
15
|
clearCacheData: state.clearCacheData,
|
|
16
16
|
setCacheData: state.setCacheData,
|
|
17
17
|
// Listener
|
|
18
18
|
setListener: state.setListener,
|
|
19
|
-
getListener: state.getListener
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
setCleanUpStack: state.setCleanUpStack
|
|
19
|
+
getListener: state.getListener,
|
|
20
|
+
// Clear Arr Items
|
|
21
|
+
clearArrItems: state.clearArrItems
|
|
23
22
|
})));
|
|
24
23
|
const { initValue: internalInitValue, formState } = useFormStore(useShallow((state) => {
|
|
25
24
|
return {
|
|
@@ -55,15 +54,14 @@ function useFormListControl({ name, form, initialValues, formName }) {
|
|
|
55
54
|
const getNewValueCache = mapCurWithKey.filter(Boolean).map((c) => c.value);
|
|
56
55
|
const startRemoveIndex = formDataBeforeChange.length - getNewValueCache.length;
|
|
57
56
|
if (startRemoveIndex > 0) {
|
|
58
|
-
Array.from(Array(startRemoveIndex)).map((_, index) => {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
setCleanUpStack({
|
|
57
|
+
const clearItems = Array.from(Array(startRemoveIndex)).map((_, index) => {
|
|
58
|
+
const clearIndex = getNewValueCache.length + index;
|
|
59
|
+
return {
|
|
62
60
|
formName: formName || (form == null ? void 0 : form.formName) || (contextForm == null ? void 0 : contextForm.formName),
|
|
63
|
-
name: `${name}.${
|
|
64
|
-
|
|
65
|
-
});
|
|
61
|
+
name: `${name}.${clearIndex}`
|
|
62
|
+
};
|
|
66
63
|
});
|
|
64
|
+
clearArrItems(clearItems);
|
|
67
65
|
}
|
|
68
66
|
setCacheData(formName || (form == null ? void 0 : form.formName) || (contextForm == null ? void 0 : contextForm.formName), name, getNewValueCache);
|
|
69
67
|
};
|
package/dist/providers/Form.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { cloneDeep, filter, get, isEqual, isNil, isPlainObject, last, set, uniqBy } from "lodash";
|
|
3
3
|
import { useTask } from "minh-custom-hooks-release";
|
|
4
4
|
import { createContext, useContext, useEffect, useState } from "react";
|
|
5
5
|
import { flushSync } from "react-dom";
|
|
6
6
|
import { useShallow } from "zustand/react/shallow";
|
|
7
|
-
import FormCleanUp from "../components/Form/FormCleanUp";
|
|
8
7
|
import FormItem from "../components/Form/FormItem";
|
|
9
8
|
import { SUBMIT_STATE } from "../constants/form";
|
|
10
9
|
import { useFormStore } from "../stores/formStore";
|
|
@@ -300,9 +299,9 @@ function Form({ children, formName, initialValues, onFinish, onReject, onFinally
|
|
|
300
299
|
clearFormState(formName);
|
|
301
300
|
};
|
|
302
301
|
}, []);
|
|
303
|
-
return
|
|
302
|
+
return _jsx(FormContext.Provider, { value: {
|
|
304
303
|
formName
|
|
305
|
-
}, children:
|
|
304
|
+
}, children: FormElement ? _jsx(FormElement, { onSubmit: (e) => {
|
|
306
305
|
e.preventDefault();
|
|
307
306
|
e.stopPropagation();
|
|
308
307
|
runSubmit(void 0);
|
|
@@ -310,7 +309,7 @@ function Form({ children, formName, initialValues, onFinish, onReject, onFinally
|
|
|
310
309
|
e.preventDefault();
|
|
311
310
|
e.stopPropagation();
|
|
312
311
|
runSubmit(void 0);
|
|
313
|
-
}, ...props, children })
|
|
312
|
+
}, ...props, children }) });
|
|
314
313
|
}
|
|
315
314
|
function useFormContext() {
|
|
316
315
|
const c = useContext(FormContext);
|
package/dist/stores/formStore.js
CHANGED
|
@@ -72,6 +72,19 @@ const createFormStoreSlice = (storeSet, storeGet, api) => ({
|
|
|
72
72
|
}
|
|
73
73
|
}));
|
|
74
74
|
},
|
|
75
|
+
clearArrItems(clearItems) {
|
|
76
|
+
return storeSet(produce((state) => {
|
|
77
|
+
const oldValues = state.forms;
|
|
78
|
+
clearItems.forEach(({ formName, name }) => {
|
|
79
|
+
const arrPath = name.split(".").slice(0, -1).join(".");
|
|
80
|
+
const elPath = Number(name.split(".").slice(-1).join(""));
|
|
81
|
+
const getArrItem = get(oldValues, `${formName}.${arrPath}`);
|
|
82
|
+
if (isNumber(elPath)) {
|
|
83
|
+
getArrItem.splice(elPath, 1);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}));
|
|
87
|
+
},
|
|
75
88
|
setFormState({ formName, isInitied, submitState }) {
|
|
76
89
|
return storeSet(produce((state) => {
|
|
77
90
|
const oldValues = state.formStates;
|
package/package.json
CHANGED
|
@@ -35,24 +35,28 @@ export default function useFormListControl<T = any>({
|
|
|
35
35
|
const [listFormInitValues, setListFormInitValues] = useState<
|
|
36
36
|
any[] | undefined
|
|
37
37
|
>(undefined);
|
|
38
|
-
const {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
// Listener
|
|
47
|
-
setListener: state.setListener,
|
|
48
|
-
getListener: state.getListener,
|
|
49
|
-
})),
|
|
50
|
-
);
|
|
51
|
-
const { setCleanUpStack } = useFormStore(
|
|
38
|
+
const {
|
|
39
|
+
clearCacheData,
|
|
40
|
+
setCacheData,
|
|
41
|
+
setListener,
|
|
42
|
+
getListener,
|
|
43
|
+
clearArrItems,
|
|
44
|
+
} = useFormStore(
|
|
52
45
|
useShallow((state) => ({
|
|
53
|
-
|
|
46
|
+
// Cache
|
|
47
|
+
cacheData: state.cacheData,
|
|
48
|
+
clearCacheData: state.clearCacheData,
|
|
49
|
+
setCacheData: state.setCacheData,
|
|
50
|
+
|
|
51
|
+
// Listener
|
|
52
|
+
setListener: state.setListener,
|
|
53
|
+
getListener: state.getListener,
|
|
54
|
+
|
|
55
|
+
// Clear Arr Items
|
|
56
|
+
clearArrItems: state.clearArrItems,
|
|
54
57
|
})),
|
|
55
58
|
);
|
|
59
|
+
|
|
56
60
|
const { initValue: internalInitValue, formState } = useFormStore(
|
|
57
61
|
useShallow((state) => {
|
|
58
62
|
// console.log(
|
|
@@ -129,22 +133,15 @@ export default function useFormListControl<T = any>({
|
|
|
129
133
|
|
|
130
134
|
// Nếu số phần tử trước khi thay đổi mảng lớn hơn thì đẩy các phần tử còn lại vào clean up stack để clear
|
|
131
135
|
if (startRemoveIndex > 0) {
|
|
132
|
-
Array.from(Array(startRemoveIndex))
|
|
133
|
-
.
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
// });
|
|
142
|
-
setCleanUpStack({
|
|
143
|
-
formName: formName || form?.formName || contextForm?.formName,
|
|
144
|
-
name: `${name}.${index}`,
|
|
145
|
-
type: "array",
|
|
146
|
-
});
|
|
147
|
-
});
|
|
136
|
+
const clearItems = Array.from(Array(startRemoveIndex)).map((_, index) => {
|
|
137
|
+
const clearIndex = getNewValueCache.length + index;
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
formName: formName || form?.formName || contextForm?.formName,
|
|
141
|
+
name: `${name}.${clearIndex}`,
|
|
142
|
+
};
|
|
143
|
+
});
|
|
144
|
+
clearArrItems(clearItems);
|
|
148
145
|
}
|
|
149
146
|
|
|
150
147
|
console.log("Set cache data for form list: ", {
|
package/src/providers/Form.tsx
CHANGED
|
@@ -14,7 +14,6 @@ import type { ComponentType, FormHTMLAttributes, ReactNode } from "react";
|
|
|
14
14
|
import { createContext, useContext, useEffect, useState } from "react";
|
|
15
15
|
import { flushSync } from "react-dom";
|
|
16
16
|
import { useShallow } from "zustand/react/shallow"; // Import useShallow
|
|
17
|
-
import FormCleanUp from "../components/Form/FormCleanUp";
|
|
18
17
|
import FormItem from "../components/Form/FormItem";
|
|
19
18
|
import { SUBMIT_STATE } from "../constants/form";
|
|
20
19
|
import { ListenerItem, SubmitProps, useFormStore } from "../stores/formStore";
|
|
@@ -467,8 +466,6 @@ export default function Form<T = any>({
|
|
|
467
466
|
formName,
|
|
468
467
|
}}
|
|
469
468
|
>
|
|
470
|
-
<FormCleanUp />
|
|
471
|
-
|
|
472
469
|
{FormElement ? (
|
|
473
470
|
<FormElement
|
|
474
471
|
onSubmit={(e) => {
|
package/src/stores/formStore.ts
CHANGED
|
@@ -185,6 +185,30 @@ const createFormStoreSlice = (storeSet: any, storeGet: any, api: any) => ({
|
|
|
185
185
|
);
|
|
186
186
|
},
|
|
187
187
|
|
|
188
|
+
clearArrItems(clearItems: { formName: string; name: string }[]) {
|
|
189
|
+
return storeSet(
|
|
190
|
+
produce<any>((state: any) => {
|
|
191
|
+
const oldValues = state.forms;
|
|
192
|
+
|
|
193
|
+
console.log("Clear item array values: ", clearItems);
|
|
194
|
+
|
|
195
|
+
clearItems.forEach(({ formName, name }) => {
|
|
196
|
+
const arrPath = name.split(".").slice(0, -1).join(".");
|
|
197
|
+
|
|
198
|
+
const elPath = Number(name.split(".").slice(-1).join(""));
|
|
199
|
+
|
|
200
|
+
const getArrItem = get(oldValues, `${formName}.${arrPath}`);
|
|
201
|
+
|
|
202
|
+
if (isNumber(elPath)) {
|
|
203
|
+
getArrItem.splice(elPath, 1);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// console.log(JSON.parse(JSON.stringify(oldValues)));
|
|
208
|
+
}),
|
|
209
|
+
);
|
|
210
|
+
},
|
|
211
|
+
|
|
188
212
|
setFormState({ formName, isInitied, submitState }) {
|
|
189
213
|
return storeSet(
|
|
190
214
|
produce<any>((state: any) => {
|