@vuehookform/core 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -217
- package/dist/context.d.ts +0 -1
- package/dist/core/formContext.d.ts +0 -1
- package/dist/core/useFieldArray.d.ts +0 -1
- package/dist/core/useFieldRegistration.d.ts +0 -1
- package/dist/core/useValidation.d.ts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/types.d.ts +0 -1
- package/dist/useController.d.ts +0 -1
- package/dist/useForm.d.ts +0 -1
- package/dist/useFormState.d.ts +0 -1
- package/dist/useWatch.d.ts +0 -1
- package/dist/utils/paths.d.ts +0 -1
- package/dist/vuehookform.cjs +0 -2
- package/dist/vuehookform.js +0 -2
- package/package.json +4 -4
- package/dist/context.d.ts.map +0 -1
- package/dist/core/formContext.d.ts.map +0 -1
- package/dist/core/useFieldArray.d.ts.map +0 -1
- package/dist/core/useFieldRegistration.d.ts.map +0 -1
- package/dist/core/useValidation.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/useController.d.ts.map +0 -1
- package/dist/useForm.d.ts.map +0 -1
- package/dist/useFormState.d.ts.map +0 -1
- package/dist/useWatch.d.ts.map +0 -1
- package/dist/utils/paths.d.ts.map +0 -1
- package/dist/vuehookform.cjs.map +0 -1
- package/dist/vuehookform.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,57 +1,44 @@
|
|
|
1
|
-
# Vue Hook Form
|
|
1
|
+
# Vue Hook Form
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A TypeScript-first form library for Vue 3, inspired by React Hook Form.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Features
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- **TypeScript First** - Perfect type inference with zero manual typing
|
|
8
|
+
- **Zero Config** - Works out of the box with sensible defaults
|
|
9
|
+
- **Performant** - Minimal re-renders using uncontrolled inputs
|
|
10
|
+
- **Zod Native** - First-class Zod integration for validation
|
|
11
|
+
- **Tiny Bundle** - < 5kb gzipped, tree-shakable
|
|
12
|
+
- **UI Agnostic** - Works with any UI library or custom components
|
|
8
13
|
|
|
9
|
-
|
|
10
|
-
- **⚡ Zero Config** - Works out of the box with sensible defaults
|
|
11
|
-
- **🚀 Performant** - Minimal re-renders using uncontrolled inputs
|
|
12
|
-
- **🔥 Zod Native** - First-class Zod integration for validation
|
|
13
|
-
- **📦 Tiny Bundle** - Tree-shakable and dependency-free (< 10kb gzipped)
|
|
14
|
-
- **🎨 UI Agnostic** - Works with any UI library or custom components
|
|
15
|
-
- **🔌 Composable-First** - Built for Vue 3's Composition API
|
|
16
|
-
|
|
17
|
-
## 🚀 Quick Start
|
|
18
|
-
|
|
19
|
-
### Installation
|
|
14
|
+
## Quick Start
|
|
20
15
|
|
|
21
16
|
```bash
|
|
22
17
|
npm install @vuehookform/core zod
|
|
23
|
-
# or
|
|
24
|
-
bun add @vuehookform/core zod
|
|
25
18
|
```
|
|
26
19
|
|
|
27
|
-
### Basic Usage
|
|
28
|
-
|
|
29
20
|
```vue
|
|
30
21
|
<script setup lang="ts">
|
|
31
22
|
import { useForm } from '@vuehookform/core'
|
|
32
23
|
import { z } from 'zod'
|
|
33
24
|
|
|
34
|
-
// 1. Define your schema
|
|
35
25
|
const schema = z.object({
|
|
36
26
|
email: z.email('Invalid email'),
|
|
37
27
|
password: z.string().min(8, 'At least 8 characters'),
|
|
38
28
|
})
|
|
39
29
|
|
|
40
|
-
// 2. Initialize form
|
|
41
30
|
const { register, handleSubmit, formState } = useForm({
|
|
42
31
|
schema,
|
|
43
32
|
mode: 'onBlur',
|
|
44
33
|
})
|
|
45
34
|
|
|
46
|
-
// 3. Handle submission
|
|
47
35
|
const onSubmit = (data) => {
|
|
48
|
-
console.log(data) // Fully typed
|
|
36
|
+
console.log(data) // Fully typed: { email: string, password: string }
|
|
49
37
|
}
|
|
50
38
|
</script>
|
|
51
39
|
|
|
52
40
|
<template>
|
|
53
41
|
<form @submit="handleSubmit(onSubmit)">
|
|
54
|
-
<!-- Bind inputs with v-bind -->
|
|
55
42
|
<input v-bind="register('email')" type="email" />
|
|
56
43
|
<span v-if="formState.errors.email">{{ formState.errors.email }}</span>
|
|
57
44
|
|
|
@@ -63,33 +50,10 @@ const onSubmit = (data) => {
|
|
|
63
50
|
</template>
|
|
64
51
|
```
|
|
65
52
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
## 📚 Examples
|
|
69
|
-
|
|
70
|
-
This repo includes working examples showcasing all features:
|
|
71
|
-
|
|
72
|
-
### Run Examples
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
# Install dependencies
|
|
76
|
-
npm install
|
|
77
|
-
|
|
78
|
-
# Start dev server
|
|
79
|
-
npm run dev
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
Then open http://localhost:5173 to see:
|
|
83
|
-
|
|
84
|
-
1. **Basic Form** - Simple validation, error handling, form state
|
|
85
|
-
2. **Dynamic Arrays** - Add/remove nested form sections dynamically
|
|
86
|
-
|
|
87
|
-
## 💡 Key Concepts
|
|
53
|
+
## Key Concepts
|
|
88
54
|
|
|
89
55
|
### Schema as Source of Truth
|
|
90
56
|
|
|
91
|
-
Define your form structure and validation in one place:
|
|
92
|
-
|
|
93
57
|
```typescript
|
|
94
58
|
const userSchema = z.object({
|
|
95
59
|
name: z.string().min(2),
|
|
@@ -97,20 +61,15 @@ const userSchema = z.object({
|
|
|
97
61
|
age: z.number().min(18),
|
|
98
62
|
})
|
|
99
63
|
|
|
100
|
-
// Types are automatically inferred
|
|
101
64
|
type UserForm = z.infer<typeof userSchema>
|
|
102
65
|
// { name: string; email: string; age: number }
|
|
103
66
|
```
|
|
104
67
|
|
|
105
|
-
###
|
|
106
|
-
|
|
107
|
-
Managing dynamic form sections is trivial:
|
|
68
|
+
### Dynamic Arrays
|
|
108
69
|
|
|
109
70
|
```vue
|
|
110
71
|
<script setup>
|
|
111
72
|
const { register, fields } = useForm({ schema })
|
|
112
|
-
|
|
113
|
-
// Get field array manager
|
|
114
73
|
const addresses = fields('addresses')
|
|
115
74
|
</script>
|
|
116
75
|
|
|
@@ -119,194 +78,60 @@ const addresses = fields('addresses')
|
|
|
119
78
|
<input v-bind="register(`addresses.${field.index}.street`)" />
|
|
120
79
|
<button @click="field.remove()">Remove</button>
|
|
121
80
|
</div>
|
|
122
|
-
|
|
123
81
|
<button @click="addresses.append({ street: '', city: '' })">Add Address</button>
|
|
124
82
|
</template>
|
|
125
83
|
```
|
|
126
84
|
|
|
127
85
|
### Validation Modes
|
|
128
86
|
|
|
129
|
-
Control when validation runs:
|
|
130
|
-
|
|
131
87
|
```typescript
|
|
132
88
|
useForm({
|
|
133
89
|
schema,
|
|
134
|
-
mode: 'onSubmit',
|
|
135
|
-
// mode: 'onBlur',
|
|
136
|
-
// mode: 'onChange',
|
|
137
|
-
// mode: 'onTouched',
|
|
90
|
+
mode: 'onSubmit', // Only validate on submit (default)
|
|
91
|
+
// mode: 'onBlur', // Validate when field loses focus
|
|
92
|
+
// mode: 'onChange', // Validate on every keystroke
|
|
93
|
+
// mode: 'onTouched', // Validate after field is touched
|
|
138
94
|
})
|
|
139
95
|
```
|
|
140
96
|
|
|
141
|
-
##
|
|
97
|
+
## API Reference
|
|
142
98
|
|
|
143
99
|
### `useForm(options)`
|
|
144
100
|
|
|
145
|
-
Main composable for form management.
|
|
146
|
-
|
|
147
|
-
**Options:**
|
|
148
|
-
|
|
149
101
|
```typescript
|
|
150
|
-
{
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
{
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
setValue: (name, value) => void
|
|
166
|
-
getValue: (name) => any
|
|
167
|
-
reset: (values?) => void
|
|
168
|
-
watch: (name?) => ComputedRef<any>
|
|
169
|
-
validate: (name?) => Promise<boolean>
|
|
170
|
-
}
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
### `register(name, options?)`
|
|
174
|
-
|
|
175
|
-
Register an input field for validation and state management.
|
|
176
|
-
|
|
177
|
-
```vue
|
|
178
|
-
<input v-bind="register('email')" />
|
|
179
|
-
<input v-bind="register('email', { controlled: true })" />
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
### `handleSubmit(onValid, onInvalid?)`
|
|
183
|
-
|
|
184
|
-
Create submit handler with validation.
|
|
185
|
-
|
|
186
|
-
```typescript
|
|
187
|
-
const onSubmit = handleSubmit(
|
|
188
|
-
(data) => {
|
|
189
|
-
// Called with validated data
|
|
190
|
-
console.log(data)
|
|
191
|
-
},
|
|
192
|
-
(errors) => {
|
|
193
|
-
// Optional: called when validation fails
|
|
194
|
-
console.log(errors)
|
|
195
|
-
},
|
|
196
|
-
)
|
|
102
|
+
const {
|
|
103
|
+
register, // Register input field
|
|
104
|
+
handleSubmit, // Create submit handler with validation
|
|
105
|
+
formState, // Reactive form state (errors, isSubmitting, etc.)
|
|
106
|
+
fields, // Manage dynamic field arrays
|
|
107
|
+
setValue, // Programmatically set field value
|
|
108
|
+
getValue, // Get current field value
|
|
109
|
+
reset, // Reset form to default values
|
|
110
|
+
watch, // Watch field value changes
|
|
111
|
+
validate, // Manually trigger validation
|
|
112
|
+
} = useForm({
|
|
113
|
+
schema, // Zod schema for validation
|
|
114
|
+
defaultValues: {}, // Initial form values
|
|
115
|
+
mode: 'onSubmit', // When to validate
|
|
116
|
+
})
|
|
197
117
|
```
|
|
198
118
|
|
|
199
119
|
### `fields(name)`
|
|
200
120
|
|
|
201
|
-
Manage dynamic field arrays.
|
|
202
|
-
|
|
203
121
|
```typescript
|
|
204
122
|
const addresses = fields('addresses')
|
|
205
123
|
|
|
206
|
-
addresses.append({ street: '', city: '' })
|
|
207
|
-
addresses.remove(0)
|
|
208
|
-
addresses.insert(1, value)
|
|
209
|
-
addresses.swap(0, 1)
|
|
210
|
-
addresses.move(0, 2)
|
|
124
|
+
addresses.append({ street: '', city: '' })
|
|
125
|
+
addresses.remove(0)
|
|
126
|
+
addresses.insert(1, value)
|
|
127
|
+
addresses.swap(0, 1)
|
|
128
|
+
addresses.move(0, 2)
|
|
211
129
|
```
|
|
212
130
|
|
|
213
|
-
##
|
|
214
|
-
|
|
215
|
-
```
|
|
216
|
-
src/
|
|
217
|
-
├── lib/ # Library source code
|
|
218
|
-
│ ├── index.ts # Public exports
|
|
219
|
-
│ ├── useForm.ts # Main composable
|
|
220
|
-
│ ├── types.ts # TypeScript definitions
|
|
221
|
-
│ └── utils/ # Helper functions
|
|
222
|
-
├── examples/ # Demo applications
|
|
223
|
-
│ ├── BasicForm.vue
|
|
224
|
-
│ └── DynamicArrays.vue
|
|
225
|
-
└── App.vue # Example showcase
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
## 🎯 Why Vue Hook Form?
|
|
229
|
-
|
|
230
|
-
### vs VeeValidate
|
|
231
|
-
|
|
232
|
-
- **Less boilerplate** - One composable manages entire form
|
|
233
|
-
- **Better performance** - Uncontrolled inputs by default
|
|
234
|
-
- **Simpler API** - Form-level vs field-level management
|
|
235
|
-
|
|
236
|
-
### vs FormKit
|
|
237
|
-
|
|
238
|
-
- **Lighter** - < 10kb vs 50kb+
|
|
239
|
-
- **Less opinionated** - No UI components required
|
|
240
|
-
- **Native Zod** - First-class integration, not an adapter
|
|
241
|
-
|
|
242
|
-
### vs Vuelidate
|
|
243
|
-
|
|
244
|
-
- **Type-safe** - Perfect TypeScript inference
|
|
245
|
-
- **Built-in arrays** - Dynamic fields work out of the box
|
|
246
|
-
- **Modern** - Built for Composition API
|
|
247
|
-
|
|
248
|
-
## 🔧 Development
|
|
249
|
-
|
|
250
|
-
### Setup
|
|
251
|
-
|
|
252
|
-
```bash
|
|
253
|
-
npm install
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
### Run Dev Server
|
|
257
|
-
|
|
258
|
-
```bash
|
|
259
|
-
npm run dev
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
### Type Check
|
|
263
|
-
|
|
264
|
-
```bash
|
|
265
|
-
npm run type-check
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
### Lint
|
|
269
|
-
|
|
270
|
-
```bash
|
|
271
|
-
npm run lint
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
### Build
|
|
275
|
-
|
|
276
|
-
```bash
|
|
277
|
-
npm run build
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
## 📖 Documentation
|
|
281
|
-
|
|
282
|
-
For detailed implementation notes, architecture decisions, and future roadmap, see [CORE_CONCEPTS.md](./CORE_CONCEPTS.md).
|
|
283
|
-
|
|
284
|
-
## 🤝 Contributing
|
|
285
|
-
|
|
286
|
-
Contributions welcome! This is a proof-of-concept library demonstrating:
|
|
287
|
-
|
|
288
|
-
- Form-level state management
|
|
289
|
-
- Zod-first validation
|
|
290
|
-
- TypeScript-first design
|
|
291
|
-
- Performance-optimized architecture
|
|
292
|
-
|
|
293
|
-
Feel free to:
|
|
294
|
-
|
|
295
|
-
- Report bugs
|
|
296
|
-
- Suggest features
|
|
297
|
-
- Submit PRs
|
|
298
|
-
- Ask questions
|
|
299
|
-
|
|
300
|
-
## 📝 License
|
|
301
|
-
|
|
302
|
-
MIT - Build something awesome!
|
|
303
|
-
|
|
304
|
-
## 🙏 Inspiration
|
|
131
|
+
## Contributing
|
|
305
132
|
|
|
306
|
-
|
|
307
|
-
- [Zod](https://zod.dev/) - Schema validation
|
|
308
|
-
- [VeeValidate](https://vee-validate.logaretm.com/) - Vue form validation patterns
|
|
133
|
+
Contributions welcome! Feel free to report bugs, suggest features, or submit PRs.
|
|
309
134
|
|
|
310
|
-
|
|
135
|
+
## License
|
|
311
136
|
|
|
312
|
-
|
|
137
|
+
MIT
|
package/dist/context.d.ts
CHANGED
|
@@ -35,4 +35,3 @@ export declare function provideForm<TSchema extends ZodType>(methods: UseFormRet
|
|
|
35
35
|
* @throws Error if used outside of a FormProvider context
|
|
36
36
|
*/
|
|
37
37
|
export declare function useFormContext<TSchema extends ZodType>(): UseFormReturn<TSchema>;
|
|
38
|
-
//# sourceMappingURL=context.d.ts.map
|
|
@@ -32,4 +32,3 @@ export interface FormContext<FormValues> {
|
|
|
32
32
|
* Create a new form context with all reactive state initialized
|
|
33
33
|
*/
|
|
34
34
|
export declare function createFormContext<TSchema extends ZodType>(options: UseFormOptions<TSchema>): FormContext<InferSchema<TSchema>>;
|
|
35
|
-
//# sourceMappingURL=formContext.d.ts.map
|
|
@@ -6,4 +6,3 @@ import { FieldArray, Path } from '../types';
|
|
|
6
6
|
export declare function createFieldArrayManager<FormValues>(ctx: FormContext<FormValues>, validate: (fieldPath?: string) => Promise<boolean>): {
|
|
7
7
|
fields: <TPath extends Path<FormValues>>(name: TPath) => FieldArray;
|
|
8
8
|
};
|
|
9
|
-
//# sourceMappingURL=useFieldArray.d.ts.map
|
|
@@ -7,4 +7,3 @@ export declare function createFieldRegistration<FormValues>(ctx: FormContext<For
|
|
|
7
7
|
register: <TPath extends Path<FormValues>>(name: TPath, registerOptions?: RegisterOptions) => RegisterReturn;
|
|
8
8
|
unregister: <TPath extends Path<FormValues>>(name: TPath) => void;
|
|
9
9
|
};
|
|
10
|
-
//# sourceMappingURL=useFieldRegistration.d.ts.map
|
package/dist/index.d.ts
CHANGED
|
@@ -20,4 +20,3 @@ export { useWatch, type UseWatchOptions } from './useWatch';
|
|
|
20
20
|
export { useController, type UseControllerOptions, type UseControllerReturn, type ControllerFieldProps } from './useController';
|
|
21
21
|
export { useFormState, type UseFormStateOptions, type FormStateKey } from './useFormState';
|
|
22
22
|
export type { UseFormOptions, UseFormReturn, RegisterOptions, RegisterReturn, FormState, FieldState, FieldErrors, FieldError, FieldErrorValue, FieldArray, FieldArrayItem, ValidationMode, InferSchema, Path, PathValue, ErrorOption, SetFocusOptions, ResetOptions, AsyncDefaultValues, } from './types';
|
|
23
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/types.d.ts
CHANGED
package/dist/useController.d.ts
CHANGED
|
@@ -61,4 +61,3 @@ export interface UseControllerReturn<TValue> {
|
|
|
61
61
|
* ```
|
|
62
62
|
*/
|
|
63
63
|
export declare function useController<TSchema extends ZodType, TPath extends Path<InferSchema<TSchema>>>(options: UseControllerOptions<TSchema, TPath>): UseControllerReturn<PathValue<InferSchema<TSchema>, TPath>>;
|
|
64
|
-
//# sourceMappingURL=useController.d.ts.map
|
package/dist/useForm.d.ts
CHANGED
package/dist/useFormState.d.ts
CHANGED
|
@@ -37,4 +37,3 @@ export interface UseFormStateOptions<TSchema extends ZodType> {
|
|
|
37
37
|
* ```
|
|
38
38
|
*/
|
|
39
39
|
export declare function useFormState<TSchema extends ZodType>(options?: UseFormStateOptions<TSchema>): ComputedRef<Partial<FormState<InferSchema<TSchema>>>>;
|
|
40
|
-
//# sourceMappingURL=useFormState.d.ts.map
|
package/dist/useWatch.d.ts
CHANGED
|
@@ -38,4 +38,3 @@ export interface UseWatchOptions<TSchema extends ZodType, TPath extends Path<Inf
|
|
|
38
38
|
* ```
|
|
39
39
|
*/
|
|
40
40
|
export declare function useWatch<TSchema extends ZodType, TPath extends Path<InferSchema<TSchema>> = Path<InferSchema<TSchema>>>(options?: UseWatchOptions<TSchema, TPath>): ComputedRef<unknown>;
|
|
41
|
-
//# sourceMappingURL=useWatch.d.ts.map
|
package/dist/utils/paths.d.ts
CHANGED
package/dist/vuehookform.cjs
CHANGED
package/dist/vuehookform.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vuehookform/core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "TypeScript-first form library for Vue 3, inspired by React Hook Form. Form-level state management with Zod validation.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/vuehookform.cjs",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
"repository": {
|
|
39
39
|
"type": "git",
|
|
40
|
-
"url": "git+https://github.com/vuehookform/
|
|
40
|
+
"url": "git+https://github.com/vuehookform/core.git"
|
|
41
41
|
},
|
|
42
42
|
"keywords": [
|
|
43
43
|
"vue",
|
|
@@ -53,9 +53,9 @@
|
|
|
53
53
|
"author": "",
|
|
54
54
|
"license": "MIT",
|
|
55
55
|
"bugs": {
|
|
56
|
-
"url": "https://github.com/vuehookform/
|
|
56
|
+
"url": "https://github.com/vuehookform/core/issues"
|
|
57
57
|
},
|
|
58
|
-
"homepage": "https://github.com/vuehookform/
|
|
58
|
+
"homepage": "https://github.com/vuehookform/core#readme",
|
|
59
59
|
"peerDependencies": {
|
|
60
60
|
"vue": "^3.3.0",
|
|
61
61
|
"zod": "^3.0.0 || ^4.0.0"
|
package/dist/context.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/lib/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,KAAK,CAAA;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAC5C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AAElC;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,YAAY,CAAC,aAAa,CAAC,OAAO,CAAC,CAAyB,CAAA;AAEzF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,OAAO,SAAS,OAAO,EAAE,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,IAAI,CAE1F;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,OAAO,SAAS,OAAO,KAAK,aAAa,CAAC,OAAO,CAAC,CAWhF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"formContext.d.ts","sourceRoot":"","sources":["../../src/lib/core/formContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,GAAG,EAAE,KAAK,UAAU,EAAE,MAAM,KAAK,CAAA;AAC1E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AAClC,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,WAAW,EACX,eAAe,EACf,cAAc,EACf,MAAM,UAAU,CAAA;AAEjB;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,GAAG,CAAC,cAAc,EAAE,CAAC,CAAA;IAC5B,MAAM,EAAE,OAAO,EAAE,CAAA;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW,CAAC,UAAU;IAErC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACjC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAGtC,MAAM,EAAE,UAAU,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAA;IAC3C,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IAC3C,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IACzC,YAAY,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IAC1B,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACvB,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAGxB,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC,CAAA;IACpD,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;IAC1C,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;IAGzC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC,CAAA;IAC1D,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAGzC,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC,CAAA;CACjC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,SAAS,OAAO,EACvD,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC,GAC/B,WAAW,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAgEnC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useFieldArray.d.ts","sourceRoot":"","sources":["../../src/lib/core/useFieldArray.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,KAAK,EAAE,UAAU,EAAkB,IAAI,EAAE,MAAM,UAAU,CAAA;AAGhE;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAChD,GAAG,EAAE,WAAW,CAAC,UAAU,CAAC,EAC5B,QAAQ,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC;aAKlC,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,QAAQ,KAAK,KAAG,UAAU;EAyKzE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useFieldRegistration.d.ts","sourceRoot":"","sources":["../../src/lib/core/useFieldRegistration.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EAEd,IAAI,EACL,MAAM,UAAU,CAAA;AAGjB;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAChD,GAAG,EAAE,WAAW,CAAC,UAAU,CAAC,EAC5B,QAAQ,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC;eAKhC,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,QACxC,KAAK,oBACO,eAAe,KAChC,cAAc;iBA6LG,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,QAAQ,KAAK,KAAG,IAAI;EAcvE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useValidation.d.ts","sourceRoot":"","sources":["../../src/lib/core/useValidation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAsEhD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,GAAG,EAAE,WAAW,CAAC,UAAU,CAAC;2BAInC,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;EAuD9D"}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/lib/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AACvE,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,KAAK,mBAAmB,EAAE,KAAK,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAC/H,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAE1F,YAAY,EACV,cAAc,EACd,aAAa,EACb,eAAe,EACf,cAAc,EACd,SAAS,EACT,UAAU,EACV,WAAW,EACX,UAAU,EACV,eAAe,EACf,UAAU,EACV,cAAc,EACd,cAAc,EACd,WAAW,EACX,IAAI,EACJ,SAAS,EACT,WAAW,EACX,eAAe,EACf,YAAY,EACZ,kBAAkB,GACnB,MAAM,SAAS,CAAA"}
|
package/dist/types.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/lib/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useController.d.ts","sourceRoot":"","sources":["../src/lib/useController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,WAAW,EAAE,KAAK,GAAG,EAAE,MAAM,KAAK,CAAA;AAC/D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AAClC,OAAO,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAItF;;GAEG;AACH,MAAM,WAAW,oBAAoB,CACnC,OAAO,SAAS,OAAO,EACvB,KAAK,SAAS,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAExC,sBAAsB;IACtB,IAAI,EAAE,KAAK,CAAA;IACX,+DAA+D;IAC/D,OAAO,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAA;IAChC,kCAAkC;IAClC,YAAY,CAAC,EAAE,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,CAAA;CACtD;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB,CAAC,MAAM;IAC1C,0BAA0B;IAC1B,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAClB,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,2CAA2C;IAC3C,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC,mBAAmB;IACnB,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,yCAAyC;IACzC,GAAG,EAAE,CAAC,EAAE,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAA;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB,CAAC,MAAM;IACzC,kDAAkD;IAClD,KAAK,EAAE,oBAAoB,CAAC,MAAM,CAAC,CAAA;IACnC,mDAAmD;IACnD,UAAU,EAAE,WAAW,CAAC,UAAU,CAAC,CAAA;CACpC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,aAAa,CAC3B,OAAO,SAAS,OAAO,EACvB,KAAK,SAAS,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,EAExC,OAAO,EAAE,oBAAoB,CAAC,OAAO,EAAE,KAAK,CAAC,GAC5C,mBAAmB,CAAC,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC,CAyD7D"}
|
package/dist/useForm.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useForm.d.ts","sourceRoot":"","sources":["../src/lib/useForm.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AAClC,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EAUd,MAAM,SAAS,CAAA;AAOhB;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,OAAO,CAAC,OAAO,SAAS,OAAO,EAC7C,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC,GAC/B,aAAa,CAAC,OAAO,CAAC,CAuWxB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useFormState.d.ts","sourceRoot":"","sources":["../src/lib/useFormState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,WAAW,EAAE,MAAM,KAAK,CAAA;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AAClC,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAGpE;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,CAAA;AAEnD;;GAEG;AACH,MAAM,WAAW,mBAAmB,CAAC,OAAO,SAAS,OAAO;IAC1D,+DAA+D;IAC/D,OAAO,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAA;IAChC,8EAA8E;IAC9E,IAAI,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,CAAA;CACrC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,YAAY,CAAC,OAAO,SAAS,OAAO,EAClD,OAAO,GAAE,mBAAmB,CAAC,OAAO,CAAM,GACzC,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CA0BvD"}
|
package/dist/useWatch.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useWatch.d.ts","sourceRoot":"","sources":["../src/lib/useWatch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,WAAW,EAAE,MAAM,KAAK,CAAA;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AAClC,OAAO,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAI/D;;GAEG;AACH,MAAM,WAAW,eAAe,CAAC,OAAO,SAAS,OAAO,EAAE,KAAK,SAAS,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAChG,+DAA+D;IAC/D,OAAO,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAA;IAChC,0EAA0E;IAC1E,IAAI,CAAC,EAAE,KAAK,GAAG,KAAK,EAAE,CAAA;IACtB,4CAA4C;IAC5C,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,QAAQ,CACtB,OAAO,SAAS,OAAO,EACvB,KAAK,SAAS,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,EACrE,OAAO,GAAE,eAAe,CAAC,OAAO,EAAE,KAAK,CAAM,GAAG,WAAW,CAAC,OAAO,CAAC,CA0BrE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/lib/utils/paths.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAcvE;AAED;;;GAGG;AACH,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAsBpF;AAED;;;GAGG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAatE;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvE;AAMD,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGjD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAK9D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD"}
|
package/dist/vuehookform.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"vuehookform.cjs","names":["result: unknown","current: Record<string, unknown>","types: Record<string, string | string[]>","newErrors: Record<string, string | FieldError>","result: Record<string, unknown>","FormContextKey: InjectionKey<UseFormReturn<ZodType>>","result: Record<string, unknown>","result: Partial<FormState<InferSchema<TSchema>>>"],"sources":["../src/lib/utils/paths.ts","../src/lib/core/formContext.ts","../src/lib/core/useValidation.ts","../src/lib/core/useFieldRegistration.ts","../src/lib/core/useFieldArray.ts","../src/lib/useForm.ts","../src/lib/context.ts","../src/lib/useWatch.ts","../src/lib/useController.ts","../src/lib/useFormState.ts"],"sourcesContent":["/**\n * Get value from object using dot notation path\n * @example get({ user: { name: 'John' } }, 'user.name') => 'John'\n */\nexport function get(obj: Record<string, unknown>, path: string): unknown {\n if (!path) return obj\n\n const keys = path.split('.')\n let result: unknown = obj\n\n for (const key of keys) {\n if (result === null || result === undefined) {\n return undefined\n }\n result = (result as Record<string, unknown>)[key]\n }\n\n return result\n}\n\n/**\n * Set value in object using dot notation path\n * @example set({}, 'user.name', 'John') => { user: { name: 'John' } }\n */\nexport function set(obj: Record<string, unknown>, path: string, value: unknown): void {\n if (!path) return\n\n const keys = path.split('.')\n\n // Prototype pollution protection\n const UNSAFE_KEYS = ['__proto__', 'constructor', 'prototype']\n if (keys.some((k) => UNSAFE_KEYS.includes(k))) return\n const lastKey = keys.pop()!\n let current: Record<string, unknown> = obj\n\n // Create nested objects as needed\n for (const key of keys) {\n if (!(key in current) || typeof current[key] !== 'object') {\n // Check if next key is a number to create array vs object\n const nextKey = keys[keys.indexOf(key) + 1]\n current[key] = nextKey && /^\\d+$/.test(nextKey) ? [] : {}\n }\n current = current[key] as Record<string, unknown>\n }\n\n current[lastKey] = value\n}\n\n/**\n * Delete value from object using dot notation path\n * @example unset({ user: { name: 'John' } }, 'user.name') => { user: {} }\n */\nexport function unset(obj: Record<string, unknown>, path: string): void {\n if (!path) return\n\n const keys = path.split('.')\n const lastKey = keys.pop()!\n let current: Record<string, unknown> = obj\n\n for (const key of keys) {\n if (!(key in current)) return\n current = current[key] as Record<string, unknown>\n }\n\n delete current[lastKey]\n}\n\n/**\n * Check if path exists in object\n */\nexport function has(obj: Record<string, unknown>, path: string): boolean {\n return get(obj, path) !== undefined\n}\n\n/**\n * Generate a unique ID for field array items\n */\nlet idCounter = 0\nexport function generateId(): string {\n return `field_${Date.now()}_${idCounter++}`\n}\n\n/**\n * Check if a path represents an array index\n * @example isArrayPath('users.0') => true\n * @example isArrayPath('users.name') => false\n */\nexport function isArrayPath(path: string): boolean {\n const lastSegment = path.split('.').pop()\n return /^\\d+$/.test(lastSegment || '')\n}\n\n/**\n * Get parent path\n * @example getParentPath('user.addresses.0.street') => 'user.addresses.0'\n */\nexport function getParentPath(path: string): string | undefined {\n const segments = path.split('.')\n if (segments.length <= 1) return undefined\n segments.pop()\n return segments.join('.')\n}\n\n/**\n * Get field name from path\n * @example getFieldName('user.addresses.0.street') => 'street'\n */\nexport function getFieldName(path: string): string {\n return path.split('.').pop() || path\n}\n","import { reactive, ref, shallowRef, type Ref, type ShallowRef } from 'vue'\nimport type { ZodType } from 'zod'\nimport type {\n UseFormOptions,\n FieldErrors,\n InferSchema,\n RegisterOptions,\n FieldArrayItem,\n} from '../types'\n\n/**\n * Internal state for field array management\n */\nexport interface FieldArrayState {\n items: Ref<FieldArrayItem[]>\n values: unknown[]\n}\n\n/**\n * Shared form context containing all reactive state\n * This is passed to sub-modules via dependency injection\n */\nexport interface FormContext<FormValues> {\n // Reactive form data\n formData: Record<string, unknown>\n defaultValues: Record<string, unknown>\n\n // Form state\n errors: ShallowRef<FieldErrors<FormValues>>\n touchedFields: Ref<Record<string, boolean>>\n dirtyFields: Ref<Record<string, boolean>>\n isSubmitting: Ref<boolean>\n isLoading: Ref<boolean>\n submitCount: Ref<number>\n\n // Field tracking\n fieldRefs: Map<string, Ref<HTMLInputElement | null>>\n fieldOptions: Map<string, RegisterOptions>\n fieldArrays: Map<string, FieldArrayState>\n\n // Debounce tracking for async validation\n debounceTimers: Map<string, ReturnType<typeof setTimeout>>\n validationRequestIds: Map<string, number>\n\n // Options\n options: UseFormOptions<ZodType>\n}\n\n/**\n * Create a new form context with all reactive state initialized\n */\nexport function createFormContext<TSchema extends ZodType>(\n options: UseFormOptions<TSchema>,\n): FormContext<InferSchema<TSchema>> {\n type FormValues = InferSchema<TSchema>\n\n // Form data storage\n const formData = reactive<Record<string, unknown>>({})\n const defaultValues = reactive<Record<string, unknown>>({})\n\n // Check if defaultValues is a function (async) or an object (sync)\n const isAsyncDefaults = typeof options.defaultValues === 'function'\n const isLoading = ref(isAsyncDefaults)\n\n if (isAsyncDefaults) {\n // Async default values - load them\n const asyncFn = options.defaultValues as () => Promise<Partial<FormValues>>\n asyncFn()\n .then((values) => {\n Object.assign(defaultValues, values)\n Object.assign(formData, values)\n isLoading.value = false\n })\n .catch((error) => {\n console.error('Failed to load async default values:', error)\n isLoading.value = false\n })\n } else if (options.defaultValues) {\n // Sync default values\n Object.assign(defaultValues, options.defaultValues)\n Object.assign(formData, defaultValues)\n }\n\n // Form state - using Record instead of Set for per-field tracking\n const errors = shallowRef<FieldErrors<FormValues>>({})\n const touchedFields = ref<Record<string, boolean>>({})\n const dirtyFields = ref<Record<string, boolean>>({})\n const isSubmitting = ref(false)\n const submitCount = ref(0)\n\n // Field registration tracking\n const fieldRefs = new Map<string, Ref<HTMLInputElement | null>>()\n const fieldOptions = new Map<string, RegisterOptions>()\n\n // Field array tracking for dynamic arrays\n const fieldArrays = new Map<string, FieldArrayState>()\n\n // Debounce tracking for async validation\n const debounceTimers = new Map<string, ReturnType<typeof setTimeout>>()\n const validationRequestIds = new Map<string, number>()\n\n return {\n formData,\n defaultValues,\n errors,\n touchedFields,\n dirtyFields,\n isSubmitting,\n isLoading,\n submitCount,\n fieldRefs,\n fieldOptions,\n fieldArrays,\n debounceTimers,\n validationRequestIds,\n options: options as UseFormOptions<ZodType>,\n }\n}\n","import type { FormContext } from './formContext'\nimport type { FieldErrors, FieldError } from '../types'\nimport { set, get } from '../utils/paths'\n\n/**\n * Helper to clear errors for a specific field path and its children\n */\nfunction clearFieldErrors<T>(\n errors: FieldErrors<T>,\n fieldPath: string,\n): FieldErrors<T> {\n const newErrors = { ...errors }\n for (const key of Object.keys(newErrors)) {\n if (key === fieldPath || key.startsWith(`${fieldPath}.`)) {\n delete newErrors[key as keyof typeof newErrors]\n }\n }\n return newErrors as FieldErrors<T>\n}\n\n/**\n * Group errors by field path for multi-error support\n */\nfunction groupErrorsByPath(\n issues: Array<{ path: (string | number)[]; message: string; code: string }>,\n): Map<string, Array<{ type: string; message: string }>> {\n const grouped = new Map<string, Array<{ type: string; message: string }>>()\n\n for (const issue of issues) {\n const path = issue.path.join('.')\n const existing = grouped.get(path) || []\n existing.push({ type: issue.code, message: issue.message })\n grouped.set(path, existing)\n }\n\n return grouped\n}\n\n/**\n * Convert grouped errors to FieldError format\n * Single error = string (backward compatible)\n * Multiple errors = FieldError with types\n */\nfunction createFieldError(errors: Array<{ type: string; message: string }>): string | FieldError {\n if (errors.length === 1) {\n // Single error - return string for backward compatibility\n return errors[0].message\n }\n\n // Multiple errors - return structured FieldError\n const types: Record<string, string | string[]> = {}\n for (const err of errors) {\n const existing = types[err.type]\n if (existing) {\n // Multiple errors of same type - make array\n types[err.type] = Array.isArray(existing)\n ? [...existing, err.message]\n : [existing, err.message]\n } else {\n types[err.type] = err.message\n }\n }\n\n return {\n type: errors[0].type,\n message: errors[0].message,\n types,\n }\n}\n\n/**\n * Create validation functions for form\n */\nexport function createValidation<FormValues>(ctx: FormContext<FormValues>) {\n /**\n * Validate a single field or entire form\n */\n async function validate(fieldPath?: string): Promise<boolean> {\n // Use safeParseAsync to avoid throwing\n const result = await ctx.options.schema.safeParseAsync(ctx.formData)\n\n if (result.success) {\n // Clear errors on success\n if (fieldPath) {\n ctx.errors.value = clearFieldErrors(ctx.errors.value, fieldPath)\n } else {\n ctx.errors.value = {} as FieldErrors<FormValues>\n }\n return true\n }\n\n // Validation failed - process errors\n const zodErrors = result.error.issues\n\n if (fieldPath) {\n // Single field validation - filter to only this field's errors\n const fieldErrors = zodErrors.filter((issue) => {\n const path = issue.path.join('.')\n return path === fieldPath || path.startsWith(`${fieldPath}.`)\n })\n\n if (fieldErrors.length === 0) {\n // This specific field is valid, clear its errors\n ctx.errors.value = clearFieldErrors(ctx.errors.value, fieldPath)\n return true\n }\n\n // Update only this field's errors (merge with existing), with multi-error support\n let newErrors = clearFieldErrors(ctx.errors.value, fieldPath)\n const grouped = groupErrorsByPath(fieldErrors)\n\n for (const [path, errors] of grouped) {\n set(newErrors, path, createFieldError(errors))\n }\n\n ctx.errors.value = newErrors as FieldErrors<FormValues>\n return false\n }\n\n // Full form validation with multi-error support\n const newErrors: Record<string, string | FieldError> = {}\n const grouped = groupErrorsByPath(zodErrors)\n\n for (const [path, errors] of grouped) {\n set(newErrors, path, createFieldError(errors))\n }\n\n ctx.errors.value = newErrors as FieldErrors<FormValues>\n return false\n }\n\n return { validate }\n}\n","import { computed, ref } from 'vue'\nimport type { FormContext } from './formContext'\nimport type {\n RegisterOptions,\n RegisterReturn,\n FieldErrors,\n Path,\n} from '../types'\nimport { get, set, unset } from '../utils/paths'\n\n/**\n * Create field registration functions\n */\nexport function createFieldRegistration<FormValues>(\n ctx: FormContext<FormValues>,\n validate: (fieldPath?: string) => Promise<boolean>,\n) {\n /**\n * Register an input field\n */\n function register<TPath extends Path<FormValues>>(\n name: TPath,\n registerOptions?: RegisterOptions,\n ): RegisterReturn {\n const fieldRef = ref<HTMLInputElement | null>(null)\n ctx.fieldRefs.set(name, fieldRef)\n\n if (registerOptions) {\n ctx.fieldOptions.set(name, registerOptions)\n }\n\n // Initialize field value if not set\n if (get(ctx.formData, name) === undefined) {\n const defaultValue = get(ctx.defaultValues, name)\n if (defaultValue !== undefined) {\n set(ctx.formData, name, defaultValue)\n }\n }\n\n /**\n * Run custom field validation with optional debouncing\n */\n const runCustomValidation = async (fieldName: string, value: unknown, requestId: number) => {\n const fieldOpts = ctx.fieldOptions.get(fieldName)\n if (!fieldOpts?.validate || fieldOpts.disabled) {\n return\n }\n\n const error = await fieldOpts.validate(value)\n\n // Check if this is still the latest request (race condition handling)\n const latestRequestId = ctx.validationRequestIds.get(fieldName)\n if (requestId !== latestRequestId) {\n return // Stale request, ignore result\n }\n\n if (error) {\n ctx.errors.value = { ...ctx.errors.value, [fieldName]: error } as FieldErrors<FormValues>\n } else {\n // Clear the error if validation passes\n const newErrors = { ...ctx.errors.value }\n delete newErrors[fieldName as keyof typeof newErrors]\n ctx.errors.value = newErrors as FieldErrors<FormValues>\n }\n }\n\n /**\n * Handle field input (fires on every keystroke)\n */\n const onInput = async (e: Event) => {\n const target = e.target as HTMLInputElement\n const value = target.type === 'checkbox' ? target.checked : target.value\n\n // Update form data\n set(ctx.formData, name, value)\n\n // Mark as dirty using Record\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n\n // Validate based on mode\n if (\n ctx.options.mode === 'onChange' ||\n (ctx.options.mode === 'onTouched' && ctx.touchedFields.value[name]) ||\n (ctx.touchedFields.value[name] && ctx.options.reValidateMode === 'onChange')\n ) {\n await validate(name)\n }\n\n // Custom validation with optional debouncing\n const fieldOpts = ctx.fieldOptions.get(name)\n if (fieldOpts?.validate && !fieldOpts.disabled) {\n // Generate a new request ID for race condition handling\n const requestId = Date.now() + Math.random()\n ctx.validationRequestIds.set(name, requestId)\n\n const debounceMs = fieldOpts.validateDebounce || 0\n\n if (debounceMs > 0) {\n // Cancel any existing debounce timer\n const existingTimer = ctx.debounceTimers.get(name)\n if (existingTimer) {\n clearTimeout(existingTimer)\n }\n\n // Set new debounce timer\n const timer = setTimeout(() => {\n ctx.debounceTimers.delete(name)\n runCustomValidation(name, value, requestId)\n }, debounceMs)\n\n ctx.debounceTimers.set(name, timer)\n } else {\n // No debounce, run immediately\n await runCustomValidation(name, value, requestId)\n }\n }\n }\n\n /**\n * Handle field blur\n */\n const onBlur = async (_e: Event) => {\n // Mark as touched using Record\n ctx.touchedFields.value = { ...ctx.touchedFields.value, [name]: true }\n\n // Validate based on mode\n if (\n ctx.options.mode === 'onBlur' ||\n ctx.options.mode === 'onTouched' ||\n (ctx.submitCount.value > 0 && ctx.options.reValidateMode === 'onBlur')\n ) {\n await validate(name)\n }\n }\n\n /**\n * Ref callback to store element reference\n */\n const refCallback = (el: unknown) => {\n const previousEl = fieldRef.value\n fieldRef.value = el as HTMLInputElement | null\n\n // Set initial value for uncontrolled inputs\n if (el && !registerOptions?.controlled && el instanceof HTMLInputElement) {\n const value = get(ctx.formData, name)\n if (value !== undefined) {\n if (el.type === 'checkbox') {\n el.checked = value as boolean\n } else {\n el.value = value as string\n }\n }\n }\n\n // Handle shouldUnregister when element is removed (ref becomes null)\n if (previousEl && !el) {\n const shouldUnreg =\n registerOptions?.shouldUnregister ?? ctx.options.shouldUnregister ?? false\n\n if (shouldUnreg) {\n // Clear form data for this field\n unset(ctx.formData, name)\n\n // Clear errors for this field\n const newErrors = { ...ctx.errors.value }\n delete newErrors[name as keyof typeof newErrors]\n ctx.errors.value = newErrors as FieldErrors<FormValues>\n\n // Clear touched/dirty state\n const newTouched = { ...ctx.touchedFields.value }\n delete newTouched[name]\n ctx.touchedFields.value = newTouched\n\n const newDirty = { ...ctx.dirtyFields.value }\n delete newDirty[name]\n ctx.dirtyFields.value = newDirty\n\n // Clean up refs and options\n ctx.fieldRefs.delete(name)\n ctx.fieldOptions.delete(name)\n\n // Clean up debounce timers\n const timer = ctx.debounceTimers.get(name)\n if (timer) {\n clearTimeout(timer)\n ctx.debounceTimers.delete(name)\n }\n ctx.validationRequestIds.delete(name)\n }\n }\n }\n\n return {\n name,\n ref: refCallback,\n onInput,\n onBlur,\n ...(registerOptions?.controlled && {\n value: computed({\n get: () => get(ctx.formData, name),\n set: (val) => {\n set(ctx.formData, name, val)\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n },\n }),\n }),\n }\n }\n\n /**\n * Unregister a field to clean up refs and options\n */\n function unregister<TPath extends Path<FormValues>>(name: TPath): void {\n ctx.fieldRefs.delete(name)\n ctx.fieldOptions.delete(name)\n\n // Clean up debounce timers\n const timer = ctx.debounceTimers.get(name)\n if (timer) {\n clearTimeout(timer)\n ctx.debounceTimers.delete(name)\n }\n ctx.validationRequestIds.delete(name)\n }\n\n return { register, unregister }\n}\n","import { ref } from 'vue'\nimport type { FormContext } from './formContext'\nimport type { FieldArray, FieldArrayItem, Path } from '../types'\nimport { get, set, generateId } from '../utils/paths'\n\n/**\n * Create field array management functions\n */\nexport function createFieldArrayManager<FormValues>(\n ctx: FormContext<FormValues>,\n validate: (fieldPath?: string) => Promise<boolean>,\n) {\n /**\n * Manage dynamic field arrays\n */\n function fields<TPath extends Path<FormValues>>(name: TPath): FieldArray {\n // Get or create field array entry\n let fieldArray = ctx.fieldArrays.get(name)\n\n if (!fieldArray) {\n const existingValues = (get(ctx.formData, name) || []) as unknown[]\n fieldArray = {\n items: ref<FieldArrayItem[]>([]),\n values: existingValues,\n }\n ctx.fieldArrays.set(name, fieldArray)\n\n // Initialize form data if needed\n if (!get(ctx.formData, name)) {\n set(ctx.formData, name, [] as unknown[])\n }\n }\n\n // Capture reference for closures\n const fa = fieldArray\n\n /**\n * Helper to create items with dynamic index lookup\n * Uses getters so index is always current, not stale\n */\n const createItem = (key: string): FieldArrayItem => ({\n key,\n get index() {\n return fa.items.value.findIndex((item) => item.key === key)\n },\n remove() {\n const currentIndex = fa.items.value.findIndex((item) => item.key === key)\n if (currentIndex !== -1) {\n removeAt(currentIndex)\n }\n },\n })\n\n // Populate items if empty (first access after creation)\n if (fa.items.value.length === 0 && fa.values.length > 0) {\n fa.items.value = fa.values.map(() => createItem(generateId()))\n }\n\n const append = (value: unknown) => {\n const currentValues = (get(ctx.formData, name) || []) as unknown[]\n const newValues = [...currentValues, value]\n set(ctx.formData, name, newValues)\n\n fa.items.value = [...fa.items.value, createItem(generateId())]\n\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n\n if (ctx.options.mode === 'onChange') {\n validate(name)\n }\n }\n\n const prepend = (value: unknown) => {\n insert(0, value)\n }\n\n const update = (index: number, value: unknown) => {\n const currentValues = (get(ctx.formData, name) || []) as unknown[]\n if (index < 0 || index >= currentValues.length) {\n return // Invalid index, do nothing\n }\n const newValues = [...currentValues]\n newValues[index] = value\n set(ctx.formData, name, newValues)\n\n // Keep the same key - no items array change needed (preserves stable identity)\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n\n if (ctx.options.mode === 'onChange') {\n validate(name)\n }\n }\n\n const removeAt = (index: number) => {\n const currentValues = (get(ctx.formData, name) || []) as unknown[]\n const newValues = currentValues.filter((_: unknown, i: number) => i !== index)\n set(ctx.formData, name, newValues)\n\n // Remove item by current index, keep others (indices auto-update via getter)\n const keyToRemove = fa.items.value[index]?.key\n fa.items.value = fa.items.value.filter((item) => item.key !== keyToRemove)\n\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n\n if (ctx.options.mode === 'onChange') {\n validate(name)\n }\n }\n\n const insert = (index: number, value: unknown) => {\n const currentValues = (get(ctx.formData, name) || []) as unknown[]\n const newValues = [...currentValues.slice(0, index), value, ...currentValues.slice(index)]\n set(ctx.formData, name, newValues)\n\n const newItem = createItem(generateId())\n fa.items.value = [...fa.items.value.slice(0, index), newItem, ...fa.items.value.slice(index)]\n\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n\n if (ctx.options.mode === 'onChange') {\n validate(name)\n }\n }\n\n const swap = (indexA: number, indexB: number) => {\n const currentValues = (get(ctx.formData, name) || []) as unknown[]\n const newValues = [...currentValues]\n ;[newValues[indexA], newValues[indexB]] = [newValues[indexB], newValues[indexA]]\n set(ctx.formData, name, newValues)\n\n // Swap items in array (indices auto-update via getter)\n const newItems = [...fa.items.value]\n const itemA = newItems[indexA]\n const itemB = newItems[indexB]\n if (itemA && itemB) {\n newItems[indexA] = itemB\n newItems[indexB] = itemA\n fa.items.value = newItems\n }\n\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n\n if (ctx.options.mode === 'onChange') {\n validate(name)\n }\n }\n\n const move = (from: number, to: number) => {\n const currentValues = (get(ctx.formData, name) || []) as unknown[]\n const newValues = [...currentValues]\n const [removed] = newValues.splice(from, 1)\n if (removed !== undefined) {\n newValues.splice(to, 0, removed)\n set(ctx.formData, name, newValues)\n }\n\n // Move item in array (indices auto-update via getter)\n const newItems = [...fa.items.value]\n const [removedItem] = newItems.splice(from, 1)\n if (removedItem) {\n newItems.splice(to, 0, removedItem)\n fa.items.value = newItems\n }\n\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n\n if (ctx.options.mode === 'onChange') {\n validate(name)\n }\n }\n\n return {\n value: fa.items.value,\n append,\n prepend,\n remove: removeAt,\n insert,\n swap,\n move,\n update,\n }\n }\n\n return { fields }\n}\n","import { computed } from 'vue'\nimport type { ZodType } from 'zod'\nimport type {\n UseFormOptions,\n UseFormReturn,\n FormState,\n FieldErrors,\n FieldState,\n ErrorOption,\n SetFocusOptions,\n ResetOptions,\n InferSchema,\n Path,\n PathValue,\n} from './types'\nimport { get, set } from './utils/paths'\nimport { createFormContext } from './core/formContext'\nimport { createValidation } from './core/useValidation'\nimport { createFieldRegistration } from './core/useFieldRegistration'\nimport { createFieldArrayManager } from './core/useFieldArray'\n\n/**\n * Main form management composable\n *\n * @example\n * ```ts\n * const schema = z.object({\n * email: z.email(),\n * name: z.string().min(2)\n * })\n *\n * const { register, handleSubmit, formState } = useForm({ schema })\n *\n * const onSubmit = (data) => {\n * console.log(data) // { email: '...', name: '...' }\n * }\n * ```\n */\nexport function useForm<TSchema extends ZodType>(\n options: UseFormOptions<TSchema>,\n): UseFormReturn<TSchema> {\n type FormValues = InferSchema<TSchema>\n\n // Create shared context with all reactive state\n const ctx = createFormContext(options)\n\n // Create validation functions\n const { validate } = createValidation<FormValues>(ctx)\n\n // Create field registration functions\n const { register, unregister } = createFieldRegistration<FormValues>(ctx, validate)\n\n // Create field array manager\n const { fields } = createFieldArrayManager<FormValues>(ctx, validate)\n\n /**\n * Get current form state\n */\n const formState = computed<FormState<FormValues>>(() => ({\n errors: ctx.errors.value,\n isDirty: Object.keys(ctx.dirtyFields.value).some((k) => ctx.dirtyFields.value[k]),\n dirtyFields: ctx.dirtyFields.value,\n isValid:\n (ctx.submitCount.value > 0 || Object.keys(ctx.touchedFields.value).length > 0) &&\n Object.keys(ctx.errors.value).length === 0,\n isSubmitting: ctx.isSubmitting.value,\n isLoading: ctx.isLoading.value,\n touchedFields: ctx.touchedFields.value,\n submitCount: ctx.submitCount.value,\n }))\n\n /**\n * Handle form submission\n */\n function handleSubmit(\n onValid: (data: FormValues) => void | Promise<void>,\n onInvalid?: (errors: FieldErrors<FormValues>) => void,\n ) {\n return async (e: Event) => {\n e.preventDefault()\n\n ctx.isSubmitting.value = true\n ctx.submitCount.value++\n\n try {\n // Collect values from uncontrolled inputs\n for (const [name, fieldRef] of ctx.fieldRefs.entries()) {\n const el = fieldRef.value\n if (el) {\n const opts = ctx.fieldOptions.get(name)\n if (!opts?.controlled) {\n const value = el.type === 'checkbox' ? el.checked : el.value\n set(ctx.formData, name, value)\n }\n }\n }\n\n // Validate entire form\n const isValid = await validate()\n\n if (isValid) {\n // Call success handler with validated data\n await onValid(ctx.formData as FormValues)\n } else {\n // Call error handler if provided\n onInvalid?.(ctx.errors.value)\n }\n } finally {\n ctx.isSubmitting.value = false\n }\n }\n }\n\n /**\n * Set field value programmatically\n */\n function setValue<TPath extends Path<FormValues>>(\n name: TPath,\n value: PathValue<FormValues, TPath>,\n ): void {\n set(ctx.formData, name, value)\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n\n // Update input element if it exists\n const fieldRef = ctx.fieldRefs.get(name)\n if (fieldRef?.value) {\n const el = fieldRef.value\n if (el.type === 'checkbox') {\n el.checked = value as boolean\n } else {\n el.value = value as string\n }\n }\n\n // Validate if needed\n if (options.mode === 'onChange' || ctx.touchedFields.value[name]) {\n validate(name)\n }\n }\n\n /**\n * Get field value\n */\n function getValue<TPath extends Path<FormValues>>(\n name: TPath,\n ): PathValue<FormValues, TPath> | undefined {\n return get(ctx.formData, name) as PathValue<FormValues, TPath> | undefined\n }\n\n /**\n * Reset form to default values\n */\n function reset(values?: Partial<FormValues>, resetOptions?: ResetOptions): void {\n const opts = resetOptions || {}\n\n // Update default values unless keepDefaultValues is true\n if (!opts.keepDefaultValues && values) {\n Object.assign(ctx.defaultValues, values)\n }\n\n // Clear form data\n Object.keys(ctx.formData).forEach((key) => delete ctx.formData[key])\n\n // Apply new values or defaults\n const newValues = values || ctx.defaultValues\n Object.assign(ctx.formData, newValues)\n\n // Reset state based on options\n if (!opts.keepErrors) {\n ctx.errors.value = {} as FieldErrors<FormValues>\n }\n if (!opts.keepTouched) {\n ctx.touchedFields.value = {}\n }\n if (!opts.keepDirty) {\n ctx.dirtyFields.value = {}\n }\n if (!opts.keepSubmitCount) {\n ctx.submitCount.value = 0\n }\n if (!opts.keepIsSubmitting) {\n ctx.isSubmitting.value = false\n }\n\n // Always clear field arrays (they'll be recreated on next access)\n ctx.fieldArrays.clear()\n\n // Update input elements\n for (const [name, fieldRef] of ctx.fieldRefs.entries()) {\n const el = fieldRef.value\n if (el) {\n const value = get(newValues as Record<string, unknown>, name)\n if (value !== undefined) {\n if (el.type === 'checkbox') {\n el.checked = value as boolean\n } else {\n el.value = value as string\n }\n }\n }\n }\n }\n\n /**\n * Watch field value(s) reactively\n */\n function watch<TPath extends Path<FormValues>>(name?: TPath | TPath[]) {\n return computed(() => {\n if (!name) {\n return ctx.formData\n }\n if (Array.isArray(name)) {\n return name.reduce(\n (acc, n) => {\n acc[n] = get(ctx.formData, n)\n return acc\n },\n {} as Record<TPath, unknown>,\n )\n }\n return get(ctx.formData, name)\n })\n }\n\n // ========================================\n // NEW P0/P1 FEATURES\n // ========================================\n\n /**\n * Clear errors for one or more fields, or all errors\n */\n function clearErrors<TPath extends Path<FormValues>>(name?: TPath | TPath[]): void {\n if (name === undefined) {\n // Clear all errors\n ctx.errors.value = {} as FieldErrors<FormValues>\n return\n }\n\n const fieldsToClean = Array.isArray(name) ? name : [name]\n const newErrors = { ...ctx.errors.value }\n\n for (const field of fieldsToClean) {\n // Clear exact path and any nested paths\n for (const key of Object.keys(newErrors)) {\n if (key === field || key.startsWith(`${field}.`)) {\n delete newErrors[key as keyof typeof newErrors]\n }\n }\n }\n\n ctx.errors.value = newErrors as FieldErrors<FormValues>\n }\n\n /**\n * Programmatically set an error for a field\n * Supports both simple string errors (backward compatible) and structured FieldError objects\n */\n function setError<TPath extends Path<FormValues>>(\n name: TPath | 'root' | `root.${string}`,\n error: ErrorOption,\n ): void {\n const newErrors = { ...ctx.errors.value }\n\n // Create structured error if type is provided, otherwise use string for backward compatibility\n const errorValue = error.type\n ? { type: error.type, message: error.message }\n : error.message\n\n set(newErrors, name, errorValue)\n ctx.errors.value = newErrors as FieldErrors<FormValues>\n }\n\n /**\n * Get form values - all values, single field, or multiple fields\n */\n function getValues(): FormValues\n function getValues<TPath extends Path<FormValues>>(name: TPath): PathValue<FormValues, TPath>\n function getValues<TPath extends Path<FormValues>>(names: TPath[]): Partial<FormValues>\n function getValues<TPath extends Path<FormValues>>(\n nameOrNames?: TPath | TPath[],\n ): FormValues | PathValue<FormValues, TPath> | Partial<FormValues> {\n // Sync values from uncontrolled inputs before returning\n for (const [name, fieldRef] of ctx.fieldRefs.entries()) {\n const el = fieldRef.value\n if (el) {\n const opts = ctx.fieldOptions.get(name)\n if (!opts?.controlled) {\n const value = el.type === 'checkbox' ? el.checked : el.value\n set(ctx.formData, name, value)\n }\n }\n }\n\n if (nameOrNames === undefined) {\n // Return all values\n return { ...ctx.formData } as FormValues\n }\n\n if (Array.isArray(nameOrNames)) {\n // Return multiple field values\n const result: Record<string, unknown> = {}\n for (const fieldName of nameOrNames) {\n result[fieldName] = get(ctx.formData, fieldName)\n }\n return result as Partial<FormValues>\n }\n\n // Return single field value\n return get(ctx.formData, nameOrNames) as PathValue<FormValues, TPath>\n }\n\n /**\n * Get the state of an individual field\n */\n function getFieldState<TPath extends Path<FormValues>>(name: TPath): FieldState {\n const error = get(ctx.errors.value, name) as string | { type: string; message: string } | undefined\n return {\n isDirty: ctx.dirtyFields.value[name] === true,\n isTouched: ctx.touchedFields.value[name] === true,\n invalid: error !== undefined && error !== null,\n error,\n }\n }\n\n /**\n * Manually trigger validation for specific fields or entire form\n */\n async function trigger<TPath extends Path<FormValues>>(\n name?: TPath | TPath[],\n ): Promise<boolean> {\n if (name === undefined) {\n // Validate entire form\n return await validate()\n }\n\n if (Array.isArray(name)) {\n // Validate multiple fields\n let allValid = true\n for (const fieldName of name) {\n const isValid = await validate(fieldName)\n if (!isValid) {\n allValid = false\n }\n }\n return allValid\n }\n\n // Validate single field\n return await validate(name)\n }\n\n /**\n * Programmatically focus a field\n */\n function setFocus<TPath extends Path<FormValues>>(\n name: TPath,\n focusOptions?: SetFocusOptions,\n ): void {\n const fieldRef = ctx.fieldRefs.get(name)\n\n if (!fieldRef?.value) {\n return\n }\n\n const el = fieldRef.value\n\n // Check if element is focusable\n if (typeof el.focus === 'function') {\n el.focus()\n\n // Select text if requested and element supports selection\n if (\n focusOptions?.shouldSelect &&\n el instanceof HTMLInputElement &&\n typeof el.select === 'function'\n ) {\n el.select()\n }\n }\n }\n\n return {\n register,\n unregister,\n handleSubmit,\n formState,\n fields,\n setValue,\n getValue,\n reset,\n watch,\n validate,\n clearErrors,\n setError,\n getValues,\n getFieldState,\n trigger,\n setFocus,\n }\n}\n","import { inject, provide, type InjectionKey } from 'vue'\nimport type { UseFormReturn } from './types'\nimport type { ZodType } from 'zod'\n\n/**\n * Injection key for form context\n */\nexport const FormContextKey: InjectionKey<UseFormReturn<ZodType>> = Symbol('FormContext')\n\n/**\n * Provide form methods to child components via Vue's dependency injection.\n *\n * Call this in a parent component's setup function after calling useForm().\n *\n * @example\n * ```ts\n * // Parent component\n * const form = useForm({ schema })\n * provideForm(form)\n * ```\n *\n * @param methods - The return value from useForm()\n */\nexport function provideForm<TSchema extends ZodType>(methods: UseFormReturn<TSchema>): void {\n provide(FormContextKey, methods as unknown as UseFormReturn<ZodType>)\n}\n\n/**\n * Access form methods in a child component via Vue's dependency injection.\n *\n * Must be used within a component tree where provideForm() has been called.\n *\n * @example\n * ```ts\n * // Child component\n * const { register, formState } = useFormContext()\n * ```\n *\n * @returns The form methods from the parent component's useForm() call\n * @throws Error if used outside of a FormProvider context\n */\nexport function useFormContext<TSchema extends ZodType>(): UseFormReturn<TSchema> {\n const context = inject(FormContextKey)\n\n if (!context) {\n throw new Error(\n 'useFormContext must be used within a component tree where provideForm() has been called. ' +\n 'Make sure to call provideForm(useForm({ schema })) in a parent component.',\n )\n }\n\n return context as unknown as UseFormReturn<TSchema>\n}\n","import { computed, type ComputedRef } from 'vue'\nimport type { ZodType } from 'zod'\nimport type { UseFormReturn, Path, InferSchema } from './types'\nimport { useFormContext } from './context'\nimport { get } from './utils/paths'\n\n/**\n * Options for useWatch composable\n */\nexport interface UseWatchOptions<TSchema extends ZodType, TPath extends Path<InferSchema<TSchema>>> {\n /** Form control from useForm (uses context if not provided) */\n control?: UseFormReturn<TSchema>\n /** Field path or array of paths to watch (watches all if not provided) */\n name?: TPath | TPath[]\n /** Default value when field is undefined */\n defaultValue?: unknown\n}\n\n/**\n * Watch form field values reactively without the full form instance\n *\n * This composable allows you to subscribe to form value changes from any component\n * in the tree, as long as the form context is provided via provideForm().\n *\n * @example\n * ```ts\n * // Watch a single field\n * const email = useWatch({ name: 'email' })\n *\n * // Watch multiple fields\n * const fields = useWatch({ name: ['firstName', 'lastName'] })\n *\n * // Watch all form values\n * const allValues = useWatch({})\n *\n * // With explicit control\n * const { control } = useForm({ schema })\n * const email = useWatch({ control, name: 'email' })\n *\n * // With default value\n * const status = useWatch({ name: 'status', defaultValue: 'pending' })\n * ```\n */\nexport function useWatch<\n TSchema extends ZodType,\n TPath extends Path<InferSchema<TSchema>> = Path<InferSchema<TSchema>>,\n>(options: UseWatchOptions<TSchema, TPath> = {}): ComputedRef<unknown> {\n const { control, name, defaultValue } = options\n\n // Get form control from context if not provided\n const form = control ?? useFormContext<TSchema>()\n\n return computed(() => {\n if (name === undefined) {\n // Watch all values\n return form.getValues()\n }\n\n if (Array.isArray(name)) {\n // Watch multiple fields\n const result: Record<string, unknown> = {}\n for (const fieldName of name) {\n const value = get(form.getValues(), fieldName)\n result[fieldName] = value ?? defaultValue\n }\n return result\n }\n\n // Watch single field\n const value = get(form.getValues(), name)\n return value ?? defaultValue\n })\n}\n","import { computed, ref, type ComputedRef, type Ref } from 'vue'\nimport type { ZodType } from 'zod'\nimport type { UseFormReturn, Path, PathValue, InferSchema, FieldState } from './types'\nimport { useFormContext } from './context'\nimport { get } from './utils/paths'\n\n/**\n * Options for useController composable\n */\nexport interface UseControllerOptions<\n TSchema extends ZodType,\n TPath extends Path<InferSchema<TSchema>>,\n> {\n /** Field name/path */\n name: TPath\n /** Form control from useForm (uses context if not provided) */\n control?: UseFormReturn<TSchema>\n /** Default value for the field */\n defaultValue?: PathValue<InferSchema<TSchema>, TPath>\n}\n\n/**\n * Field props returned by useController\n */\nexport interface ControllerFieldProps<TValue> {\n /** Current field value */\n value: Ref<TValue>\n /** Field name */\n name: string\n /** Change handler - call with new value */\n onChange: (value: TValue) => void\n /** Blur handler */\n onBlur: () => void\n /** Ref callback for the input element */\n ref: (el: HTMLElement | null) => void\n}\n\n/**\n * Return value from useController\n */\nexport interface UseControllerReturn<TValue> {\n /** Field props for binding to input components */\n field: ControllerFieldProps<TValue>\n /** Current field state (errors, dirty, touched) */\n fieldState: ComputedRef<FieldState>\n}\n\n/**\n * Hook for controlled components that need fine-grained control over field state\n *\n * This composable is useful for integrating with custom input components or\n * third-party UI libraries that don't work with the standard register() approach.\n *\n * @example\n * ```ts\n * // Basic usage with context\n * const { field, fieldState } = useController({ name: 'email' })\n *\n * // With explicit control\n * const { control } = useForm({ schema })\n * const { field, fieldState } = useController({ control, name: 'email' })\n *\n * // In template:\n * // <CustomInput\n * // :value=\"field.value.value\"\n * // @update:modelValue=\"field.onChange\"\n * // @blur=\"field.onBlur\"\n * // />\n * // <span v-if=\"fieldState.value.error\">{{ fieldState.value.error }}</span>\n * ```\n */\nexport function useController<\n TSchema extends ZodType,\n TPath extends Path<InferSchema<TSchema>>,\n>(\n options: UseControllerOptions<TSchema, TPath>,\n): UseControllerReturn<PathValue<InferSchema<TSchema>, TPath>> {\n type TValue = PathValue<InferSchema<TSchema>, TPath>\n\n const { name, control, defaultValue } = options\n\n // Get form control from context if not provided\n const form = control ?? useFormContext<TSchema>()\n\n // Element ref for focus management\n const elementRef = ref<HTMLElement | null>(null)\n\n // Initialize with default value if provided\n if (defaultValue !== undefined && form.getValue(name) === undefined) {\n form.setValue(name, defaultValue)\n }\n\n // Create reactive value\n const value = computed({\n get: () => {\n const currentValue = form.getValue(name)\n return (currentValue ?? defaultValue) as TValue\n },\n set: (newValue: TValue) => {\n form.setValue(name, newValue)\n },\n })\n\n // Change handler\n const onChange = (newValue: TValue) => {\n form.setValue(name, newValue)\n }\n\n // Blur handler - triggers validation based on mode\n const onBlur = () => {\n form.trigger(name)\n }\n\n // Ref callback\n const refCallback = (el: HTMLElement | null) => {\n elementRef.value = el\n }\n\n // Field state computed\n const fieldState = computed<FieldState>(() => {\n return form.getFieldState(name)\n })\n\n return {\n field: {\n value: value as unknown as Ref<TValue>,\n name,\n onChange,\n onBlur,\n ref: refCallback,\n },\n fieldState,\n }\n}\n","import { computed, type ComputedRef } from 'vue'\nimport type { ZodType } from 'zod'\nimport type { UseFormReturn, FormState, InferSchema } from './types'\nimport { useFormContext } from './context'\n\n/**\n * Keys of FormState that can be subscribed to\n */\nexport type FormStateKey = keyof FormState<unknown>\n\n/**\n * Options for useFormState composable\n */\nexport interface UseFormStateOptions<TSchema extends ZodType> {\n /** Form control from useForm (uses context if not provided) */\n control?: UseFormReturn<TSchema>\n /** Specific state keys to subscribe to (subscribes to all if not provided) */\n name?: FormStateKey | FormStateKey[]\n}\n\n/**\n * Subscribe to specific form state properties\n *\n * This composable allows you to efficiently subscribe to only the form state\n * properties you need, reducing unnecessary re-renders.\n *\n * @example\n * ```ts\n * // Subscribe to all form state\n * const formState = useFormState({})\n *\n * // Subscribe to specific properties\n * const { isSubmitting, errors } = useFormState({ name: ['isSubmitting', 'errors'] })\n *\n * // Subscribe to single property\n * const isDirty = useFormState({ name: 'isDirty' })\n *\n * // With explicit control\n * const { control } = useForm({ schema })\n * const formState = useFormState({ control })\n * ```\n */\nexport function useFormState<TSchema extends ZodType>(\n options: UseFormStateOptions<TSchema> = {},\n): ComputedRef<Partial<FormState<InferSchema<TSchema>>>> {\n const { control, name } = options\n\n // Get form control from context if not provided\n const form = control ?? useFormContext<TSchema>()\n\n return computed(() => {\n const fullState = form.formState.value\n\n if (name === undefined) {\n // Return all state\n return { ...fullState }\n }\n\n if (Array.isArray(name)) {\n // Return specific properties\n const result: Partial<FormState<InferSchema<TSchema>>> = {}\n for (const key of name) {\n ;(result as Record<string, unknown>)[key] = fullState[key]\n }\n return result\n }\n\n // Return single property wrapped in object\n return { [name]: fullState[name] } as Partial<FormState<InferSchema<TSchema>>>\n })\n}\n"],"mappings":"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"}
|
package/dist/vuehookform.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"vuehookform.js","names":["result: unknown","current: Record<string, unknown>","types: Record<string, string | string[]>","newErrors: Record<string, string | FieldError>","result: Record<string, unknown>","FormContextKey: InjectionKey<UseFormReturn<ZodType>>","result: Record<string, unknown>","result: Partial<FormState<InferSchema<TSchema>>>"],"sources":["../src/lib/utils/paths.ts","../src/lib/core/formContext.ts","../src/lib/core/useValidation.ts","../src/lib/core/useFieldRegistration.ts","../src/lib/core/useFieldArray.ts","../src/lib/useForm.ts","../src/lib/context.ts","../src/lib/useWatch.ts","../src/lib/useController.ts","../src/lib/useFormState.ts"],"sourcesContent":["/**\n * Get value from object using dot notation path\n * @example get({ user: { name: 'John' } }, 'user.name') => 'John'\n */\nexport function get(obj: Record<string, unknown>, path: string): unknown {\n if (!path) return obj\n\n const keys = path.split('.')\n let result: unknown = obj\n\n for (const key of keys) {\n if (result === null || result === undefined) {\n return undefined\n }\n result = (result as Record<string, unknown>)[key]\n }\n\n return result\n}\n\n/**\n * Set value in object using dot notation path\n * @example set({}, 'user.name', 'John') => { user: { name: 'John' } }\n */\nexport function set(obj: Record<string, unknown>, path: string, value: unknown): void {\n if (!path) return\n\n const keys = path.split('.')\n\n // Prototype pollution protection\n const UNSAFE_KEYS = ['__proto__', 'constructor', 'prototype']\n if (keys.some((k) => UNSAFE_KEYS.includes(k))) return\n const lastKey = keys.pop()!\n let current: Record<string, unknown> = obj\n\n // Create nested objects as needed\n for (const key of keys) {\n if (!(key in current) || typeof current[key] !== 'object') {\n // Check if next key is a number to create array vs object\n const nextKey = keys[keys.indexOf(key) + 1]\n current[key] = nextKey && /^\\d+$/.test(nextKey) ? [] : {}\n }\n current = current[key] as Record<string, unknown>\n }\n\n current[lastKey] = value\n}\n\n/**\n * Delete value from object using dot notation path\n * @example unset({ user: { name: 'John' } }, 'user.name') => { user: {} }\n */\nexport function unset(obj: Record<string, unknown>, path: string): void {\n if (!path) return\n\n const keys = path.split('.')\n const lastKey = keys.pop()!\n let current: Record<string, unknown> = obj\n\n for (const key of keys) {\n if (!(key in current)) return\n current = current[key] as Record<string, unknown>\n }\n\n delete current[lastKey]\n}\n\n/**\n * Check if path exists in object\n */\nexport function has(obj: Record<string, unknown>, path: string): boolean {\n return get(obj, path) !== undefined\n}\n\n/**\n * Generate a unique ID for field array items\n */\nlet idCounter = 0\nexport function generateId(): string {\n return `field_${Date.now()}_${idCounter++}`\n}\n\n/**\n * Check if a path represents an array index\n * @example isArrayPath('users.0') => true\n * @example isArrayPath('users.name') => false\n */\nexport function isArrayPath(path: string): boolean {\n const lastSegment = path.split('.').pop()\n return /^\\d+$/.test(lastSegment || '')\n}\n\n/**\n * Get parent path\n * @example getParentPath('user.addresses.0.street') => 'user.addresses.0'\n */\nexport function getParentPath(path: string): string | undefined {\n const segments = path.split('.')\n if (segments.length <= 1) return undefined\n segments.pop()\n return segments.join('.')\n}\n\n/**\n * Get field name from path\n * @example getFieldName('user.addresses.0.street') => 'street'\n */\nexport function getFieldName(path: string): string {\n return path.split('.').pop() || path\n}\n","import { reactive, ref, shallowRef, type Ref, type ShallowRef } from 'vue'\nimport type { ZodType } from 'zod'\nimport type {\n UseFormOptions,\n FieldErrors,\n InferSchema,\n RegisterOptions,\n FieldArrayItem,\n} from '../types'\n\n/**\n * Internal state for field array management\n */\nexport interface FieldArrayState {\n items: Ref<FieldArrayItem[]>\n values: unknown[]\n}\n\n/**\n * Shared form context containing all reactive state\n * This is passed to sub-modules via dependency injection\n */\nexport interface FormContext<FormValues> {\n // Reactive form data\n formData: Record<string, unknown>\n defaultValues: Record<string, unknown>\n\n // Form state\n errors: ShallowRef<FieldErrors<FormValues>>\n touchedFields: Ref<Record<string, boolean>>\n dirtyFields: Ref<Record<string, boolean>>\n isSubmitting: Ref<boolean>\n isLoading: Ref<boolean>\n submitCount: Ref<number>\n\n // Field tracking\n fieldRefs: Map<string, Ref<HTMLInputElement | null>>\n fieldOptions: Map<string, RegisterOptions>\n fieldArrays: Map<string, FieldArrayState>\n\n // Debounce tracking for async validation\n debounceTimers: Map<string, ReturnType<typeof setTimeout>>\n validationRequestIds: Map<string, number>\n\n // Options\n options: UseFormOptions<ZodType>\n}\n\n/**\n * Create a new form context with all reactive state initialized\n */\nexport function createFormContext<TSchema extends ZodType>(\n options: UseFormOptions<TSchema>,\n): FormContext<InferSchema<TSchema>> {\n type FormValues = InferSchema<TSchema>\n\n // Form data storage\n const formData = reactive<Record<string, unknown>>({})\n const defaultValues = reactive<Record<string, unknown>>({})\n\n // Check if defaultValues is a function (async) or an object (sync)\n const isAsyncDefaults = typeof options.defaultValues === 'function'\n const isLoading = ref(isAsyncDefaults)\n\n if (isAsyncDefaults) {\n // Async default values - load them\n const asyncFn = options.defaultValues as () => Promise<Partial<FormValues>>\n asyncFn()\n .then((values) => {\n Object.assign(defaultValues, values)\n Object.assign(formData, values)\n isLoading.value = false\n })\n .catch((error) => {\n console.error('Failed to load async default values:', error)\n isLoading.value = false\n })\n } else if (options.defaultValues) {\n // Sync default values\n Object.assign(defaultValues, options.defaultValues)\n Object.assign(formData, defaultValues)\n }\n\n // Form state - using Record instead of Set for per-field tracking\n const errors = shallowRef<FieldErrors<FormValues>>({})\n const touchedFields = ref<Record<string, boolean>>({})\n const dirtyFields = ref<Record<string, boolean>>({})\n const isSubmitting = ref(false)\n const submitCount = ref(0)\n\n // Field registration tracking\n const fieldRefs = new Map<string, Ref<HTMLInputElement | null>>()\n const fieldOptions = new Map<string, RegisterOptions>()\n\n // Field array tracking for dynamic arrays\n const fieldArrays = new Map<string, FieldArrayState>()\n\n // Debounce tracking for async validation\n const debounceTimers = new Map<string, ReturnType<typeof setTimeout>>()\n const validationRequestIds = new Map<string, number>()\n\n return {\n formData,\n defaultValues,\n errors,\n touchedFields,\n dirtyFields,\n isSubmitting,\n isLoading,\n submitCount,\n fieldRefs,\n fieldOptions,\n fieldArrays,\n debounceTimers,\n validationRequestIds,\n options: options as UseFormOptions<ZodType>,\n }\n}\n","import type { FormContext } from './formContext'\nimport type { FieldErrors, FieldError } from '../types'\nimport { set, get } from '../utils/paths'\n\n/**\n * Helper to clear errors for a specific field path and its children\n */\nfunction clearFieldErrors<T>(\n errors: FieldErrors<T>,\n fieldPath: string,\n): FieldErrors<T> {\n const newErrors = { ...errors }\n for (const key of Object.keys(newErrors)) {\n if (key === fieldPath || key.startsWith(`${fieldPath}.`)) {\n delete newErrors[key as keyof typeof newErrors]\n }\n }\n return newErrors as FieldErrors<T>\n}\n\n/**\n * Group errors by field path for multi-error support\n */\nfunction groupErrorsByPath(\n issues: Array<{ path: (string | number)[]; message: string; code: string }>,\n): Map<string, Array<{ type: string; message: string }>> {\n const grouped = new Map<string, Array<{ type: string; message: string }>>()\n\n for (const issue of issues) {\n const path = issue.path.join('.')\n const existing = grouped.get(path) || []\n existing.push({ type: issue.code, message: issue.message })\n grouped.set(path, existing)\n }\n\n return grouped\n}\n\n/**\n * Convert grouped errors to FieldError format\n * Single error = string (backward compatible)\n * Multiple errors = FieldError with types\n */\nfunction createFieldError(errors: Array<{ type: string; message: string }>): string | FieldError {\n if (errors.length === 1) {\n // Single error - return string for backward compatibility\n return errors[0].message\n }\n\n // Multiple errors - return structured FieldError\n const types: Record<string, string | string[]> = {}\n for (const err of errors) {\n const existing = types[err.type]\n if (existing) {\n // Multiple errors of same type - make array\n types[err.type] = Array.isArray(existing)\n ? [...existing, err.message]\n : [existing, err.message]\n } else {\n types[err.type] = err.message\n }\n }\n\n return {\n type: errors[0].type,\n message: errors[0].message,\n types,\n }\n}\n\n/**\n * Create validation functions for form\n */\nexport function createValidation<FormValues>(ctx: FormContext<FormValues>) {\n /**\n * Validate a single field or entire form\n */\n async function validate(fieldPath?: string): Promise<boolean> {\n // Use safeParseAsync to avoid throwing\n const result = await ctx.options.schema.safeParseAsync(ctx.formData)\n\n if (result.success) {\n // Clear errors on success\n if (fieldPath) {\n ctx.errors.value = clearFieldErrors(ctx.errors.value, fieldPath)\n } else {\n ctx.errors.value = {} as FieldErrors<FormValues>\n }\n return true\n }\n\n // Validation failed - process errors\n const zodErrors = result.error.issues\n\n if (fieldPath) {\n // Single field validation - filter to only this field's errors\n const fieldErrors = zodErrors.filter((issue) => {\n const path = issue.path.join('.')\n return path === fieldPath || path.startsWith(`${fieldPath}.`)\n })\n\n if (fieldErrors.length === 0) {\n // This specific field is valid, clear its errors\n ctx.errors.value = clearFieldErrors(ctx.errors.value, fieldPath)\n return true\n }\n\n // Update only this field's errors (merge with existing), with multi-error support\n let newErrors = clearFieldErrors(ctx.errors.value, fieldPath)\n const grouped = groupErrorsByPath(fieldErrors)\n\n for (const [path, errors] of grouped) {\n set(newErrors, path, createFieldError(errors))\n }\n\n ctx.errors.value = newErrors as FieldErrors<FormValues>\n return false\n }\n\n // Full form validation with multi-error support\n const newErrors: Record<string, string | FieldError> = {}\n const grouped = groupErrorsByPath(zodErrors)\n\n for (const [path, errors] of grouped) {\n set(newErrors, path, createFieldError(errors))\n }\n\n ctx.errors.value = newErrors as FieldErrors<FormValues>\n return false\n }\n\n return { validate }\n}\n","import { computed, ref } from 'vue'\nimport type { FormContext } from './formContext'\nimport type {\n RegisterOptions,\n RegisterReturn,\n FieldErrors,\n Path,\n} from '../types'\nimport { get, set, unset } from '../utils/paths'\n\n/**\n * Create field registration functions\n */\nexport function createFieldRegistration<FormValues>(\n ctx: FormContext<FormValues>,\n validate: (fieldPath?: string) => Promise<boolean>,\n) {\n /**\n * Register an input field\n */\n function register<TPath extends Path<FormValues>>(\n name: TPath,\n registerOptions?: RegisterOptions,\n ): RegisterReturn {\n const fieldRef = ref<HTMLInputElement | null>(null)\n ctx.fieldRefs.set(name, fieldRef)\n\n if (registerOptions) {\n ctx.fieldOptions.set(name, registerOptions)\n }\n\n // Initialize field value if not set\n if (get(ctx.formData, name) === undefined) {\n const defaultValue = get(ctx.defaultValues, name)\n if (defaultValue !== undefined) {\n set(ctx.formData, name, defaultValue)\n }\n }\n\n /**\n * Run custom field validation with optional debouncing\n */\n const runCustomValidation = async (fieldName: string, value: unknown, requestId: number) => {\n const fieldOpts = ctx.fieldOptions.get(fieldName)\n if (!fieldOpts?.validate || fieldOpts.disabled) {\n return\n }\n\n const error = await fieldOpts.validate(value)\n\n // Check if this is still the latest request (race condition handling)\n const latestRequestId = ctx.validationRequestIds.get(fieldName)\n if (requestId !== latestRequestId) {\n return // Stale request, ignore result\n }\n\n if (error) {\n ctx.errors.value = { ...ctx.errors.value, [fieldName]: error } as FieldErrors<FormValues>\n } else {\n // Clear the error if validation passes\n const newErrors = { ...ctx.errors.value }\n delete newErrors[fieldName as keyof typeof newErrors]\n ctx.errors.value = newErrors as FieldErrors<FormValues>\n }\n }\n\n /**\n * Handle field input (fires on every keystroke)\n */\n const onInput = async (e: Event) => {\n const target = e.target as HTMLInputElement\n const value = target.type === 'checkbox' ? target.checked : target.value\n\n // Update form data\n set(ctx.formData, name, value)\n\n // Mark as dirty using Record\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n\n // Validate based on mode\n if (\n ctx.options.mode === 'onChange' ||\n (ctx.options.mode === 'onTouched' && ctx.touchedFields.value[name]) ||\n (ctx.touchedFields.value[name] && ctx.options.reValidateMode === 'onChange')\n ) {\n await validate(name)\n }\n\n // Custom validation with optional debouncing\n const fieldOpts = ctx.fieldOptions.get(name)\n if (fieldOpts?.validate && !fieldOpts.disabled) {\n // Generate a new request ID for race condition handling\n const requestId = Date.now() + Math.random()\n ctx.validationRequestIds.set(name, requestId)\n\n const debounceMs = fieldOpts.validateDebounce || 0\n\n if (debounceMs > 0) {\n // Cancel any existing debounce timer\n const existingTimer = ctx.debounceTimers.get(name)\n if (existingTimer) {\n clearTimeout(existingTimer)\n }\n\n // Set new debounce timer\n const timer = setTimeout(() => {\n ctx.debounceTimers.delete(name)\n runCustomValidation(name, value, requestId)\n }, debounceMs)\n\n ctx.debounceTimers.set(name, timer)\n } else {\n // No debounce, run immediately\n await runCustomValidation(name, value, requestId)\n }\n }\n }\n\n /**\n * Handle field blur\n */\n const onBlur = async (_e: Event) => {\n // Mark as touched using Record\n ctx.touchedFields.value = { ...ctx.touchedFields.value, [name]: true }\n\n // Validate based on mode\n if (\n ctx.options.mode === 'onBlur' ||\n ctx.options.mode === 'onTouched' ||\n (ctx.submitCount.value > 0 && ctx.options.reValidateMode === 'onBlur')\n ) {\n await validate(name)\n }\n }\n\n /**\n * Ref callback to store element reference\n */\n const refCallback = (el: unknown) => {\n const previousEl = fieldRef.value\n fieldRef.value = el as HTMLInputElement | null\n\n // Set initial value for uncontrolled inputs\n if (el && !registerOptions?.controlled && el instanceof HTMLInputElement) {\n const value = get(ctx.formData, name)\n if (value !== undefined) {\n if (el.type === 'checkbox') {\n el.checked = value as boolean\n } else {\n el.value = value as string\n }\n }\n }\n\n // Handle shouldUnregister when element is removed (ref becomes null)\n if (previousEl && !el) {\n const shouldUnreg =\n registerOptions?.shouldUnregister ?? ctx.options.shouldUnregister ?? false\n\n if (shouldUnreg) {\n // Clear form data for this field\n unset(ctx.formData, name)\n\n // Clear errors for this field\n const newErrors = { ...ctx.errors.value }\n delete newErrors[name as keyof typeof newErrors]\n ctx.errors.value = newErrors as FieldErrors<FormValues>\n\n // Clear touched/dirty state\n const newTouched = { ...ctx.touchedFields.value }\n delete newTouched[name]\n ctx.touchedFields.value = newTouched\n\n const newDirty = { ...ctx.dirtyFields.value }\n delete newDirty[name]\n ctx.dirtyFields.value = newDirty\n\n // Clean up refs and options\n ctx.fieldRefs.delete(name)\n ctx.fieldOptions.delete(name)\n\n // Clean up debounce timers\n const timer = ctx.debounceTimers.get(name)\n if (timer) {\n clearTimeout(timer)\n ctx.debounceTimers.delete(name)\n }\n ctx.validationRequestIds.delete(name)\n }\n }\n }\n\n return {\n name,\n ref: refCallback,\n onInput,\n onBlur,\n ...(registerOptions?.controlled && {\n value: computed({\n get: () => get(ctx.formData, name),\n set: (val) => {\n set(ctx.formData, name, val)\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n },\n }),\n }),\n }\n }\n\n /**\n * Unregister a field to clean up refs and options\n */\n function unregister<TPath extends Path<FormValues>>(name: TPath): void {\n ctx.fieldRefs.delete(name)\n ctx.fieldOptions.delete(name)\n\n // Clean up debounce timers\n const timer = ctx.debounceTimers.get(name)\n if (timer) {\n clearTimeout(timer)\n ctx.debounceTimers.delete(name)\n }\n ctx.validationRequestIds.delete(name)\n }\n\n return { register, unregister }\n}\n","import { ref } from 'vue'\nimport type { FormContext } from './formContext'\nimport type { FieldArray, FieldArrayItem, Path } from '../types'\nimport { get, set, generateId } from '../utils/paths'\n\n/**\n * Create field array management functions\n */\nexport function createFieldArrayManager<FormValues>(\n ctx: FormContext<FormValues>,\n validate: (fieldPath?: string) => Promise<boolean>,\n) {\n /**\n * Manage dynamic field arrays\n */\n function fields<TPath extends Path<FormValues>>(name: TPath): FieldArray {\n // Get or create field array entry\n let fieldArray = ctx.fieldArrays.get(name)\n\n if (!fieldArray) {\n const existingValues = (get(ctx.formData, name) || []) as unknown[]\n fieldArray = {\n items: ref<FieldArrayItem[]>([]),\n values: existingValues,\n }\n ctx.fieldArrays.set(name, fieldArray)\n\n // Initialize form data if needed\n if (!get(ctx.formData, name)) {\n set(ctx.formData, name, [] as unknown[])\n }\n }\n\n // Capture reference for closures\n const fa = fieldArray\n\n /**\n * Helper to create items with dynamic index lookup\n * Uses getters so index is always current, not stale\n */\n const createItem = (key: string): FieldArrayItem => ({\n key,\n get index() {\n return fa.items.value.findIndex((item) => item.key === key)\n },\n remove() {\n const currentIndex = fa.items.value.findIndex((item) => item.key === key)\n if (currentIndex !== -1) {\n removeAt(currentIndex)\n }\n },\n })\n\n // Populate items if empty (first access after creation)\n if (fa.items.value.length === 0 && fa.values.length > 0) {\n fa.items.value = fa.values.map(() => createItem(generateId()))\n }\n\n const append = (value: unknown) => {\n const currentValues = (get(ctx.formData, name) || []) as unknown[]\n const newValues = [...currentValues, value]\n set(ctx.formData, name, newValues)\n\n fa.items.value = [...fa.items.value, createItem(generateId())]\n\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n\n if (ctx.options.mode === 'onChange') {\n validate(name)\n }\n }\n\n const prepend = (value: unknown) => {\n insert(0, value)\n }\n\n const update = (index: number, value: unknown) => {\n const currentValues = (get(ctx.formData, name) || []) as unknown[]\n if (index < 0 || index >= currentValues.length) {\n return // Invalid index, do nothing\n }\n const newValues = [...currentValues]\n newValues[index] = value\n set(ctx.formData, name, newValues)\n\n // Keep the same key - no items array change needed (preserves stable identity)\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n\n if (ctx.options.mode === 'onChange') {\n validate(name)\n }\n }\n\n const removeAt = (index: number) => {\n const currentValues = (get(ctx.formData, name) || []) as unknown[]\n const newValues = currentValues.filter((_: unknown, i: number) => i !== index)\n set(ctx.formData, name, newValues)\n\n // Remove item by current index, keep others (indices auto-update via getter)\n const keyToRemove = fa.items.value[index]?.key\n fa.items.value = fa.items.value.filter((item) => item.key !== keyToRemove)\n\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n\n if (ctx.options.mode === 'onChange') {\n validate(name)\n }\n }\n\n const insert = (index: number, value: unknown) => {\n const currentValues = (get(ctx.formData, name) || []) as unknown[]\n const newValues = [...currentValues.slice(0, index), value, ...currentValues.slice(index)]\n set(ctx.formData, name, newValues)\n\n const newItem = createItem(generateId())\n fa.items.value = [...fa.items.value.slice(0, index), newItem, ...fa.items.value.slice(index)]\n\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n\n if (ctx.options.mode === 'onChange') {\n validate(name)\n }\n }\n\n const swap = (indexA: number, indexB: number) => {\n const currentValues = (get(ctx.formData, name) || []) as unknown[]\n const newValues = [...currentValues]\n ;[newValues[indexA], newValues[indexB]] = [newValues[indexB], newValues[indexA]]\n set(ctx.formData, name, newValues)\n\n // Swap items in array (indices auto-update via getter)\n const newItems = [...fa.items.value]\n const itemA = newItems[indexA]\n const itemB = newItems[indexB]\n if (itemA && itemB) {\n newItems[indexA] = itemB\n newItems[indexB] = itemA\n fa.items.value = newItems\n }\n\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n\n if (ctx.options.mode === 'onChange') {\n validate(name)\n }\n }\n\n const move = (from: number, to: number) => {\n const currentValues = (get(ctx.formData, name) || []) as unknown[]\n const newValues = [...currentValues]\n const [removed] = newValues.splice(from, 1)\n if (removed !== undefined) {\n newValues.splice(to, 0, removed)\n set(ctx.formData, name, newValues)\n }\n\n // Move item in array (indices auto-update via getter)\n const newItems = [...fa.items.value]\n const [removedItem] = newItems.splice(from, 1)\n if (removedItem) {\n newItems.splice(to, 0, removedItem)\n fa.items.value = newItems\n }\n\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n\n if (ctx.options.mode === 'onChange') {\n validate(name)\n }\n }\n\n return {\n value: fa.items.value,\n append,\n prepend,\n remove: removeAt,\n insert,\n swap,\n move,\n update,\n }\n }\n\n return { fields }\n}\n","import { computed } from 'vue'\nimport type { ZodType } from 'zod'\nimport type {\n UseFormOptions,\n UseFormReturn,\n FormState,\n FieldErrors,\n FieldState,\n ErrorOption,\n SetFocusOptions,\n ResetOptions,\n InferSchema,\n Path,\n PathValue,\n} from './types'\nimport { get, set } from './utils/paths'\nimport { createFormContext } from './core/formContext'\nimport { createValidation } from './core/useValidation'\nimport { createFieldRegistration } from './core/useFieldRegistration'\nimport { createFieldArrayManager } from './core/useFieldArray'\n\n/**\n * Main form management composable\n *\n * @example\n * ```ts\n * const schema = z.object({\n * email: z.email(),\n * name: z.string().min(2)\n * })\n *\n * const { register, handleSubmit, formState } = useForm({ schema })\n *\n * const onSubmit = (data) => {\n * console.log(data) // { email: '...', name: '...' }\n * }\n * ```\n */\nexport function useForm<TSchema extends ZodType>(\n options: UseFormOptions<TSchema>,\n): UseFormReturn<TSchema> {\n type FormValues = InferSchema<TSchema>\n\n // Create shared context with all reactive state\n const ctx = createFormContext(options)\n\n // Create validation functions\n const { validate } = createValidation<FormValues>(ctx)\n\n // Create field registration functions\n const { register, unregister } = createFieldRegistration<FormValues>(ctx, validate)\n\n // Create field array manager\n const { fields } = createFieldArrayManager<FormValues>(ctx, validate)\n\n /**\n * Get current form state\n */\n const formState = computed<FormState<FormValues>>(() => ({\n errors: ctx.errors.value,\n isDirty: Object.keys(ctx.dirtyFields.value).some((k) => ctx.dirtyFields.value[k]),\n dirtyFields: ctx.dirtyFields.value,\n isValid:\n (ctx.submitCount.value > 0 || Object.keys(ctx.touchedFields.value).length > 0) &&\n Object.keys(ctx.errors.value).length === 0,\n isSubmitting: ctx.isSubmitting.value,\n isLoading: ctx.isLoading.value,\n touchedFields: ctx.touchedFields.value,\n submitCount: ctx.submitCount.value,\n }))\n\n /**\n * Handle form submission\n */\n function handleSubmit(\n onValid: (data: FormValues) => void | Promise<void>,\n onInvalid?: (errors: FieldErrors<FormValues>) => void,\n ) {\n return async (e: Event) => {\n e.preventDefault()\n\n ctx.isSubmitting.value = true\n ctx.submitCount.value++\n\n try {\n // Collect values from uncontrolled inputs\n for (const [name, fieldRef] of ctx.fieldRefs.entries()) {\n const el = fieldRef.value\n if (el) {\n const opts = ctx.fieldOptions.get(name)\n if (!opts?.controlled) {\n const value = el.type === 'checkbox' ? el.checked : el.value\n set(ctx.formData, name, value)\n }\n }\n }\n\n // Validate entire form\n const isValid = await validate()\n\n if (isValid) {\n // Call success handler with validated data\n await onValid(ctx.formData as FormValues)\n } else {\n // Call error handler if provided\n onInvalid?.(ctx.errors.value)\n }\n } finally {\n ctx.isSubmitting.value = false\n }\n }\n }\n\n /**\n * Set field value programmatically\n */\n function setValue<TPath extends Path<FormValues>>(\n name: TPath,\n value: PathValue<FormValues, TPath>,\n ): void {\n set(ctx.formData, name, value)\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n\n // Update input element if it exists\n const fieldRef = ctx.fieldRefs.get(name)\n if (fieldRef?.value) {\n const el = fieldRef.value\n if (el.type === 'checkbox') {\n el.checked = value as boolean\n } else {\n el.value = value as string\n }\n }\n\n // Validate if needed\n if (options.mode === 'onChange' || ctx.touchedFields.value[name]) {\n validate(name)\n }\n }\n\n /**\n * Get field value\n */\n function getValue<TPath extends Path<FormValues>>(\n name: TPath,\n ): PathValue<FormValues, TPath> | undefined {\n return get(ctx.formData, name) as PathValue<FormValues, TPath> | undefined\n }\n\n /**\n * Reset form to default values\n */\n function reset(values?: Partial<FormValues>, resetOptions?: ResetOptions): void {\n const opts = resetOptions || {}\n\n // Update default values unless keepDefaultValues is true\n if (!opts.keepDefaultValues && values) {\n Object.assign(ctx.defaultValues, values)\n }\n\n // Clear form data\n Object.keys(ctx.formData).forEach((key) => delete ctx.formData[key])\n\n // Apply new values or defaults\n const newValues = values || ctx.defaultValues\n Object.assign(ctx.formData, newValues)\n\n // Reset state based on options\n if (!opts.keepErrors) {\n ctx.errors.value = {} as FieldErrors<FormValues>\n }\n if (!opts.keepTouched) {\n ctx.touchedFields.value = {}\n }\n if (!opts.keepDirty) {\n ctx.dirtyFields.value = {}\n }\n if (!opts.keepSubmitCount) {\n ctx.submitCount.value = 0\n }\n if (!opts.keepIsSubmitting) {\n ctx.isSubmitting.value = false\n }\n\n // Always clear field arrays (they'll be recreated on next access)\n ctx.fieldArrays.clear()\n\n // Update input elements\n for (const [name, fieldRef] of ctx.fieldRefs.entries()) {\n const el = fieldRef.value\n if (el) {\n const value = get(newValues as Record<string, unknown>, name)\n if (value !== undefined) {\n if (el.type === 'checkbox') {\n el.checked = value as boolean\n } else {\n el.value = value as string\n }\n }\n }\n }\n }\n\n /**\n * Watch field value(s) reactively\n */\n function watch<TPath extends Path<FormValues>>(name?: TPath | TPath[]) {\n return computed(() => {\n if (!name) {\n return ctx.formData\n }\n if (Array.isArray(name)) {\n return name.reduce(\n (acc, n) => {\n acc[n] = get(ctx.formData, n)\n return acc\n },\n {} as Record<TPath, unknown>,\n )\n }\n return get(ctx.formData, name)\n })\n }\n\n // ========================================\n // NEW P0/P1 FEATURES\n // ========================================\n\n /**\n * Clear errors for one or more fields, or all errors\n */\n function clearErrors<TPath extends Path<FormValues>>(name?: TPath | TPath[]): void {\n if (name === undefined) {\n // Clear all errors\n ctx.errors.value = {} as FieldErrors<FormValues>\n return\n }\n\n const fieldsToClean = Array.isArray(name) ? name : [name]\n const newErrors = { ...ctx.errors.value }\n\n for (const field of fieldsToClean) {\n // Clear exact path and any nested paths\n for (const key of Object.keys(newErrors)) {\n if (key === field || key.startsWith(`${field}.`)) {\n delete newErrors[key as keyof typeof newErrors]\n }\n }\n }\n\n ctx.errors.value = newErrors as FieldErrors<FormValues>\n }\n\n /**\n * Programmatically set an error for a field\n * Supports both simple string errors (backward compatible) and structured FieldError objects\n */\n function setError<TPath extends Path<FormValues>>(\n name: TPath | 'root' | `root.${string}`,\n error: ErrorOption,\n ): void {\n const newErrors = { ...ctx.errors.value }\n\n // Create structured error if type is provided, otherwise use string for backward compatibility\n const errorValue = error.type\n ? { type: error.type, message: error.message }\n : error.message\n\n set(newErrors, name, errorValue)\n ctx.errors.value = newErrors as FieldErrors<FormValues>\n }\n\n /**\n * Get form values - all values, single field, or multiple fields\n */\n function getValues(): FormValues\n function getValues<TPath extends Path<FormValues>>(name: TPath): PathValue<FormValues, TPath>\n function getValues<TPath extends Path<FormValues>>(names: TPath[]): Partial<FormValues>\n function getValues<TPath extends Path<FormValues>>(\n nameOrNames?: TPath | TPath[],\n ): FormValues | PathValue<FormValues, TPath> | Partial<FormValues> {\n // Sync values from uncontrolled inputs before returning\n for (const [name, fieldRef] of ctx.fieldRefs.entries()) {\n const el = fieldRef.value\n if (el) {\n const opts = ctx.fieldOptions.get(name)\n if (!opts?.controlled) {\n const value = el.type === 'checkbox' ? el.checked : el.value\n set(ctx.formData, name, value)\n }\n }\n }\n\n if (nameOrNames === undefined) {\n // Return all values\n return { ...ctx.formData } as FormValues\n }\n\n if (Array.isArray(nameOrNames)) {\n // Return multiple field values\n const result: Record<string, unknown> = {}\n for (const fieldName of nameOrNames) {\n result[fieldName] = get(ctx.formData, fieldName)\n }\n return result as Partial<FormValues>\n }\n\n // Return single field value\n return get(ctx.formData, nameOrNames) as PathValue<FormValues, TPath>\n }\n\n /**\n * Get the state of an individual field\n */\n function getFieldState<TPath extends Path<FormValues>>(name: TPath): FieldState {\n const error = get(ctx.errors.value, name) as string | { type: string; message: string } | undefined\n return {\n isDirty: ctx.dirtyFields.value[name] === true,\n isTouched: ctx.touchedFields.value[name] === true,\n invalid: error !== undefined && error !== null,\n error,\n }\n }\n\n /**\n * Manually trigger validation for specific fields or entire form\n */\n async function trigger<TPath extends Path<FormValues>>(\n name?: TPath | TPath[],\n ): Promise<boolean> {\n if (name === undefined) {\n // Validate entire form\n return await validate()\n }\n\n if (Array.isArray(name)) {\n // Validate multiple fields\n let allValid = true\n for (const fieldName of name) {\n const isValid = await validate(fieldName)\n if (!isValid) {\n allValid = false\n }\n }\n return allValid\n }\n\n // Validate single field\n return await validate(name)\n }\n\n /**\n * Programmatically focus a field\n */\n function setFocus<TPath extends Path<FormValues>>(\n name: TPath,\n focusOptions?: SetFocusOptions,\n ): void {\n const fieldRef = ctx.fieldRefs.get(name)\n\n if (!fieldRef?.value) {\n return\n }\n\n const el = fieldRef.value\n\n // Check if element is focusable\n if (typeof el.focus === 'function') {\n el.focus()\n\n // Select text if requested and element supports selection\n if (\n focusOptions?.shouldSelect &&\n el instanceof HTMLInputElement &&\n typeof el.select === 'function'\n ) {\n el.select()\n }\n }\n }\n\n return {\n register,\n unregister,\n handleSubmit,\n formState,\n fields,\n setValue,\n getValue,\n reset,\n watch,\n validate,\n clearErrors,\n setError,\n getValues,\n getFieldState,\n trigger,\n setFocus,\n }\n}\n","import { inject, provide, type InjectionKey } from 'vue'\nimport type { UseFormReturn } from './types'\nimport type { ZodType } from 'zod'\n\n/**\n * Injection key for form context\n */\nexport const FormContextKey: InjectionKey<UseFormReturn<ZodType>> = Symbol('FormContext')\n\n/**\n * Provide form methods to child components via Vue's dependency injection.\n *\n * Call this in a parent component's setup function after calling useForm().\n *\n * @example\n * ```ts\n * // Parent component\n * const form = useForm({ schema })\n * provideForm(form)\n * ```\n *\n * @param methods - The return value from useForm()\n */\nexport function provideForm<TSchema extends ZodType>(methods: UseFormReturn<TSchema>): void {\n provide(FormContextKey, methods as unknown as UseFormReturn<ZodType>)\n}\n\n/**\n * Access form methods in a child component via Vue's dependency injection.\n *\n * Must be used within a component tree where provideForm() has been called.\n *\n * @example\n * ```ts\n * // Child component\n * const { register, formState } = useFormContext()\n * ```\n *\n * @returns The form methods from the parent component's useForm() call\n * @throws Error if used outside of a FormProvider context\n */\nexport function useFormContext<TSchema extends ZodType>(): UseFormReturn<TSchema> {\n const context = inject(FormContextKey)\n\n if (!context) {\n throw new Error(\n 'useFormContext must be used within a component tree where provideForm() has been called. ' +\n 'Make sure to call provideForm(useForm({ schema })) in a parent component.',\n )\n }\n\n return context as unknown as UseFormReturn<TSchema>\n}\n","import { computed, type ComputedRef } from 'vue'\nimport type { ZodType } from 'zod'\nimport type { UseFormReturn, Path, InferSchema } from './types'\nimport { useFormContext } from './context'\nimport { get } from './utils/paths'\n\n/**\n * Options for useWatch composable\n */\nexport interface UseWatchOptions<TSchema extends ZodType, TPath extends Path<InferSchema<TSchema>>> {\n /** Form control from useForm (uses context if not provided) */\n control?: UseFormReturn<TSchema>\n /** Field path or array of paths to watch (watches all if not provided) */\n name?: TPath | TPath[]\n /** Default value when field is undefined */\n defaultValue?: unknown\n}\n\n/**\n * Watch form field values reactively without the full form instance\n *\n * This composable allows you to subscribe to form value changes from any component\n * in the tree, as long as the form context is provided via provideForm().\n *\n * @example\n * ```ts\n * // Watch a single field\n * const email = useWatch({ name: 'email' })\n *\n * // Watch multiple fields\n * const fields = useWatch({ name: ['firstName', 'lastName'] })\n *\n * // Watch all form values\n * const allValues = useWatch({})\n *\n * // With explicit control\n * const { control } = useForm({ schema })\n * const email = useWatch({ control, name: 'email' })\n *\n * // With default value\n * const status = useWatch({ name: 'status', defaultValue: 'pending' })\n * ```\n */\nexport function useWatch<\n TSchema extends ZodType,\n TPath extends Path<InferSchema<TSchema>> = Path<InferSchema<TSchema>>,\n>(options: UseWatchOptions<TSchema, TPath> = {}): ComputedRef<unknown> {\n const { control, name, defaultValue } = options\n\n // Get form control from context if not provided\n const form = control ?? useFormContext<TSchema>()\n\n return computed(() => {\n if (name === undefined) {\n // Watch all values\n return form.getValues()\n }\n\n if (Array.isArray(name)) {\n // Watch multiple fields\n const result: Record<string, unknown> = {}\n for (const fieldName of name) {\n const value = get(form.getValues(), fieldName)\n result[fieldName] = value ?? defaultValue\n }\n return result\n }\n\n // Watch single field\n const value = get(form.getValues(), name)\n return value ?? defaultValue\n })\n}\n","import { computed, ref, type ComputedRef, type Ref } from 'vue'\nimport type { ZodType } from 'zod'\nimport type { UseFormReturn, Path, PathValue, InferSchema, FieldState } from './types'\nimport { useFormContext } from './context'\nimport { get } from './utils/paths'\n\n/**\n * Options for useController composable\n */\nexport interface UseControllerOptions<\n TSchema extends ZodType,\n TPath extends Path<InferSchema<TSchema>>,\n> {\n /** Field name/path */\n name: TPath\n /** Form control from useForm (uses context if not provided) */\n control?: UseFormReturn<TSchema>\n /** Default value for the field */\n defaultValue?: PathValue<InferSchema<TSchema>, TPath>\n}\n\n/**\n * Field props returned by useController\n */\nexport interface ControllerFieldProps<TValue> {\n /** Current field value */\n value: Ref<TValue>\n /** Field name */\n name: string\n /** Change handler - call with new value */\n onChange: (value: TValue) => void\n /** Blur handler */\n onBlur: () => void\n /** Ref callback for the input element */\n ref: (el: HTMLElement | null) => void\n}\n\n/**\n * Return value from useController\n */\nexport interface UseControllerReturn<TValue> {\n /** Field props for binding to input components */\n field: ControllerFieldProps<TValue>\n /** Current field state (errors, dirty, touched) */\n fieldState: ComputedRef<FieldState>\n}\n\n/**\n * Hook for controlled components that need fine-grained control over field state\n *\n * This composable is useful for integrating with custom input components or\n * third-party UI libraries that don't work with the standard register() approach.\n *\n * @example\n * ```ts\n * // Basic usage with context\n * const { field, fieldState } = useController({ name: 'email' })\n *\n * // With explicit control\n * const { control } = useForm({ schema })\n * const { field, fieldState } = useController({ control, name: 'email' })\n *\n * // In template:\n * // <CustomInput\n * // :value=\"field.value.value\"\n * // @update:modelValue=\"field.onChange\"\n * // @blur=\"field.onBlur\"\n * // />\n * // <span v-if=\"fieldState.value.error\">{{ fieldState.value.error }}</span>\n * ```\n */\nexport function useController<\n TSchema extends ZodType,\n TPath extends Path<InferSchema<TSchema>>,\n>(\n options: UseControllerOptions<TSchema, TPath>,\n): UseControllerReturn<PathValue<InferSchema<TSchema>, TPath>> {\n type TValue = PathValue<InferSchema<TSchema>, TPath>\n\n const { name, control, defaultValue } = options\n\n // Get form control from context if not provided\n const form = control ?? useFormContext<TSchema>()\n\n // Element ref for focus management\n const elementRef = ref<HTMLElement | null>(null)\n\n // Initialize with default value if provided\n if (defaultValue !== undefined && form.getValue(name) === undefined) {\n form.setValue(name, defaultValue)\n }\n\n // Create reactive value\n const value = computed({\n get: () => {\n const currentValue = form.getValue(name)\n return (currentValue ?? defaultValue) as TValue\n },\n set: (newValue: TValue) => {\n form.setValue(name, newValue)\n },\n })\n\n // Change handler\n const onChange = (newValue: TValue) => {\n form.setValue(name, newValue)\n }\n\n // Blur handler - triggers validation based on mode\n const onBlur = () => {\n form.trigger(name)\n }\n\n // Ref callback\n const refCallback = (el: HTMLElement | null) => {\n elementRef.value = el\n }\n\n // Field state computed\n const fieldState = computed<FieldState>(() => {\n return form.getFieldState(name)\n })\n\n return {\n field: {\n value: value as unknown as Ref<TValue>,\n name,\n onChange,\n onBlur,\n ref: refCallback,\n },\n fieldState,\n }\n}\n","import { computed, type ComputedRef } from 'vue'\nimport type { ZodType } from 'zod'\nimport type { UseFormReturn, FormState, InferSchema } from './types'\nimport { useFormContext } from './context'\n\n/**\n * Keys of FormState that can be subscribed to\n */\nexport type FormStateKey = keyof FormState<unknown>\n\n/**\n * Options for useFormState composable\n */\nexport interface UseFormStateOptions<TSchema extends ZodType> {\n /** Form control from useForm (uses context if not provided) */\n control?: UseFormReturn<TSchema>\n /** Specific state keys to subscribe to (subscribes to all if not provided) */\n name?: FormStateKey | FormStateKey[]\n}\n\n/**\n * Subscribe to specific form state properties\n *\n * This composable allows you to efficiently subscribe to only the form state\n * properties you need, reducing unnecessary re-renders.\n *\n * @example\n * ```ts\n * // Subscribe to all form state\n * const formState = useFormState({})\n *\n * // Subscribe to specific properties\n * const { isSubmitting, errors } = useFormState({ name: ['isSubmitting', 'errors'] })\n *\n * // Subscribe to single property\n * const isDirty = useFormState({ name: 'isDirty' })\n *\n * // With explicit control\n * const { control } = useForm({ schema })\n * const formState = useFormState({ control })\n * ```\n */\nexport function useFormState<TSchema extends ZodType>(\n options: UseFormStateOptions<TSchema> = {},\n): ComputedRef<Partial<FormState<InferSchema<TSchema>>>> {\n const { control, name } = options\n\n // Get form control from context if not provided\n const form = control ?? useFormContext<TSchema>()\n\n return computed(() => {\n const fullState = form.formState.value\n\n if (name === undefined) {\n // Return all state\n return { ...fullState }\n }\n\n if (Array.isArray(name)) {\n // Return specific properties\n const result: Partial<FormState<InferSchema<TSchema>>> = {}\n for (const key of name) {\n ;(result as Record<string, unknown>)[key] = fullState[key]\n }\n return result\n }\n\n // Return single property wrapped in object\n return { [name]: fullState[name] } as Partial<FormState<InferSchema<TSchema>>>\n })\n}\n"],"mappings":";AAIA,SAAgB,IAAI,KAA8B,MAAuB;AACvE,KAAI,CAAC,KAAM,QAAO;CAElB,MAAM,OAAO,KAAK,MAAM,IAAI;CAC5B,IAAIA,SAAkB;AAEtB,MAAK,MAAM,OAAO,MAAM;AACtB,MAAI,WAAW,QAAQ,WAAW,KAAA,EAChC;AAEF,WAAU,OAAmC;;AAG/C,QAAO;;AAOT,SAAgB,IAAI,KAA8B,MAAc,OAAsB;AACpF,KAAI,CAAC,KAAM;CAEX,MAAM,OAAO,KAAK,MAAM,IAAI;CAG5B,MAAM,cAAc;EAAC;EAAa;EAAe;EAAY;AAC7D,KAAI,KAAK,MAAM,MAAM,YAAY,SAAS,EAAE,CAAC,CAAE;CAC/C,MAAM,UAAU,KAAK,KAAK;CAC1B,IAAIC,UAAmC;AAGvC,MAAK,MAAM,OAAO,MAAM;AACtB,MAAI,EAAE,OAAO,YAAY,OAAO,QAAQ,SAAS,UAAU;GAEzD,MAAM,UAAU,KAAK,KAAK,QAAQ,IAAI,GAAG;AACzC,WAAQ,OAAO,WAAW,QAAQ,KAAK,QAAQ,GAAG,EAAE,GAAG,EAAE;;AAE3D,YAAU,QAAQ;;AAGpB,SAAQ,WAAW;;AAOrB,SAAgB,MAAM,KAA8B,MAAoB;AACtE,KAAI,CAAC,KAAM;CAEX,MAAM,OAAO,KAAK,MAAM,IAAI;CAC5B,MAAM,UAAU,KAAK,KAAK;CAC1B,IAAIA,UAAmC;AAEvC,MAAK,MAAM,OAAO,MAAM;AACtB,MAAI,EAAE,OAAO,SAAU;AACvB,YAAU,QAAQ;;AAGpB,QAAO,QAAQ;;AAajB,IAAI,YAAY;AAChB,SAAgB,aAAqB;AACnC,QAAO,SAAS,KAAK,KAAK,CAAC,GAAG;;AC5BhC,SAAgB,kBACd,SACmC;CAInC,MAAM,WAAW,SAAkC,EAAE,CAAC;CACtD,MAAM,gBAAgB,SAAkC,EAAE,CAAC;CAG3D,MAAM,kBAAkB,OAAO,QAAQ,kBAAkB;CACzD,MAAM,YAAY,IAAI,gBAAgB;AAEtC,KAAI,iBAAiB;EAEnB,MAAM,UAAU,QAAQ;AACxB,WAAS,CACN,MAAM,WAAW;AAChB,UAAO,OAAO,eAAe,OAAO;AACpC,UAAO,OAAO,UAAU,OAAO;AAC/B,aAAU,QAAQ;IAClB,CACD,OAAO,UAAU;AAChB,WAAQ,MAAM,wCAAwC,MAAM;AAC5D,aAAU,QAAQ;IAClB;YACK,QAAQ,eAAe;AAEhC,SAAO,OAAO,eAAe,QAAQ,cAAc;AACnD,SAAO,OAAO,UAAU,cAAc;;AAqBxC,QAAO;EACL;EACA;EACA,QApBa,WAAoC,EAAE,CAAC;EAqBpD,eApBoB,IAA6B,EAAE,CAAC;EAqBpD,aApBkB,IAA6B,EAAE,CAAC;EAqBlD,cApBmB,IAAI,MAAM;EAqB7B;EACA,aArBkB,IAAI,EAAE;EAsBxB,2BAnBgB,IAAI,KAA2C;EAoB/D,8BAnBmB,IAAI,KAA8B;EAoBrD,6BAjBkB,IAAI,KAA8B;EAkBpD,gCAfqB,IAAI,KAA4C;EAgBrE,sCAf2B,IAAI,KAAqB;EAgB3C;EACV;;AC7GH,SAAS,iBACP,QACA,WACgB;CAChB,MAAM,YAAY,EAAE,GAAG,QAAQ;AAC/B,MAAK,MAAM,OAAO,OAAO,KAAK,UAAU,CACtC,KAAI,QAAQ,aAAa,IAAI,WAAW,GAAG,UAAU,GAAG,CACtD,QAAO,UAAU;AAGrB,QAAO;;AAMT,SAAS,kBACP,QACuD;CACvD,MAAM,0BAAU,IAAI,KAAuD;AAE3E,MAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,OAAO,MAAM,KAAK,KAAK,IAAI;EACjC,MAAM,WAAW,QAAQ,IAAI,KAAK,IAAI,EAAE;AACxC,WAAS,KAAK;GAAE,MAAM,MAAM;GAAM,SAAS,MAAM;GAAS,CAAC;AAC3D,UAAQ,IAAI,MAAM,SAAS;;AAG7B,QAAO;;AAQT,SAAS,iBAAiB,QAAuE;AAC/F,KAAI,OAAO,WAAW,EAEpB,QAAO,OAAO,GAAG;CAInB,MAAMC,QAA2C,EAAE;AACnD,MAAK,MAAM,OAAO,QAAQ;EACxB,MAAM,WAAW,MAAM,IAAI;AAC3B,MAAI,SAEF,OAAM,IAAI,QAAQ,MAAM,QAAQ,SAAS,GACrC,CAAC,GAAG,UAAU,IAAI,QAAQ,GAC1B,CAAC,UAAU,IAAI,QAAQ;MAE3B,OAAM,IAAI,QAAQ,IAAI;;AAI1B,QAAO;EACL,MAAM,OAAO,GAAG;EAChB,SAAS,OAAO,GAAG;EACnB;EACD;;AAMH,SAAgB,iBAA6B,KAA8B;CAIzE,eAAe,SAAS,WAAsC;EAE5D,MAAM,SAAS,MAAM,IAAI,QAAQ,OAAO,eAAe,IAAI,SAAS;AAEpE,MAAI,OAAO,SAAS;AAElB,OAAI,UACF,KAAI,OAAO,QAAQ,iBAAiB,IAAI,OAAO,OAAO,UAAU;OAEhE,KAAI,OAAO,QAAQ,EAAE;AAEvB,UAAO;;EAIT,MAAM,YAAY,OAAO,MAAM;AAE/B,MAAI,WAAW;GAEb,MAAM,cAAc,UAAU,QAAQ,UAAU;IAC9C,MAAM,OAAO,MAAM,KAAK,KAAK,IAAI;AACjC,WAAO,SAAS,aAAa,KAAK,WAAW,GAAG,UAAU,GAAG;KAC7D;AAEF,OAAI,YAAY,WAAW,GAAG;AAE5B,QAAI,OAAO,QAAQ,iBAAiB,IAAI,OAAO,OAAO,UAAU;AAChE,WAAO;;GAIT,IAAI,cAAY,iBAAiB,IAAI,OAAO,OAAO,UAAU;GAC7D,MAAM,YAAU,kBAAkB,YAAY;AAE9C,QAAK,MAAM,CAAC,MAAM,WAAW,UAC3B,KAAI,aAAW,MAAM,iBAAiB,OAAO,CAAC;AAGhD,OAAI,OAAO,QAAQ;AACnB,UAAO;;EAIT,MAAMC,YAAiD,EAAE;EACzD,MAAM,UAAU,kBAAkB,UAAU;AAE5C,OAAK,MAAM,CAAC,MAAM,WAAW,QAC3B,KAAI,WAAW,MAAM,iBAAiB,OAAO,CAAC;AAGhD,MAAI,OAAO,QAAQ;AACnB,SAAO;;AAGT,QAAO,EAAE,UAAU;;ACtHrB,SAAgB,wBACd,KACA,UACA;CAIA,SAAS,SACP,MACA,iBACgB;EAChB,MAAM,WAAW,IAA6B,KAAK;AACnD,MAAI,UAAU,IAAI,MAAM,SAAS;AAEjC,MAAI,gBACF,KAAI,aAAa,IAAI,MAAM,gBAAgB;AAI7C,MAAI,IAAI,IAAI,UAAU,KAAK,KAAK,KAAA,GAAW;GACzC,MAAM,eAAe,IAAI,IAAI,eAAe,KAAK;AACjD,OAAI,iBAAiB,KAAA,EACnB,KAAI,IAAI,UAAU,MAAM,aAAa;;EAOzC,MAAM,sBAAsB,OAAO,WAAmB,OAAgB,cAAsB;GAC1F,MAAM,YAAY,IAAI,aAAa,IAAI,UAAU;AACjD,OAAI,CAAC,WAAW,YAAY,UAAU,SACpC;GAGF,MAAM,QAAQ,MAAM,UAAU,SAAS,MAAM;AAI7C,OAAI,cADoB,IAAI,qBAAqB,IAAI,UAAU,CAE7D;AAGF,OAAI,MACF,KAAI,OAAO,QAAQ;IAAE,GAAG,IAAI,OAAO;KAAQ,YAAY;IAAO;QACzD;IAEL,MAAM,YAAY,EAAE,GAAG,IAAI,OAAO,OAAO;AACzC,WAAO,UAAU;AACjB,QAAI,OAAO,QAAQ;;;EAOvB,MAAM,UAAU,OAAO,MAAa;GAClC,MAAM,SAAS,EAAE;GACjB,MAAM,QAAQ,OAAO,SAAS,aAAa,OAAO,UAAU,OAAO;AAGnE,OAAI,IAAI,UAAU,MAAM,MAAM;AAG9B,OAAI,YAAY,QAAQ;IAAE,GAAG,IAAI,YAAY;KAAQ,OAAO;IAAM;AAGlE,OACE,IAAI,QAAQ,SAAS,cACpB,IAAI,QAAQ,SAAS,eAAe,IAAI,cAAc,MAAM,SAC5D,IAAI,cAAc,MAAM,SAAS,IAAI,QAAQ,mBAAmB,WAEjE,OAAM,SAAS,KAAK;GAItB,MAAM,YAAY,IAAI,aAAa,IAAI,KAAK;AAC5C,OAAI,WAAW,YAAY,CAAC,UAAU,UAAU;IAE9C,MAAM,YAAY,KAAK,KAAK,GAAG,KAAK,QAAQ;AAC5C,QAAI,qBAAqB,IAAI,MAAM,UAAU;IAE7C,MAAM,aAAa,UAAU,oBAAoB;AAEjD,QAAI,aAAa,GAAG;KAElB,MAAM,gBAAgB,IAAI,eAAe,IAAI,KAAK;AAClD,SAAI,cACF,cAAa,cAAc;KAI7B,MAAM,QAAQ,iBAAiB;AAC7B,UAAI,eAAe,OAAO,KAAK;AAC/B,0BAAoB,MAAM,OAAO,UAAU;QAC1C,WAAW;AAEd,SAAI,eAAe,IAAI,MAAM,MAAM;UAGnC,OAAM,oBAAoB,MAAM,OAAO,UAAU;;;EAQvD,MAAM,SAAS,OAAO,OAAc;AAElC,OAAI,cAAc,QAAQ;IAAE,GAAG,IAAI,cAAc;KAAQ,OAAO;IAAM;AAGtE,OACE,IAAI,QAAQ,SAAS,YACrB,IAAI,QAAQ,SAAS,eACpB,IAAI,YAAY,QAAQ,KAAK,IAAI,QAAQ,mBAAmB,SAE7D,OAAM,SAAS,KAAK;;EAOxB,MAAM,eAAe,OAAgB;GACnC,MAAM,aAAa,SAAS;AAC5B,YAAS,QAAQ;AAGjB,OAAI,MAAM,CAAC,iBAAiB,cAAc,cAAc,kBAAkB;IACxE,MAAM,QAAQ,IAAI,IAAI,UAAU,KAAK;AACrC,QAAI,UAAU,KAAA,EACZ,KAAI,GAAG,SAAS,WACd,IAAG,UAAU;QAEb,IAAG,QAAQ;;AAMjB,OAAI,cAAc,CAAC;QAEf,iBAAiB,oBAAoB,IAAI,QAAQ,oBAAoB,OAEtD;AAEf,WAAM,IAAI,UAAU,KAAK;KAGzB,MAAM,YAAY,EAAE,GAAG,IAAI,OAAO,OAAO;AACzC,YAAO,UAAU;AACjB,SAAI,OAAO,QAAQ;KAGnB,MAAM,aAAa,EAAE,GAAG,IAAI,cAAc,OAAO;AACjD,YAAO,WAAW;AAClB,SAAI,cAAc,QAAQ;KAE1B,MAAM,WAAW,EAAE,GAAG,IAAI,YAAY,OAAO;AAC7C,YAAO,SAAS;AAChB,SAAI,YAAY,QAAQ;AAGxB,SAAI,UAAU,OAAO,KAAK;AAC1B,SAAI,aAAa,OAAO,KAAK;KAG7B,MAAM,QAAQ,IAAI,eAAe,IAAI,KAAK;AAC1C,SAAI,OAAO;AACT,mBAAa,MAAM;AACnB,UAAI,eAAe,OAAO,KAAK;;AAEjC,SAAI,qBAAqB,OAAO,KAAK;;;;AAK3C,SAAO;GACL;GACA,KAAK;GACL;GACA;GACA,GAAI,iBAAiB,cAAc,EACjC,OAAO,SAAS;IACd,WAAW,IAAI,IAAI,UAAU,KAAK;IAClC,MAAM,QAAQ;AACZ,SAAI,IAAI,UAAU,MAAM,IAAI;AAC5B,SAAI,YAAY,QAAQ;MAAE,GAAG,IAAI,YAAY;OAAQ,OAAO;MAAM;;IAErE,CAAC,EACH;GACF;;CAMH,SAAS,WAA2C,MAAmB;AACrE,MAAI,UAAU,OAAO,KAAK;AAC1B,MAAI,aAAa,OAAO,KAAK;EAG7B,MAAM,QAAQ,IAAI,eAAe,IAAI,KAAK;AAC1C,MAAI,OAAO;AACT,gBAAa,MAAM;AACnB,OAAI,eAAe,OAAO,KAAK;;AAEjC,MAAI,qBAAqB,OAAO,KAAK;;AAGvC,QAAO;EAAE;EAAU;EAAY;;ACzNjC,SAAgB,wBACd,KACA,UACA;CAIA,SAAS,OAAuC,MAAyB;EAEvE,IAAI,aAAa,IAAI,YAAY,IAAI,KAAK;AAE1C,MAAI,CAAC,YAAY;GACf,MAAM,iBAAkB,IAAI,IAAI,UAAU,KAAK,IAAI,EAAE;AACrD,gBAAa;IACX,OAAO,IAAsB,EAAE,CAAC;IAChC,QAAQ;IACT;AACD,OAAI,YAAY,IAAI,MAAM,WAAW;AAGrC,OAAI,CAAC,IAAI,IAAI,UAAU,KAAK,CAC1B,KAAI,IAAI,UAAU,MAAM,EAAE,CAAc;;EAK5C,MAAM,KAAK;EAMX,MAAM,cAAc,SAAiC;GACnD;GACA,IAAI,QAAQ;AACV,WAAO,GAAG,MAAM,MAAM,WAAW,SAAS,KAAK,QAAQ,IAAI;;GAE7D,SAAS;IACP,MAAM,eAAe,GAAG,MAAM,MAAM,WAAW,SAAS,KAAK,QAAQ,IAAI;AACzE,QAAI,iBAAiB,GACnB,UAAS,aAAa;;GAG3B;AAGD,MAAI,GAAG,MAAM,MAAM,WAAW,KAAK,GAAG,OAAO,SAAS,EACpD,IAAG,MAAM,QAAQ,GAAG,OAAO,UAAU,WAAW,YAAY,CAAC,CAAC;EAGhE,MAAM,UAAU,UAAmB;GAEjC,MAAM,YAAY,CAAC,GADI,IAAI,IAAI,UAAU,KAAK,IAAI,EAAE,EACf,MAAM;AAC3C,OAAI,IAAI,UAAU,MAAM,UAAU;AAElC,MAAG,MAAM,QAAQ,CAAC,GAAG,GAAG,MAAM,OAAO,WAAW,YAAY,CAAC,CAAC;AAE9D,OAAI,YAAY,QAAQ;IAAE,GAAG,IAAI,YAAY;KAAQ,OAAO;IAAM;AAElE,OAAI,IAAI,QAAQ,SAAS,WACvB,UAAS,KAAK;;EAIlB,MAAM,WAAW,UAAmB;AAClC,UAAO,GAAG,MAAM;;EAGlB,MAAM,UAAU,OAAe,UAAmB;GAChD,MAAM,gBAAiB,IAAI,IAAI,UAAU,KAAK,IAAI,EAAE;AACpD,OAAI,QAAQ,KAAK,SAAS,cAAc,OACtC;GAEF,MAAM,YAAY,CAAC,GAAG,cAAc;AACpC,aAAU,SAAS;AACnB,OAAI,IAAI,UAAU,MAAM,UAAU;AAGlC,OAAI,YAAY,QAAQ;IAAE,GAAG,IAAI,YAAY;KAAQ,OAAO;IAAM;AAElE,OAAI,IAAI,QAAQ,SAAS,WACvB,UAAS,KAAK;;EAIlB,MAAM,YAAY,UAAkB;GAElC,MAAM,aADiB,IAAI,IAAI,UAAU,KAAK,IAAI,EAAE,EACpB,QAAQ,GAAY,MAAc,MAAM,MAAM;AAC9E,OAAI,IAAI,UAAU,MAAM,UAAU;GAGlC,MAAM,cAAc,GAAG,MAAM,MAAM,QAAQ;AAC3C,MAAG,MAAM,QAAQ,GAAG,MAAM,MAAM,QAAQ,SAAS,KAAK,QAAQ,YAAY;AAE1E,OAAI,YAAY,QAAQ;IAAE,GAAG,IAAI,YAAY;KAAQ,OAAO;IAAM;AAElE,OAAI,IAAI,QAAQ,SAAS,WACvB,UAAS,KAAK;;EAIlB,MAAM,UAAU,OAAe,UAAmB;GAChD,MAAM,gBAAiB,IAAI,IAAI,UAAU,KAAK,IAAI,EAAE;GACpD,MAAM,YAAY;IAAC,GAAG,cAAc,MAAM,GAAG,MAAM;IAAE;IAAO,GAAG,cAAc,MAAM,MAAM;IAAC;AAC1F,OAAI,IAAI,UAAU,MAAM,UAAU;GAElC,MAAM,UAAU,WAAW,YAAY,CAAC;AACxC,MAAG,MAAM,QAAQ;IAAC,GAAG,GAAG,MAAM,MAAM,MAAM,GAAG,MAAM;IAAE;IAAS,GAAG,GAAG,MAAM,MAAM,MAAM,MAAM;IAAC;AAE7F,OAAI,YAAY,QAAQ;IAAE,GAAG,IAAI,YAAY;KAAQ,OAAO;IAAM;AAElE,OAAI,IAAI,QAAQ,SAAS,WACvB,UAAS,KAAK;;EAIlB,MAAM,QAAQ,QAAgB,WAAmB;GAE/C,MAAM,YAAY,CAAC,GADI,IAAI,IAAI,UAAU,KAAK,IAAI,EAAE,CAChB;AACnC,IAAC,UAAU,SAAS,UAAU,WAAW,CAAC,UAAU,SAAS,UAAU,QAAQ;AAChF,OAAI,IAAI,UAAU,MAAM,UAAU;GAGlC,MAAM,WAAW,CAAC,GAAG,GAAG,MAAM,MAAM;GACpC,MAAM,QAAQ,SAAS;GACvB,MAAM,QAAQ,SAAS;AACvB,OAAI,SAAS,OAAO;AAClB,aAAS,UAAU;AACnB,aAAS,UAAU;AACnB,OAAG,MAAM,QAAQ;;AAGnB,OAAI,YAAY,QAAQ;IAAE,GAAG,IAAI,YAAY;KAAQ,OAAO;IAAM;AAElE,OAAI,IAAI,QAAQ,SAAS,WACvB,UAAS,KAAK;;EAIlB,MAAM,QAAQ,MAAc,OAAe;GAEzC,MAAM,YAAY,CAAC,GADI,IAAI,IAAI,UAAU,KAAK,IAAI,EAAE,CAChB;GACpC,MAAM,CAAC,WAAW,UAAU,OAAO,MAAM,EAAE;AAC3C,OAAI,YAAY,KAAA,GAAW;AACzB,cAAU,OAAO,IAAI,GAAG,QAAQ;AAChC,QAAI,IAAI,UAAU,MAAM,UAAU;;GAIpC,MAAM,WAAW,CAAC,GAAG,GAAG,MAAM,MAAM;GACpC,MAAM,CAAC,eAAe,SAAS,OAAO,MAAM,EAAE;AAC9C,OAAI,aAAa;AACf,aAAS,OAAO,IAAI,GAAG,YAAY;AACnC,OAAG,MAAM,QAAQ;;AAGnB,OAAI,YAAY,QAAQ;IAAE,GAAG,IAAI,YAAY;KAAQ,OAAO;IAAM;AAElE,OAAI,IAAI,QAAQ,SAAS,WACvB,UAAS,KAAK;;AAIlB,SAAO;GACL,OAAO,GAAG,MAAM;GAChB;GACA;GACA,QAAQ;GACR;GACA;GACA;GACA;GACD;;AAGH,QAAO,EAAE,QAAQ;;ACjJnB,SAAgB,QACd,SACwB;CAIxB,MAAM,MAAM,kBAAkB,QAAQ;CAGtC,MAAM,EAAE,aAAa,iBAA6B,IAAI;CAGtD,MAAM,EAAE,UAAU,eAAe,wBAAoC,KAAK,SAAS;CAGnF,MAAM,EAAE,WAAW,wBAAoC,KAAK,SAAS;CAKrE,MAAM,YAAY,gBAAuC;EACvD,QAAQ,IAAI,OAAO;EACnB,SAAS,OAAO,KAAK,IAAI,YAAY,MAAM,CAAC,MAAM,MAAM,IAAI,YAAY,MAAM,GAAG;EACjF,aAAa,IAAI,YAAY;EAC7B,UACG,IAAI,YAAY,QAAQ,KAAK,OAAO,KAAK,IAAI,cAAc,MAAM,CAAC,SAAS,MAC5E,OAAO,KAAK,IAAI,OAAO,MAAM,CAAC,WAAW;EAC3C,cAAc,IAAI,aAAa;EAC/B,WAAW,IAAI,UAAU;EACzB,eAAe,IAAI,cAAc;EACjC,aAAa,IAAI,YAAY;EAC9B,EAAE;CAKH,SAAS,aACP,SACA,WACA;AACA,SAAO,OAAO,MAAa;AACzB,KAAE,gBAAgB;AAElB,OAAI,aAAa,QAAQ;AACzB,OAAI,YAAY;AAEhB,OAAI;AAEF,SAAK,MAAM,CAAC,MAAM,aAAa,IAAI,UAAU,SAAS,EAAE;KACtD,MAAM,KAAK,SAAS;AACpB,SAAI;UAEE,CADS,IAAI,aAAa,IAAI,KAAK,EAC5B,YAAY;OACrB,MAAM,QAAQ,GAAG,SAAS,aAAa,GAAG,UAAU,GAAG;AACvD,WAAI,IAAI,UAAU,MAAM,MAAM;;;;AAQpC,QAFgB,MAAM,UAAU,CAI9B,OAAM,QAAQ,IAAI,SAAuB;QAGzC,aAAY,IAAI,OAAO,MAAM;aAEvB;AACR,QAAI,aAAa,QAAQ;;;;CAQ/B,SAAS,SACP,MACA,OACM;AACN,MAAI,IAAI,UAAU,MAAM,MAAM;AAC9B,MAAI,YAAY,QAAQ;GAAE,GAAG,IAAI,YAAY;IAAQ,OAAO;GAAM;EAGlE,MAAM,WAAW,IAAI,UAAU,IAAI,KAAK;AACxC,MAAI,UAAU,OAAO;GACnB,MAAM,KAAK,SAAS;AACpB,OAAI,GAAG,SAAS,WACd,IAAG,UAAU;OAEb,IAAG,QAAQ;;AAKf,MAAI,QAAQ,SAAS,cAAc,IAAI,cAAc,MAAM,MACzD,UAAS,KAAK;;CAOlB,SAAS,SACP,MAC0C;AAC1C,SAAO,IAAI,IAAI,UAAU,KAAK;;CAMhC,SAAS,MAAM,QAA8B,cAAmC;EAC9E,MAAM,OAAO,gBAAgB,EAAE;AAG/B,MAAI,CAAC,KAAK,qBAAqB,OAC7B,QAAO,OAAO,IAAI,eAAe,OAAO;AAI1C,SAAO,KAAK,IAAI,SAAS,CAAC,SAAS,QAAQ,OAAO,IAAI,SAAS,KAAK;EAGpE,MAAM,YAAY,UAAU,IAAI;AAChC,SAAO,OAAO,IAAI,UAAU,UAAU;AAGtC,MAAI,CAAC,KAAK,WACR,KAAI,OAAO,QAAQ,EAAE;AAEvB,MAAI,CAAC,KAAK,YACR,KAAI,cAAc,QAAQ,EAAE;AAE9B,MAAI,CAAC,KAAK,UACR,KAAI,YAAY,QAAQ,EAAE;AAE5B,MAAI,CAAC,KAAK,gBACR,KAAI,YAAY,QAAQ;AAE1B,MAAI,CAAC,KAAK,iBACR,KAAI,aAAa,QAAQ;AAI3B,MAAI,YAAY,OAAO;AAGvB,OAAK,MAAM,CAAC,MAAM,aAAa,IAAI,UAAU,SAAS,EAAE;GACtD,MAAM,KAAK,SAAS;AACpB,OAAI,IAAI;IACN,MAAM,QAAQ,IAAI,WAAsC,KAAK;AAC7D,QAAI,UAAU,KAAA,EACZ,KAAI,GAAG,SAAS,WACd,IAAG,UAAU;QAEb,IAAG,QAAQ;;;;CAUrB,SAAS,MAAsC,MAAwB;AACrE,SAAO,eAAe;AACpB,OAAI,CAAC,KACH,QAAO,IAAI;AAEb,OAAI,MAAM,QAAQ,KAAK,CACrB,QAAO,KAAK,QACT,KAAK,MAAM;AACV,QAAI,KAAK,IAAI,IAAI,UAAU,EAAE;AAC7B,WAAO;MAET,EAAE,CACH;AAEH,UAAO,IAAI,IAAI,UAAU,KAAK;IAC9B;;CAUJ,SAAS,YAA4C,MAA8B;AACjF,MAAI,SAAS,KAAA,GAAW;AAEtB,OAAI,OAAO,QAAQ,EAAE;AACrB;;EAGF,MAAM,gBAAgB,MAAM,QAAQ,KAAK,GAAG,OAAO,CAAC,KAAK;EACzD,MAAM,YAAY,EAAE,GAAG,IAAI,OAAO,OAAO;AAEzC,OAAK,MAAM,SAAS,cAElB,MAAK,MAAM,OAAO,OAAO,KAAK,UAAU,CACtC,KAAI,QAAQ,SAAS,IAAI,WAAW,GAAG,MAAM,GAAG,CAC9C,QAAO,UAAU;AAKvB,MAAI,OAAO,QAAQ;;CAOrB,SAAS,SACP,MACA,OACM;EACN,MAAM,YAAY,EAAE,GAAG,IAAI,OAAO,OAAO;AAOzC,MAAI,WAAW,MAJI,MAAM,OACrB;GAAE,MAAM,MAAM;GAAM,SAAS,MAAM;GAAS,GAC5C,MAAM,QAEsB;AAChC,MAAI,OAAO,QAAQ;;CASrB,SAAS,UACP,aACiE;AAEjE,OAAK,MAAM,CAAC,MAAM,aAAa,IAAI,UAAU,SAAS,EAAE;GACtD,MAAM,KAAK,SAAS;AACpB,OAAI;QAEE,CADS,IAAI,aAAa,IAAI,KAAK,EAC5B,YAAY;KACrB,MAAM,QAAQ,GAAG,SAAS,aAAa,GAAG,UAAU,GAAG;AACvD,SAAI,IAAI,UAAU,MAAM,MAAM;;;;AAKpC,MAAI,gBAAgB,KAAA,EAElB,QAAO,EAAE,GAAG,IAAI,UAAU;AAG5B,MAAI,MAAM,QAAQ,YAAY,EAAE;GAE9B,MAAMC,SAAkC,EAAE;AAC1C,QAAK,MAAM,aAAa,YACtB,QAAO,aAAa,IAAI,IAAI,UAAU,UAAU;AAElD,UAAO;;AAIT,SAAO,IAAI,IAAI,UAAU,YAAY;;CAMvC,SAAS,cAA8C,MAAyB;EAC9E,MAAM,QAAQ,IAAI,IAAI,OAAO,OAAO,KAAK;AACzC,SAAO;GACL,SAAS,IAAI,YAAY,MAAM,UAAU;GACzC,WAAW,IAAI,cAAc,MAAM,UAAU;GAC7C,SAAS,UAAU,KAAA,KAAa,UAAU;GAC1C;GACD;;CAMH,eAAe,QACb,MACkB;AAClB,MAAI,SAAS,KAAA,EAEX,QAAO,MAAM,UAAU;AAGzB,MAAI,MAAM,QAAQ,KAAK,EAAE;GAEvB,IAAI,WAAW;AACf,QAAK,MAAM,aAAa,KAEtB,KAAI,CADY,MAAM,SAAS,UAAU,CAEvC,YAAW;AAGf,UAAO;;AAIT,SAAO,MAAM,SAAS,KAAK;;CAM7B,SAAS,SACP,MACA,cACM;EACN,MAAM,WAAW,IAAI,UAAU,IAAI,KAAK;AAExC,MAAI,CAAC,UAAU,MACb;EAGF,MAAM,KAAK,SAAS;AAGpB,MAAI,OAAO,GAAG,UAAU,YAAY;AAClC,MAAG,OAAO;AAGV,OACE,cAAc,gBACd,cAAc,oBACd,OAAO,GAAG,WAAW,WAErB,IAAG,QAAQ;;;AAKjB,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;;ACvYH,MAAaC,iBAAuD,OAAO,cAAc;AAgBzF,SAAgB,YAAqC,SAAuC;AAC1F,SAAQ,gBAAgB,QAA6C;;AAiBvE,SAAgB,iBAAkE;CAChF,MAAM,UAAU,OAAO,eAAe;AAEtC,KAAI,CAAC,QACH,OAAM,IAAI,MACR,qKAED;AAGH,QAAO;;ACRT,SAAgB,SAGd,UAA2C,EAAE,EAAwB;CACrE,MAAM,EAAE,SAAS,MAAM,iBAAiB;CAGxC,MAAM,OAAO,WAAW,gBAAyB;AAEjD,QAAO,eAAe;AACpB,MAAI,SAAS,KAAA,EAEX,QAAO,KAAK,WAAW;AAGzB,MAAI,MAAM,QAAQ,KAAK,EAAE;GAEvB,MAAMC,SAAkC,EAAE;AAC1C,QAAK,MAAM,aAAa,KAEtB,QAAO,aADO,IAAI,KAAK,WAAW,EAAE,UAAU,IACjB;AAE/B,UAAO;;AAKT,SADc,IAAI,KAAK,WAAW,EAAE,KAAK,IACzB;GAChB;;ACAJ,SAAgB,cAId,SAC6D;CAG7D,MAAM,EAAE,MAAM,SAAS,iBAAiB;CAGxC,MAAM,OAAO,WAAW,gBAAyB;CAGjD,MAAM,aAAa,IAAwB,KAAK;AAGhD,KAAI,iBAAiB,KAAA,KAAa,KAAK,SAAS,KAAK,KAAK,KAAA,EACxD,MAAK,SAAS,MAAM,aAAa;CAInC,MAAM,QAAQ,SAAS;EACrB,WAAW;AAET,UADqB,KAAK,SAAS,KAAK,IAChB;;EAE1B,MAAM,aAAqB;AACzB,QAAK,SAAS,MAAM,SAAS;;EAEhC,CAAC;CAGF,MAAM,YAAY,aAAqB;AACrC,OAAK,SAAS,MAAM,SAAS;;CAI/B,MAAM,eAAe;AACnB,OAAK,QAAQ,KAAK;;CAIpB,MAAM,eAAe,OAA2B;AAC9C,aAAW,QAAQ;;CAIrB,MAAM,aAAa,eAA2B;AAC5C,SAAO,KAAK,cAAc,KAAK;GAC/B;AAEF,QAAO;EACL,OAAO;GACE;GACP;GACA;GACA;GACA,KAAK;GACN;EACD;EACD;;AC1FH,SAAgB,aACd,UAAwC,EAAE,EACa;CACvD,MAAM,EAAE,SAAS,SAAS;CAG1B,MAAM,OAAO,WAAW,gBAAyB;AAEjD,QAAO,eAAe;EACpB,MAAM,YAAY,KAAK,UAAU;AAEjC,MAAI,SAAS,KAAA,EAEX,QAAO,EAAE,GAAG,WAAW;AAGzB,MAAI,MAAM,QAAQ,KAAK,EAAE;GAEvB,MAAMC,SAAmD,EAAE;AAC3D,QAAK,MAAM,OAAO,KACd,QAAmC,OAAO,UAAU;AAExD,UAAO;;AAIT,SAAO,GAAG,OAAO,UAAU,OAAO;GAClC"}
|