@volverjs/form-vue 0.0.10-beta.6 → 0.0.10-beta.8
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 +246 -169
- package/dist/VvForm.d.ts +22 -6
- package/dist/VvFormField.d.ts +13 -4
- package/dist/index.d.ts +76 -17
- package/dist/index.es.js +235 -216
- package/dist/index.umd.js +1 -1
- package/dist/types.d.ts +10 -4
- package/package.json +11 -11
- package/src/VvForm.ts +15 -7
- package/src/VvFormField.ts +8 -5
- package/src/VvFormTemplate.ts +27 -9
- package/src/index.ts +27 -7
- package/src/types.d.ts +10 -4
package/README.md
CHANGED
|
@@ -33,11 +33,11 @@ npm install @volverjs/form-vue --save
|
|
|
33
33
|
|
|
34
34
|
## Usage
|
|
35
35
|
|
|
36
|
-
`@volverjs/form-vue` allow you to create a Vue 3 form with [`@volverjs/ui-vue`](https://github.com/volverjs/ui-vue) components from a [Zod Object](https://zod.dev/?id=objects) schema. It provides
|
|
36
|
+
`@volverjs/form-vue` allow you to create a Vue 3 form with [`@volverjs/ui-vue`](https://github.com/volverjs/ui-vue) components from a [Zod Object](https://zod.dev/?id=objects) schema. It provides two functions: `createForm()` and `useForm()`.
|
|
37
37
|
|
|
38
38
|
## Plugin
|
|
39
39
|
|
|
40
|
-
`createForm` defines globally three components `VvForm`, `VvFormWrapper`, and `VvFormField` through a [Vue 3 Plugin](https://vuejs.org/guide/reusability/plugins.html).
|
|
40
|
+
`createForm()` defines globally three components `VvForm`, `VvFormWrapper`, and `VvFormField` through a [Vue 3 Plugin](https://vuejs.org/guide/reusability/plugins.html).
|
|
41
41
|
|
|
42
42
|
```typescript
|
|
43
43
|
import { createApp } from 'vue'
|
|
@@ -45,8 +45,8 @@ import { createForm } from '@volverjs/form-vue'
|
|
|
45
45
|
import { z } from 'zod'
|
|
46
46
|
|
|
47
47
|
const schema = z.object({
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
firstName: z.string(),
|
|
49
|
+
lastName: z.string()
|
|
50
50
|
})
|
|
51
51
|
|
|
52
52
|
const app = createApp(App)
|
|
@@ -62,7 +62,7 @@ app.use(form)
|
|
|
62
62
|
app.mount('#app')
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
If the schema is omitted, the plugin only share the options to the forms created with the [composable](https://github.com/volverjs/form-vue/#composable).
|
|
66
66
|
|
|
67
67
|
### VvForm
|
|
68
68
|
|
|
@@ -72,16 +72,16 @@ A `valid` or `invalid` event is emitted when the form status changes.
|
|
|
72
72
|
```vue
|
|
73
73
|
<script lang="ts" setup>
|
|
74
74
|
const onSubmit = (formData) => {
|
|
75
|
-
//
|
|
75
|
+
// ...
|
|
76
76
|
}
|
|
77
77
|
const onInvalid = (errors) => {
|
|
78
|
-
//
|
|
78
|
+
// ...
|
|
79
79
|
}
|
|
80
80
|
</script>
|
|
81
81
|
|
|
82
82
|
<template>
|
|
83
83
|
<VvForm @submit="onSubmit" @invalid="onInvalid">
|
|
84
|
-
<!--
|
|
84
|
+
<!-- ... -->
|
|
85
85
|
<button type="submit">Submit</button>
|
|
86
86
|
</VvForm>
|
|
87
87
|
</template>
|
|
@@ -96,7 +96,7 @@ The submit can be triggered programmatically with the `submit()` method.
|
|
|
96
96
|
|
|
97
97
|
const formEl = ref<InstanceType<FormComponent>>(null)
|
|
98
98
|
const onSubmit = (formData) => {
|
|
99
|
-
//
|
|
99
|
+
// ...
|
|
100
100
|
}
|
|
101
101
|
const submitForm = () => {
|
|
102
102
|
formEl.value.submit()
|
|
@@ -105,58 +105,103 @@ The submit can be triggered programmatically with the `submit()` method.
|
|
|
105
105
|
|
|
106
106
|
<template>
|
|
107
107
|
<VvForm @submit="onSubmit" ref="formEl">
|
|
108
|
-
<!--
|
|
108
|
+
<!-- ... -->
|
|
109
109
|
</VvForm>
|
|
110
110
|
<button type="button" @click.stop="submitForm">Submit</button>
|
|
111
111
|
</template>
|
|
112
112
|
```
|
|
113
113
|
|
|
114
|
-
Use the `v-model` directive (or only `:model-value` to set the initial value of form data)
|
|
115
|
-
|
|
116
|
-
The throttle can be changed with the `updateThrottle` option.
|
|
114
|
+
Use the `v-model` directive (or only `:model-value` to set the initial value of form data) or bind the form data.
|
|
115
|
+
|
|
116
|
+
The form data two way binding is **throttled** by default (500ms) to avoid performance issues. The throttle can be changed with the `updateThrottle` option or prop.
|
|
117
|
+
|
|
118
|
+
By default form validation **stops** when a **valid state** is reached.
|
|
119
|
+
To activate **continuos validation** use the `continuosValidation` option or prop.
|
|
117
120
|
|
|
118
121
|
```vue
|
|
119
122
|
<script lang="ts" setup>
|
|
120
123
|
import { ref } from 'vue'
|
|
121
124
|
|
|
122
125
|
const formData = ref({
|
|
123
|
-
|
|
124
|
-
|
|
126
|
+
firstName: '',
|
|
127
|
+
lastName: ''
|
|
125
128
|
})
|
|
126
129
|
</script>
|
|
127
130
|
|
|
128
131
|
<template>
|
|
129
|
-
<VvForm v-model="formData">
|
|
130
|
-
<!--
|
|
132
|
+
<VvForm v-model="formData" :update-throttle="1000" continuos-validation>
|
|
133
|
+
<!-- ... -->
|
|
131
134
|
</VvForm>
|
|
132
135
|
</template>
|
|
133
136
|
```
|
|
134
137
|
|
|
135
|
-
|
|
136
|
-
|
|
138
|
+
## Composable
|
|
139
|
+
|
|
140
|
+
`useForm()` can be used to create a form programmatically inside a Vue 3 Component.
|
|
141
|
+
The **default settings** are **inherited** from the plugin (if it's installed).
|
|
137
142
|
|
|
138
143
|
```vue
|
|
139
144
|
<script lang="ts" setup>
|
|
140
|
-
import {
|
|
145
|
+
import { useForm } from '@volverjs/form-vue'
|
|
146
|
+
import { z } from 'zod'
|
|
141
147
|
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
148
|
+
const schema = z.object({
|
|
149
|
+
firstName: z.string(),
|
|
150
|
+
lastName: z.string()
|
|
145
151
|
})
|
|
146
152
|
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
153
|
+
const { VvForm, VvFormWrapper, VvFormField } = useForm(schema, {
|
|
154
|
+
// lazyLoad: boolean - default false
|
|
155
|
+
// updateThrottle: number - default 500
|
|
156
|
+
// continuosValidation: boolean - default false
|
|
157
|
+
// sideEffects?: (formData: any) => void
|
|
150
158
|
})
|
|
151
159
|
</script>
|
|
152
160
|
|
|
153
161
|
<template>
|
|
154
|
-
<VvForm
|
|
155
|
-
|
|
162
|
+
<VvForm>
|
|
163
|
+
<VvFormField type="text" name="firstName" label="First Name" />
|
|
164
|
+
<VvFormField type="text" name="lastName" label="Last Name" />
|
|
156
165
|
</VvForm>
|
|
157
166
|
</template>
|
|
158
167
|
```
|
|
159
168
|
|
|
169
|
+
### Outside a Vue 3 Component
|
|
170
|
+
|
|
171
|
+
`useForm()` can create a form also outside a Vue 3 Component, plugin settings are **not inherited**.
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
import { formFactory } from '@volverjs/form-vue'
|
|
175
|
+
import { z } from 'zod'
|
|
176
|
+
|
|
177
|
+
const schema = z.object({
|
|
178
|
+
name: z.string(),
|
|
179
|
+
surname: z.string()
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
const {
|
|
183
|
+
VvForm,
|
|
184
|
+
VvFormWrapper,
|
|
185
|
+
VvFormField,
|
|
186
|
+
VvFormTemplate,
|
|
187
|
+
formData,
|
|
188
|
+
status,
|
|
189
|
+
errors
|
|
190
|
+
} = formFactory(schema, {
|
|
191
|
+
lazyLoad: true
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
export default {
|
|
195
|
+
VvForm,
|
|
196
|
+
VvFormWrapper,
|
|
197
|
+
VvFormField,
|
|
198
|
+
VvFormTemplate,
|
|
199
|
+
formData,
|
|
200
|
+
status,
|
|
201
|
+
errors
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
160
205
|
### VvFormWrapper
|
|
161
206
|
|
|
162
207
|
`VvFormWrapper` gives you the validation status of a part of your form.
|
|
@@ -181,7 +226,7 @@ The wrapper status is invalid if at least one of the fields inside it is invalid
|
|
|
181
226
|
</template>
|
|
182
227
|
```
|
|
183
228
|
|
|
184
|
-
`VvFormWrapper` can be used recursively to create a validation tree. The wrapper status is invalid if at least one of the fields inside it or one of its children is invalid
|
|
229
|
+
`VvFormWrapper` can be used recursively to create a validation tree. The wrapper status is invalid if **at least one of the fields** inside it or one of its children **is invalid**.
|
|
185
230
|
|
|
186
231
|
```vue
|
|
187
232
|
<template>
|
|
@@ -204,57 +249,28 @@ The wrapper status is invalid if at least one of the fields inside it is invalid
|
|
|
204
249
|
|
|
205
250
|
### VvFormField
|
|
206
251
|
|
|
207
|
-
`VvFormField` allow you to render a [`@volverjs/ui-vue`](https://github.com/volverjs/ui-vue) input component inside a form.
|
|
208
|
-
|
|
209
|
-
```vue
|
|
210
|
-
<template>
|
|
211
|
-
<VvForm>
|
|
212
|
-
<VvFormField type="text" name="name" label="Name" />
|
|
213
|
-
<VvFormField type="text" name="surname" label="Surname" />
|
|
214
|
-
</VvForm>
|
|
215
|
-
</template>
|
|
216
|
-
```
|
|
252
|
+
`VvFormField` allow you to render a form field or a [`@volverjs/ui-vue`](https://github.com/volverjs/ui-vue) input component inside a form.
|
|
217
253
|
|
|
218
|
-
For nested objects, use the `name` attribute with dot notation
|
|
219
|
-
|
|
220
|
-
```vue
|
|
221
|
-
<template>
|
|
222
|
-
<VvForm>
|
|
223
|
-
<VvFormField type="text" name="shipping.address" label="Shipping address" />
|
|
224
|
-
</VvForm>
|
|
225
|
-
</template>
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
The type of input component is defined by the `type` attribute.
|
|
229
|
-
All the available input types are listed in the [VvFormField documentation](/docs/VvFormField.md).
|
|
230
|
-
|
|
231
|
-
You can also use the `VvFormField` component to render a default slot without a `type` (default `type` is `custom`).
|
|
254
|
+
It automatically bind the form data through the `name` attribute. For nested objects, use the `name` attribute with **dot notation**.
|
|
232
255
|
|
|
233
256
|
```vue
|
|
234
257
|
<template>
|
|
235
258
|
<VvForm>
|
|
236
259
|
<VvFormField
|
|
237
|
-
v-slot="{
|
|
238
|
-
|
|
239
|
-
invalid,
|
|
240
|
-
invalidLabel,
|
|
241
|
-
formData,
|
|
242
|
-
formErrors,
|
|
243
|
-
errors,
|
|
244
|
-
onUpdate
|
|
245
|
-
}"
|
|
246
|
-
name="surname"
|
|
260
|
+
v-slot="{ modelValue, invalid, invalidLabel, onUpdate }"
|
|
261
|
+
name="lastName"
|
|
247
262
|
>
|
|
248
|
-
<label for="
|
|
263
|
+
<label for="lastName">Last Name</label>
|
|
249
264
|
<input
|
|
250
|
-
id="
|
|
265
|
+
id="lastName"
|
|
251
266
|
type="text"
|
|
267
|
+
name="lastName"
|
|
252
268
|
:value="modelValue"
|
|
253
269
|
:aria-invalid="invalid"
|
|
254
|
-
:aria-errormessage="invalid ? '
|
|
270
|
+
:aria-errormessage="invalid ? 'last-name-alert' : undefined"
|
|
255
271
|
@input="onUpdate"
|
|
256
272
|
/>
|
|
257
|
-
<small v-if="invalid" role="alert" id="
|
|
273
|
+
<small v-if="invalid" role="alert" id="last-name-alert">
|
|
258
274
|
{{ invalidLabel }}
|
|
259
275
|
</small>
|
|
260
276
|
</VvFormField>
|
|
@@ -262,104 +278,107 @@ You can also use the `VvFormField` component to render a default slot without a
|
|
|
262
278
|
</template>
|
|
263
279
|
```
|
|
264
280
|
|
|
265
|
-
|
|
281
|
+
To render a [`@volverjs/ui-vue`](https://github.com/volverjs/ui-vue) input component, use the `type` attribute.
|
|
266
282
|
|
|
267
|
-
|
|
268
|
-
<script lang="ts" setup>
|
|
269
|
-
import MyInput from './MyInput.vue'
|
|
270
|
-
</script>
|
|
283
|
+
By default [`@volverjs/ui-vue`](https://github.com/volverjs/ui-vue) components must be defined globally but can be lazy loaded with `lazyLoad` option or prop.
|
|
271
284
|
|
|
285
|
+
```vue
|
|
272
286
|
<template>
|
|
273
287
|
<VvForm>
|
|
274
|
-
<VvFormField name="
|
|
288
|
+
<VvFormField type="text" name="username" label="Username" />
|
|
289
|
+
<VvFormField type="password" name="password" label="Password" />
|
|
275
290
|
</VvForm>
|
|
276
291
|
</template>
|
|
277
292
|
```
|
|
278
293
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
In some use cases can be usefull nest `VvFormField`.
|
|
282
|
-
For example let's assume:
|
|
294
|
+
Check the [`VvFormField`](./docs/VvFormField.md) documentation to learn more about form fields.
|
|
283
295
|
|
|
284
|
-
|
|
285
|
-
- the sum of all products of the shopping list cannot be 0
|
|
286
|
-
- we don't know all the products a priori
|
|
296
|
+
## Form Template
|
|
287
297
|
|
|
288
|
-
|
|
298
|
+
Forms can also be created using a template. A template is an **array of objects** that describes the form fields. All properties that are **not listed** below are passed to the component **as props**.
|
|
289
299
|
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
milk: 0,
|
|
295
|
-
tomato: 0,
|
|
296
|
-
potato: 0,
|
|
297
|
-
...
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
```
|
|
301
|
-
|
|
302
|
-
Our Zod schema can be:
|
|
300
|
+
```vue
|
|
301
|
+
<script lang="ts" setup>
|
|
302
|
+
import { useForm } from '@volverjs/form-vue'
|
|
303
|
+
import { z } from 'zod'
|
|
303
304
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
.object({
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
Object.keys(value).length &&
|
|
313
|
-
!Object.keys(value).find((key) => shoppingList[key] > 0)
|
|
314
|
-
) {
|
|
315
|
-
ctx.addIssue({
|
|
316
|
-
code: z.ZodIssueCode.custom,
|
|
317
|
-
message: i18n.global.t('atLeastOneProduct')
|
|
318
|
-
})
|
|
319
|
-
}
|
|
305
|
+
const schema = z.object({
|
|
306
|
+
firstName: z.string(),
|
|
307
|
+
lastName: z.string(),
|
|
308
|
+
address: z.object({
|
|
309
|
+
street: z.string(),
|
|
310
|
+
number: z.string(),
|
|
311
|
+
city: z.string(),
|
|
312
|
+
zip: z.string()
|
|
320
313
|
})
|
|
321
|
-
})
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
And the Vue component:
|
|
325
|
-
|
|
326
|
-
```vue
|
|
327
|
-
<script setup lang="ts">
|
|
328
|
-
const { VvForm, VvFormField } = useForm(toDoSchema, {
|
|
329
|
-
lazyLoad: true,
|
|
330
|
-
continuosValidation: true
|
|
331
314
|
})
|
|
332
315
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
316
|
+
const templateSchema = [
|
|
317
|
+
{
|
|
318
|
+
vvName: 'firstName',
|
|
319
|
+
vvType: 'text',
|
|
320
|
+
label: 'First Name'
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
vvName: 'lastName',
|
|
324
|
+
vvType: 'text',
|
|
325
|
+
label: 'Last Name'
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
vvIs: 'div',
|
|
329
|
+
class: 'grid grid-col-3 gap-4',
|
|
330
|
+
vvChildren: [
|
|
331
|
+
{
|
|
332
|
+
vvName: 'address.street',
|
|
333
|
+
vvType: 'text',
|
|
334
|
+
label: 'Street',
|
|
335
|
+
class: 'col-span-2'
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
vvName: 'address.number',
|
|
339
|
+
vvType: 'text',
|
|
340
|
+
label: 'Number'
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
vvName: 'address.city',
|
|
344
|
+
vvType: 'text',
|
|
345
|
+
label: 'City'
|
|
346
|
+
class: 'col-span-2',
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
vvName: 'address.zip',
|
|
350
|
+
vvType: 'number',
|
|
351
|
+
label: 'Zip'
|
|
352
|
+
}
|
|
353
|
+
]
|
|
354
|
+
}
|
|
355
|
+
]
|
|
356
|
+
|
|
357
|
+
const { VvForm, VvFormTemplate } = useForm(schema)
|
|
340
358
|
</script>
|
|
341
359
|
|
|
342
360
|
<template>
|
|
343
361
|
<VvForm>
|
|
344
|
-
<
|
|
345
|
-
<VvFormField
|
|
346
|
-
v-for="key in Object.keys(shoppingList)"
|
|
347
|
-
:key="key"
|
|
348
|
-
:name="`shoppingList.${key}`"
|
|
349
|
-
:label="$t(key)"
|
|
350
|
-
/>
|
|
351
|
-
<small v-if="invalid" class="input-counter__hint">{{
|
|
352
|
-
invalidLabel[0]
|
|
353
|
-
}}</small>
|
|
354
|
-
</VvFormField>
|
|
362
|
+
<VvFormTemplate :schema="templateSchema" />
|
|
355
363
|
</VvForm>
|
|
356
364
|
</template>
|
|
357
365
|
```
|
|
358
366
|
|
|
359
|
-
|
|
367
|
+
Template items, by default, are rendered as a `VvFormField` component but this can be changed using the `vvIs` property. The `vvIs` property can be a string or a component.
|
|
368
|
+
|
|
369
|
+
`vvName` refers to the name of the field in the schema and can be a nested property using **dot notation**.
|
|
370
|
+
|
|
371
|
+
`vvType` refers to the type of the field and can be any of the supported types.
|
|
372
|
+
|
|
373
|
+
`vvDefaultValue` can be used to set default values for the form item.
|
|
360
374
|
|
|
361
|
-
`
|
|
362
|
-
|
|
375
|
+
`vvShowValid` can be used to show the valid state of the form item.
|
|
376
|
+
|
|
377
|
+
`vvSlots` can be used to pass a slots to the template item.
|
|
378
|
+
|
|
379
|
+
`vvChildren` is an array of template items which will be wrapped in the parent item.
|
|
380
|
+
|
|
381
|
+
Conditional rendering can be achieved using the `vvIf` and `vvElseIf` properties.
|
|
363
382
|
|
|
364
383
|
```vue
|
|
365
384
|
<script lang="ts" setup>
|
|
@@ -367,54 +386,112 @@ The default settings are inherited from the plugin (if it was defined).
|
|
|
367
386
|
import { z } from 'zod'
|
|
368
387
|
|
|
369
388
|
const schema = z.object({
|
|
370
|
-
|
|
371
|
-
|
|
389
|
+
firstName: z.string(),
|
|
390
|
+
lastName: z.string(),
|
|
391
|
+
hasUsername: z.boolean(),
|
|
392
|
+
username: z.string().optional()
|
|
393
|
+
email: z.string().email().optional()
|
|
394
|
+
}).superRefine((value, ctx) => {
|
|
395
|
+
if (value.hasUsername && !value.username) {
|
|
396
|
+
ctx.addIssue({
|
|
397
|
+
code: z.ZodIssueCode.custom,
|
|
398
|
+
message: 'Username is required'
|
|
399
|
+
})
|
|
400
|
+
}
|
|
401
|
+
if (!value.hasUsername && !value.email) {
|
|
402
|
+
ctx.addIssue({
|
|
403
|
+
code: z.ZodIssueCode.custom,
|
|
404
|
+
message: 'Email is required'
|
|
405
|
+
})
|
|
406
|
+
}
|
|
372
407
|
})
|
|
373
408
|
|
|
374
|
-
const
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
409
|
+
const templateSchema = [
|
|
410
|
+
{
|
|
411
|
+
vvName: 'firstName',
|
|
412
|
+
vvType: 'text',
|
|
413
|
+
label: 'First Name'
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
vvName: 'lastName',
|
|
417
|
+
vvType: 'text',
|
|
418
|
+
label: 'Last Name'
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
vvName: 'hasUsername',
|
|
422
|
+
vvType: 'checkbox',
|
|
423
|
+
label: 'Has Username'
|
|
424
|
+
value: true,
|
|
425
|
+
uncheckedValue: false
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
vvIf: 'hasUsername',
|
|
429
|
+
vvName: 'username',
|
|
430
|
+
vvType: 'text',
|
|
431
|
+
label: 'Username'
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
vvElseIf: true,
|
|
435
|
+
vvName: 'email',
|
|
436
|
+
vvType: 'email',
|
|
437
|
+
label: 'Email'
|
|
438
|
+
}
|
|
439
|
+
]
|
|
440
|
+
|
|
441
|
+
const { VvForm, VvFormTemplate } = useForm(schema)
|
|
380
442
|
</script>
|
|
381
443
|
|
|
382
444
|
<template>
|
|
383
445
|
<VvForm>
|
|
384
|
-
<
|
|
385
|
-
<VvFormField type="text" name="surname" label="Surname" />
|
|
446
|
+
<VvFormTemplate :schema="templateSchema" />
|
|
386
447
|
</VvForm>
|
|
387
448
|
</template>
|
|
388
449
|
```
|
|
389
450
|
|
|
390
|
-
|
|
451
|
+
`vvElseIf` can be used multiple times. `vvElseIf: true` is like an `else` statement and will be rendered if all previous `vvIf` and `vvElseIf` conditions are false.
|
|
391
452
|
|
|
392
|
-
`
|
|
393
|
-
No settings are inherited.
|
|
453
|
+
`vvIf` and `vvElseIf` can be a string or a function. If it is a string it will be evaluated as a **property** of the form data. If it is a function it will be called with the **form context** as the **first argument**.
|
|
394
454
|
|
|
395
455
|
```ts
|
|
396
|
-
|
|
397
|
-
|
|
456
|
+
{
|
|
457
|
+
vvIf: (ctx) => ctx.formData.value.hasUsername,
|
|
458
|
+
vvName: 'username',
|
|
459
|
+
vvType: 'text',
|
|
460
|
+
label: 'Username'
|
|
461
|
+
}
|
|
462
|
+
```
|
|
398
463
|
|
|
399
|
-
|
|
400
|
-
name: z.string(),
|
|
401
|
-
surname: z.string()
|
|
402
|
-
})
|
|
464
|
+
The template schema and all template items can be a function. The function will be called with the form context as the first argument.
|
|
403
465
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
}
|
|
466
|
+
```ts
|
|
467
|
+
const templateSchema = (ctx) => [
|
|
468
|
+
{
|
|
469
|
+
vvName: 'firstName',
|
|
470
|
+
vvType: 'text',
|
|
471
|
+
label: `Hi ${ctx.formData.value.firstName}!`
|
|
472
|
+
}
|
|
473
|
+
]
|
|
474
|
+
```
|
|
410
475
|
|
|
411
|
-
|
|
476
|
+
```ts
|
|
477
|
+
const templateSchema = [
|
|
478
|
+
(ctx) => ({
|
|
479
|
+
vvName: 'firstName',
|
|
480
|
+
vvType: 'text',
|
|
481
|
+
label: `Hi ${ctx.formData.value.firstName}!`
|
|
482
|
+
}),
|
|
483
|
+
{
|
|
484
|
+
vvName: 'username',
|
|
485
|
+
type: 'text',
|
|
486
|
+
label: 'username'
|
|
487
|
+
}
|
|
488
|
+
]
|
|
412
489
|
```
|
|
413
490
|
|
|
414
491
|
## Default Object by Zod Object Schema
|
|
415
492
|
|
|
416
|
-
`defaultObjectBySchema` creates an object by a Zod Object Schema.
|
|
417
|
-
It can be useful to create a default object for a form
|
|
493
|
+
`defaultObjectBySchema` creates an object by a [Zod Object Schema](https://zod.dev/?id=objects).
|
|
494
|
+
It can be useful to create a **default object** for a **form**. The default object is created by the default values of the schema and can be merged with an other object passed as parameter.
|
|
418
495
|
|
|
419
496
|
```ts
|
|
420
497
|
import { z } from 'zod'
|
package/dist/VvForm.d.ts
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { type InjectionKey, type DeepReadonly, type Ref } from 'vue';
|
|
2
2
|
import type { z, TypeOf } from 'zod';
|
|
3
|
-
import type { FormSchema, InjectedFormData } from './types';
|
|
3
|
+
import type { FormComponentOptions, FormSchema, InjectedFormData } from './types';
|
|
4
4
|
import { FormStatus } from './enums';
|
|
5
|
-
export declare const defineForm: <Schema extends FormSchema>(schema: Schema, provideKey: InjectionKey<InjectedFormData<Schema>>, options?: {
|
|
6
|
-
updateThrottle?: number;
|
|
7
|
-
continuosValidation?: boolean;
|
|
8
|
-
}) => {
|
|
5
|
+
export declare const defineForm: <Schema extends FormSchema>(schema: Schema, provideKey: InjectionKey<InjectedFormData<Schema>>, options?: FormComponentOptions) => {
|
|
9
6
|
errors: Ref<z.ZodFormattedError<z.TypeOf<Schema>> | undefined>;
|
|
10
7
|
status: Ref<FormStatus | undefined>;
|
|
11
8
|
formData: Ref<Partial<z.TypeOf<Schema> | undefined>>;
|
|
@@ -18,12 +15,17 @@ export declare const defineForm: <Schema extends FormSchema>(schema: Schema, pro
|
|
|
18
15
|
$data: {};
|
|
19
16
|
$props: Partial<{
|
|
20
17
|
modelValue: Record<string, any>;
|
|
18
|
+
updateThrottle: number;
|
|
21
19
|
continuosValidation: boolean;
|
|
22
20
|
}> & Omit<Readonly<import("vue").ExtractPropTypes<{
|
|
23
21
|
modelValue: {
|
|
24
22
|
type: ObjectConstructor;
|
|
25
23
|
default: () => {};
|
|
26
24
|
};
|
|
25
|
+
updateThrottle: {
|
|
26
|
+
type: NumberConstructor;
|
|
27
|
+
default: number;
|
|
28
|
+
};
|
|
27
29
|
continuosValidation: {
|
|
28
30
|
type: BooleanConstructor;
|
|
29
31
|
default: boolean;
|
|
@@ -33,7 +35,7 @@ export declare const defineForm: <Schema extends FormSchema>(schema: Schema, pro
|
|
|
33
35
|
onValid?: ((...args: any[]) => any) | undefined;
|
|
34
36
|
onSubmit?: ((...args: any[]) => any) | undefined;
|
|
35
37
|
"onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
|
|
36
|
-
} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, "modelValue" | "continuosValidation">;
|
|
38
|
+
} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, "modelValue" | "updateThrottle" | "continuosValidation">;
|
|
37
39
|
$attrs: {
|
|
38
40
|
[x: string]: unknown;
|
|
39
41
|
};
|
|
@@ -52,6 +54,10 @@ export declare const defineForm: <Schema extends FormSchema>(schema: Schema, pro
|
|
|
52
54
|
type: ObjectConstructor;
|
|
53
55
|
default: () => {};
|
|
54
56
|
};
|
|
57
|
+
updateThrottle: {
|
|
58
|
+
type: NumberConstructor;
|
|
59
|
+
default: number;
|
|
60
|
+
};
|
|
55
61
|
continuosValidation: {
|
|
56
62
|
type: BooleanConstructor;
|
|
57
63
|
default: boolean;
|
|
@@ -69,6 +75,7 @@ export declare const defineForm: <Schema extends FormSchema>(schema: Schema, pro
|
|
|
69
75
|
invalid: import("vue").ComputedRef<boolean>;
|
|
70
76
|
}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("invalid" | "valid" | "submit" | "update:modelValue")[], string, {
|
|
71
77
|
modelValue: Record<string, any>;
|
|
78
|
+
updateThrottle: number;
|
|
72
79
|
continuosValidation: boolean;
|
|
73
80
|
}, {}, string> & {
|
|
74
81
|
beforeCreate?: ((() => void) | (() => void)[]) | undefined;
|
|
@@ -95,6 +102,10 @@ export declare const defineForm: <Schema extends FormSchema>(schema: Schema, pro
|
|
|
95
102
|
type: ObjectConstructor;
|
|
96
103
|
default: () => {};
|
|
97
104
|
};
|
|
105
|
+
updateThrottle: {
|
|
106
|
+
type: NumberConstructor;
|
|
107
|
+
default: number;
|
|
108
|
+
};
|
|
98
109
|
continuosValidation: {
|
|
99
110
|
type: BooleanConstructor;
|
|
100
111
|
default: boolean;
|
|
@@ -119,6 +130,10 @@ export declare const defineForm: <Schema extends FormSchema>(schema: Schema, pro
|
|
|
119
130
|
type: ObjectConstructor;
|
|
120
131
|
default: () => {};
|
|
121
132
|
};
|
|
133
|
+
updateThrottle: {
|
|
134
|
+
type: NumberConstructor;
|
|
135
|
+
default: number;
|
|
136
|
+
};
|
|
122
137
|
continuosValidation: {
|
|
123
138
|
type: BooleanConstructor;
|
|
124
139
|
default: boolean;
|
|
@@ -136,6 +151,7 @@ export declare const defineForm: <Schema extends FormSchema>(schema: Schema, pro
|
|
|
136
151
|
invalid: import("vue").ComputedRef<boolean>;
|
|
137
152
|
}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("invalid" | "valid" | "submit" | "update:modelValue")[], "invalid" | "valid" | "submit" | "update:modelValue", {
|
|
138
153
|
modelValue: Record<string, any>;
|
|
154
|
+
updateThrottle: number;
|
|
139
155
|
continuosValidation: boolean;
|
|
140
156
|
}, {}, string> & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps & (new () => {
|
|
141
157
|
$slots: {
|