@tanstack/react-form 0.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.
Files changed (40) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +35 -0
  3. package/build/cjs/Field.js +57 -0
  4. package/build/cjs/Field.js.map +1 -0
  5. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js +33 -0
  6. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js.map +1 -0
  7. package/build/cjs/formContext.js +54 -0
  8. package/build/cjs/formContext.js.map +1 -0
  9. package/build/cjs/index.js +27 -0
  10. package/build/cjs/index.js.map +1 -0
  11. package/build/cjs/useField.js +71 -0
  12. package/build/cjs/useField.js.map +1 -0
  13. package/build/cjs/useForm.js +96 -0
  14. package/build/cjs/useForm.js.map +1 -0
  15. package/build/esm/index.js +160 -0
  16. package/build/esm/index.js.map +1 -0
  17. package/build/stats-html.html +2689 -0
  18. package/build/stats-react.json +367 -0
  19. package/build/types/form-core/src/FieldApi.d.ts +69 -0
  20. package/build/types/form-core/src/FormApi.d.ts +74 -0
  21. package/build/types/form-core/src/index.d.ts +3 -0
  22. package/build/types/form-core/src/utils.d.ts +16 -0
  23. package/build/types/index.d.ts +50 -0
  24. package/build/types/react-form/src/Field.d.ts +9 -0
  25. package/build/types/react-form/src/formContext.d.ts +4 -0
  26. package/build/types/react-form/src/index.d.ts +3 -0
  27. package/build/types/react-form/src/tests/test.test.d.ts +0 -0
  28. package/build/types/react-form/src/useField.d.ts +7 -0
  29. package/build/types/react-form/src/useForm.d.ts +25 -0
  30. package/build/umd/index.development.js +907 -0
  31. package/build/umd/index.development.js.map +1 -0
  32. package/build/umd/index.production.js +42 -0
  33. package/build/umd/index.production.js.map +1 -0
  34. package/package.json +55 -0
  35. package/src/Field.tsx +37 -0
  36. package/src/formContext.ts +18 -0
  37. package/src/index.ts +3 -0
  38. package/src/tests/test.test.tsx +5 -0
  39. package/src/useField.ts +54 -0
  40. package/src/useForm.tsx +125 -0
@@ -0,0 +1,907 @@
1
+ /**
2
+ * react-form
3
+ *
4
+ * Copyright (c) TanStack
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE.md file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+ (function (global, factory) {
12
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('use-sync-external-store/shim/with-selector'), require('react')) :
13
+ typeof define === 'function' && define.amd ? define(['exports', 'use-sync-external-store/shim/with-selector', 'react'], factory) :
14
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ReactForm = {}, global.withSelector, global.React));
15
+ })(this, (function (exports, withSelector, React) { 'use strict';
16
+
17
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
18
+
19
+ function _interopNamespace(e) {
20
+ if (e && e.__esModule) return e;
21
+ var n = Object.create(null);
22
+ if (e) {
23
+ Object.keys(e).forEach(function (k) {
24
+ if (k !== 'default') {
25
+ var d = Object.getOwnPropertyDescriptor(e, k);
26
+ Object.defineProperty(n, k, d.get ? d : {
27
+ enumerable: true,
28
+ get: function () { return e[k]; }
29
+ });
30
+ }
31
+ });
32
+ }
33
+ n["default"] = e;
34
+ return Object.freeze(n);
35
+ }
36
+
37
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
38
+ var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
39
+
40
+ function _extends() {
41
+ _extends = Object.assign ? Object.assign.bind() : function (target) {
42
+ for (var i = 1; i < arguments.length; i++) {
43
+ var source = arguments[i];
44
+
45
+ for (var key in source) {
46
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
47
+ target[key] = source[key];
48
+ }
49
+ }
50
+ }
51
+
52
+ return target;
53
+ };
54
+ return _extends.apply(this, arguments);
55
+ }
56
+
57
+ /**
58
+ * store
59
+ *
60
+ * Copyright (c) TanStack
61
+ *
62
+ * This source code is licensed under the MIT license found in the
63
+ * LICENSE.md file in the root directory of this source tree.
64
+ *
65
+ * @license MIT
66
+ */
67
+ class Store {
68
+ listeners = new Set();
69
+ batching = false;
70
+ queue = [];
71
+ constructor(initialState, options) {
72
+ this.state = initialState;
73
+ this.options = options;
74
+ }
75
+ subscribe = listener => {
76
+ this.listeners.add(listener);
77
+ const unsub = this.options?.onSubscribe?.(listener, this);
78
+ return () => {
79
+ this.listeners.delete(listener);
80
+ unsub?.();
81
+ };
82
+ };
83
+ setState = updater => {
84
+ const previous = this.state;
85
+ this.state = this.options?.updateFn ? this.options.updateFn(previous)(updater) : updater(previous);
86
+ if (this.state === previous) return;
87
+ this.options?.onUpdate?.(this.state, previous);
88
+ this.queue.push(() => {
89
+ this.listeners.forEach(listener => listener(this.state, previous));
90
+ });
91
+ this.#flush();
92
+ };
93
+ #flush = () => {
94
+ if (this.batching) return;
95
+ this.queue.forEach(cb => cb());
96
+ this.queue = [];
97
+ };
98
+ batch = cb => {
99
+ this.batching = true;
100
+ cb();
101
+ this.batching = false;
102
+ this.#flush();
103
+ };
104
+ }
105
+
106
+ /**
107
+ * form-core
108
+ *
109
+ * Copyright (c) TanStack
110
+ *
111
+ * This source code is licensed under the MIT license found in the
112
+ * LICENSE.md file in the root directory of this source tree.
113
+ *
114
+ * @license MIT
115
+ */
116
+
117
+ function functionalUpdate(updater, input) {
118
+ return typeof updater === 'function' ? updater(input) : updater;
119
+ }
120
+ function getBy(obj, path) {
121
+ if (!path) {
122
+ throw new Error('A path string is required to use getBy');
123
+ }
124
+
125
+ const pathArray = makePathArray(path);
126
+ const pathObj = pathArray;
127
+ return pathObj.reduce((current, pathPart) => {
128
+ if (typeof current !== 'undefined') {
129
+ return current[pathPart];
130
+ }
131
+
132
+ return undefined;
133
+ }, obj);
134
+ }
135
+ function setBy(obj, _path, updater) {
136
+ const path = makePathArray(_path);
137
+
138
+ function doSet(parent) {
139
+ if (!path.length) {
140
+ return functionalUpdate(updater, parent);
141
+ }
142
+
143
+ const key = path.shift();
144
+
145
+ if (typeof key === 'string') {
146
+ if (typeof parent === 'object') {
147
+ return { ...parent,
148
+ [key]: doSet(parent[key])
149
+ };
150
+ }
151
+
152
+ return {
153
+ [key]: doSet()
154
+ };
155
+ }
156
+
157
+ if (typeof key === 'number') {
158
+ if (Array.isArray(parent)) {
159
+ const prefix = parent.slice(0, key);
160
+ return [...(prefix.length ? prefix : new Array(key)), doSet(parent[key]), ...parent.slice(key + 1)];
161
+ }
162
+
163
+ return [...new Array(key), doSet()];
164
+ }
165
+
166
+ throw new Error('Uh oh!');
167
+ }
168
+
169
+ return doSet(obj);
170
+ }
171
+ const reFindNumbers0 = /^(\d*)$/gm;
172
+ const reFindNumbers1 = /\.(\d*)\./gm;
173
+ const reFindNumbers2 = /^(\d*)\./gm;
174
+ const reFindNumbers3 = /\.(\d*$)/gm;
175
+ const reFindMultiplePeriods = /\.{2,}/gm;
176
+
177
+ function makePathArray(str) {
178
+ return str.replace('[', '.').replace(']', '').replace(reFindNumbers0, '__int__$1').replace(reFindNumbers1, '.__int__$1.').replace(reFindNumbers2, '__int__$1.').replace(reFindNumbers3, '.__int__$1').replace(reFindMultiplePeriods, '.').split('.').map(d => {
179
+ if (d.indexOf('__int__') === 0) {
180
+ return parseInt(d.substring('__int__'.length), 10);
181
+ }
182
+
183
+ return d;
184
+ });
185
+ }
186
+
187
+ function getDefaultFormState(defaultState) {
188
+ return {
189
+ values: {},
190
+ fieldMeta: {},
191
+ canSubmit: true,
192
+ isFieldsValid: false,
193
+ isFieldsValidating: false,
194
+ isFormValid: false,
195
+ isFormValidating: false,
196
+ isSubmitted: false,
197
+ isSubmitting: false,
198
+ isTouched: false,
199
+ isValid: false,
200
+ isValidating: false,
201
+ submissionAttempts: 0,
202
+ formValidationCount: 0,
203
+ ...defaultState
204
+ };
205
+ }
206
+ class FormApi {
207
+ // // This carries the context for nested fields
208
+ constructor(_opts) {
209
+ var _opts$defaultValues, _opts$defaultState;
210
+
211
+ this.options = {};
212
+ this.fieldInfo = {};
213
+ this.validationMeta = {};
214
+
215
+ this.update = options => {
216
+ this.store.batch(() => {
217
+ if (options.defaultState && options.defaultState !== this.options.defaultState) {
218
+ this.store.setState(prev => ({ ...prev,
219
+ ...options.defaultState
220
+ }));
221
+ }
222
+
223
+ if (options.defaultValues !== this.options.defaultValues) {
224
+ this.store.setState(prev => ({ ...prev,
225
+ values: options.defaultValues
226
+ }));
227
+ }
228
+ });
229
+ this.options = options;
230
+ };
231
+
232
+ this.reset = () => this.store.setState(() => getDefaultFormState(this.options.defaultValues));
233
+
234
+ this.validateAllFields = async () => {
235
+ const fieldValidationPromises = [];
236
+ this.store.batch(() => {
237
+ void Object.values(this.fieldInfo).forEach(field => {
238
+ Object.values(field.instances).forEach(instance => {
239
+ // If any fields are not touched
240
+ if (!instance.state.meta.isTouched) {
241
+ // Mark them as touched
242
+ instance.setMeta(prev => ({ ...prev,
243
+ isTouched: true
244
+ })); // Validate the field
245
+
246
+ if (instance.options.validate) {
247
+ fieldValidationPromises.push(instance.validate());
248
+ }
249
+ }
250
+ });
251
+ });
252
+ });
253
+ return Promise.all(fieldValidationPromises);
254
+ };
255
+
256
+ this.validateForm = async () => {
257
+ const {
258
+ validate
259
+ } = this.options;
260
+
261
+ if (!validate) {
262
+ return;
263
+ } // Use the formValidationCount for all field instances to
264
+ // track freshness of the validation
265
+
266
+
267
+ this.store.setState(prev => ({ ...prev,
268
+ isValidating: true,
269
+ formValidationCount: prev.formValidationCount + 1
270
+ }));
271
+ const formValidationCount = this.state.formValidationCount;
272
+
273
+ const checkLatest = () => formValidationCount === this.state.formValidationCount;
274
+
275
+ if (!this.validationMeta.validationPromise) {
276
+ this.validationMeta.validationPromise = new Promise((resolve, reject) => {
277
+ this.validationMeta.validationResolve = resolve;
278
+ this.validationMeta.validationReject = reject;
279
+ });
280
+ }
281
+
282
+ const doValidation = async () => {
283
+ try {
284
+ const error = await validate(this.state.values, this);
285
+
286
+ if (checkLatest()) {
287
+ var _this$validationMeta$, _this$validationMeta;
288
+
289
+ this.store.setState(prev => ({ ...prev,
290
+ isValidating: false,
291
+ error: error ? typeof error === 'string' ? error : 'Invalid Form Values' : null
292
+ }));
293
+ (_this$validationMeta$ = (_this$validationMeta = this.validationMeta).validationResolve) == null ? void 0 : _this$validationMeta$.call(_this$validationMeta, error);
294
+ }
295
+ } catch (err) {
296
+ if (checkLatest()) {
297
+ var _this$validationMeta$2, _this$validationMeta2;
298
+
299
+ (_this$validationMeta$2 = (_this$validationMeta2 = this.validationMeta).validationReject) == null ? void 0 : _this$validationMeta$2.call(_this$validationMeta2, err);
300
+ }
301
+ } finally {
302
+ delete this.validationMeta.validationPromise;
303
+ }
304
+ };
305
+
306
+ doValidation();
307
+ return this.validationMeta.validationPromise;
308
+ };
309
+
310
+ this.handleSubmit = async e => {
311
+ e.preventDefault();
312
+ e.stopPropagation(); // Check to see that the form and all fields have been touched
313
+ // If they have not, touch them all and run validation
314
+ // Run form validation
315
+ // Submit the form
316
+
317
+ this.store.setState(old => ({ ...old,
318
+ // Submittion attempts mark the form as not submitted
319
+ isSubmitted: false,
320
+ // Count submission attempts
321
+ submissionAttempts: old.submissionAttempts + 1
322
+ })); // Don't let invalid forms submit
323
+
324
+ if (!this.state.canSubmit) return;
325
+ this.store.setState(d => ({ ...d,
326
+ isSubmitting: true
327
+ }));
328
+
329
+ const done = () => {
330
+ this.store.setState(prev => ({ ...prev,
331
+ isSubmitting: false
332
+ }));
333
+ }; // Validate all fields
334
+
335
+
336
+ await this.validateAllFields(); // Fields are invalid, do not submit
337
+
338
+ if (!this.state.isFieldsValid) {
339
+ var _this$options$onInval, _this$options;
340
+
341
+ done();
342
+ (_this$options$onInval = (_this$options = this.options).onInvalidSubmit) == null ? void 0 : _this$options$onInval.call(_this$options, this.state.values, this);
343
+ return;
344
+ } // Run validation for the form
345
+
346
+
347
+ await this.validateForm();
348
+
349
+ if (!this.state.isValid) {
350
+ var _this$options$onInval2, _this$options2;
351
+
352
+ done();
353
+ (_this$options$onInval2 = (_this$options2 = this.options).onInvalidSubmit) == null ? void 0 : _this$options$onInval2.call(_this$options2, this.state.values, this);
354
+ return;
355
+ }
356
+
357
+ try {
358
+ var _this$options$onSubmi, _this$options3;
359
+
360
+ // Run the submit code
361
+ await ((_this$options$onSubmi = (_this$options3 = this.options).onSubmit) == null ? void 0 : _this$options$onSubmi.call(_this$options3, this.state.values, this));
362
+ this.store.batch(() => {
363
+ this.store.setState(prev => ({ ...prev,
364
+ isSubmitted: true
365
+ }));
366
+ done();
367
+ });
368
+ } catch (err) {
369
+ done();
370
+ throw err;
371
+ }
372
+ };
373
+
374
+ this.getFieldValue = field => getBy(this.state.values, field);
375
+
376
+ this.getFieldMeta = field => {
377
+ return this.state.fieldMeta[field];
378
+ };
379
+
380
+ this.getFieldInfo = field => {
381
+ var _this$fieldInfo;
382
+
383
+ return (_this$fieldInfo = this.fieldInfo)[field] || (_this$fieldInfo[field] = {
384
+ instances: {}
385
+ });
386
+ };
387
+
388
+ this.setFieldMeta = (field, updater) => {
389
+ this.store.setState(prev => {
390
+ return { ...prev,
391
+ fieldMeta: { ...prev.fieldMeta,
392
+ [field]: functionalUpdate(updater, prev.fieldMeta[field])
393
+ }
394
+ };
395
+ });
396
+ };
397
+
398
+ this.setFieldValue = (field, updater, opts) => {
399
+ var _opts$touch;
400
+
401
+ const touch = (_opts$touch = opts == null ? void 0 : opts.touch) != null ? _opts$touch : true;
402
+ this.store.batch(() => {
403
+ this.store.setState(prev => {
404
+ return { ...prev,
405
+ values: setBy(prev.values, field, updater)
406
+ };
407
+ });
408
+
409
+ if (touch) {
410
+ this.setFieldMeta(field, prev => ({ ...prev,
411
+ isTouched: true
412
+ }));
413
+ }
414
+ });
415
+ };
416
+
417
+ this.pushFieldValue = (field, value, opts) => {
418
+ return this.setFieldValue(field, prev => [...(Array.isArray(prev) ? prev : []), value], opts);
419
+ };
420
+
421
+ this.insertFieldValue = (field, index, value, opts) => {
422
+ this.setFieldValue(field, prev => {
423
+ // invariant( // TODO: bring in invariant
424
+ // Array.isArray(prev),
425
+ // `Cannot insert a field value into a non-array field. Check that this field's existing value is an array: ${field}.`
426
+ // )
427
+ return prev.map((d, i) => i === index ? value : d);
428
+ }, opts);
429
+ };
430
+
431
+ this.spliceFieldValue = (field, index, opts) => {
432
+ this.setFieldValue(field, prev => {
433
+ // invariant( // TODO: bring in invariant
434
+ // Array.isArray(prev),
435
+ // `Cannot insert a field value into a non-array field. Check that this field's existing value is an array: ${field}.`
436
+ // )
437
+ return prev.filter((_d, i) => i !== index);
438
+ }, opts);
439
+ };
440
+
441
+ this.swapFieldValues = (field, index1, index2) => {
442
+ this.setFieldValue(field, prev => {
443
+ const prev1 = prev[index1];
444
+ const prev2 = prev[index2];
445
+ return setBy(setBy(prev, [index1], prev2), [index2], prev1);
446
+ });
447
+ };
448
+
449
+ this.store = new Store(getDefaultFormState({ ...(_opts == null ? void 0 : _opts.defaultState),
450
+ values: (_opts$defaultValues = _opts == null ? void 0 : _opts.defaultValues) != null ? _opts$defaultValues : _opts == null ? void 0 : (_opts$defaultState = _opts.defaultState) == null ? void 0 : _opts$defaultState.values,
451
+ isFormValid: !(_opts != null && _opts.validate)
452
+ }), {
453
+ onUpdate: next => {
454
+ // Computed state
455
+ const fieldMetaValues = Object.values(next.fieldMeta);
456
+ const isFieldsValidating = fieldMetaValues.some(field => field == null ? void 0 : field.isValidating);
457
+ const isFieldsValid = !fieldMetaValues.some(field => field == null ? void 0 : field.error);
458
+ const isTouched = fieldMetaValues.some(field => field == null ? void 0 : field.isTouched);
459
+ const isValidating = isFieldsValidating || next.isFormValidating;
460
+ const isFormValid = !next.formError;
461
+ const isValid = isFieldsValid && isFormValid;
462
+ const canSubmit = next.submissionAttempts === 0 && !isTouched || !isValidating && !next.isSubmitting && isValid;
463
+ next = { ...next,
464
+ isFieldsValidating,
465
+ isFieldsValid,
466
+ isFormValid,
467
+ isValid,
468
+ canSubmit,
469
+ isTouched
470
+ }; // Create a shortcut for the state
471
+ // Write it back to the store
472
+
473
+ this.store.state = next;
474
+ this.state = next;
475
+ }
476
+ });
477
+ this.state = this.store.state;
478
+ this.update(_opts || {});
479
+ }
480
+
481
+ }
482
+
483
+ var id = 0;
484
+
485
+ function _classPrivateFieldLooseKey(name) {
486
+ return "__private_" + id++ + "_" + name;
487
+ }
488
+
489
+ function _classPrivateFieldLooseBase(receiver, privateKey) {
490
+ if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) {
491
+ throw new TypeError("attempted to use private field on non-instance");
492
+ }
493
+
494
+ return receiver;
495
+ }
496
+
497
+ let uid = 0;
498
+
499
+ var _updateStore = /*#__PURE__*/_classPrivateFieldLooseKey("updateStore");
500
+
501
+ var _validate = /*#__PURE__*/_classPrivateFieldLooseKey("validate");
502
+
503
+ class FieldApi {
504
+ constructor(_opts) {
505
+ var _this$getMeta;
506
+
507
+ this.options = {};
508
+
509
+ this.mount = () => {
510
+ const info = this.getInfo();
511
+ info.instances[this.uid] = this;
512
+ const unsubscribe = this.form.store.subscribe(() => {
513
+ _classPrivateFieldLooseBase(this, _updateStore)[_updateStore]();
514
+ });
515
+ return () => {
516
+ unsubscribe();
517
+ delete info.instances[this.uid];
518
+
519
+ if (!Object.keys(info.instances).length) {
520
+ delete this.form.fieldInfo[this.name];
521
+ }
522
+ };
523
+ };
524
+
525
+ Object.defineProperty(this, _updateStore, {
526
+ writable: true,
527
+ value: () => {
528
+ this.store.batch(() => {
529
+ const nextValue = this.getValue();
530
+ const nextMeta = this.getMeta();
531
+
532
+ if (nextValue !== this.state.value) {
533
+ this.store.setState(prev => ({ ...prev,
534
+ value: nextValue
535
+ }));
536
+ }
537
+
538
+ if (nextMeta !== this.state.meta) {
539
+ this.store.setState(prev => ({ ...prev,
540
+ meta: nextMeta
541
+ }));
542
+ }
543
+ });
544
+ }
545
+ });
546
+
547
+ this.update = opts => {
548
+ this.options = {
549
+ validateOn: 'change',
550
+ validateAsyncOn: 'blur',
551
+ validateAsyncDebounceMs: 0,
552
+ ...opts
553
+ }; // Default Value
554
+
555
+ if (this.state.value === undefined && this.options.defaultValue !== undefined) {
556
+ this.setValue(this.options.defaultValue);
557
+ } // Default Meta
558
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
559
+
560
+
561
+ if (this.getMeta() === undefined) {
562
+ this.setMeta(this.state.meta);
563
+ }
564
+ };
565
+
566
+ this.getValue = () => this.form.getFieldValue(this.name);
567
+
568
+ this.setValue = (updater, options) => this.form.setFieldValue(this.name, updater, options);
569
+
570
+ this.getMeta = () => this.form.getFieldMeta(this.name);
571
+
572
+ this.setMeta = updater => this.form.setFieldMeta(this.name, updater);
573
+
574
+ this.getInfo = () => this.form.getFieldInfo(this.name);
575
+
576
+ this.pushValue = value => this.form.pushFieldValue(this.name, value);
577
+
578
+ this.insertValue = (index, value) => this.form.insertFieldValue(this.name, index, value);
579
+
580
+ this.removeValue = index => this.form.spliceFieldValue(this.name, index);
581
+
582
+ this.swapValues = (aIndex, bIndex) => this.form.swapFieldValues(this.name, aIndex, bIndex);
583
+
584
+ this.getSubField = name => new FieldApi({
585
+ name: this.name + "." + name,
586
+ form: this.form
587
+ });
588
+
589
+ Object.defineProperty(this, _validate, {
590
+ writable: true,
591
+ value: async isAsync => {
592
+ if (!this.options.validate) {
593
+ return;
594
+ }
595
+
596
+ this.setMeta(prev => ({ ...prev,
597
+ isValidating: true
598
+ })); // Use the validationCount for all field instances to
599
+ // track freshness of the validation
600
+
601
+ const validationCount = (this.getInfo().validationCount || 0) + 1;
602
+ this.getInfo().validationCount = validationCount;
603
+
604
+ const checkLatest = () => validationCount === this.getInfo().validationCount;
605
+
606
+ if (!this.getInfo().validationPromise) {
607
+ this.getInfo().validationPromise = new Promise((resolve, reject) => {
608
+ this.getInfo().validationResolve = resolve;
609
+ this.getInfo().validationReject = reject;
610
+ });
611
+ }
612
+
613
+ try {
614
+ const rawError = await this.options.validate(this.state.value, this);
615
+
616
+ if (checkLatest()) {
617
+ var _this$getInfo$validat, _this$getInfo;
618
+
619
+ const error = (() => {
620
+ if (rawError) {
621
+ if (typeof rawError !== 'string') {
622
+ return 'Invalid Form Values';
623
+ }
624
+
625
+ return rawError;
626
+ }
627
+
628
+ return undefined;
629
+ })();
630
+
631
+ this.setMeta(prev => ({ ...prev,
632
+ isValidating: false,
633
+ error
634
+ }));
635
+ (_this$getInfo$validat = (_this$getInfo = this.getInfo()).validationResolve) == null ? void 0 : _this$getInfo$validat.call(_this$getInfo, error);
636
+ }
637
+ } catch (error) {
638
+ if (checkLatest()) {
639
+ var _this$getInfo$validat2, _this$getInfo2;
640
+
641
+ (_this$getInfo$validat2 = (_this$getInfo2 = this.getInfo()).validationReject) == null ? void 0 : _this$getInfo$validat2.call(_this$getInfo2, error);
642
+ throw error;
643
+ }
644
+ } finally {
645
+ if (checkLatest()) {
646
+ this.setMeta(prev => ({ ...prev,
647
+ isValidating: false
648
+ }));
649
+ delete this.getInfo().validationPromise;
650
+ }
651
+ }
652
+
653
+ return this.getInfo().validationPromise;
654
+ }
655
+ });
656
+
657
+ this.validate = () => _classPrivateFieldLooseBase(this, _validate)[_validate](false);
658
+
659
+ this.validateAsync = () => _classPrivateFieldLooseBase(this, _validate)[_validate](true);
660
+
661
+ this.getChangeProps = (props = {}) => {
662
+ return { ...props,
663
+ value: this.state.value,
664
+ onChange: value => {
665
+ this.setValue(value);
666
+ props.onChange == null ? void 0 : props.onChange(value);
667
+ },
668
+ onBlur: e => {
669
+ this.setMeta(prev => ({ ...prev,
670
+ isTouched: true
671
+ }));
672
+ const {
673
+ validateOn
674
+ } = this.options;
675
+
676
+ if (validateOn === 'blur' || validateOn.split('-')[0] === 'blur') {
677
+ this.validate();
678
+ }
679
+
680
+ props.onBlur == null ? void 0 : props.onBlur(e);
681
+ }
682
+ };
683
+ };
684
+
685
+ this.getInputProps = (props = {}) => {
686
+ return { ...props,
687
+ value: String(this.state.value),
688
+ onChange: e => {
689
+ this.setValue(e.target.value);
690
+ props.onChange == null ? void 0 : props.onChange(e.target.value);
691
+ },
692
+ onBlur: this.getChangeProps(props).onBlur
693
+ };
694
+ };
695
+
696
+ this.form = _opts.form;
697
+ this.uid = uid++; // Support field prefixing from FieldScope
698
+
699
+ let fieldPrefix = '';
700
+
701
+ if (this.form.fieldName) {
702
+ fieldPrefix = this.form.fieldName + ".";
703
+ }
704
+
705
+ this.name = fieldPrefix + _opts.name;
706
+ this.store = new Store({
707
+ value: this.getValue(),
708
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
709
+ meta: (_this$getMeta = this.getMeta()) != null ? _this$getMeta : {
710
+ isValidating: false,
711
+ isTouched: false,
712
+ ...this.options.defaultMeta
713
+ }
714
+ }, {
715
+ onUpdate: next => {
716
+ next.meta.touchedError = next.meta.isTouched ? next.meta.error : undefined; // Do not validate pristine fields
717
+
718
+ if (!this.options.validatePristine && !next.meta.isTouched) return; // If validateOn is set to a variation of change, run the validation
719
+
720
+ if (this.options.validateOn === 'change' || this.options.validateOn.split('-')[0] === 'change') {
721
+ try {
722
+ this.validate();
723
+ } catch (err) {
724
+ console.error('An error occurred during validation', err);
725
+ }
726
+ }
727
+
728
+ this.state = next;
729
+ }
730
+ });
731
+ this.state = this.store.state;
732
+ this.update(_opts);
733
+ }
734
+
735
+ }
736
+
737
+ /**
738
+ * react-store
739
+ *
740
+ * Copyright (c) TanStack
741
+ *
742
+ * This source code is licensed under the MIT license found in the
743
+ * LICENSE.md file in the root directory of this source tree.
744
+ *
745
+ * @license MIT
746
+ */
747
+
748
+ function useStore(store, selector = d => d) {
749
+ const slice = withSelector.useSyncExternalStoreWithSelector(store.subscribe, () => store.state, () => store.state, selector, shallow);
750
+ return slice;
751
+ }
752
+ function shallow(objA, objB) {
753
+ if (Object.is(objA, objB)) {
754
+ return true;
755
+ }
756
+ if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
757
+ return false;
758
+ }
759
+ const keysA = Object.keys(objA);
760
+ if (keysA.length !== Object.keys(objB).length) {
761
+ return false;
762
+ }
763
+ for (let i = 0; i < keysA.length; i++) {
764
+ if (!Object.prototype.hasOwnProperty.call(objB, keysA[i]) || !Object.is(objA[keysA[i]], objB[keysA[i]])) {
765
+ return false;
766
+ }
767
+ }
768
+ return true;
769
+ }
770
+
771
+ const formContext = /*#__PURE__*/React__namespace.createContext(null);
772
+ function useFormContext(customFormApi) {
773
+ const formApi = React__namespace.useContext(formContext);
774
+
775
+ if (customFormApi) {
776
+ return customFormApi;
777
+ }
778
+
779
+ if (!formApi) {
780
+ throw new Error("You are trying to use the form API outside of a form!");
781
+ }
782
+
783
+ return formApi;
784
+ }
785
+
786
+ function createUseField(formApi) {
787
+ const useFormField = opts => {
788
+ return useField({ ...opts,
789
+ form: formApi
790
+ });
791
+ };
792
+
793
+ return useFormField;
794
+ }
795
+ function useField(opts) {
796
+ // invariant( // TODO:
797
+ // opts.name,
798
+ // `useField: A field is required to use this hook. eg, useField('myField', options)`
799
+ // )
800
+ // Get the form API either manually or from context
801
+ const formApi = useFormContext(opts.form);
802
+ const [fieldApi] = React__namespace.useState(() => new FieldApi({ ...opts,
803
+ form: formApi
804
+ })); // Keep options up to date as they are rendered
805
+
806
+ fieldApi.update({ ...opts,
807
+ form: formApi
808
+ });
809
+ useStore(fieldApi.store); // Instantiates field meta and removes it when unrendered
810
+
811
+ React__namespace.useEffect(() => fieldApi.mount(), [fieldApi]);
812
+ return fieldApi;
813
+ }
814
+
815
+ function createFieldComponent(formApi) {
816
+ const ConnectedField = props => /*#__PURE__*/React__namespace.createElement(Field, _extends({}, props, {
817
+ form: formApi
818
+ }));
819
+
820
+ return ConnectedField;
821
+ }
822
+ function Field({
823
+ children,
824
+ ...fieldOptions
825
+ }) {
826
+ const fieldApi = useField(fieldOptions);
827
+ return functionalUpdate(children, fieldApi);
828
+ }
829
+
830
+ //
831
+ function useForm(opts) {
832
+ const [formApi] = React__default["default"].useState(() => {
833
+ // @ts-ignore
834
+ const api = new FormApi(opts || {});
835
+ api.Form = createFormComponent(api);
836
+ api.Field = createFieldComponent(api);
837
+ api.useField = createUseField(api);
838
+
839
+ api.useStore = ( // @ts-ignore
840
+ selector) => {
841
+ // eslint-disable-next-line react-hooks/rules-of-hooks
842
+ return useStore(api.store, selector);
843
+ };
844
+
845
+ api.Subscribe = ( // @ts-ignore
846
+ props) => {
847
+ return functionalUpdate(props.children, // eslint-disable-next-line react-hooks/rules-of-hooks
848
+ useStore(api.store, props.selector));
849
+ };
850
+
851
+ return api;
852
+ }); // React.useEffect(() => formApi.mount(), [])
853
+
854
+ return formApi;
855
+ }
856
+ function createFormComponent(formApi) {
857
+ const Form = ({
858
+ children,
859
+ noFormElement,
860
+ ...rest
861
+ }) => {
862
+ const isSubmitting = formApi.useStore(state => state.isSubmitting);
863
+ return /*#__PURE__*/React__default["default"].createElement(formContext.Provider, {
864
+ value: formApi
865
+ }, noFormElement ? children : /*#__PURE__*/React__default["default"].createElement("form", _extends({
866
+ onSubmit: formApi.handleSubmit,
867
+ disabled: isSubmitting
868
+ }, rest), formApi.options.debugForm ? /*#__PURE__*/React__default["default"].createElement("div", {
869
+ style: {
870
+ margin: '2rem 0'
871
+ }
872
+ }, /*#__PURE__*/React__default["default"].createElement("div", {
873
+ style: {
874
+ fontWeight: 'bolder'
875
+ }
876
+ }, "Form State"), /*#__PURE__*/React__default["default"].createElement("pre", null, /*#__PURE__*/React__default["default"].createElement("code", null, JSON.stringify(formApi, safeStringifyReplace(), 2)))) : null, children));
877
+ };
878
+
879
+ return Form;
880
+ }
881
+
882
+ function safeStringifyReplace() {
883
+ const set = new Set();
884
+ return (_key, value) => {
885
+ if (typeof value === 'object' || Array.isArray(value)) {
886
+ if (set.has(value)) {
887
+ return '(circular value)';
888
+ }
889
+
890
+ set.add(value);
891
+ }
892
+
893
+ return typeof value === 'function' ? undefined : value;
894
+ };
895
+ }
896
+
897
+ exports.Field = Field;
898
+ exports.createFieldComponent = createFieldComponent;
899
+ exports.createFormComponent = createFormComponent;
900
+ exports.createUseField = createUseField;
901
+ exports.useField = useField;
902
+ exports.useForm = useForm;
903
+
904
+ Object.defineProperty(exports, '__esModule', { value: true });
905
+
906
+ }));
907
+ //# sourceMappingURL=index.development.js.map