@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 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 ControlButtonProps, type FormId, type FieldName, type FormContext, type FormControl, type FormValue, type FormState, type SubscriptionScope, type SubscriptionSubject, type UnionKeyof, type UnionKeyType } from '@conform-to/dom';
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, FormError, FormSchema extends Record<string, unknown>> = {
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, FormError, FormSchema>;
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, FormError, Schema>, 'id'> & {
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>, FormError, Schema>;
25
+ [Key in UnionKeyof<Schema>]: FieldMetadata<UnionKeyType<Schema, Key>, Schema, FormError>;
29
26
  };
30
- onSubmit: (event: React.FormEvent<HTMLFormElement>) => ReturnType<FormContext<Schema>['submit']>;
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, FormError = string[], FormSchema extends Record<string, any> = Record<string, unknown>> = Metadata<Schema, FormError, FormSchema> & {
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
- export declare function useFormContext<Schema extends Record<string, any>, FormError>(formId?: FormId<Schema, FormError>): FormContext<Schema, FormError, unknown>;
44
- export declare function useFormState<FormError>(form: FormContext<any, FormError>, subjectRef?: MutableRefObject<SubscriptionSubject>): FormState<FormError>;
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, FormError, FormSchema>): Metadata<Schema, FormError, FormSchema>;
55
- export declare function getFieldMetadata<Schema, FormError, FormSchema extends Record<string, any>>(formId: FormId<FormSchema, FormError>, state: FormState<FormError>, subjectRef: MutableRefObject<SubscriptionSubject>, prefix?: string, key?: string | number): FieldMetadata<Schema, FormError, FormSchema>;
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, FormError, any>, noValidate: boolean): FormMetadata<Schema, FormError>;
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 value = react.useMemo(() => [props.context].concat(forms),
31
+ var context = getWrappedFormContext(props.context);
32
+ var value = react.useMemo(() => [context].concat(forms),
26
33
  // Put the latest form context first
27
- [forms, props.context]);
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 === 'errors' ? 'error' : key, 'name');
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 context;
164
+ return {
165
+ [wrappedSymbol]: context
166
+ };
173
167
  case 'status':
174
168
  return state.submissionStatus;
175
- case 'dispatch':
176
- case 'getControlButtonProps':
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 (submitEvent.defaultPrevented) {
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 value = useMemo(() => [props.context].concat(forms),
27
+ var context = getWrappedFormContext(props.context);
28
+ var value = useMemo(() => [context].concat(forms),
22
29
  // Put the latest form context first
23
- [forms, props.context]);
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 === 'errors' ? 'error' : key, 'name');
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 context;
160
+ return {
161
+ [wrappedSymbol]: context
162
+ };
169
163
  case 'status':
170
164
  return state.submissionStatus;
171
- case 'dispatch':
172
- case 'getControlButtonProps':
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 (submitEvent.defaultPrevented) {
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 `field.valid` or `field.allValid`.
20
- * @default 'field'
18
+ * Decide whether the aria-invalid attributes should be based on `meta.errors` or `meta.allErrors`.
19
+ * @default 'errors'
21
20
  */
22
- ariaInvalid?: 'all' | 'field';
21
+ ariaInvalid?: 'errors' | 'allErrors';
23
22
  /**
24
- * Assign additional `id` to the `aria-describedby` attribute. If `true`, it will use the `descriptionId` from the metadata.
23
+ * Assign additional `id` to the `aria-describedby` attribute.
25
24
  */
26
- ariaDescribedBy?: boolean | string;
25
+ ariaDescribedBy?: string;
27
26
  } | {
28
27
  ariaAttributes: false;
29
28
  };
30
29
  type InputProps = Pretty<FormControlProps & {
31
- type?: 'checkbox' | 'color' | 'date' | 'datetime-local' | 'email' | 'file' | 'hidden' | 'image' | 'month' | 'number' | 'password' | 'radio' | 'range' | 'search' | 'tel' | 'text' | 'time' | 'url' | 'week';
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?: Exclude<InputProps['type'], 'checkbox' | 'radio'>;
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 Exclude<Primitive, File>>(metadata: FieldMetadata<Schema, any, any>, options?: InputOptions): InputProps;
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 === 'all' ? !metadata.allValid : !metadata.valid;
29
- var ariaDescribedBy = typeof options.ariaDescribedBy === 'string' ? options.ariaDescribedBy : options.ariaDescribedBy ? metadata.descriptionId : undefined;
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 === 'all' ? !metadata.allValid : !metadata.valid;
25
- var ariaDescribedBy = typeof options.ariaDescribedBy === 'string' ? options.ariaDescribedBy : options.ariaDescribedBy ? metadata.descriptionId : undefined;
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>, FormError = string[], FormValue = Schema>(options: Pretty<Omit<FormOptions<Schema, FormError, FormValue>, 'formId'> & {
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, FormError = string[], FormSchema extends Record<string, unknown> = Record<string, unknown>>(name: FieldName<FieldSchema, FormError, FormSchema>, options?: {
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, FormError, FormSchema>,
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.createFormContext(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, formConfig), {}, {
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.input);
45
- document.addEventListener('focusout', context$1.blur);
46
- document.addEventListener('reset', context$1.reset);
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.input);
49
- document.removeEventListener('focusout', context$1.blur);
50
- document.removeEventListener('reset', context$1.reset);
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.update(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, formConfig), {}, {
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 { createFormContext } from '@conform-to/dom';
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(() => createFormContext(_objectSpread2(_objectSpread2({}, formConfig), {}, {
36
+ var [context] = useState(() => unstable_createFormContext(_objectSpread2(_objectSpread2({}, formConfig), {}, {
37
37
  formId
38
38
  })));
39
39
  useSafeLayoutEffect(() => {
40
- document.addEventListener('input', context.input);
41
- document.addEventListener('focusout', context.blur);
42
- document.addEventListener('reset', context.reset);
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.input);
45
- document.removeEventListener('focusout', context.blur);
46
- document.removeEventListener('reset', context.reset);
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.update(_objectSpread2(_objectSpread2({}, formConfig), {}, {
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 FormControl, type FormId, type FieldName, requestSubmit, isFieldElement, control, } from '@conform-to/dom';
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, 'control', {
13
+ Object.defineProperty(exports, 'parse', {
15
14
  enumerable: true,
16
- get: function () { return dom.control; }
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 { control, isFieldElement, requestSubmit } from '@conform-to/dom';
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(options: {
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: string | undefined;
14
+ initialValue?: string | undefined;
15
15
  }): InputControl;