@conform-to/react 0.6.0-pre.0 → 0.6.0

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
@@ -11,13 +11,12 @@
11
11
  - [useFieldList](#usefieldlist)
12
12
  - [useInputEvent](#useinputevent)
13
13
  - [conform](#conform)
14
+ - [parse](#parse)
15
+ - [validateConstraint](#validateconstraint)
14
16
  - [list](#list)
15
17
  - [validate](#validate)
16
18
  - [requestIntent](#requestintent)
17
- - [getFormElements](#getformelements)
18
- - [hasError](#haserror)
19
- - [parse](#parse)
20
- - [shouldValidate](#shouldvalidate)
19
+ - [isFieldElement](#isfieldelement)
21
20
 
22
21
  <!-- /aside -->
23
22
 
@@ -27,9 +26,9 @@ By default, the browser calls the [reportValidity()](https://developer.mozilla.o
27
26
 
28
27
  This hook enhances the form validation behaviour by:
29
28
 
30
- - Enabling customizing form validation behaviour.
31
- - Capturing the error message and removes the error bubbles.
32
- - Preparing all properties required to configure the dom elements.
29
+ - Enabling customizing validation logic.
30
+ - Capturing error message and removes the error bubbles.
31
+ - Preparing all properties required to configure the form elements.
33
32
 
34
33
  ```tsx
35
34
  import { useForm } from '@conform-to/react';
@@ -53,17 +52,17 @@ function LoginForm() {
53
52
  /**
54
53
  * An object representing the initial value of the form.
55
54
  */
56
- defaultValue: undefined;
55
+ defaultValue: undefined,
57
56
 
58
57
  /**
59
- * An object describing the state from the last submission
58
+ * The last submission result from the server
60
59
  */
61
- state: undefined;
60
+ lastSubmission: undefined,
62
61
 
63
62
  /**
64
63
  * An object describing the constraint of each field
65
64
  */
66
- constraint: undefined;
65
+ constraint: undefined,
67
66
 
68
67
  /**
69
68
  * Enable native validation before hydation.
@@ -90,7 +89,7 @@ function LoginForm() {
90
89
  /**
91
90
  * The submit event handler of the form.
92
91
  */
93
- onSubmit(event, { formData, submission }) {
92
+ onSubmit(event, { formData, submission, action, encType, method }) {
94
93
  // ...
95
94
  },
96
95
  });
@@ -165,20 +164,20 @@ function Example() {
165
164
  const [form, { address }] = useForm<{ address: Address }>();
166
165
  const { city, zipcode, street, country } = useFieldset(
167
166
  form.ref,
168
- address.config,
167
+ address,
169
168
  );
170
169
 
171
170
  return (
172
171
  <form {...form.props}>
173
172
  <fieldset>
174
173
  <legned>Address</legend>
175
- <input {...conform.input(street.config)} />
174
+ <input {...conform.input(street)} />
176
175
  <div>{street.error}</div>
177
- <input {...conform.input(zipcode.config)} />
176
+ <input {...conform.input(zipcode)} />
178
177
  <div>{zipcode.error}</div>
179
- <input {...conform.input(city.config)} />
178
+ <input {...conform.input(city)} />
180
179
  <div>{city.error}</div>
181
- <input {...conform.input(country.config)} />
180
+ <input {...conform.input(country)} />
182
181
  <div>{country.error}</div>
183
182
  </fieldset>
184
183
  <button>Submit</button>
@@ -204,7 +203,7 @@ function Fieldset(config: FieldConfig<Address>) {
204
203
  <details>
205
204
  <summary>Why does `useFieldset` require a ref object of the form or fieldset?</summary>
206
205
 
207
- **conform** utilises the DOM as its context provider / input registry, which maintains a link between each input / button / fieldset with the form through the [form property](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement#properties). The ref object allows it to restrict the scope to elements associated to the same form only.
206
+ **conform** utilises the DOM as its context provider / input registry, which maintains a link between each input / button / fieldset with the form through the [form property](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement#properties). The ref object allows it to restrict the scope to form elements associated to the same form only.
208
207
 
209
208
  ```tsx
210
209
  function ExampleForm() {
@@ -231,7 +230,7 @@ function ExampleForm() {
231
230
 
232
231
  ### useFieldList
233
232
 
234
- This hook enables you to work with [array](/docs/configuration.md#array) and support [list](#list) command button builder to modify a list. It can also be used with [useFieldset](#usefieldset) for [nested list](/docs/configuration.md#nested-list) at the same time.
233
+ This hook enables you to work with [array](/docs/configuration.md#array) and support the [list](#list) intent button builder to modify a list. It can also be used with [useFieldset](#usefieldset) for [nested list](/docs/configuration.md#nested-list) at the same time.
235
234
 
236
235
  ```tsx
237
236
  import { useForm, useFieldList, list } from '@conform-to/react';
@@ -245,27 +244,25 @@ type Schema = {
245
244
 
246
245
  function Example() {
247
246
  const [form, { items }] = useForm<Schema>();
248
- const list = useFieldList(form.ref, items.config);
247
+ const itemsList = useFieldList(form.ref, items);
249
248
 
250
249
  return (
251
250
  <fieldset ref={ref}>
252
- {list.map((item, index) => (
251
+ {itemsList.map((item, index) => (
253
252
  <div key={item.key}>
254
253
  {/* Setup an input per item */}
255
- <input {...conform.input(item.config)} />
254
+ <input {...conform.input(item)} />
256
255
 
257
256
  {/* Error of each item */}
258
257
  <span>{item.error}</span>
259
258
 
260
259
  {/* Setup a delete button (Note: It is `items` not `item`) */}
261
- <button {...list.remove(items.config.name, { index })}>Delete</button>
260
+ <button {...list.remove(items.name, { index })}>Delete</button>
262
261
  </div>
263
262
  ))}
264
263
 
265
264
  {/* Setup a button that can append a new row with optional default value */}
266
- <button {...list.append(items.config.name, { defaultValue: '' })}>
267
- add
268
- </button>
265
+ <button {...list.append(items.name, { defaultValue: '' })}>add</button>
269
266
  </fieldset>
270
267
  );
271
268
  }
@@ -284,9 +281,9 @@ import { useState, useRef } from 'react';
284
281
 
285
282
  function MuiForm() {
286
283
  const [form, { category }] = useForm();
287
- const [value, setValue] = useState(category.config.defaultValue ?? '');
284
+ const [value, setValue] = useState(category.defaultValue ?? '');
288
285
  const [ref, control] = useInputEvent({
289
- onReset: () => setValue(category.config.defaultValue ?? ''),
286
+ onReset: () => setValue(category.defaultValue ?? ''),
290
287
  });
291
288
  const inputRef = useRef<HTMLInputElement>(null);
292
289
 
@@ -295,7 +292,7 @@ function MuiForm() {
295
292
  {/* Render a shadow input somewhere */}
296
293
  <input
297
294
  ref={ref}
298
- {...conform.input(category.config, { hidden: true })}
295
+ {...conform.input(category, { hidden: true })}
299
296
  onChange={(e) => setValue(e.target.value)}
300
297
  onFocus={() => inputRef.current?.focus()}
301
298
  />
@@ -323,9 +320,9 @@ function MuiForm() {
323
320
 
324
321
  ### conform
325
322
 
326
- It provides several helpers to remove the boilerplate when configuring a form control.
323
+ It provides several helpers to remove the boilerplate when configuring a form control and derives attributes for [accessibility](/docs/accessibility.md#configuration) concerns and helps [focus management](/docs/focus-management.md#focusing-before-javascript-is-loaded).
327
324
 
328
- You are recommended to create a wrapper on top if you need to integrate with custom input component. As the helper derives attributes for [accessibility](/docs/accessibility.md#configuration) concerns and helps [focus management](/docs/focus-management.md#focusing-before-javascript-is-loaded).
325
+ You can also create a wrapper on top if you need to integrate with custom input component.
329
326
 
330
327
  Before:
331
328
 
@@ -339,31 +336,31 @@ function Example() {
339
336
  <form {...form.props}>
340
337
  <input
341
338
  type="text"
342
- name={title.config.name}
343
- form={title.config.form}
344
- defaultValue={title.config.defaultValue}
345
- requried={title.config.required}
346
- minLength={title.config.minLength}
347
- maxLength={title.config.maxLength}
348
- min={title.config.min}
349
- max={title.config.max}
350
- multiple={title.config.multiple}
351
- pattern={title.config.pattern}
339
+ name={title.name}
340
+ form={title.form}
341
+ defaultValue={title.defaultValue}
342
+ requried={title.required}
343
+ minLength={title.minLength}
344
+ maxLength={title.maxLength}
345
+ min={title.min}
346
+ max={title.max}
347
+ multiple={title.multiple}
348
+ pattern={title.pattern}
352
349
  />
353
350
  <textarea
354
- name={description.config.name}
355
- form={description.config.form}
356
- defaultValue={description.config.defaultValue}
357
- requried={description.config.required}
358
- minLength={description.config.minLength}
359
- maxLength={description.config.maxLength}
351
+ name={description.name}
352
+ form={description.form}
353
+ defaultValue={description.defaultValue}
354
+ requried={description.required}
355
+ minLength={description.minLength}
356
+ maxLength={description.maxLength}
360
357
  />
361
358
  <select
362
- name={category.config.name}
363
- form={category.config.form}
364
- defaultValue={category.config.defaultValue}
365
- requried={category.config.required}
366
- multiple={category.config.multiple}
359
+ name={category.name}
360
+ form={category.form}
361
+ defaultValue={category.defaultValue}
362
+ requried={category.required}
363
+ multiple={category.multiple}
367
364
  >
368
365
  {/* ... */}
369
366
  </select>
@@ -382,9 +379,9 @@ function Example() {
382
379
 
383
380
  return (
384
381
  <form {...form.props}>
385
- <input {...conform.input(title.config, { type: 'text' })} />
386
- <textarea {...conform.textarea(description.config)} />
387
- <select {...conform.select(category.config)}>{/* ... */}</select>
382
+ <input {...conform.input(title, { type: 'text' })} />
383
+ <textarea {...conform.textarea(description)} />
384
+ <select {...conform.select(category)}>{/* ... */}</select>
388
385
  </form>
389
386
  );
390
387
  }
@@ -392,9 +389,117 @@ function Example() {
392
389
 
393
390
  ---
394
391
 
392
+ ### parse
393
+
394
+ It parses the formData based on the [naming convention](/docs/configuration.md#naming-convention) with the validation result from the resolver.
395
+
396
+ ```tsx
397
+ import { parse } from '@conform-to/react';
398
+
399
+ const formData = new FormData();
400
+ const submission = parse(formData, {
401
+ resolve({ email, password }) {
402
+ const error: Record<string, string> = {};
403
+
404
+ if (typeof email !== 'string') {
405
+ error.email = 'Email is required';
406
+ } else if (!/^[^@]+@[^@]+$/.test(email)) {
407
+ error.email = 'Email is invalid';
408
+ }
409
+
410
+ if (typeof password !== 'string') {
411
+ error.password = 'Password is required';
412
+ }
413
+
414
+ if (error.email || error.password) {
415
+ return { error };
416
+ }
417
+
418
+ return {
419
+ value: { email, password },
420
+ };
421
+ },
422
+ });
423
+ ```
424
+
425
+ ---
426
+
427
+ ### validateConstraint
428
+
429
+ This enable Constraint Validation with ability to enable custom constraint using data-attribute and customizing error messages. By default, the error message would be the attribute that triggered the error (e.g. `required` / `type` / 'minLength' etc).
430
+
431
+ ```tsx
432
+ import { useForm, validateConstraint } from '@conform-to/react';
433
+ import { Form } from 'react-router-dom';
434
+
435
+ export default function SignupForm() {
436
+ const [form, { email, password, confirmPassword }] = useForm({
437
+ onValidate(context) {
438
+ // This enables validating each field based on the validity state and custom cosntraint if defined
439
+ return validateConstraint(
440
+ ...context,
441
+ constraint: {
442
+ // Define custom constraint
443
+ match(value, { formData, attributeValue }) {
444
+ // Check if the value of the field match the value of another field
445
+ return value === formData.get(attributeValue);
446
+ },
447
+ });
448
+ }
449
+ });
450
+
451
+ return (
452
+ <Form method="post" {...form.props}>
453
+ <div>
454
+ <label>Email</label>
455
+ <input
456
+ name="email"
457
+ type="email"
458
+ required
459
+ pattern="[^@]+@[^@]+\\.[^@]+"
460
+ />
461
+ {email.error === 'required' ? (
462
+ <div>Email is required</div>
463
+ ) : email.error === 'type' ? (
464
+ <div>Email is invalid</div>
465
+ ) : null}
466
+ </div>
467
+ <div>
468
+ <label>Password</label>
469
+ <input
470
+ name="password"
471
+ type="password"
472
+ required
473
+ />
474
+ {password.error === 'required' ? (
475
+ <div>Password is required</div>
476
+ ) : null}
477
+ </div>
478
+ <div>
479
+ <label>Confirm Password</label>
480
+ <input
481
+ name="confirmPassword"
482
+ type="password"
483
+ required
484
+ data-constraint-match="password"
485
+ />
486
+ {confirmPassword.error === 'required' ? (
487
+ <div>Confirm Password is required</div>
488
+ ) : confirmPassword.error === 'match' ? (
489
+ <div>Password does not match</div>
490
+ ) : null}
491
+ </div>
492
+ <button>Signup</button>
493
+ </Form>
494
+ );
495
+ }
496
+ ```
497
+
498
+ ---
499
+
395
500
  ### list
396
501
 
397
- It provides serveral helpers to configure a command button for [modifying a list](/docs/commands.md#modifying-a-list).
502
+ It provides serveral helpers to configure an intent button for [modifying a list](/docs/commands.md#modifying-a-list).
398
503
 
399
504
  ```tsx
400
505
  import { list } from '@conform-to/react';
@@ -427,7 +532,7 @@ function Example() {
427
532
 
428
533
  ### validate
429
534
 
430
- It returns the properties required to configure a command button for [validation](/docs/commands.md#validation).
535
+ It returns the properties required to configure an intent button for [validation](/docs/commands.md#validation).
431
536
 
432
537
  ```tsx
433
538
  import { validate } from '@conform-to/react';
@@ -463,7 +568,7 @@ import DragAndDrop from 'awesome-dnd-example';
463
568
 
464
569
  export default function Todos() {
465
570
  const [form, { tasks }] = useForm();
466
- const taskList = useFieldList(form.ref, tasks.config);
571
+ const taskList = useFieldList(form.ref, tasks);
467
572
 
468
573
  const handleDrop = (from, to) =>
469
574
  requestIntent(form.ref.current, list.reorder({ from, to }));
@@ -473,7 +578,7 @@ export default function Todos() {
473
578
  <DragAndDrop onDrop={handleDrop}>
474
579
  {taskList.map((task, index) => (
475
580
  <div key={task.key}>
476
- <input {...conform.input(task.config)} />
581
+ <input {...conform.input(task)} />
477
582
  </div>
478
583
  ))}
479
584
  </DragAndDrop>
@@ -485,81 +590,22 @@ export default function Todos() {
485
590
 
486
591
  ---
487
592
 
488
- ### getFormElements
593
+ ### isFieldElement
489
594
 
490
- It returns all _input_ / _select_ / _textarea_ or _button_ in the forms. Useful when looping through the form elements to validate each field manually.
595
+ This is an utility for checking if the provided element is a form element (_input_ / _select_ / _textarea_ or _button_) which also works as a type guard.
491
596
 
492
597
  ```tsx
493
- import { useForm, parse, getFormElements } from '@conform-to/react';
494
-
495
- export default function LoginForm() {
496
- const [form] = useForm({
497
- onValidate({ form, formData }) {
498
- const submission = parse(formData);
499
-
500
- for (const element of getFormElements(form)) {
501
- switch (element.name) {
502
- case 'email': {
503
- if (element.validity.valueMissing) {
504
- submission.error.push([element.name, 'Email is required']);
505
- } else if (element.validity.typeMismatch) {
506
- submission.error.push([element.name, 'Email is invalid']);
507
- }
508
- break;
509
- }
510
- case 'password': {
511
- if (element.validity.valueMissing) {
512
- submission.error.push([element.name, 'Password is required']);
513
- }
514
- break;
515
- }
598
+ function Example() {
599
+ return (
600
+ <form
601
+ onFocus={(event) => {
602
+ if (isFieldElement(event.target)) {
603
+ // event.target is now considered one of the form elements type
516
604
  }
517
- }
518
-
519
- return submission;
520
- },
521
-
522
- // ....
523
- });
524
-
525
- // ...
605
+ }}
606
+ >
607
+ {/* ... */}
608
+ </form>
609
+ );
526
610
  }
527
611
  ```
528
-
529
- ---
530
-
531
- ### parse
532
-
533
- It parses the formData based on the [naming convention](/docs/submission).
534
-
535
- ```tsx
536
- import { parse } from '@conform-to/react';
537
-
538
- const formData = new FormData();
539
- const submission = parse(formData);
540
-
541
- console.log(submission);
542
- ```
543
-
544
- ---
545
-
546
- ### shouldValidate
547
-
548
- This helper checks if the scope of validation includes a specific field by checking the submission:
549
-
550
- ```tsx
551
- import { shouldValidate } from '@conform-to/react';
552
-
553
- /**
554
- * The submission intent give us hint on what should be valdiated.
555
- * If the intent is 'validate/:field', only the field with name matching must be validated.
556
- * If the intent is undefined, everything should be validated (Default submission)
557
- */
558
- const intent = 'validate/email';
559
-
560
- // This will log 'true'
561
- console.log(shouldValidate(intent, 'email'));
562
-
563
- // This will log 'false'
564
- console.log(shouldValidate(intent, 'password'));
565
- ```
package/helpers.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { type FieldConfig, VALIDATION_SKIPPED, VALIDATION_UNDEFINED } from '@conform-to/dom';
1
+ import { type FieldConfig, type Primitive, VALIDATION_UNDEFINED, VALIDATION_SKIPPED, INTENT } from '@conform-to/dom';
2
2
  import type { CSSProperties, HTMLInputTypeAttribute } from 'react';
3
- interface FieldProps {
3
+ interface FormControlProps {
4
4
  id?: string;
5
5
  name: string;
6
6
  form?: string;
@@ -8,11 +8,11 @@ interface FieldProps {
8
8
  autoFocus?: boolean;
9
9
  tabIndex?: number;
10
10
  style?: CSSProperties;
11
- 'aria-invalid': boolean;
12
11
  'aria-describedby'?: string;
12
+ 'aria-invalid'?: boolean;
13
13
  'aria-hidden'?: boolean;
14
14
  }
15
- interface InputProps<Schema> extends FieldProps {
15
+ interface InputProps<Schema> extends FormControlProps {
16
16
  type?: HTMLInputTypeAttribute;
17
17
  minLength?: number;
18
18
  maxLength?: number;
@@ -25,11 +25,11 @@ interface InputProps<Schema> extends FieldProps {
25
25
  defaultChecked?: boolean;
26
26
  defaultValue?: string;
27
27
  }
28
- interface SelectProps extends FieldProps {
28
+ interface SelectProps extends FormControlProps {
29
29
  defaultValue?: string | number | readonly string[] | undefined;
30
30
  multiple?: boolean;
31
31
  }
32
- interface TextareaProps extends FieldProps {
32
+ interface TextareaProps extends FormControlProps {
33
33
  minLength?: number;
34
34
  maxLength?: number;
35
35
  defaultValue?: string;
@@ -46,12 +46,11 @@ type InputOptions = {
46
46
  export declare function input<Schema extends File | File[]>(config: FieldConfig<Schema>, options: {
47
47
  type: 'file';
48
48
  }): InputProps<Schema>;
49
- export declare function input<Schema extends any>(config: FieldConfig<Schema>, options?: InputOptions): InputProps<Schema>;
50
- export declare function select<Schema>(config: FieldConfig<Schema>, options?: {
49
+ export declare function input<Schema extends Primitive>(config: FieldConfig<Schema>, options?: InputOptions): InputProps<Schema>;
50
+ export declare function select(config: FieldConfig<Primitive | Primitive[]>, options?: {
51
51
  hidden?: boolean;
52
52
  }): SelectProps;
53
- export declare function textarea<Schema>(config: FieldConfig<Schema>, options?: {
53
+ export declare function textarea(config: FieldConfig<Primitive>, options?: {
54
54
  hidden?: boolean;
55
55
  }): TextareaProps;
56
- export declare const intent = "__intent__";
57
- export { VALIDATION_UNDEFINED, VALIDATION_SKIPPED };
56
+ export { INTENT, VALIDATION_UNDEFINED, VALIDATION_SKIPPED };
package/helpers.js CHANGED
@@ -2,6 +2,7 @@
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
 
7
8
  /**
@@ -19,90 +20,72 @@ var hiddenStyle = {
19
20
  whiteSpace: 'nowrap',
20
21
  border: 0
21
22
  };
22
- function input(config) {
23
- var _config$initialError;
24
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
25
- var attributes = {
23
+ function getFormControlProps(config, options) {
24
+ var _config$error;
25
+ var props = {
26
26
  id: config.id,
27
- type: options.type,
28
27
  name: config.name,
29
28
  form: config.form,
30
- required: config.required,
29
+ required: config.required
30
+ };
31
+ if (config.id) {
32
+ props.id = config.id;
33
+ props['aria-describedby'] = config.errorId;
34
+ }
35
+ if (config.errorId && (_config$error = config.error) !== null && _config$error !== void 0 && _config$error.length) {
36
+ props['aria-invalid'] = true;
37
+ }
38
+ if (config.initialError && Object.entries(config.initialError).length > 0) {
39
+ props.autoFocus = true;
40
+ }
41
+ if (options !== null && options !== void 0 && options.hidden) {
42
+ props.style = hiddenStyle;
43
+ props.tabIndex = -1;
44
+ props['aria-hidden'] = true;
45
+ }
46
+ return props;
47
+ }
48
+ function input(config) {
49
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
50
+ var props = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormControlProps(config, options)), {}, {
51
+ type: options.type,
31
52
  minLength: config.minLength,
32
53
  maxLength: config.maxLength,
33
54
  min: config.min,
34
55
  max: config.max,
35
56
  step: config.step,
36
57
  pattern: config.pattern,
37
- multiple: config.multiple,
38
- 'aria-invalid': Boolean((_config$initialError = config.initialError) === null || _config$initialError === void 0 ? void 0 : _config$initialError.length),
39
- 'aria-describedby': config.errorId
40
- };
41
- if (options !== null && options !== void 0 && options.hidden) {
42
- attributes.style = hiddenStyle;
43
- attributes.tabIndex = -1;
44
- attributes['aria-hidden'] = true;
45
- }
46
- if (config.initialError && Object.entries(config.initialError).length > 0) {
47
- attributes.autoFocus = true;
48
- }
58
+ multiple: config.multiple
59
+ });
49
60
  if (options.type === 'checkbox' || options.type === 'radio') {
50
61
  var _options$value;
51
- attributes.value = (_options$value = options.value) !== null && _options$value !== void 0 ? _options$value : 'on';
52
- attributes.defaultChecked = config.defaultValue === attributes.value;
62
+ props.value = (_options$value = options.value) !== null && _options$value !== void 0 ? _options$value : 'on';
63
+ props.defaultChecked = config.defaultValue === props.value;
53
64
  } else if (options.type !== 'file') {
54
- attributes.defaultValue = config.defaultValue;
65
+ props.defaultValue = config.defaultValue;
55
66
  }
56
- return attributes;
67
+ return props;
57
68
  }
58
69
  function select(config, options) {
59
- var _config$defaultValue, _config$initialError2;
60
- var attributes = {
61
- id: config.id,
62
- name: config.name,
63
- form: config.form,
64
- defaultValue: config.multiple ? Array.isArray(config.defaultValue) ? config.defaultValue : [] : "".concat((_config$defaultValue = config.defaultValue) !== null && _config$defaultValue !== void 0 ? _config$defaultValue : ''),
65
- required: config.required,
66
- multiple: config.multiple,
67
- 'aria-invalid': Boolean((_config$initialError2 = config.initialError) === null || _config$initialError2 === void 0 ? void 0 : _config$initialError2.length),
68
- 'aria-describedby': config.errorId
69
- };
70
- if (options !== null && options !== void 0 && options.hidden) {
71
- attributes.style = hiddenStyle;
72
- attributes.tabIndex = -1;
73
- attributes['aria-hidden'] = true;
74
- }
75
- if (config.initialError && Object.entries(config.initialError).length > 0) {
76
- attributes.autoFocus = true;
77
- }
78
- return attributes;
70
+ var props = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormControlProps(config, options)), {}, {
71
+ defaultValue: config.defaultValue,
72
+ multiple: config.multiple
73
+ });
74
+ return props;
79
75
  }
80
76
  function textarea(config, options) {
81
- var _config$defaultValue2, _config$initialError3;
82
- var attributes = {
83
- id: config.id,
84
- name: config.name,
85
- form: config.form,
86
- defaultValue: "".concat((_config$defaultValue2 = config.defaultValue) !== null && _config$defaultValue2 !== void 0 ? _config$defaultValue2 : ''),
87
- required: config.required,
77
+ var props = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormControlProps(config, options)), {}, {
78
+ defaultValue: config.defaultValue,
88
79
  minLength: config.minLength,
89
- maxLength: config.maxLength,
90
- autoFocus: Boolean(config.initialError),
91
- 'aria-invalid': Boolean((_config$initialError3 = config.initialError) === null || _config$initialError3 === void 0 ? void 0 : _config$initialError3.length),
92
- 'aria-describedby': config.errorId
93
- };
94
- if (options !== null && options !== void 0 && options.hidden) {
95
- attributes.style = hiddenStyle;
96
- attributes.tabIndex = -1;
97
- attributes['aria-hidden'] = true;
98
- }
99
- if (config.initialError && Object.entries(config.initialError).length > 0) {
100
- attributes.autoFocus = true;
101
- }
102
- return attributes;
80
+ maxLength: config.maxLength
81
+ });
82
+ return props;
103
83
  }
104
- var intent = '__intent__';
105
84
 
85
+ Object.defineProperty(exports, 'INTENT', {
86
+ enumerable: true,
87
+ get: function () { return dom.INTENT; }
88
+ });
106
89
  Object.defineProperty(exports, 'VALIDATION_SKIPPED', {
107
90
  enumerable: true,
108
91
  get: function () { return dom.VALIDATION_SKIPPED; }
@@ -112,6 +95,5 @@ Object.defineProperty(exports, 'VALIDATION_UNDEFINED', {
112
95
  get: function () { return dom.VALIDATION_UNDEFINED; }
113
96
  });
114
97
  exports.input = input;
115
- exports.intent = intent;
116
98
  exports.select = select;
117
99
  exports.textarea = textarea;