react-form-manage 1.0.8-beta.9 → 1.0.8

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 (94) hide show
  1. package/CHANGELOG.md +173 -4
  2. package/README.md +8 -4
  3. package/dist/components/Form/FormCleanUp.js +3 -3
  4. package/dist/components/Form/FormItem.d.ts +10 -4
  5. package/dist/components/Form/FormItem.js +52 -14
  6. package/dist/components/Form/FormList.d.ts +2 -2
  7. package/dist/components/Form/FormList.js +2 -2
  8. package/dist/constants/form.d.ts +1 -1
  9. package/dist/hooks/useFormItemControl.d.ts +8 -3
  10. package/dist/hooks/useFormItemControl.js +64 -28
  11. package/dist/hooks/useFormListControl.d.ts +2 -1
  12. package/dist/hooks/useFormListControl.js +85 -19
  13. package/dist/index.cjs.d.ts +1 -0
  14. package/dist/index.d.ts +4 -3
  15. package/dist/index.esm.d.ts +1 -0
  16. package/dist/index.js +4 -2
  17. package/dist/providers/Form.d.ts +15 -2
  18. package/dist/providers/Form.js +197 -22
  19. package/dist/stores/formStore.d.ts +44 -4
  20. package/dist/stores/formStore.js +42 -7
  21. package/dist/test/CommonTest.d.ts +3 -0
  22. package/dist/test/CommonTest.js +49 -0
  23. package/dist/test/TestDialog.d.ts +3 -0
  24. package/dist/test/TestDialog.js +21 -0
  25. package/dist/test/TestListener.d.ts +3 -0
  26. package/dist/test/TestListener.js +17 -0
  27. package/dist/test/TestNotFormWrapper.d.ts +3 -0
  28. package/dist/test/TestNotFormWrapper.js +15 -0
  29. package/dist/test/TestSelect.d.ts +6 -0
  30. package/dist/test/TestSelect.js +24 -0
  31. package/dist/test/TestWatchNormalize.d.ts +3 -0
  32. package/dist/test/TestWatchNormalize.js +23 -0
  33. package/dist/test/TestWrapperFormItem.d.ts +3 -0
  34. package/dist/test/TestWrapperFormItem.js +13 -0
  35. package/dist/test/testSetValue/TestCase10_SetFieldValues_ComplexNested.d.ts +21 -0
  36. package/dist/test/testSetValue/TestCase10_SetFieldValues_ComplexNested.js +61 -0
  37. package/dist/test/testSetValue/TestCase1_PlainObjectToPrimitives.d.ts +16 -0
  38. package/dist/test/testSetValue/TestCase1_PlainObjectToPrimitives.js +18 -0
  39. package/dist/test/testSetValue/TestCase2_PlainObjectToFormList.d.ts +21 -0
  40. package/dist/test/testSetValue/TestCase2_PlainObjectToFormList.js +33 -0
  41. package/dist/test/testSetValue/TestCase3_ArrayNonListenerToPrimitives.d.ts +21 -0
  42. package/dist/test/testSetValue/TestCase3_ArrayNonListenerToPrimitives.js +26 -0
  43. package/dist/test/testSetValue/TestCase4_PlainObjectRemovedFields.d.ts +20 -0
  44. package/dist/test/testSetValue/TestCase4_PlainObjectRemovedFields.js +32 -0
  45. package/dist/test/testSetValue/TestCase5_FormListRemovedItems.d.ts +22 -0
  46. package/dist/test/testSetValue/TestCase5_FormListRemovedItems.js +29 -0
  47. package/dist/test/testSetValue/TestCase6_NestedFormListRemoved.d.ts +28 -0
  48. package/dist/test/testSetValue/TestCase6_NestedFormListRemoved.js +36 -0
  49. package/dist/test/testSetValue/TestCase7_SetFieldValues_MixedStructure.d.ts +17 -0
  50. package/dist/test/testSetValue/TestCase7_SetFieldValues_MixedStructure.js +33 -0
  51. package/dist/test/testSetValue/TestCase8_SetFieldValues_NestedObject.d.ts +27 -0
  52. package/dist/test/testSetValue/TestCase8_SetFieldValues_NestedObject.js +57 -0
  53. package/dist/test/testSetValue/TestCase9_SetFieldValues_MultipleArrays.d.ts +25 -0
  54. package/dist/test/testSetValue/TestCase9_SetFieldValues_MultipleArrays.js +46 -0
  55. package/dist/test/testSetValue/index.d.ts +2 -0
  56. package/dist/test/testSetValue/index.js +28 -0
  57. package/dist/types/index.d.ts +1 -1
  58. package/dist/types/public.d.ts +1 -1
  59. package/dist/utils/obj.util.d.ts +29 -1
  60. package/dist/utils/obj.util.js +59 -5
  61. package/package.json +2 -1
  62. package/src/App.tsx +38 -163
  63. package/src/DEEP_TRIGGER_LOGIC.md +573 -0
  64. package/src/components/Form/FormCleanUp.tsx +4 -8
  65. package/src/components/Form/FormItem.tsx +174 -57
  66. package/src/components/Form/FormList.tsx +17 -4
  67. package/src/constants/form.ts +1 -1
  68. package/src/hooks/useFormItemControl.ts +78 -32
  69. package/src/hooks/useFormListControl.ts +133 -43
  70. package/src/index.ts +25 -13
  71. package/src/main.tsx +6 -1
  72. package/src/providers/Form.tsx +451 -23
  73. package/src/stores/formStore.ts +363 -283
  74. package/src/test/CommonTest.tsx +177 -0
  75. package/src/test/TestDialog.tsx +52 -0
  76. package/src/test/TestListener.tsx +21 -0
  77. package/src/test/TestNotFormWrapper.tsx +43 -0
  78. package/src/test/TestSelect.tsx +38 -0
  79. package/src/test/TestWatchNormalize.tsx +32 -0
  80. package/src/test/TestWrapperFormItem.tsx +34 -0
  81. package/src/test/testSetValue/TestCase10_SetFieldValues_ComplexNested.tsx +203 -0
  82. package/src/test/testSetValue/TestCase1_PlainObjectToPrimitives.tsx +72 -0
  83. package/src/test/testSetValue/TestCase2_PlainObjectToFormList.tsx +114 -0
  84. package/src/test/testSetValue/TestCase3_ArrayNonListenerToPrimitives.tsx +99 -0
  85. package/src/test/testSetValue/TestCase4_PlainObjectRemovedFields.tsx +112 -0
  86. package/src/test/testSetValue/TestCase5_FormListRemovedItems.tsx +119 -0
  87. package/src/test/testSetValue/TestCase6_NestedFormListRemoved.tsx +185 -0
  88. package/src/test/testSetValue/TestCase7_SetFieldValues_MixedStructure.tsx +110 -0
  89. package/src/test/testSetValue/TestCase8_SetFieldValues_NestedObject.tsx +162 -0
  90. package/src/test/testSetValue/TestCase9_SetFieldValues_MultipleArrays.tsx +169 -0
  91. package/src/test/testSetValue/index.tsx +100 -0
  92. package/src/types/index.ts +1 -1
  93. package/src/types/public.ts +1 -1
  94. package/src/utils/obj.util.ts +153 -13
@@ -3,7 +3,7 @@ import { cloneDeep, get, isNil, isNumber, last, set, unset } from "lodash";
3
3
  import { v4 } from "uuid";
4
4
  import { create } from "zustand";
5
5
  import { getAllNoneObjStringPath } from "../utils/obj.util";
6
- const useFormStore = create((storeSet, storeGet) => ({
6
+ const createFormStoreSlice = (storeSet, storeGet, api) => ({
7
7
  forms: {},
8
8
  initialValues: {},
9
9
  formStates: {},
@@ -72,6 +72,19 @@ const useFormStore = create((storeSet, storeGet) => ({
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;
@@ -191,8 +204,8 @@ const useFormStore = create((storeSet, storeGet) => ({
191
204
  }
192
205
  }));
193
206
  }
194
- }));
195
- const useFormListeners = create((storeSet, storeGet) => ({
207
+ });
208
+ const createListenersSlice = (storeSet, storeGet, api) => ({
196
209
  listeners: [],
197
210
  getListener(formItemId) {
198
211
  return storeGet().listeners.find((l) => l.formItemId === formItemId);
@@ -200,7 +213,7 @@ const useFormListeners = create((storeSet, storeGet) => ({
200
213
  getListeners() {
201
214
  return storeGet().listeners;
202
215
  },
203
- setListener({ formName, name, onChange, onReset, isTouched, isDirty, formItemId, internalErrors, onFocus, emitFocus, isInitied }) {
216
+ setListener({ formName, name, onChange, onReset, isTouched, isDirty, formItemId, internalErrors, onFocus, emitFocus, isInitied, type, onArrayChange, hidden, collectOnHidden }) {
204
217
  return storeSet(produce((state) => {
205
218
  const storeListeners = state.listeners;
206
219
  const findListenerIndex = state.listeners.findIndex((l) => l.formItemId === formItemId);
@@ -235,6 +248,15 @@ const useFormListeners = create((storeSet, storeGet) => ({
235
248
  if (!isNil(isInitied)) {
236
249
  storeListeners[findListenerIndex].isInitied = isInitied;
237
250
  }
251
+ if (!isNil(onArrayChange)) {
252
+ storeListeners[findListenerIndex].onArrayChange = onArrayChange;
253
+ }
254
+ if (!isNil(hidden)) {
255
+ storeListeners[findListenerIndex].hidden = hidden;
256
+ }
257
+ if (!isNil(collectOnHidden)) {
258
+ storeListeners[findListenerIndex].collectOnHidden = collectOnHidden;
259
+ }
238
260
  return;
239
261
  }
240
262
  storeListeners.push({
@@ -246,7 +268,13 @@ const useFormListeners = create((storeSet, storeGet) => ({
246
268
  internalErrors,
247
269
  onChange,
248
270
  onReset,
249
- isInitied: Boolean(isInitied)
271
+ isInitied: Boolean(isInitied),
272
+ type: type || "normal",
273
+ onArrayChange,
274
+ onFocus,
275
+ emitFocus,
276
+ hidden: Boolean(hidden),
277
+ collectOnHidden
250
278
  });
251
279
  }));
252
280
  },
@@ -261,8 +289,8 @@ const useFormListeners = create((storeSet, storeGet) => ({
261
289
  }
262
290
  }));
263
291
  }
264
- }));
265
- const useFormCleanUp = create((storeSet) => ({
292
+ });
293
+ const createCleanUpSlice = (storeSet, storeGet, api) => ({
266
294
  cleanUpStack: [],
267
295
  setCleanUpStack({ name, type, itemKey, formName }) {
268
296
  return storeSet(produce((state) => {
@@ -276,7 +304,14 @@ const useFormCleanUp = create((storeSet) => ({
276
304
  state.cleanUpStack = [];
277
305
  }));
278
306
  }
307
+ });
308
+ const useFormStore = create((...a) => ({
309
+ ...createFormStoreSlice(...a),
310
+ ...createListenersSlice(...a),
311
+ ...createCleanUpSlice(...a)
279
312
  }));
313
+ const useFormListeners = useFormStore;
314
+ const useFormCleanUp = useFormStore;
280
315
  export {
281
316
  useFormCleanUp,
282
317
  useFormListeners,
@@ -0,0 +1,3 @@
1
+ type Props = {};
2
+ declare function CommonTest({}: Props): import("react/jsx-runtime").JSX.Element;
3
+ export default CommonTest;
@@ -0,0 +1,49 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Checkbox, Input } from "antd";
3
+ import { motion } from "framer-motion";
4
+ import FormItem from "../components/Form/FormItem";
5
+ import FormList from "../components/Form/FormList";
6
+ import InputWrapper from "../components/Form/InputWrapper";
7
+ import Form from "../providers/Form";
8
+ function CommonTest({}) {
9
+ const [form] = Form.useForm("form1");
10
+ const watchCheckBox = Form.useWatch("checkControlledAfterInit", "form1");
11
+ return _jsxs(Form, { initialValues: {
12
+ TestData: "",
13
+ numericCode: ""
14
+ // arr: [{ el: "Item 1" }, { el: "Item 2" }],
15
+ }, onFinish: (values) => {
16
+ }, formName: "form1", children: [_jsx(FormItem, { name: "username", rules: [
17
+ {
18
+ required: true,
19
+ message: "Test"
20
+ }
21
+ ], initialValue: "283746", children: _jsx(InputWrapper, { children: _jsx(Input, {}) }) }), _jsx(FormItem, { name: "numericCode", rules: [
22
+ { required: true, message: "Vui l\xF2ng nh\u1EADp m\xE3" },
23
+ {
24
+ pattern: /^\d+$/,
25
+ message: "Ch\u1EC9 cho ph\xE9p chu\u1ED7i s\u1ED1"
26
+ }
27
+ ], children: _jsx(InputWrapper, { children: _jsx(Input, { placeholder: "M\xE3 ch\u1EC9 g\u1ED3m s\u1ED1", style: { width: 200 } }) }) }), _jsx(motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, transition: { duration: 1 }, children: _jsx(FormItem, { name: "motionTest", controlAfterInit: true, initialValue: "1234134", children: _jsx(InputWrapper, { children: _jsx(Input, { placeholder: "Motion Test", style: { width: 200 } }) }) }) }), _jsx(FormList, { initialValues: [
28
+ {
29
+ el: "sdfsdf",
30
+ d: { child: "Test Child" }
31
+ }
32
+ ], name: "arr", children: (fields, { add, remove, move }) => _jsxs("div", { children: [fields.map((field, index) => _jsxs("div", { style: { marginBottom: 8 }, children: [_jsx(FormItem, { name: `${field.name}.el`, initialValue: "Ch\xE9m gi\xF3", children: _jsx(InputWrapper, { children: _jsx(Input, { placeholder: "Item value", style: { width: 200 } }) }) }), _jsx(FormItem, { name: `${field.name}.d.child`, initialValue: "Con c\u1EE7a item", children: _jsx(InputWrapper, { children: _jsx(Input, { placeholder: "Item value", style: { width: 200 } }) }) }), _jsx(Button, { onClick: () => remove({ index }), style: { marginLeft: 8 }, children: "Remove" }), index > 0 && _jsx(Button, { onClick: () => move({ from: index, to: index - 1 }), style: { marginLeft: 8 }, children: "Move Up" }), index < fields.length - 1 && _jsx(Button, { onClick: () => move({ from: index, to: index + 1 }), style: { marginLeft: 8 }, children: "Move Down" })] }, field.key)), _jsx(Button, { onClick: () => add(fields.length), children: "Add Item" })] }) }), _jsx(Button, { onClick: () => {
33
+ form == null ? void 0 : form.setFieldValue("arr", [
34
+ { el: "Set Item 1" },
35
+ { el: "Set Item 2" },
36
+ { el: "Set Item 3" }
37
+ ]);
38
+ }, children: "Test set array list value" }), _jsx(motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, transition: { duration: 1.5 }, children: _jsx(Form.Item, { valuePropName: "checked", getValueFromEvent: (_, checked) => checked, name: "checkControlledAfterInit", controlAfterInit: true, initialValue: true, hidden: true, children: _jsx(Checkbox, {}) }) }), _jsx(Button, { onClick: () => {
39
+ const current = form == null ? void 0 : form.getFieldValue("checkControlledAfterInit");
40
+ form == null ? void 0 : form.setFieldValue("checkControlledAfterInit", !current);
41
+ }, children: "Toggle" }), _jsx(Button, { htmlType: "submit", children: "Submit" }), _jsx(Button, { onClick: () => {
42
+ var _a;
43
+ (_a = form == null ? void 0 : form.resetFields) == null ? void 0 : _a.call(form);
44
+ }, children: "Reset" })] });
45
+ }
46
+ var stdin_default = CommonTest;
47
+ export {
48
+ stdin_default as default
49
+ };
@@ -0,0 +1,3 @@
1
+ type Props = {};
2
+ declare function TestDialog({}: Props): import("react/jsx-runtime").JSX.Element;
3
+ export default TestDialog;
@@ -0,0 +1,21 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Dialog, DialogContent, DialogContentText, DialogTitle, TextField } from "@mui/material";
3
+ import { Box } from "@mui/system";
4
+ import { useToggle } from "minh-custom-hooks-release";
5
+ import FormItem from "../components/Form/FormItem";
6
+ import TestSelect from "./TestSelect";
7
+ function TestDialog({}) {
8
+ const { state: open, toggle } = useToggle();
9
+ return _jsxs(Box, { children: [_jsxs(Dialog, { open, onClose: toggle, children: [_jsx(DialogTitle, { children: "Test Dialog" }), _jsxs(DialogContent, { children: [_jsx(DialogContentText, { children: "This is a test dialog." }), _jsx(FormItem, { rules: [
10
+ {
11
+ handler(value) {
12
+ return Boolean(value);
13
+ },
14
+ message: "Testt"
15
+ }
16
+ ], controlAfterInit: true, initialValue: null, name: "testSelectInsideDialog", children: _jsx(TestSelect, {}) }), _jsx(FormItem, { controlAfterInit: true, initialValue: "", name: "anotherField", children: _jsx(TextField, {}) })] })] }), _jsx(Button, { variant: "contained", onClick: toggle, children: "Open Test Dialog" })] });
17
+ }
18
+ var stdin_default = TestDialog;
19
+ export {
20
+ stdin_default as default
21
+ };
@@ -0,0 +1,3 @@
1
+ type Props = {};
2
+ declare function TestListener({}: Props): import("react/jsx-runtime").JSX.Element;
3
+ export default TestListener;
@@ -0,0 +1,17 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cloneDeep } from "lodash";
3
+ import { useEffect } from "react";
4
+ import { useShallow } from "zustand/react/shallow";
5
+ import { useFormStore } from "../stores/formStore";
6
+ function TestListener({}) {
7
+ const { listeners } = useFormStore(useShallow((state) => ({
8
+ listeners: state.listeners
9
+ })));
10
+ useEffect(() => {
11
+ }, [listeners]);
12
+ return _jsx("div", { children: "TestListener" });
13
+ }
14
+ var stdin_default = TestListener;
15
+ export {
16
+ stdin_default as default
17
+ };
@@ -0,0 +1,3 @@
1
+ type Props = {};
2
+ declare function TestNotFormWrapper({}: Props): import("react/jsx-runtime").JSX.Element;
3
+ export default TestNotFormWrapper;
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Input } from "antd";
3
+ function TestNotFormWrapper({}) {
4
+ return _jsx("div", { onSubmit: (e) => {
5
+ e.preventDefault();
6
+ }, children: _jsxs("form", { id: "not-form", onSubmit: (e) => {
7
+ e.preventDefault();
8
+ }, children: [_jsxs("div", { id: "child-form", onSubmit: (e) => {
9
+ e.preventDefault();
10
+ }, children: [_jsx(Input, {}), _jsx(Button, { htmlType: "submit", form: "child-form", children: "Child Form Submit" })] }), _jsx(Input, {}), _jsx(Button, { htmlType: "submit", form: "not-form", children: "Submit" })] }) });
11
+ }
12
+ var stdin_default = TestNotFormWrapper;
13
+ export {
14
+ stdin_default as default
15
+ };
@@ -0,0 +1,6 @@
1
+ type Props = {
2
+ value?: any;
3
+ onChange?: (value: any) => void;
4
+ };
5
+ declare function TestSelect({ value, onChange }: Props): import("react/jsx-runtime").JSX.Element;
6
+ export default TestSelect;
@@ -0,0 +1,24 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Autocomplete, TextField } from "@mui/material";
3
+ function TestSelect({ value = null, onChange }) {
4
+ return _jsx(Autocomplete, { value, onChange: (_, newValue) => {
5
+ onChange == null ? void 0 : onChange(newValue);
6
+ }, renderInput: (params) => _jsx(TextField, { ...params }), options: [
7
+ {
8
+ value: "option1",
9
+ label: "Option 1"
10
+ },
11
+ {
12
+ value: "option2",
13
+ label: "Option 2"
14
+ }
15
+ ], getOptionKey: (o) => {
16
+ return o == null ? void 0 : o.value;
17
+ }, getOptionLabel: (o) => {
18
+ return o == null ? void 0 : o.label;
19
+ } });
20
+ }
21
+ var stdin_default = TestSelect;
22
+ export {
23
+ stdin_default as default
24
+ };
@@ -0,0 +1,3 @@
1
+ type Props = {};
2
+ declare function TestWatchNormalize({}: Props): import("react/jsx-runtime").JSX.Element;
3
+ export default TestWatchNormalize;
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Input } from "antd";
3
+ import React from "react";
4
+ import Form from "../providers/Form";
5
+ function TestWatchNormalize({}) {
6
+ const normalizeData = Form.useWatchNormalized({
7
+ name: "normalizeItem",
8
+ formNameOrFormInstance: "testNormalize",
9
+ normalizeFn: (value) => {
10
+ if (typeof value === "string") {
11
+ return value.toUpperCase();
12
+ }
13
+ return value;
14
+ }
15
+ });
16
+ React.useEffect(() => {
17
+ }, [normalizeData]);
18
+ return _jsxs(Form, { formName: "testNormalize", children: ["Test Watch Normalize", _jsx(Form.Item, { name: "normalizeItem", children: _jsx(Input, {}) })] });
19
+ }
20
+ var stdin_default = TestWatchNormalize;
21
+ export {
22
+ stdin_default as default
23
+ };
@@ -0,0 +1,3 @@
1
+ type Props = {};
2
+ declare function TestWrapperFormItem({}: Props): import("react/jsx-runtime").JSX.Element;
3
+ export default TestWrapperFormItem;
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Col, Input, Row } from "antd";
3
+ import { useToggle } from "minh-custom-hooks-release";
4
+ import Form from "../providers/Form";
5
+ function TestWrapperFormItem({}) {
6
+ const { state, toggle } = useToggle(false);
7
+ return _jsxs(Form, { onFinish: (values, all) => {
8
+ }, formName: "testWrapper", children: [_jsx(Row, { children: _jsx(Form.Item, { hidden: !state, name: "test", collectOnHidden: false, initialValue: "test", Component: Col, xs: 12, children: _jsx(Input, {}) }) }), _jsx(Button, { htmlType: "submit", children: "Submit" }), _jsx(Button, { onClick: toggle, children: state ? "Off" : "On" })] });
9
+ }
10
+ var stdin_default = TestWrapperFormItem;
11
+ export {
12
+ stdin_default as default
13
+ };
@@ -0,0 +1,21 @@
1
+ type Props = {};
2
+ /**
3
+ * Test Case 10: setFieldValues với Complex Nested Structure
4
+ *
5
+ * Cấu trúc phức tạp:
6
+ * - config.appName (string)
7
+ * - config.version (string)
8
+ * - config.features (array) - deepTrigger
9
+ * - users (FormList array) - deepTrigger
10
+ * - users.0.name (string)
11
+ * - users.0.roles (array) - nested array trong FormList
12
+ *
13
+ * Test: setFieldValues với structure phức tạp nhiều cấp
14
+ *
15
+ * Kỳ vọng:
16
+ * - Primitives trigger onChange
17
+ * - Arrays ở mọi level đều gọi handleDeepTriggerSet
18
+ * - Nested arrays trong FormList được xử lý đúng
19
+ */
20
+ declare function TestCase10_SetFieldValues_ComplexNested({}: Props): import("react/jsx-runtime").JSX.Element;
21
+ export default TestCase10_SetFieldValues_ComplexNested;
@@ -0,0 +1,61 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box } from "@mui/material";
3
+ import { Button, Input, Typography } from "antd";
4
+ import FormList from "../../components/Form/FormList";
5
+ import Form from "../../providers/Form";
6
+ function TestCase10_SetFieldValues_ComplexNested({}) {
7
+ const [form] = Form.useForm("testCase10");
8
+ const handleTestSetFieldValues = () => {
9
+ form == null ? void 0 : form.setFieldValues({
10
+ config: {
11
+ appName: "My App",
12
+ version: "1.0.0",
13
+ features: ["auth", "api", "ui"]
14
+ },
15
+ users: [
16
+ { name: "John", roles: ["admin", "editor"] },
17
+ { name: "Jane", roles: ["viewer"] }
18
+ ]
19
+ });
20
+ };
21
+ const handleTestUpdateStructure = () => {
22
+ form == null ? void 0 : form.setFieldValues({
23
+ config: {
24
+ appName: "Updated App",
25
+ version: "2.0.0",
26
+ features: ["auth", "api"]
27
+ // removed "ui"
28
+ },
29
+ users: [
30
+ { name: "John", roles: ["admin"] }
31
+ // removed editor role + removed Jane user
32
+ ]
33
+ });
34
+ };
35
+ const handleClear = () => {
36
+ form == null ? void 0 : form.setFieldValues({
37
+ config: {
38
+ appName: "",
39
+ version: "",
40
+ features: []
41
+ },
42
+ users: []
43
+ });
44
+ };
45
+ return _jsxs(Box, { sx: { p: 2 }, children: [_jsx(Typography.Title, { level: 4, children: "Test Case 10: setFieldValues - Complex Nested" }), _jsx(Typography.Paragraph, { children: "Test setFieldValues v\u1EDBi structure ph\u1EE9c t\u1EA1p: nested objects + arrays + FormList" }), _jsxs(Form, { formName: "testCase10", children: [_jsxs(Box, { sx: { border: "2px solid #1890ff", p: 2, mb: 2, borderRadius: 1 }, children: [_jsx(Typography.Text, { strong: true, style: { fontSize: 16 }, children: "Config" }), _jsx(Form.Item, { name: "config.appName", label: "App Name", children: _jsx(Input, { placeholder: "Enter app name" }) }), _jsx(Form.Item, { name: "config.version", label: "Version", children: _jsx(Input, { placeholder: "Enter version" }) }), _jsxs(Box, { sx: { mt: 1 }, children: [_jsx(Typography.Text, { children: "Features (Array):" }), _jsx(Form.Item, { name: "config.features.0", children: _jsx(Input, { placeholder: "Feature 1" }) }), _jsx(Form.Item, { name: "config.features.1", children: _jsx(Input, { placeholder: "Feature 2" }) }), _jsx(Form.Item, { name: "config.features.2", children: _jsx(Input, { placeholder: "Feature 3" }) })] })] }), _jsxs(Box, { sx: { border: "2px solid #52c41a", p: 2, mb: 2, borderRadius: 1 }, children: [_jsx(Typography.Text, { strong: true, style: { fontSize: 16 }, children: "Users (FormList)" }), _jsx(FormList, { name: "users", children: (fields, { add, remove }) => _jsxs(Box, { children: [fields.map((field, index) => _jsxs(Box, { sx: {
46
+ border: "1px dashed #52c41a",
47
+ p: 1,
48
+ mb: 1,
49
+ borderRadius: 1
50
+ }, children: [_jsxs(Typography.Text, { children: ["User ", index + 1] }), _jsx(Form.Item, { name: `users.${index}.name`, label: "Name", children: _jsx(Input, { placeholder: "User name" }) }), _jsxs(Box, { sx: { ml: 2, bgcolor: "#f6ffed", p: 1, borderRadius: 1 }, children: [_jsx(Typography.Text, { children: "Roles (Nested Array):" }), _jsx(Form.Item, { name: `users.${index}.roles.0`, children: _jsx(Input, { placeholder: "Role 1" }) }), _jsx(Form.Item, { name: `users.${index}.roles.1`, children: _jsx(Input, { placeholder: "Role 2" }) })] }), _jsx(Button, { danger: true, size: "small", onClick: () => remove({ key: field.key }), children: "Remove User" })] }, field.key)), _jsx(Button, { type: "dashed", onClick: () => add(), children: "Add User" })] }) })] }), _jsxs(Box, { sx: { mt: 2, display: "flex", gap: 2, flexDirection: "column" }, children: [_jsx(Button, { type: "primary", onClick: handleTestSetFieldValues, children: "1. Set Complex Structure" }), _jsx(Button, { onClick: handleTestUpdateStructure, children: "2. Update with Cleanup" }), _jsx(Button, { danger: true, onClick: handleClear, children: "3. Clear All" })] }), _jsxs(Box, { sx: {
51
+ mt: 2,
52
+ p: 2,
53
+ bgcolor: "#e6fffb",
54
+ border: "1px solid #13c2c2",
55
+ borderRadius: 1
56
+ }, children: [_jsx(Typography.Text, { strong: true, children: "Expected Behavior:" }), _jsxs(Typography.Paragraph, { children: [_jsx("strong", { children: "setFieldValues logic:" }), _jsx("br", {}), "- Traverse object, d\u1EEBng t\u1EA1i m\u1ED7i array", _jsx("br", {}), "- Primitives: trigger onChange", _jsx("br", {}), "- Arrays: g\u1ECDi handleDeepTriggerSet", _jsx("br", {}), _jsx("br", {}), _jsx("strong", { children: "Update with Cleanup:" }), _jsx("br", {}), "- config.features.2 \u2192 undefined (removed)", _jsx("br", {}), "- users.1 \u2192 undefined (Jane removed)", _jsx("br", {}), "- users.0.roles.1 \u2192 undefined (editor removed)"] })] })] })] });
57
+ }
58
+ var stdin_default = TestCase10_SetFieldValues_ComplexNested;
59
+ export {
60
+ stdin_default as default
61
+ };
@@ -0,0 +1,16 @@
1
+ type Props = {};
2
+ /**
3
+ * Test Case 1: Plain Object → Primitive Listeners
4
+ *
5
+ * Cấu trúc:
6
+ * - user.name (string)
7
+ * - user.age (number)
8
+ *
9
+ * Test: setFieldValue("user", {name: "John", age: 30}, {deepTrigger: true})
10
+ * Kỳ vọng:
11
+ * - Trigger "user" listener (nếu có)
12
+ * - Trigger "user.name" listener
13
+ * - Trigger "user.age" listener
14
+ */
15
+ declare function TestCase1_PlainObjectToPrimitives({}: Props): import("react/jsx-runtime").JSX.Element;
16
+ export default TestCase1_PlainObjectToPrimitives;
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box } from "@mui/material";
3
+ import { Button, Input, Typography } from "antd";
4
+ import Form from "../../providers/Form";
5
+ function TestCase1_PlainObjectToPrimitives({}) {
6
+ const [form] = Form.useForm("testCase1");
7
+ const handleTestDeepTrigger = () => {
8
+ form == null ? void 0 : form.setFieldValue("user", { name: "John Doe", age: 30 }, { deepTrigger: true });
9
+ };
10
+ const handleTestNormalSet = () => {
11
+ form == null ? void 0 : form.setFieldValue("user", { name: "Jane Doe", age: 25 });
12
+ };
13
+ return _jsxs(Box, { sx: { p: 2 }, children: [_jsx(Typography.Title, { level: 4, children: "Test Case 1: Plain Object \u2192 Primitive Listeners" }), _jsxs(Typography.Paragraph, { children: ['Test setFieldValue("user", ', "{name, age}", ") v\u1EDBi deepTrigger=true"] }), _jsxs(Form, { formName: "testCase1", children: [_jsx(Form.Item, { name: "user", children: _jsx(Input, { placeholder: "User Object (JSON)", disabled: true }) }), _jsx(Form.Item, { name: "user.name", label: "Name", children: _jsx(Input, { placeholder: "Enter name" }) }), _jsx(Form.Item, { name: "user.age", label: "Age", children: _jsx(Input, { type: "number", placeholder: "Enter age" }) }), _jsxs(Box, { sx: { mt: 2, display: "flex", gap: 2 }, children: [_jsx(Button, { type: "primary", onClick: handleTestDeepTrigger, children: "Test Deep Trigger" }), _jsx(Button, { onClick: handleTestNormalSet, children: "Test Normal Set" })] })] })] });
14
+ }
15
+ var stdin_default = TestCase1_PlainObjectToPrimitives;
16
+ export {
17
+ stdin_default as default
18
+ };
@@ -0,0 +1,21 @@
1
+ type Props = {};
2
+ /**
3
+ * Test Case 2: Plain Object → Array Listener (FormList) → Primitives
4
+ *
5
+ * Cấu trúc:
6
+ * - user.name (string)
7
+ * - user.items (array - FormList)
8
+ * - user.items.0.id (number)
9
+ * - user.items.0.title (string)
10
+ *
11
+ * Test: setFieldValue("user", {name: "John", items: [{id: 1, title: "Item 1"}]}, {deepTrigger: true})
12
+ * Kỳ vọng:
13
+ * - Trigger "user" listener
14
+ * - Trigger "user.name" listener
15
+ * - Trigger "user.items" onArrayChange
16
+ * - Trigger "user.items.0" listener
17
+ * - Trigger "user.items.0.id" listener
18
+ * - Trigger "user.items.0.title" listener
19
+ */
20
+ declare function TestCase2_PlainObjectToFormList({}: Props): import("react/jsx-runtime").JSX.Element;
21
+ export default TestCase2_PlainObjectToFormList;
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box } from "@mui/material";
3
+ import { Button, Input, Typography } from "antd";
4
+ import FormList from "../../components/Form/FormList";
5
+ import Form from "../../providers/Form";
6
+ function TestCase2_PlainObjectToFormList({}) {
7
+ const [form] = Form.useForm("testCase2");
8
+ const handleTestDeepTrigger = () => {
9
+ form == null ? void 0 : form.setFieldValue("user", {
10
+ name: "John Doe",
11
+ items: [
12
+ { id: 1, title: "Item 1" },
13
+ { id: 2, title: "Item 2" }
14
+ ]
15
+ }, { deepTrigger: true });
16
+ };
17
+ const handleTestNormalSet = () => {
18
+ form == null ? void 0 : form.setFieldValue("user", {
19
+ name: "Jane Doe",
20
+ items: [{ id: 3, title: "Item 3" }]
21
+ });
22
+ };
23
+ return _jsxs(Box, { sx: { p: 2 }, children: [_jsx(Typography.Title, { level: 4, children: "Test Case 2: Plain Object \u2192 FormList \u2192 Primitives" }), _jsxs(Typography.Paragraph, { children: ['Test setFieldValue("user", ', "{name, items: [...]}", ") v\u1EDBi nested FormList"] }), _jsxs(Form, { formName: "testCase2", children: [_jsx(Form.Item, { name: "user.name", label: "User Name", children: _jsx(Input, { placeholder: "Enter user name" }) }), _jsx(FormList, { name: "user.items", children: (fields, { add, remove }) => _jsxs(Box, { children: [fields.map((field, index) => _jsxs(Box, { sx: {
24
+ border: "1px solid #d9d9d9",
25
+ p: 2,
26
+ mb: 2,
27
+ borderRadius: 1
28
+ }, children: [_jsxs(Typography.Text, { strong: true, children: ["Item ", index + 1] }), _jsx(Form.Item, { name: `user.items.${index}.id`, label: "ID", children: _jsx(Input, { placeholder: "Item ID" }) }), _jsx(Form.Item, { name: `user.items.${index}.title`, label: "Title", children: _jsx(Input, { placeholder: "Item title" }) }), _jsx(Button, { danger: true, onClick: () => remove({ key: field.key }), children: "Remove" })] }, field.key)), _jsx(Button, { type: "dashed", onClick: () => add(), children: "Add Item" })] }) }), _jsxs(Box, { sx: { mt: 2, display: "flex", gap: 2 }, children: [_jsx(Button, { type: "primary", onClick: handleTestDeepTrigger, children: "Test Deep Trigger" }), _jsx(Button, { onClick: handleTestNormalSet, children: "Test Normal Set" })] })] })] });
29
+ }
30
+ var stdin_default = TestCase2_PlainObjectToFormList;
31
+ export {
32
+ stdin_default as default
33
+ };
@@ -0,0 +1,21 @@
1
+ type Props = {};
2
+ /**
3
+ * Test Case 3: Array Non-Listener → Primitives
4
+ *
5
+ * Cấu trúc:
6
+ * - data (array - KHÔNG phải FormList, chỉ là field bình thường)
7
+ * - data.0.name (string)
8
+ * - data.0.value (number)
9
+ *
10
+ * Test: setFieldValue("data", [{name: "A", value: 1}, {name: "B", value: 2}], {deepTrigger: true})
11
+ * Kỳ vọng:
12
+ * - Set data array vào store
13
+ * - Trigger "data.0" listener (nếu có)
14
+ * - Trigger "data.0.name" listener
15
+ * - Trigger "data.0.value" listener
16
+ * - Trigger "data.1" listener (nếu có)
17
+ * - Trigger "data.1.name" listener
18
+ * - Trigger "data.1.value" listener
19
+ */
20
+ declare function TestCase3_ArrayNonListenerToPrimitives({}: Props): import("react/jsx-runtime").JSX.Element;
21
+ export default TestCase3_ArrayNonListenerToPrimitives;
@@ -0,0 +1,26 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box } from "@mui/material";
3
+ import { Button, Input, Typography } from "antd";
4
+ import Form from "../../providers/Form";
5
+ function TestCase3_ArrayNonListenerToPrimitives({}) {
6
+ const [form] = Form.useForm("testCase3");
7
+ const handleTestDeepTrigger = () => {
8
+ form == null ? void 0 : form.setFieldValue("data", [
9
+ { name: "Item A", value: 100 },
10
+ { name: "Item B", value: 200 }
11
+ ], { deepTrigger: true });
12
+ };
13
+ const handleTestRemoveItems = () => {
14
+ form == null ? void 0 : form.setFieldValue("data", [{ name: "Item A", value: 100 }], {
15
+ deepTrigger: true
16
+ });
17
+ };
18
+ const handleTestNormalSet = () => {
19
+ form == null ? void 0 : form.setFieldValue("data", [{ name: "Item C", value: 300 }]);
20
+ };
21
+ return _jsxs(Box, { sx: { p: 2 }, children: [_jsx(Typography.Title, { level: 4, children: "Test Case 3: Array Non-Listener \u2192 Primitives" }), _jsxs(Typography.Paragraph, { children: ['Test setFieldValue("data", ', "[{name, value}, ...]", ") v\u1EDBi array kh\xF4ng ph\u1EA3i FormList"] }), _jsxs(Form, { formName: "testCase3", children: [_jsxs(Box, { sx: { border: "1px solid #d9d9d9", p: 2, mb: 2, borderRadius: 1 }, children: [_jsx(Typography.Text, { strong: true, children: "Item 0" }), _jsx(Form.Item, { name: "data.0.name", label: "Name", children: _jsx(Input, { placeholder: "Item 0 name" }) }), _jsx(Form.Item, { name: "data.0.value", label: "Value", children: _jsx(Input, { type: "number", placeholder: "Item 0 value" }) })] }), _jsxs(Box, { sx: { border: "1px solid #d9d9d9", p: 2, mb: 2, borderRadius: 1 }, children: [_jsx(Typography.Text, { strong: true, children: "Item 1" }), _jsx(Form.Item, { name: "data.1.name", label: "Name", children: _jsx(Input, { placeholder: "Item 1 name" }) }), _jsx(Form.Item, { name: "data.1.value", label: "Value", children: _jsx(Input, { type: "number", placeholder: "Item 1 value" }) })] }), _jsxs(Box, { sx: { mt: 2, display: "flex", gap: 2 }, children: [_jsx(Button, { type: "primary", onClick: handleTestDeepTrigger, children: "Test Deep Trigger (2 items)" }), _jsx(Button, { onClick: handleTestRemoveItems, children: "Test Remove Items (1 item)" }), _jsx(Button, { onClick: handleTestNormalSet, children: "Test Normal Set" })] })] })] });
22
+ }
23
+ var stdin_default = TestCase3_ArrayNonListenerToPrimitives;
24
+ export {
25
+ stdin_default as default
26
+ };
@@ -0,0 +1,20 @@
1
+ type Props = {};
2
+ /**
3
+ * Test Case 4: Plain Object with Removed Fields (Edge Case)
4
+ *
5
+ * Cấu trúc ban đầu:
6
+ * - profile.name (string)
7
+ * - profile.city (string)
8
+ * - profile.country (string)
9
+ *
10
+ * Test:
11
+ * 1. Set initial: {name: "John", city: "NY", country: "USA"}
12
+ * 2. Set removed: {name: "John"} (city và country bị xóa)
13
+ *
14
+ * Kỳ vọng:
15
+ * - Trigger "profile.name" với "John"
16
+ * - Trigger "profile.city" với undefined (cleanup)
17
+ * - Trigger "profile.country" với undefined (cleanup)
18
+ */
19
+ declare function TestCase4_PlainObjectRemovedFields({}: Props): import("react/jsx-runtime").JSX.Element;
20
+ export default TestCase4_PlainObjectRemovedFields;
@@ -0,0 +1,32 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box } from "@mui/material";
3
+ import { Button, Input, Typography } from "antd";
4
+ import Form from "../../providers/Form";
5
+ function TestCase4_PlainObjectRemovedFields({}) {
6
+ const [form] = Form.useForm("testCase4");
7
+ const handleSetInitial = () => {
8
+ form == null ? void 0 : form.setFieldValue("profile", {
9
+ name: "John Doe",
10
+ city: "New York",
11
+ country: "USA"
12
+ }, { deepTrigger: true });
13
+ };
14
+ const handleRemoveFields = () => {
15
+ form == null ? void 0 : form.setFieldValue("profile", {
16
+ name: "John Doe"
17
+ // city and country removed!
18
+ }, { deepTrigger: true });
19
+ };
20
+ const handleRestoreFields = () => {
21
+ form == null ? void 0 : form.setFieldValue("profile", {
22
+ name: "Jane Doe",
23
+ city: "Los Angeles",
24
+ country: "USA"
25
+ }, { deepTrigger: true });
26
+ };
27
+ return _jsxs(Box, { sx: { p: 2 }, children: [_jsx(Typography.Title, { level: 4, children: "Test Case 4: Plain Object - Removed Fields" }), _jsx(Typography.Paragraph, { children: "Test edge case: khi object fields b\u1ECB x\xF3a, listener ph\u1EA3i \u0111\u01B0\u1EE3c trigger v\u1EDBi undefined" }), _jsxs(Form, { formName: "testCase4", children: [_jsx(Form.Item, { name: "profile.name", label: "Name", children: _jsx(Input, { placeholder: "Enter name" }) }), _jsx(Form.Item, { name: "profile.city", label: "City", children: _jsx(Input, { placeholder: "Enter city" }) }), _jsx(Form.Item, { name: "profile.country", label: "Country", children: _jsx(Input, { placeholder: "Enter country" }) }), _jsxs(Box, { sx: { mt: 2, display: "flex", gap: 2, flexDirection: "column" }, children: [_jsx(Button, { type: "primary", onClick: handleSetInitial, children: "1. Set Initial (All Fields)" }), _jsx(Button, { danger: true, onClick: handleRemoveFields, children: "2. Remove Fields (city, country)" }), _jsx(Button, { onClick: handleRestoreFields, children: "3. Restore Fields" })] }), _jsxs(Box, { sx: { mt: 2, p: 2, bgcolor: "#f0f0f0", borderRadius: 1 }, children: [_jsx(Typography.Text, { strong: true, children: "Expected Behavior:" }), _jsx(Typography.Paragraph, { children: 'Khi click "Remove Fields", city v\xE0 country listeners ph\u1EA3i nh\u1EADn undefined' })] })] })] });
28
+ }
29
+ var stdin_default = TestCase4_PlainObjectRemovedFields;
30
+ export {
31
+ stdin_default as default
32
+ };
@@ -0,0 +1,22 @@
1
+ type Props = {};
2
+ /**
3
+ * Test Case 5: Array Listener (FormList) with Removed Items
4
+ *
5
+ * Cấu trúc:
6
+ * - items (FormList)
7
+ * - items.0.name (string)
8
+ * - items.1.name (string)
9
+ * - items.2.name (string)
10
+ *
11
+ * Test:
12
+ * 1. Set initial: [{name: "A"}, {name: "B"}, {name: "C"}]
13
+ * 2. Set removed: [{name: "A"}] (items 1 và 2 bị xóa)
14
+ *
15
+ * Kỳ vọng:
16
+ * - onArrayChange được gọi với array mới
17
+ * - Trigger "items.0.name" với "A"
18
+ * - Trigger "items.1" với undefined (cleanup)
19
+ * - Trigger "items.2" với undefined (cleanup)
20
+ */
21
+ declare function TestCase5_FormListRemovedItems({}: Props): import("react/jsx-runtime").JSX.Element;
22
+ export default TestCase5_FormListRemovedItems;