react-f0rm 0.3.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +48 -2
  2. package/dist/devtools/index.cjs.js +20 -13
  3. package/dist/devtools/index.cjs.js.map +1 -1
  4. package/dist/devtools/index.d.ts +1 -1
  5. package/dist/devtools/index.mjs +20 -13
  6. package/dist/devtools/index.mjs.map +1 -1
  7. package/dist/{form-b9441d8c.cjs.js → form-B4r7INJ0.cjs.js} +10 -39
  8. package/dist/form-B4r7INJ0.cjs.js.map +1 -0
  9. package/dist/{form-61297bc0.d.ts → form-DeRFdFKE.d.ts} +2 -2
  10. package/dist/{form-94c70b4b.mjs → form-R1hDKjBm.mjs} +11 -40
  11. package/dist/form-R1hDKjBm.mjs.map +1 -0
  12. package/dist/index.cjs.js +30 -15
  13. package/dist/index.cjs.js.map +1 -1
  14. package/dist/index.d.ts +78 -19
  15. package/dist/index.mjs +31 -16
  16. package/dist/index.mjs.map +1 -1
  17. package/dist/index.umd.js +30 -15
  18. package/dist/index.umd.js.map +1 -1
  19. package/dist/index.umd.min.js +2 -2
  20. package/dist/index.umd.min.js.map +1 -1
  21. package/dist/resolvers/standard-schema.cjs.js +1 -1
  22. package/dist/resolvers/standard-schema.cjs.js.map +1 -1
  23. package/dist/resolvers/standard-schema.d.ts +2 -2
  24. package/dist/resolvers/standard-schema.mjs +1 -1
  25. package/dist/resolvers/standard-schema.mjs.map +1 -1
  26. package/dist/resolvers/yup.cjs.js +5 -7
  27. package/dist/resolvers/yup.cjs.js.map +1 -1
  28. package/dist/resolvers/yup.d.ts +2 -2
  29. package/dist/resolvers/yup.mjs +5 -7
  30. package/dist/resolvers/yup.mjs.map +1 -1
  31. package/dist/resolvers/zod.cjs.js +5 -7
  32. package/dist/resolvers/zod.cjs.js.map +1 -1
  33. package/dist/resolvers/zod.d.ts +2 -2
  34. package/dist/resolvers/zod.mjs +5 -7
  35. package/dist/resolvers/zod.mjs.map +1 -1
  36. package/dist/{validate-148fe167.d.ts → validate-B7S9EiRT.d.ts} +1 -1
  37. package/package.json +52 -51
  38. package/dist/form-94c70b4b.mjs.map +0 -1
  39. package/dist/form-b9441d8c.cjs.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { F as FieldPath, N as Name, a as Form$1, P as PathValueOf, b as FieldError, O as Options, c as Path } from './form-61297bc0.js';
2
- export { f as FieldErrorEntry, u as FieldState, a3 as HandleSubmitOptions, e as PathValue, R as ReValidateMode, U as ResetFieldOptions, Q as ResetOptions, S as SetFieldOptions, a5 as SetFocusOptions, g as VALIDATION_OUTCOME, i as ValidateResult, V as ValidationMode, h as ValidationOutcome, A as clearErrors, d as createForm, Z as ensureValidate, H as getDirtyFields, n as getError, o as getErrorByPath, r as getErrors, p as getFieldErrors, q as getFieldErrorsByPath, v as getFieldState, t as getFirstError, I as getTouchedFields, k as getValue, l as getValueByPath, j as getValues, a4 as handleSubmit, X as hasErrors, D as hasTouched, E as hasTouchedByPath, a0 as incrementSubmitCount, G as isDirty, J as isTouched, K as removeField, L as removeFieldByPath, T as reset, W as resetField, a2 as setDisabled, y as setError, z as setErrorByPath, a6 as setFocus, M as setInitialValues, $ as setIsSubmitting, a1 as setSubmitSuccessful, B as setTouched, C as setTouchedByPath, x as setValidatingByPath, s as setValue, m as setValueByPath, Y as trigger, w as unsetValidatingByPath, _ as validate } from './form-61297bc0.js';
1
+ import { a as FieldPath, N as Name, F as Form$1, P as PathValueOf, b as FieldError, c as Path, O as Options } from './form-DeRFdFKE.js';
2
+ export { d as FieldErrorEntry, e as FieldState, H as HandleSubmitOptions, f as PathValue, R as ReValidateMode, g as ResetFieldOptions, h as ResetOptions, S as SetFieldOptions, i as SetFocusOptions, V as VALIDATION_OUTCOME, j as ValidateResult, k as ValidationMode, l as ValidationOutcome, m as clearErrors, n as createForm, o as ensureValidate, p as getDirtyFields, q as getError, r as getErrorByPath, s as getErrors, t as getFieldErrors, u as getFieldErrorsByPath, v as getFieldState, w as getFirstError, x as getTouchedFields, y as getValue, z as getValueByPath, A as getValues, B as handleSubmit, C as hasErrors, D as hasTouched, E as hasTouchedByPath, G as incrementSubmitCount, I as isDirty, J as isTouched, K as removeField, L as removeFieldByPath, M as reset, Q as resetField, T as setDisabled, U as setError, W as setErrorByPath, X as setFocus, Y as setInitialValues, Z as setIsSubmitting, _ as setSubmitSuccessful, $ as setTouched, a0 as setTouchedByPath, a1 as setValidatingByPath, a2 as setValue, a3 as setValueByPath, a4 as trigger, a5 as unsetValidatingByPath, a6 as validate } from './form-DeRFdFKE.js';
3
+ import { V as Validator } from './validate-B7S9EiRT.js';
3
4
  import * as React from 'react';
4
5
  import { ReactNode } from 'react';
5
- import { V as Validator } from './validate-148fe167.js';
6
6
  import { EventEmitter } from '@for-fun/event-emitter';
7
7
 
8
8
  /** Type tag of a failed rule, as stored on the resulting FieldError. */
@@ -151,9 +151,11 @@ declare function useFormContext<T extends Record<string, any> = any>(): Form$1<T
151
151
  * (`Ctx.useField({name: 'user.name'})` gets its `name` constrained by
152
152
  * `FieldPath<Values>` and its `value` typed accordingly), so call sites stop
153
153
  * hand-writing generics, and each instance's Provider scopes a strictly
154
- * separate form.
154
+ * separate form. The bundle also carries its raw React context
155
+ * (`Ctx.context`) so `<Form context={Ctx.context}>` can provide into it.
155
156
  */
156
157
  declare function createFormContext<TValues extends Record<string, any> = any>(): {
158
+ context: React.Context<Form$1<TValues> | null>;
157
159
  FormProvider: ({ form, children }: {
158
160
  form: Form$1<TValues>;
159
161
  children: ReactNode;
@@ -315,7 +317,17 @@ declare function subscribe(form: Form$1, options: SubscribeOptions): () => void;
315
317
  * this component is a thin wrapper that binds it to the rendered <form>.
316
318
  */
317
319
  interface FormProps<T extends Record<string, any> = any> extends Omit<React.FormHTMLAttributes<HTMLFormElement>, 'onSubmit'> {
318
- form?: Form<T>;
320
+ form?: Form$1<T>;
321
+ /**
322
+ * Provide into an isolated context from `createFormContext()` instead of
323
+ * the module-level one — `<Form context={ProfileForm.context}>` keeps the
324
+ * component's full submit machinery while the factory's bound hooks
325
+ * (`ProfileForm.useField`, `ProfileForm.useFormContext`, ...) resolve this
326
+ * form from their private context. The module-level `useFormContext()` /
327
+ * `useField` do not see it; that is the point of the isolation. Omitted,
328
+ * the form lands in the module-level FormContext as before.
329
+ */
330
+ context?: React.Context<Form$1<any> | null>;
319
331
  initialValues?: T;
320
332
  /**
321
333
  * Controlled external values. When the `values` reference changes, the
@@ -326,8 +338,11 @@ interface FormProps<T extends Record<string, any> = any> extends Omit<React.Form
326
338
  * `values` reference never clobber what the user is typing.
327
339
  */
328
340
  values?: T;
329
- onSubmit?: (values: T, e: React.FormEvent) => void;
330
- onValidSubmit?: (values: T, e: React.FormEvent) => void;
341
+ /** May be async — the submit flow awaits it, so form.isSubmitting
342
+ * covers the entire flight. */
343
+ onSubmit?: (values: T, e: React.FormEvent) => void | Promise<void>;
344
+ /** May be async, same as onSubmit. */
345
+ onValidSubmit?: (values: T, e: React.FormEvent) => void | Promise<void>;
331
346
  /**
332
347
  * Called when validation fails.
333
348
  * @param errors array of {path, type, message} entries in insertion
@@ -349,14 +364,34 @@ interface FormProps<T extends Record<string, any> = any> extends Omit<React.Form
349
364
  */
350
365
  shouldFocusError?: boolean;
351
366
  }
352
- declare function Form<T extends Record<string, any> = any>({ form: f1, initialValues, values, onSubmit, onValidSubmit, onInvalidSubmit, shouldFocusError, ...props }: FormProps<T>): React.JSX.Element;
367
+ declare function Form<T extends Record<string, any> = any>({ form: f1, context, initialValues, values, onSubmit, onValidSubmit, onInvalidSubmit, shouldFocusError, ...props }: FormProps<T>): React.JSX.Element;
353
368
 
354
- interface UseFieldOptions {
355
- form?: any;
356
- name?: Name;
369
+ /**
370
+ * Props shared by Field/Checkbox/Select. Generic so a typed form flows into
371
+ * the `validate` callback: with `form` (a `Form<Values>`) and `name`
372
+ * (a `FieldPath<Values>`) provided, `validate` receives the value at that
373
+ * path — `PathValueOf<Values, P>` — instead of `any`. The defaults keep the
374
+ * bare `<Field name="x" />` (context-resolved, untyped) call sites exactly
375
+ * as permissive as before.
376
+ */
377
+ interface UseFieldOptions<TValues extends Record<string, any> = any, TPath extends FieldPath<TValues> | Name = Name> {
378
+ form?: Form$1<TValues>;
379
+ name?: TPath;
357
380
  initialValue?: any;
358
381
  shouldUnregister?: boolean;
359
- validate?: Validator;
382
+ /**
383
+ * Field-level validator. The value argument is typed when the field is
384
+ * tied to a typed form (via the `form` prop); the return shape mirrors
385
+ * {@link Validator} — an error (string / FieldError / mixed array) or
386
+ * undefined when valid, possibly a Promise for async validation. The
387
+ * second argument carries the validation context (`meta.signal` aborts
388
+ * when the round is superseded).
389
+ */
390
+ validate?: (value: PathValueOf<TValues, TPath>, meta: {
391
+ form: Form$1;
392
+ path: Path;
393
+ signal: AbortSignal;
394
+ }) => ReturnType<Validator>;
360
395
  /**
361
396
  * Declarative rules (required/min/max/minLength/maxLength/pattern),
362
397
  * compiled into a validator that runs before `validate`; failures land
@@ -388,7 +423,7 @@ interface UseFieldOptions {
388
423
  delayError?: number;
389
424
  [key: string]: any;
390
425
  }
391
- interface FieldProps extends UseFieldOptions {
426
+ interface FieldProps<TValues extends Record<string, any> = any, TPath extends FieldPath<TValues> | Name = Name> extends UseFieldOptions<TValues, TPath> {
392
427
  as?: React.ComponentType<any>;
393
428
  asProps?: Record<string, any>;
394
429
  eventToValue?: (e: any) => any;
@@ -402,15 +437,39 @@ interface FieldProps extends UseFieldOptions {
402
437
  */
403
438
  renderError?: (error: string, id: string) => React.ReactNode;
404
439
  }
405
- declare const Field: React.ForwardRefExoticComponent<Omit<FieldProps, "ref"> & React.RefAttributes<HTMLInputElement>>;
406
- interface CheckboxProps extends UseFieldOptions {
440
+ /**
441
+ * The callable shape of {@link Field}: `form` + `name` flow their generics
442
+ * into `validate`'s value argument (`PathValueOf<TValues, TPath>`). A named
443
+ * interface rather than an inline `as <TValues, ...>() => ...` signature —
444
+ * same types, and the inline form trips no-use-before-define on the type
445
+ * parameters.
446
+ */
447
+ interface FieldComponent {
448
+ <TValues extends Record<string, any> = any, TPath extends FieldPath<TValues> | Name = Name>(props: FieldProps<TValues, TPath> & React.RefAttributes<HTMLInputElement>): React.ReactElement | null;
449
+ }
450
+ declare const Field: FieldComponent;
451
+ interface CheckboxProps<TValues extends Record<string, any> = any, TPath extends FieldPath<TValues> | Name = Name> extends UseFieldOptions<TValues, TPath> {
452
+ }
453
+ /**
454
+ * Callable shape of {@link Checkbox}: the same form-typed `validate`
455
+ * inference contract as {@link FieldComponent}.
456
+ */
457
+ interface CheckboxComponent {
458
+ <TValues extends Record<string, any> = any, TPath extends FieldPath<TValues> | Name = Name>(props: CheckboxProps<TValues, TPath> & React.RefAttributes<HTMLInputElement>): React.ReactElement | null;
407
459
  }
408
- declare const Checkbox: React.ForwardRefExoticComponent<Omit<CheckboxProps, "ref"> & React.RefAttributes<HTMLInputElement>>;
409
- interface SelectProps extends UseFieldOptions {
460
+ declare const Checkbox: CheckboxComponent;
461
+ interface SelectProps<TValues extends Record<string, any> = any, TPath extends FieldPath<TValues> | Name = Name> extends UseFieldOptions<TValues, TPath> {
410
462
  multiple?: boolean;
411
463
  children?: React.ReactNode;
412
464
  }
413
- declare const Select: React.ForwardRefExoticComponent<Omit<SelectProps, "ref"> & React.RefAttributes<HTMLSelectElement>>;
465
+ /**
466
+ * Callable shape of {@link Select}: the same form-typed `validate`
467
+ * inference contract as {@link FieldComponent}.
468
+ */
469
+ interface SelectComponent {
470
+ <TValues extends Record<string, any> = any, TPath extends FieldPath<TValues> | Name = Name>(props: SelectProps<TValues, TPath> & React.RefAttributes<HTMLSelectElement>): React.ReactElement | null;
471
+ }
472
+ declare const Select: SelectComponent;
414
473
 
415
- export { Checkbox, CheckboxGroupContext, CheckboxGroupProvider, Field, FieldError, FieldPath, Form, FormContext, Form$1 as FormInstance, FormProvider, Name, Options, PathValueOf, Select, createFormContext, subscribe, useCheckboxGroupContext, useDirtyFields, useError, useErrorByPath, useField, useFieldArray, useFieldErrors, useFieldErrorsByPath, useForm, useFormContext, useHasErrors, useIsDirty, useIsSubmitting, useSubmitCount, useTouched, useTouchedByPath, useTouchedFields, useValue, useValueByPath, useWatch };
474
+ export { Checkbox, CheckboxGroupContext, CheckboxGroupProvider, Field, FieldError, FieldPath, Form, FormContext, Form$1 as FormInstance, FormProvider, Name, Options, Path, PathValueOf, Select, Validator, createFormContext, subscribe, useCheckboxGroupContext, useDirtyFields, useError, useErrorByPath, useField, useFieldArray, useFieldErrors, useFieldErrorsByPath, useForm, useFormContext, useHasErrors, useIsDirty, useIsSubmitting, useSubmitCount, useTouched, useTouchedByPath, useTouchedFields, useValue, useValueByPath, useWatch };
416
475
  export type { FieldRules, SubscribeEvent, SubscribeOptions, WatchScope };
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import React__default, { useState, useRef, useEffect, useCallback, useMemo, useContext, useReducer, createContext, createElement } from 'react';
2
+ import React__default, { useCallback, useRef, useState, useEffect, useMemo, useContext, useReducer, createContext, createElement } from 'react';
3
3
 
4
4
  function getSet(ee, key) {
5
5
  var set = ee.get(key);
@@ -11,7 +11,7 @@ function getSet(ee, key) {
11
11
  function create$2() {
12
12
  return new Map();
13
13
  }
14
- function emit$1(ee, key) {
14
+ function emit(ee, key) {
15
15
  for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
16
16
  args[_key - 2] = arguments[_key];
17
17
  }
@@ -166,7 +166,6 @@ function create$1(name) {
166
166
  return { value, key: JSON.stringify(value) };
167
167
  }
168
168
 
169
- const emit = emit$1;
170
169
  const VALIDATION_OUTCOME = /* @__PURE__ */ Symbol("validation-outcome");
171
170
  function create(options) {
172
171
  const emitter = create$2();
@@ -761,7 +760,7 @@ function requireUseSyncExternalStoreShim_production () {
761
760
  var nextValue = latestGetSnapshot();
762
761
  return !objectIs(inst, nextValue);
763
762
  } catch (error) {
764
- return !0;
763
+ return true;
765
764
  }
766
765
  }
767
766
  function useSyncExternalStore$1(subscribe, getSnapshot) {
@@ -803,7 +802,7 @@ function requireUseSyncExternalStoreShim_development () {
803
802
  function useSyncExternalStore$2(subscribe, getSnapshot) {
804
803
  didWarnOld18Alpha ||
805
804
  void 0 === React.startTransition ||
806
- ((didWarnOld18Alpha = !0),
805
+ ((didWarnOld18Alpha = true),
807
806
  console.error(
808
807
  "You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release."
809
808
  ));
@@ -814,7 +813,7 @@ function requireUseSyncExternalStoreShim_development () {
814
813
  (console.error(
815
814
  "The result of getSnapshot should be cached to avoid an infinite loop"
816
815
  ),
817
- (didWarnUncachedGetSnapshot = !0));
816
+ (didWarnUncachedGetSnapshot = true));
818
817
  }
819
818
  cachedValue = useState({
820
819
  inst: { value: value, getSnapshot: getSnapshot }
@@ -848,7 +847,7 @@ function requireUseSyncExternalStoreShim_development () {
848
847
  var nextValue = latestGetSnapshot();
849
848
  return !objectIs(inst, nextValue);
850
849
  } catch (error) {
851
- return !0;
850
+ return true;
852
851
  }
853
852
  }
854
853
  function useSyncExternalStore$1(subscribe, getSnapshot) {
@@ -864,8 +863,8 @@ function requireUseSyncExternalStoreShim_development () {
864
863
  useEffect = React.useEffect,
865
864
  useLayoutEffect = React.useLayoutEffect,
866
865
  useDebugValue = React.useDebugValue,
867
- didWarnOld18Alpha = !1,
868
- didWarnUncachedGetSnapshot = !1,
866
+ didWarnOld18Alpha = false,
867
+ didWarnUncachedGetSnapshot = false,
869
868
  shim =
870
869
  "undefined" === typeof window ||
871
870
  "undefined" === typeof window.document ||
@@ -882,13 +881,21 @@ function requireUseSyncExternalStoreShim_development () {
882
881
  return useSyncExternalStoreShim_development;
883
882
  }
884
883
 
885
- if (process.env.NODE_ENV === 'production') {
886
- shim.exports = requireUseSyncExternalStoreShim_production();
887
- } else {
888
- shim.exports = requireUseSyncExternalStoreShim_development();
884
+ var hasRequiredShim;
885
+
886
+ function requireShim () {
887
+ if (hasRequiredShim) return shim.exports;
888
+ hasRequiredShim = 1;
889
+
890
+ if (process.env.NODE_ENV === 'production') {
891
+ shim.exports = requireUseSyncExternalStoreShim_production();
892
+ } else {
893
+ shim.exports = requireUseSyncExternalStoreShim_development();
894
+ }
895
+ return shim.exports;
889
896
  }
890
897
 
891
- var shimExports = shim.exports;
898
+ var shimExports = requireShim();
892
899
 
893
900
  function isDescendant(key, ancestorKey) {
894
901
  return key.startsWith(`${ancestorKey.slice(0, -1)},`);
@@ -1421,7 +1428,13 @@ function createFormContext() {
1421
1428
  function useFieldArray(options) {
1422
1429
  return useFieldArrayCore(options, Context);
1423
1430
  }
1424
- return { FormProvider: FormProvider2, useFormContext: useFormContext2, useField, useFieldArray };
1431
+ return {
1432
+ context: Context,
1433
+ FormProvider: FormProvider2,
1434
+ useFormContext: useFormContext2,
1435
+ useField,
1436
+ useFieldArray
1437
+ };
1425
1438
  }
1426
1439
  const CheckboxGroupContext = createContext(null);
1427
1440
  const CheckboxGroupProvider = CheckboxGroupContext.Provider;
@@ -1433,6 +1446,7 @@ function useCheckboxGroupContext() {
1433
1446
 
1434
1447
  function Form({
1435
1448
  form: f1,
1449
+ context,
1436
1450
  initialValues,
1437
1451
  values,
1438
1452
  onSubmit,
@@ -1449,7 +1463,8 @@ function Form({
1449
1463
  onInvalidSubmit,
1450
1464
  shouldFocusError
1451
1465
  });
1452
- return /* @__PURE__ */ React.createElement(FormProvider, { value: form }, /* @__PURE__ */ React.createElement("form", { ...props, noValidate: true, onSubmit: submit }));
1466
+ const { Provider } = context ?? FormContext;
1467
+ return /* @__PURE__ */ React.createElement(Provider, { value: form }, /* @__PURE__ */ React.createElement("form", { ...props, noValidate: true, onSubmit: submit }));
1453
1468
  }
1454
1469
 
1455
1470
  function setRef(ref, value) {