react-form-action 2.19.0 → 2.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -18
- package/dist/client.d.mts +21 -35
- package/dist/client.mjs +1 -1
- package/dist/{formAction-0eiUHrXx.d.mts → formAction-CGw5j857.d.mts} +0 -4
- package/dist/index.d.mts +3 -5
- package/package.json +15 -15
package/README.md
CHANGED
|
@@ -67,9 +67,8 @@ export const subscribeAction = formAction
|
|
|
67
67
|
|
|
68
68
|
import {
|
|
69
69
|
Form,
|
|
70
|
-
|
|
70
|
+
Submit,
|
|
71
71
|
createComponents,
|
|
72
|
-
useActionContext,
|
|
73
72
|
} from "react-form-action/client";
|
|
74
73
|
|
|
75
74
|
import { subscribeAction } from "./action";
|
|
@@ -77,13 +76,12 @@ import { subscribeAction } from "./action";
|
|
|
77
76
|
const { FieldError, Success } = createComponents(subscribeAction);
|
|
78
77
|
|
|
79
78
|
export function SubscribeForm() {
|
|
80
|
-
const { isPending, isFailure, error, data } =
|
|
81
|
-
useActionContext(subscribeAction);
|
|
82
|
-
|
|
83
79
|
return (
|
|
84
80
|
<Form>
|
|
85
81
|
<Success>
|
|
86
|
-
|
|
82
|
+
{({ isSuccess, data }) =>
|
|
83
|
+
isSuccess && <p>✅ Please check your email :{data}.</p>
|
|
84
|
+
}
|
|
87
85
|
</Success>
|
|
88
86
|
{/*💡 The FieldError "name" prop supports autocompletion */}
|
|
89
87
|
<FieldError name="email">
|
|
@@ -91,10 +89,13 @@ export function SubscribeForm() {
|
|
|
91
89
|
<input className={error ? "invalid" : ""} name={name} />
|
|
92
90
|
)}
|
|
93
91
|
</FieldError>
|
|
94
|
-
<
|
|
95
|
-
{
|
|
96
|
-
|
|
97
|
-
|
|
92
|
+
<Submit>
|
|
93
|
+
{({ pending, disabled }) => (
|
|
94
|
+
<button type="submit" disabled={disabled}>
|
|
95
|
+
{pending ? "🌀 Submitting..." : "Submit"}
|
|
96
|
+
</button>
|
|
97
|
+
)}
|
|
98
|
+
</Submit>
|
|
98
99
|
</Form>
|
|
99
100
|
);
|
|
100
101
|
}
|
|
@@ -111,7 +112,7 @@ import { SubscribeForm } from "./form";
|
|
|
111
112
|
|
|
112
113
|
export default function Page() {
|
|
113
114
|
return (
|
|
114
|
-
<Action action={subscribeAction}
|
|
115
|
+
<Action action={subscribeAction}>
|
|
115
116
|
<SubscribeForm />
|
|
116
117
|
</Action>
|
|
117
118
|
);
|
|
@@ -226,7 +227,7 @@ export default function Page({
|
|
|
226
227
|
const { userId } = await params;
|
|
227
228
|
|
|
228
229
|
return (
|
|
229
|
-
<Action action={updateUser} args={[await locale(), userId]}
|
|
230
|
+
<Action action={updateUser} args={[await locale(), userId]} >
|
|
230
231
|
<UpdateUserForm />
|
|
231
232
|
</Action>
|
|
232
233
|
);
|
|
@@ -298,7 +299,6 @@ export function SignUpAction({ children }: PropsWithChildren) {
|
|
|
298
299
|
return (
|
|
299
300
|
<Action
|
|
300
301
|
action={signUp}
|
|
301
|
-
initialData={undefined}
|
|
302
302
|
validate={(formData) => {
|
|
303
303
|
const result = zfd.formData(signUpSchema).safeParse(formData);
|
|
304
304
|
|
|
@@ -327,7 +327,6 @@ export function SignUpAction({ children }: PropsWithChildren) {
|
|
|
327
327
|
return (
|
|
328
328
|
<Action
|
|
329
329
|
action={signUp}
|
|
330
|
-
initialData={undefined}
|
|
331
330
|
validate={validateSchema(signUpSchema)}
|
|
332
331
|
>
|
|
333
332
|
{children}
|
|
@@ -352,7 +351,6 @@ export function UpdateUserAction({ children }: PropsWithChildren) {
|
|
|
352
351
|
return (
|
|
353
352
|
<Action
|
|
354
353
|
action={updateUser}
|
|
355
|
-
initialData={undefined}
|
|
356
354
|
>
|
|
357
355
|
{/* IMPORTANT: must be rendered as a child of the <Action /> context. */}
|
|
358
356
|
<ResetAction />
|
|
@@ -396,6 +394,56 @@ export function UpdateUserForm() {
|
|
|
396
394
|
}
|
|
397
395
|
```
|
|
398
396
|
|
|
397
|
+
### `<Submit>`
|
|
398
|
+
|
|
399
|
+
A render prop component for submit buttons. It combines the action pending state (from the `<Action>` context) with the native `useFormStatus()` of the enclosing `<form>`.
|
|
400
|
+
|
|
401
|
+
⚠️ Must be rendered within a `<form>` (e.g. the `<Form>` component) which is a descendant of `<Action>`.
|
|
402
|
+
|
|
403
|
+
The render prop receives the `FormStatus` fields (`pending`, `data`, `method`, `action`) and an additional `disabled` flag, which is `true` while the **action** is pending.
|
|
404
|
+
|
|
405
|
+
```tsx
|
|
406
|
+
import type { ReactNode } from "react";
|
|
407
|
+
import { Action, Form, Submit } from "react-form-action/client";
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
// 👉 Use the <Submit> to define your custom SubmitButton:
|
|
411
|
+
function SubmitButton({
|
|
412
|
+
children,
|
|
413
|
+
pendingLabel,
|
|
414
|
+
}: {
|
|
415
|
+
children: ReactNode;
|
|
416
|
+
pendingLabel: string;
|
|
417
|
+
}) {
|
|
418
|
+
return (
|
|
419
|
+
<Submit>
|
|
420
|
+
{({ pending, disabled }) => (
|
|
421
|
+
// 👉 `disabled` reflects the action state, `pending` the form submission
|
|
422
|
+
<button type="submit" disabled={disabled}>
|
|
423
|
+
{pending ? pendingLabel : children}
|
|
424
|
+
</button>
|
|
425
|
+
)}
|
|
426
|
+
</Submit>
|
|
427
|
+
);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// 👉 on submit, both buttons will be disabled but only the submitted one will have the pending label
|
|
431
|
+
function DecisionForm() {
|
|
432
|
+
return (
|
|
433
|
+
<Action action={decideAction}>
|
|
434
|
+
<Form>
|
|
435
|
+
<input type="hidden" name="decision" defaultValue="accept" />
|
|
436
|
+
<SubmitButton pendingLabel="Accepting...">Accept</SubmitButton>
|
|
437
|
+
</Form>
|
|
438
|
+
<Form>
|
|
439
|
+
<input type="hidden" name="decision" defaultValue="reject" />
|
|
440
|
+
<SubmitButton pendingLabel="Rejecting...">Reject</SubmitButton>
|
|
441
|
+
</Form>
|
|
442
|
+
</Action>
|
|
443
|
+
);
|
|
444
|
+
}
|
|
445
|
+
```
|
|
446
|
+
|
|
399
447
|
### Context Bound Components `createComponents()`
|
|
400
448
|
|
|
401
449
|
Use the `createComponents(action)` helper to create components which use the ActionContext and have types bound to the action type.
|
|
@@ -435,7 +483,7 @@ const { FieldError } = createComponents(signUpAction);
|
|
|
435
483
|
|
|
436
484
|
export function SignUpForm() {
|
|
437
485
|
return (
|
|
438
|
-
<Action action={signUpAction}
|
|
486
|
+
<Action action={signUpAction}>
|
|
439
487
|
<Form>
|
|
440
488
|
{/* 1️⃣ When the "name" prop is an empty string, the top-level error will be rendered e.g.:
|
|
441
489
|
"Passwords don't match" */}
|
|
@@ -570,8 +618,6 @@ function SubmitButton() {
|
|
|
570
618
|
};
|
|
571
619
|
```
|
|
572
620
|
|
|
573
|
-
|
|
574
|
-
|
|
575
621
|
### Action Creator
|
|
576
622
|
|
|
577
623
|
Low-level action creator, which provides the `success`, `failure` and `invalid` envelope constructors. With the `createFormAction` you must handle the native `FormData` by yourself.
|
package/dist/client.d.mts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { a as FormAction, c as SuccessState, i as FailureState, o as InitialState, r as ActionState, s as InvalidState, t as Flatten } from "./formAction-
|
|
1
|
+
import { a as FormAction, c as SuccessState, i as FailureState, o as InitialState, r as ActionState, s as InvalidState, t as Flatten } from "./formAction-CGw5j857.mjs";
|
|
2
2
|
import React$1, { JSX, PropsWithChildren, ReactNode } from "react";
|
|
3
3
|
import { FormStatus } from "react-dom";
|
|
4
4
|
import { $ZodErrorTree } from "zod/v4/core";
|
|
5
|
-
|
|
6
|
-
type ActionProps<Data, Error, ValidationError, Arguments extends unknown[] = []> = PropsWithChildren<{
|
|
5
|
+
export type ActionProps<Data, Error, ValidationError, Arguments extends unknown[] = []> = PropsWithChildren<{
|
|
7
6
|
/**
|
|
8
7
|
* Whether the form action should automatically reset when unmounted.
|
|
9
8
|
*/
|
|
@@ -15,7 +14,7 @@ type ActionProps<Data, Error, ValidationError, Arguments extends unknown[] = []>
|
|
|
15
14
|
*/
|
|
16
15
|
validate?: (payload: FormData) => ValidationError | undefined | null;
|
|
17
16
|
permalink?: string;
|
|
18
|
-
initialData
|
|
17
|
+
initialData?: Data;
|
|
19
18
|
} & (Arguments extends [unknown, ...unknown[]] ? {
|
|
20
19
|
action: FormAction<Data, Error, ValidationError, FormData, Arguments>;
|
|
21
20
|
args: Arguments;
|
|
@@ -29,7 +28,7 @@ type ActionStatusFlags<T extends ActionState<unknown, unknown, unknown>["type"]
|
|
|
29
28
|
isFailure: T extends "failure" ? true : false;
|
|
30
29
|
isSuccess: T extends "success" ? true : false;
|
|
31
30
|
};
|
|
32
|
-
type ActionContextState<T extends ActionState<unknown, unknown, unknown>> = Flatten<T & ActionStatusFlags<T["type"]> & {
|
|
31
|
+
export type ActionContextState<T extends ActionState<unknown, unknown, unknown>> = Flatten<T & ActionStatusFlags<T["type"]> & {
|
|
33
32
|
/**
|
|
34
33
|
* The dispatch function returned from React.useActionState()
|
|
35
34
|
*/
|
|
@@ -43,40 +42,36 @@ type ActionContextState<T extends ActionState<unknown, unknown, unknown>> = Flat
|
|
|
43
42
|
/**
|
|
44
43
|
* NOTE: ActionContextState<ActionState<...>> would not allow discriminate the union inside of the ActionState.
|
|
45
44
|
*/
|
|
46
|
-
type SpreadActionContext<Data = unknown, Error = unknown, ValidationError = unknown> = ActionContextState<InitialState<Data>> | ActionContextState<InvalidState<ValidationError>> | ActionContextState<FailureState<Error>> | ActionContextState<SuccessState<Data>>;
|
|
45
|
+
export type SpreadActionContext<Data = unknown, Error = unknown, ValidationError = unknown> = ActionContextState<InitialState<Data>> | ActionContextState<InvalidState<ValidationError>> | ActionContextState<FailureState<Error>> | ActionContextState<SuccessState<Data>>;
|
|
47
46
|
/**
|
|
48
47
|
* A hook to consume the form action state from the context.
|
|
49
48
|
*/
|
|
50
|
-
declare function useActionContext<Data, Error, ValidationError, Args extends unknown[] = []>(_action?: FormAction<Data, Error, ValidationError, FormData, Args>): SpreadActionContext<Data, Error, ValidationError>;
|
|
51
|
-
declare function Action<Data, Error, ValidationError, Args extends unknown[] = []>({ children, action: formAction, initialData, args, permalink, validate, autoReset }: ActionProps<Data, Error, ValidationError, Args>): import("react").JSX.Element;
|
|
52
|
-
//#endregion
|
|
53
|
-
//#region src/ZodFieldError.d.ts
|
|
49
|
+
export declare function useActionContext<Data, Error, ValidationError, Args extends unknown[] = []>(_action?: FormAction<Data, Error, ValidationError, FormData, Args>): SpreadActionContext<Data, Error, ValidationError>;
|
|
50
|
+
export declare function Action<Data, Error, ValidationError, Args extends unknown[] = []>({ children, action: formAction, initialData, args, permalink, validate, autoReset }: ActionProps<Data, Error, ValidationError, Args>): import("react").JSX.Element;
|
|
54
51
|
declare const SEPARATOR: ".";
|
|
55
|
-
type Paths<Shape extends $ZodErrorTree<object>, Props = Required<NonNullable<Shape["properties"]>>> = { [k in keyof Props]: k extends string ? NonNullable<Props[k]> extends $ZodErrorTree<object> ? "properties" extends keyof NonNullable<Props[k]> ? `${k}${typeof SEPARATOR}${Paths<NonNullable<Props[k]>>}` : k : k : never; }[keyof Props];
|
|
56
|
-
type InferZodErrorPaths<T> = T extends $ZodErrorTree<object> ? Paths<T> : never;
|
|
57
|
-
type ZodFieldErrorProps<Errors extends $ZodErrorTree<unknown>, Name extends "" | InferZodErrorPaths<Errors>> = {
|
|
52
|
+
export type Paths<Shape extends $ZodErrorTree<object>, Props = Required<NonNullable<Shape["properties"]>>> = { [k in keyof Props]: k extends string ? NonNullable<Props[k]> extends $ZodErrorTree<object> ? "properties" extends keyof NonNullable<Props[k]> ? `${k}${typeof SEPARATOR}${Paths<NonNullable<Props[k]>>}` : k : k : never; }[keyof Props];
|
|
53
|
+
export type InferZodErrorPaths<T> = T extends $ZodErrorTree<object> ? Paths<T> : never;
|
|
54
|
+
export type ZodFieldErrorProps<Errors extends $ZodErrorTree<unknown>, Name extends "" | InferZodErrorPaths<Errors>> = {
|
|
58
55
|
errors: Errors;
|
|
59
56
|
name: Name;
|
|
60
57
|
children?: (props: ZodFieldErrorChildrenProps<Name>) => React$1.ReactNode;
|
|
61
58
|
};
|
|
62
|
-
type ZodFieldErrorChildrenProps<Name> = {
|
|
59
|
+
export type ZodFieldErrorChildrenProps<Name> = {
|
|
63
60
|
name: Name;
|
|
64
61
|
error?: string;
|
|
65
62
|
errors: readonly string[];
|
|
66
63
|
};
|
|
67
|
-
declare const noError: Readonly<{
|
|
64
|
+
export declare const noError: Readonly<{
|
|
68
65
|
errors: readonly string[];
|
|
69
66
|
}>;
|
|
70
|
-
declare function ZodFieldError<Errors extends $ZodErrorTree<object>, Name extends "" | InferZodErrorPaths<Errors> = "">({ errors, name, children }: ZodFieldErrorProps<Errors, Name>): React$1.ReactNode;
|
|
71
|
-
//#endregion
|
|
72
|
-
//#region src/createComponents.d.ts
|
|
67
|
+
export declare function ZodFieldError<Errors extends $ZodErrorTree<object>, Name extends "" | InferZodErrorPaths<Errors> = "">({ errors, name, children }: ZodFieldErrorProps<Errors, Name>): React$1.ReactNode;
|
|
73
68
|
type ErrorProps = ZodFieldErrorChildrenProps<string>;
|
|
74
69
|
type Reducers<State = unknown> = Record<string, (state: State, errorProps: ErrorProps) => unknown>;
|
|
75
70
|
type InferFieldProps<T extends Reducers<any>> = { [K in keyof T]: ReturnType<T[K]>; };
|
|
76
71
|
/**
|
|
77
72
|
* Creates a typed components for actions created with the formAction builder.
|
|
78
73
|
*/
|
|
79
|
-
declare function createComponents<Data, Error, ValidationError extends $ZodErrorTree<any>, Args extends unknown[] = [], FieldReducers extends Reducers<SpreadActionContext<Data, Error, ValidationError>> = Reducers<SpreadActionContext<Data, Error, ValidationError>>>(action: FormAction<Data, Error, ValidationError, FormData, Args>, options?: {
|
|
74
|
+
export declare function createComponents<Data, Error, ValidationError extends $ZodErrorTree<any>, Args extends unknown[] = [], FieldReducers extends Reducers<SpreadActionContext<Data, Error, ValidationError>> = Reducers<SpreadActionContext<Data, Error, ValidationError>>>(action: FormAction<Data, Error, ValidationError, FormData, Args>, options?: {
|
|
80
75
|
fieldProps?: FieldReducers;
|
|
81
76
|
}): {
|
|
82
77
|
FieldError: <Name extends "" | InferZodErrorPaths<ValidationError>>({ name, children }: {
|
|
@@ -112,9 +107,7 @@ declare function createComponents<Data, Error, ValidationError extends $ZodError
|
|
|
112
107
|
value: string;
|
|
113
108
|
} & React$1.InputHTMLAttributes<HTMLInputElement>) => React$1.JSX.Element;
|
|
114
109
|
};
|
|
115
|
-
|
|
116
|
-
//#region src/Form.d.ts
|
|
117
|
-
type FormProps = Omit<JSX.IntrinsicElements["form"], "action"> & {
|
|
110
|
+
export type FormProps = Omit<JSX.IntrinsicElements["form"], "action"> & {
|
|
118
111
|
/**
|
|
119
112
|
* Opt-in into automatic form reset by using the form "action" prop.
|
|
120
113
|
* By default, the onSubmit with a custom transition which opts-out of the implicit form reset.
|
|
@@ -123,19 +116,15 @@ type FormProps = Omit<JSX.IntrinsicElements["form"], "action"> & {
|
|
|
123
116
|
*/
|
|
124
117
|
autoReset?: boolean;
|
|
125
118
|
};
|
|
126
|
-
declare function Form({ autoReset, ...props }: FormProps): JSX.Element;
|
|
127
|
-
//#endregion
|
|
128
|
-
//#region src/Pending.d.ts
|
|
119
|
+
export declare function Form({ autoReset, ...props }: FormProps): JSX.Element;
|
|
129
120
|
/**
|
|
130
121
|
* Conditionally renders the children, when the form action is in the "pending" state.
|
|
131
122
|
*/
|
|
132
|
-
declare function Pending({ children }: PropsWithChildren | {
|
|
123
|
+
export declare function Pending({ children }: PropsWithChildren | {
|
|
133
124
|
children?: (props: {
|
|
134
125
|
isPending: boolean;
|
|
135
126
|
}) => React.ReactNode;
|
|
136
127
|
}): import("react").ReactNode;
|
|
137
|
-
//#endregion
|
|
138
|
-
//#region src/Submit.d.ts
|
|
139
128
|
type SubmitChildrenProps = FormStatus & {
|
|
140
129
|
/**
|
|
141
130
|
* Whether the **action** is pending. It will disable the submit button when true.
|
|
@@ -152,16 +141,13 @@ type SubmitProps = {
|
|
|
152
141
|
* A submit status component that tracks both the action & form pending states.
|
|
153
142
|
* NOTE: must be rendered within a <form>.
|
|
154
143
|
*/
|
|
155
|
-
declare function Submit({ children }: SubmitProps): ReactNode;
|
|
156
|
-
//#endregion
|
|
157
|
-
//#region src/useResetAction.d.ts
|
|
144
|
+
export declare function Submit({ children }: SubmitProps): ReactNode;
|
|
158
145
|
/**
|
|
159
146
|
* Hook to automatically reset the action when the component unmounts, unless it is in the initial state.
|
|
160
147
|
*/
|
|
161
|
-
declare function useResetAction(): void;
|
|
148
|
+
export declare function useResetAction(): void;
|
|
162
149
|
/**
|
|
163
150
|
* Component that automatically resets the action when it unmounts, unless it is in the initial state.
|
|
164
151
|
*/
|
|
165
|
-
declare function ResetAction(): null;
|
|
166
|
-
|
|
167
|
-
export { Action, ActionContextState, ActionProps, Form, FormProps, InferZodErrorPaths, Paths, Pending, ResetAction, SpreadActionContext, Submit, ZodFieldError, ZodFieldErrorChildrenProps, ZodFieldErrorProps, createComponents, noError, useActionContext, useResetAction };
|
|
152
|
+
export declare function ResetAction(): null;
|
|
153
|
+
export {};
|
package/dist/client.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{n as e,t}from"./createFormAction-BwMYAzm2.mjs";import{createContext as n,startTransition as r,use as i,useActionState as a,useCallback as o,useEffect as s}from"react";import{Fragment as c,jsx as l,jsxs as u}from"react/jsx-runtime";import{useFormStatus as d}from"react-dom";function f(){let{reset:e,isInitial:t}=g();s(()=>()=>{t||e()},[t,e])}function p(){return f(),null}const m={isInitial:!1,isInvalid:!1,isFailure:!1,isSuccess:!1},h=n(null);function g(e){let t=i(h);if(!t)throw Error(`ActionContext must be initialized before use. Is your useActionContext hook wrapped with an <Action> Component?`);return t}function _({children:n,action:i,initialData:s,args:c,permalink:d,validate:f,autoReset:g=!0}){let _=c?i.bind(null,...c):i,[v,y,b]=a(async(n,r)=>{if(r===null)return e(s);if(f){let e=await t(({invalid:e,success:t})=>async(n,r)=>{let i=f(r);return i?e(i):t(!0)})(n,r);if(e.type===`invalid`)return e}return _(n,r)},e(s),d),x={action:y,reset:o(()=>{r(()=>{y(null)})},[y]),isPending:b},S=v.type===`initial`?{...x,...v,...m,isInitial:!0}:v.type===`invalid`?{...x,...v,...m,isInvalid:!0}:v.type===`failure`?{...x,...v,...m,isFailure:!0}:{...x,...v,...m,isSuccess:!0};return u(h,{value:S,children:[g
|
|
1
|
+
"use client";import{n as e,t}from"./createFormAction-BwMYAzm2.mjs";import{createContext as n,startTransition as r,use as i,useActionState as a,useCallback as o,useEffect as s}from"react";import{Fragment as c,jsx as l,jsxs as u}from"react/jsx-runtime";import{useFormStatus as d}from"react-dom";function f(){let{reset:e,isInitial:t}=g();s(()=>()=>{t||e()},[t,e])}function p(){return f(),null}const m={isInitial:!1,isInvalid:!1,isFailure:!1,isSuccess:!1},h=n(null);function g(e){let t=i(h);if(!t)throw Error(`ActionContext must be initialized before use. Is your useActionContext hook wrapped with an <Action> Component?`);return t}function _({children:n,action:i,initialData:s,args:c,permalink:d,validate:f,autoReset:g=!0}){let _=c?i.bind(null,...c):i,[v,y,b]=a(async(n,r)=>{if(r===null)return e(s);if(f){let e=await t(({invalid:e,success:t})=>async(n,r)=>{let i=f(r);return i?e(i):t(!0)})(n,r);if(e.type===`invalid`)return e}return _(n,r)},e(s),d),x={action:y,reset:o(()=>{r(()=>{y(null)})},[y]),isPending:b},S=v.type===`initial`?{...x,...v,...m,isInitial:!0}:v.type===`invalid`?{...x,...v,...m,isInvalid:!0}:v.type===`failure`?{...x,...v,...m,isFailure:!0}:{...x,...v,...m,isSuccess:!0};return/* @__PURE__ */ u(h,{value:S,children:[g&&/* @__PURE__ */ l(p,{}),n]})}const v=Object.freeze({errors:Object.freeze([])});function y({errors:e,name:t,children:n=({error:e})=>/* @__PURE__ */ l(c,{children:e})}){if(t.length===0)return n({name:t,error:e.errors[0],errors:e.errors});let r=t.split(`.`),i=e;for(let e of r){if(!i.properties){i=v;break}i=i.properties[e]??v}return n({name:t,error:i.errors[0],errors:i.errors})}function b(e,t={}){function n({name:e,value:t,...n}){return/* @__PURE__ */ l(`input`,{type:`hidden`,name:e,defaultValue:t,...n})}function r({name:n,children:r}){let i=g(e),{isInvalid:a,validationError:o}=i,s=r??(({error:e})=>a&&/* @__PURE__ */ l(c,{children:e}));return/* @__PURE__ */ l(y,{errors:o??v,name:n,children:e=>{let n=Object.fromEntries(Object.entries(t.fieldProps??{}).map(([t,n])=>[t,n(i,e)]));return s({...e,...n})}})}function i({children:t}){let{isFailure:n,error:r}=g(e);return n?typeof t==`function`?t({isFailure:n,error:r}):t:null}function a({children:t}){let{isSuccess:n,data:r}=g(e);return typeof t==`function`?t({isSuccess:n,data:r}):n&&t}function o({children:t}){let{isInvalid:n,validationError:r}=g(e);return typeof t==`function`?t({isInvalid:n,validationError:r}):n&&t}return{FieldError:r,Failure:i,Success:a,Invalid:o,Value:n}}function x({autoReset:e=!1,...t}){let{action:n}=g();return/* @__PURE__ */ l(`form`,{...e?{action:n}:{onSubmit:e=>{e.preventDefault();let t=e.currentTarget;r(()=>{n(new FormData(t))})}},...t})}function S({children:e}){let{isPending:t}=g();return typeof e==`function`?e({isPending:t}):t&&e}function C({children:e}){let{isPending:t}=g();return e({...d(),disabled:t})}export{_ as Action,x as Form,S as Pending,p as ResetAction,C as Submit,y as ZodFieldError,b as createComponents,v as noError,g as useActionContext,f as useResetAction};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { ZodObject, ZodTuple, ZodType, z } from "zod/v4";
|
|
2
2
|
import { $ZodErrorTree, $ZodShape, $ZodType } from "zod/v4/core";
|
|
3
|
-
//#region src/createFormAction.d.ts
|
|
4
3
|
type InitialState<T> = {
|
|
5
4
|
type: "initial";
|
|
6
5
|
data: T;
|
|
@@ -33,8 +32,6 @@ declare function createFormAction<Data, Error = Data, ValidationError = Record<s
|
|
|
33
32
|
failure: (error: Error) => FailureState<Error>;
|
|
34
33
|
invalid: (validationError: ValidationError) => InvalidState<ValidationError>;
|
|
35
34
|
}, ...args: Arguments) => FormAction<Data, Error, ValidationError, Payload>): (...args: [...Arguments, state: ActionState<Data, Error, ValidationError>, payload: Payload]) => Promise<ActionState<Data, Error, ValidationError>>;
|
|
36
|
-
//#endregion
|
|
37
|
-
//#region src/formAction.d.ts
|
|
38
35
|
declare const emptyInput: unique symbol;
|
|
39
36
|
type EmptyInput = typeof emptyInput;
|
|
40
37
|
type Flatten<T> = Identity<{ [K in keyof T]: T[K]; }>;
|
|
@@ -86,5 +83,4 @@ type FormActionBuilder<Schema extends ZodType | EmptyInput, Args extends $ZodTyp
|
|
|
86
83
|
error: <TErr>(processError: ErrorHandler<Context, TErr, PlainArgs>) => FormActionBuilder<Schema, Args, TErr, Context>;
|
|
87
84
|
};
|
|
88
85
|
declare const formAction: FormActionBuilder<typeof emptyInput, [], unknown, InitialContext, []>;
|
|
89
|
-
//#endregion
|
|
90
86
|
export { FormAction as a, SuccessState as c, FailureState as i, createFormAction as l, formAction as n, InitialState as o, ActionState as r, InvalidState as s, Flatten as t, initial as u };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import { a as FormAction, c as SuccessState, i as FailureState, l as createFormAction, n as formAction, o as InitialState, r as ActionState, s as InvalidState, t as Flatten, u as initial } from "./formAction-
|
|
1
|
+
import { a as FormAction, c as SuccessState, i as FailureState, l as createFormAction, n as formAction, o as InitialState, r as ActionState, s as InvalidState, t as Flatten, u as initial } from "./formAction-CGw5j857.mjs";
|
|
2
2
|
import { ZodObject, z } from "zod";
|
|
3
|
-
//#region src/validateSchema.d.ts
|
|
4
3
|
/**
|
|
5
4
|
* A helper to make a validate function for the client validation with <Action validate={} /> prop.
|
|
6
5
|
* @param schema z.object(...) schema
|
|
7
6
|
* @returns validate function
|
|
8
7
|
*/
|
|
9
|
-
declare function validateSchema<T extends ZodObject>(schema: T): (formData: FormData) => z.core.$ZodErrorTree<z.infer<T>, string> | null;
|
|
10
|
-
|
|
11
|
-
export { ActionState, FailureState, Flatten, FormAction, InitialState, InvalidState, SuccessState, createFormAction, formAction, initial, validateSchema };
|
|
8
|
+
export declare function validateSchema<T extends ZodObject>(schema: T): (formData: FormData) => z.core.$ZodErrorTree<z.infer<T>, string> | null;
|
|
9
|
+
export { ActionState, FailureState, Flatten, FormAction, InitialState, InvalidState, SuccessState, createFormAction, formAction, initial };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-form-action",
|
|
3
|
-
"version": "2.19.
|
|
3
|
+
"version": "2.19.1",
|
|
4
4
|
"description": "State management helpers for the react form actions.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -57,22 +57,22 @@
|
|
|
57
57
|
"zod-form-data": "^3.0.0"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
|
-
"@biomejs/biome": "^2.
|
|
61
|
-
"@testing-library/dom": "^10.4.
|
|
60
|
+
"@biomejs/biome": "^2.6.6",
|
|
61
|
+
"@testing-library/dom": "^10.4.2",
|
|
62
62
|
"@testing-library/jest-dom": "^7.0.1",
|
|
63
63
|
"@testing-library/react": "^16.3.3",
|
|
64
|
-
"@testing-library/user-event": "^14.6.
|
|
65
|
-
"@types/react": "^19.
|
|
66
|
-
"@types/react-dom": "^19.
|
|
67
|
-
"@vitejs/plugin-react": "^6.
|
|
68
|
-
"happy-dom": "^
|
|
69
|
-
"npm-check-updates": "^23.1.
|
|
70
|
-
"react": "^19.
|
|
71
|
-
"react-dom": "^19.
|
|
72
|
-
"tsdown": "^0.
|
|
64
|
+
"@testing-library/user-event": "^14.6.8",
|
|
65
|
+
"@types/react": "^19.3.0",
|
|
66
|
+
"@types/react-dom": "^19.3.0",
|
|
67
|
+
"@vitejs/plugin-react": "^6.2.1",
|
|
68
|
+
"happy-dom": "^21.0.4",
|
|
69
|
+
"npm-check-updates": "^23.1.1",
|
|
70
|
+
"react": "^19.3.1",
|
|
71
|
+
"react-dom": "^19.3.1",
|
|
72
|
+
"tsdown": "^0.23.7",
|
|
73
73
|
"typescript": "^7.0.2",
|
|
74
|
-
"vitest": "^
|
|
75
|
-
"zod": "^4.
|
|
76
|
-
"zod-form-data": "^3.0.
|
|
74
|
+
"vitest": "^5.1.0",
|
|
75
|
+
"zod": "^4.6.7",
|
|
76
|
+
"zod-form-data": "^3.0.4"
|
|
77
77
|
}
|
|
78
78
|
}
|