@conform-to/react 0.5.0-pre.0 → 0.5.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,10 +1,16 @@
1
1
  import type { FieldConfig } from '@conform-to/dom';
2
- import type { HTMLInputTypeAttribute } from 'react';
2
+ import type { CSSProperties, HTMLInputTypeAttribute } from 'react';
3
3
  interface FieldProps {
4
+ id?: string;
4
5
  name: string;
5
6
  form?: string;
6
7
  required?: boolean;
7
8
  autoFocus?: boolean;
9
+ tabIndex?: number;
10
+ style?: CSSProperties;
11
+ 'aria-invalid': boolean;
12
+ 'aria-describedby'?: string;
13
+ 'aria-hidden'?: boolean;
8
14
  }
9
15
  interface InputProps<Schema> extends FieldProps {
10
16
  type?: HTMLInputTypeAttribute;
@@ -30,18 +36,21 @@ interface TextareaProps extends FieldProps {
30
36
  }
31
37
  declare type InputOptions = {
32
38
  type: 'checkbox' | 'radio';
39
+ hidden?: boolean;
33
40
  value?: string;
34
41
  } | {
35
- type: 'file';
36
- value?: never;
37
- } | {
38
- type?: Exclude<HTMLInputTypeAttribute, 'button' | 'submit' | 'hidden' | 'file'>;
42
+ type?: Exclude<HTMLInputTypeAttribute, 'button' | 'submit' | 'hidden'>;
43
+ hidden?: boolean;
39
44
  value?: never;
40
45
  };
41
46
  export declare function input<Schema extends File | File[]>(config: FieldConfig<Schema>, options: {
42
47
  type: 'file';
43
48
  }): InputProps<Schema>;
44
49
  export declare function input<Schema extends any>(config: FieldConfig<Schema>, options?: InputOptions): InputProps<Schema>;
45
- export declare function select<Schema>(config: FieldConfig<Schema>): SelectProps;
46
- export declare function textarea<Schema>(config: FieldConfig<Schema>): TextareaProps;
50
+ export declare function select<Schema>(config: FieldConfig<Schema>, options?: {
51
+ hidden?: boolean;
52
+ }): SelectProps;
53
+ export declare function textarea<Schema>(config: FieldConfig<Schema>, options?: {
54
+ hidden?: boolean;
55
+ }): TextareaProps;
47
56
  export {};
package/helpers.js CHANGED
@@ -2,9 +2,26 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
+ /**
6
+ * Style to make the input element visually hidden
7
+ * Based on the `sr-only` class from tailwindcss
8
+ */
9
+ var hiddenStyle = {
10
+ position: 'absolute',
11
+ width: '1px',
12
+ height: '1px',
13
+ padding: 0,
14
+ margin: '-1px',
15
+ overflow: 'hidden',
16
+ clip: 'rect(0,0,0,0)',
17
+ whiteSpace: 'nowrap',
18
+ border: 0
19
+ };
5
20
  function input(config) {
21
+ var _config$initialError;
6
22
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
7
23
  var attributes = {
24
+ id: config.id,
8
25
  type: options.type,
9
26
  name: config.name,
10
27
  form: config.form,
@@ -15,8 +32,15 @@ function input(config) {
15
32
  max: config.max,
16
33
  step: config.step,
17
34
  pattern: config.pattern,
18
- multiple: config.multiple
35
+ multiple: config.multiple,
36
+ 'aria-invalid': Boolean((_config$initialError = config.initialError) === null || _config$initialError === void 0 ? void 0 : _config$initialError.length),
37
+ 'aria-describedby': config.errorId
19
38
  };
39
+ if (options !== null && options !== void 0 && options.hidden) {
40
+ attributes.style = hiddenStyle;
41
+ attributes.tabIndex = -1;
42
+ attributes['aria-hidden'] = true;
43
+ }
20
44
  if (config.initialError && config.initialError.length > 0) {
21
45
  attributes.autoFocus = true;
22
46
  }
@@ -29,31 +53,47 @@ function input(config) {
29
53
  }
30
54
  return attributes;
31
55
  }
32
- function select(config) {
33
- var _config$defaultValue;
56
+ function select(config, options) {
57
+ var _config$defaultValue, _config$initialError2;
34
58
  var attributes = {
59
+ id: config.id,
35
60
  name: config.name,
36
61
  form: config.form,
37
62
  defaultValue: config.multiple ? Array.isArray(config.defaultValue) ? config.defaultValue : [] : "".concat((_config$defaultValue = config.defaultValue) !== null && _config$defaultValue !== void 0 ? _config$defaultValue : ''),
38
63
  required: config.required,
39
- multiple: config.multiple
64
+ multiple: config.multiple,
65
+ 'aria-invalid': Boolean((_config$initialError2 = config.initialError) === null || _config$initialError2 === void 0 ? void 0 : _config$initialError2.length),
66
+ 'aria-describedby': config.errorId
40
67
  };
68
+ if (options !== null && options !== void 0 && options.hidden) {
69
+ attributes.style = hiddenStyle;
70
+ attributes.tabIndex = -1;
71
+ attributes['aria-hidden'] = true;
72
+ }
41
73
  if (config.initialError && config.initialError.length > 0) {
42
74
  attributes.autoFocus = true;
43
75
  }
44
76
  return attributes;
45
77
  }
46
- function textarea(config) {
47
- var _config$defaultValue2;
78
+ function textarea(config, options) {
79
+ var _config$defaultValue2, _config$initialError3;
48
80
  var attributes = {
81
+ id: config.id,
49
82
  name: config.name,
50
83
  form: config.form,
51
84
  defaultValue: "".concat((_config$defaultValue2 = config.defaultValue) !== null && _config$defaultValue2 !== void 0 ? _config$defaultValue2 : ''),
52
85
  required: config.required,
53
86
  minLength: config.minLength,
54
87
  maxLength: config.maxLength,
55
- autoFocus: Boolean(config.initialError)
88
+ autoFocus: Boolean(config.initialError),
89
+ 'aria-invalid': Boolean((_config$initialError3 = config.initialError) === null || _config$initialError3 === void 0 ? void 0 : _config$initialError3.length),
90
+ 'aria-describedby': config.errorId
56
91
  };
92
+ if (options !== null && options !== void 0 && options.hidden) {
93
+ attributes.style = hiddenStyle;
94
+ attributes.tabIndex = -1;
95
+ attributes['aria-hidden'] = true;
96
+ }
57
97
  if (config.initialError && config.initialError.length > 0) {
58
98
  attributes.autoFocus = true;
59
99
  }
package/hooks.d.ts CHANGED
@@ -1,6 +1,11 @@
1
- import { type FieldConfig, type FieldElement, type FieldValue, type FieldsetConstraint, type ListCommand, type Primitive, type Submission } from '@conform-to/dom';
1
+ import { type FieldConfig, type FieldElement, type FieldValue, type FieldsetConstraint, type Primitive, type Submission } from '@conform-to/dom';
2
2
  import { type InputHTMLAttributes, type FormEvent, type RefObject } from 'react';
3
3
  export interface FormConfig<Schema extends Record<string, any>> {
4
+ /**
5
+ * If the form id is provided, Id for label,
6
+ * input and error elements will be derived.
7
+ */
8
+ id?: string;
4
9
  /**
5
10
  * Validation mode. Default to `client-only`.
6
11
  */
@@ -20,6 +25,10 @@ export interface FormConfig<Schema extends Record<string, any>> {
20
25
  * An object describing the state from the last submission
21
26
  */
22
27
  state?: Submission<Schema>;
28
+ /**
29
+ * An object describing the constraint of each field
30
+ */
31
+ constraint?: FieldsetConstraint<Schema>;
23
32
  /**
24
33
  * Enable native validation before hydation.
25
34
  *
@@ -53,10 +62,12 @@ export interface FormConfig<Schema extends Record<string, any>> {
53
62
  */
54
63
  interface FormProps {
55
64
  ref: RefObject<HTMLFormElement>;
65
+ id?: string;
56
66
  onSubmit: (event: FormEvent<HTMLFormElement>) => void;
57
67
  noValidate: boolean;
58
68
  }
59
69
  interface Form<Schema extends Record<string, any>> {
70
+ id?: string;
60
71
  ref: RefObject<HTMLFormElement>;
61
72
  error: string;
62
73
  props: FormProps;
@@ -66,9 +77,9 @@ interface Form<Schema extends Record<string, any>> {
66
77
  * Returns properties required to hook into form events.
67
78
  * Applied custom validation and define when error should be reported.
68
79
  *
69
- * @see https://github.com/edmundhung/conform/tree/v0.4.1/packages/conform-react/README.md#useform
80
+ * @see https://conform.guide/api/react#useform
70
81
  */
71
- export declare function useForm<Schema extends Record<string, any>>(config?: FormConfig<Schema>): Form<Schema>;
82
+ export declare function useForm<Schema extends Record<string, any>>(config?: FormConfig<Schema>): [Form<Schema>, Fieldset<Schema>];
72
83
  /**
73
84
  * All the information of the field, including state and config.
74
85
  */
@@ -107,43 +118,25 @@ export interface FieldsetConfig<Schema extends Record<string, any>> {
107
118
  /**
108
119
  * Returns all the information about the fieldset.
109
120
  *
110
- * @see https://github.com/edmundhung/conform/tree/v0.4.1/packages/conform-react/README.md#usefieldset
121
+ * @see https://conform.guide/api/react#usefieldset
111
122
  */
112
123
  export declare function useFieldset<Schema extends Record<string, any>>(ref: RefObject<HTMLFormElement | HTMLFieldSetElement>, config: FieldsetConfig<Schema>): Fieldset<Schema>;
113
124
  export declare function useFieldset<Schema extends Record<string, any>>(ref: RefObject<HTMLFormElement | HTMLFieldSetElement>, config: FieldConfig<Schema>): Fieldset<Schema>;
114
- interface CommandButtonProps {
115
- name?: string;
116
- value?: string;
117
- form?: string;
118
- formNoValidate: true;
119
- }
120
- declare type ListCommandPayload<Schema, Type extends ListCommand<FieldValue<Schema>>['type']> = Extract<ListCommand<FieldValue<Schema>>, {
121
- type: Type;
122
- }>['payload'];
123
125
  /**
124
126
  * Returns a list of key and config, with a group of helpers
125
127
  * configuring buttons for list manipulation
126
128
  *
127
- * @see https://github.com/edmundhung/conform/tree/v0.4.1/packages/conform-react/README.md#usefieldlist
129
+ * @see https://conform.guide/api/react#usefieldlist
128
130
  */
129
- export declare function useFieldList<Payload = any>(ref: RefObject<HTMLFormElement | HTMLFieldSetElement>, config: FieldConfig<Array<Payload>>): [
130
- Array<{
131
- key: string;
132
- error: string | undefined;
133
- config: FieldConfig<Payload>;
134
- }>,
135
- {
136
- prepend(payload?: ListCommandPayload<Payload, 'prepend'>): CommandButtonProps;
137
- append(payload?: ListCommandPayload<Payload, 'append'>): CommandButtonProps;
138
- replace(payload: ListCommandPayload<Payload, 'replace'>): CommandButtonProps;
139
- remove(payload: ListCommandPayload<Payload, 'remove'>): CommandButtonProps;
140
- reorder(payload: ListCommandPayload<Payload, 'reorder'>): CommandButtonProps;
141
- }
142
- ];
131
+ export declare function useFieldList<Payload = any>(ref: RefObject<HTMLFormElement | HTMLFieldSetElement>, config: FieldConfig<Array<Payload>>): Array<{
132
+ key: string;
133
+ error: string | undefined;
134
+ config: FieldConfig<Payload>;
135
+ }>;
143
136
  interface ShadowInputProps extends InputHTMLAttributes<HTMLInputElement> {
144
137
  ref: RefObject<HTMLInputElement>;
145
138
  }
146
- interface InputControl<Element extends {
139
+ interface LegacyInputControl<Element extends {
147
140
  focus: () => void;
148
141
  }> {
149
142
  ref: RefObject<Element>;
@@ -161,9 +154,33 @@ interface InputControl<Element extends {
161
154
  * This is particular useful when integrating dropdown and datepicker whichs
162
155
  * introduces custom input mode.
163
156
  *
164
- * @see https://github.com/edmundhung/conform/tree/v0.4.1/packages/conform-react/README.md#usecontrolledinput
157
+ * @deprecated Please use the `useInputEvent` hook instead
158
+ * @see https://conform.guide/api/react#usecontrolledinput
165
159
  */
166
160
  export declare function useControlledInput<Element extends {
167
161
  focus: () => void;
168
- } = HTMLInputElement, Schema extends Primitive = Primitive>(config: FieldConfig<Schema>): [ShadowInputProps, InputControl<Element>];
162
+ } = HTMLInputElement, Schema extends Primitive = Primitive>(config: FieldConfig<Schema>): [ShadowInputProps, LegacyInputControl<Element>];
163
+ interface InputControl {
164
+ change: (eventOrValue: {
165
+ target: {
166
+ value: string;
167
+ };
168
+ } | string) => void;
169
+ focus: () => void;
170
+ blur: () => void;
171
+ }
172
+ /**
173
+ * Returns a ref object and a set of helpers that dispatch corresponding dom event.
174
+ *
175
+ * @see https://conform.guide/api/react#useinputevent
176
+ */
177
+ export declare function useInputEvent<RefShape extends FieldElement = HTMLInputElement>(options?: {
178
+ onSubmit?: (event: SubmitEvent) => void;
179
+ onReset?: (event: Event) => void;
180
+ }): [RefObject<RefShape>, InputControl];
181
+ export declare function useInputEvent<RefShape extends Exclude<any, FieldElement>>(options: {
182
+ getElement: (ref: RefShape | null) => FieldElement | null | undefined;
183
+ onSubmit?: (event: SubmitEvent) => void;
184
+ onReset?: (event: Event) => void;
185
+ }): [RefObject<RefShape>, InputControl];
169
186
  export {};