react-form-manage 1.0.6-beta.0 → 1.0.6-beta.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 (50) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/dist/components/Form/FormCleanUp.js +46 -0
  3. package/dist/components/Form/FormItem.js +46 -0
  4. package/dist/components/Form/FormList.js +11 -0
  5. package/dist/components/Form/InputWrapper.js +7 -0
  6. package/dist/components/Input.d.ts +4 -5
  7. package/dist/components/Input.js +8 -0
  8. package/dist/constants/validation.js +33 -0
  9. package/dist/contexts/FormContext.js +2 -0
  10. package/dist/hooks/useFormItemControl.js +390 -0
  11. package/dist/hooks/useFormListControl.js +280 -0
  12. package/dist/index.d.ts +8 -185
  13. package/dist/index.js +9 -0
  14. package/dist/providers/Form.js +322 -0
  15. package/dist/stores/formStore.js +304 -0
  16. package/dist/types/index.d.ts +1 -0
  17. package/dist/types/index.js +1 -0
  18. package/dist/types/public.d.ts +51 -0
  19. package/dist/utils/obj.util.js +24 -0
  20. package/package.json +30 -45
  21. package/src/App.css +49 -0
  22. package/src/App.tsx +36 -0
  23. package/src/assets/react.svg +1 -0
  24. package/src/components/Form/FormCleanUp.tsx +57 -0
  25. package/src/components/Form/FormItem.tsx +60 -0
  26. package/src/components/Form/FormList.tsx +13 -0
  27. package/src/components/Form/InputWrapper.tsx +17 -0
  28. package/src/components/Input.jsx +13 -0
  29. package/src/components/Input.tsx +21 -0
  30. package/src/constants/validation.ts +63 -0
  31. package/src/contexts/FormContext.ts +3 -0
  32. package/src/hooks/useFormItemControl.ts +558 -0
  33. package/src/hooks/useFormListControl.ts +378 -0
  34. package/src/index.css +68 -0
  35. package/src/index.ts +30 -0
  36. package/src/main.tsx +10 -0
  37. package/src/providers/Form.tsx +429 -0
  38. package/src/stores/formStore.ts +477 -0
  39. package/src/types/index.ts +1 -0
  40. package/src/types/public.ts +50 -0
  41. package/src/utils/obj.util.ts +42 -0
  42. package/dist/App.d.ts +0 -2
  43. package/dist/index.cjs +0 -2
  44. package/dist/index.cjs.d.ts +0 -1
  45. package/dist/index.cjs.map +0 -1
  46. package/dist/index.esm.d.ts +0 -1
  47. package/dist/index.esm.js +0 -2
  48. package/dist/index.esm.js.map +0 -1
  49. package/src/types/components.d.ts +0 -135
  50. /package/dist/{main.d.ts → types/public.js} +0 -0
@@ -0,0 +1,477 @@
1
+ import { produce } from "immer";
2
+ import { cloneDeep, get, isNil, isNumber, last, set, unset } from "lodash";
3
+ import { v4 } from "uuid";
4
+ import { create } from "zustand";
5
+ import { getAllNoneObjStringPath } from "../utils/obj.util";
6
+
7
+ export interface FormInstance {
8
+ formName: string;
9
+ resetFields?: any;
10
+ submit?: any;
11
+ submitAsync?: any;
12
+ setFieldValue?: any;
13
+ setFieldValues?: any;
14
+ getFieldValue?: any;
15
+ getFieldValues?: any;
16
+ getFieldErrors?: any;
17
+ setFieldFocus?: any;
18
+ }
19
+
20
+ interface ListenerItem {
21
+ name?: string;
22
+ formName?: string;
23
+ isTouched?: boolean;
24
+ isDirty?: boolean;
25
+ formItemId?: string;
26
+ internalErrors?: any;
27
+ onChange?: any;
28
+ onReset?: any;
29
+ onFocus?: any;
30
+ emitFocus?: any;
31
+ }
32
+
33
+ interface CleanUpItem {
34
+ name?: string;
35
+ type?: string;
36
+ key: string;
37
+ itemKey?: string;
38
+ formName?: string;
39
+ }
40
+
41
+ interface FormStoreState {
42
+ forms: Record<string, any>;
43
+ initialValues: Record<string, any>;
44
+ formStates: Record<string, any>;
45
+ cacheData: Record<string, any>;
46
+ formInstances: FormInstance[];
47
+ submitHistory: Record<string, any[]>;
48
+ // methods (loose typed for incremental migration)
49
+ [key: string]: any;
50
+ }
51
+ export const useFormStore = create<FormStoreState>((storeSet: any, storeGet: any) => ({
52
+ forms: {},
53
+ initialValues: {},
54
+ formStates: {},
55
+ cacheData: {},
56
+ formInstances: [],
57
+ submitHistory: {},
58
+ setData(formName, name, value) {
59
+ return storeSet(
60
+ produce<any>((state: any) => {
61
+ const oldValues = state.forms;
62
+ set(oldValues, `${formName}.${name}`, value);
63
+ }),
64
+ );
65
+ },
66
+
67
+ getCacheData(formName) {
68
+ return get(storeGet(), `cacheData.${formName}`);
69
+ },
70
+
71
+ setCacheData(formName, name, value) {
72
+ return storeSet(
73
+ produce<any>((state: any) => {
74
+ const oldValues = state.cacheData;
75
+ set(oldValues, `${formName}.${name}`, value);
76
+ }),
77
+ );
78
+ },
79
+
80
+ clearCacheData(formName) {
81
+ return storeSet(
82
+ produce<any>((state: any) => {
83
+ const oldValues = state.cacheData;
84
+
85
+ if (formName) {
86
+ set(oldValues, formName, {});
87
+ } else {
88
+ set(oldValues, "", {});
89
+ }
90
+ }),
91
+ );
92
+ },
93
+
94
+ getFormItemValue(formName, name) {
95
+ return get(storeGet().forms?.[formName], name);
96
+ },
97
+
98
+ getFormValues(formName) {
99
+ return storeGet().forms?.[formName];
100
+ },
101
+
102
+ clearFormValues(formName) {
103
+ return storeSet(
104
+ produce<any>((state: any) => {
105
+ const oldValues = state.forms;
106
+
107
+ // console.log("Clear form values", formName);
108
+
109
+ unset(oldValues, formName);
110
+
111
+ // console.log(JSON.parse(JSON.stringify(oldValues)));
112
+ }),
113
+ );
114
+ },
115
+
116
+ clearFormInitialValues(formName) {
117
+ return storeSet(
118
+ produce<any>((state: any) => {
119
+ const oldValues = state.initialValues;
120
+
121
+ // console.log("Clear form initial values", formName);
122
+
123
+ unset(oldValues, formName);
124
+
125
+ // console.log(JSON.parse(JSON.stringify(oldValues)));
126
+ }),
127
+ );
128
+ },
129
+
130
+ clearObjKeyItem(formName, name) {
131
+ return storeSet(
132
+ produce<any>((state: any) => {
133
+ const oldValues = state.forms;
134
+
135
+ // console.log("Clear item value", formName, name);
136
+
137
+ unset(oldValues, `${formName}.${name}`);
138
+
139
+ // console.log(JSON.parse(JSON.stringify(oldValues)));
140
+ }),
141
+ );
142
+ },
143
+ clearArrItem(formName, name) {
144
+ return storeSet(
145
+ produce<any>((state: any) => {
146
+ const oldValues = state.forms;
147
+
148
+ console.log("Clear item array value", formName, name);
149
+
150
+ const arrPath = name.split(".").slice(0, -1).join(".");
151
+
152
+ const elPath = Number(name.split(".").slice(-1).join(""));
153
+
154
+ const getArrItem = get(oldValues, `${formName}.${arrPath}`);
155
+
156
+ if (isNumber(elPath)) {
157
+ getArrItem.splice(elPath, 1);
158
+ }
159
+
160
+ // console.log(JSON.parse(JSON.stringify(oldValues)));
161
+ }),
162
+ );
163
+ },
164
+
165
+ setFormState({ formName, isInitied, submitState }) {
166
+ return storeSet(
167
+ produce<any>((state: any) => {
168
+ const oldValues = state.formStates;
169
+ const getFormState = get(storeGet().formStates, formName);
170
+
171
+ if (isNil(getFormState)) {
172
+ set(oldValues, formName, { isInitied, submitState });
173
+ } else {
174
+ if (!isNil(isInitied)) {
175
+ set(oldValues, `${formName}.isInitied`, isInitied);
176
+ }
177
+
178
+ if (!isNil(submitState)) {
179
+ set(oldValues, `${formName}.submitState`, submitState);
180
+ }
181
+ }
182
+ }),
183
+ );
184
+ },
185
+
186
+ clearFormState(formName) {
187
+ return storeSet(
188
+ produce<any>((state: any) => {
189
+ const oldValues = state.formStates;
190
+
191
+ // console.log("Clear form state", formName);
192
+
193
+ unset(oldValues, formName);
194
+
195
+ // console.log(JSON.parse(JSON.stringify(oldValues)));
196
+ }),
197
+ );
198
+ },
199
+
200
+ getFormState(formName) {
201
+ return get(storeGet(), `formStates.${formName}`);
202
+ },
203
+
204
+ setFormInitData(formName, initValues) {
205
+ return storeSet(
206
+ produce<any>((state: any) => {
207
+ const oldValues = state.initialValues;
208
+ const listInitPath = getAllNoneObjStringPath(initValues);
209
+
210
+ // console.log({ listInitPath, initValues });
211
+
212
+ listInitPath.forEach((k) => {
213
+ if (get(initValues, k)) {
214
+ // console.log("init form data values: ", k, get(initValues, k));
215
+ set(oldValues, `${formName}.${k}`, get(initValues, k));
216
+ }
217
+ });
218
+ }),
219
+ );
220
+ },
221
+
222
+ getInitData(formName, name) {
223
+ return get(storeGet().initialValues, `${formName}.${name}`);
224
+ },
225
+
226
+ setInitData(formName, name, value) {
227
+ return storeSet(
228
+ produce<any>((state: any) => {
229
+ const oldValues = state.initialValues;
230
+ // console.log("Inner init: ", `${formName}.${name}`, value);
231
+ set(oldValues, `${formName}.${name}`, value);
232
+ }),
233
+ );
234
+ },
235
+
236
+ setFormInstance({
237
+ formName,
238
+ resetFields,
239
+ submit,
240
+ submitAsync,
241
+ setFieldValue,
242
+ setFieldValues,
243
+ getFieldValue,
244
+ getFieldValues,
245
+ getFieldErrors,
246
+ setFieldFocus,
247
+ }) {
248
+ return storeSet(
249
+ produce<any>((state: any) => {
250
+ const storeListeners = state.formInstances;
251
+ const findListenerIndex = storeListeners.findIndex(
252
+ (l) => l.formName === formName,
253
+ );
254
+ if (findListenerIndex > -1) {
255
+ if (!isNil(resetFields)) {
256
+ storeListeners[findListenerIndex].resetFields = resetFields;
257
+ }
258
+ if (!isNil(submit)) {
259
+ storeListeners[findListenerIndex].submit = submit;
260
+ }
261
+ if (!isNil(setFieldFocus)) {
262
+ storeListeners[findListenerIndex].setFieldFocus = setFieldFocus;
263
+ }
264
+ if (!isNil(submitAsync)) {
265
+ storeListeners[findListenerIndex].submitAsync = submitAsync;
266
+ }
267
+
268
+ if (!isNil(setFieldValue)) {
269
+ storeListeners[findListenerIndex].setFieldValue = setFieldValue;
270
+ }
271
+
272
+ if (!isNil(setFieldValues)) {
273
+ storeListeners[findListenerIndex].setFieldValues = setFieldValues;
274
+ }
275
+
276
+ if (!isNil(getFieldValue)) {
277
+ storeListeners[findListenerIndex].getFieldValue = getFieldValue;
278
+ }
279
+
280
+ if (!isNil(getFieldValues)) {
281
+ storeListeners[findListenerIndex].getFieldValues = getFieldValues;
282
+ }
283
+
284
+ if (!isNil(getFieldErrors)) {
285
+ storeListeners[findListenerIndex].getFieldErrors = getFieldErrors;
286
+ }
287
+
288
+ return;
289
+ }
290
+ storeListeners.push({
291
+ formName,
292
+ resetFields,
293
+ submit,
294
+ submitAsync,
295
+ setFieldValue,
296
+ setFieldValues,
297
+ getFieldValue,
298
+ getFieldValues,
299
+ getFieldErrors,
300
+ setFieldFocus,
301
+ });
302
+ }),
303
+ );
304
+ },
305
+ revokeFormInstance({ formName }) {
306
+ return storeSet(
307
+ produce<any>((state: any) => {
308
+ const instances = state.formInstances;
309
+
310
+ const findInstanceIndex = instances.findIndex(
311
+ (l) => l.formName == formName,
312
+ );
313
+
314
+ // console.log("Find item for revoke: ", findListenerIndex, formItemId);
315
+
316
+ if (findInstanceIndex > -1) {
317
+ // const listenersInfo = cloneDeep(instances[findInstanceIndex]);
318
+
319
+ instances.splice(findInstanceIndex, 1);
320
+
321
+ // onAfterRevoke(
322
+ // listenersInfo,
323
+ // instances.filter(
324
+ // (l) =>
325
+ // l.name === listenersInfo.name &&
326
+ // l.formName === listenersInfo.formName &&
327
+ // l.formItemId !== listenersInfo.formItemId
328
+ // )
329
+ // );
330
+ }
331
+ }),
332
+ );
333
+ },
334
+
335
+ getCurrentSubmit(formName) {
336
+ return last(get(storeGet().submitHistory, formName)) || null;
337
+ },
338
+ getSubmitHistory(formName) {
339
+ return get(storeGet().submitHistory, formName);
340
+ },
341
+ setSubmitHistory(formName, submitData) {
342
+ return storeSet(
343
+ produce<any>((state: any) => {
344
+ const oldValues = get(state.submitHistory, formName);
345
+ if (oldValues) {
346
+ oldValues.push(submitData);
347
+ oldValues.splice(0, oldValues.length - 3);
348
+ } else {
349
+ set(state.submitHistory, formName, [submitData]);
350
+ }
351
+ console.log("Submit history: ", formName);
352
+ }),
353
+ );
354
+ },
355
+ }));
356
+
357
+ export const useFormListeners = create<any>((storeSet: any, storeGet: any) => ({
358
+ listeners: [],
359
+ getListener(formItemId) {
360
+ return storeGet().listeners.find((l) => l.formItemId === formItemId);
361
+ },
362
+ getListeners() {
363
+ return storeGet().listeners;
364
+ },
365
+ setListener({
366
+ formName,
367
+ name,
368
+ onChange,
369
+ onReset,
370
+ isTouched,
371
+ isDirty,
372
+ formItemId,
373
+ internalErrors,
374
+ onFocus,
375
+ emitFocus,
376
+ }) {
377
+ return storeSet(
378
+ produce<any>((state: any) => {
379
+ const storeListeners = state.listeners;
380
+ const findListenerIndex = state.listeners.findIndex(
381
+ (l: any) => l.formItemId === formItemId,
382
+ );
383
+
384
+ if (findListenerIndex > -1) {
385
+ if (!isNil(formName)) {
386
+ storeListeners[findListenerIndex].formName = formName;
387
+ }
388
+ if (!isNil(name)) {
389
+ storeListeners[findListenerIndex].name = name;
390
+ }
391
+ if (!isNil(onChange)) {
392
+ storeListeners[findListenerIndex].onChange = onChange;
393
+ }
394
+ if (!isNil(onReset)) {
395
+ storeListeners[findListenerIndex].onReset = onReset;
396
+ }
397
+ if (!isNil(isTouched)) {
398
+ storeListeners[findListenerIndex].isTouched = isTouched;
399
+ }
400
+ if (!isNil(isDirty)) {
401
+ storeListeners[findListenerIndex].isDirty = isDirty;
402
+ }
403
+ if (!isNil(internalErrors)) {
404
+ storeListeners[findListenerIndex].internalErrors = internalErrors;
405
+ }
406
+ if (!isNil(onFocus)) {
407
+ storeListeners[findListenerIndex].onFocus = onFocus;
408
+ }
409
+ if (!isNil(emitFocus)) {
410
+ storeListeners[findListenerIndex].emitFocus = emitFocus;
411
+ }
412
+
413
+ return;
414
+ }
415
+ storeListeners.push({
416
+ name,
417
+ formName,
418
+ isTouched,
419
+ isDirty,
420
+ formItemId,
421
+ internalErrors,
422
+ onChange,
423
+ onReset,
424
+ });
425
+ }),
426
+ );
427
+ },
428
+ revokeListener(formItemId, onAfterRevoke) {
429
+ return storeSet(
430
+ produce<any>((state: any) => {
431
+ const storeListeners = state.listeners;
432
+
433
+ const findListenerIndex = storeListeners.findIndex(
434
+ (l: any) => l.formItemId == formItemId,
435
+ );
436
+
437
+ // console.log("Find item for revoke: ", findListenerIndex, formItemId);
438
+
439
+ if (findListenerIndex > -1) {
440
+ const listenersInfo = cloneDeep(storeListeners[findListenerIndex]);
441
+
442
+ storeListeners.splice(findListenerIndex, 1);
443
+
444
+ onAfterRevoke(
445
+ listenersInfo,
446
+ storeListeners.filter(
447
+ (l: any) =>
448
+ l.name === listenersInfo.name &&
449
+ l.formName === listenersInfo.formName &&
450
+ l.formItemId !== listenersInfo.formItemId,
451
+ ),
452
+ );
453
+ }
454
+ }),
455
+ );
456
+ },
457
+ }));
458
+
459
+ export const useFormCleanUp = create<any>((storeSet: any) => ({
460
+ cleanUpStack: [],
461
+ setCleanUpStack({ name, type, itemKey, formName }) {
462
+ return storeSet(
463
+ produce<any>((state: any) => {
464
+ const oldValues = state.cleanUpStack;
465
+ const cleanUpKey = v4();
466
+ oldValues.push({ name, type, key: cleanUpKey, itemKey, formName });
467
+ }),
468
+ );
469
+ },
470
+ clearCleanUpStack() {
471
+ return storeSet(
472
+ produce<any>((state: any) => {
473
+ state.cleanUpStack = [];
474
+ }),
475
+ );
476
+ },
477
+ }));
@@ -0,0 +1 @@
1
+ export * from './public';
@@ -0,0 +1,50 @@
1
+ export type FormValues<T = any> = T;
2
+
3
+ export interface PublicFormInstance<T = any> {
4
+ formName: string;
5
+ resetFields?: (values?: Partial<T>) => void;
6
+ submit?: (values?: T) => void;
7
+ submitAsync?: (values?: T) => Promise<any>;
8
+ setFieldValue?: (name: keyof T & string, value: any) => void;
9
+ setFieldValues?: (values: Partial<T>) => void;
10
+ getFieldValue?: (name: keyof T & string) => any;
11
+ getFieldValues?: () => T;
12
+ getFieldErrors?: () => Record<string, any>;
13
+ }
14
+
15
+ export interface UseFormItemProps<T = any> {
16
+ formName?: string;
17
+ form?: PublicFormInstance<T>;
18
+ name?: keyof T & string;
19
+ initialValue?: any;
20
+ formItemId?: string;
21
+ rules?: any[];
22
+ }
23
+
24
+ export interface UseFormItemReturn<T = any> {
25
+ value: T | undefined;
26
+ onChange: (value: T, options?: any) => void;
27
+ state: any;
28
+ errors: any;
29
+ onFocus: () => void;
30
+ isDirty?: boolean;
31
+ }
32
+
33
+ export interface UseFormListProps<T = any> {
34
+ name?: string;
35
+ form?: PublicFormInstance<T>;
36
+ initialValues?: T[];
37
+ formName?: string;
38
+ }
39
+
40
+ export interface ListField {
41
+ name: string;
42
+ key: string;
43
+ }
44
+
45
+ export interface UseFormListReturn {
46
+ listFields: ListField[];
47
+ move: (opts: { from?: number; fromKey?: string; to: number }) => void;
48
+ add: (index: number) => void;
49
+ remove: (opts: { index?: number; key?: string }) => void;
50
+ }
@@ -0,0 +1,42 @@
1
+ import { filter, isNil, join } from "lodash";
2
+
3
+ export function getAllNoneObjStringPath(value: any, prevPath: string = "") {
4
+ if (typeof value === "object") {
5
+ return Object.keys(value).reduce((prev, cur) => {
6
+ return [
7
+ ...prev,
8
+
9
+ ...getAllNoneObjStringPath(
10
+ value[cur],
11
+ join(
12
+ filter([prevPath, cur], (v) => !isNil(v) && v !== ""),
13
+ "."
14
+ )
15
+ ),
16
+ ];
17
+ }, []);
18
+ }
19
+ return [prevPath];
20
+ }
21
+
22
+ export function getAllStringPath(value: any, prevPath: string = "") {
23
+ if (typeof value === "object") {
24
+ return Object.keys(value).reduce((prev, cur) => {
25
+ return [
26
+ ...prev,
27
+ join(
28
+ filter([prevPath, cur], (v) => !isNil(v) && v !== ""),
29
+ "."
30
+ ),
31
+ ...getAllStringPath(
32
+ value[cur],
33
+ join(
34
+ filter([prevPath, cur], (v) => !isNil(v) && v !== ""),
35
+ "."
36
+ )
37
+ ),
38
+ ];
39
+ }, []);
40
+ }
41
+ return [];
42
+ }
package/dist/App.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export default App;
2
- declare function App(): import("react/jsx-runtime").JSX.Element;
package/dist/index.cjs DELETED
@@ -1,2 +0,0 @@
1
-
2
- //# sourceMappingURL=index.cjs.map
@@ -1 +0,0 @@
1
- export * from './index';
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- export * from './index';
package/dist/index.esm.js DELETED
@@ -1,2 +0,0 @@
1
-
2
- //# sourceMappingURL=index.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}