@firecms/formex 3.0.0-beta.10 → 3.0.0-beta.11
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/dist/index.es.js +175 -49
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +176 -51
- package/dist/index.umd.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/useCreateFormex.d.ts +2 -1
- package/dist/utils.d.ts +1 -0
- package/package.json +9 -7
- package/src/types.ts +2 -0
- package/src/useCreateFormex.tsx +8 -5
- package/src/utils.ts +1 -1
package/dist/index.es.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import { c } from "react-compiler-runtime";
|
|
1
2
|
import * as React from "react";
|
|
2
3
|
import React__default, { useContext, useState, useEffect } from "react";
|
|
3
4
|
import equal from "react-fast-compare";
|
|
4
5
|
const FormexContext = React__default.createContext({});
|
|
5
|
-
const useFormex = () =>
|
|
6
|
+
const useFormex = () => {
|
|
7
|
+
return useContext(FormexContext);
|
|
8
|
+
};
|
|
6
9
|
const Formex = FormexContext.Provider;
|
|
7
10
|
const isEmptyArray = (value) => Array.isArray(value) && value.length === 0;
|
|
8
11
|
const isFunction = (obj) => typeof obj === "function";
|
|
@@ -81,7 +84,9 @@ function clone(value) {
|
|
|
81
84
|
if (Array.isArray(value)) {
|
|
82
85
|
return [...value];
|
|
83
86
|
} else if (typeof value === "object" && value !== null) {
|
|
84
|
-
return {
|
|
87
|
+
return {
|
|
88
|
+
...value
|
|
89
|
+
};
|
|
85
90
|
} else {
|
|
86
91
|
return value;
|
|
87
92
|
}
|
|
@@ -90,31 +95,145 @@ function toPath(value) {
|
|
|
90
95
|
if (Array.isArray(value)) return value;
|
|
91
96
|
return value.replace(/\[(\d+)]/g, ".$1").replace(/^\./, "").replace(/\.$/, "").split(".");
|
|
92
97
|
}
|
|
93
|
-
function Field({
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
98
|
+
function Field(t0) {
|
|
99
|
+
const $ = c(37);
|
|
100
|
+
let children;
|
|
101
|
+
let className;
|
|
102
|
+
let is;
|
|
103
|
+
let name;
|
|
104
|
+
let props;
|
|
105
|
+
if ($[0] !== t0) {
|
|
106
|
+
const {
|
|
107
|
+
validate,
|
|
108
|
+
name: t12,
|
|
109
|
+
children: t22,
|
|
110
|
+
as: t3,
|
|
111
|
+
className: t4,
|
|
112
|
+
...t5
|
|
113
|
+
} = t0;
|
|
114
|
+
name = t12;
|
|
115
|
+
children = t22;
|
|
116
|
+
is = t3;
|
|
117
|
+
className = t4;
|
|
118
|
+
props = t5;
|
|
119
|
+
$[0] = t0;
|
|
120
|
+
$[1] = children;
|
|
121
|
+
$[2] = className;
|
|
122
|
+
$[3] = is;
|
|
123
|
+
$[4] = name;
|
|
124
|
+
$[5] = props;
|
|
125
|
+
} else {
|
|
126
|
+
children = $[1];
|
|
127
|
+
className = $[2];
|
|
128
|
+
is = $[3];
|
|
129
|
+
name = $[4];
|
|
130
|
+
props = $[5];
|
|
131
|
+
}
|
|
103
132
|
const formex = useFormex();
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
133
|
+
let field;
|
|
134
|
+
let t1;
|
|
135
|
+
if ($[6] !== children || $[7] !== formex || $[8] !== name || $[9] !== props) {
|
|
136
|
+
t1 = Symbol.for("react.early_return_sentinel");
|
|
137
|
+
bb0: {
|
|
138
|
+
field = getFieldProps({
|
|
139
|
+
name,
|
|
140
|
+
...props
|
|
141
|
+
}, formex);
|
|
142
|
+
if (isFunction(children)) {
|
|
143
|
+
t1 = children({
|
|
144
|
+
field,
|
|
145
|
+
form: formex
|
|
146
|
+
});
|
|
147
|
+
break bb0;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
$[6] = children;
|
|
151
|
+
$[7] = formex;
|
|
152
|
+
$[8] = name;
|
|
153
|
+
$[9] = props;
|
|
154
|
+
$[10] = field;
|
|
155
|
+
$[11] = t1;
|
|
156
|
+
} else {
|
|
157
|
+
field = $[10];
|
|
158
|
+
t1 = $[11];
|
|
159
|
+
}
|
|
160
|
+
if (t1 !== Symbol.for("react.early_return_sentinel")) {
|
|
161
|
+
return t1;
|
|
107
162
|
}
|
|
108
163
|
const asElement = is || "input";
|
|
109
164
|
if (typeof asElement === "string") {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
{
|
|
114
|
-
|
|
115
|
-
|
|
165
|
+
let innerRef;
|
|
166
|
+
let rest;
|
|
167
|
+
if ($[12] !== props) {
|
|
168
|
+
({
|
|
169
|
+
innerRef,
|
|
170
|
+
...rest
|
|
171
|
+
} = props);
|
|
172
|
+
$[12] = props;
|
|
173
|
+
$[13] = innerRef;
|
|
174
|
+
$[14] = rest;
|
|
175
|
+
} else {
|
|
176
|
+
innerRef = $[13];
|
|
177
|
+
rest = $[14];
|
|
178
|
+
}
|
|
179
|
+
let t22;
|
|
180
|
+
if ($[15] !== asElement || $[16] !== children || $[17] !== className || $[18] !== field || $[19] !== innerRef || $[20] !== rest) {
|
|
181
|
+
let t3;
|
|
182
|
+
if ($[22] !== className || $[23] !== field || $[24] !== innerRef || $[25] !== rest) {
|
|
183
|
+
t3 = {
|
|
184
|
+
ref: innerRef,
|
|
185
|
+
...field,
|
|
186
|
+
...rest,
|
|
187
|
+
className
|
|
188
|
+
};
|
|
189
|
+
$[22] = className;
|
|
190
|
+
$[23] = field;
|
|
191
|
+
$[24] = innerRef;
|
|
192
|
+
$[25] = rest;
|
|
193
|
+
$[26] = t3;
|
|
194
|
+
} else {
|
|
195
|
+
t3 = $[26];
|
|
196
|
+
}
|
|
197
|
+
t22 = React.createElement(asElement, t3, children);
|
|
198
|
+
$[15] = asElement;
|
|
199
|
+
$[16] = children;
|
|
200
|
+
$[17] = className;
|
|
201
|
+
$[18] = field;
|
|
202
|
+
$[19] = innerRef;
|
|
203
|
+
$[20] = rest;
|
|
204
|
+
$[21] = t22;
|
|
205
|
+
} else {
|
|
206
|
+
t22 = $[21];
|
|
207
|
+
}
|
|
208
|
+
return t22;
|
|
116
209
|
}
|
|
117
|
-
|
|
210
|
+
let t2;
|
|
211
|
+
if ($[27] !== asElement || $[28] !== children || $[29] !== className || $[30] !== field || $[31] !== props) {
|
|
212
|
+
let t3;
|
|
213
|
+
if ($[33] !== className || $[34] !== field || $[35] !== props) {
|
|
214
|
+
t3 = {
|
|
215
|
+
...field,
|
|
216
|
+
...props,
|
|
217
|
+
className
|
|
218
|
+
};
|
|
219
|
+
$[33] = className;
|
|
220
|
+
$[34] = field;
|
|
221
|
+
$[35] = props;
|
|
222
|
+
$[36] = t3;
|
|
223
|
+
} else {
|
|
224
|
+
t3 = $[36];
|
|
225
|
+
}
|
|
226
|
+
t2 = React.createElement(asElement, t3, children);
|
|
227
|
+
$[27] = asElement;
|
|
228
|
+
$[28] = children;
|
|
229
|
+
$[29] = className;
|
|
230
|
+
$[30] = field;
|
|
231
|
+
$[31] = props;
|
|
232
|
+
$[32] = t2;
|
|
233
|
+
} else {
|
|
234
|
+
t2 = $[32];
|
|
235
|
+
}
|
|
236
|
+
return t2;
|
|
118
237
|
}
|
|
119
238
|
const getFieldProps = (nameOrOptions, formex) => {
|
|
120
239
|
const isAnObject = isObject(nameOrOptions);
|
|
@@ -157,10 +276,12 @@ function useCreateFormex({
|
|
|
157
276
|
validation,
|
|
158
277
|
validateOnChange = false,
|
|
159
278
|
onSubmit,
|
|
160
|
-
validateOnInitialRender = false
|
|
279
|
+
validateOnInitialRender = false,
|
|
280
|
+
debugId
|
|
161
281
|
}) {
|
|
162
282
|
const initialValuesRef = React__default.useRef(initialValues);
|
|
163
283
|
const valuesRef = React__default.useRef(initialValues);
|
|
284
|
+
const debugIdRef = React__default.useRef(debugId);
|
|
164
285
|
const [values, setValuesInner] = useState(initialValues);
|
|
165
286
|
const [touchedState, setTouchedState] = useState({});
|
|
166
287
|
const [errors, setErrors] = useState(initialErrors ?? {});
|
|
@@ -181,16 +302,15 @@ function useCreateFormex({
|
|
|
181
302
|
};
|
|
182
303
|
const validate = async () => {
|
|
183
304
|
setIsValidating(true);
|
|
184
|
-
const
|
|
185
|
-
const validationErrors = await validation?.(values2);
|
|
305
|
+
const validationErrors = await validation?.(valuesRef.current);
|
|
186
306
|
setErrors(validationErrors ?? {});
|
|
187
307
|
setIsValidating(false);
|
|
188
308
|
return validationErrors;
|
|
189
309
|
};
|
|
190
310
|
const setFieldValue = (key, value, shouldValidate) => {
|
|
191
|
-
const
|
|
192
|
-
valuesRef.current =
|
|
193
|
-
setValuesInner(
|
|
311
|
+
const newValues_0 = setIn(valuesRef.current, key, value);
|
|
312
|
+
valuesRef.current = newValues_0;
|
|
313
|
+
setValuesInner(newValues_0);
|
|
194
314
|
if (!equal(getIn(initialValuesRef.current, key), value)) {
|
|
195
315
|
setDirty(true);
|
|
196
316
|
}
|
|
@@ -198,50 +318,54 @@ function useCreateFormex({
|
|
|
198
318
|
validate();
|
|
199
319
|
}
|
|
200
320
|
};
|
|
201
|
-
const setFieldError = (
|
|
202
|
-
const newErrors = {
|
|
321
|
+
const setFieldError = (key_0, error) => {
|
|
322
|
+
const newErrors = {
|
|
323
|
+
...errors
|
|
324
|
+
};
|
|
203
325
|
if (error) {
|
|
204
|
-
newErrors[
|
|
326
|
+
newErrors[key_0] = error;
|
|
205
327
|
} else {
|
|
206
|
-
delete newErrors[
|
|
328
|
+
delete newErrors[key_0];
|
|
207
329
|
}
|
|
208
330
|
setErrors(newErrors);
|
|
209
331
|
};
|
|
210
|
-
const setFieldTouched = (
|
|
211
|
-
const newTouched = {
|
|
212
|
-
|
|
332
|
+
const setFieldTouched = (key_1, touched, shouldValidate_0) => {
|
|
333
|
+
const newTouched = {
|
|
334
|
+
...touchedState
|
|
335
|
+
};
|
|
336
|
+
newTouched[key_1] = touched;
|
|
213
337
|
setTouchedState(newTouched);
|
|
214
|
-
if (
|
|
338
|
+
if (shouldValidate_0) {
|
|
215
339
|
validate();
|
|
216
340
|
}
|
|
217
341
|
};
|
|
218
342
|
const handleChange = (event) => {
|
|
219
343
|
const target = event.target;
|
|
220
|
-
let
|
|
344
|
+
let value_0;
|
|
221
345
|
if (target.type === "checkbox") {
|
|
222
|
-
|
|
346
|
+
value_0 = target.checked;
|
|
223
347
|
} else if (target.type === "number") {
|
|
224
|
-
|
|
348
|
+
value_0 = target.valueAsNumber;
|
|
225
349
|
} else {
|
|
226
|
-
|
|
350
|
+
value_0 = target.value;
|
|
227
351
|
}
|
|
228
352
|
const name = target.name;
|
|
229
|
-
setFieldValue(name,
|
|
353
|
+
setFieldValue(name, value_0, validateOnChange);
|
|
230
354
|
setFieldTouched(name, true);
|
|
231
355
|
};
|
|
232
|
-
const handleBlur = (
|
|
233
|
-
const
|
|
234
|
-
const
|
|
235
|
-
setFieldTouched(
|
|
356
|
+
const handleBlur = (event_0) => {
|
|
357
|
+
const target_0 = event_0.target;
|
|
358
|
+
const name_0 = target_0.name;
|
|
359
|
+
setFieldTouched(name_0, true);
|
|
236
360
|
};
|
|
237
361
|
const submit = async (e) => {
|
|
238
362
|
e?.preventDefault();
|
|
239
363
|
e?.stopPropagation();
|
|
240
364
|
setIsSubmitting(true);
|
|
241
365
|
setSubmitCount(submitCount + 1);
|
|
242
|
-
const
|
|
243
|
-
if (
|
|
244
|
-
setErrors(
|
|
366
|
+
const validationErrors_0 = await validation?.(valuesRef.current);
|
|
367
|
+
if (validationErrors_0 && Object.keys(validationErrors_0).length > 0) {
|
|
368
|
+
setErrors(validationErrors_0);
|
|
245
369
|
} else {
|
|
246
370
|
setErrors({});
|
|
247
371
|
await onSubmit?.(valuesRef.current, controllerRef.current);
|
|
@@ -286,7 +410,8 @@ function useCreateFormex({
|
|
|
286
410
|
validate,
|
|
287
411
|
isValidating,
|
|
288
412
|
resetForm,
|
|
289
|
-
version
|
|
413
|
+
version,
|
|
414
|
+
debugId: debugIdRef.current
|
|
290
415
|
};
|
|
291
416
|
const controllerRef = React__default.useRef(controller);
|
|
292
417
|
controllerRef.current = controller;
|
|
@@ -295,6 +420,7 @@ function useCreateFormex({
|
|
|
295
420
|
export {
|
|
296
421
|
Field,
|
|
297
422
|
Formex,
|
|
423
|
+
clone,
|
|
298
424
|
getActiveElement,
|
|
299
425
|
getIn,
|
|
300
426
|
isEmptyArray,
|
package/dist/index.es.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.es.js","sources":["../src/Formex.tsx","../src/utils.ts","../src/Field.tsx","../src/useCreateFormex.tsx"],"sourcesContent":["import React, { useContext } from \"react\";\nimport { FormexController } from \"./types\";\n\nconst FormexContext = React.createContext<FormexController<any>>({} as any);\n\nexport const useFormex = <T extends object>() => useContext<FormexController<T>>(FormexContext);\n\nexport const Formex = FormexContext.Provider;\n","import * as React from \"react\";\n\n/** @private is the value an empty array? */\nexport const isEmptyArray = (value?: any) =>\n Array.isArray(value) && value.length === 0;\n\n/** @private is the given object a Function? */\nexport const isFunction = (obj: any): obj is Function =>\n typeof obj === \"function\";\n\n/** @private is the given object an Object? */\nexport const isObject = (obj: any): obj is Object =>\n obj !== null && typeof obj === \"object\";\n\n/** @private is the given object an integer? */\nexport const isInteger = (obj: any): boolean =>\n String(Math.floor(Number(obj))) === obj;\n\n/** @private is the given object a string? */\nexport const isString = (obj: any): obj is string =>\n Object.prototype.toString.call(obj) === \"[object String]\";\n\n/** @private is the given object a NaN? */\n// eslint-disable-next-line no-self-compare\nexport const isNaN = (obj: any): boolean => obj !== obj;\n\n/** @private Does a React component have exactly 0 children? */\nexport const isEmptyChildren = (children: any): boolean =>\n React.Children.count(children) === 0;\n\n/** @private is the given object/value a promise? */\nexport const isPromise = (value: any): value is PromiseLike<any> =>\n isObject(value) && isFunction(value.then);\n\n/** @private is the given object/value a type of synthetic event? */\nexport const isInputEvent = (value: any): value is React.SyntheticEvent<any> =>\n value && isObject(value) && isObject(value.target);\n\n/**\n * Same as document.activeElement but wraps in a try-catch block. In IE it is\n * not safe to call document.activeElement if there is nothing focused.\n *\n * The activeElement will be null only if the document or document body is not\n * yet defined.\n *\n * @param {?Document} doc Defaults to current document.\n * @return {Element | null}\n * @see https://github.com/facebook/fbjs/blob/master/packages/fbjs/src/core/dom/getActiveElement.js\n */\nexport function getActiveElement(doc?: Document): Element | null {\n doc = doc || (typeof document !== \"undefined\" ? document : undefined);\n if (typeof doc === \"undefined\") {\n return null;\n }\n try {\n return doc.activeElement || doc.body;\n } catch (e) {\n return doc.body;\n }\n}\n\n/**\n * Deeply get a value from an object via its path.\n */\nexport function getIn(\n obj: any,\n key: string | string[],\n def?: any,\n p = 0\n) {\n const path = toPath(key);\n while (obj && p < path.length) {\n obj = obj[path[p++]];\n }\n\n // check if path is not in the end\n if (p !== path.length && !obj) {\n return def;\n }\n\n return obj === undefined ? def : obj;\n}\n\nexport function setIn(obj: any, path: string, value: any): any {\n const res: any = clone(obj); // this keeps inheritance when obj is a class\n let resVal: any = res;\n let i = 0;\n const pathArray = toPath(path);\n\n for (; i < pathArray.length - 1; i++) {\n const currentPath: string = pathArray[i];\n const currentObj: any = getIn(obj, pathArray.slice(0, i + 1));\n\n if (currentObj && (isObject(currentObj) || Array.isArray(currentObj))) {\n resVal = resVal[currentPath] = clone(currentObj);\n } else {\n const nextPath: string = pathArray[i + 1];\n resVal = resVal[currentPath] =\n isInteger(nextPath) && Number(nextPath) >= 0 ? [] : {};\n }\n }\n\n // Return original object if new value is the same as current\n if ((i === 0 ? obj : resVal)[pathArray[i]] === value) {\n return obj;\n }\n\n if (value === undefined) {\n delete resVal[pathArray[i]];\n } else {\n resVal[pathArray[i]] = value;\n }\n\n // If the path array has a single element, the loop did not run.\n // Deleting on `resVal` had no effect in this scenario, so we delete on the result instead.\n if (i === 0 && value === undefined) {\n delete res[pathArray[i]];\n }\n\n return res;\n}\n\n/**\n * Recursively a set the same value for all keys and arrays nested object, cloning\n * @param object\n * @param value\n * @param visited\n * @param response\n */\nexport function setNestedObjectValues<T>(\n object: any,\n value: any,\n visited: any = new WeakMap(),\n response: any = {}\n): T {\n for (const k of Object.keys(object)) {\n const val = object[k];\n if (isObject(val)) {\n if (!visited.get(val)) {\n visited.set(val, true);\n // In order to keep array values consistent for both dot path and\n // bracket syntax, we need to check if this is an array so that\n // this will output { friends: [true] } and not { friends: { \"0\": true } }\n response[k] = Array.isArray(val) ? [] : {};\n setNestedObjectValues(val, value, visited, response[k]);\n }\n } else {\n response[k] = value;\n }\n }\n\n return response;\n}\n\nfunction clone(value: any) {\n if (Array.isArray(value)) {\n return [...value];\n } else if (typeof value === \"object\" && value !== null) {\n return { ...value };\n } else {\n return value; // This is for primitive types which do not need cloning.\n }\n}\n\nfunction toPath(value: string | string[]) {\n if (Array.isArray(value)) return value; // Already in path array form.\n // Replace brackets with dots, remove leading/trailing dots, then split by dot.\n return value.replace(/\\[(\\d+)]/g, \".$1\").replace(/^\\./, \"\").replace(/\\.$/, \"\").split(\".\");\n}\n","import * as React from \"react\";\nimport { useFormex } from \"./Formex\";\nimport { getIn, isFunction, isObject } from \"./utils\";\nimport { FormexController } from \"./types\";\n\nexport interface FieldInputProps<Value> {\n /** Value of the field */\n value: Value;\n /** Name of the field */\n name: string;\n /** Multiple select? */\n multiple?: boolean;\n /** Is the field checked? */\n checked?: boolean;\n /** Change event handler */\n onChange: (event: React.SyntheticEvent) => void,\n /** Blur event handler */\n onBlur: (event: React.FocusEvent) => void,\n}\n\nexport interface FormexFieldProps<Value = any, FormValues extends object = any> {\n field: FieldInputProps<Value>;\n form: FormexController<FormValues>;\n}\n\nexport interface FieldConfig<Value, C extends React.ElementType | undefined = undefined> {\n\n /**\n * Component to render. Can either be a string e.g. 'select', 'input', or 'textarea', or a component.\n */\n as?:\n | C\n | string\n | React.ForwardRefExoticComponent<any>;\n\n /**\n * Children render function <Field name>{props => ...}</Field>)\n */\n children?: ((props: FormexFieldProps<Value>) => React.ReactNode) | React.ReactNode;\n\n /**\n * Validate a single field value independently\n */\n // validate?: FieldValidator;\n\n /**\n * Used for 'select' and related input types.\n */\n multiple?: boolean;\n\n /**\n * Field name\n */\n name: string;\n\n /** HTML input type */\n type?: string;\n\n /** Field value */\n value?: any;\n\n /** Inner ref */\n innerRef?: (instance: any) => void;\n\n}\n\nexport type FieldProps<T, C extends React.ElementType | undefined> = {\n as?: C;\n} & (C extends React.ElementType ? (React.ComponentProps<C> & FieldConfig<T, C>) : FieldConfig<T, C>);\n\nexport function Field<T, C extends React.ElementType | undefined = undefined>({\n validate,\n name,\n children,\n as: is, // `as` is reserved in typescript lol\n // component,\n className,\n ...props\n }: FieldProps<T, C>) {\n const formex = useFormex();\n\n const field = getFieldProps({ name, ...props }, formex);\n\n if (isFunction(children)) {\n return children({ field, form: formex });\n }\n\n // if (component) {\n // if (typeof component === \"string\") {\n // const { innerRef, ...rest } = props;\n // return React.createElement(\n // component,\n // { ref: innerRef, ...field, ...rest, className },\n // children\n // );\n // }\n // return React.createElement(\n // component,\n // { field, form: formex, ...props, className },\n // children\n // );\n // }\n\n // default to input here so we can check for both `as` and `children` above\n const asElement = is || \"input\";\n\n if (typeof asElement === \"string\") {\n const { innerRef, ...rest } = props;\n return React.createElement(\n asElement,\n { ref: innerRef, ...field, ...rest, className },\n children\n );\n }\n\n return React.createElement(asElement, { ...field, ...props, className }, children);\n}\n\nconst getFieldProps = (nameOrOptions: string | FieldConfig<any>, formex: FormexController<any>): FieldInputProps<any> => {\n const isAnObject = isObject(nameOrOptions);\n const name = isAnObject\n ? (nameOrOptions as FieldConfig<any>).name\n : nameOrOptions;\n const valueState = getIn(formex.values, name);\n\n const field: FieldInputProps<any> = {\n name,\n value: valueState,\n onChange: formex.handleChange,\n onBlur: formex.handleBlur,\n };\n if (isAnObject) {\n const {\n type,\n value: valueProp, // value is special for checkboxes\n as: is,\n multiple,\n } = nameOrOptions as FieldConfig<any>;\n\n if (type === \"checkbox\") {\n if (valueProp === undefined) {\n field.checked = !!valueState;\n } else {\n field.checked = !!(\n Array.isArray(valueState) && ~valueState.indexOf(valueProp)\n );\n field.value = valueProp;\n }\n } else if (type === \"radio\") {\n field.checked = valueState === valueProp;\n field.value = valueProp;\n } else if (is === \"select\" && multiple) {\n field.value = field.value || [];\n field.multiple = true;\n }\n }\n return field;\n};\n","import React, { FormEvent, useEffect, useState } from \"react\";\nimport { getIn, setIn } from \"./utils\";\nimport equal from \"react-fast-compare\"\n\nimport { FormexController, FormexResetProps } from \"./types\";\n\nexport function useCreateFormex<T extends object>({\n initialValues,\n initialErrors,\n validation,\n validateOnChange = false,\n onSubmit,\n validateOnInitialRender = false\n }: {\n initialValues: T,\n initialErrors?: Record<string, string>,\n validateOnChange?: boolean,\n validateOnInitialRender?: boolean,\n validation?: (values: T) => Record<string, string> | Promise<Record<string, string>> | undefined | void,\n onSubmit?: (values: T, controller: FormexController<T>) => void | Promise<void>\n}): FormexController<T> {\n\n const initialValuesRef = React.useRef<T>(initialValues);\n const valuesRef = React.useRef<T>(initialValues);\n\n const [values, setValuesInner] = useState<T>(initialValues);\n const [touchedState, setTouchedState] = useState<Record<string, boolean>>({});\n const [errors, setErrors] = useState<Record<string, string>>(initialErrors ?? {});\n const [dirty, setDirty] = useState(false);\n const [submitCount, setSubmitCount] = useState(0);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [isValidating, setIsValidating] = useState(false);\n const [version, setVersion] = useState(0);\n\n useEffect(() => {\n if (validateOnInitialRender) {\n validate();\n }\n }, []);\n\n const setValues = (newValues: T) => {\n valuesRef.current = newValues;\n setValuesInner(newValues);\n setDirty(equal(initialValuesRef.current, newValues));\n }\n\n const validate = async () => {\n setIsValidating(true);\n const values = valuesRef.current;\n const validationErrors = await validation?.(values);\n setErrors(validationErrors ?? {});\n setIsValidating(false);\n return validationErrors;\n }\n\n const setFieldValue = (key: string, value: any, shouldValidate?: boolean) => {\n const newValues = setIn(valuesRef.current, key, value);\n valuesRef.current = newValues;\n setValuesInner(newValues);\n if (!equal(getIn(initialValuesRef.current, key), value)) {\n setDirty(true);\n }\n if (shouldValidate) {\n validate();\n }\n }\n\n const setFieldError = (key: string, error: string | undefined) => {\n const newErrors = { ...errors };\n if (error) {\n newErrors[key] = error;\n } else {\n delete newErrors[key];\n }\n setErrors(newErrors);\n }\n\n const setFieldTouched = (key: string, touched: boolean, shouldValidate?: boolean | undefined) => {\n const newTouched = { ...touchedState };\n newTouched[key] = touched;\n setTouchedState(newTouched);\n if (shouldValidate) {\n validate();\n }\n }\n\n const handleChange = (event: React.SyntheticEvent) => {\n const target = event.target as HTMLInputElement;\n let value;\n if (target.type === \"checkbox\") {\n value = target.checked;\n } else if (target.type === \"number\") {\n value = target.valueAsNumber;\n } else {\n value = target.value;\n }\n const name = target.name;\n setFieldValue(name, value, validateOnChange);\n setFieldTouched(name, true);\n }\n\n const handleBlur = (event: React.FocusEvent) => {\n const target = event.target as HTMLInputElement;\n const name = target.name;\n setFieldTouched(name, true);\n }\n\n const submit = async (e?: FormEvent<HTMLFormElement>) => {\n e?.preventDefault();\n e?.stopPropagation();\n setIsSubmitting(true);\n setSubmitCount(submitCount + 1);\n const validationErrors = await validation?.(valuesRef.current);\n if (validationErrors && Object.keys(validationErrors).length > 0) {\n setErrors(validationErrors);\n } else {\n setErrors({});\n await onSubmit?.(valuesRef.current, controllerRef.current);\n }\n setIsSubmitting(false);\n setVersion(version + 1);\n }\n\n const resetForm = (props?: FormexResetProps<T>) => {\n const {\n submitCount: submitCountProp,\n values: valuesProp,\n errors: errorsProp,\n touched: touchedProp\n } = props ?? {};\n initialValuesRef.current = valuesProp ?? initialValues;\n valuesRef.current = valuesProp ?? initialValues;\n setValuesInner(valuesProp ?? initialValues);\n setErrors(errorsProp ?? {});\n setTouchedState(touchedProp ?? {});\n setDirty(false);\n setSubmitCount(submitCountProp ?? 0);\n setVersion(version + 1);\n }\n\n const controller: FormexController<T> = {\n values,\n initialValues: initialValuesRef.current,\n handleChange,\n isSubmitting,\n setSubmitting: setIsSubmitting,\n setValues,\n setFieldValue,\n errors,\n setFieldError,\n touched: touchedState,\n setFieldTouched,\n dirty,\n setDirty,\n handleSubmit: submit,\n submitCount,\n setSubmitCount,\n handleBlur,\n validate,\n isValidating,\n resetForm,\n version\n };\n\n const controllerRef = React.useRef<FormexController<T>>(controller);\n controllerRef.current = controller;\n return controller\n}\n"],"names":["React","values"],"mappings":";;;AAGA,MAAM,gBAAgBA,eAAM,cAAqC,CAAA,CAAS;AAE7D,MAAA,YAAY,MAAwB,WAAgC,aAAa;AAEvF,MAAM,SAAS,cAAc;ACJvB,MAAA,eAAe,CAAC,UACzB,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW;AAGtC,MAAM,aAAa,CAAC,QACvB,OAAO,QAAQ;AAGZ,MAAM,WAAW,CAAC,QACrB,QAAQ,QAAQ,OAAO,QAAQ;AAGtB,MAAA,YAAY,CAAC,QACtB,OAAO,KAAK,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM;AAG3B,MAAA,WAAW,CAAC,QACrB,OAAO,UAAU,SAAS,KAAK,GAAG,MAAM;AAI/B,MAAA,QAAQ,CAAC,QAAsB,QAAQ;AAG7C,MAAM,kBAAkB,CAAC,aAC5B,MAAM,SAAS,MAAM,QAAQ,MAAM;AAG1B,MAAA,YAAY,CAAC,UACtB,SAAS,KAAK,KAAK,WAAW,MAAM,IAAI;AAG/B,MAAA,eAAe,CAAC,UACzB,SAAS,SAAS,KAAK,KAAK,SAAS,MAAM,MAAM;AAa9C,SAAS,iBAAiB,KAAgC;AAC7D,QAAM,QAAQ,OAAO,aAAa,cAAc,WAAW;AACvD,MAAA,OAAO,QAAQ,aAAa;AACrB,WAAA;AAAA,EACX;AACI,MAAA;AACO,WAAA,IAAI,iBAAiB,IAAI;AAAA,WAC3B,GAAG;AACR,WAAO,IAAI;AAAA,EACf;AACJ;AAKO,SAAS,MACZ,KACA,KACA,KACA,IAAI,GACN;AACQ,QAAA,OAAO,OAAO,GAAG;AAChB,SAAA,OAAO,IAAI,KAAK,QAAQ;AACrB,UAAA,IAAI,KAAK,GAAG,CAAC;AAAA,EACvB;AAGA,MAAI,MAAM,KAAK,UAAU,CAAC,KAAK;AACpB,WAAA;AAAA,EACX;AAEO,SAAA,QAAQ,SAAY,MAAM;AACrC;AAEgB,SAAA,MAAM,KAAU,MAAc,OAAiB;AACrD,QAAA,MAAW,MAAM,GAAG;AAC1B,MAAI,SAAc;AAClB,MAAI,IAAI;AACF,QAAA,YAAY,OAAO,IAAI;AAE7B,SAAO,IAAI,UAAU,SAAS,GAAG,KAAK;AAC5B,UAAA,cAAsB,UAAU,CAAC;AACjC,UAAA,aAAkB,MAAM,KAAK,UAAU,MAAM,GAAG,IAAI,CAAC,CAAC;AAE5D,QAAI,eAAe,SAAS,UAAU,KAAK,MAAM,QAAQ,UAAU,IAAI;AACnE,eAAS,OAAO,WAAW,IAAI,MAAM,UAAU;AAAA,IAAA,OAC5C;AACG,YAAA,WAAmB,UAAU,IAAI,CAAC;AACxC,eAAS,OAAO,WAAW,IACvB,UAAU,QAAQ,KAAK,OAAO,QAAQ,KAAK,IAAI,CAAA,IAAK,CAAA;AAAA,IAC5D;AAAA,EACJ;AAGK,OAAA,MAAM,IAAI,MAAM,QAAQ,UAAU,CAAC,CAAC,MAAM,OAAO;AAC3C,WAAA;AAAA,EACX;AAEA,MAAI,UAAU,QAAW;AACd,WAAA,OAAO,UAAU,CAAC,CAAC;AAAA,EAAA,OACvB;AACI,WAAA,UAAU,CAAC,CAAC,IAAI;AAAA,EAC3B;AAII,MAAA,MAAM,KAAK,UAAU,QAAW;AACzB,WAAA,IAAI,UAAU,CAAC,CAAC;AAAA,EAC3B;AAEO,SAAA;AACX;AASgB,SAAA,sBACZ,QACA,OACA,8BAAmB,QAAQ,GAC3B,WAAgB,IACf;AACD,aAAW,KAAK,OAAO,KAAK,MAAM,GAAG;AAC3B,UAAA,MAAM,OAAO,CAAC;AAChB,QAAA,SAAS,GAAG,GAAG;AACf,UAAI,CAAC,QAAQ,IAAI,GAAG,GAAG;AACX,gBAAA,IAAI,KAAK,IAAI;AAIZ,iBAAA,CAAC,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK;AACxC,8BAAsB,KAAK,OAAO,SAAS,SAAS,CAAC,CAAC;AAAA,MAC1D;AAAA,IAAA,OACG;AACH,eAAS,CAAC,IAAI;AAAA,IAClB;AAAA,EACJ;AAEO,SAAA;AACX;AAEA,SAAS,MAAM,OAAY;AACnB,MAAA,MAAM,QAAQ,KAAK,GAAG;AACf,WAAA,CAAC,GAAG,KAAK;AAAA,EACT,WAAA,OAAO,UAAU,YAAY,UAAU,MAAM;AAC7C,WAAA,EAAE,GAAG;EAAM,OACf;AACI,WAAA;AAAA,EACX;AACJ;AAEA,SAAS,OAAO,OAA0B;AACtC,MAAI,MAAM,QAAQ,KAAK,EAAU,QAAA;AAEjC,SAAO,MAAM,QAAQ,aAAa,KAAK,EAAE,QAAQ,OAAO,EAAE,EAAE,QAAQ,OAAO,EAAE,EAAE,MAAM,GAAG;AAC5F;AClGO,SAAS,MAA8D;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EACA,IAAI;AAAA;AAAA;AAAA,EAEJ;AAAA,EACA,GAAG;AACP,GAAqB;AAC/F,QAAM,SAAS;AAEf,QAAM,QAAQ,cAAc,EAAE,MAAM,GAAG,MAAA,GAAS,MAAM;AAElD,MAAA,WAAW,QAAQ,GAAG;AACtB,WAAO,SAAS,EAAE,OAAO,MAAM,OAAQ,CAAA;AAAA,EAC3C;AAmBA,QAAM,YAAY,MAAM;AAEpB,MAAA,OAAO,cAAc,UAAU;AAC/B,UAAM,EAAE,UAAU,GAAG,KAAA,IAAS;AAC9B,WAAO,MAAM;AAAA,MACT;AAAA,MACA,EAAE,KAAK,UAAU,GAAG,OAAO,GAAG,MAAM,UAAU;AAAA,MAC9C;AAAA,IAAA;AAAA,EAER;AAEO,SAAA,MAAM,cAAc,WAAW,EAAE,GAAG,OAAO,GAAG,OAAO,aAAa,QAAQ;AACrF;AAEA,MAAM,gBAAgB,CAAC,eAA0C,WAAwD;AAC/G,QAAA,aAAa,SAAS,aAAa;AACnC,QAAA,OAAO,aACN,cAAmC,OACpC;AACN,QAAM,aAAa,MAAM,OAAO,QAAQ,IAAI;AAE5C,QAAM,QAA8B;AAAA,IAChC;AAAA,IACA,OAAO;AAAA,IACP,UAAU,OAAO;AAAA,IACjB,QAAQ,OAAO;AAAA,EAAA;AAEnB,MAAI,YAAY;AACN,UAAA;AAAA,MACF;AAAA,MACA,OAAO;AAAA;AAAA,MACP,IAAI;AAAA,MACJ;AAAA,IACA,IAAA;AAEJ,QAAI,SAAS,YAAY;AACrB,UAAI,cAAc,QAAW;AACnB,cAAA,UAAU,CAAC,CAAC;AAAA,MAAA,OACf;AACG,cAAA,UAAU,CAAC,EACb,MAAM,QAAQ,UAAU,KAAK,CAAC,WAAW,QAAQ,SAAS;AAE9D,cAAM,QAAQ;AAAA,MAClB;AAAA,IAAA,WACO,SAAS,SAAS;AACzB,YAAM,UAAU,eAAe;AAC/B,YAAM,QAAQ;AAAA,IAAA,WACP,OAAO,YAAY,UAAU;AAC9B,YAAA,QAAQ,MAAM,SAAS,CAAA;AAC7B,YAAM,WAAW;AAAA,IACrB;AAAA,EACJ;AACO,SAAA;AACX;ACvJO,SAAS,gBAAkC;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EACA,mBAAmB;AAAA,EACnB;AAAA,EACA,0BAA0B;AAC9B,GAO1B;AAEd,QAAA,mBAAmBA,eAAM,OAAU,aAAa;AAChD,QAAA,YAAYA,eAAM,OAAU,aAAa;AAE/C,QAAM,CAAC,QAAQ,cAAc,IAAI,SAAY,aAAa;AAC1D,QAAM,CAAC,cAAc,eAAe,IAAI,SAAkC,CAAE,CAAA;AAC5E,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAiC,iBAAiB,CAAA,CAAE;AAChF,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,KAAK;AACxC,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,CAAC;AAChD,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,KAAK;AACtD,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,KAAK;AACtD,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,CAAC;AAExC,YAAU,MAAM;AACZ,QAAI,yBAAyB;AAChB;IACb;AAAA,EACJ,GAAG,CAAE,CAAA;AAEC,QAAA,YAAY,CAAC,cAAiB;AAChC,cAAU,UAAU;AACpB,mBAAe,SAAS;AACxB,aAAS,MAAM,iBAAiB,SAAS,SAAS,CAAC;AAAA,EAAA;AAGvD,QAAM,WAAW,YAAY;AACzB,oBAAgB,IAAI;AACpB,UAAMC,UAAS,UAAU;AACnB,UAAA,mBAAmB,MAAM,aAAaA,OAAM;AACxC,cAAA,oBAAoB,CAAA,CAAE;AAChC,oBAAgB,KAAK;AACd,WAAA;AAAA,EAAA;AAGX,QAAM,gBAAgB,CAAC,KAAa,OAAY,mBAA6B;AACzE,UAAM,YAAY,MAAM,UAAU,SAAS,KAAK,KAAK;AACrD,cAAU,UAAU;AACpB,mBAAe,SAAS;AACpB,QAAA,CAAC,MAAM,MAAM,iBAAiB,SAAS,GAAG,GAAG,KAAK,GAAG;AACrD,eAAS,IAAI;AAAA,IACjB;AACA,QAAI,gBAAgB;AACP;IACb;AAAA,EAAA;AAGE,QAAA,gBAAgB,CAAC,KAAa,UAA8B;AACxD,UAAA,YAAY,EAAE,GAAG;AACvB,QAAI,OAAO;AACP,gBAAU,GAAG,IAAI;AAAA,IAAA,OACd;AACH,aAAO,UAAU,GAAG;AAAA,IACxB;AACA,cAAU,SAAS;AAAA,EAAA;AAGvB,QAAM,kBAAkB,CAAC,KAAa,SAAkB,mBAAyC;AACvF,UAAA,aAAa,EAAE,GAAG;AACxB,eAAW,GAAG,IAAI;AAClB,oBAAgB,UAAU;AAC1B,QAAI,gBAAgB;AACP;IACb;AAAA,EAAA;AAGE,QAAA,eAAe,CAAC,UAAgC;AAClD,UAAM,SAAS,MAAM;AACjB,QAAA;AACA,QAAA,OAAO,SAAS,YAAY;AAC5B,cAAQ,OAAO;AAAA,IAAA,WACR,OAAO,SAAS,UAAU;AACjC,cAAQ,OAAO;AAAA,IAAA,OACZ;AACH,cAAQ,OAAO;AAAA,IACnB;AACA,UAAM,OAAO,OAAO;AACN,kBAAA,MAAM,OAAO,gBAAgB;AAC3C,oBAAgB,MAAM,IAAI;AAAA,EAAA;AAGxB,QAAA,aAAa,CAAC,UAA4B;AAC5C,UAAM,SAAS,MAAM;AACrB,UAAM,OAAO,OAAO;AACpB,oBAAgB,MAAM,IAAI;AAAA,EAAA;AAGxB,QAAA,SAAS,OAAO,MAAmC;AACrD,OAAG,eAAe;AAClB,OAAG,gBAAgB;AACnB,oBAAgB,IAAI;AACpB,mBAAe,cAAc,CAAC;AAC9B,UAAM,mBAAmB,MAAM,aAAa,UAAU,OAAO;AAC7D,QAAI,oBAAoB,OAAO,KAAK,gBAAgB,EAAE,SAAS,GAAG;AAC9D,gBAAU,gBAAgB;AAAA,IAAA,OACvB;AACH,gBAAU,CAAE,CAAA;AACZ,YAAM,WAAW,UAAU,SAAS,cAAc,OAAO;AAAA,IAC7D;AACA,oBAAgB,KAAK;AACrB,eAAW,UAAU,CAAC;AAAA,EAAA;AAGpB,QAAA,YAAY,CAAC,UAAgC;AACzC,UAAA;AAAA,MACF,aAAa;AAAA,MACb,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,SAAS;AAAA,IAAA,IACT,SAAS,CAAA;AACb,qBAAiB,UAAU,cAAc;AACzC,cAAU,UAAU,cAAc;AAClC,mBAAe,cAAc,aAAa;AAChC,cAAA,cAAc,CAAA,CAAE;AACV,oBAAA,eAAe,CAAA,CAAE;AACjC,aAAS,KAAK;AACd,mBAAe,mBAAmB,CAAC;AACnC,eAAW,UAAU,CAAC;AAAA,EAAA;AAG1B,QAAM,aAAkC;AAAA,IACpC;AAAA,IACA,eAAe,iBAAiB;AAAA,IAChC;AAAA,IACA;AAAA,IACA,eAAe;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAGE,QAAA,gBAAgBD,eAAM,OAA4B,UAAU;AAClE,gBAAc,UAAU;AACjB,SAAA;AACX;"}
|
|
1
|
+
{"version":3,"file":"index.es.js","sources":["../src/Formex.tsx","../src/utils.ts","../src/Field.tsx","../src/useCreateFormex.tsx"],"sourcesContent":["import React, { useContext } from \"react\";\nimport { FormexController } from \"./types\";\n\nconst FormexContext = React.createContext<FormexController<any>>({} as any);\n\nexport const useFormex = <T extends object>() => useContext<FormexController<T>>(FormexContext);\n\nexport const Formex = FormexContext.Provider;\n","import * as React from \"react\";\n\n/** @private is the value an empty array? */\nexport const isEmptyArray = (value?: any) =>\n Array.isArray(value) && value.length === 0;\n\n/** @private is the given object a Function? */\nexport const isFunction = (obj: any): obj is Function =>\n typeof obj === \"function\";\n\n/** @private is the given object an Object? */\nexport const isObject = (obj: any): obj is Object =>\n obj !== null && typeof obj === \"object\";\n\n/** @private is the given object an integer? */\nexport const isInteger = (obj: any): boolean =>\n String(Math.floor(Number(obj))) === obj;\n\n/** @private is the given object a string? */\nexport const isString = (obj: any): obj is string =>\n Object.prototype.toString.call(obj) === \"[object String]\";\n\n/** @private is the given object a NaN? */\n// eslint-disable-next-line no-self-compare\nexport const isNaN = (obj: any): boolean => obj !== obj;\n\n/** @private Does a React component have exactly 0 children? */\nexport const isEmptyChildren = (children: any): boolean =>\n React.Children.count(children) === 0;\n\n/** @private is the given object/value a promise? */\nexport const isPromise = (value: any): value is PromiseLike<any> =>\n isObject(value) && isFunction(value.then);\n\n/** @private is the given object/value a type of synthetic event? */\nexport const isInputEvent = (value: any): value is React.SyntheticEvent<any> =>\n value && isObject(value) && isObject(value.target);\n\n/**\n * Same as document.activeElement but wraps in a try-catch block. In IE it is\n * not safe to call document.activeElement if there is nothing focused.\n *\n * The activeElement will be null only if the document or document body is not\n * yet defined.\n *\n * @param {?Document} doc Defaults to current document.\n * @return {Element | null}\n * @see https://github.com/facebook/fbjs/blob/master/packages/fbjs/src/core/dom/getActiveElement.js\n */\nexport function getActiveElement(doc?: Document): Element | null {\n doc = doc || (typeof document !== \"undefined\" ? document : undefined);\n if (typeof doc === \"undefined\") {\n return null;\n }\n try {\n return doc.activeElement || doc.body;\n } catch (e) {\n return doc.body;\n }\n}\n\n/**\n * Deeply get a value from an object via its path.\n */\nexport function getIn(\n obj: any,\n key: string | string[],\n def?: any,\n p = 0\n) {\n const path = toPath(key);\n while (obj && p < path.length) {\n obj = obj[path[p++]];\n }\n\n // check if path is not in the end\n if (p !== path.length && !obj) {\n return def;\n }\n\n return obj === undefined ? def : obj;\n}\n\nexport function setIn(obj: any, path: string, value: any): any {\n const res: any = clone(obj); // this keeps inheritance when obj is a class\n let resVal: any = res;\n let i = 0;\n const pathArray = toPath(path);\n\n for (; i < pathArray.length - 1; i++) {\n const currentPath: string = pathArray[i];\n const currentObj: any = getIn(obj, pathArray.slice(0, i + 1));\n\n if (currentObj && (isObject(currentObj) || Array.isArray(currentObj))) {\n resVal = resVal[currentPath] = clone(currentObj);\n } else {\n const nextPath: string = pathArray[i + 1];\n resVal = resVal[currentPath] =\n isInteger(nextPath) && Number(nextPath) >= 0 ? [] : {};\n }\n }\n\n // Return original object if new value is the same as current\n if ((i === 0 ? obj : resVal)[pathArray[i]] === value) {\n return obj;\n }\n\n if (value === undefined) {\n delete resVal[pathArray[i]];\n } else {\n resVal[pathArray[i]] = value;\n }\n\n // If the path array has a single element, the loop did not run.\n // Deleting on `resVal` had no effect in this scenario, so we delete on the result instead.\n if (i === 0 && value === undefined) {\n delete res[pathArray[i]];\n }\n\n return res;\n}\n\n/**\n * Recursively a set the same value for all keys and arrays nested object, cloning\n * @param object\n * @param value\n * @param visited\n * @param response\n */\nexport function setNestedObjectValues<T>(\n object: any,\n value: any,\n visited: any = new WeakMap(),\n response: any = {}\n): T {\n for (const k of Object.keys(object)) {\n const val = object[k];\n if (isObject(val)) {\n if (!visited.get(val)) {\n visited.set(val, true);\n // In order to keep array values consistent for both dot path and\n // bracket syntax, we need to check if this is an array so that\n // this will output { friends: [true] } and not { friends: { \"0\": true } }\n response[k] = Array.isArray(val) ? [] : {};\n setNestedObjectValues(val, value, visited, response[k]);\n }\n } else {\n response[k] = value;\n }\n }\n\n return response;\n}\n\nexport function clone(value: any) {\n if (Array.isArray(value)) {\n return [...value];\n } else if (typeof value === \"object\" && value !== null) {\n return { ...value };\n } else {\n return value; // This is for primitive types which do not need cloning.\n }\n}\n\nfunction toPath(value: string | string[]) {\n if (Array.isArray(value)) return value; // Already in path array form.\n // Replace brackets with dots, remove leading/trailing dots, then split by dot.\n return value.replace(/\\[(\\d+)]/g, \".$1\").replace(/^\\./, \"\").replace(/\\.$/, \"\").split(\".\");\n}\n","import * as React from \"react\";\nimport { useFormex } from \"./Formex\";\nimport { getIn, isFunction, isObject } from \"./utils\";\nimport { FormexController } from \"./types\";\n\nexport interface FieldInputProps<Value> {\n /** Value of the field */\n value: Value;\n /** Name of the field */\n name: string;\n /** Multiple select? */\n multiple?: boolean;\n /** Is the field checked? */\n checked?: boolean;\n /** Change event handler */\n onChange: (event: React.SyntheticEvent) => void,\n /** Blur event handler */\n onBlur: (event: React.FocusEvent) => void,\n}\n\nexport interface FormexFieldProps<Value = any, FormValues extends object = any> {\n field: FieldInputProps<Value>;\n form: FormexController<FormValues>;\n}\n\nexport interface FieldConfig<Value, C extends React.ElementType | undefined = undefined> {\n\n /**\n * Component to render. Can either be a string e.g. 'select', 'input', or 'textarea', or a component.\n */\n as?:\n | C\n | string\n | React.ForwardRefExoticComponent<any>;\n\n /**\n * Children render function <Field name>{props => ...}</Field>)\n */\n children?: ((props: FormexFieldProps<Value>) => React.ReactNode) | React.ReactNode;\n\n /**\n * Validate a single field value independently\n */\n // validate?: FieldValidator;\n\n /**\n * Used for 'select' and related input types.\n */\n multiple?: boolean;\n\n /**\n * Field name\n */\n name: string;\n\n /** HTML input type */\n type?: string;\n\n /** Field value */\n value?: any;\n\n /** Inner ref */\n innerRef?: (instance: any) => void;\n\n}\n\nexport type FieldProps<T, C extends React.ElementType | undefined> = {\n as?: C;\n} & (C extends React.ElementType ? (React.ComponentProps<C> & FieldConfig<T, C>) : FieldConfig<T, C>);\n\nexport function Field<T, C extends React.ElementType | undefined = undefined>({\n validate,\n name,\n children,\n as: is, // `as` is reserved in typescript lol\n // component,\n className,\n ...props\n }: FieldProps<T, C>) {\n const formex = useFormex();\n\n const field = getFieldProps({ name, ...props }, formex);\n\n if (isFunction(children)) {\n return children({ field, form: formex });\n }\n\n // if (component) {\n // if (typeof component === \"string\") {\n // const { innerRef, ...rest } = props;\n // return React.createElement(\n // component,\n // { ref: innerRef, ...field, ...rest, className },\n // children\n // );\n // }\n // return React.createElement(\n // component,\n // { field, form: formex, ...props, className },\n // children\n // );\n // }\n\n // default to input here so we can check for both `as` and `children` above\n const asElement = is || \"input\";\n\n if (typeof asElement === \"string\") {\n const { innerRef, ...rest } = props;\n return React.createElement(\n asElement,\n { ref: innerRef, ...field, ...rest, className },\n children\n );\n }\n\n return React.createElement(asElement, { ...field, ...props, className }, children);\n}\n\nconst getFieldProps = (nameOrOptions: string | FieldConfig<any>, formex: FormexController<any>): FieldInputProps<any> => {\n const isAnObject = isObject(nameOrOptions);\n const name = isAnObject\n ? (nameOrOptions as FieldConfig<any>).name\n : nameOrOptions;\n const valueState = getIn(formex.values, name);\n\n const field: FieldInputProps<any> = {\n name,\n value: valueState,\n onChange: formex.handleChange,\n onBlur: formex.handleBlur,\n };\n if (isAnObject) {\n const {\n type,\n value: valueProp, // value is special for checkboxes\n as: is,\n multiple,\n } = nameOrOptions as FieldConfig<any>;\n\n if (type === \"checkbox\") {\n if (valueProp === undefined) {\n field.checked = !!valueState;\n } else {\n field.checked = !!(\n Array.isArray(valueState) && ~valueState.indexOf(valueProp)\n );\n field.value = valueProp;\n }\n } else if (type === \"radio\") {\n field.checked = valueState === valueProp;\n field.value = valueProp;\n } else if (is === \"select\" && multiple) {\n field.value = field.value || [];\n field.multiple = true;\n }\n }\n return field;\n};\n","import React, { FormEvent, useEffect, useState } from \"react\";\nimport { getIn, setIn } from \"./utils\";\nimport equal from \"react-fast-compare\"\n\nimport { FormexController, FormexResetProps } from \"./types\";\n\nexport function useCreateFormex<T extends object>({\n initialValues,\n initialErrors,\n validation,\n validateOnChange = false,\n onSubmit,\n validateOnInitialRender = false,\n debugId\n }: {\n initialValues: T,\n initialErrors?: Record<string, string>,\n validateOnChange?: boolean,\n validateOnInitialRender?: boolean,\n validation?: (values: T) => Record<string, string> | Promise<Record<string, string>> | undefined | void,\n onSubmit?: (values: T, controller: FormexController<T>) => void | Promise<void>,\n debugId?: string\n}): FormexController<T> {\n\n const initialValuesRef = React.useRef<T>(initialValues);\n const valuesRef = React.useRef<T>(initialValues);\n const debugIdRef = React.useRef<string | undefined>(debugId);\n\n const [values, setValuesInner] = useState<T>(initialValues);\n const [touchedState, setTouchedState] = useState<Record<string, boolean>>({});\n const [errors, setErrors] = useState<Record<string, string>>(initialErrors ?? {});\n const [dirty, setDirty] = useState(false);\n const [submitCount, setSubmitCount] = useState(0);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [isValidating, setIsValidating] = useState(false);\n const [version, setVersion] = useState(0);\n\n useEffect(() => {\n if (validateOnInitialRender) {\n validate();\n }\n }, []);\n\n const setValues = (newValues: T) => {\n valuesRef.current = newValues;\n setValuesInner(newValues);\n setDirty(equal(initialValuesRef.current, newValues));\n }\n\n const validate = async () => {\n setIsValidating(true);\n const validationErrors = await validation?.(valuesRef.current);\n setErrors(validationErrors ?? {});\n setIsValidating(false);\n return validationErrors;\n }\n\n const setFieldValue = (key: string, value: any, shouldValidate?: boolean) => {\n const newValues = setIn(valuesRef.current, key, value);\n valuesRef.current = newValues;\n setValuesInner(newValues);\n if (!equal(getIn(initialValuesRef.current, key), value)) {\n setDirty(true);\n }\n if (shouldValidate) {\n validate();\n }\n }\n\n const setFieldError = (key: string, error: string | undefined) => {\n const newErrors = { ...errors };\n if (error) {\n newErrors[key] = error;\n } else {\n delete newErrors[key];\n }\n setErrors(newErrors);\n }\n\n const setFieldTouched = (key: string, touched: boolean, shouldValidate?: boolean | undefined) => {\n const newTouched = { ...touchedState };\n newTouched[key] = touched;\n setTouchedState(newTouched);\n if (shouldValidate) {\n validate();\n }\n }\n\n const handleChange = (event: React.SyntheticEvent) => {\n const target = event.target as HTMLInputElement;\n let value;\n if (target.type === \"checkbox\") {\n value = target.checked;\n } else if (target.type === \"number\") {\n value = target.valueAsNumber;\n } else {\n value = target.value;\n }\n const name = target.name;\n setFieldValue(name, value, validateOnChange);\n setFieldTouched(name, true);\n }\n\n const handleBlur = (event: React.FocusEvent) => {\n const target = event.target as HTMLInputElement;\n const name = target.name;\n setFieldTouched(name, true);\n }\n\n const submit = async (e?: FormEvent<HTMLFormElement>) => {\n e?.preventDefault();\n e?.stopPropagation();\n setIsSubmitting(true);\n setSubmitCount(submitCount + 1);\n const validationErrors = await validation?.(valuesRef.current);\n if (validationErrors && Object.keys(validationErrors).length > 0) {\n setErrors(validationErrors);\n } else {\n setErrors({});\n await onSubmit?.(valuesRef.current, controllerRef.current);\n }\n setIsSubmitting(false);\n setVersion(version + 1);\n }\n\n const resetForm = (props?: FormexResetProps<T>) => {\n const {\n submitCount: submitCountProp,\n values: valuesProp,\n errors: errorsProp,\n touched: touchedProp\n } = props ?? {};\n initialValuesRef.current = valuesProp ?? initialValues;\n valuesRef.current = valuesProp ?? initialValues;\n setValuesInner(valuesProp ?? initialValues);\n setErrors(errorsProp ?? {});\n setTouchedState(touchedProp ?? {});\n setDirty(false);\n setSubmitCount(submitCountProp ?? 0);\n setVersion(version + 1);\n }\n\n const controller: FormexController<T> = {\n values,\n initialValues: initialValuesRef.current,\n handleChange,\n isSubmitting,\n setSubmitting: setIsSubmitting,\n setValues,\n setFieldValue,\n errors,\n setFieldError,\n touched: touchedState,\n setFieldTouched,\n dirty,\n setDirty,\n handleSubmit: submit,\n submitCount,\n setSubmitCount,\n handleBlur,\n validate,\n isValidating,\n resetForm,\n version,\n debugId: debugIdRef.current\n };\n\n const controllerRef = React.useRef<FormexController<T>>(controller);\n controllerRef.current = controller;\n return controller\n}\n"],"names":["FormexContext","React","createContext","useFormex","useContext","Formex","Provider","isEmptyArray","value","Array","isArray","length","isFunction","obj","isObject","isInteger","String","Math","floor","Number","isString","Object","prototype","toString","call","isNaN","isEmptyChildren","children","Children","count","isPromise","then","isInputEvent","target","getActiveElement","doc","document","undefined","activeElement","body","e","getIn","key","def","p","path","toPath","setIn","res","clone","resVal","i","pathArray","currentPath","currentObj","slice","nextPath","setNestedObjectValues","object","visited","WeakMap","response","k","keys","val","get","set","replace","split","Field","t0","$","_c","className","is","name","props","validate","t1","t2","as","t3","t4","t5","formex","field","Symbol","for","getFieldProps","form","bb0","asElement","innerRef","rest","ref","createElement","nameOrOptions","isAnObject","valueState","values","onChange","handleChange","onBlur","handleBlur","type","valueProp","multiple","checked","indexOf","useCreateFormex","initialValues","initialErrors","validation","validateOnChange","onSubmit","validateOnInitialRender","debugId","initialValuesRef","useRef","valuesRef","debugIdRef","setValuesInner","useState","touchedState","setTouchedState","errors","setErrors","dirty","setDirty","submitCount","setSubmitCount","isSubmitting","setIsSubmitting","isValidating","setIsValidating","version","setVersion","useEffect","setValues","newValues","current","equal","validationErrors","setFieldValue","shouldValidate","setFieldError","error","newErrors","setFieldTouched","touched","newTouched","event","valueAsNumber","submit","preventDefault","stopPropagation","controllerRef","resetForm","submitCountProp","valuesProp","errorsProp","touchedProp","controller","setSubmitting","handleSubmit"],"mappings":"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"}
|
package/dist/index.umd.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(function(global, factory) {
|
|
2
|
-
typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("react"), require("react-fast-compare")) : typeof define === "function" && define.amd ? define(["exports", "react", "react-fast-compare"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.Formex = {}, global.React, global.equal));
|
|
3
|
-
})(this, function(exports2, React, equal) {
|
|
2
|
+
typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("react-compiler-runtime"), require("react"), require("react-fast-compare")) : typeof define === "function" && define.amd ? define(["exports", "react-compiler-runtime", "react", "react-fast-compare"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.Formex = {}, global.reactCompilerRuntime, global.React, global.equal));
|
|
3
|
+
})(this, function(exports2, reactCompilerRuntime, React, equal) {
|
|
4
4
|
"use strict";
|
|
5
5
|
function _interopNamespaceDefault(e) {
|
|
6
6
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
@@ -20,7 +20,9 @@
|
|
|
20
20
|
}
|
|
21
21
|
const React__namespace = /* @__PURE__ */ _interopNamespaceDefault(React);
|
|
22
22
|
const FormexContext = React.createContext({});
|
|
23
|
-
const useFormex = () =>
|
|
23
|
+
const useFormex = () => {
|
|
24
|
+
return React.useContext(FormexContext);
|
|
25
|
+
};
|
|
24
26
|
const Formex = FormexContext.Provider;
|
|
25
27
|
const isEmptyArray = (value) => Array.isArray(value) && value.length === 0;
|
|
26
28
|
const isFunction = (obj) => typeof obj === "function";
|
|
@@ -99,7 +101,9 @@
|
|
|
99
101
|
if (Array.isArray(value)) {
|
|
100
102
|
return [...value];
|
|
101
103
|
} else if (typeof value === "object" && value !== null) {
|
|
102
|
-
return {
|
|
104
|
+
return {
|
|
105
|
+
...value
|
|
106
|
+
};
|
|
103
107
|
} else {
|
|
104
108
|
return value;
|
|
105
109
|
}
|
|
@@ -108,31 +112,145 @@
|
|
|
108
112
|
if (Array.isArray(value)) return value;
|
|
109
113
|
return value.replace(/\[(\d+)]/g, ".$1").replace(/^\./, "").replace(/\.$/, "").split(".");
|
|
110
114
|
}
|
|
111
|
-
function Field({
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
115
|
+
function Field(t0) {
|
|
116
|
+
const $ = reactCompilerRuntime.c(37);
|
|
117
|
+
let children;
|
|
118
|
+
let className;
|
|
119
|
+
let is;
|
|
120
|
+
let name;
|
|
121
|
+
let props;
|
|
122
|
+
if ($[0] !== t0) {
|
|
123
|
+
const {
|
|
124
|
+
validate,
|
|
125
|
+
name: t12,
|
|
126
|
+
children: t22,
|
|
127
|
+
as: t3,
|
|
128
|
+
className: t4,
|
|
129
|
+
...t5
|
|
130
|
+
} = t0;
|
|
131
|
+
name = t12;
|
|
132
|
+
children = t22;
|
|
133
|
+
is = t3;
|
|
134
|
+
className = t4;
|
|
135
|
+
props = t5;
|
|
136
|
+
$[0] = t0;
|
|
137
|
+
$[1] = children;
|
|
138
|
+
$[2] = className;
|
|
139
|
+
$[3] = is;
|
|
140
|
+
$[4] = name;
|
|
141
|
+
$[5] = props;
|
|
142
|
+
} else {
|
|
143
|
+
children = $[1];
|
|
144
|
+
className = $[2];
|
|
145
|
+
is = $[3];
|
|
146
|
+
name = $[4];
|
|
147
|
+
props = $[5];
|
|
148
|
+
}
|
|
121
149
|
const formex = useFormex();
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
150
|
+
let field;
|
|
151
|
+
let t1;
|
|
152
|
+
if ($[6] !== children || $[7] !== formex || $[8] !== name || $[9] !== props) {
|
|
153
|
+
t1 = Symbol.for("react.early_return_sentinel");
|
|
154
|
+
bb0: {
|
|
155
|
+
field = getFieldProps({
|
|
156
|
+
name,
|
|
157
|
+
...props
|
|
158
|
+
}, formex);
|
|
159
|
+
if (isFunction(children)) {
|
|
160
|
+
t1 = children({
|
|
161
|
+
field,
|
|
162
|
+
form: formex
|
|
163
|
+
});
|
|
164
|
+
break bb0;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
$[6] = children;
|
|
168
|
+
$[7] = formex;
|
|
169
|
+
$[8] = name;
|
|
170
|
+
$[9] = props;
|
|
171
|
+
$[10] = field;
|
|
172
|
+
$[11] = t1;
|
|
173
|
+
} else {
|
|
174
|
+
field = $[10];
|
|
175
|
+
t1 = $[11];
|
|
176
|
+
}
|
|
177
|
+
if (t1 !== Symbol.for("react.early_return_sentinel")) {
|
|
178
|
+
return t1;
|
|
125
179
|
}
|
|
126
180
|
const asElement = is || "input";
|
|
127
181
|
if (typeof asElement === "string") {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
{
|
|
132
|
-
|
|
133
|
-
|
|
182
|
+
let innerRef;
|
|
183
|
+
let rest;
|
|
184
|
+
if ($[12] !== props) {
|
|
185
|
+
({
|
|
186
|
+
innerRef,
|
|
187
|
+
...rest
|
|
188
|
+
} = props);
|
|
189
|
+
$[12] = props;
|
|
190
|
+
$[13] = innerRef;
|
|
191
|
+
$[14] = rest;
|
|
192
|
+
} else {
|
|
193
|
+
innerRef = $[13];
|
|
194
|
+
rest = $[14];
|
|
195
|
+
}
|
|
196
|
+
let t22;
|
|
197
|
+
if ($[15] !== asElement || $[16] !== children || $[17] !== className || $[18] !== field || $[19] !== innerRef || $[20] !== rest) {
|
|
198
|
+
let t3;
|
|
199
|
+
if ($[22] !== className || $[23] !== field || $[24] !== innerRef || $[25] !== rest) {
|
|
200
|
+
t3 = {
|
|
201
|
+
ref: innerRef,
|
|
202
|
+
...field,
|
|
203
|
+
...rest,
|
|
204
|
+
className
|
|
205
|
+
};
|
|
206
|
+
$[22] = className;
|
|
207
|
+
$[23] = field;
|
|
208
|
+
$[24] = innerRef;
|
|
209
|
+
$[25] = rest;
|
|
210
|
+
$[26] = t3;
|
|
211
|
+
} else {
|
|
212
|
+
t3 = $[26];
|
|
213
|
+
}
|
|
214
|
+
t22 = React__namespace.createElement(asElement, t3, children);
|
|
215
|
+
$[15] = asElement;
|
|
216
|
+
$[16] = children;
|
|
217
|
+
$[17] = className;
|
|
218
|
+
$[18] = field;
|
|
219
|
+
$[19] = innerRef;
|
|
220
|
+
$[20] = rest;
|
|
221
|
+
$[21] = t22;
|
|
222
|
+
} else {
|
|
223
|
+
t22 = $[21];
|
|
224
|
+
}
|
|
225
|
+
return t22;
|
|
134
226
|
}
|
|
135
|
-
|
|
227
|
+
let t2;
|
|
228
|
+
if ($[27] !== asElement || $[28] !== children || $[29] !== className || $[30] !== field || $[31] !== props) {
|
|
229
|
+
let t3;
|
|
230
|
+
if ($[33] !== className || $[34] !== field || $[35] !== props) {
|
|
231
|
+
t3 = {
|
|
232
|
+
...field,
|
|
233
|
+
...props,
|
|
234
|
+
className
|
|
235
|
+
};
|
|
236
|
+
$[33] = className;
|
|
237
|
+
$[34] = field;
|
|
238
|
+
$[35] = props;
|
|
239
|
+
$[36] = t3;
|
|
240
|
+
} else {
|
|
241
|
+
t3 = $[36];
|
|
242
|
+
}
|
|
243
|
+
t2 = React__namespace.createElement(asElement, t3, children);
|
|
244
|
+
$[27] = asElement;
|
|
245
|
+
$[28] = children;
|
|
246
|
+
$[29] = className;
|
|
247
|
+
$[30] = field;
|
|
248
|
+
$[31] = props;
|
|
249
|
+
$[32] = t2;
|
|
250
|
+
} else {
|
|
251
|
+
t2 = $[32];
|
|
252
|
+
}
|
|
253
|
+
return t2;
|
|
136
254
|
}
|
|
137
255
|
const getFieldProps = (nameOrOptions, formex) => {
|
|
138
256
|
const isAnObject = isObject(nameOrOptions);
|
|
@@ -175,10 +293,12 @@
|
|
|
175
293
|
validation,
|
|
176
294
|
validateOnChange = false,
|
|
177
295
|
onSubmit,
|
|
178
|
-
validateOnInitialRender = false
|
|
296
|
+
validateOnInitialRender = false,
|
|
297
|
+
debugId
|
|
179
298
|
}) {
|
|
180
299
|
const initialValuesRef = React.useRef(initialValues);
|
|
181
300
|
const valuesRef = React.useRef(initialValues);
|
|
301
|
+
const debugIdRef = React.useRef(debugId);
|
|
182
302
|
const [values, setValuesInner] = React.useState(initialValues);
|
|
183
303
|
const [touchedState, setTouchedState] = React.useState({});
|
|
184
304
|
const [errors, setErrors] = React.useState(initialErrors ?? {});
|
|
@@ -199,16 +319,15 @@
|
|
|
199
319
|
};
|
|
200
320
|
const validate = async () => {
|
|
201
321
|
setIsValidating(true);
|
|
202
|
-
const
|
|
203
|
-
const validationErrors = await validation?.(values2);
|
|
322
|
+
const validationErrors = await validation?.(valuesRef.current);
|
|
204
323
|
setErrors(validationErrors ?? {});
|
|
205
324
|
setIsValidating(false);
|
|
206
325
|
return validationErrors;
|
|
207
326
|
};
|
|
208
327
|
const setFieldValue = (key, value, shouldValidate) => {
|
|
209
|
-
const
|
|
210
|
-
valuesRef.current =
|
|
211
|
-
setValuesInner(
|
|
328
|
+
const newValues_0 = setIn(valuesRef.current, key, value);
|
|
329
|
+
valuesRef.current = newValues_0;
|
|
330
|
+
setValuesInner(newValues_0);
|
|
212
331
|
if (!equal(getIn(initialValuesRef.current, key), value)) {
|
|
213
332
|
setDirty(true);
|
|
214
333
|
}
|
|
@@ -216,50 +335,54 @@
|
|
|
216
335
|
validate();
|
|
217
336
|
}
|
|
218
337
|
};
|
|
219
|
-
const setFieldError = (
|
|
220
|
-
const newErrors = {
|
|
338
|
+
const setFieldError = (key_0, error) => {
|
|
339
|
+
const newErrors = {
|
|
340
|
+
...errors
|
|
341
|
+
};
|
|
221
342
|
if (error) {
|
|
222
|
-
newErrors[
|
|
343
|
+
newErrors[key_0] = error;
|
|
223
344
|
} else {
|
|
224
|
-
delete newErrors[
|
|
345
|
+
delete newErrors[key_0];
|
|
225
346
|
}
|
|
226
347
|
setErrors(newErrors);
|
|
227
348
|
};
|
|
228
|
-
const setFieldTouched = (
|
|
229
|
-
const newTouched = {
|
|
230
|
-
|
|
349
|
+
const setFieldTouched = (key_1, touched, shouldValidate_0) => {
|
|
350
|
+
const newTouched = {
|
|
351
|
+
...touchedState
|
|
352
|
+
};
|
|
353
|
+
newTouched[key_1] = touched;
|
|
231
354
|
setTouchedState(newTouched);
|
|
232
|
-
if (
|
|
355
|
+
if (shouldValidate_0) {
|
|
233
356
|
validate();
|
|
234
357
|
}
|
|
235
358
|
};
|
|
236
359
|
const handleChange = (event) => {
|
|
237
360
|
const target = event.target;
|
|
238
|
-
let
|
|
361
|
+
let value_0;
|
|
239
362
|
if (target.type === "checkbox") {
|
|
240
|
-
|
|
363
|
+
value_0 = target.checked;
|
|
241
364
|
} else if (target.type === "number") {
|
|
242
|
-
|
|
365
|
+
value_0 = target.valueAsNumber;
|
|
243
366
|
} else {
|
|
244
|
-
|
|
367
|
+
value_0 = target.value;
|
|
245
368
|
}
|
|
246
369
|
const name = target.name;
|
|
247
|
-
setFieldValue(name,
|
|
370
|
+
setFieldValue(name, value_0, validateOnChange);
|
|
248
371
|
setFieldTouched(name, true);
|
|
249
372
|
};
|
|
250
|
-
const handleBlur = (
|
|
251
|
-
const
|
|
252
|
-
const
|
|
253
|
-
setFieldTouched(
|
|
373
|
+
const handleBlur = (event_0) => {
|
|
374
|
+
const target_0 = event_0.target;
|
|
375
|
+
const name_0 = target_0.name;
|
|
376
|
+
setFieldTouched(name_0, true);
|
|
254
377
|
};
|
|
255
378
|
const submit = async (e) => {
|
|
256
379
|
e?.preventDefault();
|
|
257
380
|
e?.stopPropagation();
|
|
258
381
|
setIsSubmitting(true);
|
|
259
382
|
setSubmitCount(submitCount + 1);
|
|
260
|
-
const
|
|
261
|
-
if (
|
|
262
|
-
setErrors(
|
|
383
|
+
const validationErrors_0 = await validation?.(valuesRef.current);
|
|
384
|
+
if (validationErrors_0 && Object.keys(validationErrors_0).length > 0) {
|
|
385
|
+
setErrors(validationErrors_0);
|
|
263
386
|
} else {
|
|
264
387
|
setErrors({});
|
|
265
388
|
await onSubmit?.(valuesRef.current, controllerRef.current);
|
|
@@ -304,7 +427,8 @@
|
|
|
304
427
|
validate,
|
|
305
428
|
isValidating,
|
|
306
429
|
resetForm,
|
|
307
|
-
version
|
|
430
|
+
version,
|
|
431
|
+
debugId: debugIdRef.current
|
|
308
432
|
};
|
|
309
433
|
const controllerRef = React.useRef(controller);
|
|
310
434
|
controllerRef.current = controller;
|
|
@@ -312,6 +436,7 @@
|
|
|
312
436
|
}
|
|
313
437
|
exports2.Field = Field;
|
|
314
438
|
exports2.Formex = Formex;
|
|
439
|
+
exports2.clone = clone;
|
|
315
440
|
exports2.getActiveElement = getActiveElement;
|
|
316
441
|
exports2.getIn = getIn;
|
|
317
442
|
exports2.isEmptyArray = isEmptyArray;
|
package/dist/index.umd.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.umd.js","sources":["../src/Formex.tsx","../src/utils.ts","../src/Field.tsx","../src/useCreateFormex.tsx"],"sourcesContent":["import React, { useContext } from \"react\";\nimport { FormexController } from \"./types\";\n\nconst FormexContext = React.createContext<FormexController<any>>({} as any);\n\nexport const useFormex = <T extends object>() => useContext<FormexController<T>>(FormexContext);\n\nexport const Formex = FormexContext.Provider;\n","import * as React from \"react\";\n\n/** @private is the value an empty array? */\nexport const isEmptyArray = (value?: any) =>\n Array.isArray(value) && value.length === 0;\n\n/** @private is the given object a Function? */\nexport const isFunction = (obj: any): obj is Function =>\n typeof obj === \"function\";\n\n/** @private is the given object an Object? */\nexport const isObject = (obj: any): obj is Object =>\n obj !== null && typeof obj === \"object\";\n\n/** @private is the given object an integer? */\nexport const isInteger = (obj: any): boolean =>\n String(Math.floor(Number(obj))) === obj;\n\n/** @private is the given object a string? */\nexport const isString = (obj: any): obj is string =>\n Object.prototype.toString.call(obj) === \"[object String]\";\n\n/** @private is the given object a NaN? */\n// eslint-disable-next-line no-self-compare\nexport const isNaN = (obj: any): boolean => obj !== obj;\n\n/** @private Does a React component have exactly 0 children? */\nexport const isEmptyChildren = (children: any): boolean =>\n React.Children.count(children) === 0;\n\n/** @private is the given object/value a promise? */\nexport const isPromise = (value: any): value is PromiseLike<any> =>\n isObject(value) && isFunction(value.then);\n\n/** @private is the given object/value a type of synthetic event? */\nexport const isInputEvent = (value: any): value is React.SyntheticEvent<any> =>\n value && isObject(value) && isObject(value.target);\n\n/**\n * Same as document.activeElement but wraps in a try-catch block. In IE it is\n * not safe to call document.activeElement if there is nothing focused.\n *\n * The activeElement will be null only if the document or document body is not\n * yet defined.\n *\n * @param {?Document} doc Defaults to current document.\n * @return {Element | null}\n * @see https://github.com/facebook/fbjs/blob/master/packages/fbjs/src/core/dom/getActiveElement.js\n */\nexport function getActiveElement(doc?: Document): Element | null {\n doc = doc || (typeof document !== \"undefined\" ? document : undefined);\n if (typeof doc === \"undefined\") {\n return null;\n }\n try {\n return doc.activeElement || doc.body;\n } catch (e) {\n return doc.body;\n }\n}\n\n/**\n * Deeply get a value from an object via its path.\n */\nexport function getIn(\n obj: any,\n key: string | string[],\n def?: any,\n p = 0\n) {\n const path = toPath(key);\n while (obj && p < path.length) {\n obj = obj[path[p++]];\n }\n\n // check if path is not in the end\n if (p !== path.length && !obj) {\n return def;\n }\n\n return obj === undefined ? def : obj;\n}\n\nexport function setIn(obj: any, path: string, value: any): any {\n const res: any = clone(obj); // this keeps inheritance when obj is a class\n let resVal: any = res;\n let i = 0;\n const pathArray = toPath(path);\n\n for (; i < pathArray.length - 1; i++) {\n const currentPath: string = pathArray[i];\n const currentObj: any = getIn(obj, pathArray.slice(0, i + 1));\n\n if (currentObj && (isObject(currentObj) || Array.isArray(currentObj))) {\n resVal = resVal[currentPath] = clone(currentObj);\n } else {\n const nextPath: string = pathArray[i + 1];\n resVal = resVal[currentPath] =\n isInteger(nextPath) && Number(nextPath) >= 0 ? [] : {};\n }\n }\n\n // Return original object if new value is the same as current\n if ((i === 0 ? obj : resVal)[pathArray[i]] === value) {\n return obj;\n }\n\n if (value === undefined) {\n delete resVal[pathArray[i]];\n } else {\n resVal[pathArray[i]] = value;\n }\n\n // If the path array has a single element, the loop did not run.\n // Deleting on `resVal` had no effect in this scenario, so we delete on the result instead.\n if (i === 0 && value === undefined) {\n delete res[pathArray[i]];\n }\n\n return res;\n}\n\n/**\n * Recursively a set the same value for all keys and arrays nested object, cloning\n * @param object\n * @param value\n * @param visited\n * @param response\n */\nexport function setNestedObjectValues<T>(\n object: any,\n value: any,\n visited: any = new WeakMap(),\n response: any = {}\n): T {\n for (const k of Object.keys(object)) {\n const val = object[k];\n if (isObject(val)) {\n if (!visited.get(val)) {\n visited.set(val, true);\n // In order to keep array values consistent for both dot path and\n // bracket syntax, we need to check if this is an array so that\n // this will output { friends: [true] } and not { friends: { \"0\": true } }\n response[k] = Array.isArray(val) ? [] : {};\n setNestedObjectValues(val, value, visited, response[k]);\n }\n } else {\n response[k] = value;\n }\n }\n\n return response;\n}\n\nfunction clone(value: any) {\n if (Array.isArray(value)) {\n return [...value];\n } else if (typeof value === \"object\" && value !== null) {\n return { ...value };\n } else {\n return value; // This is for primitive types which do not need cloning.\n }\n}\n\nfunction toPath(value: string | string[]) {\n if (Array.isArray(value)) return value; // Already in path array form.\n // Replace brackets with dots, remove leading/trailing dots, then split by dot.\n return value.replace(/\\[(\\d+)]/g, \".$1\").replace(/^\\./, \"\").replace(/\\.$/, \"\").split(\".\");\n}\n","import * as React from \"react\";\nimport { useFormex } from \"./Formex\";\nimport { getIn, isFunction, isObject } from \"./utils\";\nimport { FormexController } from \"./types\";\n\nexport interface FieldInputProps<Value> {\n /** Value of the field */\n value: Value;\n /** Name of the field */\n name: string;\n /** Multiple select? */\n multiple?: boolean;\n /** Is the field checked? */\n checked?: boolean;\n /** Change event handler */\n onChange: (event: React.SyntheticEvent) => void,\n /** Blur event handler */\n onBlur: (event: React.FocusEvent) => void,\n}\n\nexport interface FormexFieldProps<Value = any, FormValues extends object = any> {\n field: FieldInputProps<Value>;\n form: FormexController<FormValues>;\n}\n\nexport interface FieldConfig<Value, C extends React.ElementType | undefined = undefined> {\n\n /**\n * Component to render. Can either be a string e.g. 'select', 'input', or 'textarea', or a component.\n */\n as?:\n | C\n | string\n | React.ForwardRefExoticComponent<any>;\n\n /**\n * Children render function <Field name>{props => ...}</Field>)\n */\n children?: ((props: FormexFieldProps<Value>) => React.ReactNode) | React.ReactNode;\n\n /**\n * Validate a single field value independently\n */\n // validate?: FieldValidator;\n\n /**\n * Used for 'select' and related input types.\n */\n multiple?: boolean;\n\n /**\n * Field name\n */\n name: string;\n\n /** HTML input type */\n type?: string;\n\n /** Field value */\n value?: any;\n\n /** Inner ref */\n innerRef?: (instance: any) => void;\n\n}\n\nexport type FieldProps<T, C extends React.ElementType | undefined> = {\n as?: C;\n} & (C extends React.ElementType ? (React.ComponentProps<C> & FieldConfig<T, C>) : FieldConfig<T, C>);\n\nexport function Field<T, C extends React.ElementType | undefined = undefined>({\n validate,\n name,\n children,\n as: is, // `as` is reserved in typescript lol\n // component,\n className,\n ...props\n }: FieldProps<T, C>) {\n const formex = useFormex();\n\n const field = getFieldProps({ name, ...props }, formex);\n\n if (isFunction(children)) {\n return children({ field, form: formex });\n }\n\n // if (component) {\n // if (typeof component === \"string\") {\n // const { innerRef, ...rest } = props;\n // return React.createElement(\n // component,\n // { ref: innerRef, ...field, ...rest, className },\n // children\n // );\n // }\n // return React.createElement(\n // component,\n // { field, form: formex, ...props, className },\n // children\n // );\n // }\n\n // default to input here so we can check for both `as` and `children` above\n const asElement = is || \"input\";\n\n if (typeof asElement === \"string\") {\n const { innerRef, ...rest } = props;\n return React.createElement(\n asElement,\n { ref: innerRef, ...field, ...rest, className },\n children\n );\n }\n\n return React.createElement(asElement, { ...field, ...props, className }, children);\n}\n\nconst getFieldProps = (nameOrOptions: string | FieldConfig<any>, formex: FormexController<any>): FieldInputProps<any> => {\n const isAnObject = isObject(nameOrOptions);\n const name = isAnObject\n ? (nameOrOptions as FieldConfig<any>).name\n : nameOrOptions;\n const valueState = getIn(formex.values, name);\n\n const field: FieldInputProps<any> = {\n name,\n value: valueState,\n onChange: formex.handleChange,\n onBlur: formex.handleBlur,\n };\n if (isAnObject) {\n const {\n type,\n value: valueProp, // value is special for checkboxes\n as: is,\n multiple,\n } = nameOrOptions as FieldConfig<any>;\n\n if (type === \"checkbox\") {\n if (valueProp === undefined) {\n field.checked = !!valueState;\n } else {\n field.checked = !!(\n Array.isArray(valueState) && ~valueState.indexOf(valueProp)\n );\n field.value = valueProp;\n }\n } else if (type === \"radio\") {\n field.checked = valueState === valueProp;\n field.value = valueProp;\n } else if (is === \"select\" && multiple) {\n field.value = field.value || [];\n field.multiple = true;\n }\n }\n return field;\n};\n","import React, { FormEvent, useEffect, useState } from \"react\";\nimport { getIn, setIn } from \"./utils\";\nimport equal from \"react-fast-compare\"\n\nimport { FormexController, FormexResetProps } from \"./types\";\n\nexport function useCreateFormex<T extends object>({\n initialValues,\n initialErrors,\n validation,\n validateOnChange = false,\n onSubmit,\n validateOnInitialRender = false\n }: {\n initialValues: T,\n initialErrors?: Record<string, string>,\n validateOnChange?: boolean,\n validateOnInitialRender?: boolean,\n validation?: (values: T) => Record<string, string> | Promise<Record<string, string>> | undefined | void,\n onSubmit?: (values: T, controller: FormexController<T>) => void | Promise<void>\n}): FormexController<T> {\n\n const initialValuesRef = React.useRef<T>(initialValues);\n const valuesRef = React.useRef<T>(initialValues);\n\n const [values, setValuesInner] = useState<T>(initialValues);\n const [touchedState, setTouchedState] = useState<Record<string, boolean>>({});\n const [errors, setErrors] = useState<Record<string, string>>(initialErrors ?? {});\n const [dirty, setDirty] = useState(false);\n const [submitCount, setSubmitCount] = useState(0);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [isValidating, setIsValidating] = useState(false);\n const [version, setVersion] = useState(0);\n\n useEffect(() => {\n if (validateOnInitialRender) {\n validate();\n }\n }, []);\n\n const setValues = (newValues: T) => {\n valuesRef.current = newValues;\n setValuesInner(newValues);\n setDirty(equal(initialValuesRef.current, newValues));\n }\n\n const validate = async () => {\n setIsValidating(true);\n const values = valuesRef.current;\n const validationErrors = await validation?.(values);\n setErrors(validationErrors ?? {});\n setIsValidating(false);\n return validationErrors;\n }\n\n const setFieldValue = (key: string, value: any, shouldValidate?: boolean) => {\n const newValues = setIn(valuesRef.current, key, value);\n valuesRef.current = newValues;\n setValuesInner(newValues);\n if (!equal(getIn(initialValuesRef.current, key), value)) {\n setDirty(true);\n }\n if (shouldValidate) {\n validate();\n }\n }\n\n const setFieldError = (key: string, error: string | undefined) => {\n const newErrors = { ...errors };\n if (error) {\n newErrors[key] = error;\n } else {\n delete newErrors[key];\n }\n setErrors(newErrors);\n }\n\n const setFieldTouched = (key: string, touched: boolean, shouldValidate?: boolean | undefined) => {\n const newTouched = { ...touchedState };\n newTouched[key] = touched;\n setTouchedState(newTouched);\n if (shouldValidate) {\n validate();\n }\n }\n\n const handleChange = (event: React.SyntheticEvent) => {\n const target = event.target as HTMLInputElement;\n let value;\n if (target.type === \"checkbox\") {\n value = target.checked;\n } else if (target.type === \"number\") {\n value = target.valueAsNumber;\n } else {\n value = target.value;\n }\n const name = target.name;\n setFieldValue(name, value, validateOnChange);\n setFieldTouched(name, true);\n }\n\n const handleBlur = (event: React.FocusEvent) => {\n const target = event.target as HTMLInputElement;\n const name = target.name;\n setFieldTouched(name, true);\n }\n\n const submit = async (e?: FormEvent<HTMLFormElement>) => {\n e?.preventDefault();\n e?.stopPropagation();\n setIsSubmitting(true);\n setSubmitCount(submitCount + 1);\n const validationErrors = await validation?.(valuesRef.current);\n if (validationErrors && Object.keys(validationErrors).length > 0) {\n setErrors(validationErrors);\n } else {\n setErrors({});\n await onSubmit?.(valuesRef.current, controllerRef.current);\n }\n setIsSubmitting(false);\n setVersion(version + 1);\n }\n\n const resetForm = (props?: FormexResetProps<T>) => {\n const {\n submitCount: submitCountProp,\n values: valuesProp,\n errors: errorsProp,\n touched: touchedProp\n } = props ?? {};\n initialValuesRef.current = valuesProp ?? initialValues;\n valuesRef.current = valuesProp ?? initialValues;\n setValuesInner(valuesProp ?? initialValues);\n setErrors(errorsProp ?? {});\n setTouchedState(touchedProp ?? {});\n setDirty(false);\n setSubmitCount(submitCountProp ?? 0);\n setVersion(version + 1);\n }\n\n const controller: FormexController<T> = {\n values,\n initialValues: initialValuesRef.current,\n handleChange,\n isSubmitting,\n setSubmitting: setIsSubmitting,\n setValues,\n setFieldValue,\n errors,\n setFieldError,\n touched: touchedState,\n setFieldTouched,\n dirty,\n setDirty,\n handleSubmit: submit,\n submitCount,\n setSubmitCount,\n handleBlur,\n validate,\n isValidating,\n resetForm,\n version\n };\n\n const controllerRef = React.useRef<FormexController<T>>(controller);\n controllerRef.current = controller;\n return controller\n}\n"],"names":["useContext","React","useState","useEffect","values"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.umd.js","sources":["../src/Formex.tsx","../src/utils.ts","../src/Field.tsx","../src/useCreateFormex.tsx"],"sourcesContent":["import React, { useContext } from \"react\";\nimport { FormexController } from \"./types\";\n\nconst FormexContext = React.createContext<FormexController<any>>({} as any);\n\nexport const useFormex = <T extends object>() => useContext<FormexController<T>>(FormexContext);\n\nexport const Formex = FormexContext.Provider;\n","import * as React from \"react\";\n\n/** @private is the value an empty array? */\nexport const isEmptyArray = (value?: any) =>\n Array.isArray(value) && value.length === 0;\n\n/** @private is the given object a Function? */\nexport const isFunction = (obj: any): obj is Function =>\n typeof obj === \"function\";\n\n/** @private is the given object an Object? */\nexport const isObject = (obj: any): obj is Object =>\n obj !== null && typeof obj === \"object\";\n\n/** @private is the given object an integer? */\nexport const isInteger = (obj: any): boolean =>\n String(Math.floor(Number(obj))) === obj;\n\n/** @private is the given object a string? */\nexport const isString = (obj: any): obj is string =>\n Object.prototype.toString.call(obj) === \"[object String]\";\n\n/** @private is the given object a NaN? */\n// eslint-disable-next-line no-self-compare\nexport const isNaN = (obj: any): boolean => obj !== obj;\n\n/** @private Does a React component have exactly 0 children? */\nexport const isEmptyChildren = (children: any): boolean =>\n React.Children.count(children) === 0;\n\n/** @private is the given object/value a promise? */\nexport const isPromise = (value: any): value is PromiseLike<any> =>\n isObject(value) && isFunction(value.then);\n\n/** @private is the given object/value a type of synthetic event? */\nexport const isInputEvent = (value: any): value is React.SyntheticEvent<any> =>\n value && isObject(value) && isObject(value.target);\n\n/**\n * Same as document.activeElement but wraps in a try-catch block. In IE it is\n * not safe to call document.activeElement if there is nothing focused.\n *\n * The activeElement will be null only if the document or document body is not\n * yet defined.\n *\n * @param {?Document} doc Defaults to current document.\n * @return {Element | null}\n * @see https://github.com/facebook/fbjs/blob/master/packages/fbjs/src/core/dom/getActiveElement.js\n */\nexport function getActiveElement(doc?: Document): Element | null {\n doc = doc || (typeof document !== \"undefined\" ? document : undefined);\n if (typeof doc === \"undefined\") {\n return null;\n }\n try {\n return doc.activeElement || doc.body;\n } catch (e) {\n return doc.body;\n }\n}\n\n/**\n * Deeply get a value from an object via its path.\n */\nexport function getIn(\n obj: any,\n key: string | string[],\n def?: any,\n p = 0\n) {\n const path = toPath(key);\n while (obj && p < path.length) {\n obj = obj[path[p++]];\n }\n\n // check if path is not in the end\n if (p !== path.length && !obj) {\n return def;\n }\n\n return obj === undefined ? def : obj;\n}\n\nexport function setIn(obj: any, path: string, value: any): any {\n const res: any = clone(obj); // this keeps inheritance when obj is a class\n let resVal: any = res;\n let i = 0;\n const pathArray = toPath(path);\n\n for (; i < pathArray.length - 1; i++) {\n const currentPath: string = pathArray[i];\n const currentObj: any = getIn(obj, pathArray.slice(0, i + 1));\n\n if (currentObj && (isObject(currentObj) || Array.isArray(currentObj))) {\n resVal = resVal[currentPath] = clone(currentObj);\n } else {\n const nextPath: string = pathArray[i + 1];\n resVal = resVal[currentPath] =\n isInteger(nextPath) && Number(nextPath) >= 0 ? [] : {};\n }\n }\n\n // Return original object if new value is the same as current\n if ((i === 0 ? obj : resVal)[pathArray[i]] === value) {\n return obj;\n }\n\n if (value === undefined) {\n delete resVal[pathArray[i]];\n } else {\n resVal[pathArray[i]] = value;\n }\n\n // If the path array has a single element, the loop did not run.\n // Deleting on `resVal` had no effect in this scenario, so we delete on the result instead.\n if (i === 0 && value === undefined) {\n delete res[pathArray[i]];\n }\n\n return res;\n}\n\n/**\n * Recursively a set the same value for all keys and arrays nested object, cloning\n * @param object\n * @param value\n * @param visited\n * @param response\n */\nexport function setNestedObjectValues<T>(\n object: any,\n value: any,\n visited: any = new WeakMap(),\n response: any = {}\n): T {\n for (const k of Object.keys(object)) {\n const val = object[k];\n if (isObject(val)) {\n if (!visited.get(val)) {\n visited.set(val, true);\n // In order to keep array values consistent for both dot path and\n // bracket syntax, we need to check if this is an array so that\n // this will output { friends: [true] } and not { friends: { \"0\": true } }\n response[k] = Array.isArray(val) ? [] : {};\n setNestedObjectValues(val, value, visited, response[k]);\n }\n } else {\n response[k] = value;\n }\n }\n\n return response;\n}\n\nexport function clone(value: any) {\n if (Array.isArray(value)) {\n return [...value];\n } else if (typeof value === \"object\" && value !== null) {\n return { ...value };\n } else {\n return value; // This is for primitive types which do not need cloning.\n }\n}\n\nfunction toPath(value: string | string[]) {\n if (Array.isArray(value)) return value; // Already in path array form.\n // Replace brackets with dots, remove leading/trailing dots, then split by dot.\n return value.replace(/\\[(\\d+)]/g, \".$1\").replace(/^\\./, \"\").replace(/\\.$/, \"\").split(\".\");\n}\n","import * as React from \"react\";\nimport { useFormex } from \"./Formex\";\nimport { getIn, isFunction, isObject } from \"./utils\";\nimport { FormexController } from \"./types\";\n\nexport interface FieldInputProps<Value> {\n /** Value of the field */\n value: Value;\n /** Name of the field */\n name: string;\n /** Multiple select? */\n multiple?: boolean;\n /** Is the field checked? */\n checked?: boolean;\n /** Change event handler */\n onChange: (event: React.SyntheticEvent) => void,\n /** Blur event handler */\n onBlur: (event: React.FocusEvent) => void,\n}\n\nexport interface FormexFieldProps<Value = any, FormValues extends object = any> {\n field: FieldInputProps<Value>;\n form: FormexController<FormValues>;\n}\n\nexport interface FieldConfig<Value, C extends React.ElementType | undefined = undefined> {\n\n /**\n * Component to render. Can either be a string e.g. 'select', 'input', or 'textarea', or a component.\n */\n as?:\n | C\n | string\n | React.ForwardRefExoticComponent<any>;\n\n /**\n * Children render function <Field name>{props => ...}</Field>)\n */\n children?: ((props: FormexFieldProps<Value>) => React.ReactNode) | React.ReactNode;\n\n /**\n * Validate a single field value independently\n */\n // validate?: FieldValidator;\n\n /**\n * Used for 'select' and related input types.\n */\n multiple?: boolean;\n\n /**\n * Field name\n */\n name: string;\n\n /** HTML input type */\n type?: string;\n\n /** Field value */\n value?: any;\n\n /** Inner ref */\n innerRef?: (instance: any) => void;\n\n}\n\nexport type FieldProps<T, C extends React.ElementType | undefined> = {\n as?: C;\n} & (C extends React.ElementType ? (React.ComponentProps<C> & FieldConfig<T, C>) : FieldConfig<T, C>);\n\nexport function Field<T, C extends React.ElementType | undefined = undefined>({\n validate,\n name,\n children,\n as: is, // `as` is reserved in typescript lol\n // component,\n className,\n ...props\n }: FieldProps<T, C>) {\n const formex = useFormex();\n\n const field = getFieldProps({ name, ...props }, formex);\n\n if (isFunction(children)) {\n return children({ field, form: formex });\n }\n\n // if (component) {\n // if (typeof component === \"string\") {\n // const { innerRef, ...rest } = props;\n // return React.createElement(\n // component,\n // { ref: innerRef, ...field, ...rest, className },\n // children\n // );\n // }\n // return React.createElement(\n // component,\n // { field, form: formex, ...props, className },\n // children\n // );\n // }\n\n // default to input here so we can check for both `as` and `children` above\n const asElement = is || \"input\";\n\n if (typeof asElement === \"string\") {\n const { innerRef, ...rest } = props;\n return React.createElement(\n asElement,\n { ref: innerRef, ...field, ...rest, className },\n children\n );\n }\n\n return React.createElement(asElement, { ...field, ...props, className }, children);\n}\n\nconst getFieldProps = (nameOrOptions: string | FieldConfig<any>, formex: FormexController<any>): FieldInputProps<any> => {\n const isAnObject = isObject(nameOrOptions);\n const name = isAnObject\n ? (nameOrOptions as FieldConfig<any>).name\n : nameOrOptions;\n const valueState = getIn(formex.values, name);\n\n const field: FieldInputProps<any> = {\n name,\n value: valueState,\n onChange: formex.handleChange,\n onBlur: formex.handleBlur,\n };\n if (isAnObject) {\n const {\n type,\n value: valueProp, // value is special for checkboxes\n as: is,\n multiple,\n } = nameOrOptions as FieldConfig<any>;\n\n if (type === \"checkbox\") {\n if (valueProp === undefined) {\n field.checked = !!valueState;\n } else {\n field.checked = !!(\n Array.isArray(valueState) && ~valueState.indexOf(valueProp)\n );\n field.value = valueProp;\n }\n } else if (type === \"radio\") {\n field.checked = valueState === valueProp;\n field.value = valueProp;\n } else if (is === \"select\" && multiple) {\n field.value = field.value || [];\n field.multiple = true;\n }\n }\n return field;\n};\n","import React, { FormEvent, useEffect, useState } from \"react\";\nimport { getIn, setIn } from \"./utils\";\nimport equal from \"react-fast-compare\"\n\nimport { FormexController, FormexResetProps } from \"./types\";\n\nexport function useCreateFormex<T extends object>({\n initialValues,\n initialErrors,\n validation,\n validateOnChange = false,\n onSubmit,\n validateOnInitialRender = false,\n debugId\n }: {\n initialValues: T,\n initialErrors?: Record<string, string>,\n validateOnChange?: boolean,\n validateOnInitialRender?: boolean,\n validation?: (values: T) => Record<string, string> | Promise<Record<string, string>> | undefined | void,\n onSubmit?: (values: T, controller: FormexController<T>) => void | Promise<void>,\n debugId?: string\n}): FormexController<T> {\n\n const initialValuesRef = React.useRef<T>(initialValues);\n const valuesRef = React.useRef<T>(initialValues);\n const debugIdRef = React.useRef<string | undefined>(debugId);\n\n const [values, setValuesInner] = useState<T>(initialValues);\n const [touchedState, setTouchedState] = useState<Record<string, boolean>>({});\n const [errors, setErrors] = useState<Record<string, string>>(initialErrors ?? {});\n const [dirty, setDirty] = useState(false);\n const [submitCount, setSubmitCount] = useState(0);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [isValidating, setIsValidating] = useState(false);\n const [version, setVersion] = useState(0);\n\n useEffect(() => {\n if (validateOnInitialRender) {\n validate();\n }\n }, []);\n\n const setValues = (newValues: T) => {\n valuesRef.current = newValues;\n setValuesInner(newValues);\n setDirty(equal(initialValuesRef.current, newValues));\n }\n\n const validate = async () => {\n setIsValidating(true);\n const validationErrors = await validation?.(valuesRef.current);\n setErrors(validationErrors ?? {});\n setIsValidating(false);\n return validationErrors;\n }\n\n const setFieldValue = (key: string, value: any, shouldValidate?: boolean) => {\n const newValues = setIn(valuesRef.current, key, value);\n valuesRef.current = newValues;\n setValuesInner(newValues);\n if (!equal(getIn(initialValuesRef.current, key), value)) {\n setDirty(true);\n }\n if (shouldValidate) {\n validate();\n }\n }\n\n const setFieldError = (key: string, error: string | undefined) => {\n const newErrors = { ...errors };\n if (error) {\n newErrors[key] = error;\n } else {\n delete newErrors[key];\n }\n setErrors(newErrors);\n }\n\n const setFieldTouched = (key: string, touched: boolean, shouldValidate?: boolean | undefined) => {\n const newTouched = { ...touchedState };\n newTouched[key] = touched;\n setTouchedState(newTouched);\n if (shouldValidate) {\n validate();\n }\n }\n\n const handleChange = (event: React.SyntheticEvent) => {\n const target = event.target as HTMLInputElement;\n let value;\n if (target.type === \"checkbox\") {\n value = target.checked;\n } else if (target.type === \"number\") {\n value = target.valueAsNumber;\n } else {\n value = target.value;\n }\n const name = target.name;\n setFieldValue(name, value, validateOnChange);\n setFieldTouched(name, true);\n }\n\n const handleBlur = (event: React.FocusEvent) => {\n const target = event.target as HTMLInputElement;\n const name = target.name;\n setFieldTouched(name, true);\n }\n\n const submit = async (e?: FormEvent<HTMLFormElement>) => {\n e?.preventDefault();\n e?.stopPropagation();\n setIsSubmitting(true);\n setSubmitCount(submitCount + 1);\n const validationErrors = await validation?.(valuesRef.current);\n if (validationErrors && Object.keys(validationErrors).length > 0) {\n setErrors(validationErrors);\n } else {\n setErrors({});\n await onSubmit?.(valuesRef.current, controllerRef.current);\n }\n setIsSubmitting(false);\n setVersion(version + 1);\n }\n\n const resetForm = (props?: FormexResetProps<T>) => {\n const {\n submitCount: submitCountProp,\n values: valuesProp,\n errors: errorsProp,\n touched: touchedProp\n } = props ?? {};\n initialValuesRef.current = valuesProp ?? initialValues;\n valuesRef.current = valuesProp ?? initialValues;\n setValuesInner(valuesProp ?? initialValues);\n setErrors(errorsProp ?? {});\n setTouchedState(touchedProp ?? {});\n setDirty(false);\n setSubmitCount(submitCountProp ?? 0);\n setVersion(version + 1);\n }\n\n const controller: FormexController<T> = {\n values,\n initialValues: initialValuesRef.current,\n handleChange,\n isSubmitting,\n setSubmitting: setIsSubmitting,\n setValues,\n setFieldValue,\n errors,\n setFieldError,\n touched: touchedState,\n setFieldTouched,\n dirty,\n setDirty,\n handleSubmit: submit,\n submitCount,\n setSubmitCount,\n handleBlur,\n validate,\n isValidating,\n resetForm,\n version,\n debugId: debugIdRef.current\n };\n\n const controllerRef = React.useRef<FormexController<T>>(controller);\n controllerRef.current = controller;\n return controller\n}\n"],"names":["FormexContext","React","createContext","useFormex","useContext","Formex","Provider","isEmptyArray","value","Array","isArray","length","isFunction","obj","isObject","isInteger","String","Math","floor","Number","isString","Object","prototype","toString","call","isNaN","isEmptyChildren","children","Children","count","isPromise","then","isInputEvent","target","getActiveElement","doc","document","undefined","activeElement","body","e","getIn","key","def","p","path","toPath","setIn","res","clone","resVal","i","pathArray","currentPath","currentObj","slice","nextPath","setNestedObjectValues","object","visited","WeakMap","response","k","keys","val","get","set","replace","split","Field","t0","$","_c","className","is","name","props","validate","t1","t2","as","t3","t4","t5","formex","field","Symbol","for","getFieldProps","form","bb0","asElement","innerRef","rest","ref","createElement","nameOrOptions","isAnObject","valueState","values","onChange","handleChange","onBlur","handleBlur","type","valueProp","multiple","checked","indexOf","useCreateFormex","initialValues","initialErrors","validation","validateOnChange","onSubmit","validateOnInitialRender","debugId","initialValuesRef","useRef","valuesRef","debugIdRef","setValuesInner","useState","touchedState","setTouchedState","errors","setErrors","dirty","setDirty","submitCount","setSubmitCount","isSubmitting","setIsSubmitting","isValidating","setIsValidating","version","setVersion","useEffect","setValues","newValues","current","equal","validationErrors","setFieldValue","shouldValidate","setFieldError","error","newErrors","setFieldTouched","touched","newTouched","event","valueAsNumber","submit","preventDefault","stopPropagation","controllerRef","resetForm","submitCountProp","valuesProp","errorsProp","touchedProp","controller","setSubmitting","handleSubmit"],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { FormexController } from "./types";
|
|
2
|
-
export declare function useCreateFormex<T extends object>({ initialValues, initialErrors, validation, validateOnChange, onSubmit, validateOnInitialRender }: {
|
|
2
|
+
export declare function useCreateFormex<T extends object>({ initialValues, initialErrors, validation, validateOnChange, onSubmit, validateOnInitialRender, debugId }: {
|
|
3
3
|
initialValues: T;
|
|
4
4
|
initialErrors?: Record<string, string>;
|
|
5
5
|
validateOnChange?: boolean;
|
|
6
6
|
validateOnInitialRender?: boolean;
|
|
7
7
|
validation?: (values: T) => Record<string, string> | Promise<Record<string, string>> | undefined | void;
|
|
8
8
|
onSubmit?: (values: T, controller: FormexController<T>) => void | Promise<void>;
|
|
9
|
+
debugId?: string;
|
|
9
10
|
}): FormexController<T>;
|
package/dist/utils.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@firecms/formex",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.0.0-beta.
|
|
4
|
+
"version": "3.0.0-beta.11",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -37,14 +37,16 @@
|
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@jest/globals": "^29.7.0",
|
|
40
|
-
"@types/jest": "^29.5.
|
|
41
|
-
"@types/node": "^20.
|
|
40
|
+
"@types/jest": "^29.5.14",
|
|
41
|
+
"@types/node": "^20.17.9",
|
|
42
42
|
"@types/react": "^18.3.11",
|
|
43
|
-
"@types/react-dom": "^18.3.
|
|
43
|
+
"@types/react-dom": "^18.3.1",
|
|
44
|
+
"babel-plugin-react-compiler": "beta",
|
|
45
|
+
"eslint-plugin-react-compiler": "beta",
|
|
44
46
|
"jest": "^29.7.0",
|
|
45
47
|
"ts-jest": "^29.2.5",
|
|
46
|
-
"typescript": "^5.
|
|
47
|
-
"vite": "^5.4.
|
|
48
|
+
"typescript": "^5.7.2",
|
|
49
|
+
"vite": "^5.4.11"
|
|
48
50
|
},
|
|
49
51
|
"scripts": {
|
|
50
52
|
"dev": "vite",
|
|
@@ -72,5 +74,5 @@
|
|
|
72
74
|
"node"
|
|
73
75
|
]
|
|
74
76
|
},
|
|
75
|
-
"gitHead": "
|
|
77
|
+
"gitHead": "cb6d419faf2664cfd6cb2603a834e4bf499a92bb"
|
|
76
78
|
}
|
package/src/types.ts
CHANGED
package/src/useCreateFormex.tsx
CHANGED
|
@@ -10,18 +10,21 @@ export function useCreateFormex<T extends object>({
|
|
|
10
10
|
validation,
|
|
11
11
|
validateOnChange = false,
|
|
12
12
|
onSubmit,
|
|
13
|
-
validateOnInitialRender = false
|
|
13
|
+
validateOnInitialRender = false,
|
|
14
|
+
debugId
|
|
14
15
|
}: {
|
|
15
16
|
initialValues: T,
|
|
16
17
|
initialErrors?: Record<string, string>,
|
|
17
18
|
validateOnChange?: boolean,
|
|
18
19
|
validateOnInitialRender?: boolean,
|
|
19
20
|
validation?: (values: T) => Record<string, string> | Promise<Record<string, string>> | undefined | void,
|
|
20
|
-
onSubmit?: (values: T, controller: FormexController<T>) => void | Promise<void
|
|
21
|
+
onSubmit?: (values: T, controller: FormexController<T>) => void | Promise<void>,
|
|
22
|
+
debugId?: string
|
|
21
23
|
}): FormexController<T> {
|
|
22
24
|
|
|
23
25
|
const initialValuesRef = React.useRef<T>(initialValues);
|
|
24
26
|
const valuesRef = React.useRef<T>(initialValues);
|
|
27
|
+
const debugIdRef = React.useRef<string | undefined>(debugId);
|
|
25
28
|
|
|
26
29
|
const [values, setValuesInner] = useState<T>(initialValues);
|
|
27
30
|
const [touchedState, setTouchedState] = useState<Record<string, boolean>>({});
|
|
@@ -46,8 +49,7 @@ export function useCreateFormex<T extends object>({
|
|
|
46
49
|
|
|
47
50
|
const validate = async () => {
|
|
48
51
|
setIsValidating(true);
|
|
49
|
-
const
|
|
50
|
-
const validationErrors = await validation?.(values);
|
|
52
|
+
const validationErrors = await validation?.(valuesRef.current);
|
|
51
53
|
setErrors(validationErrors ?? {});
|
|
52
54
|
setIsValidating(false);
|
|
53
55
|
return validationErrors;
|
|
@@ -159,7 +161,8 @@ export function useCreateFormex<T extends object>({
|
|
|
159
161
|
validate,
|
|
160
162
|
isValidating,
|
|
161
163
|
resetForm,
|
|
162
|
-
version
|
|
164
|
+
version,
|
|
165
|
+
debugId: debugIdRef.current
|
|
163
166
|
};
|
|
164
167
|
|
|
165
168
|
const controllerRef = React.useRef<FormexController<T>>(controller);
|
package/src/utils.ts
CHANGED
|
@@ -152,7 +152,7 @@ export function setNestedObjectValues<T>(
|
|
|
152
152
|
return response;
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
-
function clone(value: any) {
|
|
155
|
+
export function clone(value: any) {
|
|
156
156
|
if (Array.isArray(value)) {
|
|
157
157
|
return [...value];
|
|
158
158
|
} else if (typeof value === "object" && value !== null) {
|