remix-validated-form 5.0.2 → 5.1.0
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.cjs.js.map +1 -1
 - package/dist/index.d.ts +7 -2
 - package/dist/index.esm.js.map +1 -1
 - package/package.json +1 -1
 - package/src/ValidatedForm.tsx +0 -427
 - package/src/hooks.ts +0 -160
 - package/src/index.ts +0 -12
 - package/src/internal/MultiValueMap.ts +0 -44
 - package/src/internal/constants.ts +0 -4
 - package/src/internal/flatten.ts +0 -12
 - package/src/internal/formContext.ts +0 -13
 - package/src/internal/getInputProps.test.ts +0 -251
 - package/src/internal/getInputProps.ts +0 -94
 - package/src/internal/hooks.ts +0 -217
 - package/src/internal/hydratable.ts +0 -28
 - package/src/internal/logic/getCheckboxChecked.ts +0 -10
 - package/src/internal/logic/getRadioChecked.ts +0 -18
 - package/src/internal/logic/nestedObjectToPathObject.ts +0 -63
 - package/src/internal/logic/requestSubmit.test.tsx +0 -24
 - package/src/internal/logic/requestSubmit.ts +0 -103
 - package/src/internal/state/arrayUtil.ts +0 -451
 - package/src/internal/state/controlledFields.ts +0 -86
 - package/src/internal/state/createFormStore.ts +0 -591
 - package/src/internal/state/fieldArray.tsx +0 -197
 - package/src/internal/state/storeHooks.ts +0 -9
 - package/src/internal/state/types.ts +0 -1
 - package/src/internal/submissionCallbacks.ts +0 -15
 - package/src/internal/util.ts +0 -39
 - package/src/server.ts +0 -53
 - package/src/unreleased/formStateHooks.ts +0 -170
 - package/src/userFacingFormContext.ts +0 -147
 - package/src/validation/createValidator.ts +0 -53
 - package/src/validation/types.ts +0 -72
 - package/tsconfig.json +0 -8
 
| 
         @@ -1,197 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            import { nanoid } from "nanoid";
         
     | 
| 
       2 
     | 
    
         
            -
            import React, { useMemo, useRef, useState } from "react";
         
     | 
| 
       3 
     | 
    
         
            -
            import { useCallback } from "react";
         
     | 
| 
       4 
     | 
    
         
            -
            import invariant from "tiny-invariant";
         
     | 
| 
       5 
     | 
    
         
            -
            import { InternalFormContextValue } from "../formContext";
         
     | 
| 
       6 
     | 
    
         
            -
            import {
         
     | 
| 
       7 
     | 
    
         
            -
              useFieldDefaultValue,
         
     | 
| 
       8 
     | 
    
         
            -
              useFieldError,
         
     | 
| 
       9 
     | 
    
         
            -
              useInternalFormContext,
         
     | 
| 
       10 
     | 
    
         
            -
              useInternalHasBeenSubmitted,
         
     | 
| 
       11 
     | 
    
         
            -
              useSmartValidate,
         
     | 
| 
       12 
     | 
    
         
            -
            } from "../hooks";
         
     | 
| 
       13 
     | 
    
         
            -
            import * as arrayUtil from "./arrayUtil";
         
     | 
| 
       14 
     | 
    
         
            -
            import { useRegisterControlledField } from "./controlledFields";
         
     | 
| 
       15 
     | 
    
         
            -
            import { useFormStore } from "./storeHooks";
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
            export type FieldArrayValidationBehavior = "onChange" | "onSubmit";
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
            export type FieldArrayValidationBehaviorOptions = {
         
     | 
| 
       20 
     | 
    
         
            -
              initial: FieldArrayValidationBehavior;
         
     | 
| 
       21 
     | 
    
         
            -
              whenSubmitted: FieldArrayValidationBehavior;
         
     | 
| 
       22 
     | 
    
         
            -
            };
         
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
            export type FieldArrayItem<T> = {
         
     | 
| 
       25 
     | 
    
         
            -
              /**
         
     | 
| 
       26 
     | 
    
         
            -
               * The default value of the item.
         
     | 
| 
       27 
     | 
    
         
            -
               * This does not update as the field is changed by the user.
         
     | 
| 
       28 
     | 
    
         
            -
               */
         
     | 
| 
       29 
     | 
    
         
            -
              defaultValue: T;
         
     | 
| 
       30 
     | 
    
         
            -
              /**
         
     | 
| 
       31 
     | 
    
         
            -
               * A unique key for the item.
         
     | 
| 
       32 
     | 
    
         
            -
               * Use this as the key prop when rendering the item.
         
     | 
| 
       33 
     | 
    
         
            -
               */
         
     | 
| 
       34 
     | 
    
         
            -
              key: string;
         
     | 
| 
       35 
     | 
    
         
            -
            };
         
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
            const useInternalFieldArray = (
         
     | 
| 
       38 
     | 
    
         
            -
              context: InternalFormContextValue,
         
     | 
| 
       39 
     | 
    
         
            -
              field: string,
         
     | 
| 
       40 
     | 
    
         
            -
              validationBehavior?: Partial<FieldArrayValidationBehaviorOptions>
         
     | 
| 
       41 
     | 
    
         
            -
            ) => {
         
     | 
| 
       42 
     | 
    
         
            -
              const value = useFieldDefaultValue(field, context);
         
     | 
| 
       43 
     | 
    
         
            -
              useRegisterControlledField(context, field);
         
     | 
| 
       44 
     | 
    
         
            -
              const hasBeenSubmitted = useInternalHasBeenSubmitted(context.formId);
         
     | 
| 
       45 
     | 
    
         
            -
              const validateField = useSmartValidate(context.formId);
         
     | 
| 
       46 
     | 
    
         
            -
              const error = useFieldError(field, context);
         
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
              const resolvedValidationBehavior: FieldArrayValidationBehaviorOptions = {
         
     | 
| 
       49 
     | 
    
         
            -
                initial: "onSubmit",
         
     | 
| 
       50 
     | 
    
         
            -
                whenSubmitted: "onChange",
         
     | 
| 
       51 
     | 
    
         
            -
                ...validationBehavior,
         
     | 
| 
       52 
     | 
    
         
            -
              };
         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
              const behavior = hasBeenSubmitted
         
     | 
| 
       55 
     | 
    
         
            -
                ? resolvedValidationBehavior.whenSubmitted
         
     | 
| 
       56 
     | 
    
         
            -
                : resolvedValidationBehavior.initial;
         
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
              const maybeValidate = useCallback(() => {
         
     | 
| 
       59 
     | 
    
         
            -
                if (behavior === "onChange") {
         
     | 
| 
       60 
     | 
    
         
            -
                  validateField({ alwaysIncludeErrorsFromFields: [field] });
         
     | 
| 
       61 
     | 
    
         
            -
                }
         
     | 
| 
       62 
     | 
    
         
            -
              }, [behavior, field, validateField]);
         
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
              invariant(
         
     | 
| 
       65 
     | 
    
         
            -
                value === undefined || value === null || Array.isArray(value),
         
     | 
| 
       66 
     | 
    
         
            -
                `FieldArray: defaultValue value for ${field} must be an array, null, or undefined`
         
     | 
| 
       67 
     | 
    
         
            -
              );
         
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
              const arr = useFormStore(
         
     | 
| 
       70 
     | 
    
         
            -
                context.formId,
         
     | 
| 
       71 
     | 
    
         
            -
                (state) => state.controlledFields.array
         
     | 
| 
       72 
     | 
    
         
            -
              );
         
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
       74 
     | 
    
         
            -
              const arrayValue = useMemo<unknown[]>(() => value ?? [], [value]);
         
     | 
| 
       75 
     | 
    
         
            -
              const keyRef = useRef<string[]>([]);
         
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
       77 
     | 
    
         
            -
              // If the lengths don't match up it means one of two things
         
     | 
| 
       78 
     | 
    
         
            -
              // 1. The array has been modified outside of this hook
         
     | 
| 
       79 
     | 
    
         
            -
              // 2. We're initializing the array
         
     | 
| 
       80 
     | 
    
         
            -
              if (keyRef.current.length !== arrayValue.length) {
         
     | 
| 
       81 
     | 
    
         
            -
                keyRef.current = arrayValue.map(() => nanoid());
         
     | 
| 
       82 
     | 
    
         
            -
              }
         
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
       84 
     | 
    
         
            -
              const helpers = useMemo(
         
     | 
| 
       85 
     | 
    
         
            -
                () => ({
         
     | 
| 
       86 
     | 
    
         
            -
                  push: (item: any) => {
         
     | 
| 
       87 
     | 
    
         
            -
                    arr.push(field, item);
         
     | 
| 
       88 
     | 
    
         
            -
                    keyRef.current.push(nanoid());
         
     | 
| 
       89 
     | 
    
         
            -
                    maybeValidate();
         
     | 
| 
       90 
     | 
    
         
            -
                  },
         
     | 
| 
       91 
     | 
    
         
            -
                  swap: (indexA: number, indexB: number) => {
         
     | 
| 
       92 
     | 
    
         
            -
                    arr.swap(field, indexA, indexB);
         
     | 
| 
       93 
     | 
    
         
            -
                    arrayUtil.swap(keyRef.current, indexA, indexB);
         
     | 
| 
       94 
     | 
    
         
            -
                    maybeValidate();
         
     | 
| 
       95 
     | 
    
         
            -
                  },
         
     | 
| 
       96 
     | 
    
         
            -
                  move: (from: number, to: number) => {
         
     | 
| 
       97 
     | 
    
         
            -
                    arr.move(field, from, to);
         
     | 
| 
       98 
     | 
    
         
            -
                    arrayUtil.move(keyRef.current, from, to);
         
     | 
| 
       99 
     | 
    
         
            -
                    maybeValidate();
         
     | 
| 
       100 
     | 
    
         
            -
                  },
         
     | 
| 
       101 
     | 
    
         
            -
                  insert: (index: number, value: any) => {
         
     | 
| 
       102 
     | 
    
         
            -
                    arr.insert(field, index, value);
         
     | 
| 
       103 
     | 
    
         
            -
                    arrayUtil.insert(keyRef.current, index, nanoid());
         
     | 
| 
       104 
     | 
    
         
            -
                    maybeValidate();
         
     | 
| 
       105 
     | 
    
         
            -
                  },
         
     | 
| 
       106 
     | 
    
         
            -
                  unshift: (value: any) => {
         
     | 
| 
       107 
     | 
    
         
            -
                    arr.unshift(field, value);
         
     | 
| 
       108 
     | 
    
         
            -
                    keyRef.current.unshift(nanoid());
         
     | 
| 
       109 
     | 
    
         
            -
                    maybeValidate();
         
     | 
| 
       110 
     | 
    
         
            -
                  },
         
     | 
| 
       111 
     | 
    
         
            -
                  remove: (index: number) => {
         
     | 
| 
       112 
     | 
    
         
            -
                    arr.remove(field, index);
         
     | 
| 
       113 
     | 
    
         
            -
                    arrayUtil.remove(keyRef.current, index);
         
     | 
| 
       114 
     | 
    
         
            -
                    maybeValidate();
         
     | 
| 
       115 
     | 
    
         
            -
                  },
         
     | 
| 
       116 
     | 
    
         
            -
                  pop: () => {
         
     | 
| 
       117 
     | 
    
         
            -
                    arr.pop(field);
         
     | 
| 
       118 
     | 
    
         
            -
                    keyRef.current.pop();
         
     | 
| 
       119 
     | 
    
         
            -
                    maybeValidate();
         
     | 
| 
       120 
     | 
    
         
            -
                  },
         
     | 
| 
       121 
     | 
    
         
            -
                  replace: (index: number, value: any) => {
         
     | 
| 
       122 
     | 
    
         
            -
                    arr.replace(field, index, value);
         
     | 
| 
       123 
     | 
    
         
            -
                    keyRef.current[index] = nanoid();
         
     | 
| 
       124 
     | 
    
         
            -
                    maybeValidate();
         
     | 
| 
       125 
     | 
    
         
            -
                  },
         
     | 
| 
       126 
     | 
    
         
            -
                }),
         
     | 
| 
       127 
     | 
    
         
            -
                [arr, field, maybeValidate]
         
     | 
| 
       128 
     | 
    
         
            -
              );
         
     | 
| 
       129 
     | 
    
         
            -
             
     | 
| 
       130 
     | 
    
         
            -
              const valueWithKeys = useMemo(() => {
         
     | 
| 
       131 
     | 
    
         
            -
                const result: { defaultValue: any; key: string }[] = [];
         
     | 
| 
       132 
     | 
    
         
            -
                arrayValue.forEach((item, index) => {
         
     | 
| 
       133 
     | 
    
         
            -
                  result[index] = {
         
     | 
| 
       134 
     | 
    
         
            -
                    key: keyRef.current[index],
         
     | 
| 
       135 
     | 
    
         
            -
                    defaultValue: item,
         
     | 
| 
       136 
     | 
    
         
            -
                  };
         
     | 
| 
       137 
     | 
    
         
            -
                });
         
     | 
| 
       138 
     | 
    
         
            -
                return result;
         
     | 
| 
       139 
     | 
    
         
            -
              }, [arrayValue]);
         
     | 
| 
       140 
     | 
    
         
            -
             
     | 
| 
       141 
     | 
    
         
            -
              return [valueWithKeys, helpers, error] as const;
         
     | 
| 
       142 
     | 
    
         
            -
            };
         
     | 
| 
       143 
     | 
    
         
            -
             
     | 
| 
       144 
     | 
    
         
            -
            export type FieldArrayHelpers<Item = any> = {
         
     | 
| 
       145 
     | 
    
         
            -
              push: (item: Item) => void;
         
     | 
| 
       146 
     | 
    
         
            -
              swap: (indexA: number, indexB: number) => void;
         
     | 
| 
       147 
     | 
    
         
            -
              move: (from: number, to: number) => void;
         
     | 
| 
       148 
     | 
    
         
            -
              insert: (index: number, value: Item) => void;
         
     | 
| 
       149 
     | 
    
         
            -
              unshift: (value: Item) => void;
         
     | 
| 
       150 
     | 
    
         
            -
              remove: (index: number) => void;
         
     | 
| 
       151 
     | 
    
         
            -
              pop: () => void;
         
     | 
| 
       152 
     | 
    
         
            -
              replace: (index: number, value: Item) => void;
         
     | 
| 
       153 
     | 
    
         
            -
            };
         
     | 
| 
       154 
     | 
    
         
            -
             
     | 
| 
       155 
     | 
    
         
            -
            export type UseFieldArrayOptions = {
         
     | 
| 
       156 
     | 
    
         
            -
              formId?: string;
         
     | 
| 
       157 
     | 
    
         
            -
              validationBehavior?: Partial<FieldArrayValidationBehaviorOptions>;
         
     | 
| 
       158 
     | 
    
         
            -
            };
         
     | 
| 
       159 
     | 
    
         
            -
             
     | 
| 
       160 
     | 
    
         
            -
            export function useFieldArray<Item = any>(
         
     | 
| 
       161 
     | 
    
         
            -
              name: string,
         
     | 
| 
       162 
     | 
    
         
            -
              { formId, validationBehavior }: UseFieldArrayOptions = {}
         
     | 
| 
       163 
     | 
    
         
            -
            ) {
         
     | 
| 
       164 
     | 
    
         
            -
              const context = useInternalFormContext(formId, "FieldArray");
         
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
       166 
     | 
    
         
            -
              return useInternalFieldArray(context, name, validationBehavior) as [
         
     | 
| 
       167 
     | 
    
         
            -
                items: FieldArrayItem<Item>[],
         
     | 
| 
       168 
     | 
    
         
            -
                helpers: FieldArrayHelpers,
         
     | 
| 
       169 
     | 
    
         
            -
                error: string | undefined
         
     | 
| 
       170 
     | 
    
         
            -
              ];
         
     | 
| 
       171 
     | 
    
         
            -
            }
         
     | 
| 
       172 
     | 
    
         
            -
             
     | 
| 
       173 
     | 
    
         
            -
            export type FieldArrayProps<Item> = {
         
     | 
| 
       174 
     | 
    
         
            -
              name: string;
         
     | 
| 
       175 
     | 
    
         
            -
              children: (
         
     | 
| 
       176 
     | 
    
         
            -
                items: FieldArrayItem<Item>[],
         
     | 
| 
       177 
     | 
    
         
            -
                helpers: FieldArrayHelpers<Item>,
         
     | 
| 
       178 
     | 
    
         
            -
                error: string | undefined
         
     | 
| 
       179 
     | 
    
         
            -
              ) => React.ReactNode;
         
     | 
| 
       180 
     | 
    
         
            -
              formId?: string;
         
     | 
| 
       181 
     | 
    
         
            -
              validationBehavior?: FieldArrayValidationBehaviorOptions;
         
     | 
| 
       182 
     | 
    
         
            -
            };
         
     | 
| 
       183 
     | 
    
         
            -
             
     | 
| 
       184 
     | 
    
         
            -
            export function FieldArray<Item = any>({
         
     | 
| 
       185 
     | 
    
         
            -
              name,
         
     | 
| 
       186 
     | 
    
         
            -
              children,
         
     | 
| 
       187 
     | 
    
         
            -
              formId,
         
     | 
| 
       188 
     | 
    
         
            -
              validationBehavior,
         
     | 
| 
       189 
     | 
    
         
            -
            }: FieldArrayProps<Item>) {
         
     | 
| 
       190 
     | 
    
         
            -
              const context = useInternalFormContext(formId, "FieldArray");
         
     | 
| 
       191 
     | 
    
         
            -
              const [value, helpers, error] = useInternalFieldArray(
         
     | 
| 
       192 
     | 
    
         
            -
                context,
         
     | 
| 
       193 
     | 
    
         
            -
                name,
         
     | 
| 
       194 
     | 
    
         
            -
                validationBehavior
         
     | 
| 
       195 
     | 
    
         
            -
              );
         
     | 
| 
       196 
     | 
    
         
            -
              return <>{children(value, helpers, error)}</>;
         
     | 
| 
       197 
     | 
    
         
            -
            }
         
     | 
| 
         @@ -1,9 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            import { FormState, useRootFormStore } from "./createFormStore";
         
     | 
| 
       2 
     | 
    
         
            -
            import { InternalFormId } from "./types";
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
            export const useFormStore = <T>(
         
     | 
| 
       5 
     | 
    
         
            -
              formId: InternalFormId,
         
     | 
| 
       6 
     | 
    
         
            -
              selector: (state: FormState) => T
         
     | 
| 
       7 
     | 
    
         
            -
            ) => {
         
     | 
| 
       8 
     | 
    
         
            -
              return useRootFormStore((state) => selector(state.form(formId)));
         
     | 
| 
       9 
     | 
    
         
            -
            };
         
     | 
| 
         @@ -1 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            export type InternalFormId = string | symbol;
         
     | 
| 
         @@ -1,15 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            import { useEffect, useRef } from "react";
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            export function useSubmitComplete(isSubmitting: boolean, callback: () => void) {
         
     | 
| 
       4 
     | 
    
         
            -
              const isPending = useRef(false);
         
     | 
| 
       5 
     | 
    
         
            -
              useEffect(() => {
         
     | 
| 
       6 
     | 
    
         
            -
                if (isSubmitting) {
         
     | 
| 
       7 
     | 
    
         
            -
                  isPending.current = true;
         
     | 
| 
       8 
     | 
    
         
            -
                }
         
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
                if (!isSubmitting && isPending.current) {
         
     | 
| 
       11 
     | 
    
         
            -
                  isPending.current = false;
         
     | 
| 
       12 
     | 
    
         
            -
                  callback();
         
     | 
| 
       13 
     | 
    
         
            -
                }
         
     | 
| 
       14 
     | 
    
         
            -
              });
         
     | 
| 
       15 
     | 
    
         
            -
            }
         
     | 
    
        package/src/internal/util.ts
    DELETED
    
    | 
         @@ -1,39 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            import type React from "react";
         
     | 
| 
       2 
     | 
    
         
            -
            import { useEffect, useLayoutEffect, useRef } from "react";
         
     | 
| 
       3 
     | 
    
         
            -
            import * as R from "remeda";
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
            export const omit = (obj: any, ...keys: string[]) => {
         
     | 
| 
       6 
     | 
    
         
            -
              const result = { ...obj };
         
     | 
| 
       7 
     | 
    
         
            -
              for (const key of keys) {
         
     | 
| 
       8 
     | 
    
         
            -
                delete result[key];
         
     | 
| 
       9 
     | 
    
         
            -
              }
         
     | 
| 
       10 
     | 
    
         
            -
              return result;
         
     | 
| 
       11 
     | 
    
         
            -
            };
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
            export const mergeRefs = <T = any>(
         
     | 
| 
       14 
     | 
    
         
            -
              refs: Array<React.MutableRefObject<T> | React.LegacyRef<T> | undefined>
         
     | 
| 
       15 
     | 
    
         
            -
            ): React.RefCallback<T> => {
         
     | 
| 
       16 
     | 
    
         
            -
              return (value: T) => {
         
     | 
| 
       17 
     | 
    
         
            -
                refs.filter(Boolean).forEach((ref) => {
         
     | 
| 
       18 
     | 
    
         
            -
                  if (typeof ref === "function") {
         
     | 
| 
       19 
     | 
    
         
            -
                    ref(value);
         
     | 
| 
       20 
     | 
    
         
            -
                  } else if (ref != null) {
         
     | 
| 
       21 
     | 
    
         
            -
                    (ref as React.MutableRefObject<T | null>).current = value;
         
     | 
| 
       22 
     | 
    
         
            -
                  }
         
     | 
| 
       23 
     | 
    
         
            -
                });
         
     | 
| 
       24 
     | 
    
         
            -
              };
         
     | 
| 
       25 
     | 
    
         
            -
            };
         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
            export const useIsomorphicLayoutEffect =
         
     | 
| 
       28 
     | 
    
         
            -
              typeof window !== "undefined" ? useLayoutEffect : useEffect;
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
            export const useDeepEqualsMemo = <T>(item: T): T => {
         
     | 
| 
       31 
     | 
    
         
            -
              const ref = useRef<T>(item);
         
     | 
| 
       32 
     | 
    
         
            -
              const areEqual = ref.current === item || R.equals(ref.current, item);
         
     | 
| 
       33 
     | 
    
         
            -
              useEffect(() => {
         
     | 
| 
       34 
     | 
    
         
            -
                if (!areEqual) {
         
     | 
| 
       35 
     | 
    
         
            -
                  ref.current = item;
         
     | 
| 
       36 
     | 
    
         
            -
                }
         
     | 
| 
       37 
     | 
    
         
            -
              });
         
     | 
| 
       38 
     | 
    
         
            -
              return areEqual ? ref.current : item;
         
     | 
| 
       39 
     | 
    
         
            -
            };
         
     | 
    
        package/src/server.ts
    DELETED
    
    | 
         @@ -1,53 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            import { json } from "@remix-run/server-runtime";
         
     | 
| 
       2 
     | 
    
         
            -
            import {
         
     | 
| 
       3 
     | 
    
         
            -
              formDefaultValuesKey,
         
     | 
| 
       4 
     | 
    
         
            -
              FORM_DEFAULTS_FIELD,
         
     | 
| 
       5 
     | 
    
         
            -
            } from "./internal/constants";
         
     | 
| 
       6 
     | 
    
         
            -
            import {
         
     | 
| 
       7 
     | 
    
         
            -
              ValidatorError,
         
     | 
| 
       8 
     | 
    
         
            -
              ValidationErrorResponseData,
         
     | 
| 
       9 
     | 
    
         
            -
            } from "./validation/types";
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
            /**
         
     | 
| 
       12 
     | 
    
         
            -
             * Takes the errors from a `Validator` and returns a `Response`.
         
     | 
| 
       13 
     | 
    
         
            -
             * When you return this from your action, `ValidatedForm` on the frontend will automatically
         
     | 
| 
       14 
     | 
    
         
            -
             * display the errors on the correct fields on the correct form.
         
     | 
| 
       15 
     | 
    
         
            -
             *
         
     | 
| 
       16 
     | 
    
         
            -
             * You can also provide a second argument to `validationError`
         
     | 
| 
       17 
     | 
    
         
            -
             * to specify how to repopulate the form when JS is disabled.
         
     | 
| 
       18 
     | 
    
         
            -
             *
         
     | 
| 
       19 
     | 
    
         
            -
             * @example
         
     | 
| 
       20 
     | 
    
         
            -
             * ```ts
         
     | 
| 
       21 
     | 
    
         
            -
             * const result = validator.validate(await request.formData());
         
     | 
| 
       22 
     | 
    
         
            -
             * if (result.error) return validationError(result.error, result.submittedData);
         
     | 
| 
       23 
     | 
    
         
            -
             * ```
         
     | 
| 
       24 
     | 
    
         
            -
             */
         
     | 
| 
       25 
     | 
    
         
            -
            export function validationError(
         
     | 
| 
       26 
     | 
    
         
            -
              error: ValidatorError,
         
     | 
| 
       27 
     | 
    
         
            -
              repopulateFields?: unknown,
         
     | 
| 
       28 
     | 
    
         
            -
              init?: ResponseInit
         
     | 
| 
       29 
     | 
    
         
            -
            ) {
         
     | 
| 
       30 
     | 
    
         
            -
              return json<ValidationErrorResponseData>(
         
     | 
| 
       31 
     | 
    
         
            -
                {
         
     | 
| 
       32 
     | 
    
         
            -
                  fieldErrors: error.fieldErrors,
         
     | 
| 
       33 
     | 
    
         
            -
                  subaction: error.subaction,
         
     | 
| 
       34 
     | 
    
         
            -
                  repopulateFields,
         
     | 
| 
       35 
     | 
    
         
            -
                  formId: error.formId,
         
     | 
| 
       36 
     | 
    
         
            -
                },
         
     | 
| 
       37 
     | 
    
         
            -
                { status: 422, ...init }
         
     | 
| 
       38 
     | 
    
         
            -
              );
         
     | 
| 
       39 
     | 
    
         
            -
            }
         
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
            export type FormDefaults = {
         
     | 
| 
       42 
     | 
    
         
            -
              [formDefaultsKey: `${typeof FORM_DEFAULTS_FIELD}_${string}`]: any;
         
     | 
| 
       43 
     | 
    
         
            -
            };
         
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
            // FIXME: Remove after https://github.com/egoist/tsup/issues/813 is fixed
         
     | 
| 
       46 
     | 
    
         
            -
            export type internal_FORM_DEFAULTS_FIELD = typeof FORM_DEFAULTS_FIELD;
         
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
            export const setFormDefaults = <DataType = any>(
         
     | 
| 
       49 
     | 
    
         
            -
              formId: string,
         
     | 
| 
       50 
     | 
    
         
            -
              defaultValues: Partial<DataType>
         
     | 
| 
       51 
     | 
    
         
            -
            ): FormDefaults => ({
         
     | 
| 
       52 
     | 
    
         
            -
              [formDefaultValuesKey(formId)]: defaultValues,
         
     | 
| 
       53 
     | 
    
         
            -
            });
         
     | 
| 
         @@ -1,170 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            import { useMemo } from "react";
         
     | 
| 
       2 
     | 
    
         
            -
            import {} from "../internal/getInputProps";
         
     | 
| 
       3 
     | 
    
         
            -
            import {
         
     | 
| 
       4 
     | 
    
         
            -
              useInternalFormContext,
         
     | 
| 
       5 
     | 
    
         
            -
              useClearError,
         
     | 
| 
       6 
     | 
    
         
            -
              useSetTouched,
         
     | 
| 
       7 
     | 
    
         
            -
              useDefaultValuesForForm,
         
     | 
| 
       8 
     | 
    
         
            -
              useFieldErrorsForForm,
         
     | 
| 
       9 
     | 
    
         
            -
              useInternalIsSubmitting,
         
     | 
| 
       10 
     | 
    
         
            -
              useInternalHasBeenSubmitted,
         
     | 
| 
       11 
     | 
    
         
            -
              useTouchedFields,
         
     | 
| 
       12 
     | 
    
         
            -
              useInternalIsValid,
         
     | 
| 
       13 
     | 
    
         
            -
              useFieldErrors,
         
     | 
| 
       14 
     | 
    
         
            -
              useValidate,
         
     | 
| 
       15 
     | 
    
         
            -
              useSetFieldErrors,
         
     | 
| 
       16 
     | 
    
         
            -
              useResetFormElement,
         
     | 
| 
       17 
     | 
    
         
            -
              useSyncedDefaultValues,
         
     | 
| 
       18 
     | 
    
         
            -
              useFormActionProp,
         
     | 
| 
       19 
     | 
    
         
            -
              useFormSubactionProp,
         
     | 
| 
       20 
     | 
    
         
            -
              useSubmitForm,
         
     | 
| 
       21 
     | 
    
         
            -
              useFormValues,
         
     | 
| 
       22 
     | 
    
         
            -
              useSmartValidate,
         
     | 
| 
       23 
     | 
    
         
            -
            } from "../internal/hooks";
         
     | 
| 
       24 
     | 
    
         
            -
            import {
         
     | 
| 
       25 
     | 
    
         
            -
              FieldErrors,
         
     | 
| 
       26 
     | 
    
         
            -
              TouchedFields,
         
     | 
| 
       27 
     | 
    
         
            -
              ValidationResult,
         
     | 
| 
       28 
     | 
    
         
            -
            } from "../validation/types";
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
            export type FormState = {
         
     | 
| 
       31 
     | 
    
         
            -
              fieldErrors: FieldErrors;
         
     | 
| 
       32 
     | 
    
         
            -
              isSubmitting: boolean;
         
     | 
| 
       33 
     | 
    
         
            -
              hasBeenSubmitted: boolean;
         
     | 
| 
       34 
     | 
    
         
            -
              touchedFields: TouchedFields;
         
     | 
| 
       35 
     | 
    
         
            -
              defaultValues: { [fieldName: string]: any };
         
     | 
| 
       36 
     | 
    
         
            -
              action?: string;
         
     | 
| 
       37 
     | 
    
         
            -
              subaction?: string;
         
     | 
| 
       38 
     | 
    
         
            -
              isValid: boolean;
         
     | 
| 
       39 
     | 
    
         
            -
            };
         
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
            /**
         
     | 
| 
       42 
     | 
    
         
            -
             * Returns information about the form.
         
     | 
| 
       43 
     | 
    
         
            -
             *
         
     | 
| 
       44 
     | 
    
         
            -
             * @param formId the id of the form. Only necessary if being used outside a ValidatedForm.
         
     | 
| 
       45 
     | 
    
         
            -
             */
         
     | 
| 
       46 
     | 
    
         
            -
            export const useFormState = (formId?: string): FormState => {
         
     | 
| 
       47 
     | 
    
         
            -
              const formContext = useInternalFormContext(formId, "useFormState");
         
     | 
| 
       48 
     | 
    
         
            -
              const isSubmitting = useInternalIsSubmitting(formContext.formId);
         
     | 
| 
       49 
     | 
    
         
            -
              const hasBeenSubmitted = useInternalHasBeenSubmitted(formContext.formId);
         
     | 
| 
       50 
     | 
    
         
            -
              const touchedFields = useTouchedFields(formContext.formId);
         
     | 
| 
       51 
     | 
    
         
            -
              const isValid = useInternalIsValid(formContext.formId);
         
     | 
| 
       52 
     | 
    
         
            -
              const action = useFormActionProp(formContext.formId);
         
     | 
| 
       53 
     | 
    
         
            -
              const subaction = useFormSubactionProp(formContext.formId);
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
              const syncedDefaultValues = useSyncedDefaultValues(formContext.formId);
         
     | 
| 
       56 
     | 
    
         
            -
              const defaultValuesToUse = useDefaultValuesForForm(formContext);
         
     | 
| 
       57 
     | 
    
         
            -
              const hydratedDefaultValues =
         
     | 
| 
       58 
     | 
    
         
            -
                defaultValuesToUse.hydrateTo(syncedDefaultValues);
         
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
              const fieldErrorsFromState = useFieldErrors(formContext.formId);
         
     | 
| 
       61 
     | 
    
         
            -
              const fieldErrorsToUse = useFieldErrorsForForm(formContext);
         
     | 
| 
       62 
     | 
    
         
            -
              const hydratedFieldErrors = fieldErrorsToUse.hydrateTo(fieldErrorsFromState);
         
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
              return useMemo(
         
     | 
| 
       65 
     | 
    
         
            -
                () => ({
         
     | 
| 
       66 
     | 
    
         
            -
                  action,
         
     | 
| 
       67 
     | 
    
         
            -
                  subaction,
         
     | 
| 
       68 
     | 
    
         
            -
                  defaultValues: hydratedDefaultValues,
         
     | 
| 
       69 
     | 
    
         
            -
                  fieldErrors: hydratedFieldErrors ?? {},
         
     | 
| 
       70 
     | 
    
         
            -
                  hasBeenSubmitted,
         
     | 
| 
       71 
     | 
    
         
            -
                  isSubmitting,
         
     | 
| 
       72 
     | 
    
         
            -
                  touchedFields,
         
     | 
| 
       73 
     | 
    
         
            -
                  isValid,
         
     | 
| 
       74 
     | 
    
         
            -
                }),
         
     | 
| 
       75 
     | 
    
         
            -
                [
         
     | 
| 
       76 
     | 
    
         
            -
                  action,
         
     | 
| 
       77 
     | 
    
         
            -
                  hasBeenSubmitted,
         
     | 
| 
       78 
     | 
    
         
            -
                  hydratedDefaultValues,
         
     | 
| 
       79 
     | 
    
         
            -
                  hydratedFieldErrors,
         
     | 
| 
       80 
     | 
    
         
            -
                  isSubmitting,
         
     | 
| 
       81 
     | 
    
         
            -
                  isValid,
         
     | 
| 
       82 
     | 
    
         
            -
                  subaction,
         
     | 
| 
       83 
     | 
    
         
            -
                  touchedFields,
         
     | 
| 
       84 
     | 
    
         
            -
                ]
         
     | 
| 
       85 
     | 
    
         
            -
              );
         
     | 
| 
       86 
     | 
    
         
            -
            };
         
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
       88 
     | 
    
         
            -
            export type FormHelpers = {
         
     | 
| 
       89 
     | 
    
         
            -
              /**
         
     | 
| 
       90 
     | 
    
         
            -
               * Clear the error of the specified field.
         
     | 
| 
       91 
     | 
    
         
            -
               */
         
     | 
| 
       92 
     | 
    
         
            -
              clearError: (fieldName: string) => void;
         
     | 
| 
       93 
     | 
    
         
            -
              /**
         
     | 
| 
       94 
     | 
    
         
            -
               * Validate the specified field.
         
     | 
| 
       95 
     | 
    
         
            -
               */
         
     | 
| 
       96 
     | 
    
         
            -
              validateField: (fieldName: string) => Promise<string | null>;
         
     | 
| 
       97 
     | 
    
         
            -
              /**
         
     | 
| 
       98 
     | 
    
         
            -
               * Change the touched state of the specified field.
         
     | 
| 
       99 
     | 
    
         
            -
               */
         
     | 
| 
       100 
     | 
    
         
            -
              setTouched: (fieldName: string, touched: boolean) => void;
         
     | 
| 
       101 
     | 
    
         
            -
              /**
         
     | 
| 
       102 
     | 
    
         
            -
               * Validate the whole form and populate any errors.
         
     | 
| 
       103 
     | 
    
         
            -
               */
         
     | 
| 
       104 
     | 
    
         
            -
              validate: () => Promise<ValidationResult<unknown>>;
         
     | 
| 
       105 
     | 
    
         
            -
              /**
         
     | 
| 
       106 
     | 
    
         
            -
               * Clears all errors on the form.
         
     | 
| 
       107 
     | 
    
         
            -
               */
         
     | 
| 
       108 
     | 
    
         
            -
              clearAllErrors: () => void;
         
     | 
| 
       109 
     | 
    
         
            -
              /**
         
     | 
| 
       110 
     | 
    
         
            -
               * Resets the form.
         
     | 
| 
       111 
     | 
    
         
            -
               *
         
     | 
| 
       112 
     | 
    
         
            -
               * _Note_: The equivalent behavior can be achieved by calling formElement.reset()
         
     | 
| 
       113 
     | 
    
         
            -
               * or clicking a button element with `type="reset"`.
         
     | 
| 
       114 
     | 
    
         
            -
               */
         
     | 
| 
       115 
     | 
    
         
            -
              reset: () => void;
         
     | 
| 
       116 
     | 
    
         
            -
              /**
         
     | 
| 
       117 
     | 
    
         
            -
               * Submits the form, running all validations first.
         
     | 
| 
       118 
     | 
    
         
            -
               *
         
     | 
| 
       119 
     | 
    
         
            -
               * _Note_: This is equivalent to clicking a button element with `type="submit"` or calling formElement.submit().
         
     | 
| 
       120 
     | 
    
         
            -
               */
         
     | 
| 
       121 
     | 
    
         
            -
              submit: () => void;
         
     | 
| 
       122 
     | 
    
         
            -
              /**
         
     | 
| 
       123 
     | 
    
         
            -
               * Returns the current form values as FormData
         
     | 
| 
       124 
     | 
    
         
            -
               */
         
     | 
| 
       125 
     | 
    
         
            -
              getValues: () => FormData;
         
     | 
| 
       126 
     | 
    
         
            -
            };
         
     | 
| 
       127 
     | 
    
         
            -
             
     | 
| 
       128 
     | 
    
         
            -
            /**
         
     | 
| 
       129 
     | 
    
         
            -
             * Returns helpers that can be used to update the form state.
         
     | 
| 
       130 
     | 
    
         
            -
             *
         
     | 
| 
       131 
     | 
    
         
            -
             * @param formId the id of the form. Only necessary if being used outside a ValidatedForm.
         
     | 
| 
       132 
     | 
    
         
            -
             */
         
     | 
| 
       133 
     | 
    
         
            -
            export const useFormHelpers = (formId?: string): FormHelpers => {
         
     | 
| 
       134 
     | 
    
         
            -
              const formContext = useInternalFormContext(formId, "useFormHelpers");
         
     | 
| 
       135 
     | 
    
         
            -
              const setTouched = useSetTouched(formContext);
         
     | 
| 
       136 
     | 
    
         
            -
              const validateField = useSmartValidate(formContext.formId);
         
     | 
| 
       137 
     | 
    
         
            -
              const validate = useValidate(formContext.formId);
         
     | 
| 
       138 
     | 
    
         
            -
              const clearError = useClearError(formContext);
         
     | 
| 
       139 
     | 
    
         
            -
              const setFieldErrors = useSetFieldErrors(formContext.formId);
         
     | 
| 
       140 
     | 
    
         
            -
              const reset = useResetFormElement(formContext.formId);
         
     | 
| 
       141 
     | 
    
         
            -
              const submit = useSubmitForm(formContext.formId);
         
     | 
| 
       142 
     | 
    
         
            -
              const getValues = useFormValues(formContext.formId);
         
     | 
| 
       143 
     | 
    
         
            -
              return useMemo(
         
     | 
| 
       144 
     | 
    
         
            -
                () => ({
         
     | 
| 
       145 
     | 
    
         
            -
                  setTouched,
         
     | 
| 
       146 
     | 
    
         
            -
                  validateField: async (fieldName: string) => {
         
     | 
| 
       147 
     | 
    
         
            -
                    const res = await validateField({
         
     | 
| 
       148 
     | 
    
         
            -
                      alwaysIncludeErrorsFromFields: [fieldName],
         
     | 
| 
       149 
     | 
    
         
            -
                    });
         
     | 
| 
       150 
     | 
    
         
            -
                    return res.error?.fieldErrors[fieldName] ?? null;
         
     | 
| 
       151 
     | 
    
         
            -
                  },
         
     | 
| 
       152 
     | 
    
         
            -
                  clearError,
         
     | 
| 
       153 
     | 
    
         
            -
                  validate,
         
     | 
| 
       154 
     | 
    
         
            -
                  clearAllErrors: () => setFieldErrors({}),
         
     | 
| 
       155 
     | 
    
         
            -
                  reset,
         
     | 
| 
       156 
     | 
    
         
            -
                  submit,
         
     | 
| 
       157 
     | 
    
         
            -
                  getValues,
         
     | 
| 
       158 
     | 
    
         
            -
                }),
         
     | 
| 
       159 
     | 
    
         
            -
                [
         
     | 
| 
       160 
     | 
    
         
            -
                  clearError,
         
     | 
| 
       161 
     | 
    
         
            -
                  reset,
         
     | 
| 
       162 
     | 
    
         
            -
                  setFieldErrors,
         
     | 
| 
       163 
     | 
    
         
            -
                  setTouched,
         
     | 
| 
       164 
     | 
    
         
            -
                  submit,
         
     | 
| 
       165 
     | 
    
         
            -
                  validate,
         
     | 
| 
       166 
     | 
    
         
            -
                  validateField,
         
     | 
| 
       167 
     | 
    
         
            -
                  getValues,
         
     | 
| 
       168 
     | 
    
         
            -
                ]
         
     | 
| 
       169 
     | 
    
         
            -
              );
         
     | 
| 
       170 
     | 
    
         
            -
            };
         
     | 
| 
         @@ -1,147 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            import { useCallback, useMemo } from "react";
         
     | 
| 
       2 
     | 
    
         
            -
            import {
         
     | 
| 
       3 
     | 
    
         
            -
              useInternalFormContext,
         
     | 
| 
       4 
     | 
    
         
            -
              useRegisterReceiveFocus,
         
     | 
| 
       5 
     | 
    
         
            -
            } from "./internal/hooks";
         
     | 
| 
       6 
     | 
    
         
            -
            import { useFormHelpers, useFormState } from "./unreleased/formStateHooks";
         
     | 
| 
       7 
     | 
    
         
            -
            import {
         
     | 
| 
       8 
     | 
    
         
            -
              FieldErrors,
         
     | 
| 
       9 
     | 
    
         
            -
              TouchedFields,
         
     | 
| 
       10 
     | 
    
         
            -
              ValidationResult,
         
     | 
| 
       11 
     | 
    
         
            -
            } from "./validation/types";
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
            export type FormContextValue = {
         
     | 
| 
       14 
     | 
    
         
            -
              /**
         
     | 
| 
       15 
     | 
    
         
            -
               * All the errors in all the fields in the form.
         
     | 
| 
       16 
     | 
    
         
            -
               */
         
     | 
| 
       17 
     | 
    
         
            -
              fieldErrors: FieldErrors;
         
     | 
| 
       18 
     | 
    
         
            -
              /**
         
     | 
| 
       19 
     | 
    
         
            -
               * Clear the errors of the specified fields.
         
     | 
| 
       20 
     | 
    
         
            -
               */
         
     | 
| 
       21 
     | 
    
         
            -
              clearError: (...names: string[]) => void;
         
     | 
| 
       22 
     | 
    
         
            -
              /**
         
     | 
| 
       23 
     | 
    
         
            -
               * Validate the specified field.
         
     | 
| 
       24 
     | 
    
         
            -
               */
         
     | 
| 
       25 
     | 
    
         
            -
              validateField: (fieldName: string) => Promise<string | null>;
         
     | 
| 
       26 
     | 
    
         
            -
              /**
         
     | 
| 
       27 
     | 
    
         
            -
               * The `action` prop of the form.
         
     | 
| 
       28 
     | 
    
         
            -
               */
         
     | 
| 
       29 
     | 
    
         
            -
              action?: string;
         
     | 
| 
       30 
     | 
    
         
            -
              /**
         
     | 
| 
       31 
     | 
    
         
            -
               * The `subaction` prop of the form.
         
     | 
| 
       32 
     | 
    
         
            -
               */
         
     | 
| 
       33 
     | 
    
         
            -
              subaction?: string;
         
     | 
| 
       34 
     | 
    
         
            -
              /**
         
     | 
| 
       35 
     | 
    
         
            -
               * Whether or not the form is submitting.
         
     | 
| 
       36 
     | 
    
         
            -
               */
         
     | 
| 
       37 
     | 
    
         
            -
              isSubmitting: boolean;
         
     | 
| 
       38 
     | 
    
         
            -
              /**
         
     | 
| 
       39 
     | 
    
         
            -
               * Whether or not a submission has been attempted.
         
     | 
| 
       40 
     | 
    
         
            -
               * This is true once the form has been submitted, even if there were validation errors.
         
     | 
| 
       41 
     | 
    
         
            -
               * Resets to false when the form is reset.
         
     | 
| 
       42 
     | 
    
         
            -
               */
         
     | 
| 
       43 
     | 
    
         
            -
              hasBeenSubmitted: boolean;
         
     | 
| 
       44 
     | 
    
         
            -
              /**
         
     | 
| 
       45 
     | 
    
         
            -
               * Whether or not the form is valid.
         
     | 
| 
       46 
     | 
    
         
            -
               */
         
     | 
| 
       47 
     | 
    
         
            -
              isValid: boolean;
         
     | 
| 
       48 
     | 
    
         
            -
              /**
         
     | 
| 
       49 
     | 
    
         
            -
               * The default values of the form.
         
     | 
| 
       50 
     | 
    
         
            -
               */
         
     | 
| 
       51 
     | 
    
         
            -
              defaultValues?: { [fieldName: string]: any };
         
     | 
| 
       52 
     | 
    
         
            -
              /**
         
     | 
| 
       53 
     | 
    
         
            -
               * Register a custom focus handler to be used when
         
     | 
| 
       54 
     | 
    
         
            -
               * the field needs to receive focus due to a validation error.
         
     | 
| 
       55 
     | 
    
         
            -
               */
         
     | 
| 
       56 
     | 
    
         
            -
              registerReceiveFocus: (fieldName: string, handler: () => void) => () => void;
         
     | 
| 
       57 
     | 
    
         
            -
              /**
         
     | 
| 
       58 
     | 
    
         
            -
               * Any fields that have been touched by the user.
         
     | 
| 
       59 
     | 
    
         
            -
               */
         
     | 
| 
       60 
     | 
    
         
            -
              touchedFields: TouchedFields;
         
     | 
| 
       61 
     | 
    
         
            -
              /**
         
     | 
| 
       62 
     | 
    
         
            -
               * Change the touched state of the specified field.
         
     | 
| 
       63 
     | 
    
         
            -
               */
         
     | 
| 
       64 
     | 
    
         
            -
              setFieldTouched: (fieldName: string, touched: boolean) => void;
         
     | 
| 
       65 
     | 
    
         
            -
              /**
         
     | 
| 
       66 
     | 
    
         
            -
               * Validate the whole form and populate any errors.
         
     | 
| 
       67 
     | 
    
         
            -
               */
         
     | 
| 
       68 
     | 
    
         
            -
              validate: () => Promise<ValidationResult<unknown>>;
         
     | 
| 
       69 
     | 
    
         
            -
              /**
         
     | 
| 
       70 
     | 
    
         
            -
               * Clears all errors on the form.
         
     | 
| 
       71 
     | 
    
         
            -
               */
         
     | 
| 
       72 
     | 
    
         
            -
              clearAllErrors: () => void;
         
     | 
| 
       73 
     | 
    
         
            -
              /**
         
     | 
| 
       74 
     | 
    
         
            -
               * Resets the form.
         
     | 
| 
       75 
     | 
    
         
            -
               *
         
     | 
| 
       76 
     | 
    
         
            -
               * _Note_: The equivalent behavior can be achieved by calling formElement.reset()
         
     | 
| 
       77 
     | 
    
         
            -
               * or clicking a button element with `type="reset"`.
         
     | 
| 
       78 
     | 
    
         
            -
               */
         
     | 
| 
       79 
     | 
    
         
            -
              reset: () => void;
         
     | 
| 
       80 
     | 
    
         
            -
              /**
         
     | 
| 
       81 
     | 
    
         
            -
               * Submits the form, running all validations first.
         
     | 
| 
       82 
     | 
    
         
            -
               *
         
     | 
| 
       83 
     | 
    
         
            -
               * _Note_: This is equivalent to clicking a button element with `type="submit"` or calling formElement.submit().
         
     | 
| 
       84 
     | 
    
         
            -
               */
         
     | 
| 
       85 
     | 
    
         
            -
              submit: () => void;
         
     | 
| 
       86 
     | 
    
         
            -
              /**
         
     | 
| 
       87 
     | 
    
         
            -
               * Returns the current form values as FormData
         
     | 
| 
       88 
     | 
    
         
            -
               */
         
     | 
| 
       89 
     | 
    
         
            -
              getValues: () => FormData;
         
     | 
| 
       90 
     | 
    
         
            -
            };
         
     | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
       92 
     | 
    
         
            -
            /**
         
     | 
| 
       93 
     | 
    
         
            -
             * Provides access to some of the internal state of the form.
         
     | 
| 
       94 
     | 
    
         
            -
             */
         
     | 
| 
       95 
     | 
    
         
            -
            export const useFormContext = (formId?: string): FormContextValue => {
         
     | 
| 
       96 
     | 
    
         
            -
              // Try to access context so we get our error specific to this hook if it's not there
         
     | 
| 
       97 
     | 
    
         
            -
              const context = useInternalFormContext(formId, "useFormContext");
         
     | 
| 
       98 
     | 
    
         
            -
              const state = useFormState(formId);
         
     | 
| 
       99 
     | 
    
         
            -
              const {
         
     | 
| 
       100 
     | 
    
         
            -
                clearError: internalClearError,
         
     | 
| 
       101 
     | 
    
         
            -
                setTouched,
         
     | 
| 
       102 
     | 
    
         
            -
                validateField,
         
     | 
| 
       103 
     | 
    
         
            -
                clearAllErrors,
         
     | 
| 
       104 
     | 
    
         
            -
                validate,
         
     | 
| 
       105 
     | 
    
         
            -
                reset,
         
     | 
| 
       106 
     | 
    
         
            -
                submit,
         
     | 
| 
       107 
     | 
    
         
            -
                getValues,
         
     | 
| 
       108 
     | 
    
         
            -
              } = useFormHelpers(formId);
         
     | 
| 
       109 
     | 
    
         
            -
             
     | 
| 
       110 
     | 
    
         
            -
              const registerReceiveFocus = useRegisterReceiveFocus(context.formId);
         
     | 
| 
       111 
     | 
    
         
            -
             
     | 
| 
       112 
     | 
    
         
            -
              const clearError = useCallback(
         
     | 
| 
       113 
     | 
    
         
            -
                (...names: string[]) => {
         
     | 
| 
       114 
     | 
    
         
            -
                  names.forEach((name) => {
         
     | 
| 
       115 
     | 
    
         
            -
                    internalClearError(name);
         
     | 
| 
       116 
     | 
    
         
            -
                  });
         
     | 
| 
       117 
     | 
    
         
            -
                },
         
     | 
| 
       118 
     | 
    
         
            -
                [internalClearError]
         
     | 
| 
       119 
     | 
    
         
            -
              );
         
     | 
| 
       120 
     | 
    
         
            -
             
     | 
| 
       121 
     | 
    
         
            -
              return useMemo(
         
     | 
| 
       122 
     | 
    
         
            -
                () => ({
         
     | 
| 
       123 
     | 
    
         
            -
                  ...state,
         
     | 
| 
       124 
     | 
    
         
            -
                  setFieldTouched: setTouched,
         
     | 
| 
       125 
     | 
    
         
            -
                  validateField,
         
     | 
| 
       126 
     | 
    
         
            -
                  clearError,
         
     | 
| 
       127 
     | 
    
         
            -
                  registerReceiveFocus,
         
     | 
| 
       128 
     | 
    
         
            -
                  clearAllErrors,
         
     | 
| 
       129 
     | 
    
         
            -
                  validate,
         
     | 
| 
       130 
     | 
    
         
            -
                  reset,
         
     | 
| 
       131 
     | 
    
         
            -
                  submit,
         
     | 
| 
       132 
     | 
    
         
            -
                  getValues,
         
     | 
| 
       133 
     | 
    
         
            -
                }),
         
     | 
| 
       134 
     | 
    
         
            -
                [
         
     | 
| 
       135 
     | 
    
         
            -
                  clearAllErrors,
         
     | 
| 
       136 
     | 
    
         
            -
                  clearError,
         
     | 
| 
       137 
     | 
    
         
            -
                  registerReceiveFocus,
         
     | 
| 
       138 
     | 
    
         
            -
                  reset,
         
     | 
| 
       139 
     | 
    
         
            -
                  setTouched,
         
     | 
| 
       140 
     | 
    
         
            -
                  state,
         
     | 
| 
       141 
     | 
    
         
            -
                  submit,
         
     | 
| 
       142 
     | 
    
         
            -
                  validate,
         
     | 
| 
       143 
     | 
    
         
            -
                  validateField,
         
     | 
| 
       144 
     | 
    
         
            -
                  getValues,
         
     | 
| 
       145 
     | 
    
         
            -
                ]
         
     | 
| 
       146 
     | 
    
         
            -
              );
         
     | 
| 
       147 
     | 
    
         
            -
            };
         
     | 
| 
         @@ -1,53 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            import * as R from "remeda";
         
     | 
| 
       2 
     | 
    
         
            -
            import { CreateValidatorArg, GenericObject, Validator } from "..";
         
     | 
| 
       3 
     | 
    
         
            -
            import { FORM_ID_FIELD } from "../internal/constants";
         
     | 
| 
       4 
     | 
    
         
            -
            import { objectFromPathEntries } from "../internal/flatten";
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
            const preprocessFormData = (data: GenericObject | FormData): GenericObject => {
         
     | 
| 
       7 
     | 
    
         
            -
              // A slightly janky way of determining if the data is a FormData object
         
     | 
| 
       8 
     | 
    
         
            -
              // since node doesn't really have FormData
         
     | 
| 
       9 
     | 
    
         
            -
              if ("entries" in data && typeof data.entries === "function")
         
     | 
| 
       10 
     | 
    
         
            -
                return objectFromPathEntries([...data.entries()]);
         
     | 
| 
       11 
     | 
    
         
            -
              return objectFromPathEntries(Object.entries(data));
         
     | 
| 
       12 
     | 
    
         
            -
            };
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
            const omitInternalFields = (data: GenericObject): GenericObject =>
         
     | 
| 
       15 
     | 
    
         
            -
              R.omit(data, [FORM_ID_FIELD]);
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
            /**
         
     | 
| 
       18 
     | 
    
         
            -
             * Used to create a validator for a form.
         
     | 
| 
       19 
     | 
    
         
            -
             * It provides built-in handling for unflattening nested objects and
         
     | 
| 
       20 
     | 
    
         
            -
             * extracting the values from FormData.
         
     | 
| 
       21 
     | 
    
         
            -
             */
         
     | 
| 
       22 
     | 
    
         
            -
            export function createValidator<T>(
         
     | 
| 
       23 
     | 
    
         
            -
              validator: CreateValidatorArg<T>
         
     | 
| 
       24 
     | 
    
         
            -
            ): Validator<T> {
         
     | 
| 
       25 
     | 
    
         
            -
              return {
         
     | 
| 
       26 
     | 
    
         
            -
                validate: async (value) => {
         
     | 
| 
       27 
     | 
    
         
            -
                  const data = preprocessFormData(value);
         
     | 
| 
       28 
     | 
    
         
            -
                  const result = await validator.validate(omitInternalFields(data));
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
                  if (result.error) {
         
     | 
| 
       31 
     | 
    
         
            -
                    return {
         
     | 
| 
       32 
     | 
    
         
            -
                      data: undefined,
         
     | 
| 
       33 
     | 
    
         
            -
                      error: {
         
     | 
| 
       34 
     | 
    
         
            -
                        fieldErrors: result.error,
         
     | 
| 
       35 
     | 
    
         
            -
                        subaction: data.subaction,
         
     | 
| 
       36 
     | 
    
         
            -
                        formId: data[FORM_ID_FIELD],
         
     | 
| 
       37 
     | 
    
         
            -
                      },
         
     | 
| 
       38 
     | 
    
         
            -
                      submittedData: data,
         
     | 
| 
       39 
     | 
    
         
            -
                      formId: data[FORM_ID_FIELD],
         
     | 
| 
       40 
     | 
    
         
            -
                    };
         
     | 
| 
       41 
     | 
    
         
            -
                  }
         
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
                  return {
         
     | 
| 
       44 
     | 
    
         
            -
                    data: result.data,
         
     | 
| 
       45 
     | 
    
         
            -
                    error: undefined,
         
     | 
| 
       46 
     | 
    
         
            -
                    submittedData: data,
         
     | 
| 
       47 
     | 
    
         
            -
                    formId: data[FORM_ID_FIELD],
         
     | 
| 
       48 
     | 
    
         
            -
                  };
         
     | 
| 
       49 
     | 
    
         
            -
                },
         
     | 
| 
       50 
     | 
    
         
            -
                validateField: (data: GenericObject | FormData, field: string) =>
         
     | 
| 
       51 
     | 
    
         
            -
                  validator.validateField(preprocessFormData(data), field),
         
     | 
| 
       52 
     | 
    
         
            -
              };
         
     | 
| 
       53 
     | 
    
         
            -
            }
         
     |