@volverjs/form-vue 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 24/Consulting
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,281 @@
1
+ <div align="center">
2
+
3
+ [![volverjs](docs/static/volverjs-form.svg)](https://volverjs.github.io/form-vue)
4
+
5
+ ## @volverjs/form-vue
6
+
7
+ `form` `form-field` `form-wrapper` `vue3` `zod` `validation`
8
+
9
+ <br>
10
+
11
+ #### proudly powered by
12
+
13
+ <br>
14
+
15
+ [![24/Consulting](docs/static/24consulting.svg)](https://24consulting.it)
16
+
17
+ <br>
18
+
19
+ </div>
20
+
21
+ ## Install
22
+
23
+ ```bash
24
+ # pnpm
25
+ pnpm add @volverjs/form-vue
26
+
27
+ # yarn
28
+ yarn add @volverjs/form-vue
29
+
30
+ # npm
31
+ npm install @volverjs/form-vue --save
32
+ ```
33
+
34
+ ## Usage
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 three functions: `createForm`, `useForm` and `formFactory`.
37
+
38
+ ## Plugin
39
+
40
+ `createForm` defines globally three components `VvForm`, `VvFormWrapper`, and `VvFormField` through a [Vue 3 Plugin](https://vuejs.org/guide/reusability/plugins.html).
41
+
42
+ ```typescript
43
+ import { createApp } from 'vue'
44
+ import { createForm } from '@volverjs/form-vue'
45
+ import { z } from 'zod'
46
+
47
+ const schema = z.object({
48
+ name: z.string(),
49
+ surname: z.string()
50
+ })
51
+
52
+ const app = createApp(App)
53
+ const form = createForm({
54
+ schema
55
+ // lazyLoad: boolean - default false
56
+ // updateThrottle: number - default 500
57
+ // sideEffects?: (data: any) => void
58
+ })
59
+
60
+ app.use(form)
61
+ app.mount('#app')
62
+ ```
63
+
64
+ By default [`@volverjs/ui-vue`](https://github.com/volverjs/ui-vue) components must be defined globally but can be lazy loaded with `lazyLoad` option. 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).
65
+
66
+ ### VvForm
67
+
68
+ `VvForm` render a `form` tag and emit a `submit` event. Form data are validated on submit.
69
+ A `valid` or `invalid` event is emitted when the form status changes.
70
+
71
+ ```vue
72
+ <script lang="ts" setup>
73
+ const onSubmit = (formData) => {
74
+ // Do something with the form data
75
+ }
76
+ </script>
77
+
78
+ <template>
79
+ <VvForm @submit="onSubmit">
80
+ <!-- form fields -->
81
+ <button type="submit">Submit</button>
82
+ </VvForm>
83
+ </template>
84
+ ```
85
+
86
+ The submit can be triggered programmatically with the `submit()` method.
87
+
88
+ ```vue
89
+ <script lang="ts" setup>
90
+ const formEl = ref(null)
91
+ const onSubmit = (formData) => {
92
+ // Do something with the form data
93
+ }
94
+ const submitForm = () => {
95
+ formEl.value.submit()
96
+ }
97
+ </script>
98
+
99
+ <template>
100
+ <VvForm @submit="onSubmit" ref="formEl">
101
+ <!-- form fields -->
102
+ </VvForm>
103
+ <button type="button" @click.stop="submitForm">Submit</button>
104
+ </template>
105
+ ```
106
+
107
+ Use the `v-model` directive (or only `:model-value` to set the initial value of form data) to bind the form data.
108
+ The form data two way binding is throttled by default (500ms) to avoid performance issues.
109
+ The throttle can be changed with the `updateThrottle` option.
110
+
111
+ ```vue
112
+ <script lang="ts" setup>
113
+ import { ref } from 'vue'
114
+
115
+ const formData = ref({
116
+ name: '',
117
+ surname: ''
118
+ })
119
+ </script>
120
+
121
+ <template>
122
+ <VvForm v-model="formData">
123
+ <!-- form fields -->
124
+ <button type="submit">Submit</button>
125
+ </VvForm>
126
+ </template>
127
+ ```
128
+
129
+ ### VvFormWrapper
130
+
131
+ `VvFormWrapper` gives you the validation status of a part of your form.
132
+ The wrapper status is invalid if at least one of the fields inside it is invalid.
133
+
134
+ ```vue
135
+ <template>
136
+ <VvForm>
137
+ <VvFormWrapper #default="{ invalid }">
138
+ <div class="form-section-1">
139
+ <span v-if="invalid">There is a validation error</span>
140
+ <!-- form fields of section 1 -->
141
+ </div>
142
+ </VvFormWrapper>
143
+ <VvFormWrapper #default="{ invalid }">
144
+ <div class="form-section-2">
145
+ <span v-if="invalid">There is a validation error</span>
146
+ <!-- form fields of the section 2 -->
147
+ </div>
148
+ </VvFormWrapper>
149
+ </VvForm>
150
+ </template>
151
+ ```
152
+
153
+ ### VvFormField
154
+
155
+ `VvFormField` allow you to render a [`@volverjs/ui-vue`](https://github.com/volverjs/ui-vue) input component inside a form. It automatically bind the form data through the `name` attribute.
156
+
157
+ ```vue
158
+ <template>
159
+ <VvForm>
160
+ <VvFormField type="text" name="name" label="Name" />
161
+ <VvFormField type="text" name="surname" label="Surname" />
162
+ </VvForm>
163
+ </template>
164
+ ```
165
+
166
+ For nested objects, use the `name` attribute with dot notation.
167
+
168
+ ```vue
169
+ <template>
170
+ <VvForm>
171
+ <VvFormField type="text" name="shipping.address" label="Shipping address" />
172
+ </VvForm>
173
+ </template>
174
+ ```
175
+
176
+ The type of input component is defined by the `type` attribute.
177
+ All the available input types are listed in the [VvFormField documentation](/docs/VvFormField.md).
178
+
179
+ You can also use the `VvFormField` component to render a default slot without .
180
+
181
+ ```vue
182
+ <template>
183
+ <VvForm>
184
+ <VvFormField
185
+ name="name"
186
+ #default="{
187
+ modelValue,
188
+ invalid,
189
+ invalidLabel,
190
+ formData,
191
+ formErrors,
192
+ erros,
193
+ onUpdate
194
+ }"
195
+ >
196
+ <label for="name">Name</label>
197
+ <input
198
+ id="name"
199
+ type="text"
200
+ :value="modelValue"
201
+ :aria-invalid="invalid"
202
+ :aria-errormessage="invalid ? 'name-alert' : undefined"
203
+ @input="onUpdate"
204
+ />
205
+ <small v-if="invalid" role="alert" id="name-alert">
206
+ {{ invalidLabel }}
207
+ </small>
208
+ </VvFormField>
209
+ </VvForm>
210
+ </template>
211
+ ```
212
+
213
+ Or a custom component.
214
+
215
+ ```vue
216
+ <script lang="ts" setup>
217
+ import MyInput from './MyInput.vue'
218
+ </script>
219
+
220
+ <template>
221
+ <VvForm>
222
+ <VvFormField name="name" :is="MyInput" />
223
+ </VvForm>
224
+ </template>
225
+ ```
226
+
227
+ ## Composable
228
+
229
+ `useForm` can be used to create a form programmatically inside a Vue 3 Component.
230
+ If the plugin is defined globally, the settings are inherited but can be customized.
231
+
232
+ ```vue
233
+ <script lang="ts" setup>
234
+ import { useForm } from '@volverjs/form-vue'
235
+ import { z } from 'zod'
236
+
237
+ const schema = z.object({
238
+ name: z.string(),
239
+ surname: z.string()
240
+ })
241
+
242
+ const { VvForm, VvFormWrapper, VvFormField } = useForm(schema, {
243
+ // lazyLoad: boolean - default false
244
+ // updateThrottle: number - default 500
245
+ // sideEffects?: (formData: any) => void
246
+ })
247
+ </script>
248
+
249
+ <template>
250
+ <VvForm>
251
+ <VvFormField type="text" name="name" label="Name" />
252
+ <VvFormField type="text" name="surname" label="Surname" />
253
+ </VvForm>
254
+ </template>
255
+ ```
256
+
257
+ ## Outside a Vue 3 Component
258
+
259
+ `formFactory` can be used to create a form outside a Vue 3 Component.
260
+
261
+ ```ts
262
+ import { formFactory } from '@volverjs/form-vue'
263
+ import { z } from 'zod'
264
+
265
+ const schema = z.object({
266
+ name: z.string(),
267
+ surname: z.string()
268
+ })
269
+
270
+ const { VvForm, VvFormWrapper, VvFormField } = formFactory(schema, {
271
+ // lazyLoad: boolean - default false
272
+ // updateThrottle: number - default 500
273
+ // sideEffects?: (data: any) => void
274
+ })
275
+
276
+ export default { VvForm, VvFormWrapper, VvFormField }
277
+ ```
278
+
279
+ ## License
280
+
281
+ [MIT](http://opensource.org/licenses/MIT)
@@ -0,0 +1,29 @@
1
+ import { type InjectionKey } from 'vue';
2
+ import type { AnyZodObject } from 'zod';
3
+ import type { InjectedFormData } from './types';
4
+ export declare enum FormStatus {
5
+ invalid = "invalid",
6
+ valid = "valid"
7
+ }
8
+ export declare const defineForm: (schema: AnyZodObject, provideKey: InjectionKey<InjectedFormData>, options?: {
9
+ updateThrottle?: number;
10
+ }) => import("vue").DefineComponent<{
11
+ modelValue: {
12
+ type: ObjectConstructor;
13
+ default: () => {};
14
+ };
15
+ }, {
16
+ submit: () => boolean;
17
+ }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("valid" | "invalid" | "submit" | "update:modelValue")[], "valid" | "invalid" | "submit" | "update:modelValue", import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
18
+ modelValue: {
19
+ type: ObjectConstructor;
20
+ default: () => {};
21
+ };
22
+ }>> & {
23
+ onValid?: ((...args: any[]) => any) | undefined;
24
+ onInvalid?: ((...args: any[]) => any) | undefined;
25
+ onSubmit?: ((...args: any[]) => any) | undefined;
26
+ "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
27
+ }, {
28
+ modelValue: Record<string, any>;
29
+ }>;
@@ -0,0 +1,3 @@
1
+ import { type Component, type InjectionKey } from 'vue';
2
+ import type { InjectedFormData, InjectedFormWrapperData, InjectedFormFieldData, FormComposableOptions } from './types';
3
+ export declare const defineFormField: (formProvideKey: InjectionKey<InjectedFormData>, wrapperProvideKey: InjectionKey<InjectedFormWrapperData>, formFieldInjectionKey: InjectionKey<InjectedFormFieldData>, options?: FormComposableOptions) => Component;
@@ -0,0 +1,33 @@
1
+ import { type InjectionKey, type Ref } from 'vue';
2
+ import type { InjectedFormData, InjectedFormWrapperData } from './types';
3
+ export declare const defineFormWrapper: (formProvideKey: InjectionKey<InjectedFormData>, wrapperProvideKey: InjectionKey<InjectedFormWrapperData>) => import("vue").DefineComponent<{
4
+ name: {
5
+ type: StringConstructor;
6
+ required: true;
7
+ };
8
+ tag: {
9
+ type: StringConstructor;
10
+ default: undefined;
11
+ };
12
+ }, {
13
+ formProvided: InjectedFormData<Recrod<string | number, unknown>> | undefined;
14
+ invalid: import("vue").ComputedRef<boolean>;
15
+ fields: Ref<Set<string>>;
16
+ errors: Ref<Map<string, Record<string, {
17
+ _errors: string[];
18
+ }>>>;
19
+ }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("valid" | "invalid")[], "valid" | "invalid", import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
20
+ name: {
21
+ type: StringConstructor;
22
+ required: true;
23
+ };
24
+ tag: {
25
+ type: StringConstructor;
26
+ default: undefined;
27
+ };
28
+ }>> & {
29
+ onValid?: ((...args: any[]) => any) | undefined;
30
+ onInvalid?: ((...args: any[]) => any) | undefined;
31
+ }, {
32
+ tag: string;
33
+ }>;
@@ -0,0 +1,23 @@
1
+ export declare enum FormFieldType {
2
+ text = "text",
3
+ number = "number",
4
+ email = "email",
5
+ password = "password",
6
+ tel = "tel",
7
+ url = "url",
8
+ search = "search",
9
+ date = "date",
10
+ time = "time",
11
+ datetimeLocal = "datetimeLocal",
12
+ month = "month",
13
+ week = "week",
14
+ color = "color",
15
+ select = "select",
16
+ checkbox = "checkbox",
17
+ radio = "radio",
18
+ textarea = "textarea",
19
+ radioGroup = "radioGroup",
20
+ checkboxGroup = "checkboxGroup",
21
+ combobox = "combobox",
22
+ custom = "custom"
23
+ }
@@ -0,0 +1,122 @@
1
+ import { type InjectionKey, type Plugin } from 'vue';
2
+ import type { AnyZodObject } from 'zod';
3
+ import type { InjectedFormData, InjectedFormWrapperData, InjectedFormFieldData, FormComposableOptions, FormPluginOptions } from './types';
4
+ export declare const formFactory: (schema: AnyZodObject, options?: FormComposableOptions) => {
5
+ VvForm: import("vue").DefineComponent<{
6
+ modelValue: {
7
+ type: ObjectConstructor;
8
+ default: () => {};
9
+ };
10
+ }, {
11
+ submit: () => boolean;
12
+ }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("valid" | "invalid" | "submit" | "update:modelValue")[], "valid" | "invalid" | "submit" | "update:modelValue", import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
13
+ modelValue: {
14
+ type: ObjectConstructor;
15
+ default: () => {};
16
+ };
17
+ }>> & {
18
+ onValid?: ((...args: any[]) => any) | undefined;
19
+ onInvalid?: ((...args: any[]) => any) | undefined;
20
+ onSubmit?: ((...args: any[]) => any) | undefined;
21
+ "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
22
+ }, {
23
+ modelValue: Record<string, any>;
24
+ }>;
25
+ VvFormWrapper: import("vue").DefineComponent<{
26
+ name: {
27
+ type: StringConstructor;
28
+ required: true;
29
+ };
30
+ tag: {
31
+ type: StringConstructor;
32
+ default: undefined;
33
+ };
34
+ }, {
35
+ formProvided: InjectedFormData<Recrod<string | number, unknown>> | undefined;
36
+ invalid: import("vue").ComputedRef<boolean>;
37
+ fields: import("vue").Ref<Set<string>>;
38
+ errors: import("vue").Ref<Map<string, Record<string, {
39
+ _errors: string[];
40
+ }>>>;
41
+ }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("valid" | "invalid")[], "valid" | "invalid", import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
42
+ name: {
43
+ type: StringConstructor;
44
+ required: true;
45
+ };
46
+ tag: {
47
+ type: StringConstructor;
48
+ default: undefined;
49
+ };
50
+ }>> & {
51
+ onValid?: ((...args: any[]) => any) | undefined;
52
+ onInvalid?: ((...args: any[]) => any) | undefined;
53
+ }, {
54
+ tag: string;
55
+ }>;
56
+ VvFormField: import("vue").Component<any, any, any, import("vue").ComputedOptions, import("vue").MethodOptions>;
57
+ formInjectionKey: InjectionKey<InjectedFormData<Recrod<string | number, unknown>>>;
58
+ formWrapperInjectionKey: InjectionKey<InjectedFormWrapperData>;
59
+ formFieldInjectionKey: InjectionKey<InjectedFormFieldData>;
60
+ };
61
+ export declare const pluginInjectionKey: InjectionKey<FormPluginOptions>;
62
+ export declare const createForm: (options: FormPluginOptions) => Plugin & Partial<ReturnType<typeof useForm>>;
63
+ export declare const useForm: (schema: AnyZodObject, options?: FormComposableOptions) => {
64
+ VvForm: import("vue").DefineComponent<{
65
+ modelValue: {
66
+ type: ObjectConstructor;
67
+ default: () => {};
68
+ };
69
+ }, {
70
+ submit: () => boolean;
71
+ }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("valid" | "invalid" | "submit" | "update:modelValue")[], "valid" | "invalid" | "submit" | "update:modelValue", import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
72
+ modelValue: {
73
+ type: ObjectConstructor;
74
+ default: () => {};
75
+ };
76
+ }>> & {
77
+ onValid?: ((...args: any[]) => any) | undefined;
78
+ onInvalid?: ((...args: any[]) => any) | undefined;
79
+ onSubmit?: ((...args: any[]) => any) | undefined;
80
+ "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
81
+ }, {
82
+ modelValue: Record<string, any>;
83
+ }>;
84
+ VvFormWrapper: import("vue").DefineComponent<{
85
+ name: {
86
+ type: StringConstructor;
87
+ required: true;
88
+ };
89
+ tag: {
90
+ type: StringConstructor;
91
+ default: undefined;
92
+ };
93
+ }, {
94
+ formProvided: InjectedFormData<Recrod<string | number, unknown>> | undefined;
95
+ invalid: import("vue").ComputedRef<boolean>;
96
+ fields: import("vue").Ref<Set<string>>;
97
+ errors: import("vue").Ref<Map<string, Record<string, {
98
+ _errors: string[];
99
+ }>>>;
100
+ }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("valid" | "invalid")[], "valid" | "invalid", import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
101
+ name: {
102
+ type: StringConstructor;
103
+ required: true;
104
+ };
105
+ tag: {
106
+ type: StringConstructor;
107
+ default: undefined;
108
+ };
109
+ }>> & {
110
+ onValid?: ((...args: any[]) => any) | undefined;
111
+ onInvalid?: ((...args: any[]) => any) | undefined;
112
+ }, {
113
+ tag: string;
114
+ }>;
115
+ VvFormField: import("vue").Component<any, any, any, import("vue").ComputedOptions, import("vue").MethodOptions>;
116
+ formInjectionKey: InjectionKey<InjectedFormData<Recrod<string | number, unknown>>>;
117
+ formWrapperInjectionKey: InjectionKey<InjectedFormWrapperData>;
118
+ formFieldInjectionKey: InjectionKey<InjectedFormFieldData>;
119
+ };
120
+ export { FormFieldType } from './enums';
121
+ export { defaultObjectBySchema } from './utils';
122
+ export type { InjectedFormData, InjectedFormWrapperData, InjectedFormFieldData, FormComposableOptions, FormPluginOptions, };