@conform-to/react 0.9.1 → 1.0.0-pre.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/helpers.d.ts CHANGED
@@ -1,72 +1,228 @@
1
- import { INTENT, VALIDATION_UNDEFINED, VALIDATION_SKIPPED } from '@conform-to/dom';
2
- import type { FieldConfig, Primitive } from './hooks.js';
3
- import type { CSSProperties, HTMLInputTypeAttribute } from 'react';
4
- interface FormElementProps {
5
- id?: string;
1
+ /// <reference types="react" />
2
+ import { type Intent } from '@conform-to/dom';
3
+ import type { FormMetadata, FieldMetadata, Metadata, Pretty, Primitive } from './context';
4
+ type FormControlProps = {
5
+ id: string;
6
6
  name: string;
7
- form?: string;
8
- 'aria-describedby'?: string;
9
- 'aria-invalid'?: boolean;
10
- }
11
- interface FormControlProps extends FormElementProps {
7
+ form: string;
12
8
  required?: boolean;
13
9
  autoFocus?: boolean;
14
10
  tabIndex?: number;
15
- style?: CSSProperties;
16
- 'aria-hidden'?: boolean;
17
- }
18
- interface InputProps<Schema> extends FormControlProps {
19
- type?: HTMLInputTypeAttribute;
11
+ 'aria-describedby'?: string;
12
+ 'aria-invalid'?: boolean;
13
+ };
14
+ type FormControlOptions = {
15
+ /**
16
+ * Decide whether to include `aria-invalid` and `aria-describedby` in the result.
17
+ */
18
+ ariaAttributes?: true;
19
+ /**
20
+ * Decide whether the aria attributes should be based on `field.valid` or `field.allValid`.
21
+ * @default 'field'
22
+ */
23
+ ariaInvalid?: 'all' | 'field';
24
+ /**
25
+ * Assign additional `id` to the `aria-describedby` attribute. If `true`, it will use the `descriptionId` from the metadata.
26
+ */
27
+ ariaDescribedBy?: boolean | string;
28
+ } | {
29
+ ariaAttributes: false;
30
+ };
31
+ type InputProps = Pretty<FormControlProps & {
32
+ type?: 'checkbox' | 'color' | 'date' | 'datetime-local' | 'email' | 'file' | 'image' | 'month' | 'number' | 'password' | 'radio' | 'range' | 'search' | 'tel' | 'text' | 'time' | 'url' | 'week';
20
33
  minLength?: number;
21
34
  maxLength?: number;
22
- min?: Schema extends number ? number : string | number;
23
- max?: Schema extends number ? number : string | number;
24
- step?: Schema extends number ? number : string | number;
35
+ min?: string | number;
36
+ max?: string | number;
37
+ step?: string | number;
25
38
  pattern?: string;
26
39
  multiple?: boolean;
27
40
  value?: string;
28
41
  defaultChecked?: boolean;
29
42
  defaultValue?: string;
30
- }
31
- interface SelectProps extends FormControlProps {
43
+ }>;
44
+ type InputOptions = Pretty<FormControlOptions & ({
45
+ type: 'checkbox' | 'radio';
46
+ /**
47
+ * The value of the checkbox or radio button. Pass `false` if you want to mange the checked state yourself.
48
+ * @default 'on'
49
+ */
50
+ value?: string | boolean;
51
+ } | {
52
+ type?: Exclude<InputProps['type'], 'checkbox' | 'radio'>;
53
+ /**
54
+ * Decide whether defaultValue should be returned. Pass `false` if you want to mange the value yourself.
55
+ */
56
+ value?: boolean;
57
+ })>;
58
+ type SelectProps = Pretty<FormControlProps & {
32
59
  defaultValue?: string | number | readonly string[] | undefined;
33
60
  multiple?: boolean;
34
- }
35
- interface TextareaProps extends FormControlProps {
61
+ }>;
62
+ type SelectOptions = Pretty<FormControlOptions & {
63
+ /**
64
+ * Decide whether defaultValue should be returned. Pass `false` if you want to mange the value yourself.
65
+ */
66
+ value?: boolean;
67
+ }>;
68
+ type TextareaProps = Pretty<FormControlProps & {
36
69
  minLength?: number;
37
70
  maxLength?: number;
38
71
  defaultValue?: string;
39
- }
40
- type BaseOptions = {
41
- ariaAttributes?: true;
42
- description?: boolean;
43
- } | {
44
- ariaAttributes: false;
72
+ }>;
73
+ type TextareaOptions = Pretty<FormControlOptions & {
74
+ /**
75
+ * Decide whether defaultValue should be returned. Pass `false` if you want to mange the value yourself.
76
+ */
77
+ value?: true;
78
+ }>;
79
+ /**
80
+ * Derives aria attributes of a form control based on the field metadata.
81
+ */
82
+ export declare function getAriaAttributes<Schema, Error>(metadata: Metadata<Schema, Error>, options?: FormControlOptions): {
83
+ 'aria-invalid'?: boolean;
84
+ 'aria-describedby'?: string;
45
85
  };
46
- type ControlOptions = BaseOptions & {
47
- hidden?: boolean;
86
+ /**
87
+ * Derives the properties of a form element based on the form metadata,
88
+ * including `id`, `onSubmit`, `noValidate`, `aria-invalid` and `aria-describedby`.
89
+ *
90
+ * @example
91
+ * ```tsx
92
+ * <form {...getFormProps(metadata)} />
93
+ * ```
94
+ */
95
+ export declare function getFormProps<Schema extends Record<string, any>, Error>(metadata: FormMetadata<Schema, Error>, options?: FormControlOptions): {
96
+ 'aria-invalid'?: boolean | undefined;
97
+ 'aria-describedby'?: string | undefined;
98
+ id: import("@conform-to/dom").FormId<Schema, Error>;
99
+ onSubmit: (event: import("react").FormEvent<HTMLFormElement>) => void;
100
+ noValidate: boolean;
48
101
  };
49
- type InputOptions = ControlOptions & ({
50
- type: 'checkbox' | 'radio';
51
- value?: string;
52
- } | {
53
- type?: Exclude<HTMLInputTypeAttribute, 'button' | 'submit' | 'hidden'>;
54
- value?: never;
55
- });
56
- export declare const hiddenProps: {
57
- style: CSSProperties;
58
- tabIndex: number;
59
- 'aria-hidden': boolean;
102
+ /**
103
+ * Derives the properties of a fieldset element based on the field metadata,
104
+ * including `id`, `name`, `form`, `aria-invalid` and `aria-describedby`.
105
+ *
106
+ * @example
107
+ * ```tsx
108
+ * <fieldset {...getFieldsetProps(metadata)} />
109
+ * ```
110
+ */
111
+ export declare function getFieldsetProps<Schema extends Record<string, any> | undefined | unknown, Error>(metadata: FieldMetadata<Schema, Error, any>, options?: FormControlOptions): {
112
+ 'aria-invalid'?: boolean | undefined;
113
+ 'aria-describedby'?: string | undefined;
114
+ id: string;
115
+ name: import("@conform-to/dom").FieldName<Schema>;
116
+ form: import("@conform-to/dom").FormId<any, Error>;
117
+ };
118
+ /**
119
+ * Derives common properties of a form control based on the field metadata,
120
+ * including `key`, `id`, `name`, `form`, `required`, `autoFocus`, `aria-invalid` and `aria-describedby`.
121
+ */
122
+ export declare function getFormControlProps<Schema, Error>(metadata: FieldMetadata<Schema, Error, any>, options?: FormControlOptions): {
123
+ 'aria-invalid'?: boolean | undefined;
124
+ 'aria-describedby'?: string | undefined;
125
+ id: string;
126
+ name: import("@conform-to/dom").FieldName<Schema>;
127
+ form: import("@conform-to/dom").FormId<any, Error>;
128
+ key: string | undefined;
129
+ required: true | undefined;
130
+ autoFocus: true | undefined;
60
131
  };
61
- export declare function input<Schema extends Primitive | unknown>(config: FieldConfig<Schema>, options?: InputOptions): InputProps<Schema>;
62
- export declare function input<Schema extends File | File[]>(config: FieldConfig<Schema>, options: InputOptions & {
132
+ /**
133
+ * Derives the properties of an input element based on the field metadata,
134
+ * including common form control attributes like `key`, `id`, `name`, `form`, `autoFocus`, `aria-invalid`, `aria-describedby`
135
+ * and constraint attributes such as `type`, `required`, `minLength`, `maxLength`, `min`, `max`, `step`, `pattern`, `multiple`.
136
+ * Depends on the provided options, it will also set `defaultChecked` / `checked` if it is a checkbox or radio button,
137
+ * or otherwise `defaultValue` / `value`.
138
+ *
139
+ * @see https://conform.guide/api/react/get-input-props
140
+ * @example
141
+ * ```tsx
142
+ * // To setup an uncontrolled input
143
+ * <input {...getInputProps(metadata)} />
144
+ * // To setup an uncontrolled checkbox
145
+ * <input {...getInputProps(metadata, { type: 'checkbox' })} />
146
+ * // To setup an input without defaultValue
147
+ * <input {...getInputProps(metadata, { value: false })} />
148
+ * // To setup a radio button without defaultChecked state
149
+ * <input {...getInputProps(metadata, { type: 'radio', value: false })} />
150
+ * ```
151
+ */
152
+ export declare function getInputProps<Schema extends Exclude<Primitive, File>>(metadata: FieldMetadata<Schema, any, any>, options?: InputOptions): InputProps;
153
+ export declare function getInputProps<Schema extends File | File[]>(metadata: FieldMetadata<Schema, any, any>, options: InputOptions & {
63
154
  type: 'file';
64
- }): InputProps<Schema>;
65
- export declare function select<Schema extends Primitive | Primitive[] | undefined | unknown>(config: FieldConfig<Schema>, options?: ControlOptions): SelectProps;
66
- export declare function textarea<Schema extends Primitive | undefined | unknown>(config: FieldConfig<Schema>, options?: ControlOptions): TextareaProps;
67
- export declare function fieldset<Schema extends Record<string, unknown> | undefined | unknown>(config: FieldConfig<Schema>, options?: BaseOptions): FormControlProps;
68
- export declare function collection<Schema extends Array<string | boolean> | string | boolean | undefined | unknown>(config: FieldConfig<Schema>, options: BaseOptions & {
155
+ }): InputProps;
156
+ /**
157
+ * Derives the properties of a select element based on the field metadata,
158
+ * including common form control attributes like `key`, `id`, `name`, `form`, `autoFocus`, `aria-invalid`, `aria-describedby`
159
+ * and constraint attributes such as `required` or `multiple`.
160
+ * Depends on the provided options, it will also set `defaultValue` / `value`.
161
+ *
162
+ * @see https://conform.guide/api/react/get-select-props
163
+ * @example
164
+ * ```tsx
165
+ * // To setup an uncontrolled select
166
+ * <select {...getSelectProps(metadata)} />
167
+ * // To setup a select without defaultValue
168
+ * <select {...getSelectProps(metadata, { value: false })} />
169
+ * ```
170
+ */
171
+ export declare function getSelectProps<Schema extends Exclude<Primitive, File> | Array<Exclude<Primitive, File>> | undefined>(metadata: FieldMetadata<Schema, any, any>, options?: SelectOptions): SelectProps;
172
+ /**
173
+ * Derives the properties of a textarea element based on the field metadata,
174
+ * including common form control attributes like `key`, `id`, `name`, `form`, `autoFocus`, `aria-invalid`, `aria-describedby`
175
+ * and constraint attributes such as `required`, `minLength` or `maxLength`.
176
+ * Depends on the provided options, it will also set `defaultValue` / `value`.
177
+ *
178
+ * @see https://conform.guide/api/react/get-textarea-props
179
+ * @example
180
+ * ```tsx
181
+ * // To setup an uncontrolled textarea
182
+ * <textarea {...getTextareaProps(metadata)} />
183
+ * // To setup a textarea without defaultValue
184
+ * <textarea {...getTextareaProps(metadata, { value: false })} />
185
+ * ```
186
+ */
187
+ export declare function getTextareaProps<Schema extends Exclude<Primitive, File> | undefined>(metadata: FieldMetadata<Schema, any, any>, options?: TextareaOptions): TextareaProps;
188
+ /**
189
+ * Derives the properties of a collection of checkboxes or radio buttons based on the field metadata,
190
+ * including common form control attributes like `key`, `id`, `name`, `form`, `autoFocus`, `aria-invalid`, `aria-describedby` and `required`.
191
+ *
192
+ * @see https://conform.guide/api/react/get-textarea-props
193
+ * @example
194
+ * ```tsx
195
+ * <fieldset>
196
+ * {getCollectionProps(metadata, {
197
+ * type: 'checkbox',
198
+ * options: ['a', 'b', 'c']
199
+ * }).map((props) => (
200
+ * <div key={props.key}>
201
+ * <label htmlFor={props.id}>{props.value}</label>
202
+ * <input {...props} />
203
+ * </div>
204
+ * ))}
205
+ * </fieldset>
206
+ * ```
207
+ */
208
+ export declare function getCollectionProps<Schema extends Array<string | boolean> | string | boolean | undefined | unknown>(metadata: FieldMetadata<Schema, any, any>, options: Pretty<FormControlOptions & {
209
+ /**
210
+ * The input type. Use `checkbox` for multiple selection or `radio` for single selection.
211
+ */
69
212
  type: 'checkbox' | 'radio';
213
+ /**
214
+ * The `value` assigned to each input element.
215
+ */
70
216
  options: string[];
71
- }): Array<InputProps<Schema> & Pick<Required<InputProps<Schema>>, 'type' | 'value'>>;
72
- export { INTENT, VALIDATION_UNDEFINED, VALIDATION_SKIPPED };
217
+ /**
218
+ * Decide whether defaultValue should be returned. Pass `false` if you want to mange the value yourself.
219
+ */
220
+ value?: boolean;
221
+ }>): Array<InputProps & Pick<Required<InputProps>, 'type' | 'value'>>;
222
+ export declare function getControlButtonProps(formId: string, intents: Array<Intent>): {
223
+ name: string;
224
+ value: string;
225
+ form: string;
226
+ formNoValidate: boolean;
227
+ };
228
+ export {};
package/helpers.js CHANGED
@@ -6,10 +6,10 @@ var _rollupPluginBabelHelpers = require('./_virtual/_rollupPluginBabelHelpers.js
6
6
  var dom = require('@conform-to/dom');
7
7
 
8
8
  /**
9
- * Cleanup `undefined` from the dervied props
9
+ * Cleanup `undefined` from the result.
10
10
  * To minimize conflicts when merging with user defined props
11
11
  */
12
- function cleanup(props) {
12
+ function simplify(props) {
13
13
  for (var key in props) {
14
14
  if (props[key] === undefined) {
15
15
  delete props[key];
@@ -17,116 +17,221 @@ function cleanup(props) {
17
17
  }
18
18
  return props;
19
19
  }
20
- function getFormElementProps(config) {
21
- var _options$ariaAttribut, _config$error, _config$error2;
20
+
21
+ /**
22
+ * Derives aria attributes of a form control based on the field metadata.
23
+ */
24
+ function getAriaAttributes(metadata) {
22
25
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
23
- var hasAriaAttributes = (_options$ariaAttribut = options.ariaAttributes) !== null && _options$ariaAttribut !== void 0 ? _options$ariaAttribut : true;
24
- return cleanup({
25
- id: config.id,
26
- name: config.name,
27
- form: config.form,
28
- 'aria-invalid': hasAriaAttributes && config.errorId && (_config$error = config.error) !== null && _config$error !== void 0 && _config$error.length ? true : undefined,
29
- 'aria-describedby': hasAriaAttributes ? [config.errorId && (_config$error2 = config.error) !== null && _config$error2 !== void 0 && _config$error2.length ? config.errorId : undefined, config.descriptionId && options.ariaAttributes !== false && options.description ? config.descriptionId : undefined].reduce((result, id) => {
30
- if (!result) {
31
- return id;
32
- }
33
- if (!id) {
34
- return result;
35
- }
36
- return "".concat(result, " ").concat(id);
37
- }) : undefined
26
+ if (typeof options.ariaAttributes !== 'undefined' && !options.ariaAttributes) {
27
+ return {};
28
+ }
29
+ var invalid = options.ariaInvalid === 'all' ? !metadata.allValid : !metadata.valid;
30
+ var ariaDescribedBy = typeof options.ariaDescribedBy === 'string' ? options.ariaDescribedBy : options.ariaDescribedBy ? metadata.descriptionId : undefined;
31
+ return simplify({
32
+ 'aria-invalid': invalid || undefined,
33
+ 'aria-describedby': invalid ? "".concat(metadata.errorId, " ").concat(ariaDescribedBy !== null && ariaDescribedBy !== void 0 ? ariaDescribedBy : '').trim() : ariaDescribedBy
38
34
  });
39
35
  }
40
- function getFormControlProps(config, options) {
41
- return cleanup(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormElementProps(config, options)), {}, {
42
- required: config.required,
43
- autoFocus: config.initialError && Object.entries(config.initialError).length > 0 ? true : undefined
44
- }, options !== null && options !== void 0 && options.hidden ? hiddenProps : undefined));
36
+
37
+ /**
38
+ * Derives the properties of a form element based on the form metadata,
39
+ * including `id`, `onSubmit`, `noValidate`, `aria-invalid` and `aria-describedby`.
40
+ *
41
+ * @example
42
+ * ```tsx
43
+ * <form {...getFormProps(metadata)} />
44
+ * ```
45
+ */
46
+ function getFormProps(metadata, options) {
47
+ return simplify(_rollupPluginBabelHelpers.objectSpread2({
48
+ id: metadata.id,
49
+ onSubmit: metadata.onSubmit,
50
+ noValidate: metadata.noValidate
51
+ }, getAriaAttributes(metadata, options)));
45
52
  }
46
- var hiddenProps = {
47
- /**
48
- * Style to make the input element visually hidden
49
- * Based on the `sr-only` class from tailwindcss
50
- */
51
- style: {
52
- position: 'absolute',
53
- width: '1px',
54
- height: '1px',
55
- padding: 0,
56
- margin: '-1px',
57
- overflow: 'hidden',
58
- clip: 'rect(0,0,0,0)',
59
- whiteSpace: 'nowrap',
60
- border: 0
61
- },
62
- tabIndex: -1,
63
- 'aria-hidden': true
64
- };
65
- function input(config) {
53
+
54
+ /**
55
+ * Derives the properties of a fieldset element based on the field metadata,
56
+ * including `id`, `name`, `form`, `aria-invalid` and `aria-describedby`.
57
+ *
58
+ * @example
59
+ * ```tsx
60
+ * <fieldset {...getFieldsetProps(metadata)} />
61
+ * ```
62
+ */
63
+ function getFieldsetProps(metadata, options) {
64
+ return simplify(_rollupPluginBabelHelpers.objectSpread2({
65
+ id: metadata.id,
66
+ name: metadata.name,
67
+ form: metadata.formId
68
+ }, getAriaAttributes(metadata, options)));
69
+ }
70
+
71
+ /**
72
+ * Derives common properties of a form control based on the field metadata,
73
+ * including `key`, `id`, `name`, `form`, `required`, `autoFocus`, `aria-invalid` and `aria-describedby`.
74
+ */
75
+ function getFormControlProps(metadata, options) {
76
+ var _metadata$constraint;
77
+ return simplify(_rollupPluginBabelHelpers.objectSpread2({
78
+ key: metadata.key,
79
+ required: ((_metadata$constraint = metadata.constraint) === null || _metadata$constraint === void 0 ? void 0 : _metadata$constraint.required) || undefined,
80
+ autoFocus: !metadata.valid || undefined
81
+ }, getFieldsetProps(metadata, options)));
82
+ }
83
+
84
+ /**
85
+ * Derives the properties of an input element based on the field metadata,
86
+ * including common form control attributes like `key`, `id`, `name`, `form`, `autoFocus`, `aria-invalid`, `aria-describedby`
87
+ * and constraint attributes such as `type`, `required`, `minLength`, `maxLength`, `min`, `max`, `step`, `pattern`, `multiple`.
88
+ * Depends on the provided options, it will also set `defaultChecked` / `checked` if it is a checkbox or radio button,
89
+ * or otherwise `defaultValue` / `value`.
90
+ *
91
+ * @see https://conform.guide/api/react/get-input-props
92
+ * @example
93
+ * ```tsx
94
+ * // To setup an uncontrolled input
95
+ * <input {...getInputProps(metadata)} />
96
+ * // To setup an uncontrolled checkbox
97
+ * <input {...getInputProps(metadata, { type: 'checkbox' })} />
98
+ * // To setup an input without defaultValue
99
+ * <input {...getInputProps(metadata, { value: false })} />
100
+ * // To setup a radio button without defaultChecked state
101
+ * <input {...getInputProps(metadata, { type: 'radio', value: false })} />
102
+ * ```
103
+ */
104
+
105
+ function getInputProps(metadata) {
106
+ var _metadata$constraint2, _metadata$constraint3, _metadata$constraint4, _metadata$constraint5, _metadata$constraint6, _metadata$constraint7, _metadata$constraint8;
66
107
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
67
- var props = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormControlProps(config, options)), {}, {
108
+ var props = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormControlProps(metadata, options)), {}, {
68
109
  type: options.type,
69
- minLength: config.minLength,
70
- maxLength: config.maxLength,
71
- min: config.min,
72
- max: config.max,
73
- step: config.step,
74
- pattern: config.pattern,
75
- multiple: config.multiple
110
+ minLength: (_metadata$constraint2 = metadata.constraint) === null || _metadata$constraint2 === void 0 ? void 0 : _metadata$constraint2.minLength,
111
+ maxLength: (_metadata$constraint3 = metadata.constraint) === null || _metadata$constraint3 === void 0 ? void 0 : _metadata$constraint3.maxLength,
112
+ min: (_metadata$constraint4 = metadata.constraint) === null || _metadata$constraint4 === void 0 ? void 0 : _metadata$constraint4.min,
113
+ max: (_metadata$constraint5 = metadata.constraint) === null || _metadata$constraint5 === void 0 ? void 0 : _metadata$constraint5.max,
114
+ step: (_metadata$constraint6 = metadata.constraint) === null || _metadata$constraint6 === void 0 ? void 0 : _metadata$constraint6.step,
115
+ pattern: (_metadata$constraint7 = metadata.constraint) === null || _metadata$constraint7 === void 0 ? void 0 : _metadata$constraint7.pattern,
116
+ multiple: (_metadata$constraint8 = metadata.constraint) === null || _metadata$constraint8 === void 0 ? void 0 : _metadata$constraint8.multiple
76
117
  });
77
- if (options.type === 'checkbox' || options.type === 'radio') {
78
- var _options$value;
79
- props.value = (_options$value = options.value) !== null && _options$value !== void 0 ? _options$value : 'on';
80
- props.defaultChecked = config.defaultValue === props.value;
81
- } else if (options.type !== 'file') {
82
- props.defaultValue = config.defaultValue;
118
+ if (typeof options.value === 'undefined' || options.value) {
119
+ if (options.type === 'checkbox' || options.type === 'radio') {
120
+ props.value = typeof options.value === 'string' ? options.value : 'on';
121
+ props.defaultChecked = typeof metadata.initialValue === 'boolean' ? metadata.initialValue : metadata.initialValue === props.value;
122
+ } else if (typeof metadata.initialValue === 'string') {
123
+ props.defaultValue = metadata.initialValue;
124
+ }
83
125
  }
84
- return cleanup(props);
126
+ return simplify(props);
85
127
  }
86
- function select(config, options) {
87
- return cleanup(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormControlProps(config, options)), {}, {
88
- defaultValue: config.defaultValue,
89
- multiple: config.multiple
90
- }));
128
+
129
+ /**
130
+ * Derives the properties of a select element based on the field metadata,
131
+ * including common form control attributes like `key`, `id`, `name`, `form`, `autoFocus`, `aria-invalid`, `aria-describedby`
132
+ * and constraint attributes such as `required` or `multiple`.
133
+ * Depends on the provided options, it will also set `defaultValue` / `value`.
134
+ *
135
+ * @see https://conform.guide/api/react/get-select-props
136
+ * @example
137
+ * ```tsx
138
+ * // To setup an uncontrolled select
139
+ * <select {...getSelectProps(metadata)} />
140
+ * // To setup a select without defaultValue
141
+ * <select {...getSelectProps(metadata, { value: false })} />
142
+ * ```
143
+ */
144
+ function getSelectProps(metadata) {
145
+ var _metadata$constraint9;
146
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
147
+ var props = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormControlProps(metadata, options)), {}, {
148
+ multiple: (_metadata$constraint9 = metadata.constraint) === null || _metadata$constraint9 === void 0 ? void 0 : _metadata$constraint9.multiple
149
+ });
150
+ if (typeof options.value === 'undefined' || options.value) {
151
+ props.defaultValue = Array.isArray(metadata.initialValue) ? metadata.initialValue.map(item => "".concat(item !== null && item !== void 0 ? item : '')) : metadata.initialValue;
152
+ }
153
+ return simplify(props);
91
154
  }
92
- function textarea(config, options) {
93
- return cleanup(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormControlProps(config, options)), {}, {
94
- defaultValue: config.defaultValue,
95
- minLength: config.minLength,
96
- maxLength: config.maxLength
97
- }));
155
+
156
+ /**
157
+ * Derives the properties of a textarea element based on the field metadata,
158
+ * including common form control attributes like `key`, `id`, `name`, `form`, `autoFocus`, `aria-invalid`, `aria-describedby`
159
+ * and constraint attributes such as `required`, `minLength` or `maxLength`.
160
+ * Depends on the provided options, it will also set `defaultValue` / `value`.
161
+ *
162
+ * @see https://conform.guide/api/react/get-textarea-props
163
+ * @example
164
+ * ```tsx
165
+ * // To setup an uncontrolled textarea
166
+ * <textarea {...getTextareaProps(metadata)} />
167
+ * // To setup a textarea without defaultValue
168
+ * <textarea {...getTextareaProps(metadata, { value: false })} />
169
+ * ```
170
+ */
171
+ function getTextareaProps(metadata) {
172
+ var _metadata$constraint10, _metadata$constraint11;
173
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
174
+ var props = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormControlProps(metadata, options)), {}, {
175
+ minLength: (_metadata$constraint10 = metadata.constraint) === null || _metadata$constraint10 === void 0 ? void 0 : _metadata$constraint10.minLength,
176
+ maxLength: (_metadata$constraint11 = metadata.constraint) === null || _metadata$constraint11 === void 0 ? void 0 : _metadata$constraint11.maxLength
177
+ });
178
+ if (typeof options.value === 'undefined' || options.value) {
179
+ props.defaultValue = metadata.initialValue;
180
+ }
181
+ return simplify(props);
98
182
  }
99
- function fieldset(config, options) {
100
- return getFormElementProps(config, options);
183
+
184
+ /**
185
+ * Derives the properties of a collection of checkboxes or radio buttons based on the field metadata,
186
+ * including common form control attributes like `key`, `id`, `name`, `form`, `autoFocus`, `aria-invalid`, `aria-describedby` and `required`.
187
+ *
188
+ * @see https://conform.guide/api/react/get-textarea-props
189
+ * @example
190
+ * ```tsx
191
+ * <fieldset>
192
+ * {getCollectionProps(metadata, {
193
+ * type: 'checkbox',
194
+ * options: ['a', 'b', 'c']
195
+ * }).map((props) => (
196
+ * <div key={props.key}>
197
+ * <label htmlFor={props.id}>{props.value}</label>
198
+ * <input {...props} />
199
+ * </div>
200
+ * ))}
201
+ * </fieldset>
202
+ * ```
203
+ */
204
+ function getCollectionProps(metadata, options) {
205
+ return options.options.map(value => {
206
+ var _metadata$key, _metadata$constraint12;
207
+ return simplify(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormControlProps(metadata, options)), {}, {
208
+ key: "".concat((_metadata$key = metadata.key) !== null && _metadata$key !== void 0 ? _metadata$key : '').concat(value),
209
+ id: "".concat(metadata.id, "-").concat(value),
210
+ type: options.type,
211
+ value,
212
+ defaultChecked: typeof options.value === 'undefined' || options.value ? options.type === 'checkbox' && Array.isArray(metadata.initialValue) ? metadata.initialValue.includes(value) : metadata.initialValue === value : undefined,
213
+ // The required attribute doesn't make sense for checkbox group
214
+ // As it would require all checkboxes to be checked instead of at least one
215
+ // It is overriden with `undefiend` so it could be cleaned up properly
216
+ required: options.type === 'checkbox' ? undefined : (_metadata$constraint12 = metadata.constraint) === null || _metadata$constraint12 === void 0 ? void 0 : _metadata$constraint12.required
217
+ }));
218
+ });
101
219
  }
102
- function collection(config, options) {
103
- return options.options.map(value => cleanup(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormControlProps(config, options)), {}, {
104
- id: config.id ? "".concat(config.id, "-").concat(value) : undefined,
105
- type: options.type,
106
- value,
107
- defaultChecked: options.type === 'checkbox' && Array.isArray(config.defaultValue) ? config.defaultValue.includes(value) : config.defaultValue === value,
108
- // The required attribute doesn't make sense for checkbox group
109
- // As it would require all checkboxes to be checked instead of at least one
110
- // overriden with `undefiend` so it gets cleaned up
111
- required: options.type === 'checkbox' ? undefined : config.required
112
- })));
220
+ function getControlButtonProps(formId, intents) {
221
+ return {
222
+ name: dom.INTENT,
223
+ value: dom.serializeIntents(intents),
224
+ form: formId,
225
+ formNoValidate: true
226
+ };
113
227
  }
114
228
 
115
- Object.defineProperty(exports, 'INTENT', {
116
- enumerable: true,
117
- get: function () { return dom.INTENT; }
118
- });
119
- Object.defineProperty(exports, 'VALIDATION_SKIPPED', {
120
- enumerable: true,
121
- get: function () { return dom.VALIDATION_SKIPPED; }
122
- });
123
- Object.defineProperty(exports, 'VALIDATION_UNDEFINED', {
124
- enumerable: true,
125
- get: function () { return dom.VALIDATION_UNDEFINED; }
126
- });
127
- exports.collection = collection;
128
- exports.fieldset = fieldset;
129
- exports.hiddenProps = hiddenProps;
130
- exports.input = input;
131
- exports.select = select;
132
- exports.textarea = textarea;
229
+ exports.getAriaAttributes = getAriaAttributes;
230
+ exports.getCollectionProps = getCollectionProps;
231
+ exports.getControlButtonProps = getControlButtonProps;
232
+ exports.getFieldsetProps = getFieldsetProps;
233
+ exports.getFormControlProps = getFormControlProps;
234
+ exports.getFormProps = getFormProps;
235
+ exports.getInputProps = getInputProps;
236
+ exports.getSelectProps = getSelectProps;
237
+ exports.getTextareaProps = getTextareaProps;