@conform-to/react 1.0.0-rc.1 → 1.0.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/README +16 -11
- package/context.d.ts +2 -3
- package/context.js +19 -5
- package/context.mjs +19 -5
- package/helpers.js +13 -17
- package/helpers.mjs +13 -17
- package/integrations.d.ts +12 -10
- package/integrations.js +149 -74
- package/integrations.mjs +145 -74
- package/package.json +2 -2
package/README
CHANGED
|
@@ -8,25 +8,30 @@
|
|
|
8
8
|
╚══════╝ ╚═════╝ ╚═╝ ╚══╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
Version 1.0.
|
|
11
|
+
Version 1.0.1 / License MIT / Copyright (c) 2024 Edmund Hung
|
|
12
12
|
|
|
13
13
|
A type-safe form validation library utilizing web fundamentals to progressively enhance HTML Forms with full support for server frameworks like Remix and Next.js.
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
# Getting Started
|
|
16
16
|
|
|
17
17
|
Check out the overview and tutorial at our website https://conform.guide
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
# Features
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
- Progressive enhancement first APIs
|
|
22
|
+
- Type-safe field inference
|
|
23
|
+
- Fine-grained subscription
|
|
24
|
+
- Built-in accessibility helpers
|
|
25
|
+
- Automatic type coercion with Zod
|
|
22
26
|
|
|
23
|
-
|
|
24
|
-
* Examples: https://conform.guide/examples
|
|
25
|
-
* Complex structures: https://conform.guide/complex-structures
|
|
26
|
-
* UI Integrations: https://conform.guide/integrations
|
|
27
|
-
* Accessibility Guide: https://conform.guide/accessibility
|
|
28
|
-
* API Reference: https://conform.guide/references
|
|
27
|
+
# Documentation
|
|
29
28
|
|
|
30
|
-
|
|
29
|
+
- Validation: https://conform.guide/validation
|
|
30
|
+
- Nested object and Array: https://conform.guide/complex-structures
|
|
31
|
+
- UI Integrations: https://conform.guide/integration/ui-libraries
|
|
32
|
+
- Intent button: https://conform.guide/intent-button
|
|
33
|
+
- Accessibility Guide: https://conform.guide/accessibility
|
|
34
|
+
|
|
35
|
+
# Support
|
|
31
36
|
|
|
32
37
|
To report a bug, please open an issue on the repository at https://github.com/edmundhung/conform. For feature requests and questions, you can post them in the Discussions section.
|
package/context.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { type FormEvent, type ReactElement, type ReactNode, type MutableRefObjec
|
|
|
3
3
|
export type Pretty<T> = {
|
|
4
4
|
[K in keyof T]: T[K];
|
|
5
5
|
} & {};
|
|
6
|
-
export type Primitive = string | number | boolean | Date | File | null | undefined;
|
|
6
|
+
export type Primitive = string | number | bigint | boolean | Date | File | null | undefined;
|
|
7
7
|
export type Metadata<Schema, FormSchema extends Record<string, unknown>, FormError = string[]> = {
|
|
8
8
|
key: string | undefined;
|
|
9
9
|
id: string;
|
|
@@ -27,9 +27,8 @@ export type FormMetadata<Schema extends Record<string, unknown> = Record<string,
|
|
|
27
27
|
onSubmit: (event: React.FormEvent<HTMLFormElement>) => void;
|
|
28
28
|
noValidate: boolean;
|
|
29
29
|
};
|
|
30
|
-
export type FieldMetadata<Schema = unknown, FormSchema extends Record<string, any> = Record<string, unknown>, FormError = string[]> = Metadata<Schema, FormSchema, FormError> & {
|
|
30
|
+
export type FieldMetadata<Schema = unknown, FormSchema extends Record<string, any> = Record<string, unknown>, FormError = string[]> = Metadata<Schema, FormSchema, FormError> & Constraint & {
|
|
31
31
|
formId: FormId<FormSchema, FormError>;
|
|
32
|
-
constraint?: Constraint;
|
|
33
32
|
getFieldset: unknown extends Schema ? () => unknown : Schema extends Primitive | Array<any> ? never : () => {
|
|
34
33
|
[Key in UnionKeyof<Schema>]: FieldMetadata<UnionKeyType<Schema, Key>, FormSchema, FormError>;
|
|
35
34
|
};
|
package/context.js
CHANGED
|
@@ -74,9 +74,15 @@ function getMetadata(formId, state, subjectRef) {
|
|
|
74
74
|
name,
|
|
75
75
|
errorId: "".concat(id, "-error"),
|
|
76
76
|
descriptionId: "".concat(id, "-description"),
|
|
77
|
-
initialValue
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
get initialValue() {
|
|
78
|
+
return state.initialValue[name];
|
|
79
|
+
},
|
|
80
|
+
get value() {
|
|
81
|
+
return state.value[name];
|
|
82
|
+
},
|
|
83
|
+
get errors() {
|
|
84
|
+
return state.error[name];
|
|
85
|
+
},
|
|
80
86
|
get key() {
|
|
81
87
|
return state.key[name];
|
|
82
88
|
},
|
|
@@ -134,11 +140,19 @@ function getFieldMetadata(formId, state, subjectRef) {
|
|
|
134
140
|
var metadata = getMetadata(formId, state, subjectRef, name);
|
|
135
141
|
return new Proxy({}, {
|
|
136
142
|
get(_, key, receiver) {
|
|
143
|
+
var _state$constraint$nam;
|
|
137
144
|
switch (key) {
|
|
138
145
|
case 'formId':
|
|
139
146
|
return formId;
|
|
140
|
-
case '
|
|
141
|
-
|
|
147
|
+
case 'required':
|
|
148
|
+
case 'minLength':
|
|
149
|
+
case 'maxLength':
|
|
150
|
+
case 'min':
|
|
151
|
+
case 'max':
|
|
152
|
+
case 'pattern':
|
|
153
|
+
case 'step':
|
|
154
|
+
case 'multiple':
|
|
155
|
+
return (_state$constraint$nam = state.constraint[name]) === null || _state$constraint$nam === void 0 ? void 0 : _state$constraint$nam[key];
|
|
142
156
|
case 'getFieldList':
|
|
143
157
|
{
|
|
144
158
|
return () => {
|
package/context.mjs
CHANGED
|
@@ -70,9 +70,15 @@ function getMetadata(formId, state, subjectRef) {
|
|
|
70
70
|
name,
|
|
71
71
|
errorId: "".concat(id, "-error"),
|
|
72
72
|
descriptionId: "".concat(id, "-description"),
|
|
73
|
-
initialValue
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
get initialValue() {
|
|
74
|
+
return state.initialValue[name];
|
|
75
|
+
},
|
|
76
|
+
get value() {
|
|
77
|
+
return state.value[name];
|
|
78
|
+
},
|
|
79
|
+
get errors() {
|
|
80
|
+
return state.error[name];
|
|
81
|
+
},
|
|
76
82
|
get key() {
|
|
77
83
|
return state.key[name];
|
|
78
84
|
},
|
|
@@ -130,11 +136,19 @@ function getFieldMetadata(formId, state, subjectRef) {
|
|
|
130
136
|
var metadata = getMetadata(formId, state, subjectRef, name);
|
|
131
137
|
return new Proxy({}, {
|
|
132
138
|
get(_, key, receiver) {
|
|
139
|
+
var _state$constraint$nam;
|
|
133
140
|
switch (key) {
|
|
134
141
|
case 'formId':
|
|
135
142
|
return formId;
|
|
136
|
-
case '
|
|
137
|
-
|
|
143
|
+
case 'required':
|
|
144
|
+
case 'minLength':
|
|
145
|
+
case 'maxLength':
|
|
146
|
+
case 'min':
|
|
147
|
+
case 'max':
|
|
148
|
+
case 'pattern':
|
|
149
|
+
case 'step':
|
|
150
|
+
case 'multiple':
|
|
151
|
+
return (_state$constraint$nam = state.constraint[name]) === null || _state$constraint$nam === void 0 ? void 0 : _state$constraint$nam[key];
|
|
138
152
|
case 'getFieldList':
|
|
139
153
|
{
|
|
140
154
|
return () => {
|
package/helpers.js
CHANGED
|
@@ -72,10 +72,9 @@ function getFieldsetProps(metadata, options) {
|
|
|
72
72
|
* including `key`, `id`, `name`, `form`, `required`, `autoFocus`, `aria-invalid` and `aria-describedby`.
|
|
73
73
|
*/
|
|
74
74
|
function getFormControlProps(metadata, options) {
|
|
75
|
-
var _metadata$constraint;
|
|
76
75
|
return simplify(_rollupPluginBabelHelpers.objectSpread2({
|
|
77
76
|
key: metadata.key,
|
|
78
|
-
required:
|
|
77
|
+
required: metadata.required || undefined
|
|
79
78
|
}, getFieldsetProps(metadata, options)));
|
|
80
79
|
}
|
|
81
80
|
|
|
@@ -100,16 +99,15 @@ function getFormControlProps(metadata, options) {
|
|
|
100
99
|
* ```
|
|
101
100
|
*/
|
|
102
101
|
function getInputProps(metadata, options) {
|
|
103
|
-
var _metadata$constraint2, _metadata$constraint3, _metadata$constraint4, _metadata$constraint5, _metadata$constraint6, _metadata$constraint7, _metadata$constraint8;
|
|
104
102
|
var props = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormControlProps(metadata, options)), {}, {
|
|
105
103
|
type: options.type,
|
|
106
|
-
minLength:
|
|
107
|
-
maxLength:
|
|
108
|
-
min:
|
|
109
|
-
max:
|
|
110
|
-
step:
|
|
111
|
-
pattern:
|
|
112
|
-
multiple:
|
|
104
|
+
minLength: metadata.minLength,
|
|
105
|
+
maxLength: metadata.maxLength,
|
|
106
|
+
min: metadata.min,
|
|
107
|
+
max: metadata.max,
|
|
108
|
+
step: metadata.step,
|
|
109
|
+
pattern: metadata.pattern,
|
|
110
|
+
multiple: metadata.multiple
|
|
113
111
|
});
|
|
114
112
|
if (typeof options.value === 'undefined' || options.value) {
|
|
115
113
|
if (options.type === 'checkbox' || options.type === 'radio') {
|
|
@@ -138,10 +136,9 @@ function getInputProps(metadata, options) {
|
|
|
138
136
|
* ```
|
|
139
137
|
*/
|
|
140
138
|
function getSelectProps(metadata) {
|
|
141
|
-
var _metadata$constraint9;
|
|
142
139
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
143
140
|
var props = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormControlProps(metadata, options)), {}, {
|
|
144
|
-
multiple:
|
|
141
|
+
multiple: metadata.multiple
|
|
145
142
|
});
|
|
146
143
|
if (typeof options.value === 'undefined' || options.value) {
|
|
147
144
|
props.defaultValue = Array.isArray(metadata.initialValue) ? metadata.initialValue.map(item => "".concat(item !== null && item !== void 0 ? item : '')) : metadata.initialValue;
|
|
@@ -165,11 +162,10 @@ function getSelectProps(metadata) {
|
|
|
165
162
|
* ```
|
|
166
163
|
*/
|
|
167
164
|
function getTextareaProps(metadata) {
|
|
168
|
-
var _metadata$constraint10, _metadata$constraint11;
|
|
169
165
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
170
166
|
var props = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormControlProps(metadata, options)), {}, {
|
|
171
|
-
minLength:
|
|
172
|
-
maxLength:
|
|
167
|
+
minLength: metadata.minLength,
|
|
168
|
+
maxLength: metadata.maxLength
|
|
173
169
|
});
|
|
174
170
|
if (typeof options.value === 'undefined' || options.value) {
|
|
175
171
|
props.defaultValue = metadata.initialValue;
|
|
@@ -199,7 +195,7 @@ function getTextareaProps(metadata) {
|
|
|
199
195
|
*/
|
|
200
196
|
function getCollectionProps(metadata, options) {
|
|
201
197
|
return options.options.map(value => {
|
|
202
|
-
var _metadata$key
|
|
198
|
+
var _metadata$key;
|
|
203
199
|
return simplify(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormControlProps(metadata, options)), {}, {
|
|
204
200
|
key: "".concat((_metadata$key = metadata.key) !== null && _metadata$key !== void 0 ? _metadata$key : '').concat(value),
|
|
205
201
|
id: "".concat(metadata.id, "-").concat(value),
|
|
@@ -209,7 +205,7 @@ function getCollectionProps(metadata, options) {
|
|
|
209
205
|
// The required attribute doesn't make sense for checkbox group
|
|
210
206
|
// As it would require all checkboxes to be checked instead of at least one
|
|
211
207
|
// It is overriden with `undefiend` so it could be cleaned up properly
|
|
212
|
-
required: options.type === 'checkbox' ? undefined :
|
|
208
|
+
required: options.type === 'checkbox' ? undefined : metadata.required
|
|
213
209
|
}));
|
|
214
210
|
});
|
|
215
211
|
}
|
package/helpers.mjs
CHANGED
|
@@ -68,10 +68,9 @@ function getFieldsetProps(metadata, options) {
|
|
|
68
68
|
* including `key`, `id`, `name`, `form`, `required`, `autoFocus`, `aria-invalid` and `aria-describedby`.
|
|
69
69
|
*/
|
|
70
70
|
function getFormControlProps(metadata, options) {
|
|
71
|
-
var _metadata$constraint;
|
|
72
71
|
return simplify(_objectSpread2({
|
|
73
72
|
key: metadata.key,
|
|
74
|
-
required:
|
|
73
|
+
required: metadata.required || undefined
|
|
75
74
|
}, getFieldsetProps(metadata, options)));
|
|
76
75
|
}
|
|
77
76
|
|
|
@@ -96,16 +95,15 @@ function getFormControlProps(metadata, options) {
|
|
|
96
95
|
* ```
|
|
97
96
|
*/
|
|
98
97
|
function getInputProps(metadata, options) {
|
|
99
|
-
var _metadata$constraint2, _metadata$constraint3, _metadata$constraint4, _metadata$constraint5, _metadata$constraint6, _metadata$constraint7, _metadata$constraint8;
|
|
100
98
|
var props = _objectSpread2(_objectSpread2({}, getFormControlProps(metadata, options)), {}, {
|
|
101
99
|
type: options.type,
|
|
102
|
-
minLength:
|
|
103
|
-
maxLength:
|
|
104
|
-
min:
|
|
105
|
-
max:
|
|
106
|
-
step:
|
|
107
|
-
pattern:
|
|
108
|
-
multiple:
|
|
100
|
+
minLength: metadata.minLength,
|
|
101
|
+
maxLength: metadata.maxLength,
|
|
102
|
+
min: metadata.min,
|
|
103
|
+
max: metadata.max,
|
|
104
|
+
step: metadata.step,
|
|
105
|
+
pattern: metadata.pattern,
|
|
106
|
+
multiple: metadata.multiple
|
|
109
107
|
});
|
|
110
108
|
if (typeof options.value === 'undefined' || options.value) {
|
|
111
109
|
if (options.type === 'checkbox' || options.type === 'radio') {
|
|
@@ -134,10 +132,9 @@ function getInputProps(metadata, options) {
|
|
|
134
132
|
* ```
|
|
135
133
|
*/
|
|
136
134
|
function getSelectProps(metadata) {
|
|
137
|
-
var _metadata$constraint9;
|
|
138
135
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
139
136
|
var props = _objectSpread2(_objectSpread2({}, getFormControlProps(metadata, options)), {}, {
|
|
140
|
-
multiple:
|
|
137
|
+
multiple: metadata.multiple
|
|
141
138
|
});
|
|
142
139
|
if (typeof options.value === 'undefined' || options.value) {
|
|
143
140
|
props.defaultValue = Array.isArray(metadata.initialValue) ? metadata.initialValue.map(item => "".concat(item !== null && item !== void 0 ? item : '')) : metadata.initialValue;
|
|
@@ -161,11 +158,10 @@ function getSelectProps(metadata) {
|
|
|
161
158
|
* ```
|
|
162
159
|
*/
|
|
163
160
|
function getTextareaProps(metadata) {
|
|
164
|
-
var _metadata$constraint10, _metadata$constraint11;
|
|
165
161
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
166
162
|
var props = _objectSpread2(_objectSpread2({}, getFormControlProps(metadata, options)), {}, {
|
|
167
|
-
minLength:
|
|
168
|
-
maxLength:
|
|
163
|
+
minLength: metadata.minLength,
|
|
164
|
+
maxLength: metadata.maxLength
|
|
169
165
|
});
|
|
170
166
|
if (typeof options.value === 'undefined' || options.value) {
|
|
171
167
|
props.defaultValue = metadata.initialValue;
|
|
@@ -195,7 +191,7 @@ function getTextareaProps(metadata) {
|
|
|
195
191
|
*/
|
|
196
192
|
function getCollectionProps(metadata, options) {
|
|
197
193
|
return options.options.map(value => {
|
|
198
|
-
var _metadata$key
|
|
194
|
+
var _metadata$key;
|
|
199
195
|
return simplify(_objectSpread2(_objectSpread2({}, getFormControlProps(metadata, options)), {}, {
|
|
200
196
|
key: "".concat((_metadata$key = metadata.key) !== null && _metadata$key !== void 0 ? _metadata$key : '').concat(value),
|
|
201
197
|
id: "".concat(metadata.id, "-").concat(value),
|
|
@@ -205,7 +201,7 @@ function getCollectionProps(metadata, options) {
|
|
|
205
201
|
// The required attribute doesn't make sense for checkbox group
|
|
206
202
|
// As it would require all checkboxes to be checked instead of at least one
|
|
207
203
|
// It is overriden with `undefiend` so it could be cleaned up properly
|
|
208
|
-
required: options.type === 'checkbox' ? undefined :
|
|
204
|
+
required: options.type === 'checkbox' ? undefined : metadata.required
|
|
209
205
|
}));
|
|
210
206
|
});
|
|
211
207
|
}
|
package/integrations.d.ts
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import { type FieldElement } from '@conform-to/dom';
|
|
2
1
|
import { type Key } from 'react';
|
|
3
|
-
export type InputControl = {
|
|
4
|
-
value:
|
|
5
|
-
change: (value:
|
|
2
|
+
export type InputControl<Value> = {
|
|
3
|
+
value: Value | undefined;
|
|
4
|
+
change: (value: Value) => void;
|
|
6
5
|
focus: () => void;
|
|
7
6
|
blur: () => void;
|
|
8
7
|
};
|
|
9
|
-
export declare function
|
|
10
|
-
export declare function
|
|
11
|
-
export
|
|
8
|
+
export declare function getFormElement(formId: string): HTMLFormElement;
|
|
9
|
+
export declare function getFieldElements(form: HTMLFormElement, name: string): Array<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>;
|
|
10
|
+
export declare function getEventTarget(form: HTMLFormElement, name: string): HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | null;
|
|
11
|
+
export declare function createDummySelect(form: HTMLFormElement, name: string, value?: string | string[] | undefined): HTMLSelectElement;
|
|
12
|
+
export declare function isDummySelect(element: HTMLElement): element is HTMLSelectElement;
|
|
13
|
+
export declare function updateFieldValue(element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement, value: string | string[]): void;
|
|
14
|
+
export declare function useInputControl<Value>(metaOrOptions: {
|
|
12
15
|
key?: Key | null | undefined;
|
|
13
16
|
name: string;
|
|
14
17
|
formId: string;
|
|
15
|
-
initialValue?:
|
|
16
|
-
}
|
|
17
|
-
export declare function useInputControl(metaOrOptions: InputControlOptions): InputControl;
|
|
18
|
+
initialValue?: Value | undefined;
|
|
19
|
+
}): InputControl<Value extends string ? string : string | string[]>;
|
package/integrations.js
CHANGED
|
@@ -3,52 +3,141 @@
|
|
|
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
|
var react = require('react');
|
|
8
7
|
|
|
9
|
-
function
|
|
10
|
-
var
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
8
|
+
function getFormElement(formId) {
|
|
9
|
+
var element = document.forms.namedItem(formId);
|
|
10
|
+
if (!element) {
|
|
11
|
+
throw new Error('Form not found');
|
|
12
|
+
}
|
|
13
|
+
return element;
|
|
14
|
+
}
|
|
15
|
+
function getFieldElements(form, name) {
|
|
16
|
+
var field = form.elements.namedItem(name);
|
|
17
|
+
var elements = !field ? [] : field instanceof Element ? [field] : Array.from(field.values());
|
|
18
|
+
return elements.filter(element => element instanceof HTMLInputElement || element instanceof HTMLSelectElement || element instanceof HTMLTextAreaElement);
|
|
19
|
+
}
|
|
20
|
+
function getEventTarget(form, name) {
|
|
21
|
+
var _elements$;
|
|
22
|
+
var elements = getFieldElements(form, name);
|
|
23
|
+
return (_elements$ = elements[0]) !== null && _elements$ !== void 0 ? _elements$ : null;
|
|
24
|
+
}
|
|
25
|
+
function createDummySelect(form, name, value) {
|
|
26
|
+
var select = document.createElement('select');
|
|
27
|
+
var options = typeof value === 'string' ? [value] : value !== null && value !== void 0 ? value : [];
|
|
28
|
+
select.name = name;
|
|
29
|
+
select.multiple = true;
|
|
30
|
+
select.dataset.conform = 'true';
|
|
31
|
+
|
|
32
|
+
// To make sure the input is hidden but still focusable
|
|
33
|
+
select.setAttribute('aria-hidden', 'true');
|
|
34
|
+
select.tabIndex = -1;
|
|
35
|
+
select.style.position = 'absolute';
|
|
36
|
+
select.style.width = '1px';
|
|
37
|
+
select.style.height = '1px';
|
|
38
|
+
select.style.padding = '0';
|
|
39
|
+
select.style.margin = '-1px';
|
|
40
|
+
select.style.overflow = 'hidden';
|
|
41
|
+
select.style.clip = 'rect(0,0,0,0)';
|
|
42
|
+
select.style.whiteSpace = 'nowrap';
|
|
43
|
+
select.style.border = '0';
|
|
44
|
+
for (var option of options) {
|
|
45
|
+
select.options.add(new Option(option, option, true, true));
|
|
20
46
|
}
|
|
21
|
-
|
|
47
|
+
form.appendChild(select);
|
|
48
|
+
return select;
|
|
22
49
|
}
|
|
23
|
-
function
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
50
|
+
function isDummySelect(element) {
|
|
51
|
+
return element.dataset.conform === 'true';
|
|
52
|
+
}
|
|
53
|
+
function updateFieldValue(element, value) {
|
|
54
|
+
if (element instanceof HTMLInputElement && (element.type === 'checkbox' || element.type === 'radio')) {
|
|
55
|
+
element.checked = element.value === value;
|
|
56
|
+
} else if (element instanceof HTMLSelectElement && element.multiple) {
|
|
57
|
+
var selectedValue = Array.isArray(value) ? [...value] : [value];
|
|
58
|
+
for (var option of element.options) {
|
|
59
|
+
var index = selectedValue.indexOf(option.value);
|
|
60
|
+
var selected = index > -1;
|
|
61
|
+
|
|
62
|
+
// Update the selected state of the option
|
|
63
|
+
option.selected = selected;
|
|
64
|
+
// Remove the option from the selected array
|
|
65
|
+
if (selected) {
|
|
66
|
+
selectedValue.splice(index, 1);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Add the remaining options to the select element only if it's a dummy element managed by conform
|
|
71
|
+
if (isDummySelect(element)) {
|
|
72
|
+
for (var _option of selectedValue) {
|
|
73
|
+
element.options.add(new Option(_option, _option, false, true));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
} else if (element.value !== value) {
|
|
77
|
+
// No `change` event will be triggered on React if `element.value` is already updated
|
|
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);
|
|
97
|
+
} else {
|
|
98
|
+
throw new Error('The given element does not have a value setter');
|
|
99
|
+
}
|
|
100
|
+
}
|
|
27
101
|
}
|
|
28
|
-
var form = document.forms.namedItem(formId);
|
|
29
|
-
var input = document.createElement('input');
|
|
30
|
-
input.type = 'hidden';
|
|
31
|
-
input.name = name;
|
|
32
|
-
form === null || form === void 0 || form.appendChild(input);
|
|
33
|
-
return input;
|
|
34
102
|
}
|
|
35
103
|
function useInputControl(metaOrOptions) {
|
|
104
|
+
// If the initialValue is an array, it must be a string array without undefined values
|
|
105
|
+
// as there is no way to skip an entry in a multiple select when they all share the same name
|
|
106
|
+
var inputInitialValue = metaOrOptions.initialValue;
|
|
36
107
|
var eventDispatched = react.useRef({
|
|
37
108
|
change: false,
|
|
38
109
|
focus: false,
|
|
39
110
|
blur: false
|
|
40
111
|
});
|
|
41
112
|
var [key, setKey] = react.useState(metaOrOptions.key);
|
|
42
|
-
var [
|
|
113
|
+
var [initialValue, setInitialValue] = react.useState(inputInitialValue);
|
|
114
|
+
var [value, setValue] = react.useState(inputInitialValue);
|
|
43
115
|
if (key !== metaOrOptions.key) {
|
|
44
|
-
setValue(
|
|
116
|
+
setValue(inputInitialValue);
|
|
117
|
+
setInitialValue(inputInitialValue);
|
|
45
118
|
setKey(metaOrOptions.key);
|
|
46
119
|
}
|
|
120
|
+
react.useEffect(() => {
|
|
121
|
+
var form = getFormElement(metaOrOptions.formId);
|
|
122
|
+
if (getEventTarget(form, metaOrOptions.name)) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
createDummySelect(form, metaOrOptions.name, initialValue);
|
|
126
|
+
return () => {
|
|
127
|
+
var elements = getFieldElements(form, metaOrOptions.name);
|
|
128
|
+
for (var element of elements) {
|
|
129
|
+
if (isDummySelect(element)) {
|
|
130
|
+
element.remove();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
}, [metaOrOptions.formId, metaOrOptions.name, initialValue]);
|
|
47
135
|
react.useEffect(() => {
|
|
48
136
|
var createEventListener = listener => {
|
|
49
137
|
return event => {
|
|
50
|
-
var
|
|
51
|
-
|
|
138
|
+
var _element$form;
|
|
139
|
+
var element = event.target;
|
|
140
|
+
if ((element instanceof HTMLInputElement || element instanceof HTMLSelectElement || element instanceof HTMLTextAreaElement) && element.name === metaOrOptions.name && ((_element$form = element.form) === null || _element$form === void 0 ? void 0 : _element$form.id) === metaOrOptions.formId) {
|
|
52
141
|
eventDispatched.current[listener] = true;
|
|
53
142
|
}
|
|
54
143
|
};
|
|
@@ -69,68 +158,50 @@ function useInputControl(metaOrOptions) {
|
|
|
69
158
|
return {
|
|
70
159
|
change(value) {
|
|
71
160
|
if (!eventDispatched.current.change) {
|
|
72
|
-
var _element = getEventTarget(metaOrOptions.formId, metaOrOptions.name);
|
|
73
161
|
eventDispatched.current.change = true;
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
162
|
+
var form = getFormElement(metaOrOptions.formId);
|
|
163
|
+
var element = getEventTarget(form, metaOrOptions.name);
|
|
164
|
+
if (element) {
|
|
165
|
+
updateFieldValue(element, value);
|
|
78
166
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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);
|
|
97
|
-
} else {
|
|
98
|
-
throw new Error('The given element does not have a value setter');
|
|
99
|
-
}
|
|
100
|
-
}
|
|
167
|
+
// Dispatch input event with the updated input value
|
|
168
|
+
element.dispatchEvent(new InputEvent('input', {
|
|
169
|
+
bubbles: true
|
|
170
|
+
}));
|
|
171
|
+
// Dispatch change event (necessary for select to update the selected option)
|
|
172
|
+
element.dispatchEvent(new Event('change', {
|
|
173
|
+
bubbles: true
|
|
174
|
+
}));
|
|
101
175
|
}
|
|
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
|
-
}));
|
|
111
176
|
}
|
|
112
177
|
setValue(value);
|
|
113
178
|
eventDispatched.current.change = false;
|
|
114
179
|
},
|
|
115
180
|
focus() {
|
|
116
181
|
if (!eventDispatched.current.focus) {
|
|
117
|
-
var _element2 = getEventTarget(metaOrOptions.formId, metaOrOptions.name);
|
|
118
182
|
eventDispatched.current.focus = true;
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
183
|
+
var form = getFormElement(metaOrOptions.formId);
|
|
184
|
+
var element = getEventTarget(form, metaOrOptions.name);
|
|
185
|
+
if (element) {
|
|
186
|
+
element.dispatchEvent(new FocusEvent('focusin', {
|
|
187
|
+
bubbles: true
|
|
188
|
+
}));
|
|
189
|
+
element.dispatchEvent(new FocusEvent('focus'));
|
|
190
|
+
}
|
|
123
191
|
}
|
|
124
192
|
eventDispatched.current.focus = false;
|
|
125
193
|
},
|
|
126
194
|
blur() {
|
|
127
195
|
if (!eventDispatched.current.blur) {
|
|
128
|
-
var _element3 = getEventTarget(metaOrOptions.formId, metaOrOptions.name);
|
|
129
196
|
eventDispatched.current.blur = true;
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
197
|
+
var form = getFormElement(metaOrOptions.formId);
|
|
198
|
+
var element = getEventTarget(form, metaOrOptions.name);
|
|
199
|
+
if (element) {
|
|
200
|
+
element.dispatchEvent(new FocusEvent('focusout', {
|
|
201
|
+
bubbles: true
|
|
202
|
+
}));
|
|
203
|
+
element.dispatchEvent(new FocusEvent('blur'));
|
|
204
|
+
}
|
|
134
205
|
}
|
|
135
206
|
eventDispatched.current.blur = false;
|
|
136
207
|
}
|
|
@@ -141,6 +212,10 @@ function useInputControl(metaOrOptions) {
|
|
|
141
212
|
});
|
|
142
213
|
}
|
|
143
214
|
|
|
215
|
+
exports.createDummySelect = createDummySelect;
|
|
144
216
|
exports.getEventTarget = getEventTarget;
|
|
145
|
-
exports.
|
|
217
|
+
exports.getFieldElements = getFieldElements;
|
|
218
|
+
exports.getFormElement = getFormElement;
|
|
219
|
+
exports.isDummySelect = isDummySelect;
|
|
220
|
+
exports.updateFieldValue = updateFieldValue;
|
|
146
221
|
exports.useInputControl = useInputControl;
|
package/integrations.mjs
CHANGED
|
@@ -1,50 +1,139 @@
|
|
|
1
1
|
import { objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.mjs';
|
|
2
|
-
import { isFieldElement } from '@conform-to/dom';
|
|
3
2
|
import { useRef, useState, useEffect, useMemo } from 'react';
|
|
4
3
|
|
|
5
|
-
function
|
|
6
|
-
var
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
4
|
+
function getFormElement(formId) {
|
|
5
|
+
var element = document.forms.namedItem(formId);
|
|
6
|
+
if (!element) {
|
|
7
|
+
throw new Error('Form not found');
|
|
8
|
+
}
|
|
9
|
+
return element;
|
|
10
|
+
}
|
|
11
|
+
function getFieldElements(form, name) {
|
|
12
|
+
var field = form.elements.namedItem(name);
|
|
13
|
+
var elements = !field ? [] : field instanceof Element ? [field] : Array.from(field.values());
|
|
14
|
+
return elements.filter(element => element instanceof HTMLInputElement || element instanceof HTMLSelectElement || element instanceof HTMLTextAreaElement);
|
|
15
|
+
}
|
|
16
|
+
function getEventTarget(form, name) {
|
|
17
|
+
var _elements$;
|
|
18
|
+
var elements = getFieldElements(form, name);
|
|
19
|
+
return (_elements$ = elements[0]) !== null && _elements$ !== void 0 ? _elements$ : null;
|
|
20
|
+
}
|
|
21
|
+
function createDummySelect(form, name, value) {
|
|
22
|
+
var select = document.createElement('select');
|
|
23
|
+
var options = typeof value === 'string' ? [value] : value !== null && value !== void 0 ? value : [];
|
|
24
|
+
select.name = name;
|
|
25
|
+
select.multiple = true;
|
|
26
|
+
select.dataset.conform = 'true';
|
|
27
|
+
|
|
28
|
+
// To make sure the input is hidden but still focusable
|
|
29
|
+
select.setAttribute('aria-hidden', 'true');
|
|
30
|
+
select.tabIndex = -1;
|
|
31
|
+
select.style.position = 'absolute';
|
|
32
|
+
select.style.width = '1px';
|
|
33
|
+
select.style.height = '1px';
|
|
34
|
+
select.style.padding = '0';
|
|
35
|
+
select.style.margin = '-1px';
|
|
36
|
+
select.style.overflow = 'hidden';
|
|
37
|
+
select.style.clip = 'rect(0,0,0,0)';
|
|
38
|
+
select.style.whiteSpace = 'nowrap';
|
|
39
|
+
select.style.border = '0';
|
|
40
|
+
for (var option of options) {
|
|
41
|
+
select.options.add(new Option(option, option, true, true));
|
|
16
42
|
}
|
|
17
|
-
|
|
43
|
+
form.appendChild(select);
|
|
44
|
+
return select;
|
|
18
45
|
}
|
|
19
|
-
function
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
46
|
+
function isDummySelect(element) {
|
|
47
|
+
return element.dataset.conform === 'true';
|
|
48
|
+
}
|
|
49
|
+
function updateFieldValue(element, value) {
|
|
50
|
+
if (element instanceof HTMLInputElement && (element.type === 'checkbox' || element.type === 'radio')) {
|
|
51
|
+
element.checked = element.value === value;
|
|
52
|
+
} else if (element instanceof HTMLSelectElement && element.multiple) {
|
|
53
|
+
var selectedValue = Array.isArray(value) ? [...value] : [value];
|
|
54
|
+
for (var option of element.options) {
|
|
55
|
+
var index = selectedValue.indexOf(option.value);
|
|
56
|
+
var selected = index > -1;
|
|
57
|
+
|
|
58
|
+
// Update the selected state of the option
|
|
59
|
+
option.selected = selected;
|
|
60
|
+
// Remove the option from the selected array
|
|
61
|
+
if (selected) {
|
|
62
|
+
selectedValue.splice(index, 1);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Add the remaining options to the select element only if it's a dummy element managed by conform
|
|
67
|
+
if (isDummySelect(element)) {
|
|
68
|
+
for (var _option of selectedValue) {
|
|
69
|
+
element.options.add(new Option(_option, _option, false, true));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
} else if (element.value !== value) {
|
|
73
|
+
// No `change` event will be triggered on React if `element.value` is already updated
|
|
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);
|
|
93
|
+
} else {
|
|
94
|
+
throw new Error('The given element does not have a value setter');
|
|
95
|
+
}
|
|
96
|
+
}
|
|
23
97
|
}
|
|
24
|
-
var form = document.forms.namedItem(formId);
|
|
25
|
-
var input = document.createElement('input');
|
|
26
|
-
input.type = 'hidden';
|
|
27
|
-
input.name = name;
|
|
28
|
-
form === null || form === void 0 || form.appendChild(input);
|
|
29
|
-
return input;
|
|
30
98
|
}
|
|
31
99
|
function useInputControl(metaOrOptions) {
|
|
100
|
+
// If the initialValue is an array, it must be a string array without undefined values
|
|
101
|
+
// as there is no way to skip an entry in a multiple select when they all share the same name
|
|
102
|
+
var inputInitialValue = metaOrOptions.initialValue;
|
|
32
103
|
var eventDispatched = useRef({
|
|
33
104
|
change: false,
|
|
34
105
|
focus: false,
|
|
35
106
|
blur: false
|
|
36
107
|
});
|
|
37
108
|
var [key, setKey] = useState(metaOrOptions.key);
|
|
38
|
-
var [
|
|
109
|
+
var [initialValue, setInitialValue] = useState(inputInitialValue);
|
|
110
|
+
var [value, setValue] = useState(inputInitialValue);
|
|
39
111
|
if (key !== metaOrOptions.key) {
|
|
40
|
-
setValue(
|
|
112
|
+
setValue(inputInitialValue);
|
|
113
|
+
setInitialValue(inputInitialValue);
|
|
41
114
|
setKey(metaOrOptions.key);
|
|
42
115
|
}
|
|
116
|
+
useEffect(() => {
|
|
117
|
+
var form = getFormElement(metaOrOptions.formId);
|
|
118
|
+
if (getEventTarget(form, metaOrOptions.name)) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
createDummySelect(form, metaOrOptions.name, initialValue);
|
|
122
|
+
return () => {
|
|
123
|
+
var elements = getFieldElements(form, metaOrOptions.name);
|
|
124
|
+
for (var element of elements) {
|
|
125
|
+
if (isDummySelect(element)) {
|
|
126
|
+
element.remove();
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
}, [metaOrOptions.formId, metaOrOptions.name, initialValue]);
|
|
43
131
|
useEffect(() => {
|
|
44
132
|
var createEventListener = listener => {
|
|
45
133
|
return event => {
|
|
46
|
-
var
|
|
47
|
-
|
|
134
|
+
var _element$form;
|
|
135
|
+
var element = event.target;
|
|
136
|
+
if ((element instanceof HTMLInputElement || element instanceof HTMLSelectElement || element instanceof HTMLTextAreaElement) && element.name === metaOrOptions.name && ((_element$form = element.form) === null || _element$form === void 0 ? void 0 : _element$form.id) === metaOrOptions.formId) {
|
|
48
137
|
eventDispatched.current[listener] = true;
|
|
49
138
|
}
|
|
50
139
|
};
|
|
@@ -65,68 +154,50 @@ function useInputControl(metaOrOptions) {
|
|
|
65
154
|
return {
|
|
66
155
|
change(value) {
|
|
67
156
|
if (!eventDispatched.current.change) {
|
|
68
|
-
var _element = getEventTarget(metaOrOptions.formId, metaOrOptions.name);
|
|
69
157
|
eventDispatched.current.change = true;
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
158
|
+
var form = getFormElement(metaOrOptions.formId);
|
|
159
|
+
var element = getEventTarget(form, metaOrOptions.name);
|
|
160
|
+
if (element) {
|
|
161
|
+
updateFieldValue(element, value);
|
|
74
162
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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);
|
|
93
|
-
} else {
|
|
94
|
-
throw new Error('The given element does not have a value setter');
|
|
95
|
-
}
|
|
96
|
-
}
|
|
163
|
+
// Dispatch input event with the updated input value
|
|
164
|
+
element.dispatchEvent(new InputEvent('input', {
|
|
165
|
+
bubbles: true
|
|
166
|
+
}));
|
|
167
|
+
// Dispatch change event (necessary for select to update the selected option)
|
|
168
|
+
element.dispatchEvent(new Event('change', {
|
|
169
|
+
bubbles: true
|
|
170
|
+
}));
|
|
97
171
|
}
|
|
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
|
-
}));
|
|
107
172
|
}
|
|
108
173
|
setValue(value);
|
|
109
174
|
eventDispatched.current.change = false;
|
|
110
175
|
},
|
|
111
176
|
focus() {
|
|
112
177
|
if (!eventDispatched.current.focus) {
|
|
113
|
-
var _element2 = getEventTarget(metaOrOptions.formId, metaOrOptions.name);
|
|
114
178
|
eventDispatched.current.focus = true;
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
179
|
+
var form = getFormElement(metaOrOptions.formId);
|
|
180
|
+
var element = getEventTarget(form, metaOrOptions.name);
|
|
181
|
+
if (element) {
|
|
182
|
+
element.dispatchEvent(new FocusEvent('focusin', {
|
|
183
|
+
bubbles: true
|
|
184
|
+
}));
|
|
185
|
+
element.dispatchEvent(new FocusEvent('focus'));
|
|
186
|
+
}
|
|
119
187
|
}
|
|
120
188
|
eventDispatched.current.focus = false;
|
|
121
189
|
},
|
|
122
190
|
blur() {
|
|
123
191
|
if (!eventDispatched.current.blur) {
|
|
124
|
-
var _element3 = getEventTarget(metaOrOptions.formId, metaOrOptions.name);
|
|
125
192
|
eventDispatched.current.blur = true;
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
193
|
+
var form = getFormElement(metaOrOptions.formId);
|
|
194
|
+
var element = getEventTarget(form, metaOrOptions.name);
|
|
195
|
+
if (element) {
|
|
196
|
+
element.dispatchEvent(new FocusEvent('focusout', {
|
|
197
|
+
bubbles: true
|
|
198
|
+
}));
|
|
199
|
+
element.dispatchEvent(new FocusEvent('blur'));
|
|
200
|
+
}
|
|
130
201
|
}
|
|
131
202
|
eventDispatched.current.blur = false;
|
|
132
203
|
}
|
|
@@ -137,4 +208,4 @@ function useInputControl(metaOrOptions) {
|
|
|
137
208
|
});
|
|
138
209
|
}
|
|
139
210
|
|
|
140
|
-
export { getEventTarget,
|
|
211
|
+
export { createDummySelect, getEventTarget, getFieldElements, getFormElement, isDummySelect, updateFieldValue, useInputControl };
|
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.
|
|
6
|
+
"version": "1.0.1",
|
|
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.
|
|
33
|
+
"@conform-to/dom": "1.0.1"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/react": "^18.2.43",
|