@volverjs/form-vue 1.0.0-beta.12 → 1.0.0-beta.13

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.
@@ -1,171 +1,168 @@
1
1
  import {
2
- type InjectionKey,
3
- type Ref,
4
- computed,
5
- defineComponent,
6
- inject,
7
- provide,
8
- readonly,
9
- ref,
10
- toRefs,
11
- watch,
12
- h,
13
- type DeepReadonly,
2
+ type InjectionKey,
3
+ type Ref,
4
+ computed,
5
+ defineComponent,
6
+ inject,
7
+ provide,
8
+ readonly,
9
+ ref,
10
+ toRefs,
11
+ watch,
12
+ h,
13
+ type DeepReadonly,
14
14
  } from 'vue'
15
15
  import type { TypeOf, z } from 'zod'
16
16
  import type {
17
- FormSchema,
18
- InjectedFormData,
19
- InjectedFormWrapperData,
17
+ FormSchema,
18
+ InjectedFormData,
19
+ InjectedFormWrapperData,
20
20
  } from './types'
21
21
 
22
- export const defineFormWrapper = <Schema extends FormSchema>(
23
- formProvideKey: InjectionKey<InjectedFormData<Schema>>,
24
- wrapperProvideKey: InjectionKey<InjectedFormWrapperData<Schema>>,
25
- ) => {
26
- const VvFormWrapper = defineComponent({
27
- name: 'VvFormWrapper',
28
- props: {
29
- name: {
30
- type: String,
31
- required: true,
32
- },
33
- tag: {
34
- type: String,
35
- default: undefined,
36
- },
37
- },
38
- emits: ['invalid', 'valid'],
39
- expose: ['fields', 'invalid'],
40
- setup(props, { emit }) {
41
- const injectedFormData = inject(formProvideKey)
42
- const wrapperProvided = inject(wrapperProvideKey, undefined)
43
- const fields = ref(new Set<string>())
44
- const fieldsErrors: Ref<
22
+ export function defineFormWrapper<Schema extends FormSchema>(formProvideKey: InjectionKey<InjectedFormData<Schema>>, wrapperProvideKey: InjectionKey<InjectedFormWrapperData<Schema>>) {
23
+ const VvFormWrapper = defineComponent({
24
+ name: 'VvFormWrapper',
25
+ props: {
26
+ name: {
27
+ type: String,
28
+ required: true,
29
+ },
30
+ tag: {
31
+ type: String,
32
+ default: undefined,
33
+ },
34
+ },
35
+ emits: ['invalid', 'valid'],
36
+ expose: ['fields', 'invalid'],
37
+ setup(props, { emit }) {
38
+ const injectedFormData = inject(formProvideKey)
39
+ const wrapperProvided = inject(wrapperProvideKey, undefined)
40
+ const fields = ref(new Set<string>())
41
+ const fieldsErrors: Ref<
45
42
  Map<string, z.inferFormattedError<Schema>>
46
43
  > = ref(new Map())
47
- const { name } = toRefs(props)
44
+ const { name } = toRefs(props)
48
45
 
49
- // provide data to child fields
50
- provide(wrapperProvideKey, {
51
- name: readonly(name),
52
- errors: fieldsErrors,
53
- fields,
54
- })
46
+ // provide data to child fields
47
+ provide(wrapperProvideKey, {
48
+ name: readonly(name),
49
+ errors: fieldsErrors,
50
+ fields,
51
+ })
55
52
 
56
- // add fields to parent wrapper
57
- watch(
58
- fields,
59
- (newValue) => {
60
- if (wrapperProvided?.fields) {
61
- newValue.forEach((field) => {
62
- wrapperProvided?.fields.value.add(field)
63
- })
64
- }
65
- },
66
- { deep: true },
67
- )
53
+ // add fields to parent wrapper
54
+ watch(
55
+ fields,
56
+ (newValue) => {
57
+ if (wrapperProvided?.fields) {
58
+ newValue.forEach((field) => {
59
+ wrapperProvided?.fields.value.add(field)
60
+ })
61
+ }
62
+ },
63
+ { deep: true },
64
+ )
68
65
 
69
- // add fields to parent wrapper
70
- watch(
71
- () => new Map(fieldsErrors.value),
72
- (newValue, oldValue) => {
73
- if (wrapperProvided?.errors) {
74
- Array.from(oldValue.keys()).forEach((key) => {
75
- wrapperProvided.errors.value.delete(key)
76
- })
77
- Array.from(newValue.keys()).forEach((key) => {
78
- const value = newValue.get(key)
79
- if (value) {
80
- wrapperProvided.errors.value.set(key, value)
81
- }
82
- })
83
- }
84
- },
85
- { deep: true },
86
- )
66
+ // add fields to parent wrapper
67
+ watch(
68
+ () => new Map(fieldsErrors.value),
69
+ (newValue, oldValue) => {
70
+ if (wrapperProvided?.errors) {
71
+ Array.from(oldValue.keys()).forEach((key) => {
72
+ wrapperProvided.errors.value.delete(key)
73
+ })
74
+ Array.from(newValue.keys()).forEach((key) => {
75
+ const value = newValue.get(key)
76
+ if (value) {
77
+ wrapperProvided.errors.value.set(key, value)
78
+ }
79
+ })
80
+ }
81
+ },
82
+ { deep: true },
83
+ )
87
84
 
88
- const invalid = computed(() => {
89
- if (!injectedFormData?.invalid.value) {
90
- return false
91
- }
92
- return fieldsErrors.value.size > 0
93
- })
85
+ const invalid = computed(() => {
86
+ if (!injectedFormData?.invalid.value) {
87
+ return false
88
+ }
89
+ return fieldsErrors.value.size > 0
90
+ })
94
91
 
95
- watch(invalid, () => {
96
- if (invalid.value) {
97
- emit('invalid')
98
- } else {
99
- emit('valid')
100
- }
101
- })
92
+ watch(invalid, () => {
93
+ if (invalid.value) {
94
+ emit('invalid')
95
+ }
96
+ else {
97
+ emit('valid')
98
+ }
99
+ })
102
100
 
103
- return {
104
- formData: injectedFormData?.formData,
105
- errors: injectedFormData?.errors,
106
- submit: injectedFormData?.submit,
107
- validate: injectedFormData?.validate,
108
- invalid,
109
- fields,
110
- fieldsErrors,
111
- }
112
- },
113
- render() {
114
- if (this.tag) {
115
- return h(this.tag, null, {
116
- default: () =>
117
- this.$slots.default?.({
118
- invalid: this.invalid,
119
- formData: this.formData,
120
- submit: this.submit,
121
- validate: this.validate,
122
- errors: this.errors,
123
- fieldsErrors: this.fieldsErrors,
124
- }) ?? this.$slots.defalut,
125
- })
126
- }
127
- return (
128
- this.$slots.default?.({
129
- invalid: this.invalid,
130
- formData: this.formData,
131
- submit: this.submit,
132
- validate: this.validate,
133
- errors: this.errors,
134
- fieldsErrors: this.fieldsErrors,
135
- }) ?? this.$slots.defalut
136
- )
137
- },
138
- })
139
- /**
140
- * An hack to add types to the default slot
141
- */
142
- return VvFormWrapper as typeof VvFormWrapper & {
143
- new (): {
144
- $slots: {
145
- default: (_: {
146
- invalid: boolean
147
- formData: unknown extends
148
- | Partial<TypeOf<Schema>>
149
- | undefined
150
- ? undefined
151
- : Partial<TypeOf<Schema>> | undefined
152
- submit: () => Promise<boolean>
153
- validate: () => Promise<boolean>
154
- errors: Readonly<
101
+ return {
102
+ formData: injectedFormData?.formData,
103
+ errors: injectedFormData?.errors,
104
+ submit: injectedFormData?.submit,
105
+ validate: injectedFormData?.validate,
106
+ invalid,
107
+ fields,
108
+ fieldsErrors,
109
+ }
110
+ },
111
+ render() {
112
+ if (this.tag) {
113
+ return h(this.tag, null, {
114
+ default: () =>
115
+ this.$slots.default?.({
116
+ invalid: this.invalid,
117
+ formData: this.formData,
118
+ submit: this.submit,
119
+ validate: this.validate,
120
+ errors: this.errors,
121
+ fieldsErrors: this.fieldsErrors,
122
+ }) ?? this.$slots.defalut,
123
+ })
124
+ }
125
+ return (
126
+ this.$slots.default?.({
127
+ invalid: this.invalid,
128
+ formData: this.formData,
129
+ submit: this.submit,
130
+ validate: this.validate,
131
+ errors: this.errors,
132
+ fieldsErrors: this.fieldsErrors,
133
+ }) ?? this.$slots.defalut
134
+ )
135
+ },
136
+ })
137
+ /**
138
+ * An hack to add types to the default slot
139
+ */
140
+ return VvFormWrapper as typeof VvFormWrapper & {
141
+ new (): {
142
+ $slots: {
143
+ default: (_: {
144
+ invalid: boolean
145
+ formData: unknown extends
146
+ | Partial<TypeOf<Schema>>
147
+ | undefined
148
+ ? undefined
149
+ : Partial<TypeOf<Schema>> | undefined
150
+ submit: () => Promise<boolean>
151
+ validate: () => Promise<boolean>
152
+ errors: Readonly<
155
153
  Ref<DeepReadonly<z.inferFormattedError<Schema>>>
156
154
  >
157
- fieldsErrors: Map<
155
+ fieldsErrors: Map<
158
156
  string,
159
157
  Record<
160
158
  string,
161
159
  {
162
- _errors: string[]
160
+ _errors: string[]
163
161
  }
164
162
  >
165
163
  >
166
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
167
- }) => any
168
- }
169
- }
170
- }
164
+ }) => any
165
+ }
166
+ }
167
+ }
171
168
  }
package/src/enums.ts CHANGED
@@ -1,31 +1,31 @@
1
1
  export 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 = 'datetime-local',
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',
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 = 'datetime-local',
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
23
  }
24
24
 
25
25
  export enum FormStatus {
26
- invalid = 'invalid',
27
- valid = 'valid',
28
- submitting = 'submitting',
29
- updated = 'updated',
30
- unknown = 'unknown',
26
+ invalid = 'invalid',
27
+ valid = 'valid',
28
+ submitting = 'submitting',
29
+ updated = 'updated',
30
+ unknown = 'unknown',
31
31
  }
package/src/index.ts CHANGED
@@ -1,134 +1,126 @@
1
1
  import {
2
- getCurrentInstance,
3
- type App,
4
- inject,
5
- type InjectionKey,
6
- type Plugin,
2
+ getCurrentInstance,
3
+ type App,
4
+ inject,
5
+ type InjectionKey,
6
+ type Plugin,
7
7
  } from 'vue'
8
+ import type { AnyZodObject } from 'zod'
8
9
  import { defineFormField } from './VvFormField'
9
10
  import { defineForm } from './VvForm'
10
11
  import { defineFormWrapper } from './VvFormWrapper'
11
12
  import { defineFormTemplate } from './VvFormTemplate'
12
13
  import type {
13
- InjectedFormData,
14
- InjectedFormWrapperData,
15
- InjectedFormFieldData,
16
- FormComposableOptions,
17
- FormPluginOptions,
18
- FormTemplateItem,
19
- Path,
20
- PathValue,
21
- FormSchema,
22
- FormTemplate,
14
+ InjectedFormData,
15
+ InjectedFormWrapperData,
16
+ InjectedFormFieldData,
17
+ FormComposableOptions,
18
+ FormPluginOptions,
19
+ FormTemplateItem,
20
+ Path,
21
+ PathValue,
22
+ FormSchema,
23
+ FormTemplate,
23
24
  } from './types'
24
- import type { AnyZodObject } from 'zod'
25
25
 
26
- const _formFactory = <Schema extends FormSchema>(
27
- schema: Schema,
28
- options: FormComposableOptions<Schema> = {},
29
- ) => {
30
- // create injection keys
31
- const formInjectionKey = Symbol() as InjectionKey<InjectedFormData<Schema>>
32
- const formWrapperInjectionKey = Symbol() as InjectionKey<
26
+ function _formFactory<Schema extends FormSchema>(schema: Schema, options: FormComposableOptions<Schema> = {}) {
27
+ // create injection keys
28
+ const formInjectionKey = Symbol('formInjectionKey') as InjectionKey<InjectedFormData<Schema>>
29
+ const formWrapperInjectionKey = Symbol('formWrapperInjectionKey') as InjectionKey<
33
30
  InjectedFormWrapperData<Schema>
34
31
  >
35
- const formFieldInjectionKey = Symbol() as InjectionKey<
32
+ const formFieldInjectionKey = Symbol('formFieldInjectionKey') as InjectionKey<
36
33
  InjectedFormFieldData<Schema>
37
34
  >
38
35
 
39
- // create components
40
- const VvFormWrapper = defineFormWrapper(
41
- formInjectionKey,
42
- formWrapperInjectionKey,
43
- )
44
- const VvFormField = defineFormField(
45
- formInjectionKey,
46
- formWrapperInjectionKey,
47
- formFieldInjectionKey,
48
- options,
49
- )
50
- const VvFormTemplate = defineFormTemplate(formInjectionKey, VvFormField)
51
- const {
52
- VvForm,
53
- errors,
54
- status,
55
- invalid,
56
- readonly,
57
- formData,
58
- validate,
59
- submit,
60
- ignoreUpdates,
61
- stopUpdatesWatch,
62
- } = defineForm(schema, formInjectionKey, options, VvFormTemplate)
36
+ // create components
37
+ const VvFormWrapper = defineFormWrapper(
38
+ formInjectionKey,
39
+ formWrapperInjectionKey,
40
+ )
41
+ const VvFormField = defineFormField(
42
+ formInjectionKey,
43
+ formWrapperInjectionKey,
44
+ formFieldInjectionKey,
45
+ options,
46
+ )
47
+ const VvFormTemplate = defineFormTemplate(formInjectionKey, VvFormField)
48
+ const {
49
+ VvForm,
50
+ errors,
51
+ status,
52
+ invalid,
53
+ readonly,
54
+ formData,
55
+ validate,
56
+ submit,
57
+ ignoreUpdates,
58
+ stopUpdatesWatch,
59
+ } = defineForm(schema, formInjectionKey, options, VvFormTemplate)
63
60
 
64
- return {
65
- VvForm,
66
- VvFormWrapper,
67
- VvFormField,
68
- VvFormTemplate,
69
- formInjectionKey,
70
- formWrapperInjectionKey,
71
- formFieldInjectionKey,
72
- errors,
73
- status,
74
- invalid,
75
- readonly,
76
- formData,
77
- validate,
78
- submit,
79
- ignoreUpdates,
80
- stopUpdatesWatch,
81
- }
61
+ return {
62
+ VvForm,
63
+ VvFormWrapper,
64
+ VvFormField,
65
+ VvFormTemplate,
66
+ formInjectionKey,
67
+ formWrapperInjectionKey,
68
+ formFieldInjectionKey,
69
+ errors,
70
+ status,
71
+ invalid,
72
+ readonly,
73
+ formData,
74
+ validate,
75
+ submit,
76
+ ignoreUpdates,
77
+ stopUpdatesWatch,
78
+ }
82
79
  }
83
80
 
84
- export const pluginInjectionKey = Symbol() as InjectionKey<FormPluginOptions>
81
+ export const pluginInjectionKey = Symbol('pluginInjectionKey') as InjectionKey<FormPluginOptions>
85
82
 
86
- export const createForm = (
87
- options: FormPluginOptions,
88
- ): Plugin & Partial<ReturnType<typeof useForm>> => {
89
- let toReturn: Partial<ReturnType<typeof useForm>> = {}
90
- if (options.schema) {
91
- toReturn = _formFactory(options.schema as AnyZodObject, options)
92
- }
93
- return {
94
- ...toReturn,
95
- install(app: App, { global = false } = {}) {
96
- app.provide(pluginInjectionKey, options)
83
+ export function createForm(options: FormPluginOptions): Plugin & Partial<ReturnType<typeof useForm>> {
84
+ let toReturn: Partial<ReturnType<typeof useForm>> = {}
85
+ if (options.schema) {
86
+ toReturn = _formFactory(options.schema as AnyZodObject, options)
87
+ }
88
+ return {
89
+ ...toReturn,
90
+ install(app: App, { global = false } = {}) {
91
+ app.provide(pluginInjectionKey, options)
97
92
 
98
- if (global) {
99
- app.config.globalProperties.$vvForm = options
93
+ if (global) {
94
+ app.config.globalProperties.$vvForm = options
100
95
 
101
- if (toReturn?.VvForm) {
102
- app.component('VvForm', toReturn.VvForm)
103
- }
104
- if (toReturn?.VvFormWrapper) {
105
- app.component('VvFormWrapper', toReturn.VvFormWrapper)
106
- }
107
- if (toReturn?.VvFormField) {
108
- app.component('VvFormField', toReturn.VvFormField)
109
- }
110
- if (toReturn?.VvFormTemplate) {
111
- app.component('VvFormTemplate', toReturn.VvFormTemplate)
112
- }
113
- }
114
- },
115
- }
96
+ if (toReturn?.VvForm) {
97
+ app.component('VvForm', toReturn.VvForm)
98
+ }
99
+ if (toReturn?.VvFormWrapper) {
100
+ app.component('VvFormWrapper', toReturn.VvFormWrapper)
101
+ }
102
+ if (toReturn?.VvFormField) {
103
+ app.component('VvFormField', toReturn.VvFormField)
104
+ }
105
+ if (toReturn?.VvFormTemplate) {
106
+ app.component('VvFormTemplate', toReturn.VvFormTemplate)
107
+ }
108
+ }
109
+ },
110
+ }
116
111
  }
117
112
 
118
- export const useForm = <Schema extends FormSchema>(
119
- schema: Schema,
120
- options: FormComposableOptions<Schema> = {},
121
- ) => {
122
- if (!getCurrentInstance()) {
123
- return _formFactory(schema, options)
124
- }
125
- return _formFactory(
126
- schema as AnyZodObject,
127
- {
128
- ...inject(pluginInjectionKey, {}),
129
- ...options,
130
- } as FormComposableOptions<AnyZodObject>,
131
- )
113
+ export function useForm<Schema extends FormSchema>(schema: Schema, options: FormComposableOptions<Schema> = {}) {
114
+ if (!getCurrentInstance()) {
115
+ return _formFactory(schema, options)
116
+ }
117
+ return _formFactory(
118
+ schema as AnyZodObject,
119
+ {
120
+ ...inject(pluginInjectionKey, {}),
121
+ ...options,
122
+ } as FormComposableOptions<AnyZodObject>,
123
+ )
132
124
  }
133
125
 
134
126
  export { FormFieldType } from './enums'
@@ -140,28 +132,25 @@ type FormFieldComponent = ReturnType<typeof defineFormField>
140
132
  type FormTemplateComponent = ReturnType<typeof defineFormTemplate>
141
133
 
142
134
  export type {
143
- InjectedFormData,
144
- InjectedFormWrapperData,
145
- InjectedFormFieldData,
146
- FormComposableOptions,
147
- FormSchema,
148
- FormPluginOptions,
149
- FormComponent,
150
- FormWrapperComponent,
151
- FormFieldComponent,
152
- FormTemplate,
153
- FormTemplateComponent,
154
- FormTemplateItem,
155
- Path,
156
- PathValue,
135
+ InjectedFormData,
136
+ InjectedFormWrapperData,
137
+ InjectedFormFieldData,
138
+ FormComposableOptions,
139
+ FormSchema,
140
+ FormPluginOptions,
141
+ FormComponent,
142
+ FormWrapperComponent,
143
+ FormFieldComponent,
144
+ FormTemplate,
145
+ FormTemplateComponent,
146
+ FormTemplateItem,
147
+ Path,
148
+ PathValue,
157
149
  }
158
150
 
159
151
  /**
160
152
  * @deprecated Use `useForm()` instead
161
153
  */
162
- export const formFactory = <Schema extends FormSchema>(
163
- schema: Schema,
164
- options: FormComposableOptions<Schema> = {},
165
- ) => {
166
- return _formFactory(schema, options)
154
+ export function formFactory<Schema extends FormSchema>(schema: Schema, options: FormComposableOptions<Schema> = {}) {
155
+ return _formFactory(schema, options)
167
156
  }