remix-validated-form 4.6.4 → 4.6.6
Sign up to get free protection for your applications and to get access to all the features.
- package/.turbo/turbo-build.log +12 -12
- package/.turbo/turbo-typecheck.log +1 -0
- package/README.md +10 -9
- package/browser/ValidatedForm.d.ts +3 -3
- package/browser/hooks.d.ts +1 -1
- package/browser/internal/formContext.d.ts +3 -3
- package/browser/internal/getInputProps.d.ts +7 -7
- package/browser/internal/hydratable.d.ts +1 -1
- package/browser/internal/state/createFormStore.d.ts +3 -3
- package/browser/internal/state/fieldArray.d.ts +5 -5
- package/browser/internal/state/types.d.ts +1 -1
- package/browser/server.d.ts +1 -1
- package/browser/unreleased/formStateHooks.d.ts +2 -2
- package/browser/userFacingFormContext.d.ts +1 -1
- package/browser/validation/types.d.ts +15 -15
- package/dist/index.cjs.js +1928 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +337 -0
- package/dist/{remix-validated-form.es.js → index.esm.js} +573 -869
- package/dist/index.esm.js.map +1 -0
- package/package.json +14 -11
- package/src/ValidatedForm.tsx +19 -6
- package/src/hooks.ts +1 -1
- package/src/internal/formContext.ts +2 -2
- package/src/server.ts +1 -1
- package/stats.html +1 -1
- package/tsup.config.ts +3 -0
- package/dist/remix-validated-form.cjs.js +0 -27
- package/dist/remix-validated-form.cjs.js.map +0 -1
- package/dist/remix-validated-form.es.js.map +0 -1
- package/dist/remix-validated-form.umd.js +0 -27
- package/dist/remix-validated-form.umd.js.map +0 -1
- package/dist/types/ValidatedForm.d.ts +0 -50
- package/dist/types/hooks.d.ts +0 -67
- package/dist/types/index.d.ts +0 -7
- package/dist/types/internal/MultiValueMap.d.ts +0 -11
- package/dist/types/internal/constants.d.ts +0 -3
- package/dist/types/internal/flatten.d.ts +0 -1
- package/dist/types/internal/formContext.d.ts +0 -12
- package/dist/types/internal/getInputProps.d.ts +0 -29
- package/dist/types/internal/hooks.d.ts +0 -35
- package/dist/types/internal/hydratable.d.ts +0 -14
- package/dist/types/internal/logic/getCheckboxChecked.d.ts +0 -1
- package/dist/types/internal/logic/getRadioChecked.d.ts +0 -1
- package/dist/types/internal/logic/requestSubmit.d.ts +0 -5
- package/dist/types/internal/state/arrayUtil.d.ts +0 -12
- package/dist/types/internal/state/controlledFields.d.ts +0 -7
- package/dist/types/internal/state/createFormStore.d.ts +0 -79
- package/dist/types/internal/state/fieldArray.d.ts +0 -28
- package/dist/types/internal/state/storeHooks.d.ts +0 -3
- package/dist/types/internal/state/types.d.ts +0 -1
- package/dist/types/internal/submissionCallbacks.d.ts +0 -1
- package/dist/types/internal/util.d.ts +0 -5
- package/dist/types/server.d.ts +0 -21
- package/dist/types/unreleased/formStateHooks.d.ts +0 -64
- package/dist/types/userFacingFormContext.d.ts +0 -85
- package/dist/types/validation/createValidator.d.ts +0 -7
- package/dist/types/validation/types.d.ts +0 -58
- package/vite.config.ts +0 -7
package/.turbo/turbo-build.log
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
[2K[1G[2m$ vite build[22m
|
2
|
-
[36mvite v2.9.
|
2
|
+
[36mvite v2.9.15 [32mbuilding for production...[36m[39m
|
3
3
|
transforming...
|
4
|
-
[32m✓[39m
|
4
|
+
[32m✓[39m 291 modules transformed.
|
5
5
|
rendering chunks...
|
6
|
-
[90m[37m[2mdist/[22m[90m[39m[36mremix-validated-form.cjs.js [39m [2m32.
|
7
|
-
[90m[37m[2mdist/[22m[90m[39m[90mremix-validated-form.cjs.js.map[39m [2m168.
|
8
|
-
[90m[37m[2mdist/[22m[90m[39m[36mremix-validated-form.es.js [39m [
|
9
|
-
[90m[37m[2mdist/[22m[90m[39m[90mremix-validated-form.es.js.map[39m [
|
10
|
-
[90m[37m[2mdist/[22m[90m[39m[36mremix-validated-form.umd.js [39m [2m32.84 KiB / gzip: 11.42 KiB[22m
|
11
|
-
[90m[37m[2mdist/[22m[90m[39m[90mremix-validated-form.umd.js.map[39m [2m168.25 KiB[22m
|
12
|
-
[32m[39m
|
13
|
-
[32m[36m[vite:dts][39m[32m Start generate declaration files...[39m
|
14
|
-
[32m[36m[vite:dts][39m[32m Declaration files built in 2581ms.[39m
|
15
|
-
[32m[39m
|
6
|
+
[90m[37m[2mdist/[22m[90m[39m[36mremix-validated-form.cjs.js [39m [2m32.76 KiB / gzip: 11.39 KiB[22m
|
7
|
+
[90m[37m[2mdist/[22m[90m[39m[90mremix-validated-form.cjs.js.map[39m [2m168.68 KiB[22m
|
8
|
+
[90m[37m[2mdist/[22m[90m[39m[36mremix-validated-form.es.js [39m [2m67.07 KiB / gzip: 15.71 KiB[22m
|
9
|
+
[90m[37m[2mdist/[22m[90m[39m[90mremix-validated-form.es.js.map[39m [2m166.22 KiB[22m
|
16
10
|
No name was provided for external module 'react' in output.globals – guessing 'React'
|
17
11
|
No name was provided for external module '@remix-run/react' in output.globals – guessing 'react'
|
12
|
+
[90m[37m[2mdist/[22m[90m[39m[36mremix-validated-form.umd.js [39m [2m32.95 KiB / gzip: 11.46 KiB[22m
|
13
|
+
[90m[37m[2mdist/[22m[90m[39m[90mremix-validated-form.umd.js.map[39m [2m168.64 KiB[22m
|
14
|
+
[32m
|
15
|
+
[36m[vite:dts][32m Start generate declaration files...[39m
|
16
|
+
[32m[36m[vite:dts][32m Declaration files built in 1834ms.
|
17
|
+
[39m
|
@@ -0,0 +1 @@
|
|
1
|
+
[2K[1G[2m$ tsc --noEmit[22m
|
package/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Remix Validated Form
|
2
2
|
|
3
|
-
A form library built for [
|
3
|
+
A form library built for [Remix](https://remix.run) to make validation easy.
|
4
4
|
|
5
5
|
- Client-side, field-by-field and form-level validation
|
6
6
|
- Re-use validation on the server
|
@@ -107,7 +107,8 @@ export const MySubmitButton = () => {
|
|
107
107
|
Now that we have our components, making a form is easy!
|
108
108
|
|
109
109
|
```tsx
|
110
|
-
import {
|
110
|
+
import { DataFunctionArgs, json, redirect } from "@remix-run/node";
|
111
|
+
import { useLoaderData } from "@remix-run/react";
|
111
112
|
import * as yup from "yup";
|
112
113
|
import { validationError, ValidatedForm, withYup } from "remix-validated-form";
|
113
114
|
import { MyInput, MySubmitButton } from "~/components/Input";
|
@@ -121,7 +122,7 @@ const validator = withYup(
|
|
121
122
|
})
|
122
123
|
);
|
123
124
|
|
124
|
-
export const action
|
125
|
+
export const action = async ({ request }: DataFunctionArgs) => {
|
125
126
|
const fieldValues = await validator.validate(await request.formData());
|
126
127
|
if (fieldValues.error) return validationError(fieldValues.error);
|
127
128
|
const { firstName, lastName, email } = fieldValues.data;
|
@@ -131,18 +132,18 @@ export const action: ActionFunction = async ({ request }) => {
|
|
131
132
|
return redirect("/");
|
132
133
|
};
|
133
134
|
|
134
|
-
export const loader
|
135
|
-
return {
|
135
|
+
export const loader = async (args: DataFunctionArgs) => {
|
136
|
+
return json({
|
136
137
|
defaultValues: {
|
137
138
|
firstName: "Jane",
|
138
139
|
lastName: "Doe",
|
139
140
|
email: "jane.doe@example.com",
|
140
141
|
},
|
141
|
-
};
|
142
|
+
});
|
142
143
|
};
|
143
144
|
|
144
145
|
export default function MyForm() {
|
145
|
-
const { defaultValues } = useLoaderData();
|
146
|
+
const { defaultValues } = useLoaderData<typeof loader>();
|
146
147
|
return (
|
147
148
|
<ValidatedForm
|
148
149
|
validator={validator}
|
@@ -164,7 +165,7 @@ You can use nested objects and arrays by using a period (`.`) or brackets (`[]`)
|
|
164
165
|
|
165
166
|
```tsx
|
166
167
|
export default function MyForm() {
|
167
|
-
const { defaultValues } = useLoaderData();
|
168
|
+
const { defaultValues } = useLoaderData<typeof loader>();
|
168
169
|
return (
|
169
170
|
<ValidatedForm
|
170
171
|
validator={validator}
|
@@ -257,7 +258,7 @@ We recommend this approach since the validation will still work even if JS is di
|
|
257
258
|
## How do we trigger toast messages on success?
|
258
259
|
|
259
260
|
Problem: how do we trigger a toast message on success if the action redirects away from the form route? The Remix solution is to flash a message in the session and pick this up in a loader function, probably in root.tsx
|
260
|
-
See the [Remix](https://remix.run/docs/en/v1/
|
261
|
+
See the [Remix](https://remix.run/docs/en/v1/utils/sessions#sessionflashkey-value) documentation for more information.
|
261
262
|
|
262
263
|
## Why is my cancel button triggering form submission?
|
263
264
|
|
@@ -1,7 +1,7 @@
|
|
1
|
-
import { Form as RemixForm
|
1
|
+
import { FetcherWithComponents, Form as RemixForm } from "@remix-run/react";
|
2
2
|
import React, { ComponentProps } from "react";
|
3
3
|
import { Validator } from "./validation/types";
|
4
|
-
export
|
4
|
+
export type FormProps<DataType> = {
|
5
5
|
/**
|
6
6
|
* A `Validator` object that describes how to validate the form.
|
7
7
|
*/
|
@@ -16,7 +16,7 @@ export declare type FormProps<DataType> = {
|
|
16
16
|
* The form will use the fetcher for loading states, action data, etc
|
17
17
|
* instead of the default form action.
|
18
18
|
*/
|
19
|
-
fetcher?:
|
19
|
+
fetcher?: FetcherWithComponents<any>;
|
20
20
|
/**
|
21
21
|
* Accepts an object of default values for the form
|
22
22
|
* that will automatically be propagated to the form fields via `useField`.
|
package/browser/hooks.d.ts
CHANGED
@@ -13,7 +13,7 @@ export declare const useIsSubmitting: (formId?: string) => boolean;
|
|
13
13
|
* @param formId the id of the form. Only necessary if being used outside a ValidatedForm.
|
14
14
|
*/
|
15
15
|
export declare const useIsValid: (formId?: string) => boolean;
|
16
|
-
export
|
16
|
+
export type FieldProps = {
|
17
17
|
/**
|
18
18
|
* The validation error message if there is one.
|
19
19
|
*/
|
@@ -1,12 +1,12 @@
|
|
1
1
|
/// <reference types="react" />
|
2
|
-
import {
|
3
|
-
export
|
2
|
+
import { FetcherWithComponents } from "@remix-run/react";
|
3
|
+
export type InternalFormContextValue = {
|
4
4
|
formId: string | symbol;
|
5
5
|
action?: string;
|
6
6
|
subaction?: string;
|
7
7
|
defaultValuesProp?: {
|
8
8
|
[fieldName: string]: any;
|
9
9
|
};
|
10
|
-
fetcher?:
|
10
|
+
fetcher?: FetcherWithComponents<unknown>;
|
11
11
|
};
|
12
12
|
export declare const InternalFormContext: import("react").Context<InternalFormContextValue | null>;
|
@@ -1,10 +1,10 @@
|
|
1
|
-
export
|
2
|
-
export
|
1
|
+
export type ValidationBehavior = "onBlur" | "onChange" | "onSubmit";
|
2
|
+
export type ValidationBehaviorOptions = {
|
3
3
|
initial: ValidationBehavior;
|
4
4
|
whenTouched: ValidationBehavior;
|
5
5
|
whenSubmitted: ValidationBehavior;
|
6
6
|
};
|
7
|
-
export
|
7
|
+
export type CreateGetInputPropsOptions = {
|
8
8
|
clearError: () => void;
|
9
9
|
validate: () => void;
|
10
10
|
defaultValue?: any;
|
@@ -14,9 +14,9 @@ export declare type CreateGetInputPropsOptions = {
|
|
14
14
|
validationBehavior?: Partial<ValidationBehaviorOptions>;
|
15
15
|
name: string;
|
16
16
|
};
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
type HandledProps = "name" | "defaultValue" | "defaultChecked";
|
18
|
+
type Callbacks = "onChange" | "onBlur";
|
19
|
+
type MinimalInputProps = {
|
20
20
|
onChange?: (...args: any[]) => void;
|
21
21
|
onBlur?: (...args: any[]) => void;
|
22
22
|
defaultValue?: any;
|
@@ -24,6 +24,6 @@ declare type MinimalInputProps = {
|
|
24
24
|
name?: string;
|
25
25
|
type?: string;
|
26
26
|
};
|
27
|
-
export
|
27
|
+
export type GetInputProps = <T extends MinimalInputProps>(props?: Omit<T, HandledProps | Callbacks> & Partial<Pick<T, Callbacks>>) => T;
|
28
28
|
export declare const createGetInputProps: ({ clearError, validate, defaultValue, touched, setTouched, hasBeenSubmitted, validationBehavior, name, }: CreateGetInputPropsOptions) => GetInputProps;
|
29
29
|
export {};
|
@@ -3,7 +3,7 @@
|
|
3
3
|
* around data that needs to come from the server initially,
|
4
4
|
* but from the internal state after hydration.
|
5
5
|
*/
|
6
|
-
export
|
6
|
+
export type Hydratable<T> = {
|
7
7
|
hydrateTo: (data: T) => T;
|
8
8
|
map: <U>(fn: (data: T) => U) => Hydratable<U>;
|
9
9
|
};
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { WritableDraft } from "immer/dist/internal";
|
2
2
|
import { FieldErrors, TouchedFields, ValidationResult, Validator } from "../../validation/types";
|
3
3
|
import { InternalFormId } from "./types";
|
4
|
-
export
|
4
|
+
export type SyncedFormProps = {
|
5
5
|
formId?: string;
|
6
6
|
action?: string;
|
7
7
|
subaction?: string;
|
@@ -11,7 +11,7 @@ export declare type SyncedFormProps = {
|
|
11
11
|
registerReceiveFocus: (fieldName: string, handler: () => void) => () => void;
|
12
12
|
validator: Validator<unknown>;
|
13
13
|
};
|
14
|
-
export
|
14
|
+
export type FormStoreState = {
|
15
15
|
forms: {
|
16
16
|
[formId: InternalFormId]: FormState;
|
17
17
|
};
|
@@ -19,7 +19,7 @@ export declare type FormStoreState = {
|
|
19
19
|
registerForm: (formId: InternalFormId) => void;
|
20
20
|
cleanupForm: (formId: InternalFormId) => void;
|
21
21
|
};
|
22
|
-
export
|
22
|
+
export type FormState = {
|
23
23
|
isHydrated: boolean;
|
24
24
|
isSubmitting: boolean;
|
25
25
|
hasBeenSubmitted: boolean;
|
@@ -1,10 +1,10 @@
|
|
1
1
|
import React from "react";
|
2
|
-
export
|
3
|
-
export
|
2
|
+
export type FieldArrayValidationBehavior = "onChange" | "onSubmit";
|
3
|
+
export type FieldArrayValidationBehaviorOptions = {
|
4
4
|
initial: FieldArrayValidationBehavior;
|
5
5
|
whenSubmitted: FieldArrayValidationBehavior;
|
6
6
|
};
|
7
|
-
export
|
7
|
+
export type FieldArrayHelpers<Item = any> = {
|
8
8
|
push: (item: Item) => void;
|
9
9
|
swap: (indexA: number, indexB: number) => void;
|
10
10
|
move: (from: number, to: number) => void;
|
@@ -14,12 +14,12 @@ export declare type FieldArrayHelpers<Item = any> = {
|
|
14
14
|
pop: () => void;
|
15
15
|
replace: (index: number, value: Item) => void;
|
16
16
|
};
|
17
|
-
export
|
17
|
+
export type UseFieldArrayOptions = {
|
18
18
|
formId?: string;
|
19
19
|
validationBehavior?: Partial<FieldArrayValidationBehaviorOptions>;
|
20
20
|
};
|
21
21
|
export declare function useFieldArray<Item = any>(name: string, { formId, validationBehavior }?: UseFieldArrayOptions): [itemDefaults: Item[], helpers: FieldArrayHelpers<any>, error: string | undefined];
|
22
|
-
export
|
22
|
+
export type FieldArrayProps = {
|
23
23
|
name: string;
|
24
24
|
children: (itemDefaults: any[], helpers: FieldArrayHelpers, error: string | undefined) => React.ReactNode;
|
25
25
|
formId?: string;
|
@@ -1 +1 @@
|
|
1
|
-
export
|
1
|
+
export type InternalFormId = string | symbol;
|
package/browser/server.d.ts
CHANGED
@@ -15,7 +15,7 @@ import { ValidatorError, ValidationErrorResponseData } from "./validation/types"
|
|
15
15
|
* ```
|
16
16
|
*/
|
17
17
|
export declare function validationError(error: ValidatorError, repopulateFields?: unknown, init?: ResponseInit): import("@remix-run/server-runtime").TypedResponse<ValidationErrorResponseData>;
|
18
|
-
export
|
18
|
+
export type FormDefaults = {
|
19
19
|
[formDefaultsKey: `${typeof FORM_DEFAULTS_FIELD}_${string}`]: any;
|
20
20
|
};
|
21
21
|
export declare const setFormDefaults: <DataType = any>(formId: string, defaultValues: Partial<DataType>) => FormDefaults;
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { FieldErrors, TouchedFields, ValidationResult } from "../validation/types";
|
2
|
-
export
|
2
|
+
export type FormState = {
|
3
3
|
fieldErrors: FieldErrors;
|
4
4
|
isSubmitting: boolean;
|
5
5
|
hasBeenSubmitted: boolean;
|
@@ -17,7 +17,7 @@ export declare type FormState = {
|
|
17
17
|
* @param formId the id of the form. Only necessary if being used outside a ValidatedForm.
|
18
18
|
*/
|
19
19
|
export declare const useFormState: (formId?: string) => FormState;
|
20
|
-
export
|
20
|
+
export type FormHelpers = {
|
21
21
|
/**
|
22
22
|
* Clear the error of the specified field.
|
23
23
|
*/
|
@@ -1,58 +1,58 @@
|
|
1
|
-
export
|
2
|
-
export
|
3
|
-
export
|
1
|
+
export type FieldErrors = Record<string, string>;
|
2
|
+
export type TouchedFields = Record<string, boolean>;
|
3
|
+
export type GenericObject = {
|
4
4
|
[key: string]: any;
|
5
5
|
};
|
6
|
-
export
|
6
|
+
export type ValidatorError = {
|
7
7
|
subaction?: string;
|
8
8
|
formId?: string;
|
9
9
|
fieldErrors: FieldErrors;
|
10
10
|
};
|
11
|
-
export
|
11
|
+
export type ValidationErrorResponseData = {
|
12
12
|
subaction?: string;
|
13
13
|
formId?: string;
|
14
14
|
fieldErrors: FieldErrors;
|
15
15
|
repopulateFields?: unknown;
|
16
16
|
};
|
17
|
-
export
|
17
|
+
export type BaseResult = {
|
18
18
|
submittedData: GenericObject;
|
19
19
|
formId?: string;
|
20
20
|
};
|
21
|
-
export
|
21
|
+
export type ErrorResult = BaseResult & {
|
22
22
|
error: ValidatorError;
|
23
23
|
data: undefined;
|
24
24
|
};
|
25
|
-
export
|
25
|
+
export type SuccessResult<DataType> = BaseResult & {
|
26
26
|
data: DataType;
|
27
27
|
error: undefined;
|
28
28
|
};
|
29
29
|
/**
|
30
30
|
* The result when validating a form.
|
31
31
|
*/
|
32
|
-
export
|
32
|
+
export type ValidationResult<DataType> = SuccessResult<DataType> | ErrorResult;
|
33
33
|
/**
|
34
34
|
* The result when validating an individual field in a form.
|
35
35
|
*/
|
36
|
-
export
|
36
|
+
export type ValidateFieldResult = {
|
37
37
|
error?: string;
|
38
38
|
};
|
39
39
|
/**
|
40
40
|
* A `Validator` can be passed to the `validator` prop of a `ValidatedForm`.
|
41
41
|
*/
|
42
|
-
export
|
42
|
+
export type Validator<DataType> = {
|
43
43
|
validate: (unvalidatedData: GenericObject) => Promise<ValidationResult<DataType>>;
|
44
44
|
validateField: (unvalidatedData: GenericObject, field: string) => Promise<ValidateFieldResult>;
|
45
45
|
};
|
46
|
-
export
|
46
|
+
export type Valid<DataType> = {
|
47
47
|
data: DataType;
|
48
48
|
error: undefined;
|
49
49
|
};
|
50
|
-
export
|
50
|
+
export type Invalid = {
|
51
51
|
error: FieldErrors;
|
52
52
|
data: undefined;
|
53
53
|
};
|
54
|
-
export
|
54
|
+
export type CreateValidatorArg<DataType> = {
|
55
55
|
validate: (unvalidatedData: GenericObject) => Promise<Valid<DataType> | Invalid>;
|
56
56
|
validateField: (unvalidatedData: GenericObject, field: string) => Promise<ValidateFieldResult>;
|
57
57
|
};
|
58
|
-
export
|
58
|
+
export type ValidatorData<T extends Validator<any>> = T extends Validator<infer U> ? U : never;
|