@conform-to/react 1.0.0-pre.6 → 1.0.0-pre.7
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 +32 -0
- package/context.d.ts +22 -20
- package/context.js +24 -25
- package/context.mjs +24 -26
- package/helpers.d.ts +9 -13
- package/helpers.js +5 -8
- package/helpers.mjs +5 -8
- package/hooks.d.ts +4 -4
- package/hooks.js +8 -8
- package/hooks.mjs +9 -9
- package/index.d.ts +1 -2
- package/index.js +2 -12
- package/index.mjs +1 -2
- package/integrations.d.ts +3 -3
- package/integrations.js +12 -12
- package/integrations.mjs +12 -12
- package/package.json +2 -2
- package/README.md +0 -606
- package/validitystate.d.ts +0 -12
- package/validitystate.js +0 -38
- package/validitystate.mjs +0 -34
package/README
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
███████╗ ██████╗ ███╗ ██╗ ████████╗ ██████╗ ███████╗ ███╗ ███╗
|
|
4
|
+
██╔═════╝ ██╔═══██╗ ████╗ ██║ ██╔═════╝ ██╔═══██╗ ██╔═══██╗ ████████║
|
|
5
|
+
██║ ██║ ██║ ██╔██╗██║ ███████╗ ██║ ██║ ███████╔╝ ██╔██╔██║
|
|
6
|
+
██║ ██║ ██║ ██║╚████║ ██╔════╝ ██║ ██║ ██╔═══██╗ ██║╚═╝██║
|
|
7
|
+
╚███████╗ ╚██████╔╝ ██║ ╚███║ ██║ ╚██████╔╝ ██║ ██║ ██║ ██║
|
|
8
|
+
╚══════╝ ╚═════╝ ╚═╝ ╚══╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
Version 1.0.0-pre.7 / License MIT / Copyright (c) 2024 Edmund Hung
|
|
12
|
+
|
|
13
|
+
A type-safe form validation library utilizing web fundamentals to progressively enhance HTML Forms with full support for server frameworks like Remix route action and Next.js server actions.
|
|
14
|
+
|
|
15
|
+
> Getting Started
|
|
16
|
+
|
|
17
|
+
Check out the overview and tutorial at our website https://conform.guide
|
|
18
|
+
|
|
19
|
+
> Documentation
|
|
20
|
+
|
|
21
|
+
The documentation is divided into several sections:
|
|
22
|
+
|
|
23
|
+
* Overview: https://conform.guide/overview
|
|
24
|
+
* Example Usages: https://conform.guide/examples
|
|
25
|
+
* Complex structures: https://conform.guide/complex-structures
|
|
26
|
+
* UI Integrations: https://conform.guide/integrations
|
|
27
|
+
* Accessibility Guide: https://conform.guide/accessibility
|
|
28
|
+
* API Reference: https://conform.guide/references
|
|
29
|
+
|
|
30
|
+
> Support
|
|
31
|
+
|
|
32
|
+
To report a bug, please open an issue on the repository at https://github.com/edmundhung/conform. For feature requests and questions, you can post them in the Discussions section.
|
package/context.d.ts
CHANGED
|
@@ -1,49 +1,50 @@
|
|
|
1
|
-
import { type Constraint, type
|
|
1
|
+
import { type Constraint, type FormId, type FieldName, type FormContext, type FormValue, type FormState, type Intent, type SubscriptionScope, type SubscriptionSubject, type UnionKeyof, type UnionKeyType } from '@conform-to/dom';
|
|
2
2
|
import { type ReactElement, type ReactNode, type MutableRefObject } from 'react';
|
|
3
3
|
export type Pretty<T> = {
|
|
4
4
|
[K in keyof T]: T[K];
|
|
5
5
|
} & {};
|
|
6
6
|
export type Primitive = string | number | boolean | Date | File | null | undefined;
|
|
7
|
-
export type Metadata<Schema,
|
|
7
|
+
export type Metadata<Schema, FormSchema extends Record<string, unknown>, FormError = string[]> = {
|
|
8
8
|
key: string | undefined;
|
|
9
9
|
id: string;
|
|
10
10
|
errorId: string;
|
|
11
11
|
descriptionId: string;
|
|
12
|
-
name: FieldName<Schema,
|
|
12
|
+
name: FieldName<Schema, FormSchema, FormError>;
|
|
13
13
|
initialValue: FormValue<Schema>;
|
|
14
14
|
value: FormValue<Schema>;
|
|
15
15
|
errors: FormError | undefined;
|
|
16
16
|
allErrors: Record<string, FormError>;
|
|
17
|
-
allValid: boolean;
|
|
18
17
|
valid: boolean;
|
|
19
18
|
dirty: boolean;
|
|
20
19
|
};
|
|
21
|
-
export type FormMetadata<Schema extends Record<string, unknown> = Record<string, unknown>, FormError = string[]> = Omit<Metadata<Schema,
|
|
20
|
+
export type FormMetadata<Schema extends Record<string, unknown> = Record<string, unknown>, FormError = string[]> = Omit<Metadata<Schema, Schema, FormError>, 'id'> & Pick<FormContext<Schema, FormError>, Intent['type']> & {
|
|
22
21
|
id: FormId<Schema, FormError>;
|
|
23
|
-
context: FormContext<Schema, FormError
|
|
22
|
+
context: Wrapped<FormContext<Schema, FormError>>;
|
|
24
23
|
status?: 'success' | 'error';
|
|
25
|
-
dispatch(control: FormControl): void;
|
|
26
|
-
getControlButtonProps(control: FormControl): ControlButtonProps;
|
|
27
24
|
getFieldset: () => {
|
|
28
|
-
[Key in UnionKeyof<Schema>]: FieldMetadata<UnionKeyType<Schema, Key>,
|
|
25
|
+
[Key in UnionKeyof<Schema>]: FieldMetadata<UnionKeyType<Schema, Key>, Schema, FormError>;
|
|
29
26
|
};
|
|
30
|
-
onSubmit: (event: React.FormEvent<HTMLFormElement>) =>
|
|
31
|
-
onReset: (event: React.FormEvent<HTMLFormElement>) => void;
|
|
27
|
+
onSubmit: (event: React.FormEvent<HTMLFormElement>) => void;
|
|
32
28
|
noValidate: boolean;
|
|
33
29
|
};
|
|
34
|
-
export type FieldMetadata<Schema = unknown,
|
|
30
|
+
export type FieldMetadata<Schema = unknown, FormSchema extends Record<string, any> = Record<string, unknown>, FormError = string[]> = Metadata<Schema, FormSchema, FormError> & {
|
|
35
31
|
formId: FormId<FormSchema, FormError>;
|
|
36
32
|
constraint?: Constraint;
|
|
37
33
|
getFieldset: unknown extends Schema ? () => unknown : Schema extends Primitive | Array<any> ? never : () => {
|
|
38
|
-
[Key in UnionKeyof<Schema>]: FieldMetadata<UnionKeyType<Schema, Key>, FormError>;
|
|
34
|
+
[Key in UnionKeyof<Schema>]: FieldMetadata<UnionKeyType<Schema, Key>, FormSchema, FormError>;
|
|
39
35
|
};
|
|
40
|
-
getFieldList: unknown extends Schema ? () => unknown : Schema extends Array<infer Item> ? () => Array<FieldMetadata<Item, FormError>> : never;
|
|
36
|
+
getFieldList: unknown extends Schema ? () => unknown : Schema extends Array<infer Item> ? () => Array<FieldMetadata<Item, FormSchema, FormError>> : never;
|
|
41
37
|
};
|
|
42
38
|
export declare const Form: import("react").Context<FormContext[]>;
|
|
43
|
-
|
|
44
|
-
export
|
|
39
|
+
declare const wrappedSymbol: unique symbol;
|
|
40
|
+
export type Wrapped<Type> = {
|
|
41
|
+
[wrappedSymbol]: Type;
|
|
42
|
+
};
|
|
43
|
+
export declare function getWrappedFormContext(context: Wrapped<FormContext>): FormContext;
|
|
44
|
+
export declare function useFormContext<Schema extends Record<string, any>, FormError>(formId?: FormId<Schema, FormError>): FormContext<Schema, unknown, FormError>;
|
|
45
|
+
export declare function useFormState<FormError>(form: FormContext<any, any, FormError>, subjectRef?: MutableRefObject<SubscriptionSubject>): FormState<FormError>;
|
|
45
46
|
export declare function FormProvider(props: {
|
|
46
|
-
context: FormContext<any, any, any
|
|
47
|
+
context: Wrapped<FormContext<any, any, any>>;
|
|
47
48
|
children: ReactNode;
|
|
48
49
|
}): ReactElement;
|
|
49
50
|
export declare function FormStateInput(props: {
|
|
@@ -51,6 +52,7 @@ export declare function FormStateInput(props: {
|
|
|
51
52
|
}): React.ReactElement;
|
|
52
53
|
export declare function useSubjectRef(initialSubject?: SubscriptionSubject): MutableRefObject<SubscriptionSubject>;
|
|
53
54
|
export declare function updateSubjectRef(ref: MutableRefObject<SubscriptionSubject>, name: string, subject: keyof SubscriptionSubject, scope: keyof SubscriptionScope): void;
|
|
54
|
-
export declare function getMetadata<Schema, FormError, FormSchema extends Record<string, any>>(formId: FormId<FormSchema, FormError>, state: FormState<FormError>, subjectRef: MutableRefObject<SubscriptionSubject>, name?: FieldName<Schema,
|
|
55
|
-
export declare function getFieldMetadata<Schema,
|
|
56
|
-
export declare function getFormMetadata<Schema extends Record<string, any>, FormError = string[]>(formId: FormId<Schema, FormError>, state: FormState<FormError>, subjectRef: MutableRefObject<SubscriptionSubject>, context: FormContext<Schema,
|
|
55
|
+
export declare function getMetadata<Schema, FormError, FormSchema extends Record<string, any>>(formId: FormId<FormSchema, FormError>, state: FormState<FormError>, subjectRef: MutableRefObject<SubscriptionSubject>, name?: FieldName<Schema, FormSchema, FormError>): Metadata<Schema, FormSchema, FormError>;
|
|
56
|
+
export declare function getFieldMetadata<Schema, FormSchema extends Record<string, any>, FormError>(formId: FormId<FormSchema, FormError>, state: FormState<FormError>, subjectRef: MutableRefObject<SubscriptionSubject>, prefix?: string, key?: string | number): FieldMetadata<Schema, FormSchema, FormError>;
|
|
57
|
+
export declare function getFormMetadata<Schema extends Record<string, any>, FormValue = Schema, FormError = string[]>(formId: FormId<Schema, FormError>, state: FormState<FormError>, subjectRef: MutableRefObject<SubscriptionSubject>, context: FormContext<Schema, FormValue, FormError>, noValidate: boolean): FormMetadata<Schema, FormError>;
|
|
58
|
+
export {};
|
package/context.js
CHANGED
|
@@ -8,6 +8,12 @@ var react = require('react');
|
|
|
8
8
|
var jsxRuntime = require('react/jsx-runtime');
|
|
9
9
|
|
|
10
10
|
var Form = /*#__PURE__*/react.createContext([]);
|
|
11
|
+
|
|
12
|
+
// To hide the FormContext type from the public API
|
|
13
|
+
var wrappedSymbol = Symbol('wrapped');
|
|
14
|
+
function getWrappedFormContext(context) {
|
|
15
|
+
return context[wrappedSymbol];
|
|
16
|
+
}
|
|
11
17
|
function useFormContext(formId) {
|
|
12
18
|
var contexts = react.useContext(Form);
|
|
13
19
|
var form = formId ? contexts.find(context => context.formId === formId) : contexts[0];
|
|
@@ -22,9 +28,10 @@ function useFormState(form, subjectRef) {
|
|
|
22
28
|
}
|
|
23
29
|
function FormProvider(props) {
|
|
24
30
|
var forms = react.useContext(Form);
|
|
25
|
-
var
|
|
31
|
+
var context = getWrappedFormContext(props.context);
|
|
32
|
+
var value = react.useMemo(() => [context].concat(forms),
|
|
26
33
|
// Put the latest form context first
|
|
27
|
-
[forms,
|
|
34
|
+
[forms, context]);
|
|
28
35
|
return /*#__PURE__*/jsxRuntime.jsx(Form.Provider, {
|
|
29
36
|
value: value,
|
|
30
37
|
children: props.children
|
|
@@ -78,18 +85,6 @@ function getMetadata(formId, state, subjectRef) {
|
|
|
78
85
|
get dirty() {
|
|
79
86
|
return state.dirty[name];
|
|
80
87
|
},
|
|
81
|
-
get allValid() {
|
|
82
|
-
var keys = Object.keys(state.error);
|
|
83
|
-
if (name === '') {
|
|
84
|
-
return keys.length === 0;
|
|
85
|
-
}
|
|
86
|
-
for (var key of Object.keys(state.error)) {
|
|
87
|
-
if (dom.isPrefix(key, name) && !state.valid[key]) {
|
|
88
|
-
return false;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
return true;
|
|
92
|
-
},
|
|
93
88
|
get allErrors() {
|
|
94
89
|
if (name === '') {
|
|
95
90
|
return state.error;
|
|
@@ -116,18 +111,15 @@ function getMetadata(formId, state, subjectRef) {
|
|
|
116
111
|
get(target, key, receiver) {
|
|
117
112
|
switch (key) {
|
|
118
113
|
case 'key':
|
|
119
|
-
case 'errors':
|
|
120
114
|
case 'initialValue':
|
|
121
115
|
case 'value':
|
|
122
116
|
case 'valid':
|
|
123
117
|
case 'dirty':
|
|
124
|
-
updateSubjectRef(subjectRef, name, key
|
|
118
|
+
updateSubjectRef(subjectRef, name, key, 'name');
|
|
125
119
|
break;
|
|
120
|
+
case 'errors':
|
|
126
121
|
case 'allErrors':
|
|
127
|
-
updateSubjectRef(subjectRef, name, 'error', 'prefix');
|
|
128
|
-
break;
|
|
129
|
-
case 'allValid':
|
|
130
|
-
updateSubjectRef(subjectRef, name, 'valid', 'prefix');
|
|
122
|
+
updateSubjectRef(subjectRef, name, 'error', key === 'errors' ? 'name' : 'prefix');
|
|
131
123
|
break;
|
|
132
124
|
}
|
|
133
125
|
return Reflect.get(target, key, receiver);
|
|
@@ -169,17 +161,23 @@ function getFormMetadata(formId, state, subjectRef, context, noValidate) {
|
|
|
169
161
|
get(_, key, receiver) {
|
|
170
162
|
switch (key) {
|
|
171
163
|
case 'context':
|
|
172
|
-
return
|
|
164
|
+
return {
|
|
165
|
+
[wrappedSymbol]: context
|
|
166
|
+
};
|
|
173
167
|
case 'status':
|
|
174
168
|
return state.submissionStatus;
|
|
175
|
-
case '
|
|
176
|
-
case '
|
|
169
|
+
case 'validate':
|
|
170
|
+
case 'update':
|
|
171
|
+
case 'reset':
|
|
172
|
+
case 'insert':
|
|
173
|
+
case 'remove':
|
|
174
|
+
case 'reorder':
|
|
177
175
|
return context[key];
|
|
178
176
|
case 'onSubmit':
|
|
179
177
|
return event => {
|
|
180
178
|
var submitEvent = event.nativeEvent;
|
|
181
|
-
context.submit(submitEvent);
|
|
182
|
-
if (
|
|
179
|
+
var submission = context.submit(submitEvent);
|
|
180
|
+
if (submission && submission.status !== 'success' && submission.error !== null) {
|
|
183
181
|
event.preventDefault();
|
|
184
182
|
}
|
|
185
183
|
};
|
|
@@ -197,6 +195,7 @@ exports.FormStateInput = FormStateInput;
|
|
|
197
195
|
exports.getFieldMetadata = getFieldMetadata;
|
|
198
196
|
exports.getFormMetadata = getFormMetadata;
|
|
199
197
|
exports.getMetadata = getMetadata;
|
|
198
|
+
exports.getWrappedFormContext = getWrappedFormContext;
|
|
200
199
|
exports.updateSubjectRef = updateSubjectRef;
|
|
201
200
|
exports.useFormContext = useFormContext;
|
|
202
201
|
exports.useFormState = useFormState;
|
package/context.mjs
CHANGED
|
@@ -4,6 +4,12 @@ import { useContext, useMemo, createContext, useCallback, useSyncExternalStore,
|
|
|
4
4
|
import { jsx } from 'react/jsx-runtime';
|
|
5
5
|
|
|
6
6
|
var Form = /*#__PURE__*/createContext([]);
|
|
7
|
+
|
|
8
|
+
// To hide the FormContext type from the public API
|
|
9
|
+
var wrappedSymbol = Symbol('wrapped');
|
|
10
|
+
function getWrappedFormContext(context) {
|
|
11
|
+
return context[wrappedSymbol];
|
|
12
|
+
}
|
|
7
13
|
function useFormContext(formId) {
|
|
8
14
|
var contexts = useContext(Form);
|
|
9
15
|
var form = formId ? contexts.find(context => context.formId === formId) : contexts[0];
|
|
@@ -18,9 +24,10 @@ function useFormState(form, subjectRef) {
|
|
|
18
24
|
}
|
|
19
25
|
function FormProvider(props) {
|
|
20
26
|
var forms = useContext(Form);
|
|
21
|
-
var
|
|
27
|
+
var context = getWrappedFormContext(props.context);
|
|
28
|
+
var value = useMemo(() => [context].concat(forms),
|
|
22
29
|
// Put the latest form context first
|
|
23
|
-
[forms,
|
|
30
|
+
[forms, context]);
|
|
24
31
|
return /*#__PURE__*/jsx(Form.Provider, {
|
|
25
32
|
value: value,
|
|
26
33
|
children: props.children
|
|
@@ -74,18 +81,6 @@ function getMetadata(formId, state, subjectRef) {
|
|
|
74
81
|
get dirty() {
|
|
75
82
|
return state.dirty[name];
|
|
76
83
|
},
|
|
77
|
-
get allValid() {
|
|
78
|
-
var keys = Object.keys(state.error);
|
|
79
|
-
if (name === '') {
|
|
80
|
-
return keys.length === 0;
|
|
81
|
-
}
|
|
82
|
-
for (var key of Object.keys(state.error)) {
|
|
83
|
-
if (isPrefix(key, name) && !state.valid[key]) {
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
return true;
|
|
88
|
-
},
|
|
89
84
|
get allErrors() {
|
|
90
85
|
if (name === '') {
|
|
91
86
|
return state.error;
|
|
@@ -112,18 +107,15 @@ function getMetadata(formId, state, subjectRef) {
|
|
|
112
107
|
get(target, key, receiver) {
|
|
113
108
|
switch (key) {
|
|
114
109
|
case 'key':
|
|
115
|
-
case 'errors':
|
|
116
110
|
case 'initialValue':
|
|
117
111
|
case 'value':
|
|
118
112
|
case 'valid':
|
|
119
113
|
case 'dirty':
|
|
120
|
-
updateSubjectRef(subjectRef, name, key
|
|
114
|
+
updateSubjectRef(subjectRef, name, key, 'name');
|
|
121
115
|
break;
|
|
116
|
+
case 'errors':
|
|
122
117
|
case 'allErrors':
|
|
123
|
-
updateSubjectRef(subjectRef, name, 'error', 'prefix');
|
|
124
|
-
break;
|
|
125
|
-
case 'allValid':
|
|
126
|
-
updateSubjectRef(subjectRef, name, 'valid', 'prefix');
|
|
118
|
+
updateSubjectRef(subjectRef, name, 'error', key === 'errors' ? 'name' : 'prefix');
|
|
127
119
|
break;
|
|
128
120
|
}
|
|
129
121
|
return Reflect.get(target, key, receiver);
|
|
@@ -165,17 +157,23 @@ function getFormMetadata(formId, state, subjectRef, context, noValidate) {
|
|
|
165
157
|
get(_, key, receiver) {
|
|
166
158
|
switch (key) {
|
|
167
159
|
case 'context':
|
|
168
|
-
return
|
|
160
|
+
return {
|
|
161
|
+
[wrappedSymbol]: context
|
|
162
|
+
};
|
|
169
163
|
case 'status':
|
|
170
164
|
return state.submissionStatus;
|
|
171
|
-
case '
|
|
172
|
-
case '
|
|
165
|
+
case 'validate':
|
|
166
|
+
case 'update':
|
|
167
|
+
case 'reset':
|
|
168
|
+
case 'insert':
|
|
169
|
+
case 'remove':
|
|
170
|
+
case 'reorder':
|
|
173
171
|
return context[key];
|
|
174
172
|
case 'onSubmit':
|
|
175
173
|
return event => {
|
|
176
174
|
var submitEvent = event.nativeEvent;
|
|
177
|
-
context.submit(submitEvent);
|
|
178
|
-
if (
|
|
175
|
+
var submission = context.submit(submitEvent);
|
|
176
|
+
if (submission && submission.status !== 'success' && submission.error !== null) {
|
|
179
177
|
event.preventDefault();
|
|
180
178
|
}
|
|
181
179
|
};
|
|
@@ -187,4 +185,4 @@ function getFormMetadata(formId, state, subjectRef, context, noValidate) {
|
|
|
187
185
|
});
|
|
188
186
|
}
|
|
189
187
|
|
|
190
|
-
export { Form, FormProvider, FormStateInput, getFieldMetadata, getFormMetadata, getMetadata, updateSubjectRef, useFormContext, useFormState, useSubjectRef };
|
|
188
|
+
export { Form, FormProvider, FormStateInput, getFieldMetadata, getFormMetadata, getMetadata, getWrappedFormContext, updateSubjectRef, useFormContext, useFormState, useSubjectRef };
|
package/helpers.d.ts
CHANGED
|
@@ -6,7 +6,6 @@ type FormControlProps = {
|
|
|
6
6
|
name: string;
|
|
7
7
|
form: string;
|
|
8
8
|
required?: boolean;
|
|
9
|
-
autoFocus?: boolean;
|
|
10
9
|
'aria-describedby'?: string;
|
|
11
10
|
'aria-invalid'?: boolean;
|
|
12
11
|
};
|
|
@@ -16,19 +15,19 @@ type FormControlOptions = {
|
|
|
16
15
|
*/
|
|
17
16
|
ariaAttributes?: true;
|
|
18
17
|
/**
|
|
19
|
-
* Decide whether the aria attributes should be based on `
|
|
20
|
-
* @default '
|
|
18
|
+
* Decide whether the aria-invalid attributes should be based on `meta.errors` or `meta.allErrors`.
|
|
19
|
+
* @default 'errors'
|
|
21
20
|
*/
|
|
22
|
-
ariaInvalid?: '
|
|
21
|
+
ariaInvalid?: 'errors' | 'allErrors';
|
|
23
22
|
/**
|
|
24
|
-
* Assign additional `id` to the `aria-describedby` attribute.
|
|
23
|
+
* Assign additional `id` to the `aria-describedby` attribute.
|
|
25
24
|
*/
|
|
26
|
-
ariaDescribedBy?:
|
|
25
|
+
ariaDescribedBy?: string;
|
|
27
26
|
} | {
|
|
28
27
|
ariaAttributes: false;
|
|
29
28
|
};
|
|
30
29
|
type InputProps = Pretty<FormControlProps & {
|
|
31
|
-
type
|
|
30
|
+
type: 'checkbox' | 'color' | 'date' | 'datetime-local' | 'email' | 'file' | 'hidden' | 'image' | 'month' | 'number' | 'password' | 'radio' | 'range' | 'search' | 'tel' | 'text' | 'time' | 'url' | 'week';
|
|
32
31
|
minLength?: number;
|
|
33
32
|
maxLength?: number;
|
|
34
33
|
min?: string | number;
|
|
@@ -48,7 +47,7 @@ type InputOptions = Pretty<FormControlOptions & ({
|
|
|
48
47
|
*/
|
|
49
48
|
value?: string | boolean;
|
|
50
49
|
} | {
|
|
51
|
-
type
|
|
50
|
+
type: Exclude<InputProps['type'], 'checkbox' | 'radio'>;
|
|
52
51
|
/**
|
|
53
52
|
* Decide whether defaultValue should be returned. Pass `false` if you want to mange the value yourself.
|
|
54
53
|
*/
|
|
@@ -130,7 +129,7 @@ export declare function getFormControlProps<Schema>(metadata: FieldMetadata<Sche
|
|
|
130
129
|
* @example
|
|
131
130
|
* ```tsx
|
|
132
131
|
* // To setup an uncontrolled input
|
|
133
|
-
* <input {...getInputProps(metadata)} />
|
|
132
|
+
* <input {...getInputProps(metadata, { type: 'text' })} />
|
|
134
133
|
* // To setup an uncontrolled checkbox
|
|
135
134
|
* <input {...getInputProps(metadata, { type: 'checkbox' })} />
|
|
136
135
|
* // To setup an input without defaultValue
|
|
@@ -139,10 +138,7 @@ export declare function getFormControlProps<Schema>(metadata: FieldMetadata<Sche
|
|
|
139
138
|
* <input {...getInputProps(metadata, { type: 'radio', value: false })} />
|
|
140
139
|
* ```
|
|
141
140
|
*/
|
|
142
|
-
export declare function getInputProps<Schema extends
|
|
143
|
-
export declare function getInputProps<Schema extends File | File[] | null | undefined>(metadata: FieldMetadata<Schema, any, any>, options: InputOptions & {
|
|
144
|
-
type: 'file';
|
|
145
|
-
}): InputProps;
|
|
141
|
+
export declare function getInputProps<Schema extends Primitive | File[]>(metadata: FieldMetadata<Schema, any, any>, options: InputOptions): InputProps;
|
|
146
142
|
/**
|
|
147
143
|
* Derives the properties of a select element based on the field metadata,
|
|
148
144
|
* including common form control attributes like `key`, `id`, `name`, `form`, `autoFocus`, `aria-invalid`, `aria-describedby`
|
package/helpers.js
CHANGED
|
@@ -25,8 +25,8 @@ function getAriaAttributes(metadata) {
|
|
|
25
25
|
if (typeof options.ariaAttributes !== 'undefined' && !options.ariaAttributes) {
|
|
26
26
|
return {};
|
|
27
27
|
}
|
|
28
|
-
var invalid = options.ariaInvalid === '
|
|
29
|
-
var ariaDescribedBy =
|
|
28
|
+
var invalid = options.ariaInvalid === 'allErrors' ? !metadata.valid : typeof metadata.errors !== 'undefined';
|
|
29
|
+
var ariaDescribedBy = options.ariaDescribedBy;
|
|
30
30
|
return simplify({
|
|
31
31
|
'aria-invalid': invalid || undefined,
|
|
32
32
|
'aria-describedby': invalid ? "".concat(metadata.errorId, " ").concat(ariaDescribedBy !== null && ariaDescribedBy !== void 0 ? ariaDescribedBy : '').trim() : ariaDescribedBy
|
|
@@ -75,8 +75,7 @@ function getFormControlProps(metadata, options) {
|
|
|
75
75
|
var _metadata$constraint;
|
|
76
76
|
return simplify(_rollupPluginBabelHelpers.objectSpread2({
|
|
77
77
|
key: metadata.key,
|
|
78
|
-
required: ((_metadata$constraint = metadata.constraint) === null || _metadata$constraint === void 0 ? void 0 : _metadata$constraint.required) || undefined
|
|
79
|
-
autoFocus: !metadata.valid || undefined
|
|
78
|
+
required: ((_metadata$constraint = metadata.constraint) === null || _metadata$constraint === void 0 ? void 0 : _metadata$constraint.required) || undefined
|
|
80
79
|
}, getFieldsetProps(metadata, options)));
|
|
81
80
|
}
|
|
82
81
|
|
|
@@ -91,7 +90,7 @@ function getFormControlProps(metadata, options) {
|
|
|
91
90
|
* @example
|
|
92
91
|
* ```tsx
|
|
93
92
|
* // To setup an uncontrolled input
|
|
94
|
-
* <input {...getInputProps(metadata)} />
|
|
93
|
+
* <input {...getInputProps(metadata, { type: 'text' })} />
|
|
95
94
|
* // To setup an uncontrolled checkbox
|
|
96
95
|
* <input {...getInputProps(metadata, { type: 'checkbox' })} />
|
|
97
96
|
* // To setup an input without defaultValue
|
|
@@ -100,10 +99,8 @@ function getFormControlProps(metadata, options) {
|
|
|
100
99
|
* <input {...getInputProps(metadata, { type: 'radio', value: false })} />
|
|
101
100
|
* ```
|
|
102
101
|
*/
|
|
103
|
-
|
|
104
|
-
function getInputProps(metadata) {
|
|
102
|
+
function getInputProps(metadata, options) {
|
|
105
103
|
var _metadata$constraint2, _metadata$constraint3, _metadata$constraint4, _metadata$constraint5, _metadata$constraint6, _metadata$constraint7, _metadata$constraint8;
|
|
106
|
-
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
107
104
|
var props = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormControlProps(metadata, options)), {}, {
|
|
108
105
|
type: options.type,
|
|
109
106
|
minLength: (_metadata$constraint2 = metadata.constraint) === null || _metadata$constraint2 === void 0 ? void 0 : _metadata$constraint2.minLength,
|
package/helpers.mjs
CHANGED
|
@@ -21,8 +21,8 @@ function getAriaAttributes(metadata) {
|
|
|
21
21
|
if (typeof options.ariaAttributes !== 'undefined' && !options.ariaAttributes) {
|
|
22
22
|
return {};
|
|
23
23
|
}
|
|
24
|
-
var invalid = options.ariaInvalid === '
|
|
25
|
-
var ariaDescribedBy =
|
|
24
|
+
var invalid = options.ariaInvalid === 'allErrors' ? !metadata.valid : typeof metadata.errors !== 'undefined';
|
|
25
|
+
var ariaDescribedBy = options.ariaDescribedBy;
|
|
26
26
|
return simplify({
|
|
27
27
|
'aria-invalid': invalid || undefined,
|
|
28
28
|
'aria-describedby': invalid ? "".concat(metadata.errorId, " ").concat(ariaDescribedBy !== null && ariaDescribedBy !== void 0 ? ariaDescribedBy : '').trim() : ariaDescribedBy
|
|
@@ -71,8 +71,7 @@ function getFormControlProps(metadata, options) {
|
|
|
71
71
|
var _metadata$constraint;
|
|
72
72
|
return simplify(_objectSpread2({
|
|
73
73
|
key: metadata.key,
|
|
74
|
-
required: ((_metadata$constraint = metadata.constraint) === null || _metadata$constraint === void 0 ? void 0 : _metadata$constraint.required) || undefined
|
|
75
|
-
autoFocus: !metadata.valid || undefined
|
|
74
|
+
required: ((_metadata$constraint = metadata.constraint) === null || _metadata$constraint === void 0 ? void 0 : _metadata$constraint.required) || undefined
|
|
76
75
|
}, getFieldsetProps(metadata, options)));
|
|
77
76
|
}
|
|
78
77
|
|
|
@@ -87,7 +86,7 @@ function getFormControlProps(metadata, options) {
|
|
|
87
86
|
* @example
|
|
88
87
|
* ```tsx
|
|
89
88
|
* // To setup an uncontrolled input
|
|
90
|
-
* <input {...getInputProps(metadata)} />
|
|
89
|
+
* <input {...getInputProps(metadata, { type: 'text' })} />
|
|
91
90
|
* // To setup an uncontrolled checkbox
|
|
92
91
|
* <input {...getInputProps(metadata, { type: 'checkbox' })} />
|
|
93
92
|
* // To setup an input without defaultValue
|
|
@@ -96,10 +95,8 @@ function getFormControlProps(metadata, options) {
|
|
|
96
95
|
* <input {...getInputProps(metadata, { type: 'radio', value: false })} />
|
|
97
96
|
* ```
|
|
98
97
|
*/
|
|
99
|
-
|
|
100
|
-
function getInputProps(metadata) {
|
|
98
|
+
function getInputProps(metadata, options) {
|
|
101
99
|
var _metadata$constraint2, _metadata$constraint3, _metadata$constraint4, _metadata$constraint5, _metadata$constraint6, _metadata$constraint7, _metadata$constraint8;
|
|
102
|
-
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
103
100
|
var props = _objectSpread2(_objectSpread2({}, getFormControlProps(metadata, options)), {}, {
|
|
104
101
|
type: options.type,
|
|
105
102
|
minLength: (_metadata$constraint2 = metadata.constraint) === null || _metadata$constraint2 === void 0 ? void 0 : _metadata$constraint2.minLength,
|
package/hooks.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { type FormMetadata, type FieldMetadata, type Pretty } from './context';
|
|
|
8
8
|
export declare const useSafeLayoutEffect: typeof useEffect;
|
|
9
9
|
export declare function useFormId<Schema extends Record<string, unknown>, FormError>(preferredId?: string): FormId<Schema, FormError>;
|
|
10
10
|
export declare function useNoValidate(defaultNoValidate?: boolean): boolean;
|
|
11
|
-
export declare function useForm<Schema extends Record<string, any>,
|
|
11
|
+
export declare function useForm<Schema extends Record<string, any>, FormValue = Schema, FormError = string[]>(options: Pretty<Omit<FormOptions<Schema, FormError, FormValue>, 'formId'> & {
|
|
12
12
|
/**
|
|
13
13
|
* The form id. If not provided, a random id will be generated.
|
|
14
14
|
*/
|
|
@@ -23,12 +23,12 @@ export declare function useForm<Schema extends Record<string, any>, FormError =
|
|
|
23
23
|
FormMetadata<Schema, FormError>,
|
|
24
24
|
ReturnType<FormMetadata<Schema, FormError>['getFieldset']>
|
|
25
25
|
];
|
|
26
|
-
export declare function useFormMetadata<Schema extends Record<string, any>, FormError>(formId: FormId<Schema, FormError>, options?: {
|
|
26
|
+
export declare function useFormMetadata<Schema extends Record<string, any>, FormError = string[]>(formId: FormId<Schema, FormError>, options?: {
|
|
27
27
|
defaultNoValidate?: boolean;
|
|
28
28
|
}): FormMetadata<Schema, FormError>;
|
|
29
|
-
export declare function useField<FieldSchema,
|
|
29
|
+
export declare function useField<FieldSchema, FormSchema extends Record<string, unknown> = Record<string, unknown>, FormError = string[]>(name: FieldName<FieldSchema, FormSchema, FormError>, options?: {
|
|
30
30
|
formId?: FormId<FormSchema, FormError>;
|
|
31
31
|
}): [
|
|
32
|
-
FieldMetadata<FieldSchema,
|
|
32
|
+
FieldMetadata<FieldSchema, FormSchema, FormError>,
|
|
33
33
|
FormMetadata<FormSchema, FormError>
|
|
34
34
|
];
|
package/hooks.js
CHANGED
|
@@ -37,21 +37,21 @@ function useForm(options) {
|
|
|
37
37
|
} = options,
|
|
38
38
|
formConfig = _rollupPluginBabelHelpers.objectWithoutProperties(options, _excluded);
|
|
39
39
|
var formId = useFormId(id);
|
|
40
|
-
var [context$1] = react.useState(() => dom.
|
|
40
|
+
var [context$1] = react.useState(() => dom.unstable_createFormContext(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, formConfig), {}, {
|
|
41
41
|
formId
|
|
42
42
|
})));
|
|
43
43
|
useSafeLayoutEffect(() => {
|
|
44
|
-
document.addEventListener('input', context$1.
|
|
45
|
-
document.addEventListener('focusout', context$1.
|
|
46
|
-
document.addEventListener('reset', context$1.
|
|
44
|
+
document.addEventListener('input', context$1.onInput);
|
|
45
|
+
document.addEventListener('focusout', context$1.onBlur);
|
|
46
|
+
document.addEventListener('reset', context$1.onReset);
|
|
47
47
|
return () => {
|
|
48
|
-
document.removeEventListener('input', context$1.
|
|
49
|
-
document.removeEventListener('focusout', context$1.
|
|
50
|
-
document.removeEventListener('reset', context$1.
|
|
48
|
+
document.removeEventListener('input', context$1.onInput);
|
|
49
|
+
document.removeEventListener('focusout', context$1.onBlur);
|
|
50
|
+
document.removeEventListener('reset', context$1.onReset);
|
|
51
51
|
};
|
|
52
52
|
}, [context$1]);
|
|
53
53
|
useSafeLayoutEffect(() => {
|
|
54
|
-
context$1.
|
|
54
|
+
context$1.onUpdate(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, formConfig), {}, {
|
|
55
55
|
formId
|
|
56
56
|
}));
|
|
57
57
|
});
|
package/hooks.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { objectWithoutProperties as _objectWithoutProperties, objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.mjs';
|
|
2
|
-
import {
|
|
2
|
+
import { unstable_createFormContext } from '@conform-to/dom';
|
|
3
3
|
import { useState, useEffect, useLayoutEffect, useId } from 'react';
|
|
4
4
|
import { useSubjectRef, useFormState, getFormMetadata, useFormContext, getFieldMetadata } from './context.mjs';
|
|
5
5
|
|
|
@@ -33,21 +33,21 @@ function useForm(options) {
|
|
|
33
33
|
} = options,
|
|
34
34
|
formConfig = _objectWithoutProperties(options, _excluded);
|
|
35
35
|
var formId = useFormId(id);
|
|
36
|
-
var [context] = useState(() =>
|
|
36
|
+
var [context] = useState(() => unstable_createFormContext(_objectSpread2(_objectSpread2({}, formConfig), {}, {
|
|
37
37
|
formId
|
|
38
38
|
})));
|
|
39
39
|
useSafeLayoutEffect(() => {
|
|
40
|
-
document.addEventListener('input', context.
|
|
41
|
-
document.addEventListener('focusout', context.
|
|
42
|
-
document.addEventListener('reset', context.
|
|
40
|
+
document.addEventListener('input', context.onInput);
|
|
41
|
+
document.addEventListener('focusout', context.onBlur);
|
|
42
|
+
document.addEventListener('reset', context.onReset);
|
|
43
43
|
return () => {
|
|
44
|
-
document.removeEventListener('input', context.
|
|
45
|
-
document.removeEventListener('focusout', context.
|
|
46
|
-
document.removeEventListener('reset', context.
|
|
44
|
+
document.removeEventListener('input', context.onInput);
|
|
45
|
+
document.removeEventListener('focusout', context.onBlur);
|
|
46
|
+
document.removeEventListener('reset', context.onReset);
|
|
47
47
|
};
|
|
48
48
|
}, [context]);
|
|
49
49
|
useSafeLayoutEffect(() => {
|
|
50
|
-
context.
|
|
50
|
+
context.onUpdate(_objectSpread2(_objectSpread2({}, formConfig), {}, {
|
|
51
51
|
formId
|
|
52
52
|
}));
|
|
53
53
|
});
|
package/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
export { type Submission, type SubmissionResult, type DefaultValue, type
|
|
1
|
+
export { type Submission, type SubmissionResult, type DefaultValue, type Intent, type FormId, type FieldName, parse, } from '@conform-to/dom';
|
|
2
2
|
export { type FieldMetadata, type FormMetadata, FormProvider, FormStateInput, } from './context';
|
|
3
3
|
export { useForm, useFormMetadata, useField } from './hooks';
|
|
4
4
|
export { useInputControl } from './integrations';
|
|
5
|
-
export { validateConstraint } from './validitystate';
|
|
6
5
|
export { getFormProps, getFieldsetProps, getInputProps, getSelectProps, getTextareaProps, getCollectionProps, } from './helpers';
|
package/index.js
CHANGED
|
@@ -6,22 +6,13 @@ var dom = require('@conform-to/dom');
|
|
|
6
6
|
var context = require('./context.js');
|
|
7
7
|
var hooks = require('./hooks.js');
|
|
8
8
|
var integrations = require('./integrations.js');
|
|
9
|
-
var validitystate = require('./validitystate.js');
|
|
10
9
|
var helpers = require('./helpers.js');
|
|
11
10
|
|
|
12
11
|
|
|
13
12
|
|
|
14
|
-
Object.defineProperty(exports, '
|
|
13
|
+
Object.defineProperty(exports, 'parse', {
|
|
15
14
|
enumerable: true,
|
|
16
|
-
get: function () { return dom.
|
|
17
|
-
});
|
|
18
|
-
Object.defineProperty(exports, 'isFieldElement', {
|
|
19
|
-
enumerable: true,
|
|
20
|
-
get: function () { return dom.isFieldElement; }
|
|
21
|
-
});
|
|
22
|
-
Object.defineProperty(exports, 'requestSubmit', {
|
|
23
|
-
enumerable: true,
|
|
24
|
-
get: function () { return dom.requestSubmit; }
|
|
15
|
+
get: function () { return dom.parse; }
|
|
25
16
|
});
|
|
26
17
|
exports.FormProvider = context.FormProvider;
|
|
27
18
|
exports.FormStateInput = context.FormStateInput;
|
|
@@ -29,7 +20,6 @@ exports.useField = hooks.useField;
|
|
|
29
20
|
exports.useForm = hooks.useForm;
|
|
30
21
|
exports.useFormMetadata = hooks.useFormMetadata;
|
|
31
22
|
exports.useInputControl = integrations.useInputControl;
|
|
32
|
-
exports.validateConstraint = validitystate.validateConstraint;
|
|
33
23
|
exports.getCollectionProps = helpers.getCollectionProps;
|
|
34
24
|
exports.getFieldsetProps = helpers.getFieldsetProps;
|
|
35
25
|
exports.getFormProps = helpers.getFormProps;
|
package/index.mjs
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { parse } from '@conform-to/dom';
|
|
2
2
|
export { FormProvider, FormStateInput } from './context.mjs';
|
|
3
3
|
export { useField, useForm, useFormMetadata } from './hooks.mjs';
|
|
4
4
|
export { useInputControl } from './integrations.mjs';
|
|
5
|
-
export { validateConstraint } from './validitystate.mjs';
|
|
6
5
|
export { getCollectionProps, getFieldsetProps, getFormProps, getInputProps, getSelectProps, getTextareaProps } from './helpers.mjs';
|
package/integrations.d.ts
CHANGED
|
@@ -7,9 +7,9 @@ export type InputControl = {
|
|
|
7
7
|
};
|
|
8
8
|
export declare function getFieldElement(formId: string, name: string, match?: (element: FieldElement) => boolean): FieldElement | null;
|
|
9
9
|
export declare function getEventTarget(formId: string, name: string): FieldElement;
|
|
10
|
-
export declare function useInputControl(
|
|
11
|
-
key?: string | undefined;
|
|
10
|
+
export declare function useInputControl(meta: {
|
|
11
|
+
key?: string | null | undefined;
|
|
12
12
|
name: string;
|
|
13
13
|
formId: string;
|
|
14
|
-
initialValue
|
|
14
|
+
initialValue?: string | undefined;
|
|
15
15
|
}): InputControl;
|