@conform-to/dom 1.6.1 → 1.7.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
@@ -7,7 +7,7 @@
7
7
  ╚══════╝ ╚═════╝ ╚═╝ ╚══╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝
8
8
  ```
9
9
 
10
- Version 1.6.1 / License MIT / Copyright (c) 2024 Edmund Hung
10
+ Version 1.7.0 / License MIT / Copyright (c) 2024 Edmund Hung
11
11
 
12
12
  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.
13
13
 
package/dist/dom.d.ts CHANGED
@@ -3,19 +3,13 @@
3
3
  * includes `<input>`, `<select>` and `<textarea>`.
4
4
  */
5
5
  export type FieldElement = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
6
- /**
7
- * HTML Element that can be used as a form control,
8
- * includes `<input>`, `<select>`, `<textarea>` and `<button>`.
9
- */
10
- export type FormControl = FieldElement | HTMLButtonElement;
11
6
  /**
12
7
  * Form Control element. It can either be a submit button or a submit input.
13
8
  */
14
9
  export type Submitter = HTMLInputElement | HTMLButtonElement;
15
- /**
16
- * A type guard to check if the provided element is a form control
17
- */
18
- export declare function isFormControl(element: unknown): element is FormControl;
10
+ export declare function isInputElement(element: Element): element is HTMLInputElement;
11
+ export declare function isSelectElement(element: Element): element is HTMLSelectElement;
12
+ export declare function isTextAreaElement(element: Element): element is HTMLTextAreaElement;
19
13
  /**
20
14
  * A type guard to check if the provided element is a field element, which
21
15
  * is a form control excluding submit, button and reset type.
@@ -41,4 +35,31 @@ export declare function getFormMethod(event: SubmitEvent): 'GET' | 'POST' | 'PUT
41
35
  * If the submitter is not mounted, it will be appended to the form and removed after submission.
42
36
  */
43
37
  export declare function requestSubmit(form: HTMLFormElement | null | undefined, submitter: Submitter | null): void;
38
+ export declare function createFileList(value: File | File[]): FileList;
39
+ type InputCallback = (event: {
40
+ type: 'input' | 'reset' | 'mutation';
41
+ target: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
42
+ }) => void;
43
+ type FormCallback = (event: {
44
+ type: 'submit' | 'input' | 'reset' | 'mutation';
45
+ target: HTMLFormElement;
46
+ submitter?: HTMLInputElement | HTMLButtonElement | null;
47
+ }) => void;
48
+ export declare function createGlobalFormsObserver(): {
49
+ onFieldUpdate(callback: InputCallback): () => void;
50
+ onFormUpdate(callback: FormCallback): () => void;
51
+ dispose(): void;
52
+ };
53
+ export declare function change(element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement, value: string | string[] | File | File[] | FileList | null): void;
54
+ export declare function focus(element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement): void;
55
+ export declare function blur(element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement): void;
56
+ export declare function normalizeFieldValue(value: unknown): [string[] | null, FileList | null];
57
+ /**
58
+ * Updates the DOM element with the provided value and defaultValue.
59
+ */
60
+ export declare function updateField(element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement, options: {
61
+ value?: unknown;
62
+ defaultValue?: unknown;
63
+ }): void;
64
+ export {};
44
65
  //# sourceMappingURL=dom.d.ts.map
package/dist/dom.js CHANGED
@@ -9,20 +9,18 @@ var util = require('./util.js');
9
9
  * includes `<input>`, `<select>` and `<textarea>`.
10
10
  */
11
11
 
12
- /**
13
- * HTML Element that can be used as a form control,
14
- * includes `<input>`, `<select>`, `<textarea>` and `<button>`.
15
- */
16
-
17
12
  /**
18
13
  * Form Control element. It can either be a submit button or a submit input.
19
14
  */
20
15
 
21
- /**
22
- * A type guard to check if the provided element is a form control
23
- */
24
- function isFormControl(element) {
25
- return element instanceof Element && (element.tagName === 'INPUT' || element.tagName === 'SELECT' || element.tagName === 'TEXTAREA' || element.tagName === 'BUTTON');
16
+ function isInputElement(element) {
17
+ return element.tagName === 'INPUT';
18
+ }
19
+ function isSelectElement(element) {
20
+ return element.tagName === 'SELECT';
21
+ }
22
+ function isTextAreaElement(element) {
23
+ return element.tagName === 'TEXTAREA';
26
24
  }
27
25
 
28
26
  /**
@@ -30,7 +28,15 @@ function isFormControl(element) {
30
28
  * is a form control excluding submit, button and reset type.
31
29
  */
32
30
  function isFieldElement(element) {
33
- return isFormControl(element) && element.type !== 'submit' && element.type !== 'button' && element.type !== 'reset';
31
+ if (element instanceof Element) {
32
+ if (isInputElement(element)) {
33
+ return element.type !== 'submit' && element.type !== 'button' && element.type !== 'reset';
34
+ }
35
+ if (isSelectElement(element) || isTextAreaElement(element)) {
36
+ return true;
37
+ }
38
+ }
39
+ return false;
34
40
  }
35
41
 
36
42
  /**
@@ -87,18 +93,361 @@ function requestSubmit(form, submitter) {
87
93
  if (typeof form.requestSubmit === 'function') {
88
94
  form.requestSubmit(submitter);
89
95
  } else {
90
- var event = new SubmitEvent('submit', {
96
+ var _event = new SubmitEvent('submit', {
91
97
  bubbles: true,
92
98
  cancelable: true,
93
99
  submitter
94
100
  });
95
- form.dispatchEvent(event);
101
+ form.dispatchEvent(_event);
102
+ }
103
+ }
104
+ function createFileList(value) {
105
+ var dataTransfer = new DataTransfer();
106
+ if (Array.isArray(value)) {
107
+ for (var file of value) {
108
+ dataTransfer.items.add(file);
109
+ }
110
+ } else {
111
+ dataTransfer.items.add(value);
112
+ }
113
+ return dataTransfer.files;
114
+ }
115
+ function createGlobalFormsObserver() {
116
+ var inputListeners = new Set();
117
+ var formListeners = new Set();
118
+ var cleanup = null;
119
+ function initialize() {
120
+ var observer = new MutationObserver(handleMutation);
121
+ observer.observe(document.body, {
122
+ subtree: true,
123
+ childList: true,
124
+ attributeFilter: ['form', 'name', 'data-conform']
125
+ });
126
+ document.addEventListener('input', handleInput);
127
+ document.addEventListener('reset', handleReset);
128
+ document.addEventListener('submit', handleSubmit, true);
129
+ return () => {
130
+ document.removeEventListener('input', handleInput);
131
+ document.removeEventListener('reset', handleReset);
132
+ document.removeEventListener('submit', handleSubmit, true);
133
+ observer.disconnect();
134
+ };
135
+ }
136
+ function handleInput(event) {
137
+ var target = event.target;
138
+ if (isFieldElement(target)) {
139
+ inputListeners.forEach(callback => callback({
140
+ type: 'input',
141
+ target
142
+ }));
143
+ var form = target.form;
144
+ if (form) {
145
+ formListeners.forEach(callback => callback({
146
+ type: 'input',
147
+ target: form
148
+ }));
149
+ }
150
+ }
151
+ }
152
+ function handleReset(event) {
153
+ var form = event.target;
154
+ if (form instanceof HTMLFormElement) {
155
+ // Reset event is fired before the form is reset, so we need to wait for the next tick
156
+ setTimeout(() => {
157
+ formListeners.forEach(callback => {
158
+ callback({
159
+ type: 'reset',
160
+ target: form
161
+ });
162
+ });
163
+ var _loop = function _loop(target) {
164
+ if (isFieldElement(target)) {
165
+ inputListeners.forEach(callback => {
166
+ callback({
167
+ type: 'reset',
168
+ target
169
+ });
170
+ });
171
+ }
172
+ };
173
+ for (var target of form.elements) {
174
+ _loop(target);
175
+ }
176
+ });
177
+ }
178
+ }
179
+ function handleSubmit(event) {
180
+ var target = event.target;
181
+ var submitter = event.submitter;
182
+ if (target instanceof HTMLFormElement) {
183
+ formListeners.forEach(callback => callback({
184
+ type: 'submit',
185
+ target,
186
+ submitter
187
+ }));
188
+ }
189
+ }
190
+ function handleMutation(mutations) {
191
+ var seenForms = new Set();
192
+ var seenInputs = new Set();
193
+ var collectInputs = node => {
194
+ if (isFieldElement(node)) {
195
+ return [node];
196
+ }
197
+ return node instanceof Element ? Array.from(node.querySelectorAll('input,select,textarea')) : [];
198
+ };
199
+ for (var mutation of mutations) {
200
+ switch (mutation.type) {
201
+ case 'childList':
202
+ {
203
+ var nodes = [...mutation.addedNodes, ...mutation.removedNodes];
204
+ for (var node of nodes) {
205
+ for (var input of collectInputs(node)) {
206
+ seenInputs.add(input);
207
+ if (input.form) {
208
+ seenForms.add(input.form);
209
+ }
210
+ }
211
+ }
212
+ break;
213
+ }
214
+ case 'attributes':
215
+ {
216
+ if (isFieldElement(mutation.target)) {
217
+ seenInputs.add(mutation.target);
218
+ if (mutation.target.form) {
219
+ seenForms.add(mutation.target.form);
220
+ }
221
+ }
222
+ break;
223
+ }
224
+ }
225
+ }
226
+ var _loop2 = function _loop2(target) {
227
+ formListeners.forEach(callback => {
228
+ callback({
229
+ type: 'mutation',
230
+ target
231
+ });
232
+ });
233
+ };
234
+ for (var target of seenForms) {
235
+ _loop2(target);
236
+ }
237
+ var _loop3 = function _loop3(_target) {
238
+ inputListeners.forEach(callback => {
239
+ callback({
240
+ type: 'mutation',
241
+ target: _target
242
+ });
243
+ });
244
+ };
245
+ for (var _target of seenInputs) {
246
+ _loop3(_target);
247
+ }
248
+ }
249
+ return {
250
+ onFieldUpdate(callback) {
251
+ var _cleanup;
252
+ cleanup = (_cleanup = cleanup) !== null && _cleanup !== void 0 ? _cleanup : initialize();
253
+ inputListeners.add(callback);
254
+ return () => {
255
+ inputListeners.delete(callback);
256
+ };
257
+ },
258
+ onFormUpdate(callback) {
259
+ var _cleanup2;
260
+ cleanup = (_cleanup2 = cleanup) !== null && _cleanup2 !== void 0 ? _cleanup2 : initialize();
261
+ formListeners.add(callback);
262
+ return () => {
263
+ formListeners.delete(callback);
264
+ };
265
+ },
266
+ dispose() {
267
+ var _cleanup3;
268
+ (_cleanup3 = cleanup) === null || _cleanup3 === void 0 || _cleanup3();
269
+ cleanup = null;
270
+ inputListeners.clear();
271
+ formListeners.clear();
272
+ }
273
+ };
274
+ }
275
+ function change(element, value) {
276
+ // The value should be set to the element before dispatching the event
277
+ updateField(element, {
278
+ value
279
+ });
280
+
281
+ // Dispatch input event with the updated input value
282
+ element.dispatchEvent(new InputEvent('input', {
283
+ bubbles: true
284
+ }));
285
+ // Dispatch change event (necessary for select to update the selected option)
286
+ element.dispatchEvent(new Event('change', {
287
+ bubbles: true
288
+ }));
289
+ }
290
+ function focus(element) {
291
+ // Only focusin event will be bubbled
292
+ element.dispatchEvent(new FocusEvent('focusin', {
293
+ bubbles: true
294
+ }));
295
+ element.dispatchEvent(new FocusEvent('focus'));
296
+ }
297
+ function blur(element) {
298
+ // Only focusout event will be bubbled
299
+ element.dispatchEvent(new FocusEvent('focusout', {
300
+ bubbles: true
301
+ }));
302
+ element.dispatchEvent(new FocusEvent('blur'));
303
+ }
304
+ function normalizeFieldValue(value) {
305
+ if (typeof value === 'undefined') {
306
+ return [null, null];
307
+ }
308
+ if (value === null) {
309
+ return [[], createFileList([])];
310
+ }
311
+ if (typeof value === 'string') {
312
+ return [[value], null];
313
+ }
314
+ if (Array.isArray(value)) {
315
+ if (value.every(item => typeof item === 'string')) {
316
+ return [Array.from(value), null];
317
+ }
318
+ if (value.every(item => item instanceof File)) {
319
+ return [null, createFileList(value)];
320
+ }
321
+ }
322
+ if (value instanceof FileList) {
323
+ return [null, value];
324
+ }
325
+ if (value instanceof File) {
326
+ return [null, createFileList([value])];
327
+ }
328
+ return [null, null];
329
+ }
330
+
331
+ /**
332
+ * Updates the DOM element with the provided value and defaultValue.
333
+ */
334
+ function updateField(element, options) {
335
+ var _value$;
336
+ var [value, file] = normalizeFieldValue(options.value);
337
+ var [defaultValue] = normalizeFieldValue(options.defaultValue);
338
+ if (isInputElement(element)) {
339
+ switch (element.type) {
340
+ case 'file':
341
+ {
342
+ element.files = file;
343
+ return;
344
+ }
345
+ case 'checkbox':
346
+ case 'radio':
347
+ {
348
+ if (value) {
349
+ var checked = value.includes(element.value);
350
+ if (element.type === 'checkbox' ? checked !== element.checked : checked) {
351
+ // Simulate a click to update the checked state
352
+ element.click();
353
+ }
354
+ element.checked = checked;
355
+ }
356
+ if (defaultValue) {
357
+ element.defaultChecked = defaultValue.includes(element.value);
358
+ }
359
+ return;
360
+ }
361
+ }
362
+ } else if (isSelectElement(element)) {
363
+ var shouldUnselect = value && value.length === 0;
364
+ for (var option of element.options) {
365
+ if (value) {
366
+ var index = value.indexOf(option.value);
367
+ var selected = index > -1;
368
+
369
+ // Update the selected state of the option
370
+ if (option.selected !== selected) {
371
+ option.selected = selected;
372
+ }
373
+
374
+ // Remove the option from the value array
375
+ if (selected) {
376
+ value.splice(index, 1);
377
+ }
378
+ }
379
+ if (defaultValue) {
380
+ var _index = defaultValue.indexOf(option.value);
381
+ var _selected = _index > -1;
382
+
383
+ // Update the selected state of the option
384
+ if (option.defaultSelected !== _selected) {
385
+ option.defaultSelected = _selected;
386
+ }
387
+
388
+ // Remove the option from the defaultValue array
389
+ if (_selected) {
390
+ defaultValue.splice(_index, 1);
391
+ }
392
+ }
393
+ }
394
+
395
+ // We have already removed all selected options from the value and defaultValue array at this point
396
+ var missingOptions = new Set([...(value !== null && value !== void 0 ? value : []), ...(defaultValue !== null && defaultValue !== void 0 ? defaultValue : [])]);
397
+ for (var optionValue of missingOptions) {
398
+ element.options.add(new Option(optionValue, optionValue, defaultValue === null || defaultValue === void 0 ? void 0 : defaultValue.includes(optionValue), value === null || value === void 0 ? void 0 : value.includes(optionValue)));
399
+ }
400
+
401
+ // If the select element is not multiple and the value is an empty array, unset the selected index
402
+ // This is to prevent the select element from showing the first option as selected
403
+ if (shouldUnselect) {
404
+ element.selectedIndex = -1;
405
+ }
406
+ return;
407
+ }
408
+ var inputValue = (_value$ = value === null || value === void 0 ? void 0 : value[0]) !== null && _value$ !== void 0 ? _value$ : '';
409
+ if (element.value !== inputValue) {
410
+ /**
411
+ * Triggering react custom change event
412
+ * Solution based on dom-testing-library
413
+ * @see https://github.com/facebook/react/issues/10135#issuecomment-401496776
414
+ * @see https://github.com/testing-library/dom-testing-library/blob/main/src/events.js#L104-L123
415
+ */
416
+ var {
417
+ set: valueSetter
418
+ } = Object.getOwnPropertyDescriptor(element, 'value') || {};
419
+ var prototype = Object.getPrototypeOf(element);
420
+ var {
421
+ set: prototypeValueSetter
422
+ } = Object.getOwnPropertyDescriptor(prototype, 'value') || {};
423
+ if (prototypeValueSetter && valueSetter !== prototypeValueSetter) {
424
+ prototypeValueSetter.call(element, inputValue);
425
+ } else {
426
+ if (valueSetter) {
427
+ valueSetter.call(element, inputValue);
428
+ } else {
429
+ throw new Error('The given element does not have a value setter');
430
+ }
431
+ }
432
+ }
433
+ if (defaultValue) {
434
+ var _defaultValue$;
435
+ element.defaultValue = (_defaultValue$ = defaultValue[0]) !== null && _defaultValue$ !== void 0 ? _defaultValue$ : '';
96
436
  }
97
437
  }
98
438
 
439
+ exports.blur = blur;
440
+ exports.change = change;
441
+ exports.createFileList = createFileList;
442
+ exports.createGlobalFormsObserver = createGlobalFormsObserver;
443
+ exports.focus = focus;
99
444
  exports.getFormAction = getFormAction;
100
445
  exports.getFormEncType = getFormEncType;
101
446
  exports.getFormMethod = getFormMethod;
102
447
  exports.isFieldElement = isFieldElement;
103
- exports.isFormControl = isFormControl;
448
+ exports.isInputElement = isInputElement;
449
+ exports.isSelectElement = isSelectElement;
450
+ exports.isTextAreaElement = isTextAreaElement;
451
+ exports.normalizeFieldValue = normalizeFieldValue;
104
452
  exports.requestSubmit = requestSubmit;
453
+ exports.updateField = updateField;
package/dist/dom.mjs CHANGED
@@ -5,20 +5,18 @@ import { invariant } from './util.mjs';
5
5
  * includes `<input>`, `<select>` and `<textarea>`.
6
6
  */
7
7
 
8
- /**
9
- * HTML Element that can be used as a form control,
10
- * includes `<input>`, `<select>`, `<textarea>` and `<button>`.
11
- */
12
-
13
8
  /**
14
9
  * Form Control element. It can either be a submit button or a submit input.
15
10
  */
16
11
 
17
- /**
18
- * A type guard to check if the provided element is a form control
19
- */
20
- function isFormControl(element) {
21
- return element instanceof Element && (element.tagName === 'INPUT' || element.tagName === 'SELECT' || element.tagName === 'TEXTAREA' || element.tagName === 'BUTTON');
12
+ function isInputElement(element) {
13
+ return element.tagName === 'INPUT';
14
+ }
15
+ function isSelectElement(element) {
16
+ return element.tagName === 'SELECT';
17
+ }
18
+ function isTextAreaElement(element) {
19
+ return element.tagName === 'TEXTAREA';
22
20
  }
23
21
 
24
22
  /**
@@ -26,7 +24,15 @@ function isFormControl(element) {
26
24
  * is a form control excluding submit, button and reset type.
27
25
  */
28
26
  function isFieldElement(element) {
29
- return isFormControl(element) && element.type !== 'submit' && element.type !== 'button' && element.type !== 'reset';
27
+ if (element instanceof Element) {
28
+ if (isInputElement(element)) {
29
+ return element.type !== 'submit' && element.type !== 'button' && element.type !== 'reset';
30
+ }
31
+ if (isSelectElement(element) || isTextAreaElement(element)) {
32
+ return true;
33
+ }
34
+ }
35
+ return false;
30
36
  }
31
37
 
32
38
  /**
@@ -83,13 +89,347 @@ function requestSubmit(form, submitter) {
83
89
  if (typeof form.requestSubmit === 'function') {
84
90
  form.requestSubmit(submitter);
85
91
  } else {
86
- var event = new SubmitEvent('submit', {
92
+ var _event = new SubmitEvent('submit', {
87
93
  bubbles: true,
88
94
  cancelable: true,
89
95
  submitter
90
96
  });
91
- form.dispatchEvent(event);
97
+ form.dispatchEvent(_event);
98
+ }
99
+ }
100
+ function createFileList(value) {
101
+ var dataTransfer = new DataTransfer();
102
+ if (Array.isArray(value)) {
103
+ for (var file of value) {
104
+ dataTransfer.items.add(file);
105
+ }
106
+ } else {
107
+ dataTransfer.items.add(value);
108
+ }
109
+ return dataTransfer.files;
110
+ }
111
+ function createGlobalFormsObserver() {
112
+ var inputListeners = new Set();
113
+ var formListeners = new Set();
114
+ var cleanup = null;
115
+ function initialize() {
116
+ var observer = new MutationObserver(handleMutation);
117
+ observer.observe(document.body, {
118
+ subtree: true,
119
+ childList: true,
120
+ attributeFilter: ['form', 'name', 'data-conform']
121
+ });
122
+ document.addEventListener('input', handleInput);
123
+ document.addEventListener('reset', handleReset);
124
+ document.addEventListener('submit', handleSubmit, true);
125
+ return () => {
126
+ document.removeEventListener('input', handleInput);
127
+ document.removeEventListener('reset', handleReset);
128
+ document.removeEventListener('submit', handleSubmit, true);
129
+ observer.disconnect();
130
+ };
131
+ }
132
+ function handleInput(event) {
133
+ var target = event.target;
134
+ if (isFieldElement(target)) {
135
+ inputListeners.forEach(callback => callback({
136
+ type: 'input',
137
+ target
138
+ }));
139
+ var form = target.form;
140
+ if (form) {
141
+ formListeners.forEach(callback => callback({
142
+ type: 'input',
143
+ target: form
144
+ }));
145
+ }
146
+ }
147
+ }
148
+ function handleReset(event) {
149
+ var form = event.target;
150
+ if (form instanceof HTMLFormElement) {
151
+ // Reset event is fired before the form is reset, so we need to wait for the next tick
152
+ setTimeout(() => {
153
+ formListeners.forEach(callback => {
154
+ callback({
155
+ type: 'reset',
156
+ target: form
157
+ });
158
+ });
159
+ var _loop = function _loop(target) {
160
+ if (isFieldElement(target)) {
161
+ inputListeners.forEach(callback => {
162
+ callback({
163
+ type: 'reset',
164
+ target
165
+ });
166
+ });
167
+ }
168
+ };
169
+ for (var target of form.elements) {
170
+ _loop(target);
171
+ }
172
+ });
173
+ }
174
+ }
175
+ function handleSubmit(event) {
176
+ var target = event.target;
177
+ var submitter = event.submitter;
178
+ if (target instanceof HTMLFormElement) {
179
+ formListeners.forEach(callback => callback({
180
+ type: 'submit',
181
+ target,
182
+ submitter
183
+ }));
184
+ }
185
+ }
186
+ function handleMutation(mutations) {
187
+ var seenForms = new Set();
188
+ var seenInputs = new Set();
189
+ var collectInputs = node => {
190
+ if (isFieldElement(node)) {
191
+ return [node];
192
+ }
193
+ return node instanceof Element ? Array.from(node.querySelectorAll('input,select,textarea')) : [];
194
+ };
195
+ for (var mutation of mutations) {
196
+ switch (mutation.type) {
197
+ case 'childList':
198
+ {
199
+ var nodes = [...mutation.addedNodes, ...mutation.removedNodes];
200
+ for (var node of nodes) {
201
+ for (var input of collectInputs(node)) {
202
+ seenInputs.add(input);
203
+ if (input.form) {
204
+ seenForms.add(input.form);
205
+ }
206
+ }
207
+ }
208
+ break;
209
+ }
210
+ case 'attributes':
211
+ {
212
+ if (isFieldElement(mutation.target)) {
213
+ seenInputs.add(mutation.target);
214
+ if (mutation.target.form) {
215
+ seenForms.add(mutation.target.form);
216
+ }
217
+ }
218
+ break;
219
+ }
220
+ }
221
+ }
222
+ var _loop2 = function _loop2(target) {
223
+ formListeners.forEach(callback => {
224
+ callback({
225
+ type: 'mutation',
226
+ target
227
+ });
228
+ });
229
+ };
230
+ for (var target of seenForms) {
231
+ _loop2(target);
232
+ }
233
+ var _loop3 = function _loop3(_target) {
234
+ inputListeners.forEach(callback => {
235
+ callback({
236
+ type: 'mutation',
237
+ target: _target
238
+ });
239
+ });
240
+ };
241
+ for (var _target of seenInputs) {
242
+ _loop3(_target);
243
+ }
244
+ }
245
+ return {
246
+ onFieldUpdate(callback) {
247
+ var _cleanup;
248
+ cleanup = (_cleanup = cleanup) !== null && _cleanup !== void 0 ? _cleanup : initialize();
249
+ inputListeners.add(callback);
250
+ return () => {
251
+ inputListeners.delete(callback);
252
+ };
253
+ },
254
+ onFormUpdate(callback) {
255
+ var _cleanup2;
256
+ cleanup = (_cleanup2 = cleanup) !== null && _cleanup2 !== void 0 ? _cleanup2 : initialize();
257
+ formListeners.add(callback);
258
+ return () => {
259
+ formListeners.delete(callback);
260
+ };
261
+ },
262
+ dispose() {
263
+ var _cleanup3;
264
+ (_cleanup3 = cleanup) === null || _cleanup3 === void 0 || _cleanup3();
265
+ cleanup = null;
266
+ inputListeners.clear();
267
+ formListeners.clear();
268
+ }
269
+ };
270
+ }
271
+ function change(element, value) {
272
+ // The value should be set to the element before dispatching the event
273
+ updateField(element, {
274
+ value
275
+ });
276
+
277
+ // Dispatch input event with the updated input value
278
+ element.dispatchEvent(new InputEvent('input', {
279
+ bubbles: true
280
+ }));
281
+ // Dispatch change event (necessary for select to update the selected option)
282
+ element.dispatchEvent(new Event('change', {
283
+ bubbles: true
284
+ }));
285
+ }
286
+ function focus(element) {
287
+ // Only focusin event will be bubbled
288
+ element.dispatchEvent(new FocusEvent('focusin', {
289
+ bubbles: true
290
+ }));
291
+ element.dispatchEvent(new FocusEvent('focus'));
292
+ }
293
+ function blur(element) {
294
+ // Only focusout event will be bubbled
295
+ element.dispatchEvent(new FocusEvent('focusout', {
296
+ bubbles: true
297
+ }));
298
+ element.dispatchEvent(new FocusEvent('blur'));
299
+ }
300
+ function normalizeFieldValue(value) {
301
+ if (typeof value === 'undefined') {
302
+ return [null, null];
303
+ }
304
+ if (value === null) {
305
+ return [[], createFileList([])];
306
+ }
307
+ if (typeof value === 'string') {
308
+ return [[value], null];
309
+ }
310
+ if (Array.isArray(value)) {
311
+ if (value.every(item => typeof item === 'string')) {
312
+ return [Array.from(value), null];
313
+ }
314
+ if (value.every(item => item instanceof File)) {
315
+ return [null, createFileList(value)];
316
+ }
317
+ }
318
+ if (value instanceof FileList) {
319
+ return [null, value];
320
+ }
321
+ if (value instanceof File) {
322
+ return [null, createFileList([value])];
323
+ }
324
+ return [null, null];
325
+ }
326
+
327
+ /**
328
+ * Updates the DOM element with the provided value and defaultValue.
329
+ */
330
+ function updateField(element, options) {
331
+ var _value$;
332
+ var [value, file] = normalizeFieldValue(options.value);
333
+ var [defaultValue] = normalizeFieldValue(options.defaultValue);
334
+ if (isInputElement(element)) {
335
+ switch (element.type) {
336
+ case 'file':
337
+ {
338
+ element.files = file;
339
+ return;
340
+ }
341
+ case 'checkbox':
342
+ case 'radio':
343
+ {
344
+ if (value) {
345
+ var checked = value.includes(element.value);
346
+ if (element.type === 'checkbox' ? checked !== element.checked : checked) {
347
+ // Simulate a click to update the checked state
348
+ element.click();
349
+ }
350
+ element.checked = checked;
351
+ }
352
+ if (defaultValue) {
353
+ element.defaultChecked = defaultValue.includes(element.value);
354
+ }
355
+ return;
356
+ }
357
+ }
358
+ } else if (isSelectElement(element)) {
359
+ var shouldUnselect = value && value.length === 0;
360
+ for (var option of element.options) {
361
+ if (value) {
362
+ var index = value.indexOf(option.value);
363
+ var selected = index > -1;
364
+
365
+ // Update the selected state of the option
366
+ if (option.selected !== selected) {
367
+ option.selected = selected;
368
+ }
369
+
370
+ // Remove the option from the value array
371
+ if (selected) {
372
+ value.splice(index, 1);
373
+ }
374
+ }
375
+ if (defaultValue) {
376
+ var _index = defaultValue.indexOf(option.value);
377
+ var _selected = _index > -1;
378
+
379
+ // Update the selected state of the option
380
+ if (option.defaultSelected !== _selected) {
381
+ option.defaultSelected = _selected;
382
+ }
383
+
384
+ // Remove the option from the defaultValue array
385
+ if (_selected) {
386
+ defaultValue.splice(_index, 1);
387
+ }
388
+ }
389
+ }
390
+
391
+ // We have already removed all selected options from the value and defaultValue array at this point
392
+ var missingOptions = new Set([...(value !== null && value !== void 0 ? value : []), ...(defaultValue !== null && defaultValue !== void 0 ? defaultValue : [])]);
393
+ for (var optionValue of missingOptions) {
394
+ element.options.add(new Option(optionValue, optionValue, defaultValue === null || defaultValue === void 0 ? void 0 : defaultValue.includes(optionValue), value === null || value === void 0 ? void 0 : value.includes(optionValue)));
395
+ }
396
+
397
+ // If the select element is not multiple and the value is an empty array, unset the selected index
398
+ // This is to prevent the select element from showing the first option as selected
399
+ if (shouldUnselect) {
400
+ element.selectedIndex = -1;
401
+ }
402
+ return;
403
+ }
404
+ var inputValue = (_value$ = value === null || value === void 0 ? void 0 : value[0]) !== null && _value$ !== void 0 ? _value$ : '';
405
+ if (element.value !== inputValue) {
406
+ /**
407
+ * Triggering react custom change event
408
+ * Solution based on dom-testing-library
409
+ * @see https://github.com/facebook/react/issues/10135#issuecomment-401496776
410
+ * @see https://github.com/testing-library/dom-testing-library/blob/main/src/events.js#L104-L123
411
+ */
412
+ var {
413
+ set: valueSetter
414
+ } = Object.getOwnPropertyDescriptor(element, 'value') || {};
415
+ var prototype = Object.getPrototypeOf(element);
416
+ var {
417
+ set: prototypeValueSetter
418
+ } = Object.getOwnPropertyDescriptor(prototype, 'value') || {};
419
+ if (prototypeValueSetter && valueSetter !== prototypeValueSetter) {
420
+ prototypeValueSetter.call(element, inputValue);
421
+ } else {
422
+ if (valueSetter) {
423
+ valueSetter.call(element, inputValue);
424
+ } else {
425
+ throw new Error('The given element does not have a value setter');
426
+ }
427
+ }
428
+ }
429
+ if (defaultValue) {
430
+ var _defaultValue$;
431
+ element.defaultValue = (_defaultValue$ = defaultValue[0]) !== null && _defaultValue$ !== void 0 ? _defaultValue$ : '';
92
432
  }
93
433
  }
94
434
 
95
- export { getFormAction, getFormEncType, getFormMethod, isFieldElement, isFormControl, requestSubmit };
435
+ export { blur, change, createFileList, createGlobalFormsObserver, focus, getFormAction, getFormEncType, getFormMethod, isFieldElement, isInputElement, isSelectElement, isTextAreaElement, normalizeFieldValue, requestSubmit, updateField };
package/dist/form.d.ts CHANGED
@@ -147,15 +147,5 @@ export type FormContext<Schema extends Record<string, any> = any, FormError = st
147
147
  };
148
148
  };
149
149
  export declare function createFormContext<Schema extends Record<string, any>, FormError = string[], FormValue = Schema>(options: FormOptions<Schema, FormError, FormValue>): FormContext<Schema, FormError, FormValue>;
150
- /**
151
- * Updates the DOM element with the provided value.
152
- *
153
- * @param element The form element to update
154
- * @param options The options to update the form element
155
- */
156
- export declare function updateFieldValue(element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement, options: {
157
- value?: string | string[];
158
- defaultValue?: string | string[];
159
- }): void;
160
150
  export {};
161
151
  //# sourceMappingURL=form.d.ts.map
package/dist/form.js CHANGED
@@ -582,8 +582,8 @@ function createFormContext(options) {
582
582
  var paths = formdata.getChildPaths(parentPaths, element.name);
583
583
  if (paths) {
584
584
  var value = formdata.getValue(intent.payload.value, formdata.formatPaths(paths));
585
- updateFieldValue(element, {
586
- value: typeof value === 'string' || Array.isArray(value) && value.every(item => typeof item === 'string') ? value : ''
585
+ dom.updateField(element, {
586
+ value: typeof value === 'string' || Array.isArray(value) && value.every(item => typeof item === 'string') ? value : null
587
587
  });
588
588
 
589
589
  // Update the element attribute to notify useControl / useInputControl hook
@@ -597,10 +597,10 @@ function createFormContext(options) {
597
597
  {
598
598
  var prefix = formdata.formatName(intent.payload.name, intent.payload.index);
599
599
  for (var _element of formElement.elements) {
600
- if (dom.isFieldElement(_element) && formdata.isPrefix(_element.name, prefix)) {
600
+ if (dom.isFieldElement(_element) && _element.name && formdata.isPrefix(_element.name, prefix)) {
601
601
  var _value2 = formdata.getValue(meta.defaultValue, _element.name);
602
- var defaultValue = typeof _value2 === 'string' || Array.isArray(_value2) && _value2.every(item => typeof item === 'string') ? _value2 : _element instanceof HTMLSelectElement ? [] : '';
603
- updateFieldValue(_element, {
602
+ var defaultValue = typeof _value2 === 'string' || Array.isArray(_value2) && _value2.every(item => typeof item === 'string') ? _value2 : null;
603
+ dom.updateField(_element, {
604
604
  defaultValue,
605
605
  value: defaultValue
606
606
  });
@@ -638,97 +638,4 @@ function createFormContext(options) {
638
638
  };
639
639
  }
640
640
 
641
- /**
642
- * Updates the DOM element with the provided value.
643
- *
644
- * @param element The form element to update
645
- * @param options The options to update the form element
646
- */
647
- function updateFieldValue(element, options) {
648
- var value = typeof options.value === 'undefined' ? null : Array.isArray(options.value) ? Array.from(options.value) : [options.value];
649
- var defaultValue = typeof options.defaultValue === 'undefined' ? null : Array.isArray(options.defaultValue) ? Array.from(options.defaultValue) : [options.defaultValue];
650
- if (element instanceof HTMLInputElement && (element.type === 'checkbox' || element.type === 'radio')) {
651
- if (value) {
652
- element.checked = value.includes(element.value);
653
- }
654
- if (defaultValue) {
655
- element.defaultChecked = defaultValue.includes(element.value);
656
- }
657
- } else if (element instanceof HTMLSelectElement) {
658
- // If the select element is not multiple and the value is an empty array, unset the selected index
659
- // This is to prevent the select element from showing the first option as selected
660
- if (value && value.length === 0 && !element.multiple) {
661
- element.selectedIndex = -1;
662
- }
663
- for (var option of element.options) {
664
- if (value) {
665
- var index = value.indexOf(option.value);
666
- var selected = index > -1;
667
-
668
- // Update the selected state of the option
669
- if (option.selected !== selected) {
670
- option.selected = selected;
671
- }
672
-
673
- // Remove the option from the value array
674
- if (selected) {
675
- value.splice(index, 1);
676
- }
677
- }
678
- if (defaultValue) {
679
- var _index = defaultValue.indexOf(option.value);
680
- var _selected = _index > -1;
681
-
682
- // Update the selected state of the option
683
- if (option.selected !== _selected) {
684
- option.defaultSelected = _selected;
685
- }
686
-
687
- // Remove the option from the defaultValue array
688
- if (_selected) {
689
- defaultValue.splice(_index, 1);
690
- }
691
- }
692
- }
693
-
694
- // We have already removed all selected options from the value and defaultValue array at this point
695
- var missingOptions = new Set([...(value !== null && value !== void 0 ? value : []), ...(defaultValue !== null && defaultValue !== void 0 ? defaultValue : [])]);
696
- for (var optionValue of missingOptions) {
697
- element.options.add(new Option(optionValue, optionValue, defaultValue === null || defaultValue === void 0 ? void 0 : defaultValue.includes(optionValue), value === null || value === void 0 ? void 0 : value.includes(optionValue)));
698
- }
699
- } else {
700
- if (value) {
701
- var _value$;
702
- /**
703
- * Triggering react custom change event
704
- * Solution based on dom-testing-library
705
- * @see https://github.com/facebook/react/issues/10135#issuecomment-401496776
706
- * @see https://github.com/testing-library/dom-testing-library/blob/main/src/events.js#L104-L123
707
- */
708
- var inputValue = (_value$ = value[0]) !== null && _value$ !== void 0 ? _value$ : '';
709
- var {
710
- set: valueSetter
711
- } = Object.getOwnPropertyDescriptor(element, 'value') || {};
712
- var prototype = Object.getPrototypeOf(element);
713
- var {
714
- set: prototypeValueSetter
715
- } = Object.getOwnPropertyDescriptor(prototype, 'value') || {};
716
- if (prototypeValueSetter && valueSetter !== prototypeValueSetter) {
717
- prototypeValueSetter.call(element, inputValue);
718
- } else {
719
- if (valueSetter) {
720
- valueSetter.call(element, inputValue);
721
- } else {
722
- throw new Error('The given element does not have a value setter');
723
- }
724
- }
725
- }
726
- if (defaultValue) {
727
- var _defaultValue$;
728
- element.defaultValue = (_defaultValue$ = defaultValue[0]) !== null && _defaultValue$ !== void 0 ? _defaultValue$ : '';
729
- }
730
- }
731
- }
732
-
733
641
  exports.createFormContext = createFormContext;
734
- exports.updateFieldValue = updateFieldValue;
package/dist/form.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.mjs';
2
2
  import { flatten, formatName, getValue, isPlainObject, isPrefix, setValue, normalize, getFormData, getPaths, getChildPaths, formatPaths } from './formdata.mjs';
3
- import { getFormAction, getFormEncType, getFormMethod, isFieldElement, requestSubmit } from './dom.mjs';
3
+ import { getFormAction, getFormEncType, getFormMethod, isFieldElement, requestSubmit, updateField } from './dom.mjs';
4
4
  import { generateId, clone, invariant } from './util.mjs';
5
5
  import { serialize, setListState, setListValue, setState, INTENT, serializeIntent, root, getSubmissionContext } from './submission.mjs';
6
6
 
@@ -578,8 +578,8 @@ function createFormContext(options) {
578
578
  var paths = getChildPaths(parentPaths, element.name);
579
579
  if (paths) {
580
580
  var value = getValue(intent.payload.value, formatPaths(paths));
581
- updateFieldValue(element, {
582
- value: typeof value === 'string' || Array.isArray(value) && value.every(item => typeof item === 'string') ? value : ''
581
+ updateField(element, {
582
+ value: typeof value === 'string' || Array.isArray(value) && value.every(item => typeof item === 'string') ? value : null
583
583
  });
584
584
 
585
585
  // Update the element attribute to notify useControl / useInputControl hook
@@ -593,10 +593,10 @@ function createFormContext(options) {
593
593
  {
594
594
  var prefix = formatName(intent.payload.name, intent.payload.index);
595
595
  for (var _element of formElement.elements) {
596
- if (isFieldElement(_element) && isPrefix(_element.name, prefix)) {
596
+ if (isFieldElement(_element) && _element.name && isPrefix(_element.name, prefix)) {
597
597
  var _value2 = getValue(meta.defaultValue, _element.name);
598
- var defaultValue = typeof _value2 === 'string' || Array.isArray(_value2) && _value2.every(item => typeof item === 'string') ? _value2 : _element instanceof HTMLSelectElement ? [] : '';
599
- updateFieldValue(_element, {
598
+ var defaultValue = typeof _value2 === 'string' || Array.isArray(_value2) && _value2.every(item => typeof item === 'string') ? _value2 : null;
599
+ updateField(_element, {
600
600
  defaultValue,
601
601
  value: defaultValue
602
602
  });
@@ -634,96 +634,4 @@ function createFormContext(options) {
634
634
  };
635
635
  }
636
636
 
637
- /**
638
- * Updates the DOM element with the provided value.
639
- *
640
- * @param element The form element to update
641
- * @param options The options to update the form element
642
- */
643
- function updateFieldValue(element, options) {
644
- var value = typeof options.value === 'undefined' ? null : Array.isArray(options.value) ? Array.from(options.value) : [options.value];
645
- var defaultValue = typeof options.defaultValue === 'undefined' ? null : Array.isArray(options.defaultValue) ? Array.from(options.defaultValue) : [options.defaultValue];
646
- if (element instanceof HTMLInputElement && (element.type === 'checkbox' || element.type === 'radio')) {
647
- if (value) {
648
- element.checked = value.includes(element.value);
649
- }
650
- if (defaultValue) {
651
- element.defaultChecked = defaultValue.includes(element.value);
652
- }
653
- } else if (element instanceof HTMLSelectElement) {
654
- // If the select element is not multiple and the value is an empty array, unset the selected index
655
- // This is to prevent the select element from showing the first option as selected
656
- if (value && value.length === 0 && !element.multiple) {
657
- element.selectedIndex = -1;
658
- }
659
- for (var option of element.options) {
660
- if (value) {
661
- var index = value.indexOf(option.value);
662
- var selected = index > -1;
663
-
664
- // Update the selected state of the option
665
- if (option.selected !== selected) {
666
- option.selected = selected;
667
- }
668
-
669
- // Remove the option from the value array
670
- if (selected) {
671
- value.splice(index, 1);
672
- }
673
- }
674
- if (defaultValue) {
675
- var _index = defaultValue.indexOf(option.value);
676
- var _selected = _index > -1;
677
-
678
- // Update the selected state of the option
679
- if (option.selected !== _selected) {
680
- option.defaultSelected = _selected;
681
- }
682
-
683
- // Remove the option from the defaultValue array
684
- if (_selected) {
685
- defaultValue.splice(_index, 1);
686
- }
687
- }
688
- }
689
-
690
- // We have already removed all selected options from the value and defaultValue array at this point
691
- var missingOptions = new Set([...(value !== null && value !== void 0 ? value : []), ...(defaultValue !== null && defaultValue !== void 0 ? defaultValue : [])]);
692
- for (var optionValue of missingOptions) {
693
- element.options.add(new Option(optionValue, optionValue, defaultValue === null || defaultValue === void 0 ? void 0 : defaultValue.includes(optionValue), value === null || value === void 0 ? void 0 : value.includes(optionValue)));
694
- }
695
- } else {
696
- if (value) {
697
- var _value$;
698
- /**
699
- * Triggering react custom change event
700
- * Solution based on dom-testing-library
701
- * @see https://github.com/facebook/react/issues/10135#issuecomment-401496776
702
- * @see https://github.com/testing-library/dom-testing-library/blob/main/src/events.js#L104-L123
703
- */
704
- var inputValue = (_value$ = value[0]) !== null && _value$ !== void 0 ? _value$ : '';
705
- var {
706
- set: valueSetter
707
- } = Object.getOwnPropertyDescriptor(element, 'value') || {};
708
- var prototype = Object.getPrototypeOf(element);
709
- var {
710
- set: prototypeValueSetter
711
- } = Object.getOwnPropertyDescriptor(prototype, 'value') || {};
712
- if (prototypeValueSetter && valueSetter !== prototypeValueSetter) {
713
- prototypeValueSetter.call(element, inputValue);
714
- } else {
715
- if (valueSetter) {
716
- valueSetter.call(element, inputValue);
717
- } else {
718
- throw new Error('The given element does not have a value setter');
719
- }
720
- }
721
- }
722
- if (defaultValue) {
723
- var _defaultValue$;
724
- element.defaultValue = (_defaultValue$ = defaultValue[0]) !== null && _defaultValue$ !== void 0 ? _defaultValue$ : '';
725
- }
726
- }
727
- }
728
-
729
- export { createFormContext, updateFieldValue };
637
+ export { createFormContext };
@@ -64,4 +64,5 @@ export declare function flatten(data: unknown, options?: {
64
64
  resolve?: (data: unknown) => unknown;
65
65
  prefix?: string;
66
66
  }): Record<string, unknown>;
67
+ export declare function deepEqual<Value>(prev: Value, next: Value): boolean;
67
68
  //# sourceMappingURL=formdata.d.ts.map
package/dist/formdata.js CHANGED
@@ -213,7 +213,43 @@ function flatten(data) {
213
213
  }
214
214
  return result;
215
215
  }
216
+ function deepEqual(prev, next) {
217
+ if (prev === next) {
218
+ return true;
219
+ }
220
+ if (!prev || !next) {
221
+ return false;
222
+ }
223
+ if (Array.isArray(prev) && Array.isArray(next)) {
224
+ if (prev.length !== next.length) {
225
+ return false;
226
+ }
227
+ for (var i = 0; i < prev.length; i++) {
228
+ if (!deepEqual(prev[i], next[i])) {
229
+ return false;
230
+ }
231
+ }
232
+ return true;
233
+ }
234
+ if (isPlainObject(prev) && isPlainObject(next)) {
235
+ var prevKeys = Object.keys(prev);
236
+ var nextKeys = Object.keys(next);
237
+ if (prevKeys.length !== nextKeys.length) {
238
+ return false;
239
+ }
240
+ for (var key of prevKeys) {
241
+ if (!Object.prototype.hasOwnProperty.call(next, key) ||
242
+ // @ts-expect-error FIXME
243
+ !deepEqual(prev[key], next[key])) {
244
+ return false;
245
+ }
246
+ }
247
+ return true;
248
+ }
249
+ return false;
250
+ }
216
251
 
252
+ exports.deepEqual = deepEqual;
217
253
  exports.flatten = flatten;
218
254
  exports.formatName = formatName;
219
255
  exports.formatPaths = formatPaths;
package/dist/formdata.mjs CHANGED
@@ -209,5 +209,40 @@ function flatten(data) {
209
209
  }
210
210
  return result;
211
211
  }
212
+ function deepEqual(prev, next) {
213
+ if (prev === next) {
214
+ return true;
215
+ }
216
+ if (!prev || !next) {
217
+ return false;
218
+ }
219
+ if (Array.isArray(prev) && Array.isArray(next)) {
220
+ if (prev.length !== next.length) {
221
+ return false;
222
+ }
223
+ for (var i = 0; i < prev.length; i++) {
224
+ if (!deepEqual(prev[i], next[i])) {
225
+ return false;
226
+ }
227
+ }
228
+ return true;
229
+ }
230
+ if (isPlainObject(prev) && isPlainObject(next)) {
231
+ var prevKeys = Object.keys(prev);
232
+ var nextKeys = Object.keys(next);
233
+ if (prevKeys.length !== nextKeys.length) {
234
+ return false;
235
+ }
236
+ for (var key of prevKeys) {
237
+ if (!Object.prototype.hasOwnProperty.call(next, key) ||
238
+ // @ts-expect-error FIXME
239
+ !deepEqual(prev[key], next[key])) {
240
+ return false;
241
+ }
242
+ }
243
+ return true;
244
+ }
245
+ return false;
246
+ }
212
247
 
213
- export { flatten, formatName, formatPaths, getChildPaths, getFormData, getPaths, getValue, isFile, isPlainObject, isPrefix, normalize, setValue };
248
+ export { deepEqual, flatten, formatName, formatPaths, getChildPaths, getFormData, getPaths, getValue, isFile, isPlainObject, isPrefix, normalize, setValue };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- export { type Combine, type Constraint, type ControlButtonProps, type FormId, type FieldName, type DefaultValue, type FormValue, type FormOptions, type FormState, type FormContext, type SubscriptionSubject, type SubscriptionScope, createFormContext as unstable_createFormContext, updateFieldValue as unstable_updateFieldValue, } from './form';
2
- export { type FieldElement, isFieldElement } from './dom';
1
+ export { type Combine, type Constraint, type ControlButtonProps, type FormId, type FieldName, type DefaultValue, type FormValue, type FormOptions, type FormState, type FormContext, type SubscriptionSubject, type SubscriptionScope, createFormContext as unstable_createFormContext, } from './form';
2
+ export { type FieldElement, isFieldElement, updateField as unstable_updateField, createFileList, createGlobalFormsObserver as unstable_createGlobalFormsObserver, focus as unstable_focus, change as unstable_change, blur as unstable_blur, } from './dom';
3
3
  export { type Submission, type SubmissionResult, type Intent, INTENT, STATE, serializeIntent, parse, } from './submission';
4
- export { getPaths, formatPaths, isPrefix } from './formdata';
4
+ export { getPaths, formatPaths, isPrefix, deepEqual as unstable_deepEqual, } from './formdata';
5
5
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -10,8 +10,13 @@ var formdata = require('./formdata.js');
10
10
 
11
11
 
12
12
  exports.unstable_createFormContext = form.createFormContext;
13
- exports.unstable_updateFieldValue = form.updateFieldValue;
13
+ exports.createFileList = dom.createFileList;
14
14
  exports.isFieldElement = dom.isFieldElement;
15
+ exports.unstable_blur = dom.blur;
16
+ exports.unstable_change = dom.change;
17
+ exports.unstable_createGlobalFormsObserver = dom.createGlobalFormsObserver;
18
+ exports.unstable_focus = dom.focus;
19
+ exports.unstable_updateField = dom.updateField;
15
20
  exports.INTENT = submission.INTENT;
16
21
  exports.STATE = submission.STATE;
17
22
  exports.parse = submission.parse;
@@ -19,3 +24,4 @@ exports.serializeIntent = submission.serializeIntent;
19
24
  exports.formatPaths = formdata.formatPaths;
20
25
  exports.getPaths = formdata.getPaths;
21
26
  exports.isPrefix = formdata.isPrefix;
27
+ exports.unstable_deepEqual = formdata.deepEqual;
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { createFormContext as unstable_createFormContext, updateFieldValue as unstable_updateFieldValue } from './form.mjs';
2
- export { isFieldElement } from './dom.mjs';
1
+ export { createFormContext as unstable_createFormContext } from './form.mjs';
2
+ export { createFileList, isFieldElement, blur as unstable_blur, change as unstable_change, createGlobalFormsObserver as unstable_createGlobalFormsObserver, focus as unstable_focus, updateField as unstable_updateField } from './dom.mjs';
3
3
  export { INTENT, STATE, parse, serializeIntent } from './submission.mjs';
4
- export { formatPaths, getPaths, isPrefix } from './formdata.mjs';
4
+ export { formatPaths, getPaths, isPrefix, deepEqual as unstable_deepEqual } from './formdata.mjs';
@@ -0,0 +1,3 @@
1
+ declare const _default: import("vite").UserConfig;
2
+ export default _default;
3
+ //# sourceMappingURL=vitest.config.d.ts.map
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "A set of opinionated helpers built on top of the Constraint Validation API",
4
4
  "homepage": "https://conform.guide",
5
5
  "license": "MIT",
6
- "version": "1.6.1",
6
+ "version": "1.7.0",
7
7
  "main": "./dist/index.js",
8
8
  "module": "./dist/index.mjs",
9
9
  "types": "./dist/index.d.ts",