@teamnovu/kit-vue-forms 0.1.16 → 0.1.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,29 @@
1
+ import type { Awaitable, MaybeRef } from '@vueuse/core'
2
+ import { unref } from 'vue'
3
+ import type { Form, FormDataDefault } from '../types/form'
4
+ import type { ValidationStrategy } from '../types/validation'
5
+
6
+ interface SubmitHandlerOptions {
7
+ validationStrategy?: MaybeRef<ValidationStrategy>
8
+ }
9
+
10
+ export function useSubmitHandler<T extends FormDataDefault>(
11
+ form: Omit<Form<T>, 'submitHandler'>,
12
+ options: SubmitHandlerOptions,
13
+ ) {
14
+ return (onSubmit: (data: T) => Awaitable<void>) => {
15
+ return async (event: SubmitEvent) => {
16
+ event.preventDefault()
17
+
18
+ if (unref(options.validationStrategy) !== 'none') {
19
+ await form.validateForm()
20
+ }
21
+
22
+ if (!form.isValid.value) {
23
+ return
24
+ }
25
+
26
+ await onSubmit(form.data.value)
27
+ }
28
+ }
29
+ }
package/src/types/form.ts CHANGED
@@ -80,5 +80,5 @@ export interface Form<T extends FormDataDefault> {
80
80
  getSubForm: <P extends EntityPaths<T>>(
81
81
  path: P,
82
82
  options?: SubformOptions<PickEntity<T, P>>,
83
- ) => Form<PickEntity<T, P>>
83
+ ) => Omit<Form<PickEntity<T, P>>, 'submitHandler'>
84
84
  }
package/src/utils/path.ts CHANGED
@@ -1,21 +1,21 @@
1
- import { computed, isRef, unref, type MaybeRef } from "vue";
2
- import type { Paths, PickProps, SplitPath } from "../types/util";
3
- import type { ErrorBag, ValidationErrors } from "../types/validation";
4
- import type { FormField } from "../types/form";
1
+ import { computed, isRef, unref, type MaybeRef } from 'vue'
2
+ import type { Paths, PickProps, SplitPath } from '../types/util'
3
+ import type { ErrorBag, ValidationErrors } from '../types/validation'
4
+ import type { FormField } from '../types/form'
5
5
 
6
6
  export function splitPath(path: string): string[] {
7
- if (path === "") {
8
- return [];
7
+ if (path === '') {
8
+ return []
9
9
  }
10
- return path.split(/\s*\.\s*/).filter(Boolean);
10
+ return path.split(/\s*\.\s*/).filter(Boolean)
11
11
  }
12
12
 
13
13
  export function existsPath<T, K extends Paths<T>>(
14
14
  obj: T,
15
15
  path: K | SplitPath<K>,
16
16
  ): boolean {
17
- const splittedPath = Array.isArray(path) ? path : splitPath(path) as SplitPath<K>;
18
- return !!getNestedValue(obj, splittedPath.slice(0, -1) as SplitPath<K>);
17
+ const splittedPath = Array.isArray(path) ? path : splitPath(path) as SplitPath<K>
18
+ return !!getNestedValue(obj, splittedPath.slice(0, -1) as SplitPath<K>)
19
19
  }
20
20
 
21
21
  export function existsFieldPath<T, K extends Paths<T>>(field: FormField<T, K>) {
@@ -26,11 +26,11 @@ export function getNestedValue<T, K extends Paths<T>>(
26
26
  obj: T,
27
27
  path: K | SplitPath<K>,
28
28
  ) {
29
- const splittedPath = Array.isArray(path) ? path : splitPath(path);
29
+ const splittedPath = Array.isArray(path) ? path : splitPath(path)
30
30
  return splittedPath.reduce(
31
31
  (current, key) => current?.[key],
32
32
  obj as Record<string, never>,
33
- ) as PickProps<T, K>;
33
+ ) as PickProps<T, K>
34
34
  }
35
35
 
36
36
  export function setNestedValue<T, K extends Paths<T>>(
@@ -38,31 +38,31 @@ export function setNestedValue<T, K extends Paths<T>>(
38
38
  path: K | SplitPath<K>,
39
39
  value: PickProps<T, K>,
40
40
  ): void {
41
- const keys = Array.isArray(path) ? path : splitPath(path);
41
+ const keys = Array.isArray(path) ? path : splitPath(path)
42
42
 
43
- const lastKey = keys.at(-1)!;
43
+ const lastKey = keys.at(-1)!
44
44
 
45
45
  if (!lastKey) {
46
46
  if (!isRef(obj)) {
47
47
  // We cannot do anything here as we have nothing we can assign to
48
- return;
48
+ return
49
49
  }
50
50
 
51
- obj.value = value;
51
+ obj.value = value
52
52
  } else {
53
53
  const target = keys.slice(0, -1).reduce(
54
54
  (current, key) => {
55
55
  if (current?.[key] === undefined) {
56
56
  // Create the nested object if it doesn't exist
57
- current[key] = {};
57
+ current[key] = {}
58
58
  }
59
- return current?.[key];
59
+ return current?.[key]
60
60
  },
61
61
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
62
62
  unref(obj) as Record<string, any>,
63
- );
63
+ )
64
64
 
65
- target[lastKey] = value;
65
+ target[lastKey] = value
66
66
  }
67
67
  }
68
68
 
@@ -72,58 +72,57 @@ export const getLens = <T, K extends Paths<T>>(
72
72
  ) => {
73
73
  return computed({
74
74
  get() {
75
- return getNestedValue(unref(data), unref(key));
75
+ return getNestedValue(unref(data), unref(key))
76
76
  },
77
77
  set(value: PickProps<T, K>) {
78
- setNestedValue(data, unref(key), value);
78
+ setNestedValue(data, unref(key), value)
79
79
  },
80
- });
81
- };
80
+ })
81
+ }
82
82
 
83
83
  type JoinPath<
84
84
  Base extends string,
85
85
  Sub extends string,
86
- > = `${Base}${Base extends "" ? "" : Sub extends "" ? "" : "."}${Sub}`;
86
+ > = `${Base}${Base extends '' ? '' : Sub extends '' ? '' : '.'}${Sub}`
87
87
  export function joinPath<Base extends string, Sub extends string>(
88
88
  basePath: Base,
89
89
  subPath: Sub,
90
90
  ): JoinPath<Base, Sub> {
91
91
  if (!basePath && !subPath) {
92
- return "" as JoinPath<Base, Sub>;
92
+ return '' as JoinPath<Base, Sub>
93
93
  }
94
94
 
95
95
  if (!basePath && subPath) {
96
- return subPath as JoinPath<Base, Sub>;
96
+ return subPath as JoinPath<Base, Sub>
97
97
  }
98
98
 
99
99
  if (!subPath && basePath) {
100
- return basePath as JoinPath<Base, Sub>;
100
+ return basePath as JoinPath<Base, Sub>
101
101
  }
102
102
 
103
- return `${basePath}.${subPath}` as JoinPath<Base, Sub>;
103
+ return `${basePath}.${subPath}` as JoinPath<Base, Sub>
104
104
  }
105
105
 
106
106
  export function filterErrorsForPath(errors: ErrorBag, path: string): ErrorBag {
107
107
  // Handle empty path - return all errors
108
108
  if (!path) {
109
- return errors;
109
+ return errors
110
110
  }
111
111
 
112
- const pathPrefix = `${path}.`;
113
- const filteredPropertyErrors: Record<string, ValidationErrors> =
114
- Object.fromEntries(
115
- Object.entries(errors.propertyErrors)
116
- .filter(([errorPath]) => {
117
- return errorPath.startsWith(pathPrefix);
118
- })
119
- .map(([errorPath, errorMessages]) => [
120
- errorPath.slice(pathPrefix.length),
121
- errorMessages,
122
- ]),
123
- );
112
+ const pathPrefix = `${path}.`
113
+ const filteredPropertyErrors: Record<string, ValidationErrors> = Object.fromEntries(
114
+ Object.entries(errors.propertyErrors)
115
+ .filter(([errorPath]) => {
116
+ return errorPath.startsWith(pathPrefix)
117
+ })
118
+ .map(([errorPath, errorMessages]) => [
119
+ errorPath.slice(pathPrefix.length),
120
+ errorMessages,
121
+ ]),
122
+ )
124
123
 
125
124
  return {
126
125
  general: errors.general, // Keep general errors
127
126
  propertyErrors: filteredPropertyErrors,
128
- };
127
+ }
129
128
  }