@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 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, useEffect, useCallback, useMemo } from "react";
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
- }, [validate]);
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,
@@ -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
- }, [validate]);
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;
@@ -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.283",
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": "521154e8ee22424451421052cbc22fa6ba5b4d4d"
77
+ "gitHead": "a442a00b64764b353c977cc9e758953995bd9513"
78
78
  }
@@ -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
+ }