@conform-to/react 1.0.0-pre.4 → 1.0.0-pre.6

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 CHANGED
@@ -430,7 +430,7 @@ import { Form } from 'react-router-dom';
430
430
  export default function SignupForm() {
431
431
  const [form, { email, password, confirmPassword }] = useForm({
432
432
  onValidate(context) {
433
- // This enables validating each field based on the validity state and custom cosntraint if defined
433
+ // This enables validating each field based on the validity state and custom constraint if defined
434
434
  return validateConstraint(
435
435
  ...context,
436
436
  constraint: {
@@ -37,6 +37,33 @@ function _defineProperty(obj, key, value) {
37
37
  }
38
38
  return obj;
39
39
  }
40
+ function _objectWithoutPropertiesLoose(source, excluded) {
41
+ if (source == null) return {};
42
+ var target = {};
43
+ var sourceKeys = Object.keys(source);
44
+ var key, i;
45
+ for (i = 0; i < sourceKeys.length; i++) {
46
+ key = sourceKeys[i];
47
+ if (excluded.indexOf(key) >= 0) continue;
48
+ target[key] = source[key];
49
+ }
50
+ return target;
51
+ }
52
+ function _objectWithoutProperties(source, excluded) {
53
+ if (source == null) return {};
54
+ var target = _objectWithoutPropertiesLoose(source, excluded);
55
+ var key, i;
56
+ if (Object.getOwnPropertySymbols) {
57
+ var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
58
+ for (i = 0; i < sourceSymbolKeys.length; i++) {
59
+ key = sourceSymbolKeys[i];
60
+ if (excluded.indexOf(key) >= 0) continue;
61
+ if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
62
+ target[key] = source[key];
63
+ }
64
+ }
65
+ return target;
66
+ }
40
67
  function _toPrimitive(input, hint) {
41
68
  if (typeof input !== "object" || input === null) return input;
42
69
  var prim = input[Symbol.toPrimitive];
@@ -54,5 +81,7 @@ function _toPropertyKey(arg) {
54
81
 
55
82
  exports.defineProperty = _defineProperty;
56
83
  exports.objectSpread2 = _objectSpread2;
84
+ exports.objectWithoutProperties = _objectWithoutProperties;
85
+ exports.objectWithoutPropertiesLoose = _objectWithoutPropertiesLoose;
57
86
  exports.toPrimitive = _toPrimitive;
58
87
  exports.toPropertyKey = _toPropertyKey;
@@ -33,6 +33,33 @@ function _defineProperty(obj, key, value) {
33
33
  }
34
34
  return obj;
35
35
  }
36
+ function _objectWithoutPropertiesLoose(source, excluded) {
37
+ if (source == null) return {};
38
+ var target = {};
39
+ var sourceKeys = Object.keys(source);
40
+ var key, i;
41
+ for (i = 0; i < sourceKeys.length; i++) {
42
+ key = sourceKeys[i];
43
+ if (excluded.indexOf(key) >= 0) continue;
44
+ target[key] = source[key];
45
+ }
46
+ return target;
47
+ }
48
+ function _objectWithoutProperties(source, excluded) {
49
+ if (source == null) return {};
50
+ var target = _objectWithoutPropertiesLoose(source, excluded);
51
+ var key, i;
52
+ if (Object.getOwnPropertySymbols) {
53
+ var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
54
+ for (i = 0; i < sourceSymbolKeys.length; i++) {
55
+ key = sourceSymbolKeys[i];
56
+ if (excluded.indexOf(key) >= 0) continue;
57
+ if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
58
+ target[key] = source[key];
59
+ }
60
+ }
61
+ return target;
62
+ }
36
63
  function _toPrimitive(input, hint) {
37
64
  if (typeof input !== "object" || input === null) return input;
38
65
  var prim = input[Symbol.toPrimitive];
@@ -48,4 +75,4 @@ function _toPropertyKey(arg) {
48
75
  return typeof key === "symbol" ? key : String(key);
49
76
  }
50
77
 
51
- export { _defineProperty as defineProperty, _objectSpread2 as objectSpread2, _toPrimitive as toPrimitive, _toPropertyKey as toPropertyKey };
78
+ export { _defineProperty as defineProperty, _objectSpread2 as objectSpread2, _objectWithoutProperties as objectWithoutProperties, _objectWithoutPropertiesLoose as objectWithoutPropertiesLoose, _toPrimitive as toPrimitive, _toPropertyKey as toPropertyKey };
package/context.d.ts CHANGED
@@ -1,65 +1,56 @@
1
- import { type Constraint, type FormId, type FieldName, type FormContext, type FormValue, type FormState, type SubscriptionScope, type SubscriptionSubject, type UnionKeyof, type UnionKeyType } from '@conform-to/dom';
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';
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 FieldProps<FieldSchema, Error = unknown, FormSchema extends Record<string, unknown> = Record<string, unknown>> = {
8
- formId: FormId<FormSchema, Error>;
9
- name: FieldName<FieldSchema>;
10
- } | {
11
- formId: FieldSchema extends Record<string, unknown> ? FormId<FieldSchema, Error> : never;
12
- name?: undefined;
13
- };
14
- export type Metadata<Schema, Error> = {
15
- key?: string;
7
+ export type Metadata<Schema, FormError, FormSchema extends Record<string, unknown>> = {
8
+ key: string | undefined;
16
9
  id: string;
17
10
  errorId: string;
18
11
  descriptionId: string;
12
+ name: FieldName<Schema, FormError, FormSchema>;
19
13
  initialValue: FormValue<Schema>;
20
14
  value: FormValue<Schema>;
21
- errors: Error | undefined;
22
- allErrors: Record<string, Error>;
15
+ errors: FormError | undefined;
16
+ allErrors: Record<string, FormError>;
23
17
  allValid: boolean;
24
18
  valid: boolean;
25
19
  dirty: boolean;
26
20
  };
27
- export type FormMetadata<Schema extends Record<string, unknown> = Record<string, unknown>, Error = unknown> = Omit<Metadata<Schema, Error>, 'id'> & {
28
- id: FormId<Schema, Error>;
29
- context: FormContext<Schema, Error>;
21
+ export type FormMetadata<Schema extends Record<string, unknown> = Record<string, unknown>, FormError = string[]> = Omit<Metadata<Schema, FormError, Schema>, 'id'> & {
22
+ id: FormId<Schema, FormError>;
23
+ context: FormContext<Schema, FormError>;
30
24
  status?: 'success' | 'error';
25
+ dispatch(control: FormControl): void;
26
+ getControlButtonProps(control: FormControl): ControlButtonProps;
31
27
  getFieldset: () => {
32
- [Key in UnionKeyof<Schema>]: FieldMetadata<UnionKeyType<Schema, Key>, Error, Schema>;
28
+ [Key in UnionKeyof<Schema>]: FieldMetadata<UnionKeyType<Schema, Key>, FormError, Schema>;
33
29
  };
34
30
  onSubmit: (event: React.FormEvent<HTMLFormElement>) => ReturnType<FormContext<Schema>['submit']>;
35
31
  onReset: (event: React.FormEvent<HTMLFormElement>) => void;
36
32
  noValidate: boolean;
37
33
  };
38
- export type FieldMetadata<Schema = unknown, Error = unknown, FormSchema extends Record<string, any> = Record<string, unknown>> = Metadata<Schema, Error> & {
39
- formId: FormId<FormSchema, Error>;
40
- name: FieldName<Schema>;
34
+ export type FieldMetadata<Schema = unknown, FormError = string[], FormSchema extends Record<string, any> = Record<string, unknown>> = Metadata<Schema, FormError, FormSchema> & {
35
+ formId: FormId<FormSchema, FormError>;
41
36
  constraint?: Constraint;
42
37
  getFieldset: unknown extends Schema ? () => unknown : Schema extends Primitive | Array<any> ? never : () => {
43
- [Key in UnionKeyof<Schema>]: FieldMetadata<UnionKeyType<Schema, Key>, Error>;
38
+ [Key in UnionKeyof<Schema>]: FieldMetadata<UnionKeyType<Schema, Key>, FormError>;
44
39
  };
45
- getFieldList: unknown extends Schema ? () => unknown : Schema extends Array<infer Item> ? () => Array<FieldMetadata<Item, Error>> : never;
40
+ getFieldList: unknown extends Schema ? () => unknown : Schema extends Array<infer Item> ? () => Array<FieldMetadata<Item, FormError>> : never;
46
41
  };
47
- export declare const Registry: import("react").Context<Record<string, FormContext>>;
48
- export declare function useFormContext<Schema extends Record<string, any>, Error, Value = Schema>(formId: FormId<Schema, Error>, context?: FormContext<Schema, Error, Value>): FormContext<Schema, Error, Value>;
49
- export declare function useFormState<Error>(form: FormContext<any, Error>, subjectRef?: MutableRefObject<SubscriptionSubject>): FormState<Error>;
42
+ 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>;
50
45
  export declare function FormProvider(props: {
51
46
  context: FormContext<any, any, any>;
52
47
  children: ReactNode;
53
48
  }): ReactElement;
54
49
  export declare function FormStateInput(props: {
55
- formId: string;
56
- context?: undefined;
57
- } | {
58
- formId?: undefined;
59
- context: FormContext;
50
+ formId?: string;
60
51
  }): React.ReactElement;
61
52
  export declare function useSubjectRef(initialSubject?: SubscriptionSubject): MutableRefObject<SubscriptionSubject>;
62
53
  export declare function updateSubjectRef(ref: MutableRefObject<SubscriptionSubject>, name: string, subject: keyof SubscriptionSubject, scope: keyof SubscriptionScope): void;
63
- export declare function getMetadata<Schema, Error, FormSchema extends Record<string, any>>(formId: FormId<FormSchema, Error>, state: FormState<Error>, subjectRef: MutableRefObject<SubscriptionSubject>, name?: FieldName<Schema>): Metadata<Schema, Error>;
64
- export declare function getFieldMetadata<Schema, Error, FormSchema extends Record<string, any>>(formId: FormId<FormSchema, Error>, state: FormState<Error>, subjectRef: MutableRefObject<SubscriptionSubject>, prefix?: string, key?: string | number): FieldMetadata<Schema, Error, FormSchema>;
65
- export declare function getFormMetadata<Schema extends Record<string, any>, Error>(formId: FormId<Schema, Error>, state: FormState<Error>, subjectRef: MutableRefObject<SubscriptionSubject>, context: FormContext<Schema, Error, any>, noValidate: boolean): FormMetadata<Schema, Error>;
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>;
package/context.js CHANGED
@@ -7,10 +7,10 @@ var dom = require('@conform-to/dom');
7
7
  var react = require('react');
8
8
  var jsxRuntime = require('react/jsx-runtime');
9
9
 
10
- var Registry = /*#__PURE__*/react.createContext({});
11
- function useFormContext(formId, context) {
12
- var registry = react.useContext(Registry);
13
- var form = context !== null && context !== void 0 ? context : registry[formId];
10
+ var Form = /*#__PURE__*/react.createContext([]);
11
+ function useFormContext(formId) {
12
+ var contexts = react.useContext(Form);
13
+ var form = formId ? contexts.find(context => context.formId === formId) : contexts[0];
14
14
  if (!form) {
15
15
  throw new Error('Form context is not available');
16
16
  }
@@ -21,18 +21,17 @@ function useFormState(form, subjectRef) {
21
21
  return react.useSyncExternalStore(subscribe, form.getState, form.getState);
22
22
  }
23
23
  function FormProvider(props) {
24
- var registry = react.useContext(Registry);
25
- var value = react.useMemo(() => _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, registry), {}, {
26
- [props.context.formId]: props.context
27
- }), [registry, props.context]);
28
- return /*#__PURE__*/jsxRuntime.jsx(Registry.Provider, {
24
+ var forms = react.useContext(Form);
25
+ var value = react.useMemo(() => [props.context].concat(forms),
26
+ // Put the latest form context first
27
+ [forms, props.context]);
28
+ return /*#__PURE__*/jsxRuntime.jsx(Form.Provider, {
29
29
  value: value,
30
30
  children: props.children
31
31
  });
32
32
  }
33
33
  function FormStateInput(props) {
34
- var _props$formId;
35
- var context = useFormContext((_props$formId = props.formId) !== null && _props$formId !== void 0 ? _props$formId : props.context.formId, props.context);
34
+ var context = useFormContext(props.formId);
36
35
  return /*#__PURE__*/jsxRuntime.jsx("input", {
37
36
  type: "hidden",
38
37
  name: dom.STATE,
@@ -64,6 +63,7 @@ function getMetadata(formId, state, subjectRef) {
64
63
  var id = name ? "".concat(formId, "-").concat(name) : formId;
65
64
  return new Proxy({
66
65
  id,
66
+ name,
67
67
  errorId: "".concat(id, "-error"),
68
68
  descriptionId: "".concat(id, "-description"),
69
69
  initialValue: state.initialValue[name],
@@ -139,13 +139,11 @@ function getFieldMetadata(formId, state, subjectRef) {
139
139
  var key = arguments.length > 4 ? arguments[4] : undefined;
140
140
  var name = typeof key === 'undefined' ? prefix : dom.formatPaths([...dom.getPaths(prefix), key]);
141
141
  var metadata = getMetadata(formId, state, subjectRef, name);
142
- return new Proxy(metadata, {
143
- get(target, key, receiver) {
142
+ return new Proxy({}, {
143
+ get(_, key, receiver) {
144
144
  switch (key) {
145
145
  case 'formId':
146
146
  return formId;
147
- case 'name':
148
- return name;
149
147
  case 'constraint':
150
148
  return state.constraint[name];
151
149
  case 'getFieldList':
@@ -161,19 +159,22 @@ function getFieldMetadata(formId, state, subjectRef) {
161
159
  };
162
160
  }
163
161
  }
164
- return Reflect.get(target, key, receiver);
162
+ return Reflect.get(metadata, key, receiver);
165
163
  }
166
164
  });
167
165
  }
168
166
  function getFormMetadata(formId, state, subjectRef, context, noValidate) {
169
167
  var metadata = getMetadata(formId, state, subjectRef);
170
- return new Proxy(metadata, {
171
- get(target, key, receiver) {
168
+ return new Proxy({}, {
169
+ get(_, key, receiver) {
172
170
  switch (key) {
173
171
  case 'context':
174
172
  return context;
175
173
  case 'status':
176
174
  return state.submissionStatus;
175
+ case 'dispatch':
176
+ case 'getControlButtonProps':
177
+ return context[key];
177
178
  case 'onSubmit':
178
179
  return event => {
179
180
  var submitEvent = event.nativeEvent;
@@ -185,14 +186,14 @@ function getFormMetadata(formId, state, subjectRef, context, noValidate) {
185
186
  case 'noValidate':
186
187
  return noValidate;
187
188
  }
188
- return Reflect.get(target, key, receiver);
189
+ return Reflect.get(metadata, key, receiver);
189
190
  }
190
191
  });
191
192
  }
192
193
 
194
+ exports.Form = Form;
193
195
  exports.FormProvider = FormProvider;
194
196
  exports.FormStateInput = FormStateInput;
195
- exports.Registry = Registry;
196
197
  exports.getFieldMetadata = getFieldMetadata;
197
198
  exports.getFormMetadata = getFormMetadata;
198
199
  exports.getMetadata = getMetadata;
package/context.mjs CHANGED
@@ -3,10 +3,10 @@ import { STATE, formatPaths, getPaths, isPrefix } from '@conform-to/dom';
3
3
  import { useContext, useMemo, createContext, useCallback, useSyncExternalStore, useRef } from 'react';
4
4
  import { jsx } from 'react/jsx-runtime';
5
5
 
6
- var Registry = /*#__PURE__*/createContext({});
7
- function useFormContext(formId, context) {
8
- var registry = useContext(Registry);
9
- var form = context !== null && context !== void 0 ? context : registry[formId];
6
+ var Form = /*#__PURE__*/createContext([]);
7
+ function useFormContext(formId) {
8
+ var contexts = useContext(Form);
9
+ var form = formId ? contexts.find(context => context.formId === formId) : contexts[0];
10
10
  if (!form) {
11
11
  throw new Error('Form context is not available');
12
12
  }
@@ -17,18 +17,17 @@ function useFormState(form, subjectRef) {
17
17
  return useSyncExternalStore(subscribe, form.getState, form.getState);
18
18
  }
19
19
  function FormProvider(props) {
20
- var registry = useContext(Registry);
21
- var value = useMemo(() => _objectSpread2(_objectSpread2({}, registry), {}, {
22
- [props.context.formId]: props.context
23
- }), [registry, props.context]);
24
- return /*#__PURE__*/jsx(Registry.Provider, {
20
+ var forms = useContext(Form);
21
+ var value = useMemo(() => [props.context].concat(forms),
22
+ // Put the latest form context first
23
+ [forms, props.context]);
24
+ return /*#__PURE__*/jsx(Form.Provider, {
25
25
  value: value,
26
26
  children: props.children
27
27
  });
28
28
  }
29
29
  function FormStateInput(props) {
30
- var _props$formId;
31
- var context = useFormContext((_props$formId = props.formId) !== null && _props$formId !== void 0 ? _props$formId : props.context.formId, props.context);
30
+ var context = useFormContext(props.formId);
32
31
  return /*#__PURE__*/jsx("input", {
33
32
  type: "hidden",
34
33
  name: STATE,
@@ -60,6 +59,7 @@ function getMetadata(formId, state, subjectRef) {
60
59
  var id = name ? "".concat(formId, "-").concat(name) : formId;
61
60
  return new Proxy({
62
61
  id,
62
+ name,
63
63
  errorId: "".concat(id, "-error"),
64
64
  descriptionId: "".concat(id, "-description"),
65
65
  initialValue: state.initialValue[name],
@@ -135,13 +135,11 @@ function getFieldMetadata(formId, state, subjectRef) {
135
135
  var key = arguments.length > 4 ? arguments[4] : undefined;
136
136
  var name = typeof key === 'undefined' ? prefix : formatPaths([...getPaths(prefix), key]);
137
137
  var metadata = getMetadata(formId, state, subjectRef, name);
138
- return new Proxy(metadata, {
139
- get(target, key, receiver) {
138
+ return new Proxy({}, {
139
+ get(_, key, receiver) {
140
140
  switch (key) {
141
141
  case 'formId':
142
142
  return formId;
143
- case 'name':
144
- return name;
145
143
  case 'constraint':
146
144
  return state.constraint[name];
147
145
  case 'getFieldList':
@@ -157,19 +155,22 @@ function getFieldMetadata(formId, state, subjectRef) {
157
155
  };
158
156
  }
159
157
  }
160
- return Reflect.get(target, key, receiver);
158
+ return Reflect.get(metadata, key, receiver);
161
159
  }
162
160
  });
163
161
  }
164
162
  function getFormMetadata(formId, state, subjectRef, context, noValidate) {
165
163
  var metadata = getMetadata(formId, state, subjectRef);
166
- return new Proxy(metadata, {
167
- get(target, key, receiver) {
164
+ return new Proxy({}, {
165
+ get(_, key, receiver) {
168
166
  switch (key) {
169
167
  case 'context':
170
168
  return context;
171
169
  case 'status':
172
170
  return state.submissionStatus;
171
+ case 'dispatch':
172
+ case 'getControlButtonProps':
173
+ return context[key];
173
174
  case 'onSubmit':
174
175
  return event => {
175
176
  var submitEvent = event.nativeEvent;
@@ -181,9 +182,9 @@ function getFormMetadata(formId, state, subjectRef, context, noValidate) {
181
182
  case 'noValidate':
182
183
  return noValidate;
183
184
  }
184
- return Reflect.get(target, key, receiver);
185
+ return Reflect.get(metadata, key, receiver);
185
186
  }
186
187
  });
187
188
  }
188
189
 
189
- export { FormProvider, FormStateInput, Registry, getFieldMetadata, getFormMetadata, getMetadata, updateSubjectRef, useFormContext, useFormState, useSubjectRef };
190
+ export { Form, FormProvider, FormStateInput, getFieldMetadata, getFormMetadata, getMetadata, updateSubjectRef, useFormContext, useFormState, useSubjectRef };
package/helpers.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  /// <reference types="react" />
2
- import { type Intent } from '@conform-to/dom';
3
2
  import type { FormMetadata, FieldMetadata, Metadata, Pretty, Primitive } from './context';
4
3
  type FormControlProps = {
5
4
  key: string | undefined;
@@ -79,7 +78,7 @@ type TextareaOptions = Pretty<FormControlOptions & {
79
78
  /**
80
79
  * Derives aria attributes of a form control based on the field metadata.
81
80
  */
82
- export declare function getAriaAttributes<Schema, Error>(metadata: Metadata<Schema, Error>, options?: FormControlOptions): {
81
+ export declare function getAriaAttributes(metadata: Metadata<any, any, any>, options?: FormControlOptions): {
83
82
  'aria-invalid'?: boolean;
84
83
  'aria-describedby'?: string;
85
84
  };
@@ -92,10 +91,10 @@ export declare function getAriaAttributes<Schema, Error>(metadata: Metadata<Sche
92
91
  * <form {...getFormProps(metadata)} />
93
92
  * ```
94
93
  */
95
- export declare function getFormProps<Schema extends Record<string, any>, Error>(metadata: FormMetadata<Schema, Error>, options?: FormControlOptions): {
94
+ export declare function getFormProps<Schema extends Record<string, any>, FormError>(metadata: FormMetadata<Schema, FormError>, options?: FormControlOptions): {
96
95
  'aria-invalid'?: boolean | undefined;
97
96
  'aria-describedby'?: string | undefined;
98
- id: import("@conform-to/dom").FormId<Schema, Error>;
97
+ id: import("@conform-to/dom").FormId<Schema, FormError>;
99
98
  onSubmit: (event: import("react").FormEvent<HTMLFormElement>) => void;
100
99
  noValidate: boolean;
101
100
  };
@@ -108,18 +107,18 @@ export declare function getFormProps<Schema extends Record<string, any>, Error>(
108
107
  * <fieldset {...getFieldsetProps(metadata)} />
109
108
  * ```
110
109
  */
111
- export declare function getFieldsetProps<Schema extends Record<string, any> | undefined | unknown, Error>(metadata: FieldMetadata<Schema, Error, any>, options?: FormControlOptions): {
110
+ export declare function getFieldsetProps<Schema extends Record<string, any> | undefined | unknown>(metadata: FieldMetadata<Schema, any, any>, options?: FormControlOptions): {
112
111
  'aria-invalid'?: boolean | undefined;
113
112
  'aria-describedby'?: string | undefined;
114
113
  id: string;
115
- name: import("@conform-to/dom").FieldName<Schema>;
116
- form: import("@conform-to/dom").FormId<any, Error>;
114
+ name: import("@conform-to/dom").FieldName<Schema, any, any>;
115
+ form: import("@conform-to/dom").FormId<any, any>;
117
116
  };
118
117
  /**
119
118
  * Derives common properties of a form control based on the field metadata,
120
119
  * including `key`, `id`, `name`, `form`, `required`, `autoFocus`, `aria-invalid` and `aria-describedby`.
121
120
  */
122
- export declare function getFormControlProps<Schema, Error>(metadata: FieldMetadata<Schema, Error, any>, options?: FormControlOptions): FormControlProps;
121
+ export declare function getFormControlProps<Schema>(metadata: FieldMetadata<Schema, any, any>, options?: FormControlOptions): FormControlProps;
123
122
  /**
124
123
  * Derives the properties of an input element based on the field metadata,
125
124
  * including common form control attributes like `key`, `id`, `name`, `form`, `autoFocus`, `aria-invalid`, `aria-describedby`
@@ -210,10 +209,4 @@ export declare function getCollectionProps<Schema extends Array<string | boolean
210
209
  */
211
210
  value?: boolean;
212
211
  }>): Array<InputProps & Pick<Required<InputProps>, 'type' | 'value'>>;
213
- export declare function getControlButtonProps(formId: string, intent: Intent): {
214
- name: string;
215
- value: string;
216
- form: string;
217
- formNoValidate: boolean;
218
- };
219
212
  export {};
package/helpers.js CHANGED
@@ -3,7 +3,6 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var _rollupPluginBabelHelpers = require('./_virtual/_rollupPluginBabelHelpers.js');
6
- var dom = require('@conform-to/dom');
7
6
 
8
7
  /**
9
8
  * Cleanup `undefined` from the result.
@@ -217,18 +216,9 @@ function getCollectionProps(metadata, options) {
217
216
  }));
218
217
  });
219
218
  }
220
- function getControlButtonProps(formId, intent) {
221
- return {
222
- name: dom.INTENT,
223
- value: dom.serializeIntent(intent),
224
- form: formId,
225
- formNoValidate: true
226
- };
227
- }
228
219
 
229
220
  exports.getAriaAttributes = getAriaAttributes;
230
221
  exports.getCollectionProps = getCollectionProps;
231
- exports.getControlButtonProps = getControlButtonProps;
232
222
  exports.getFieldsetProps = getFieldsetProps;
233
223
  exports.getFormControlProps = getFormControlProps;
234
224
  exports.getFormProps = getFormProps;
package/helpers.mjs CHANGED
@@ -1,5 +1,4 @@
1
1
  import { objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.mjs';
2
- import { INTENT, serializeIntent } from '@conform-to/dom';
3
2
 
4
3
  /**
5
4
  * Cleanup `undefined` from the result.
@@ -213,13 +212,5 @@ function getCollectionProps(metadata, options) {
213
212
  }));
214
213
  });
215
214
  }
216
- function getControlButtonProps(formId, intent) {
217
- return {
218
- name: INTENT,
219
- value: serializeIntent(intent),
220
- form: formId,
221
- formNoValidate: true
222
- };
223
- }
224
215
 
225
- export { getAriaAttributes, getCollectionProps, getControlButtonProps, getFieldsetProps, getFormControlProps, getFormProps, getInputProps, getSelectProps, getTextareaProps };
216
+ export { getAriaAttributes, getCollectionProps, getFieldsetProps, getFormControlProps, getFormProps, getInputProps, getSelectProps, getTextareaProps };
package/hooks.d.ts CHANGED
@@ -6,12 +6,11 @@ import { type FormMetadata, type FieldMetadata, type Pretty } from './context';
6
6
  * This basically makes it a no-op on server
7
7
  */
8
8
  export declare const useSafeLayoutEffect: typeof useEffect;
9
- export declare function useFormId<Schema extends Record<string, unknown>, Error>(preferredId?: string): FormId<Schema, Error>;
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>, Error = string[], Value = Schema>(options: Pretty<FormOptions<Schema, Error, Value> & {
11
+ export declare function useForm<Schema extends Record<string, any>, FormError = string[], FormValue = Schema>(options: Pretty<Omit<FormOptions<Schema, FormError, FormValue>, 'formId'> & {
12
12
  /**
13
- * If the form id is provided, Id for label,
14
- * input and error elements will be derived.
13
+ * The form id. If not provided, a random id will be generated.
15
14
  */
16
15
  id?: string;
17
16
  /**
@@ -20,23 +19,16 @@ export declare function useForm<Schema extends Record<string, any>, Error = stri
20
19
  * Default to `true`.
21
20
  */
22
21
  defaultNoValidate?: boolean;
23
- }>): {
24
- meta: FormMetadata<Schema, Error>;
25
- fields: ReturnType<FormMetadata<Schema, Error>['getFieldset']>;
26
- };
27
- export declare function useFormMetadata<Schema extends Record<string, any>, Error>(options: {
28
- formId: FormId<Schema, Error>;
22
+ }>): [
23
+ FormMetadata<Schema, FormError>,
24
+ ReturnType<FormMetadata<Schema, FormError>['getFieldset']>
25
+ ];
26
+ export declare function useFormMetadata<Schema extends Record<string, any>, FormError>(formId: FormId<Schema, FormError>, options?: {
29
27
  defaultNoValidate?: boolean;
30
- }): FormMetadata<Schema, Error>;
31
- export declare function useField<FormSchema extends Record<string, unknown>, FieldSchema = FormSchema, Error = unknown>(options: {
32
- formId: FormId<FormSchema, Error>;
33
- name: FieldName<FieldSchema>;
34
- } | {
35
- formId: FormId<FormSchema, Error>;
36
- name?: undefined;
37
- }): {
38
- meta: FieldMetadata<FieldSchema, Error, FormSchema>;
39
- fields: FieldMetadata<FieldSchema, Error, FormSchema>['getFieldset'] extends Function ? ReturnType<FieldMetadata<FieldSchema, Error, FormSchema>['getFieldset']> : never;
40
- list: FieldMetadata<FieldSchema, Error, FormSchema>['getFieldList'] extends Function ? ReturnType<FieldMetadata<FieldSchema, Error, FormSchema>['getFieldList']> : never;
41
- form: FormMetadata<FormSchema, Error>;
42
- };
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?: {
30
+ formId?: FormId<FormSchema, FormError>;
31
+ }): [
32
+ FieldMetadata<FieldSchema, FormError, FormSchema>,
33
+ FormMetadata<FormSchema, FormError>
34
+ ];
package/hooks.js CHANGED
@@ -2,10 +2,13 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
+ var _rollupPluginBabelHelpers = require('./_virtual/_rollupPluginBabelHelpers.js');
5
6
  var dom = require('@conform-to/dom');
6
7
  var react = require('react');
7
8
  var context = require('./context.js');
8
9
 
10
+ var _excluded = ["id"];
11
+
9
12
  /**
10
13
  * useLayoutEffect is client-only.
11
14
  * This basically makes it a no-op on server
@@ -29,15 +32,14 @@ function useNoValidate() {
29
32
  return noValidate;
30
33
  }
31
34
  function useForm(options) {
32
- var formId = useFormId(options.id);
33
- var initializeContext = () => dom.createFormContext(formId, options);
34
- var [context$1, setFormContext] = react.useState(initializeContext);
35
-
36
- // If id changes, reinitialize the form immediately
37
- if (formId !== context$1.formId) {
38
- setFormContext(initializeContext);
39
- }
40
- var optionsRef = react.useRef(options);
35
+ var {
36
+ id
37
+ } = options,
38
+ formConfig = _rollupPluginBabelHelpers.objectWithoutProperties(options, _excluded);
39
+ var formId = useFormId(id);
40
+ var [context$1] = react.useState(() => dom.createFormContext(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, formConfig), {}, {
41
+ formId
42
+ })));
41
43
  useSafeLayoutEffect(() => {
42
44
  document.addEventListener('input', context$1.input);
43
45
  document.addEventListener('focusout', context$1.blur);
@@ -49,55 +51,32 @@ function useForm(options) {
49
51
  };
50
52
  }, [context$1]);
51
53
  useSafeLayoutEffect(() => {
52
- if (options.lastResult === optionsRef.current.lastResult) {
53
- // If there is no change, do nothing
54
- return;
55
- }
56
- if (options.lastResult) {
57
- context$1.report(options.lastResult);
58
- } else {
59
- var _document$forms$named;
60
- (_document$forms$named = document.forms.namedItem(context$1.formId)) === null || _document$forms$named === void 0 || _document$forms$named.reset();
61
- }
62
- }, [context$1, options.lastResult]);
63
- useSafeLayoutEffect(() => {
64
- optionsRef.current = options;
65
- context$1.update(options);
54
+ context$1.update(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, formConfig), {}, {
55
+ formId
56
+ }));
66
57
  });
67
58
  var subjectRef = context.useSubjectRef();
68
59
  var state = context.useFormState(context$1, subjectRef);
69
60
  var noValidate = useNoValidate(options.defaultNoValidate);
70
- var meta = context.getFormMetadata(formId, state, subjectRef, context$1, noValidate);
71
- return {
72
- meta,
73
- fields: meta.getFieldset()
74
- };
61
+ var form = context.getFormMetadata(formId, state, subjectRef, context$1, noValidate);
62
+ return [form, form.getFieldset()];
75
63
  }
76
- function useFormMetadata(options) {
64
+ function useFormMetadata(formId) {
65
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
77
66
  var subjectRef = context.useSubjectRef();
78
- var context$1 = context.useFormContext(options.formId);
67
+ var context$1 = context.useFormContext(formId);
79
68
  var state = context.useFormState(context$1, subjectRef);
80
69
  var noValidate = useNoValidate(options.defaultNoValidate);
81
- return context.getFormMetadata(options.formId, state, subjectRef, context$1, noValidate);
70
+ return context.getFormMetadata(context$1.formId, state, subjectRef, context$1, noValidate);
82
71
  }
83
- function useField(options) {
72
+ function useField(name) {
73
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
84
74
  var subjectRef = context.useSubjectRef();
85
75
  var context$1 = context.useFormContext(options.formId);
86
76
  var state = context.useFormState(context$1, subjectRef);
87
- var meta = context.getFieldMetadata(options.formId, state, subjectRef, options.name);
88
- var form = context.getFormMetadata(options.formId, state, subjectRef, context$1, false);
89
- return {
90
- meta,
91
- // @ts-expect-error The types is used as a hint only
92
- get fields() {
93
- return meta.getFieldset();
94
- },
95
- // @ts-expect-error The types is used as a hint only
96
- get list() {
97
- return meta.getFieldList();
98
- },
99
- form
100
- };
77
+ var field = context.getFieldMetadata(context$1.formId, state, subjectRef, name);
78
+ var form = context.getFormMetadata(context$1.formId, state, subjectRef, context$1, false);
79
+ return [field, form];
101
80
  }
102
81
 
103
82
  exports.useField = useField;
package/hooks.mjs CHANGED
@@ -1,7 +1,10 @@
1
+ import { objectWithoutProperties as _objectWithoutProperties, objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.mjs';
1
2
  import { createFormContext } from '@conform-to/dom';
2
- import { useState, useRef, useEffect, useLayoutEffect, useId } from 'react';
3
+ import { useState, useEffect, useLayoutEffect, useId } from 'react';
3
4
  import { useSubjectRef, useFormState, getFormMetadata, useFormContext, getFieldMetadata } from './context.mjs';
4
5
 
6
+ var _excluded = ["id"];
7
+
5
8
  /**
6
9
  * useLayoutEffect is client-only.
7
10
  * This basically makes it a no-op on server
@@ -25,15 +28,14 @@ function useNoValidate() {
25
28
  return noValidate;
26
29
  }
27
30
  function useForm(options) {
28
- var formId = useFormId(options.id);
29
- var initializeContext = () => createFormContext(formId, options);
30
- var [context, setFormContext] = useState(initializeContext);
31
-
32
- // If id changes, reinitialize the form immediately
33
- if (formId !== context.formId) {
34
- setFormContext(initializeContext);
35
- }
36
- var optionsRef = useRef(options);
31
+ var {
32
+ id
33
+ } = options,
34
+ formConfig = _objectWithoutProperties(options, _excluded);
35
+ var formId = useFormId(id);
36
+ var [context] = useState(() => createFormContext(_objectSpread2(_objectSpread2({}, formConfig), {}, {
37
+ formId
38
+ })));
37
39
  useSafeLayoutEffect(() => {
38
40
  document.addEventListener('input', context.input);
39
41
  document.addEventListener('focusout', context.blur);
@@ -45,55 +47,32 @@ function useForm(options) {
45
47
  };
46
48
  }, [context]);
47
49
  useSafeLayoutEffect(() => {
48
- if (options.lastResult === optionsRef.current.lastResult) {
49
- // If there is no change, do nothing
50
- return;
51
- }
52
- if (options.lastResult) {
53
- context.report(options.lastResult);
54
- } else {
55
- var _document$forms$named;
56
- (_document$forms$named = document.forms.namedItem(context.formId)) === null || _document$forms$named === void 0 || _document$forms$named.reset();
57
- }
58
- }, [context, options.lastResult]);
59
- useSafeLayoutEffect(() => {
60
- optionsRef.current = options;
61
- context.update(options);
50
+ context.update(_objectSpread2(_objectSpread2({}, formConfig), {}, {
51
+ formId
52
+ }));
62
53
  });
63
54
  var subjectRef = useSubjectRef();
64
55
  var state = useFormState(context, subjectRef);
65
56
  var noValidate = useNoValidate(options.defaultNoValidate);
66
- var meta = getFormMetadata(formId, state, subjectRef, context, noValidate);
67
- return {
68
- meta,
69
- fields: meta.getFieldset()
70
- };
57
+ var form = getFormMetadata(formId, state, subjectRef, context, noValidate);
58
+ return [form, form.getFieldset()];
71
59
  }
72
- function useFormMetadata(options) {
60
+ function useFormMetadata(formId) {
61
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
73
62
  var subjectRef = useSubjectRef();
74
- var context = useFormContext(options.formId);
63
+ var context = useFormContext(formId);
75
64
  var state = useFormState(context, subjectRef);
76
65
  var noValidate = useNoValidate(options.defaultNoValidate);
77
- return getFormMetadata(options.formId, state, subjectRef, context, noValidate);
66
+ return getFormMetadata(context.formId, state, subjectRef, context, noValidate);
78
67
  }
79
- function useField(options) {
68
+ function useField(name) {
69
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
80
70
  var subjectRef = useSubjectRef();
81
71
  var context = useFormContext(options.formId);
82
72
  var state = useFormState(context, subjectRef);
83
- var meta = getFieldMetadata(options.formId, state, subjectRef, options.name);
84
- var form = getFormMetadata(options.formId, state, subjectRef, context, false);
85
- return {
86
- meta,
87
- // @ts-expect-error The types is used as a hint only
88
- get fields() {
89
- return meta.getFieldset();
90
- },
91
- // @ts-expect-error The types is used as a hint only
92
- get list() {
93
- return meta.getFieldList();
94
- },
95
- form
96
- };
73
+ var field = getFieldMetadata(context.formId, state, subjectRef, name);
74
+ var form = getFormMetadata(context.formId, state, subjectRef, context, false);
75
+ return [field, form];
97
76
  }
98
77
 
99
78
  export { useField, useForm, useFormId, useFormMetadata, useNoValidate, useSafeLayoutEffect };
package/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- export { type Submission, type SubmissionResult, type Intent, type FormId, type FieldName, requestIntent, requestSubmit, isFieldElement, intent, } from '@conform-to/dom';
2
- export { type FieldProps, type FieldMetadata, type FormMetadata, FormProvider, FormStateInput, } from './context';
1
+ export { type Submission, type SubmissionResult, type DefaultValue, type FormControl, type FormId, type FieldName, requestSubmit, isFieldElement, control, } from '@conform-to/dom';
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
5
  export { validateConstraint } from './validitystate';
6
- export { getFormProps, getFieldsetProps, getInputProps, getSelectProps, getTextareaProps, getCollectionProps, getControlButtonProps, } from './helpers';
6
+ export { getFormProps, getFieldsetProps, getInputProps, getSelectProps, getTextareaProps, getCollectionProps, } from './helpers';
package/index.js CHANGED
@@ -11,18 +11,14 @@ var helpers = require('./helpers.js');
11
11
 
12
12
 
13
13
 
14
- Object.defineProperty(exports, 'intent', {
14
+ Object.defineProperty(exports, 'control', {
15
15
  enumerable: true,
16
- get: function () { return dom.intent; }
16
+ get: function () { return dom.control; }
17
17
  });
18
18
  Object.defineProperty(exports, 'isFieldElement', {
19
19
  enumerable: true,
20
20
  get: function () { return dom.isFieldElement; }
21
21
  });
22
- Object.defineProperty(exports, 'requestIntent', {
23
- enumerable: true,
24
- get: function () { return dom.requestIntent; }
25
- });
26
22
  Object.defineProperty(exports, 'requestSubmit', {
27
23
  enumerable: true,
28
24
  get: function () { return dom.requestSubmit; }
@@ -35,7 +31,6 @@ exports.useFormMetadata = hooks.useFormMetadata;
35
31
  exports.useInputControl = integrations.useInputControl;
36
32
  exports.validateConstraint = validitystate.validateConstraint;
37
33
  exports.getCollectionProps = helpers.getCollectionProps;
38
- exports.getControlButtonProps = helpers.getControlButtonProps;
39
34
  exports.getFieldsetProps = helpers.getFieldsetProps;
40
35
  exports.getFormProps = helpers.getFormProps;
41
36
  exports.getInputProps = helpers.getInputProps;
package/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
- export { intent, isFieldElement, requestIntent, requestSubmit } from '@conform-to/dom';
1
+ export { control, isFieldElement, requestSubmit } 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
5
  export { validateConstraint } from './validitystate.mjs';
6
- export { getCollectionProps, getControlButtonProps, getFieldsetProps, getFormProps, getInputProps, getSelectProps, getTextareaProps } from './helpers.mjs';
6
+ export { getCollectionProps, getFieldsetProps, getFormProps, getInputProps, getSelectProps, getTextareaProps } from './helpers.mjs';
package/integrations.d.ts CHANGED
@@ -1,34 +1,15 @@
1
- import { type FieldElement, type FormValue, FieldName, FormId } from '@conform-to/dom';
2
- import { type FieldMetadata } from './context';
3
- export type InputControl<Value> = {
4
- value: Value;
5
- change: (value: Value) => void;
1
+ import { type FieldElement } from '@conform-to/dom';
2
+ export type InputControl = {
3
+ value: string | undefined;
4
+ change: (value: string) => void;
6
5
  focus: () => void;
7
6
  blur: () => void;
8
7
  };
9
8
  export declare function getFieldElement(formId: string, name: string, match?: (element: FieldElement) => boolean): FieldElement | null;
10
9
  export declare function getEventTarget(formId: string, name: string): FieldElement;
11
- export declare function useInputControl<Schema>(metadata: FieldMetadata<Schema, any, any>, options?: {
12
- onFocus?: (event: Event) => void;
13
- }): InputControl<string | undefined>;
14
- export declare function useInputControl<Schema>(options: {
15
- key?: string;
16
- name: FieldName<Schema>;
17
- formId: FormId<any, any>;
18
- initialValue: FormValue<Schema>;
19
- onFocus?: (event: Event) => void;
20
- }): InputControl<string | undefined>;
21
- export declare function useInputControl<Schema, Value>(metadata: FieldMetadata<Schema, any, any>, options: {
22
- initialize: (value: FormValue<Schema> | undefined) => Value;
23
- serialize?: (value: Value) => string;
24
- onFocus?: (event: Event) => void;
25
- }): InputControl<Value>;
26
- export declare function useInputControl<Schema, Value>(options: {
27
- key?: string;
28
- name: FieldName<Schema>;
29
- formId: FormId<any, any>;
30
- initialValue: FormValue<Schema>;
31
- initialize: (value: FormValue<Schema> | undefined) => Value;
32
- serialize?: (value: Value) => string;
33
- onFocus?: (event: Event) => void;
34
- }): InputControl<Value>;
10
+ export declare function useInputControl(options: {
11
+ key?: string | undefined;
12
+ name: string;
13
+ formId: string;
14
+ initialValue: string | undefined;
15
+ }): InputControl;
package/integrations.js CHANGED
@@ -32,43 +32,23 @@ function getEventTarget(formId, name) {
32
32
  form === null || form === void 0 || form.appendChild(input);
33
33
  return input;
34
34
  }
35
- function useInputControl(metadata, options) {
36
- var _options$initialize, _options$serialize, _options$onFocus;
35
+ function useInputControl(options) {
37
36
  var eventDispatched = react.useRef({
38
37
  change: false,
39
38
  focus: false,
40
39
  blur: false
41
40
  });
42
- var [key, setKey] = react.useState(metadata.key);
43
- var initialize = (_options$initialize = options === null || options === void 0 ? void 0 : options.initialize) !== null && _options$initialize !== void 0 ? _options$initialize : 'initialize' in metadata && metadata.initialize ? metadata.initialize : value => value === null || value === void 0 ? void 0 : value.toString();
44
- var serialize = (_options$serialize = options === null || options === void 0 ? void 0 : options.serialize) !== null && _options$serialize !== void 0 ? _options$serialize : 'serialize' in metadata && metadata.serialize ? metadata.serialize : undefined;
45
- var onFocus = (_options$onFocus = options === null || options === void 0 ? void 0 : options.onFocus) !== null && _options$onFocus !== void 0 ? _options$onFocus : 'onFocus' in metadata ? metadata.onFocus : undefined;
46
- var optionsRef = react.useRef({
47
- initialize,
48
- serialize,
49
- onFocus
50
- });
51
- var [value, setValue] = react.useState(() => initialize(metadata.initialValue));
52
- if (key !== metadata.key) {
53
- setValue(initialize(metadata.initialValue));
54
- setKey(metadata.key);
41
+ var [key, setKey] = react.useState(options.key);
42
+ var [value, setValue] = react.useState(() => options.initialValue);
43
+ if (key !== options.key) {
44
+ setValue(options.initialValue);
45
+ setKey(options.key);
55
46
  }
56
- react.useEffect(() => {
57
- optionsRef.current = {
58
- initialize,
59
- serialize,
60
- onFocus
61
- };
62
- });
63
47
  react.useEffect(() => {
64
48
  var createEventListener = listener => {
65
49
  return event => {
66
- var element = getFieldElement(metadata.formId, metadata.name, element => element === event.target);
50
+ var element = getFieldElement(options.formId, options.name, element => element === event.target);
67
51
  if (element) {
68
- if (listener === 'focus') {
69
- var _optionsRef$current, _optionsRef$current$o;
70
- (_optionsRef$current = optionsRef.current) === null || _optionsRef$current === void 0 || (_optionsRef$current$o = _optionsRef$current.onFocus) === null || _optionsRef$current$o === void 0 || _optionsRef$current$o.call(_optionsRef$current, event);
71
- }
72
52
  eventDispatched.current[listener] = true;
73
53
  }
74
54
  };
@@ -84,62 +64,57 @@ function useInputControl(metadata, options) {
84
64
  document.removeEventListener('focusin', focusHandler, true);
85
65
  document.removeEventListener('focusout', blurHandler, true);
86
66
  };
87
- }, [metadata.formId, metadata.name]);
67
+ }, [options.formId, options.name]);
88
68
  var handlers = react.useMemo(() => {
89
69
  return {
90
70
  change(value) {
91
71
  if (!eventDispatched.current.change) {
92
- var _ref, _optionsRef$current$s, _optionsRef$current$s2, _optionsRef$current2;
93
- var _element = getEventTarget(metadata.formId, metadata.name);
94
- var serializedValue = (_ref = (_optionsRef$current$s = (_optionsRef$current$s2 = (_optionsRef$current2 = optionsRef.current).serialize) === null || _optionsRef$current$s2 === void 0 ? void 0 : _optionsRef$current$s2.call(_optionsRef$current2, value)) !== null && _optionsRef$current$s !== void 0 ? _optionsRef$current$s : value === null || value === void 0 ? void 0 : value.toString()) !== null && _ref !== void 0 ? _ref : '';
72
+ var _element = getEventTarget(options.formId, options.name);
95
73
  eventDispatched.current.change = true;
96
74
  if (_element instanceof HTMLInputElement && (_element.type === 'checkbox' || _element.type === 'radio')) {
97
- if (_element.checked ? _element.value !== serializedValue : _element.value === serializedValue) {
98
- _element.click();
99
- }
100
- } else {
75
+ _element.checked = _element.value === value;
76
+ } else if (_element.value !== value) {
101
77
  // No change event will be triggered on React if `element.value` is already updated
102
- if (_element.value !== serializedValue) {
103
- /**
104
- * Triggering react custom change event
105
- * Solution based on dom-testing-library
106
- * @see https://github.com/facebook/react/issues/10135#issuecomment-401496776
107
- * @see https://github.com/testing-library/dom-testing-library/blob/main/src/events.js#L104-L123
108
- */
109
- var {
110
- set: valueSetter
111
- } = Object.getOwnPropertyDescriptor(_element, 'value') || {};
112
- var prototype = Object.getPrototypeOf(_element);
113
- var {
114
- set: prototypeValueSetter
115
- } = Object.getOwnPropertyDescriptor(prototype, 'value') || {};
116
- if (prototypeValueSetter && valueSetter !== prototypeValueSetter) {
117
- prototypeValueSetter.call(_element, value);
78
+
79
+ /**
80
+ * Triggering react custom change event
81
+ * Solution based on dom-testing-library
82
+ * @see https://github.com/facebook/react/issues/10135#issuecomment-401496776
83
+ * @see https://github.com/testing-library/dom-testing-library/blob/main/src/events.js#L104-L123
84
+ */
85
+ var {
86
+ set: valueSetter
87
+ } = Object.getOwnPropertyDescriptor(_element, 'value') || {};
88
+ var prototype = Object.getPrototypeOf(_element);
89
+ var {
90
+ set: prototypeValueSetter
91
+ } = Object.getOwnPropertyDescriptor(prototype, 'value') || {};
92
+ if (prototypeValueSetter && valueSetter !== prototypeValueSetter) {
93
+ prototypeValueSetter.call(_element, value);
94
+ } else {
95
+ if (valueSetter) {
96
+ valueSetter.call(_element, value);
118
97
  } else {
119
- if (valueSetter) {
120
- valueSetter.call(_element, value);
121
- } else {
122
- throw new Error('The given element does not have a value setter');
123
- }
98
+ throw new Error('The given element does not have a value setter');
124
99
  }
125
100
  }
126
-
127
- // Dispatch input event with the updated input value
128
- _element.dispatchEvent(new InputEvent('input', {
129
- bubbles: true
130
- }));
131
- // Dispatch change event (necessary for select to update the selected option)
132
- _element.dispatchEvent(new Event('change', {
133
- bubbles: true
134
- }));
135
101
  }
102
+
103
+ // Dispatch input event with the updated input value
104
+ _element.dispatchEvent(new InputEvent('input', {
105
+ bubbles: true
106
+ }));
107
+ // Dispatch change event (necessary for select to update the selected option)
108
+ _element.dispatchEvent(new Event('change', {
109
+ bubbles: true
110
+ }));
136
111
  }
137
112
  setValue(value);
138
113
  eventDispatched.current.change = false;
139
114
  },
140
115
  focus() {
141
116
  if (!eventDispatched.current.focus) {
142
- var _element2 = getEventTarget(metadata.formId, metadata.name);
117
+ var _element2 = getEventTarget(options.formId, options.name);
143
118
  eventDispatched.current.focus = true;
144
119
  _element2.dispatchEvent(new FocusEvent('focusin', {
145
120
  bubbles: true
@@ -150,7 +125,7 @@ function useInputControl(metadata, options) {
150
125
  },
151
126
  blur() {
152
127
  if (!eventDispatched.current.blur) {
153
- var _element3 = getEventTarget(metadata.formId, metadata.name);
128
+ var _element3 = getEventTarget(options.formId, options.name);
154
129
  eventDispatched.current.blur = true;
155
130
  _element3.dispatchEvent(new FocusEvent('focusout', {
156
131
  bubbles: true
@@ -160,7 +135,7 @@ function useInputControl(metadata, options) {
160
135
  eventDispatched.current.blur = false;
161
136
  }
162
137
  };
163
- }, [metadata.formId, metadata.name]);
138
+ }, [options.formId, options.name]);
164
139
  return _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, handlers), {}, {
165
140
  value
166
141
  });
package/integrations.mjs CHANGED
@@ -28,43 +28,23 @@ function getEventTarget(formId, name) {
28
28
  form === null || form === void 0 || form.appendChild(input);
29
29
  return input;
30
30
  }
31
- function useInputControl(metadata, options) {
32
- var _options$initialize, _options$serialize, _options$onFocus;
31
+ function useInputControl(options) {
33
32
  var eventDispatched = useRef({
34
33
  change: false,
35
34
  focus: false,
36
35
  blur: false
37
36
  });
38
- var [key, setKey] = useState(metadata.key);
39
- var initialize = (_options$initialize = options === null || options === void 0 ? void 0 : options.initialize) !== null && _options$initialize !== void 0 ? _options$initialize : 'initialize' in metadata && metadata.initialize ? metadata.initialize : value => value === null || value === void 0 ? void 0 : value.toString();
40
- var serialize = (_options$serialize = options === null || options === void 0 ? void 0 : options.serialize) !== null && _options$serialize !== void 0 ? _options$serialize : 'serialize' in metadata && metadata.serialize ? metadata.serialize : undefined;
41
- var onFocus = (_options$onFocus = options === null || options === void 0 ? void 0 : options.onFocus) !== null && _options$onFocus !== void 0 ? _options$onFocus : 'onFocus' in metadata ? metadata.onFocus : undefined;
42
- var optionsRef = useRef({
43
- initialize,
44
- serialize,
45
- onFocus
46
- });
47
- var [value, setValue] = useState(() => initialize(metadata.initialValue));
48
- if (key !== metadata.key) {
49
- setValue(initialize(metadata.initialValue));
50
- setKey(metadata.key);
37
+ var [key, setKey] = useState(options.key);
38
+ var [value, setValue] = useState(() => options.initialValue);
39
+ if (key !== options.key) {
40
+ setValue(options.initialValue);
41
+ setKey(options.key);
51
42
  }
52
- useEffect(() => {
53
- optionsRef.current = {
54
- initialize,
55
- serialize,
56
- onFocus
57
- };
58
- });
59
43
  useEffect(() => {
60
44
  var createEventListener = listener => {
61
45
  return event => {
62
- var element = getFieldElement(metadata.formId, metadata.name, element => element === event.target);
46
+ var element = getFieldElement(options.formId, options.name, element => element === event.target);
63
47
  if (element) {
64
- if (listener === 'focus') {
65
- var _optionsRef$current, _optionsRef$current$o;
66
- (_optionsRef$current = optionsRef.current) === null || _optionsRef$current === void 0 || (_optionsRef$current$o = _optionsRef$current.onFocus) === null || _optionsRef$current$o === void 0 || _optionsRef$current$o.call(_optionsRef$current, event);
67
- }
68
48
  eventDispatched.current[listener] = true;
69
49
  }
70
50
  };
@@ -80,62 +60,57 @@ function useInputControl(metadata, options) {
80
60
  document.removeEventListener('focusin', focusHandler, true);
81
61
  document.removeEventListener('focusout', blurHandler, true);
82
62
  };
83
- }, [metadata.formId, metadata.name]);
63
+ }, [options.formId, options.name]);
84
64
  var handlers = useMemo(() => {
85
65
  return {
86
66
  change(value) {
87
67
  if (!eventDispatched.current.change) {
88
- var _ref, _optionsRef$current$s, _optionsRef$current$s2, _optionsRef$current2;
89
- var _element = getEventTarget(metadata.formId, metadata.name);
90
- var serializedValue = (_ref = (_optionsRef$current$s = (_optionsRef$current$s2 = (_optionsRef$current2 = optionsRef.current).serialize) === null || _optionsRef$current$s2 === void 0 ? void 0 : _optionsRef$current$s2.call(_optionsRef$current2, value)) !== null && _optionsRef$current$s !== void 0 ? _optionsRef$current$s : value === null || value === void 0 ? void 0 : value.toString()) !== null && _ref !== void 0 ? _ref : '';
68
+ var _element = getEventTarget(options.formId, options.name);
91
69
  eventDispatched.current.change = true;
92
70
  if (_element instanceof HTMLInputElement && (_element.type === 'checkbox' || _element.type === 'radio')) {
93
- if (_element.checked ? _element.value !== serializedValue : _element.value === serializedValue) {
94
- _element.click();
95
- }
96
- } else {
71
+ _element.checked = _element.value === value;
72
+ } else if (_element.value !== value) {
97
73
  // No change event will be triggered on React if `element.value` is already updated
98
- if (_element.value !== serializedValue) {
99
- /**
100
- * Triggering react custom change event
101
- * Solution based on dom-testing-library
102
- * @see https://github.com/facebook/react/issues/10135#issuecomment-401496776
103
- * @see https://github.com/testing-library/dom-testing-library/blob/main/src/events.js#L104-L123
104
- */
105
- var {
106
- set: valueSetter
107
- } = Object.getOwnPropertyDescriptor(_element, 'value') || {};
108
- var prototype = Object.getPrototypeOf(_element);
109
- var {
110
- set: prototypeValueSetter
111
- } = Object.getOwnPropertyDescriptor(prototype, 'value') || {};
112
- if (prototypeValueSetter && valueSetter !== prototypeValueSetter) {
113
- prototypeValueSetter.call(_element, value);
74
+
75
+ /**
76
+ * Triggering react custom change event
77
+ * Solution based on dom-testing-library
78
+ * @see https://github.com/facebook/react/issues/10135#issuecomment-401496776
79
+ * @see https://github.com/testing-library/dom-testing-library/blob/main/src/events.js#L104-L123
80
+ */
81
+ var {
82
+ set: valueSetter
83
+ } = Object.getOwnPropertyDescriptor(_element, 'value') || {};
84
+ var prototype = Object.getPrototypeOf(_element);
85
+ var {
86
+ set: prototypeValueSetter
87
+ } = Object.getOwnPropertyDescriptor(prototype, 'value') || {};
88
+ if (prototypeValueSetter && valueSetter !== prototypeValueSetter) {
89
+ prototypeValueSetter.call(_element, value);
90
+ } else {
91
+ if (valueSetter) {
92
+ valueSetter.call(_element, value);
114
93
  } else {
115
- if (valueSetter) {
116
- valueSetter.call(_element, value);
117
- } else {
118
- throw new Error('The given element does not have a value setter');
119
- }
94
+ throw new Error('The given element does not have a value setter');
120
95
  }
121
96
  }
122
-
123
- // Dispatch input event with the updated input value
124
- _element.dispatchEvent(new InputEvent('input', {
125
- bubbles: true
126
- }));
127
- // Dispatch change event (necessary for select to update the selected option)
128
- _element.dispatchEvent(new Event('change', {
129
- bubbles: true
130
- }));
131
97
  }
98
+
99
+ // Dispatch input event with the updated input value
100
+ _element.dispatchEvent(new InputEvent('input', {
101
+ bubbles: true
102
+ }));
103
+ // Dispatch change event (necessary for select to update the selected option)
104
+ _element.dispatchEvent(new Event('change', {
105
+ bubbles: true
106
+ }));
132
107
  }
133
108
  setValue(value);
134
109
  eventDispatched.current.change = false;
135
110
  },
136
111
  focus() {
137
112
  if (!eventDispatched.current.focus) {
138
- var _element2 = getEventTarget(metadata.formId, metadata.name);
113
+ var _element2 = getEventTarget(options.formId, options.name);
139
114
  eventDispatched.current.focus = true;
140
115
  _element2.dispatchEvent(new FocusEvent('focusin', {
141
116
  bubbles: true
@@ -146,7 +121,7 @@ function useInputControl(metadata, options) {
146
121
  },
147
122
  blur() {
148
123
  if (!eventDispatched.current.blur) {
149
- var _element3 = getEventTarget(metadata.formId, metadata.name);
124
+ var _element3 = getEventTarget(options.formId, options.name);
150
125
  eventDispatched.current.blur = true;
151
126
  _element3.dispatchEvent(new FocusEvent('focusout', {
152
127
  bubbles: true
@@ -156,7 +131,7 @@ function useInputControl(metadata, options) {
156
131
  eventDispatched.current.blur = false;
157
132
  }
158
133
  };
159
- }, [metadata.formId, metadata.name]);
134
+ }, [options.formId, options.name]);
160
135
  return _objectSpread2(_objectSpread2({}, handlers), {}, {
161
136
  value
162
137
  });
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Conform view adapter for react",
4
4
  "homepage": "https://conform.guide",
5
5
  "license": "MIT",
6
- "version": "1.0.0-pre.4",
6
+ "version": "1.0.0-pre.6",
7
7
  "main": "index.js",
8
8
  "module": "index.mjs",
9
9
  "types": "index.d.ts",
@@ -30,7 +30,7 @@
30
30
  "url": "https://github.com/edmundhung/conform/issues"
31
31
  },
32
32
  "dependencies": {
33
- "@conform-to/dom": "1.0.0-pre.4"
33
+ "@conform-to/dom": "1.0.0-pre.6"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/react": "^18.2.43",