@vuehookform/core 0.1.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.
@@ -0,0 +1,644 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let vue = require("vue");
3
+ function get(obj, path) {
4
+ if (!path) return obj;
5
+ const keys = path.split(".");
6
+ let result = obj;
7
+ for (const key of keys) {
8
+ if (result === null || result === void 0) return;
9
+ result = result[key];
10
+ }
11
+ return result;
12
+ }
13
+ function set(obj, path, value) {
14
+ if (!path) return;
15
+ const keys = path.split(".");
16
+ const UNSAFE_KEYS = [
17
+ "__proto__",
18
+ "constructor",
19
+ "prototype"
20
+ ];
21
+ if (keys.some((k) => UNSAFE_KEYS.includes(k))) return;
22
+ const lastKey = keys.pop();
23
+ let current = obj;
24
+ for (const key of keys) {
25
+ if (!(key in current) || typeof current[key] !== "object") {
26
+ const nextKey = keys[keys.indexOf(key) + 1];
27
+ current[key] = nextKey && /^\d+$/.test(nextKey) ? [] : {};
28
+ }
29
+ current = current[key];
30
+ }
31
+ current[lastKey] = value;
32
+ }
33
+ function unset(obj, path) {
34
+ if (!path) return;
35
+ const keys = path.split(".");
36
+ const lastKey = keys.pop();
37
+ let current = obj;
38
+ for (const key of keys) {
39
+ if (!(key in current)) return;
40
+ current = current[key];
41
+ }
42
+ delete current[lastKey];
43
+ }
44
+ var idCounter = 0;
45
+ function generateId() {
46
+ return `field_${Date.now()}_${idCounter++}`;
47
+ }
48
+ function createFormContext(options) {
49
+ const formData = (0, vue.reactive)({});
50
+ const defaultValues = (0, vue.reactive)({});
51
+ const isAsyncDefaults = typeof options.defaultValues === "function";
52
+ const isLoading = (0, vue.ref)(isAsyncDefaults);
53
+ if (isAsyncDefaults) {
54
+ const asyncFn = options.defaultValues;
55
+ asyncFn().then((values) => {
56
+ Object.assign(defaultValues, values);
57
+ Object.assign(formData, values);
58
+ isLoading.value = false;
59
+ }).catch((error) => {
60
+ console.error("Failed to load async default values:", error);
61
+ isLoading.value = false;
62
+ });
63
+ } else if (options.defaultValues) {
64
+ Object.assign(defaultValues, options.defaultValues);
65
+ Object.assign(formData, defaultValues);
66
+ }
67
+ return {
68
+ formData,
69
+ defaultValues,
70
+ errors: (0, vue.shallowRef)({}),
71
+ touchedFields: (0, vue.ref)({}),
72
+ dirtyFields: (0, vue.ref)({}),
73
+ isSubmitting: (0, vue.ref)(false),
74
+ isLoading,
75
+ submitCount: (0, vue.ref)(0),
76
+ fieldRefs: /* @__PURE__ */ new Map(),
77
+ fieldOptions: /* @__PURE__ */ new Map(),
78
+ fieldArrays: /* @__PURE__ */ new Map(),
79
+ debounceTimers: /* @__PURE__ */ new Map(),
80
+ validationRequestIds: /* @__PURE__ */ new Map(),
81
+ options
82
+ };
83
+ }
84
+ function clearFieldErrors(errors, fieldPath) {
85
+ const newErrors = { ...errors };
86
+ for (const key of Object.keys(newErrors)) if (key === fieldPath || key.startsWith(`${fieldPath}.`)) delete newErrors[key];
87
+ return newErrors;
88
+ }
89
+ function groupErrorsByPath(issues) {
90
+ const grouped = /* @__PURE__ */ new Map();
91
+ for (const issue of issues) {
92
+ const path = issue.path.join(".");
93
+ const existing = grouped.get(path) || [];
94
+ existing.push({
95
+ type: issue.code,
96
+ message: issue.message
97
+ });
98
+ grouped.set(path, existing);
99
+ }
100
+ return grouped;
101
+ }
102
+ function createFieldError(errors) {
103
+ if (errors.length === 1) return errors[0].message;
104
+ const types = {};
105
+ for (const err of errors) {
106
+ const existing = types[err.type];
107
+ if (existing) types[err.type] = Array.isArray(existing) ? [...existing, err.message] : [existing, err.message];
108
+ else types[err.type] = err.message;
109
+ }
110
+ return {
111
+ type: errors[0].type,
112
+ message: errors[0].message,
113
+ types
114
+ };
115
+ }
116
+ function createValidation(ctx) {
117
+ async function validate(fieldPath) {
118
+ const result = await ctx.options.schema.safeParseAsync(ctx.formData);
119
+ if (result.success) {
120
+ if (fieldPath) ctx.errors.value = clearFieldErrors(ctx.errors.value, fieldPath);
121
+ else ctx.errors.value = {};
122
+ return true;
123
+ }
124
+ const zodErrors = result.error.issues;
125
+ if (fieldPath) {
126
+ const fieldErrors = zodErrors.filter((issue) => {
127
+ const path = issue.path.join(".");
128
+ return path === fieldPath || path.startsWith(`${fieldPath}.`);
129
+ });
130
+ if (fieldErrors.length === 0) {
131
+ ctx.errors.value = clearFieldErrors(ctx.errors.value, fieldPath);
132
+ return true;
133
+ }
134
+ let newErrors$1 = clearFieldErrors(ctx.errors.value, fieldPath);
135
+ const grouped$1 = groupErrorsByPath(fieldErrors);
136
+ for (const [path, errors] of grouped$1) set(newErrors$1, path, createFieldError(errors));
137
+ ctx.errors.value = newErrors$1;
138
+ return false;
139
+ }
140
+ const newErrors = {};
141
+ const grouped = groupErrorsByPath(zodErrors);
142
+ for (const [path, errors] of grouped) set(newErrors, path, createFieldError(errors));
143
+ ctx.errors.value = newErrors;
144
+ return false;
145
+ }
146
+ return { validate };
147
+ }
148
+ function createFieldRegistration(ctx, validate) {
149
+ function register(name, registerOptions) {
150
+ const fieldRef = (0, vue.ref)(null);
151
+ ctx.fieldRefs.set(name, fieldRef);
152
+ if (registerOptions) ctx.fieldOptions.set(name, registerOptions);
153
+ if (get(ctx.formData, name) === void 0) {
154
+ const defaultValue = get(ctx.defaultValues, name);
155
+ if (defaultValue !== void 0) set(ctx.formData, name, defaultValue);
156
+ }
157
+ const runCustomValidation = async (fieldName, value, requestId) => {
158
+ const fieldOpts = ctx.fieldOptions.get(fieldName);
159
+ if (!fieldOpts?.validate || fieldOpts.disabled) return;
160
+ const error = await fieldOpts.validate(value);
161
+ if (requestId !== ctx.validationRequestIds.get(fieldName)) return;
162
+ if (error) ctx.errors.value = {
163
+ ...ctx.errors.value,
164
+ [fieldName]: error
165
+ };
166
+ else {
167
+ const newErrors = { ...ctx.errors.value };
168
+ delete newErrors[fieldName];
169
+ ctx.errors.value = newErrors;
170
+ }
171
+ };
172
+ const onInput = async (e) => {
173
+ const target = e.target;
174
+ const value = target.type === "checkbox" ? target.checked : target.value;
175
+ set(ctx.formData, name, value);
176
+ ctx.dirtyFields.value = {
177
+ ...ctx.dirtyFields.value,
178
+ [name]: true
179
+ };
180
+ if (ctx.options.mode === "onChange" || ctx.options.mode === "onTouched" && ctx.touchedFields.value[name] || ctx.touchedFields.value[name] && ctx.options.reValidateMode === "onChange") await validate(name);
181
+ const fieldOpts = ctx.fieldOptions.get(name);
182
+ if (fieldOpts?.validate && !fieldOpts.disabled) {
183
+ const requestId = Date.now() + Math.random();
184
+ ctx.validationRequestIds.set(name, requestId);
185
+ const debounceMs = fieldOpts.validateDebounce || 0;
186
+ if (debounceMs > 0) {
187
+ const existingTimer = ctx.debounceTimers.get(name);
188
+ if (existingTimer) clearTimeout(existingTimer);
189
+ const timer = setTimeout(() => {
190
+ ctx.debounceTimers.delete(name);
191
+ runCustomValidation(name, value, requestId);
192
+ }, debounceMs);
193
+ ctx.debounceTimers.set(name, timer);
194
+ } else await runCustomValidation(name, value, requestId);
195
+ }
196
+ };
197
+ const onBlur = async (_e) => {
198
+ ctx.touchedFields.value = {
199
+ ...ctx.touchedFields.value,
200
+ [name]: true
201
+ };
202
+ if (ctx.options.mode === "onBlur" || ctx.options.mode === "onTouched" || ctx.submitCount.value > 0 && ctx.options.reValidateMode === "onBlur") await validate(name);
203
+ };
204
+ const refCallback = (el) => {
205
+ const previousEl = fieldRef.value;
206
+ fieldRef.value = el;
207
+ if (el && !registerOptions?.controlled && el instanceof HTMLInputElement) {
208
+ const value = get(ctx.formData, name);
209
+ if (value !== void 0) if (el.type === "checkbox") el.checked = value;
210
+ else el.value = value;
211
+ }
212
+ if (previousEl && !el) {
213
+ if (registerOptions?.shouldUnregister ?? ctx.options.shouldUnregister ?? false) {
214
+ unset(ctx.formData, name);
215
+ const newErrors = { ...ctx.errors.value };
216
+ delete newErrors[name];
217
+ ctx.errors.value = newErrors;
218
+ const newTouched = { ...ctx.touchedFields.value };
219
+ delete newTouched[name];
220
+ ctx.touchedFields.value = newTouched;
221
+ const newDirty = { ...ctx.dirtyFields.value };
222
+ delete newDirty[name];
223
+ ctx.dirtyFields.value = newDirty;
224
+ ctx.fieldRefs.delete(name);
225
+ ctx.fieldOptions.delete(name);
226
+ const timer = ctx.debounceTimers.get(name);
227
+ if (timer) {
228
+ clearTimeout(timer);
229
+ ctx.debounceTimers.delete(name);
230
+ }
231
+ ctx.validationRequestIds.delete(name);
232
+ }
233
+ }
234
+ };
235
+ return {
236
+ name,
237
+ ref: refCallback,
238
+ onInput,
239
+ onBlur,
240
+ ...registerOptions?.controlled && { value: (0, vue.computed)({
241
+ get: () => get(ctx.formData, name),
242
+ set: (val) => {
243
+ set(ctx.formData, name, val);
244
+ ctx.dirtyFields.value = {
245
+ ...ctx.dirtyFields.value,
246
+ [name]: true
247
+ };
248
+ }
249
+ }) }
250
+ };
251
+ }
252
+ function unregister(name) {
253
+ ctx.fieldRefs.delete(name);
254
+ ctx.fieldOptions.delete(name);
255
+ const timer = ctx.debounceTimers.get(name);
256
+ if (timer) {
257
+ clearTimeout(timer);
258
+ ctx.debounceTimers.delete(name);
259
+ }
260
+ ctx.validationRequestIds.delete(name);
261
+ }
262
+ return {
263
+ register,
264
+ unregister
265
+ };
266
+ }
267
+ function createFieldArrayManager(ctx, validate) {
268
+ function fields(name) {
269
+ let fieldArray = ctx.fieldArrays.get(name);
270
+ if (!fieldArray) {
271
+ const existingValues = get(ctx.formData, name) || [];
272
+ fieldArray = {
273
+ items: (0, vue.ref)([]),
274
+ values: existingValues
275
+ };
276
+ ctx.fieldArrays.set(name, fieldArray);
277
+ if (!get(ctx.formData, name)) set(ctx.formData, name, []);
278
+ }
279
+ const fa = fieldArray;
280
+ const createItem = (key) => ({
281
+ key,
282
+ get index() {
283
+ return fa.items.value.findIndex((item) => item.key === key);
284
+ },
285
+ remove() {
286
+ const currentIndex = fa.items.value.findIndex((item) => item.key === key);
287
+ if (currentIndex !== -1) removeAt(currentIndex);
288
+ }
289
+ });
290
+ if (fa.items.value.length === 0 && fa.values.length > 0) fa.items.value = fa.values.map(() => createItem(generateId()));
291
+ const append = (value) => {
292
+ const newValues = [...get(ctx.formData, name) || [], value];
293
+ set(ctx.formData, name, newValues);
294
+ fa.items.value = [...fa.items.value, createItem(generateId())];
295
+ ctx.dirtyFields.value = {
296
+ ...ctx.dirtyFields.value,
297
+ [name]: true
298
+ };
299
+ if (ctx.options.mode === "onChange") validate(name);
300
+ };
301
+ const prepend = (value) => {
302
+ insert(0, value);
303
+ };
304
+ const update = (index, value) => {
305
+ const currentValues = get(ctx.formData, name) || [];
306
+ if (index < 0 || index >= currentValues.length) return;
307
+ const newValues = [...currentValues];
308
+ newValues[index] = value;
309
+ set(ctx.formData, name, newValues);
310
+ ctx.dirtyFields.value = {
311
+ ...ctx.dirtyFields.value,
312
+ [name]: true
313
+ };
314
+ if (ctx.options.mode === "onChange") validate(name);
315
+ };
316
+ const removeAt = (index) => {
317
+ const newValues = (get(ctx.formData, name) || []).filter((_, i) => i !== index);
318
+ set(ctx.formData, name, newValues);
319
+ const keyToRemove = fa.items.value[index]?.key;
320
+ fa.items.value = fa.items.value.filter((item) => item.key !== keyToRemove);
321
+ ctx.dirtyFields.value = {
322
+ ...ctx.dirtyFields.value,
323
+ [name]: true
324
+ };
325
+ if (ctx.options.mode === "onChange") validate(name);
326
+ };
327
+ const insert = (index, value) => {
328
+ const currentValues = get(ctx.formData, name) || [];
329
+ const newValues = [
330
+ ...currentValues.slice(0, index),
331
+ value,
332
+ ...currentValues.slice(index)
333
+ ];
334
+ set(ctx.formData, name, newValues);
335
+ const newItem = createItem(generateId());
336
+ fa.items.value = [
337
+ ...fa.items.value.slice(0, index),
338
+ newItem,
339
+ ...fa.items.value.slice(index)
340
+ ];
341
+ ctx.dirtyFields.value = {
342
+ ...ctx.dirtyFields.value,
343
+ [name]: true
344
+ };
345
+ if (ctx.options.mode === "onChange") validate(name);
346
+ };
347
+ const swap = (indexA, indexB) => {
348
+ const newValues = [...get(ctx.formData, name) || []];
349
+ [newValues[indexA], newValues[indexB]] = [newValues[indexB], newValues[indexA]];
350
+ set(ctx.formData, name, newValues);
351
+ const newItems = [...fa.items.value];
352
+ const itemA = newItems[indexA];
353
+ const itemB = newItems[indexB];
354
+ if (itemA && itemB) {
355
+ newItems[indexA] = itemB;
356
+ newItems[indexB] = itemA;
357
+ fa.items.value = newItems;
358
+ }
359
+ ctx.dirtyFields.value = {
360
+ ...ctx.dirtyFields.value,
361
+ [name]: true
362
+ };
363
+ if (ctx.options.mode === "onChange") validate(name);
364
+ };
365
+ const move = (from, to) => {
366
+ const newValues = [...get(ctx.formData, name) || []];
367
+ const [removed] = newValues.splice(from, 1);
368
+ if (removed !== void 0) {
369
+ newValues.splice(to, 0, removed);
370
+ set(ctx.formData, name, newValues);
371
+ }
372
+ const newItems = [...fa.items.value];
373
+ const [removedItem] = newItems.splice(from, 1);
374
+ if (removedItem) {
375
+ newItems.splice(to, 0, removedItem);
376
+ fa.items.value = newItems;
377
+ }
378
+ ctx.dirtyFields.value = {
379
+ ...ctx.dirtyFields.value,
380
+ [name]: true
381
+ };
382
+ if (ctx.options.mode === "onChange") validate(name);
383
+ };
384
+ return {
385
+ value: fa.items.value,
386
+ append,
387
+ prepend,
388
+ remove: removeAt,
389
+ insert,
390
+ swap,
391
+ move,
392
+ update
393
+ };
394
+ }
395
+ return { fields };
396
+ }
397
+ function useForm(options) {
398
+ const ctx = createFormContext(options);
399
+ const { validate } = createValidation(ctx);
400
+ const { register, unregister } = createFieldRegistration(ctx, validate);
401
+ const { fields } = createFieldArrayManager(ctx, validate);
402
+ const formState = (0, vue.computed)(() => ({
403
+ errors: ctx.errors.value,
404
+ isDirty: Object.keys(ctx.dirtyFields.value).some((k) => ctx.dirtyFields.value[k]),
405
+ dirtyFields: ctx.dirtyFields.value,
406
+ isValid: (ctx.submitCount.value > 0 || Object.keys(ctx.touchedFields.value).length > 0) && Object.keys(ctx.errors.value).length === 0,
407
+ isSubmitting: ctx.isSubmitting.value,
408
+ isLoading: ctx.isLoading.value,
409
+ touchedFields: ctx.touchedFields.value,
410
+ submitCount: ctx.submitCount.value
411
+ }));
412
+ function handleSubmit(onValid, onInvalid) {
413
+ return async (e) => {
414
+ e.preventDefault();
415
+ ctx.isSubmitting.value = true;
416
+ ctx.submitCount.value++;
417
+ try {
418
+ for (const [name, fieldRef] of ctx.fieldRefs.entries()) {
419
+ const el = fieldRef.value;
420
+ if (el) {
421
+ if (!ctx.fieldOptions.get(name)?.controlled) {
422
+ const value = el.type === "checkbox" ? el.checked : el.value;
423
+ set(ctx.formData, name, value);
424
+ }
425
+ }
426
+ }
427
+ if (await validate()) await onValid(ctx.formData);
428
+ else onInvalid?.(ctx.errors.value);
429
+ } finally {
430
+ ctx.isSubmitting.value = false;
431
+ }
432
+ };
433
+ }
434
+ function setValue(name, value) {
435
+ set(ctx.formData, name, value);
436
+ ctx.dirtyFields.value = {
437
+ ...ctx.dirtyFields.value,
438
+ [name]: true
439
+ };
440
+ const fieldRef = ctx.fieldRefs.get(name);
441
+ if (fieldRef?.value) {
442
+ const el = fieldRef.value;
443
+ if (el.type === "checkbox") el.checked = value;
444
+ else el.value = value;
445
+ }
446
+ if (options.mode === "onChange" || ctx.touchedFields.value[name]) validate(name);
447
+ }
448
+ function getValue(name) {
449
+ return get(ctx.formData, name);
450
+ }
451
+ function reset(values, resetOptions) {
452
+ const opts = resetOptions || {};
453
+ if (!opts.keepDefaultValues && values) Object.assign(ctx.defaultValues, values);
454
+ Object.keys(ctx.formData).forEach((key) => delete ctx.formData[key]);
455
+ const newValues = values || ctx.defaultValues;
456
+ Object.assign(ctx.formData, newValues);
457
+ if (!opts.keepErrors) ctx.errors.value = {};
458
+ if (!opts.keepTouched) ctx.touchedFields.value = {};
459
+ if (!opts.keepDirty) ctx.dirtyFields.value = {};
460
+ if (!opts.keepSubmitCount) ctx.submitCount.value = 0;
461
+ if (!opts.keepIsSubmitting) ctx.isSubmitting.value = false;
462
+ ctx.fieldArrays.clear();
463
+ for (const [name, fieldRef] of ctx.fieldRefs.entries()) {
464
+ const el = fieldRef.value;
465
+ if (el) {
466
+ const value = get(newValues, name);
467
+ if (value !== void 0) if (el.type === "checkbox") el.checked = value;
468
+ else el.value = value;
469
+ }
470
+ }
471
+ }
472
+ function watch(name) {
473
+ return (0, vue.computed)(() => {
474
+ if (!name) return ctx.formData;
475
+ if (Array.isArray(name)) return name.reduce((acc, n) => {
476
+ acc[n] = get(ctx.formData, n);
477
+ return acc;
478
+ }, {});
479
+ return get(ctx.formData, name);
480
+ });
481
+ }
482
+ function clearErrors(name) {
483
+ if (name === void 0) {
484
+ ctx.errors.value = {};
485
+ return;
486
+ }
487
+ const fieldsToClean = Array.isArray(name) ? name : [name];
488
+ const newErrors = { ...ctx.errors.value };
489
+ for (const field of fieldsToClean) for (const key of Object.keys(newErrors)) if (key === field || key.startsWith(`${field}.`)) delete newErrors[key];
490
+ ctx.errors.value = newErrors;
491
+ }
492
+ function setError(name, error) {
493
+ const newErrors = { ...ctx.errors.value };
494
+ set(newErrors, name, error.type ? {
495
+ type: error.type,
496
+ message: error.message
497
+ } : error.message);
498
+ ctx.errors.value = newErrors;
499
+ }
500
+ function getValues(nameOrNames) {
501
+ for (const [name, fieldRef] of ctx.fieldRefs.entries()) {
502
+ const el = fieldRef.value;
503
+ if (el) {
504
+ if (!ctx.fieldOptions.get(name)?.controlled) {
505
+ const value = el.type === "checkbox" ? el.checked : el.value;
506
+ set(ctx.formData, name, value);
507
+ }
508
+ }
509
+ }
510
+ if (nameOrNames === void 0) return { ...ctx.formData };
511
+ if (Array.isArray(nameOrNames)) {
512
+ const result = {};
513
+ for (const fieldName of nameOrNames) result[fieldName] = get(ctx.formData, fieldName);
514
+ return result;
515
+ }
516
+ return get(ctx.formData, nameOrNames);
517
+ }
518
+ function getFieldState(name) {
519
+ const error = get(ctx.errors.value, name);
520
+ return {
521
+ isDirty: ctx.dirtyFields.value[name] === true,
522
+ isTouched: ctx.touchedFields.value[name] === true,
523
+ invalid: error !== void 0 && error !== null,
524
+ error
525
+ };
526
+ }
527
+ async function trigger(name) {
528
+ if (name === void 0) return await validate();
529
+ if (Array.isArray(name)) {
530
+ let allValid = true;
531
+ for (const fieldName of name) if (!await validate(fieldName)) allValid = false;
532
+ return allValid;
533
+ }
534
+ return await validate(name);
535
+ }
536
+ function setFocus(name, focusOptions) {
537
+ const fieldRef = ctx.fieldRefs.get(name);
538
+ if (!fieldRef?.value) return;
539
+ const el = fieldRef.value;
540
+ if (typeof el.focus === "function") {
541
+ el.focus();
542
+ if (focusOptions?.shouldSelect && el instanceof HTMLInputElement && typeof el.select === "function") el.select();
543
+ }
544
+ }
545
+ return {
546
+ register,
547
+ unregister,
548
+ handleSubmit,
549
+ formState,
550
+ fields,
551
+ setValue,
552
+ getValue,
553
+ reset,
554
+ watch,
555
+ validate,
556
+ clearErrors,
557
+ setError,
558
+ getValues,
559
+ getFieldState,
560
+ trigger,
561
+ setFocus
562
+ };
563
+ }
564
+ const FormContextKey = Symbol("FormContext");
565
+ function provideForm(methods) {
566
+ (0, vue.provide)(FormContextKey, methods);
567
+ }
568
+ function useFormContext() {
569
+ const context = (0, vue.inject)(FormContextKey);
570
+ if (!context) throw new Error("useFormContext must be used within a component tree where provideForm() has been called. Make sure to call provideForm(useForm({ schema })) in a parent component.");
571
+ return context;
572
+ }
573
+ function useWatch(options = {}) {
574
+ const { control, name, defaultValue } = options;
575
+ const form = control ?? useFormContext();
576
+ return (0, vue.computed)(() => {
577
+ if (name === void 0) return form.getValues();
578
+ if (Array.isArray(name)) {
579
+ const result = {};
580
+ for (const fieldName of name) result[fieldName] = get(form.getValues(), fieldName) ?? defaultValue;
581
+ return result;
582
+ }
583
+ return get(form.getValues(), name) ?? defaultValue;
584
+ });
585
+ }
586
+ function useController(options) {
587
+ const { name, control, defaultValue } = options;
588
+ const form = control ?? useFormContext();
589
+ const elementRef = (0, vue.ref)(null);
590
+ if (defaultValue !== void 0 && form.getValue(name) === void 0) form.setValue(name, defaultValue);
591
+ const value = (0, vue.computed)({
592
+ get: () => {
593
+ return form.getValue(name) ?? defaultValue;
594
+ },
595
+ set: (newValue) => {
596
+ form.setValue(name, newValue);
597
+ }
598
+ });
599
+ const onChange = (newValue) => {
600
+ form.setValue(name, newValue);
601
+ };
602
+ const onBlur = () => {
603
+ form.trigger(name);
604
+ };
605
+ const refCallback = (el) => {
606
+ elementRef.value = el;
607
+ };
608
+ const fieldState = (0, vue.computed)(() => {
609
+ return form.getFieldState(name);
610
+ });
611
+ return {
612
+ field: {
613
+ value,
614
+ name,
615
+ onChange,
616
+ onBlur,
617
+ ref: refCallback
618
+ },
619
+ fieldState
620
+ };
621
+ }
622
+ function useFormState(options = {}) {
623
+ const { control, name } = options;
624
+ const form = control ?? useFormContext();
625
+ return (0, vue.computed)(() => {
626
+ const fullState = form.formState.value;
627
+ if (name === void 0) return { ...fullState };
628
+ if (Array.isArray(name)) {
629
+ const result = {};
630
+ for (const key of name) result[key] = fullState[key];
631
+ return result;
632
+ }
633
+ return { [name]: fullState[name] };
634
+ });
635
+ }
636
+ exports.FormContextKey = FormContextKey;
637
+ exports.provideForm = provideForm;
638
+ exports.useController = useController;
639
+ exports.useForm = useForm;
640
+ exports.useFormContext = useFormContext;
641
+ exports.useFormState = useFormState;
642
+ exports.useWatch = useWatch;
643
+
644
+ //# sourceMappingURL=vuehookform.cjs.map