@firecms/formex 3.0.0-canary.283 → 3.0.0-canary.285
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 +45 -8
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +44 -7
- package/dist/index.umd.js.map +1 -1
- package/dist/useCreateFormex.d.ts +3 -1
- package/dist/utils.d.ts +1 -0
- package/package.json +2 -2
- package/src/useCreateFormex.tsx +32 -7
- package/src/utils.ts +20 -0
package/dist/index.es.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { c } from "react-compiler-runtime";
|
|
2
2
|
import * as React from "react";
|
|
3
|
-
import React__default, { useContext, useRef, useState,
|
|
3
|
+
import React__default, { useContext, useRef, useState, useCallback, useEffect, useMemo } from "react";
|
|
4
4
|
import equal from "react-fast-compare";
|
|
5
5
|
const FormexContext = React__default.createContext({});
|
|
6
6
|
const useFormex = () => {
|
|
@@ -65,6 +65,21 @@ function toPath(value) {
|
|
|
65
65
|
if (Array.isArray(value)) return value;
|
|
66
66
|
return value.replace(/\[(\d+)]/g, ".$1").replace(/^\./, "").replace(/\.$/, "").split(".");
|
|
67
67
|
}
|
|
68
|
+
function flattenKeys(obj, prefix = "", result = []) {
|
|
69
|
+
if (isObject(obj) || Array.isArray(obj)) {
|
|
70
|
+
for (const key in obj) {
|
|
71
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
72
|
+
const newKey = prefix ? Array.isArray(obj) ? `${prefix}[${key}]` : `${prefix}.${key}` : key;
|
|
73
|
+
if (isObject(obj[key]) || Array.isArray(obj[key])) {
|
|
74
|
+
flattenKeys(obj[key], newKey, result);
|
|
75
|
+
} else {
|
|
76
|
+
result.push(newKey);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
68
83
|
function Field(t0) {
|
|
69
84
|
const $ = c(37);
|
|
70
85
|
let children;
|
|
@@ -244,24 +259,39 @@ function useCreateFormex({
|
|
|
244
259
|
initialValues,
|
|
245
260
|
initialErrors,
|
|
246
261
|
initialDirty,
|
|
262
|
+
initialTouched,
|
|
247
263
|
validation,
|
|
248
264
|
validateOnChange = false,
|
|
249
265
|
validateOnInitialRender = false,
|
|
250
266
|
onSubmit,
|
|
251
267
|
onReset,
|
|
268
|
+
onValuesChangeDeferred,
|
|
252
269
|
debugId
|
|
253
270
|
}) {
|
|
254
271
|
const initialValuesRef = useRef(initialValues);
|
|
255
272
|
const valuesRef = useRef(initialValues);
|
|
256
273
|
const debugIdRef = useRef(debugId);
|
|
257
274
|
const [values, setValuesInner] = useState(initialValues);
|
|
258
|
-
const [touchedState, setTouchedState] = useState({});
|
|
275
|
+
const [touchedState, setTouchedState] = useState(initialTouched ?? {});
|
|
259
276
|
const [errors, setErrors] = useState(initialErrors ?? {});
|
|
260
277
|
const [dirty, setDirty] = useState(initialDirty ?? false);
|
|
261
278
|
const [submitCount, setSubmitCount] = useState(0);
|
|
262
279
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
263
280
|
const [isValidating, setIsValidating] = useState(false);
|
|
264
281
|
const [version, setVersion] = useState(0);
|
|
282
|
+
const onValuesChangeRef = useRef(onValuesChangeDeferred);
|
|
283
|
+
onValuesChangeRef.current = onValuesChangeDeferred;
|
|
284
|
+
const debounceTimeoutRef = useRef();
|
|
285
|
+
const callDebouncedOnValuesChange = useCallback((values_0) => {
|
|
286
|
+
if (onValuesChangeRef.current) {
|
|
287
|
+
if (debounceTimeoutRef.current) {
|
|
288
|
+
clearTimeout(debounceTimeoutRef.current);
|
|
289
|
+
}
|
|
290
|
+
debounceTimeoutRef.current = setTimeout(() => {
|
|
291
|
+
onValuesChangeRef.current?.(values_0, controllerRef.current);
|
|
292
|
+
}, 300);
|
|
293
|
+
}
|
|
294
|
+
}, []);
|
|
265
295
|
const historyRef = useRef([initialValues]);
|
|
266
296
|
const historyIndexRef = useRef(0);
|
|
267
297
|
useEffect(() => {
|
|
@@ -277,7 +307,8 @@ function useCreateFormex({
|
|
|
277
307
|
newHistory.push(newValues);
|
|
278
308
|
historyRef.current = newHistory;
|
|
279
309
|
historyIndexRef.current = newHistory.length - 1;
|
|
280
|
-
|
|
310
|
+
callDebouncedOnValuesChange(newValues);
|
|
311
|
+
}, [callDebouncedOnValuesChange]);
|
|
281
312
|
const validate = useCallback(async () => {
|
|
282
313
|
setIsValidating(true);
|
|
283
314
|
const validationErrors = await validation?.(valuesRef.current);
|
|
@@ -299,7 +330,8 @@ function useCreateFormex({
|
|
|
299
330
|
newHistory_0.push(newValues_0);
|
|
300
331
|
historyRef.current = newHistory_0;
|
|
301
332
|
historyIndexRef.current = newHistory_0.length - 1;
|
|
302
|
-
|
|
333
|
+
callDebouncedOnValuesChange(newValues_0);
|
|
334
|
+
}, [validate, callDebouncedOnValuesChange]);
|
|
303
335
|
const setFieldError = useCallback((key_0, error) => {
|
|
304
336
|
setErrors((prevErrors) => {
|
|
305
337
|
const newErrors = {
|
|
@@ -367,14 +399,14 @@ function useCreateFormex({
|
|
|
367
399
|
initialValuesRef.current = valuesProp ?? initialValuesRef.current;
|
|
368
400
|
setValuesInner(valuesProp ?? initialValuesRef.current);
|
|
369
401
|
setErrors(errorsProp ?? {});
|
|
370
|
-
setTouchedState(touchedProp ?? {});
|
|
402
|
+
setTouchedState(touchedProp ?? initialTouched ?? {});
|
|
371
403
|
setDirty(false);
|
|
372
404
|
setSubmitCount(submitCountProp ?? 0);
|
|
373
405
|
setVersion((prev_2) => prev_2 + 1);
|
|
374
406
|
onReset?.(controllerRef.current);
|
|
375
407
|
historyRef.current = [valuesProp ?? initialValuesRef.current];
|
|
376
408
|
historyIndexRef.current = 0;
|
|
377
|
-
}, [onReset]);
|
|
409
|
+
}, [onReset, initialTouched]);
|
|
378
410
|
const undo = useCallback(() => {
|
|
379
411
|
if (historyIndexRef.current > 0) {
|
|
380
412
|
const newIndex = historyIndexRef.current - 1;
|
|
@@ -382,8 +414,10 @@ function useCreateFormex({
|
|
|
382
414
|
setValuesInner(newValues_1);
|
|
383
415
|
valuesRef.current = newValues_1;
|
|
384
416
|
historyIndexRef.current = newIndex;
|
|
417
|
+
setDirty(!equal(initialValuesRef.current, newValues_1));
|
|
418
|
+
callDebouncedOnValuesChange(newValues_1);
|
|
385
419
|
}
|
|
386
|
-
}, []);
|
|
420
|
+
}, [callDebouncedOnValuesChange]);
|
|
387
421
|
const redo = useCallback(() => {
|
|
388
422
|
if (historyIndexRef.current < historyRef.current.length - 1) {
|
|
389
423
|
const newIndex_0 = historyIndexRef.current + 1;
|
|
@@ -391,8 +425,10 @@ function useCreateFormex({
|
|
|
391
425
|
setValuesInner(newValues_2);
|
|
392
426
|
valuesRef.current = newValues_2;
|
|
393
427
|
historyIndexRef.current = newIndex_0;
|
|
428
|
+
setDirty(!equal(initialValuesRef.current, newValues_2));
|
|
429
|
+
callDebouncedOnValuesChange(newValues_2);
|
|
394
430
|
}
|
|
395
|
-
}, []);
|
|
431
|
+
}, [callDebouncedOnValuesChange]);
|
|
396
432
|
const controllerRef = useRef({});
|
|
397
433
|
const controller = useMemo(() => ({
|
|
398
434
|
values,
|
|
@@ -431,6 +467,7 @@ export {
|
|
|
431
467
|
Field,
|
|
432
468
|
Formex,
|
|
433
469
|
clone,
|
|
470
|
+
flattenKeys,
|
|
434
471
|
getIn,
|
|
435
472
|
isEmptyArray,
|
|
436
473
|
isFunction,
|
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","/** @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 NaN? */\n// eslint-disable-next-line no-self-compare\nexport const isNaN = (obj: any): boolean => obj !== obj;\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\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, { useCallback, useEffect, useMemo, useRef, 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 initialDirty,\n validation,\n validateOnChange = false,\n validateOnInitialRender = false,\n onSubmit,\n onReset,\n debugId,\n }: {\n initialValues: T;\n initialErrors?: Record<string, string>;\n initialDirty?: boolean;\n validateOnChange?: boolean;\n validateOnInitialRender?: boolean;\n validation?: (\n values: T\n ) =>\n | Record<string, string>\n | Promise<Record<string, string>>\n | undefined\n | void;\n onSubmit?: (values: T, controller: FormexController<T>) => void | Promise<void>;\n onReset?: (controller: FormexController<T>) => void | Promise<void>;\n debugId?: string;\n}): FormexController<T> {\n const initialValuesRef = useRef<T>(initialValues);\n const valuesRef = useRef<T>(initialValues);\n const debugIdRef = 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(initialDirty ?? 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 // Replace state for history with refs\n const historyRef = useRef<T[]>([initialValues]);\n const historyIndexRef = useRef<number>(0);\n\n useEffect(() => {\n if (validateOnInitialRender) {\n validate();\n }\n }, []);\n\n const setValues = useCallback((newValues: T) => {\n valuesRef.current = newValues;\n setValuesInner(newValues);\n setDirty(!equal(initialValuesRef.current, newValues));\n // Update history using refs\n const newHistory = historyRef.current.slice(0, historyIndexRef.current + 1);\n newHistory.push(newValues);\n historyRef.current = newHistory;\n historyIndexRef.current = newHistory.length - 1;\n }, []);\n\n const validate = useCallback(async () => {\n setIsValidating(true);\n const validationErrors = await validation?.(valuesRef.current);\n setErrors(validationErrors ?? {});\n setIsValidating(false);\n return validationErrors;\n }, [validation]);\n\n const setFieldValue = useCallback(\n (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 // Update history using refs\n const newHistory = historyRef.current.slice(0, historyIndexRef.current + 1);\n newHistory.push(newValues);\n historyRef.current = newHistory;\n historyIndexRef.current = newHistory.length - 1;\n },\n [validate]\n );\n\n const setFieldError = useCallback((key: string, error: string | undefined) => {\n setErrors((prevErrors) => {\n const newErrors = { ...prevErrors };\n if (error) {\n newErrors[key] = error;\n } else {\n delete newErrors[key];\n }\n return newErrors;\n });\n }, []);\n\n const setFieldTouched = useCallback(\n (key: string, touched: boolean, shouldValidate?: boolean) => {\n setTouchedState((prev) => ({\n ...prev,\n [key]: touched,\n }));\n if (shouldValidate) {\n validate();\n }\n },\n [validate]\n );\n\n const handleChange = useCallback(\n (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 [setFieldValue, setFieldTouched, validateOnChange]\n );\n\n const handleBlur = useCallback((event: React.FocusEvent) => {\n const target = event.target as HTMLInputElement;\n const name = target.name;\n setFieldTouched(name, true);\n }, [setFieldTouched]);\n\n const submit = useCallback(\n async (e?: React.FormEvent<HTMLFormElement>) => {\n e?.preventDefault();\n e?.stopPropagation();\n setIsSubmitting(true);\n setSubmitCount((prev) => prev + 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((prev) => prev + 1);\n },\n [onSubmit, validation]\n );\n\n const resetForm = useCallback((props?: FormexResetProps<T>) => {\n const {\n submitCount: submitCountProp,\n values: valuesProp,\n errors: errorsProp,\n touched: touchedProp\n } = props ?? {};\n valuesRef.current = valuesProp ?? initialValuesRef.current;\n initialValuesRef.current = valuesProp ?? initialValuesRef.current;\n setValuesInner(valuesProp ?? initialValuesRef.current);\n setErrors(errorsProp ?? {});\n setTouchedState(touchedProp ?? {});\n setDirty(false);\n setSubmitCount(submitCountProp ?? 0);\n setVersion((prev) => prev + 1);\n onReset?.(controllerRef.current);\n // Reset history with refs\n historyRef.current = [valuesProp ?? initialValuesRef.current];\n historyIndexRef.current = 0;\n }, [onReset]);\n\n const undo = useCallback(() => {\n if (historyIndexRef.current > 0) {\n const newIndex = historyIndexRef.current - 1;\n const newValues = historyRef.current[newIndex];\n setValuesInner(newValues);\n valuesRef.current = newValues;\n historyIndexRef.current = newIndex;\n }\n }, []);\n\n const redo = useCallback(() => {\n if (historyIndexRef.current < historyRef.current.length - 1) {\n const newIndex = historyIndexRef.current + 1;\n const newValues = historyRef.current[newIndex];\n setValuesInner(newValues);\n valuesRef.current = newValues;\n historyIndexRef.current = newIndex;\n }\n }, []);\n\n const controllerRef = useRef<FormexController<T>>({} as FormexController<T>);\n\n const controller = useMemo<FormexController<T>>(\n () => ({\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 undo,\n redo,\n canUndo: historyIndexRef.current > 0,\n canRedo: historyIndexRef.current < historyRef.current.length - 1,\n }),\n [\n values,\n errors,\n touchedState,\n dirty,\n isSubmitting,\n submitCount,\n isValidating,\n version,\n handleChange,\n handleBlur,\n setValues,\n setFieldValue,\n setFieldTouched,\n setFieldError,\n validate,\n submit,\n resetForm,\n undo,\n redo,\n ]\n );\n\n useEffect(() => {\n controllerRef.current = controller;\n }, [controller]);\n\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","isNaN","getIn","key","def","p","path","toPath","undefined","setIn","res","clone","resVal","i","pathArray","currentPath","currentObj","slice","nextPath","replace","split","Field","t0","$","_c","children","className","is","name","props","validate","t1","t2","as","t3","t4","t5","formex","field","Symbol","for","bb0","getFieldProps","form","asElement","innerRef","rest","ref","createElement","nameOrOptions","isAnObject","valueState","values","onChange","handleChange","onBlur","handleBlur","type","valueProp","multiple","checked","indexOf","useCreateFormex","initialValues","initialErrors","initialDirty","validation","validateOnChange","validateOnInitialRender","onSubmit","onReset","debugId","initialValuesRef","useRef","valuesRef","debugIdRef","setValuesInner","useState","touchedState","setTouchedState","errors","setErrors","dirty","setDirty","submitCount","setSubmitCount","isSubmitting","setIsSubmitting","isValidating","setIsValidating","version","setVersion","historyRef","historyIndexRef","useEffect","setValues","useCallback","newValues","current","equal","newHistory","push","validationErrors","setFieldValue","shouldValidate","setFieldError","error","prevErrors","newErrors","setFieldTouched","touched","prev","event","target","valueAsNumber","submit","e","preventDefault","stopPropagation","Object","keys","controllerRef","resetForm","submitCountProp","valuesProp","errorsProp","touchedProp","undo","newIndex","redo","controller","useMemo","setSubmitting","handleSubmit","canUndo","canRedo"],"mappings":"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"}
|
|
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","/** @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 NaN? */\n// eslint-disable-next-line no-self-compare\nexport const isNaN = (obj: any): boolean => obj !== obj;\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\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\nexport function flattenKeys(obj: any, prefix = \"\", result: string[] = []): string[] {\n if (isObject(obj) || Array.isArray(obj)) {\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n const newKey = prefix\n ? Array.isArray(obj)\n ? `${prefix}[${key}]`\n : `${prefix}.${key}`\n : key;\n if (isObject(obj[key]) || Array.isArray(obj[key])) {\n flattenKeys(obj[key], newKey, result);\n } else {\n result.push(newKey);\n }\n }\n }\n }\n return result;\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, { useCallback, useEffect, useMemo, useRef, 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 initialDirty,\n initialTouched,\n validation,\n validateOnChange = false,\n validateOnInitialRender = false,\n onSubmit,\n onReset,\n onValuesChangeDeferred,\n debugId,\n }: {\n initialValues: T;\n initialErrors?: Record<string, string>;\n initialDirty?: boolean;\n initialTouched?: Record<string, boolean>;\n validateOnChange?: boolean;\n validateOnInitialRender?: boolean;\n validation?: (\n values: T\n ) =>\n | Record<string, string>\n | Promise<Record<string, string>>\n | undefined\n | void;\n onValuesChangeDeferred?: (values: T, controller: FormexController<T>) => void;\n onSubmit?: (values: T, controller: FormexController<T>) => void | Promise<void>;\n onReset?: (controller: FormexController<T>) => void | Promise<void>;\n debugId?: string;\n}): FormexController<T> {\n const initialValuesRef = useRef<T>(initialValues);\n const valuesRef = useRef<T>(initialValues);\n const debugIdRef = useRef<string | undefined>(debugId);\n\n const [values, setValuesInner] = useState<T>(initialValues);\n const [touchedState, setTouchedState] = useState<Record<string, boolean>>(initialTouched ?? {});\n const [errors, setErrors] = useState<Record<string, string>>(initialErrors ?? {});\n const [dirty, setDirty] = useState(initialDirty ?? 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 const onValuesChangeRef = useRef(onValuesChangeDeferred);\n onValuesChangeRef.current = onValuesChangeDeferred;\n const debounceTimeoutRef = useRef<any>();\n\n const callDebouncedOnValuesChange = useCallback((values: T) => {\n if (onValuesChangeRef.current) {\n if (debounceTimeoutRef.current) {\n clearTimeout(debounceTimeoutRef.current);\n }\n debounceTimeoutRef.current = setTimeout(() => {\n onValuesChangeRef.current?.(values, controllerRef.current);\n }, 300);\n }\n }, []);\n\n // Replace state for history with refs\n const historyRef = useRef<T[]>([initialValues]);\n const historyIndexRef = useRef<number>(0);\n\n useEffect(() => {\n if (validateOnInitialRender) {\n validate();\n }\n }, []);\n\n const setValues = useCallback((newValues: T) => {\n valuesRef.current = newValues;\n setValuesInner(newValues);\n setDirty(!equal(initialValuesRef.current, newValues));\n // Update history using refs\n const newHistory = historyRef.current.slice(0, historyIndexRef.current + 1);\n newHistory.push(newValues);\n historyRef.current = newHistory;\n historyIndexRef.current = newHistory.length - 1;\n callDebouncedOnValuesChange(newValues);\n }, [callDebouncedOnValuesChange]);\n\n const validate = useCallback(async () => {\n setIsValidating(true);\n const validationErrors = await validation?.(valuesRef.current);\n setErrors(validationErrors ?? {});\n setIsValidating(false);\n return validationErrors;\n }, [validation]);\n\n const setFieldValue = useCallback(\n (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 // Update history using refs\n const newHistory = historyRef.current.slice(0, historyIndexRef.current + 1);\n newHistory.push(newValues);\n historyRef.current = newHistory;\n historyIndexRef.current = newHistory.length - 1;\n callDebouncedOnValuesChange(newValues);\n },\n [validate, callDebouncedOnValuesChange]\n );\n\n const setFieldError = useCallback((key: string, error: string | undefined) => {\n setErrors((prevErrors) => {\n const newErrors = { ...prevErrors };\n if (error) {\n newErrors[key] = error;\n } else {\n delete newErrors[key];\n }\n return newErrors;\n });\n }, []);\n\n const setFieldTouched = useCallback(\n (key: string, touched: boolean, shouldValidate?: boolean) => {\n setTouchedState((prev) => ({\n ...prev,\n [key]: touched,\n }));\n if (shouldValidate) {\n validate();\n }\n },\n [validate]\n );\n\n const handleChange = useCallback(\n (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 [setFieldValue, setFieldTouched, validateOnChange]\n );\n\n const handleBlur = useCallback((event: React.FocusEvent) => {\n const target = event.target as HTMLInputElement;\n const name = target.name;\n setFieldTouched(name, true);\n }, [setFieldTouched]);\n\n const submit = useCallback(\n async (e?: React.FormEvent<HTMLFormElement>) => {\n e?.preventDefault();\n e?.stopPropagation();\n setIsSubmitting(true);\n setSubmitCount((prev) => prev + 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((prev) => prev + 1);\n },\n [onSubmit, validation]\n );\n\n const resetForm = useCallback((props?: FormexResetProps<T>) => {\n const {\n submitCount: submitCountProp,\n values: valuesProp,\n errors: errorsProp,\n touched: touchedProp\n } = props ?? {};\n valuesRef.current = valuesProp ?? initialValuesRef.current;\n initialValuesRef.current = valuesProp ?? initialValuesRef.current;\n setValuesInner(valuesProp ?? initialValuesRef.current);\n setErrors(errorsProp ?? {});\n setTouchedState(touchedProp ?? initialTouched ?? {});\n setDirty(false);\n setSubmitCount(submitCountProp ?? 0);\n setVersion((prev) => prev + 1);\n onReset?.(controllerRef.current);\n // Reset history with refs\n historyRef.current = [valuesProp ?? initialValuesRef.current];\n historyIndexRef.current = 0;\n }, [onReset, initialTouched]);\n\n const undo = useCallback(() => {\n if (historyIndexRef.current > 0) {\n const newIndex = historyIndexRef.current - 1;\n const newValues = historyRef.current[newIndex];\n setValuesInner(newValues);\n valuesRef.current = newValues;\n historyIndexRef.current = newIndex;\n setDirty(!equal(initialValuesRef.current, newValues));\n callDebouncedOnValuesChange(newValues);\n }\n }, [callDebouncedOnValuesChange]);\n\n const redo = useCallback(() => {\n if (historyIndexRef.current < historyRef.current.length - 1) {\n const newIndex = historyIndexRef.current + 1;\n const newValues = historyRef.current[newIndex];\n setValuesInner(newValues);\n valuesRef.current = newValues;\n historyIndexRef.current = newIndex;\n setDirty(!equal(initialValuesRef.current, newValues));\n callDebouncedOnValuesChange(newValues);\n }\n }, [callDebouncedOnValuesChange]);\n\n const controllerRef = useRef<FormexController<T>>({} as FormexController<T>);\n\n const controller = useMemo<FormexController<T>>(\n () => ({\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 undo,\n redo,\n canUndo: historyIndexRef.current > 0,\n canRedo: historyIndexRef.current < historyRef.current.length - 1,\n }),\n [\n values,\n errors,\n touchedState,\n dirty,\n isSubmitting,\n submitCount,\n isValidating,\n version,\n handleChange,\n handleBlur,\n setValues,\n setFieldValue,\n setFieldTouched,\n setFieldError,\n validate,\n submit,\n resetForm,\n undo,\n redo,\n ]\n );\n\n useEffect(() => {\n controllerRef.current = controller;\n }, [controller]);\n\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","isNaN","getIn","key","def","p","path","toPath","undefined","setIn","res","clone","resVal","i","pathArray","currentPath","currentObj","slice","nextPath","replace","split","flattenKeys","prefix","result","Object","prototype","hasOwnProperty","call","newKey","push","Field","t0","$","_c","children","className","is","name","props","validate","t1","t2","as","t3","t4","t5","formex","field","Symbol","for","bb0","getFieldProps","form","asElement","innerRef","rest","ref","createElement","nameOrOptions","isAnObject","valueState","values","onChange","handleChange","onBlur","handleBlur","type","valueProp","multiple","checked","indexOf","useCreateFormex","initialValues","initialErrors","initialDirty","initialTouched","validation","validateOnChange","validateOnInitialRender","onSubmit","onReset","onValuesChangeDeferred","debugId","initialValuesRef","useRef","valuesRef","debugIdRef","setValuesInner","useState","touchedState","setTouchedState","errors","setErrors","dirty","setDirty","submitCount","setSubmitCount","isSubmitting","setIsSubmitting","isValidating","setIsValidating","version","setVersion","onValuesChangeRef","current","debounceTimeoutRef","callDebouncedOnValuesChange","useCallback","clearTimeout","setTimeout","controllerRef","historyRef","historyIndexRef","useEffect","setValues","newValues","equal","newHistory","validationErrors","setFieldValue","shouldValidate","setFieldError","error","prevErrors","newErrors","setFieldTouched","touched","prev","event","target","valueAsNumber","submit","e","preventDefault","stopPropagation","keys","resetForm","submitCountProp","valuesProp","errorsProp","touchedProp","undo","newIndex","redo","controller","useMemo","setSubmitting","handleSubmit","canUndo","canRedo"],"mappings":"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"}
|
package/dist/index.umd.js
CHANGED
|
@@ -82,6 +82,21 @@
|
|
|
82
82
|
if (Array.isArray(value)) return value;
|
|
83
83
|
return value.replace(/\[(\d+)]/g, ".$1").replace(/^\./, "").replace(/\.$/, "").split(".");
|
|
84
84
|
}
|
|
85
|
+
function flattenKeys(obj, prefix = "", result = []) {
|
|
86
|
+
if (isObject(obj) || Array.isArray(obj)) {
|
|
87
|
+
for (const key in obj) {
|
|
88
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
89
|
+
const newKey = prefix ? Array.isArray(obj) ? `${prefix}[${key}]` : `${prefix}.${key}` : key;
|
|
90
|
+
if (isObject(obj[key]) || Array.isArray(obj[key])) {
|
|
91
|
+
flattenKeys(obj[key], newKey, result);
|
|
92
|
+
} else {
|
|
93
|
+
result.push(newKey);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return result;
|
|
99
|
+
}
|
|
85
100
|
function Field(t0) {
|
|
86
101
|
const $ = reactCompilerRuntime.c(37);
|
|
87
102
|
let children;
|
|
@@ -261,24 +276,39 @@
|
|
|
261
276
|
initialValues,
|
|
262
277
|
initialErrors,
|
|
263
278
|
initialDirty,
|
|
279
|
+
initialTouched,
|
|
264
280
|
validation,
|
|
265
281
|
validateOnChange = false,
|
|
266
282
|
validateOnInitialRender = false,
|
|
267
283
|
onSubmit,
|
|
268
284
|
onReset,
|
|
285
|
+
onValuesChangeDeferred,
|
|
269
286
|
debugId
|
|
270
287
|
}) {
|
|
271
288
|
const initialValuesRef = React.useRef(initialValues);
|
|
272
289
|
const valuesRef = React.useRef(initialValues);
|
|
273
290
|
const debugIdRef = React.useRef(debugId);
|
|
274
291
|
const [values, setValuesInner] = React.useState(initialValues);
|
|
275
|
-
const [touchedState, setTouchedState] = React.useState({});
|
|
292
|
+
const [touchedState, setTouchedState] = React.useState(initialTouched ?? {});
|
|
276
293
|
const [errors, setErrors] = React.useState(initialErrors ?? {});
|
|
277
294
|
const [dirty, setDirty] = React.useState(initialDirty ?? false);
|
|
278
295
|
const [submitCount, setSubmitCount] = React.useState(0);
|
|
279
296
|
const [isSubmitting, setIsSubmitting] = React.useState(false);
|
|
280
297
|
const [isValidating, setIsValidating] = React.useState(false);
|
|
281
298
|
const [version, setVersion] = React.useState(0);
|
|
299
|
+
const onValuesChangeRef = React.useRef(onValuesChangeDeferred);
|
|
300
|
+
onValuesChangeRef.current = onValuesChangeDeferred;
|
|
301
|
+
const debounceTimeoutRef = React.useRef();
|
|
302
|
+
const callDebouncedOnValuesChange = React.useCallback((values_0) => {
|
|
303
|
+
if (onValuesChangeRef.current) {
|
|
304
|
+
if (debounceTimeoutRef.current) {
|
|
305
|
+
clearTimeout(debounceTimeoutRef.current);
|
|
306
|
+
}
|
|
307
|
+
debounceTimeoutRef.current = setTimeout(() => {
|
|
308
|
+
onValuesChangeRef.current?.(values_0, controllerRef.current);
|
|
309
|
+
}, 300);
|
|
310
|
+
}
|
|
311
|
+
}, []);
|
|
282
312
|
const historyRef = React.useRef([initialValues]);
|
|
283
313
|
const historyIndexRef = React.useRef(0);
|
|
284
314
|
React.useEffect(() => {
|
|
@@ -294,7 +324,8 @@
|
|
|
294
324
|
newHistory.push(newValues);
|
|
295
325
|
historyRef.current = newHistory;
|
|
296
326
|
historyIndexRef.current = newHistory.length - 1;
|
|
297
|
-
|
|
327
|
+
callDebouncedOnValuesChange(newValues);
|
|
328
|
+
}, [callDebouncedOnValuesChange]);
|
|
298
329
|
const validate = React.useCallback(async () => {
|
|
299
330
|
setIsValidating(true);
|
|
300
331
|
const validationErrors = await validation?.(valuesRef.current);
|
|
@@ -316,7 +347,8 @@
|
|
|
316
347
|
newHistory_0.push(newValues_0);
|
|
317
348
|
historyRef.current = newHistory_0;
|
|
318
349
|
historyIndexRef.current = newHistory_0.length - 1;
|
|
319
|
-
|
|
350
|
+
callDebouncedOnValuesChange(newValues_0);
|
|
351
|
+
}, [validate, callDebouncedOnValuesChange]);
|
|
320
352
|
const setFieldError = React.useCallback((key_0, error) => {
|
|
321
353
|
setErrors((prevErrors) => {
|
|
322
354
|
const newErrors = {
|
|
@@ -384,14 +416,14 @@
|
|
|
384
416
|
initialValuesRef.current = valuesProp ?? initialValuesRef.current;
|
|
385
417
|
setValuesInner(valuesProp ?? initialValuesRef.current);
|
|
386
418
|
setErrors(errorsProp ?? {});
|
|
387
|
-
setTouchedState(touchedProp ?? {});
|
|
419
|
+
setTouchedState(touchedProp ?? initialTouched ?? {});
|
|
388
420
|
setDirty(false);
|
|
389
421
|
setSubmitCount(submitCountProp ?? 0);
|
|
390
422
|
setVersion((prev_2) => prev_2 + 1);
|
|
391
423
|
onReset?.(controllerRef.current);
|
|
392
424
|
historyRef.current = [valuesProp ?? initialValuesRef.current];
|
|
393
425
|
historyIndexRef.current = 0;
|
|
394
|
-
}, [onReset]);
|
|
426
|
+
}, [onReset, initialTouched]);
|
|
395
427
|
const undo = React.useCallback(() => {
|
|
396
428
|
if (historyIndexRef.current > 0) {
|
|
397
429
|
const newIndex = historyIndexRef.current - 1;
|
|
@@ -399,8 +431,10 @@
|
|
|
399
431
|
setValuesInner(newValues_1);
|
|
400
432
|
valuesRef.current = newValues_1;
|
|
401
433
|
historyIndexRef.current = newIndex;
|
|
434
|
+
setDirty(!equal(initialValuesRef.current, newValues_1));
|
|
435
|
+
callDebouncedOnValuesChange(newValues_1);
|
|
402
436
|
}
|
|
403
|
-
}, []);
|
|
437
|
+
}, [callDebouncedOnValuesChange]);
|
|
404
438
|
const redo = React.useCallback(() => {
|
|
405
439
|
if (historyIndexRef.current < historyRef.current.length - 1) {
|
|
406
440
|
const newIndex_0 = historyIndexRef.current + 1;
|
|
@@ -408,8 +442,10 @@
|
|
|
408
442
|
setValuesInner(newValues_2);
|
|
409
443
|
valuesRef.current = newValues_2;
|
|
410
444
|
historyIndexRef.current = newIndex_0;
|
|
445
|
+
setDirty(!equal(initialValuesRef.current, newValues_2));
|
|
446
|
+
callDebouncedOnValuesChange(newValues_2);
|
|
411
447
|
}
|
|
412
|
-
}, []);
|
|
448
|
+
}, [callDebouncedOnValuesChange]);
|
|
413
449
|
const controllerRef = React.useRef({});
|
|
414
450
|
const controller = React.useMemo(() => ({
|
|
415
451
|
values,
|
|
@@ -447,6 +483,7 @@
|
|
|
447
483
|
exports2.Field = Field;
|
|
448
484
|
exports2.Formex = Formex;
|
|
449
485
|
exports2.clone = clone;
|
|
486
|
+
exports2.flattenKeys = flattenKeys;
|
|
450
487
|
exports2.getIn = getIn;
|
|
451
488
|
exports2.isEmptyArray = isEmptyArray;
|
|
452
489
|
exports2.isFunction = isFunction;
|
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","/** @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 NaN? */\n// eslint-disable-next-line no-self-compare\nexport const isNaN = (obj: any): boolean => obj !== obj;\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\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, { useCallback, useEffect, useMemo, useRef, 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 initialDirty,\n validation,\n validateOnChange = false,\n validateOnInitialRender = false,\n onSubmit,\n onReset,\n debugId,\n }: {\n initialValues: T;\n initialErrors?: Record<string, string>;\n initialDirty?: boolean;\n validateOnChange?: boolean;\n validateOnInitialRender?: boolean;\n validation?: (\n values: T\n ) =>\n | Record<string, string>\n | Promise<Record<string, string>>\n | undefined\n | void;\n onSubmit?: (values: T, controller: FormexController<T>) => void | Promise<void>;\n onReset?: (controller: FormexController<T>) => void | Promise<void>;\n debugId?: string;\n}): FormexController<T> {\n const initialValuesRef = useRef<T>(initialValues);\n const valuesRef = useRef<T>(initialValues);\n const debugIdRef = 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(initialDirty ?? 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 // Replace state for history with refs\n const historyRef = useRef<T[]>([initialValues]);\n const historyIndexRef = useRef<number>(0);\n\n useEffect(() => {\n if (validateOnInitialRender) {\n validate();\n }\n }, []);\n\n const setValues = useCallback((newValues: T) => {\n valuesRef.current = newValues;\n setValuesInner(newValues);\n setDirty(!equal(initialValuesRef.current, newValues));\n // Update history using refs\n const newHistory = historyRef.current.slice(0, historyIndexRef.current + 1);\n newHistory.push(newValues);\n historyRef.current = newHistory;\n historyIndexRef.current = newHistory.length - 1;\n }, []);\n\n const validate = useCallback(async () => {\n setIsValidating(true);\n const validationErrors = await validation?.(valuesRef.current);\n setErrors(validationErrors ?? {});\n setIsValidating(false);\n return validationErrors;\n }, [validation]);\n\n const setFieldValue = useCallback(\n (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 // Update history using refs\n const newHistory = historyRef.current.slice(0, historyIndexRef.current + 1);\n newHistory.push(newValues);\n historyRef.current = newHistory;\n historyIndexRef.current = newHistory.length - 1;\n },\n [validate]\n );\n\n const setFieldError = useCallback((key: string, error: string | undefined) => {\n setErrors((prevErrors) => {\n const newErrors = { ...prevErrors };\n if (error) {\n newErrors[key] = error;\n } else {\n delete newErrors[key];\n }\n return newErrors;\n });\n }, []);\n\n const setFieldTouched = useCallback(\n (key: string, touched: boolean, shouldValidate?: boolean) => {\n setTouchedState((prev) => ({\n ...prev,\n [key]: touched,\n }));\n if (shouldValidate) {\n validate();\n }\n },\n [validate]\n );\n\n const handleChange = useCallback(\n (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 [setFieldValue, setFieldTouched, validateOnChange]\n );\n\n const handleBlur = useCallback((event: React.FocusEvent) => {\n const target = event.target as HTMLInputElement;\n const name = target.name;\n setFieldTouched(name, true);\n }, [setFieldTouched]);\n\n const submit = useCallback(\n async (e?: React.FormEvent<HTMLFormElement>) => {\n e?.preventDefault();\n e?.stopPropagation();\n setIsSubmitting(true);\n setSubmitCount((prev) => prev + 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((prev) => prev + 1);\n },\n [onSubmit, validation]\n );\n\n const resetForm = useCallback((props?: FormexResetProps<T>) => {\n const {\n submitCount: submitCountProp,\n values: valuesProp,\n errors: errorsProp,\n touched: touchedProp\n } = props ?? {};\n valuesRef.current = valuesProp ?? initialValuesRef.current;\n initialValuesRef.current = valuesProp ?? initialValuesRef.current;\n setValuesInner(valuesProp ?? initialValuesRef.current);\n setErrors(errorsProp ?? {});\n setTouchedState(touchedProp ?? {});\n setDirty(false);\n setSubmitCount(submitCountProp ?? 0);\n setVersion((prev) => prev + 1);\n onReset?.(controllerRef.current);\n // Reset history with refs\n historyRef.current = [valuesProp ?? initialValuesRef.current];\n historyIndexRef.current = 0;\n }, [onReset]);\n\n const undo = useCallback(() => {\n if (historyIndexRef.current > 0) {\n const newIndex = historyIndexRef.current - 1;\n const newValues = historyRef.current[newIndex];\n setValuesInner(newValues);\n valuesRef.current = newValues;\n historyIndexRef.current = newIndex;\n }\n }, []);\n\n const redo = useCallback(() => {\n if (historyIndexRef.current < historyRef.current.length - 1) {\n const newIndex = historyIndexRef.current + 1;\n const newValues = historyRef.current[newIndex];\n setValuesInner(newValues);\n valuesRef.current = newValues;\n historyIndexRef.current = newIndex;\n }\n }, []);\n\n const controllerRef = useRef<FormexController<T>>({} as FormexController<T>);\n\n const controller = useMemo<FormexController<T>>(\n () => ({\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 undo,\n redo,\n canUndo: historyIndexRef.current > 0,\n canRedo: historyIndexRef.current < historyRef.current.length - 1,\n }),\n [\n values,\n errors,\n touchedState,\n dirty,\n isSubmitting,\n submitCount,\n isValidating,\n version,\n handleChange,\n handleBlur,\n setValues,\n setFieldValue,\n setFieldTouched,\n setFieldError,\n validate,\n submit,\n resetForm,\n undo,\n redo,\n ]\n );\n\n useEffect(() => {\n controllerRef.current = controller;\n }, [controller]);\n\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","isNaN","getIn","key","def","p","path","toPath","undefined","setIn","res","clone","resVal","i","pathArray","currentPath","currentObj","slice","nextPath","replace","split","Field","t0","$","_c","children","className","is","name","props","validate","t1","t2","as","t3","t4","t5","formex","field","Symbol","for","bb0","getFieldProps","form","asElement","innerRef","rest","ref","createElement","nameOrOptions","isAnObject","valueState","values","onChange","handleChange","onBlur","handleBlur","type","valueProp","multiple","checked","indexOf","useCreateFormex","initialValues","initialErrors","initialDirty","validation","validateOnChange","validateOnInitialRender","onSubmit","onReset","debugId","initialValuesRef","useRef","valuesRef","debugIdRef","setValuesInner","useState","touchedState","setTouchedState","errors","setErrors","dirty","setDirty","submitCount","setSubmitCount","isSubmitting","setIsSubmitting","isValidating","setIsValidating","version","setVersion","historyRef","historyIndexRef","useEffect","setValues","useCallback","newValues","current","equal","newHistory","push","validationErrors","setFieldValue","shouldValidate","setFieldError","error","prevErrors","newErrors","setFieldTouched","touched","prev","event","target","valueAsNumber","submit","e","preventDefault","stopPropagation","Object","keys","controllerRef","resetForm","submitCountProp","valuesProp","errorsProp","touchedProp","undo","newIndex","redo","controller","useMemo","setSubmitting","handleSubmit","canUndo","canRedo"],"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","/** @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 NaN? */\n// eslint-disable-next-line no-self-compare\nexport const isNaN = (obj: any): boolean => obj !== obj;\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\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\nexport function flattenKeys(obj: any, prefix = \"\", result: string[] = []): string[] {\n if (isObject(obj) || Array.isArray(obj)) {\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n const newKey = prefix\n ? Array.isArray(obj)\n ? `${prefix}[${key}]`\n : `${prefix}.${key}`\n : key;\n if (isObject(obj[key]) || Array.isArray(obj[key])) {\n flattenKeys(obj[key], newKey, result);\n } else {\n result.push(newKey);\n }\n }\n }\n }\n return result;\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, { useCallback, useEffect, useMemo, useRef, 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 initialDirty,\n initialTouched,\n validation,\n validateOnChange = false,\n validateOnInitialRender = false,\n onSubmit,\n onReset,\n onValuesChangeDeferred,\n debugId,\n }: {\n initialValues: T;\n initialErrors?: Record<string, string>;\n initialDirty?: boolean;\n initialTouched?: Record<string, boolean>;\n validateOnChange?: boolean;\n validateOnInitialRender?: boolean;\n validation?: (\n values: T\n ) =>\n | Record<string, string>\n | Promise<Record<string, string>>\n | undefined\n | void;\n onValuesChangeDeferred?: (values: T, controller: FormexController<T>) => void;\n onSubmit?: (values: T, controller: FormexController<T>) => void | Promise<void>;\n onReset?: (controller: FormexController<T>) => void | Promise<void>;\n debugId?: string;\n}): FormexController<T> {\n const initialValuesRef = useRef<T>(initialValues);\n const valuesRef = useRef<T>(initialValues);\n const debugIdRef = useRef<string | undefined>(debugId);\n\n const [values, setValuesInner] = useState<T>(initialValues);\n const [touchedState, setTouchedState] = useState<Record<string, boolean>>(initialTouched ?? {});\n const [errors, setErrors] = useState<Record<string, string>>(initialErrors ?? {});\n const [dirty, setDirty] = useState(initialDirty ?? 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 const onValuesChangeRef = useRef(onValuesChangeDeferred);\n onValuesChangeRef.current = onValuesChangeDeferred;\n const debounceTimeoutRef = useRef<any>();\n\n const callDebouncedOnValuesChange = useCallback((values: T) => {\n if (onValuesChangeRef.current) {\n if (debounceTimeoutRef.current) {\n clearTimeout(debounceTimeoutRef.current);\n }\n debounceTimeoutRef.current = setTimeout(() => {\n onValuesChangeRef.current?.(values, controllerRef.current);\n }, 300);\n }\n }, []);\n\n // Replace state for history with refs\n const historyRef = useRef<T[]>([initialValues]);\n const historyIndexRef = useRef<number>(0);\n\n useEffect(() => {\n if (validateOnInitialRender) {\n validate();\n }\n }, []);\n\n const setValues = useCallback((newValues: T) => {\n valuesRef.current = newValues;\n setValuesInner(newValues);\n setDirty(!equal(initialValuesRef.current, newValues));\n // Update history using refs\n const newHistory = historyRef.current.slice(0, historyIndexRef.current + 1);\n newHistory.push(newValues);\n historyRef.current = newHistory;\n historyIndexRef.current = newHistory.length - 1;\n callDebouncedOnValuesChange(newValues);\n }, [callDebouncedOnValuesChange]);\n\n const validate = useCallback(async () => {\n setIsValidating(true);\n const validationErrors = await validation?.(valuesRef.current);\n setErrors(validationErrors ?? {});\n setIsValidating(false);\n return validationErrors;\n }, [validation]);\n\n const setFieldValue = useCallback(\n (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 // Update history using refs\n const newHistory = historyRef.current.slice(0, historyIndexRef.current + 1);\n newHistory.push(newValues);\n historyRef.current = newHistory;\n historyIndexRef.current = newHistory.length - 1;\n callDebouncedOnValuesChange(newValues);\n },\n [validate, callDebouncedOnValuesChange]\n );\n\n const setFieldError = useCallback((key: string, error: string | undefined) => {\n setErrors((prevErrors) => {\n const newErrors = { ...prevErrors };\n if (error) {\n newErrors[key] = error;\n } else {\n delete newErrors[key];\n }\n return newErrors;\n });\n }, []);\n\n const setFieldTouched = useCallback(\n (key: string, touched: boolean, shouldValidate?: boolean) => {\n setTouchedState((prev) => ({\n ...prev,\n [key]: touched,\n }));\n if (shouldValidate) {\n validate();\n }\n },\n [validate]\n );\n\n const handleChange = useCallback(\n (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 [setFieldValue, setFieldTouched, validateOnChange]\n );\n\n const handleBlur = useCallback((event: React.FocusEvent) => {\n const target = event.target as HTMLInputElement;\n const name = target.name;\n setFieldTouched(name, true);\n }, [setFieldTouched]);\n\n const submit = useCallback(\n async (e?: React.FormEvent<HTMLFormElement>) => {\n e?.preventDefault();\n e?.stopPropagation();\n setIsSubmitting(true);\n setSubmitCount((prev) => prev + 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((prev) => prev + 1);\n },\n [onSubmit, validation]\n );\n\n const resetForm = useCallback((props?: FormexResetProps<T>) => {\n const {\n submitCount: submitCountProp,\n values: valuesProp,\n errors: errorsProp,\n touched: touchedProp\n } = props ?? {};\n valuesRef.current = valuesProp ?? initialValuesRef.current;\n initialValuesRef.current = valuesProp ?? initialValuesRef.current;\n setValuesInner(valuesProp ?? initialValuesRef.current);\n setErrors(errorsProp ?? {});\n setTouchedState(touchedProp ?? initialTouched ?? {});\n setDirty(false);\n setSubmitCount(submitCountProp ?? 0);\n setVersion((prev) => prev + 1);\n onReset?.(controllerRef.current);\n // Reset history with refs\n historyRef.current = [valuesProp ?? initialValuesRef.current];\n historyIndexRef.current = 0;\n }, [onReset, initialTouched]);\n\n const undo = useCallback(() => {\n if (historyIndexRef.current > 0) {\n const newIndex = historyIndexRef.current - 1;\n const newValues = historyRef.current[newIndex];\n setValuesInner(newValues);\n valuesRef.current = newValues;\n historyIndexRef.current = newIndex;\n setDirty(!equal(initialValuesRef.current, newValues));\n callDebouncedOnValuesChange(newValues);\n }\n }, [callDebouncedOnValuesChange]);\n\n const redo = useCallback(() => {\n if (historyIndexRef.current < historyRef.current.length - 1) {\n const newIndex = historyIndexRef.current + 1;\n const newValues = historyRef.current[newIndex];\n setValuesInner(newValues);\n valuesRef.current = newValues;\n historyIndexRef.current = newIndex;\n setDirty(!equal(initialValuesRef.current, newValues));\n callDebouncedOnValuesChange(newValues);\n }\n }, [callDebouncedOnValuesChange]);\n\n const controllerRef = useRef<FormexController<T>>({} as FormexController<T>);\n\n const controller = useMemo<FormexController<T>>(\n () => ({\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 undo,\n redo,\n canUndo: historyIndexRef.current > 0,\n canRedo: historyIndexRef.current < historyRef.current.length - 1,\n }),\n [\n values,\n errors,\n touchedState,\n dirty,\n isSubmitting,\n submitCount,\n isValidating,\n version,\n handleChange,\n handleBlur,\n setValues,\n setFieldValue,\n setFieldTouched,\n setFieldError,\n validate,\n submit,\n resetForm,\n undo,\n redo,\n ]\n );\n\n useEffect(() => {\n controllerRef.current = controller;\n }, [controller]);\n\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","isNaN","getIn","key","def","p","path","toPath","undefined","setIn","res","clone","resVal","i","pathArray","currentPath","currentObj","slice","nextPath","replace","split","flattenKeys","prefix","result","Object","prototype","hasOwnProperty","call","newKey","push","Field","t0","$","_c","children","className","is","name","props","validate","t1","t2","as","t3","t4","t5","formex","field","Symbol","for","bb0","getFieldProps","form","asElement","innerRef","rest","ref","createElement","nameOrOptions","isAnObject","valueState","values","onChange","handleChange","onBlur","handleBlur","type","valueProp","multiple","checked","indexOf","useCreateFormex","initialValues","initialErrors","initialDirty","initialTouched","validation","validateOnChange","validateOnInitialRender","onSubmit","onReset","onValuesChangeDeferred","debugId","initialValuesRef","useRef","valuesRef","debugIdRef","setValuesInner","useState","touchedState","setTouchedState","errors","setErrors","dirty","setDirty","submitCount","setSubmitCount","isSubmitting","setIsSubmitting","isValidating","setIsValidating","version","setVersion","onValuesChangeRef","current","debounceTimeoutRef","callDebouncedOnValuesChange","useCallback","clearTimeout","setTimeout","controllerRef","historyRef","historyIndexRef","useEffect","setValues","newValues","equal","newHistory","validationErrors","setFieldValue","shouldValidate","setFieldError","error","prevErrors","newErrors","setFieldTouched","touched","prev","event","target","valueAsNumber","submit","e","preventDefault","stopPropagation","keys","resetForm","submitCountProp","valuesProp","errorsProp","touchedProp","undo","newIndex","redo","controller","useMemo","setSubmitting","handleSubmit","canUndo","canRedo"],"mappings":"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"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { FormexController } from "./types";
|
|
2
|
-
export declare function useCreateFormex<T extends object>({ initialValues, initialErrors, initialDirty, validation, validateOnChange, validateOnInitialRender, onSubmit, onReset, debugId, }: {
|
|
2
|
+
export declare function useCreateFormex<T extends object>({ initialValues, initialErrors, initialDirty, initialTouched, validation, validateOnChange, validateOnInitialRender, onSubmit, onReset, onValuesChangeDeferred, debugId, }: {
|
|
3
3
|
initialValues: T;
|
|
4
4
|
initialErrors?: Record<string, string>;
|
|
5
5
|
initialDirty?: boolean;
|
|
6
|
+
initialTouched?: Record<string, boolean>;
|
|
6
7
|
validateOnChange?: boolean;
|
|
7
8
|
validateOnInitialRender?: boolean;
|
|
8
9
|
validation?: (values: T) => Record<string, string> | Promise<Record<string, string>> | undefined | void;
|
|
10
|
+
onValuesChangeDeferred?: (values: T, controller: FormexController<T>) => void;
|
|
9
11
|
onSubmit?: (values: T, controller: FormexController<T>) => void | Promise<void>;
|
|
10
12
|
onReset?: (controller: FormexController<T>) => void | Promise<void>;
|
|
11
13
|
debugId?: string;
|
package/dist/utils.d.ts
CHANGED
|
@@ -14,3 +14,4 @@ export declare const isNaN: (obj: any) => boolean;
|
|
|
14
14
|
export declare function getIn(obj: any, key: string | string[], def?: any, p?: number): any;
|
|
15
15
|
export declare function setIn(obj: any, path: string, value: any): any;
|
|
16
16
|
export declare function clone(value: any): any;
|
|
17
|
+
export declare function flattenKeys(obj: any, prefix?: string, result?: string[]): string[];
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@firecms/formex",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.0.0-canary.
|
|
4
|
+
"version": "3.0.0-canary.285",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -74,5 +74,5 @@
|
|
|
74
74
|
"node"
|
|
75
75
|
]
|
|
76
76
|
},
|
|
77
|
-
"gitHead": "
|
|
77
|
+
"gitHead": "a442a00b64764b353c977cc9e758953995bd9513"
|
|
78
78
|
}
|
package/src/useCreateFormex.tsx
CHANGED
|
@@ -8,16 +8,19 @@ export function useCreateFormex<T extends object>({
|
|
|
8
8
|
initialValues,
|
|
9
9
|
initialErrors,
|
|
10
10
|
initialDirty,
|
|
11
|
+
initialTouched,
|
|
11
12
|
validation,
|
|
12
13
|
validateOnChange = false,
|
|
13
14
|
validateOnInitialRender = false,
|
|
14
15
|
onSubmit,
|
|
15
16
|
onReset,
|
|
17
|
+
onValuesChangeDeferred,
|
|
16
18
|
debugId,
|
|
17
19
|
}: {
|
|
18
20
|
initialValues: T;
|
|
19
21
|
initialErrors?: Record<string, string>;
|
|
20
22
|
initialDirty?: boolean;
|
|
23
|
+
initialTouched?: Record<string, boolean>;
|
|
21
24
|
validateOnChange?: boolean;
|
|
22
25
|
validateOnInitialRender?: boolean;
|
|
23
26
|
validation?: (
|
|
@@ -27,6 +30,7 @@ export function useCreateFormex<T extends object>({
|
|
|
27
30
|
| Promise<Record<string, string>>
|
|
28
31
|
| undefined
|
|
29
32
|
| void;
|
|
33
|
+
onValuesChangeDeferred?: (values: T, controller: FormexController<T>) => void;
|
|
30
34
|
onSubmit?: (values: T, controller: FormexController<T>) => void | Promise<void>;
|
|
31
35
|
onReset?: (controller: FormexController<T>) => void | Promise<void>;
|
|
32
36
|
debugId?: string;
|
|
@@ -36,7 +40,7 @@ export function useCreateFormex<T extends object>({
|
|
|
36
40
|
const debugIdRef = useRef<string | undefined>(debugId);
|
|
37
41
|
|
|
38
42
|
const [values, setValuesInner] = useState<T>(initialValues);
|
|
39
|
-
const [touchedState, setTouchedState] = useState<Record<string, boolean>>({});
|
|
43
|
+
const [touchedState, setTouchedState] = useState<Record<string, boolean>>(initialTouched ?? {});
|
|
40
44
|
const [errors, setErrors] = useState<Record<string, string>>(initialErrors ?? {});
|
|
41
45
|
const [dirty, setDirty] = useState(initialDirty ?? false);
|
|
42
46
|
const [submitCount, setSubmitCount] = useState(0);
|
|
@@ -44,6 +48,21 @@ export function useCreateFormex<T extends object>({
|
|
|
44
48
|
const [isValidating, setIsValidating] = useState(false);
|
|
45
49
|
const [version, setVersion] = useState(0);
|
|
46
50
|
|
|
51
|
+
const onValuesChangeRef = useRef(onValuesChangeDeferred);
|
|
52
|
+
onValuesChangeRef.current = onValuesChangeDeferred;
|
|
53
|
+
const debounceTimeoutRef = useRef<any>();
|
|
54
|
+
|
|
55
|
+
const callDebouncedOnValuesChange = useCallback((values: T) => {
|
|
56
|
+
if (onValuesChangeRef.current) {
|
|
57
|
+
if (debounceTimeoutRef.current) {
|
|
58
|
+
clearTimeout(debounceTimeoutRef.current);
|
|
59
|
+
}
|
|
60
|
+
debounceTimeoutRef.current = setTimeout(() => {
|
|
61
|
+
onValuesChangeRef.current?.(values, controllerRef.current);
|
|
62
|
+
}, 300);
|
|
63
|
+
}
|
|
64
|
+
}, []);
|
|
65
|
+
|
|
47
66
|
// Replace state for history with refs
|
|
48
67
|
const historyRef = useRef<T[]>([initialValues]);
|
|
49
68
|
const historyIndexRef = useRef<number>(0);
|
|
@@ -63,7 +82,8 @@ export function useCreateFormex<T extends object>({
|
|
|
63
82
|
newHistory.push(newValues);
|
|
64
83
|
historyRef.current = newHistory;
|
|
65
84
|
historyIndexRef.current = newHistory.length - 1;
|
|
66
|
-
|
|
85
|
+
callDebouncedOnValuesChange(newValues);
|
|
86
|
+
}, [callDebouncedOnValuesChange]);
|
|
67
87
|
|
|
68
88
|
const validate = useCallback(async () => {
|
|
69
89
|
setIsValidating(true);
|
|
@@ -89,8 +109,9 @@ export function useCreateFormex<T extends object>({
|
|
|
89
109
|
newHistory.push(newValues);
|
|
90
110
|
historyRef.current = newHistory;
|
|
91
111
|
historyIndexRef.current = newHistory.length - 1;
|
|
112
|
+
callDebouncedOnValuesChange(newValues);
|
|
92
113
|
},
|
|
93
|
-
[validate]
|
|
114
|
+
[validate, callDebouncedOnValuesChange]
|
|
94
115
|
);
|
|
95
116
|
|
|
96
117
|
const setFieldError = useCallback((key: string, error: string | undefined) => {
|
|
@@ -172,7 +193,7 @@ export function useCreateFormex<T extends object>({
|
|
|
172
193
|
initialValuesRef.current = valuesProp ?? initialValuesRef.current;
|
|
173
194
|
setValuesInner(valuesProp ?? initialValuesRef.current);
|
|
174
195
|
setErrors(errorsProp ?? {});
|
|
175
|
-
setTouchedState(touchedProp ?? {});
|
|
196
|
+
setTouchedState(touchedProp ?? initialTouched ?? {});
|
|
176
197
|
setDirty(false);
|
|
177
198
|
setSubmitCount(submitCountProp ?? 0);
|
|
178
199
|
setVersion((prev) => prev + 1);
|
|
@@ -180,7 +201,7 @@ export function useCreateFormex<T extends object>({
|
|
|
180
201
|
// Reset history with refs
|
|
181
202
|
historyRef.current = [valuesProp ?? initialValuesRef.current];
|
|
182
203
|
historyIndexRef.current = 0;
|
|
183
|
-
}, [onReset]);
|
|
204
|
+
}, [onReset, initialTouched]);
|
|
184
205
|
|
|
185
206
|
const undo = useCallback(() => {
|
|
186
207
|
if (historyIndexRef.current > 0) {
|
|
@@ -189,8 +210,10 @@ export function useCreateFormex<T extends object>({
|
|
|
189
210
|
setValuesInner(newValues);
|
|
190
211
|
valuesRef.current = newValues;
|
|
191
212
|
historyIndexRef.current = newIndex;
|
|
213
|
+
setDirty(!equal(initialValuesRef.current, newValues));
|
|
214
|
+
callDebouncedOnValuesChange(newValues);
|
|
192
215
|
}
|
|
193
|
-
}, []);
|
|
216
|
+
}, [callDebouncedOnValuesChange]);
|
|
194
217
|
|
|
195
218
|
const redo = useCallback(() => {
|
|
196
219
|
if (historyIndexRef.current < historyRef.current.length - 1) {
|
|
@@ -199,8 +222,10 @@ export function useCreateFormex<T extends object>({
|
|
|
199
222
|
setValuesInner(newValues);
|
|
200
223
|
valuesRef.current = newValues;
|
|
201
224
|
historyIndexRef.current = newIndex;
|
|
225
|
+
setDirty(!equal(initialValuesRef.current, newValues));
|
|
226
|
+
callDebouncedOnValuesChange(newValues);
|
|
202
227
|
}
|
|
203
|
-
}, []);
|
|
228
|
+
}, [callDebouncedOnValuesChange]);
|
|
204
229
|
|
|
205
230
|
const controllerRef = useRef<FormexController<T>>({} as FormexController<T>);
|
|
206
231
|
|
package/src/utils.ts
CHANGED
|
@@ -94,3 +94,23 @@ function toPath(value: string | string[]) {
|
|
|
94
94
|
// Replace brackets with dots, remove leading/trailing dots, then split by dot.
|
|
95
95
|
return value.replace(/\[(\d+)]/g, ".$1").replace(/^\./, "").replace(/\.$/, "").split(".");
|
|
96
96
|
}
|
|
97
|
+
|
|
98
|
+
export function flattenKeys(obj: any, prefix = "", result: string[] = []): string[] {
|
|
99
|
+
if (isObject(obj) || Array.isArray(obj)) {
|
|
100
|
+
for (const key in obj) {
|
|
101
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
102
|
+
const newKey = prefix
|
|
103
|
+
? Array.isArray(obj)
|
|
104
|
+
? `${prefix}[${key}]`
|
|
105
|
+
: `${prefix}.${key}`
|
|
106
|
+
: key;
|
|
107
|
+
if (isObject(obj[key]) || Array.isArray(obj[key])) {
|
|
108
|
+
flattenKeys(obj[key], newKey, result);
|
|
109
|
+
} else {
|
|
110
|
+
result.push(newKey);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return result;
|
|
116
|
+
}
|