srcdev-nuxt-forms 0.0.12 → 0.0.14

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/.editorconfig ADDED
@@ -0,0 +1,12 @@
1
+ root = true
2
+
3
+ [*]
4
+ indent_size = 2
5
+ indent_style = space
6
+ end_of_line = lf
7
+ charset = utf-8
8
+ trim_trailing_whitespace = true
9
+ insert_final_newline = true
10
+
11
+ [*.md]
12
+ trim_trailing_whitespace = false
package/.eslintignore ADDED
@@ -0,0 +1,7 @@
1
+ node_modules
2
+ dist
3
+ .nuxt
4
+ .output
5
+ coverage
6
+ components.d.ts
7
+ nuxt.d.ts
package/.eslintrc.cjs ADDED
@@ -0,0 +1,12 @@
1
+ module.exports = {
2
+ "root": true,
3
+ "extends": [
4
+ "@nuxtjs/eslint-config-typescript",
5
+ "plugin:prettier/recommended"
6
+ ],
7
+ "rules": {
8
+ "vue/multi-word-component-names": "off",
9
+ "vue/no-multiple-template-root": "off",
10
+ "@typescript-eslint/no-unused-vars": "off"
11
+ }
12
+ };
package/.nuxtrc ADDED
@@ -0,0 +1 @@
1
+ typescript.includeWorkspace = true
package/.prettierrc ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "semi": false,
3
+ "singleQuote": true
4
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "$schema": "https://unpkg.com/release-it/schema/release-it.json",
3
+ "github": {
4
+ "release": true
5
+ }
6
+ }
@@ -0,0 +1,47 @@
1
+ import type { IFormData } from "@/types/types.forms";
2
+
3
+ export function useErrorMessage(name: string, formData: Ref<IFormData>) {
4
+ const defaultError = ref("");
5
+ const customErrorMessages = ref(toRaw(formData.value.customErrorMessages));
6
+
7
+ const hasCustomError = () => {
8
+ return customErrorMessages.value[name] !== undefined && customErrorMessages.value[name].useCustomError;
9
+ };
10
+
11
+ const errorMessage = computed(() => {
12
+ if (hasCustomError()) {
13
+ return customErrorMessages.value[name].message;
14
+ } else {
15
+ return defaultError.value;
16
+ }
17
+ });
18
+
19
+ const setDefaultError = (newDefaultError: string) => {
20
+ defaultError.value = newDefaultError;
21
+ };
22
+
23
+ const fieldHasError = computed(() => {
24
+ if (formData.value.isPending) {
25
+ if (hasCustomError()) {
26
+ return true;
27
+ } else if (Object.keys(formData.value.validityState).length > 0 && formData.value.validityState[name] !== undefined) {
28
+ return !formData.value.validityState[name];
29
+ }
30
+ return false;
31
+ }
32
+ });
33
+
34
+ const removeCustomError = (valid: boolean = false) => {
35
+ formData.value.validityState[name] = valid;
36
+ // await nextTick();
37
+ delete formData.value.customErrorMessages[name];
38
+ };
39
+
40
+ return {
41
+ hasCustomError,
42
+ errorMessage,
43
+ setDefaultError,
44
+ fieldHasError,
45
+ removeCustomError
46
+ };
47
+ }
@@ -0,0 +1,116 @@
1
+ import type { IFormData, IFieldsInitialState, ICustomErrorMessage, ICustomErrorMessagesArr } from "@/types/types.forms";
2
+
3
+ export function useFormControl(fieldsInitialState: IFieldsInitialState | Ref<IFieldsInitialState | null>) {
4
+ let savedInitialState = {};
5
+
6
+ const formData = ref<IFormData>({
7
+ data: {} as IFieldsInitialState,
8
+ validityState: {},
9
+ isPending: false,
10
+ errorCount: 0,
11
+ customErrorMessages: {},
12
+ hasCustomErrorMessages: false,
13
+ formIsValid: false,
14
+ showErrors: false,
15
+ submitSuccess: false
16
+ });
17
+
18
+ const initValidationState = async () => {
19
+ const fields = Object.keys(fieldsInitialState.value || {});
20
+ const state = fields.reduce((acc, field) => {
21
+ acc[field] = false;
22
+ return acc;
23
+ }, {} as Record<string, boolean>);
24
+ formData.value.validityState = state;
25
+ };
26
+
27
+ const initFormData = async () => {
28
+ await initValidationState();
29
+
30
+ if (fieldsInitialState !== null) {
31
+ savedInitialState = toRaw(fieldsInitialState.value) as IFieldsInitialState;
32
+ formData.value.data = fieldsInitialState as IFieldsInitialState;
33
+ }
34
+ return;
35
+ };
36
+
37
+ const getErrorCount = async () => {
38
+ await nextTick();
39
+
40
+ const errorCount = Object.values(formData.value.validityState).filter((value) => !value).length;
41
+ formData.value.errorCount = errorCount;
42
+ formData.value.formIsValid = errorCount === 0;
43
+ return formData.value.errorCount;
44
+ };
45
+
46
+ // Function to count items with "useCustomError" set to true
47
+ const countItemsWithCustomError = (obj: ICustomErrorMessagesArr) => {
48
+ let count = 0;
49
+
50
+ for (const key in obj) {
51
+ if (obj.hasOwnProperty(key) && obj[key].useCustomError === true) {
52
+ count++;
53
+ }
54
+ }
55
+
56
+ return count;
57
+ };
58
+
59
+ /*
60
+ * Useage:
61
+ *
62
+ * const { updateCustomErrors } = useFormControl();
63
+ *
64
+ * Add/Update entry
65
+ * const sampleCustomErrorEmail = {
66
+ * useCustomError: true,
67
+ * message: "This is a sample custom error for error EMAIL",
68
+ * };
69
+ * updateCustomErrors("email", sampleCustomErrorEmail);
70
+ */
71
+ const updateCustomErrors = (name: string, message: null | string = null, valid: boolean = false) => {
72
+ if (message !== null) {
73
+ formData.value.validityState[name] = valid;
74
+ formData.value.customErrorMessages[name] = {
75
+ useCustomError: true,
76
+ message
77
+ };
78
+ }
79
+ formData.value.hasCustomErrorMessages = countItemsWithCustomError(formData.value.customErrorMessages) > 0;
80
+ };
81
+
82
+ const resetForm = () => {
83
+ formData.value.data = toRaw(fieldsInitialState.value) as IFieldsInitialState;
84
+ formData.value.validityState = {};
85
+ formData.value.errorCount = 0;
86
+ formData.value.isPending = false;
87
+ formData.value.customErrorMessages = {};
88
+ formData.value.formIsValid = false;
89
+ };
90
+
91
+ const showErrors = computed(() => {
92
+ return formData.value.errorCount > 0 && formData.value.isPending;
93
+ });
94
+
95
+ const formIsValid = computed(() => {
96
+ return formData.value.errorCount === 0;
97
+ });
98
+
99
+ // Keep an eye on this for performance issue
100
+ watch(
101
+ () => formData.value.validityState,
102
+ () => {
103
+ getErrorCount();
104
+ },
105
+ { deep: true }
106
+ );
107
+
108
+ // watch(
109
+ // () => savedInitialState,
110
+ // () => {
111
+ // console.log("savedInitialState UPDATED", savedInitialState);
112
+ // }
113
+ // );
114
+
115
+ return { formData, initFormData, getErrorCount, updateCustomErrors, resetForm, showErrors, formIsValid };
116
+ }
@@ -0,0 +1,5 @@
1
+ const useSleep = (ms: number) => {
2
+ return new Promise((resolve) => setTimeout(resolve, ms));
3
+ };
4
+
5
+ export default useSleep;
package/nuxt.config.ts CHANGED
@@ -5,10 +5,10 @@ const { resolve } = createResolver(import.meta.url)
5
5
  export default defineNuxtConfig({
6
6
  devtools: { enabled: true },
7
7
  css: [resolve('./assets/styles/main.css')],
8
- // components: [
9
- // {
10
- // path: '~/components',
11
- // pathPrefix: false,
12
- // },
13
- // ],
8
+ components: [
9
+ {
10
+ path: '~/components',
11
+ pathPrefix: false,
12
+ },
13
+ ],
14
14
  })
package/package.json CHANGED
@@ -1,15 +1,8 @@
1
1
  {
2
2
  "name": "srcdev-nuxt-forms",
3
3
  "type": "module",
4
- "version": "0.0.12",
4
+ "version": "0.0.14",
5
5
  "main": "./nuxt.config.ts",
6
- "files": [
7
- "assets",
8
- "components",
9
- "layouts",
10
- "pages",
11
- "nuxt.config.ts"
12
- ],
13
6
  "scripts": {
14
7
  "dev": "nuxi dev",
15
8
  "build": "nuxt build",
package/pages/index.vue CHANGED
@@ -5,19 +5,19 @@
5
5
  <div>
6
6
  <h1>Sample form page</h1>
7
7
 
8
- <NuxtFormsScaffoldingFormWrapper width="medium">
8
+ <FormWrapper width="medium">
9
9
  <template #default>
10
10
  <form>
11
11
  <p>Form content</p>
12
- <NuxtFormsScaffoldingFormField width="wide" :has-gutter="true">
12
+ <InputField width="wide" :has-gutter="true">
13
13
  <template #default>
14
14
  <p>Input text</p>
15
- <NuxtFormsInputText />
15
+ <InputText />
16
16
  </template>
17
- </NuxtFormsScaffoldingFormField>
17
+ </InputField>
18
18
  </form>
19
19
  </template>
20
- </NuxtFormsScaffoldingFormWrapper>
20
+ </FormWrapper>
21
21
  </div>
22
22
  </template>
23
23
  </NuxtLayout>
package/tsconfig.json ADDED
@@ -0,0 +1,3 @@
1
+ {
2
+ "extends": "./.nuxt/tsconfig.json"
3
+ }
@@ -0,0 +1,76 @@
1
+ export interface IValidationPatterns {
2
+ pattern: string;
3
+ minlength: string;
4
+ maxlength: string;
5
+ hint: string;
6
+ }
7
+
8
+ export interface IOptionsConfig {
9
+ id: string;
10
+ name: string;
11
+ value: string;
12
+ label: string;
13
+ }
14
+
15
+ export interface IOptionsValueArr {
16
+ [key: string]: string | boolean | number | URL | object;
17
+ }
18
+
19
+ export interface IFieldsInitialState {
20
+ [key: string]: null | string | boolean | number | URL | object | IOptionsValueArr[];
21
+ }
22
+
23
+ export interface IValidityState {
24
+ badInput: boolean;
25
+ customError: boolean;
26
+ patternMismatch: boolean;
27
+ rangeOverflow: boolean;
28
+ rangeUnderflow: boolean;
29
+ stepMismatch: boolean;
30
+ tooLong: boolean;
31
+ tooShort: boolean;
32
+ typeMismatch: boolean;
33
+ valid: boolean;
34
+ valueMissing: boolean;
35
+ }
36
+
37
+ export interface IValidityStateArr {
38
+ [key: string]: {
39
+ badInput: boolean;
40
+ customError: boolean;
41
+ patternMismatch: boolean;
42
+ rangeOverflow: boolean;
43
+ rangeUnderflow: boolean;
44
+ stepMismatch: boolean;
45
+ tooLong: boolean;
46
+ tooShort: boolean;
47
+ typeMismatch: boolean;
48
+ valid: boolean;
49
+ valueMissing: boolean;
50
+ };
51
+ }
52
+
53
+ export interface IValidityStateArrShort {
54
+ [key: string]: boolean;
55
+ }
56
+
57
+ export interface ICustomErrorMessage {
58
+ useCustomError: boolean;
59
+ message: string;
60
+ }
61
+
62
+ export interface ICustomErrorMessagesArr {
63
+ [x: string]: ICustomErrorMessage;
64
+ }
65
+
66
+ export interface IFormData {
67
+ [x: string]: string | boolean | number | URL | object;
68
+ data: IFieldsInitialState;
69
+ validityState: IValidityStateArrShort;
70
+ isPending: boolean;
71
+ errorCount: number;
72
+ customErrorMessages: ICustomErrorMessagesArr;
73
+ formIsValid: boolean;
74
+ showErrors: boolean;
75
+ submitSuccess: boolean;
76
+ }