srcdev-nuxt-forms 0.0.23 → 0.2.0

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.
Files changed (64) hide show
  1. package/.prettierrc +2 -1
  2. package/LICENSE +21 -0
  3. package/assets/styles/forms/index.css +1 -0
  4. package/assets/styles/forms/themes/_error.css +9 -0
  5. package/assets/styles/forms/themes/_ghost.css +11 -0
  6. package/assets/styles/forms/themes/_primary.css +11 -1
  7. package/assets/styles/forms/themes/_secondary.css +13 -0
  8. package/assets/styles/forms/themes/_success.css +12 -0
  9. package/assets/styles/forms/themes/_tertiary.css +11 -0
  10. package/assets/styles/forms/themes/_warning.css +11 -0
  11. package/assets/styles/forms/themes/index.css +5 -0
  12. package/assets/styles/forms/utils/_a11y.css +5 -0
  13. package/assets/styles/forms/utils/index.css +1 -0
  14. package/assets/styles/forms/variables/_theme.css +56 -2
  15. package/assets/styles/variables/colors/_gray.css +1 -0
  16. package/assets/styles/variables/colors/_orange.css +1 -1
  17. package/assets/styles/variables/colors/_red.css +1 -1
  18. package/components/forms/c12/prop-validators/index.ts +13 -0
  19. package/components/forms/c12/utils.ts +14 -0
  20. package/components/forms/c12/validation-patterns/en.json +13 -1
  21. package/components/forms/form-errors/InputError.vue +132 -0
  22. package/components/forms/input-button/InputButtonCore.vue +370 -0
  23. package/components/forms/input-button/variants/InputButtonConfirm.vue +78 -0
  24. package/components/forms/input-button/variants/InputButtonSubmit.vue +74 -0
  25. package/components/forms/input-checkbox/InputCheckboxCore.vue +407 -0
  26. package/components/forms/input-checkbox/InputCheckboxWithLabel.vue +125 -0
  27. package/components/forms/input-checkbox/variants/MultipleCheckboxes.vue +194 -0
  28. package/components/forms/input-checkbox/variants/SingleCheckbox.vue +157 -0
  29. package/components/forms/input-radio/InputRadioCore.vue +226 -0
  30. package/components/forms/input-radio/InputRadioWithLabel.vue +118 -0
  31. package/components/forms/input-radio/variants/MultipleRadio.vue +183 -0
  32. package/components/forms/input-radio/variants/SingleRadio.vue +131 -0
  33. package/components/forms/input-range/InputRangeCore.vue +171 -0
  34. package/components/forms/input-range/variants/InputRangeDefault.vue +131 -0
  35. package/components/forms/input-text/InputTextCore.vue +115 -79
  36. package/components/forms/input-text/variants/material/InputEmailMaterial.vue +72 -0
  37. package/components/forms/input-text/variants/material/InputPasswordMaterial.vue +114 -0
  38. package/components/forms/input-text/variants/material/InputTextMaterial.vue +68 -0
  39. package/components/forms/input-text/variants/material/InputTextMaterialCore.vue +313 -0
  40. package/components/forms/input-textarea/InputTextareaCore.vue +170 -0
  41. package/components/forms/input-textarea/variants/material/InputTextareaMaterial.vue +75 -0
  42. package/components/forms/input-textarea/variants/material/InputTextareaMaterialCore.vue +290 -0
  43. package/components/forms/ui/FormField.vue +7 -2
  44. package/components/forms/ui/FormWrapper.vue +2 -2
  45. package/components/ui/content-grid/ContentGrid.vue +85 -0
  46. package/composables/useErrorMessages.ts +21 -9
  47. package/composables/useFormControl.ts +171 -41
  48. package/layouts/default.vue +28 -3
  49. package/nuxt.config.ts +26 -3
  50. package/package.json +9 -6
  51. package/pages/forms/examples/buttons/index.vue +155 -0
  52. package/pages/forms/examples/material/text-fields.vue +372 -0
  53. package/pages/index.vue +2 -70
  54. package/pages/limit-text.vue +43 -0
  55. package/server/api/places/list.get.ts +23 -0
  56. package/server/api/textFields.post.ts +37 -0
  57. package/server/api/utils/index.get.ts +20 -0
  58. package/server/data/places/cities.json +37 -0
  59. package/server/data/places/countries.json +55 -0
  60. package/server/data/utils/title.json +49 -0
  61. package/types/types.forms.ts +38 -13
  62. package/types/types.places.ts +8 -0
  63. package/components/forms/input-text/InputTextField.vue +0 -22
  64. package/components/forms/input-text/variants/InputTextMaterial.vue +0 -192
@@ -1,31 +1,38 @@
1
- import type { IFormData, IFieldsInitialState, ICustomErrorMessage, ICustomErrorMessagesArr } from "@/types/types.forms";
1
+ import type { IFormData, IFieldsInitialState, IFormFieldC12, IApiErrorMessages, ICustomErrorMessage, IErrorMessagesArr } from '@/types/types.forms';
2
+ import { formFieldC12 } from '@/components/forms/c12/utils';
2
3
 
3
- export function useFormControl(fieldsInitialState: IFieldsInitialState | Ref<IFieldsInitialState | null>) {
4
+ // export function useFormControl(name: string = '') {
5
+ export function useFormControl(name: string = '') {
4
6
  let savedInitialState = {};
5
7
 
6
8
  const formData = ref<IFormData>({
7
9
  data: {} as IFieldsInitialState,
8
10
  validityState: {},
11
+ dirtyFields: {},
12
+ focusedField: '',
9
13
  isPending: false,
10
14
  errorCount: 0,
11
- customErrorMessages: {},
15
+ errorMessages: {},
16
+ formFieldsC12: {},
12
17
  hasCustomErrorMessages: false,
13
18
  formIsValid: false,
14
- showErrors: false,
15
- submitSuccess: false
19
+ submitAttempted: false,
20
+ submitDisabled: false,
21
+ submitSuccess: false,
22
+ displayErrorMessages: false,
16
23
  });
17
24
 
18
- const initValidationState = async () => {
25
+ const initValidationState = async (fieldsInitialState: IFieldsInitialState | Ref<IFieldsInitialState | null>) => {
19
26
  const fields = Object.keys(fieldsInitialState.value || {});
20
- const state = fields.reduce((acc, field) => {
21
- acc[field] = false;
22
- return acc;
27
+ const state = fields.reduce((accumulatedFields, field) => {
28
+ accumulatedFields[field] = false;
29
+ return accumulatedFields;
23
30
  }, {} as Record<string, boolean>);
24
31
  formData.value.validityState = state;
25
32
  };
26
33
 
27
- const initFormData = async () => {
28
- await initValidationState();
34
+ const initFormData = async (fieldsInitialState: IFieldsInitialState | Ref<IFieldsInitialState | null>) => {
35
+ initValidationState(fieldsInitialState);
29
36
 
30
37
  if (fieldsInitialState !== null) {
31
38
  savedInitialState = toRaw(fieldsInitialState.value) as IFieldsInitialState;
@@ -34,17 +41,46 @@ export function useFormControl(fieldsInitialState: IFieldsInitialState | Ref<IFi
34
41
  return;
35
42
  };
36
43
 
37
- const getErrorCount = async () => {
44
+ const initFormFieldsC12 = (name: string, formFieldC12: IFormFieldC12) => {
45
+ formData.value.formFieldsC12[name] = formFieldC12;
46
+ return;
47
+ };
48
+
49
+ const updatePreviousValues = () => {
50
+ Object.keys(formData.value.data).forEach((key) => {
51
+ formData.value.formFieldsC12[key].previousValue = formData.value.data[key];
52
+ });
53
+ };
54
+
55
+ const getErrorCount = async (updateState: boolean = false) => {
38
56
  await nextTick();
39
57
 
40
58
  const errorCount = Object.values(formData.value.validityState).filter((value) => !value).length;
41
59
  formData.value.errorCount = errorCount;
42
60
  formData.value.formIsValid = errorCount === 0;
61
+
62
+ if (updateState) {
63
+ formData.value.submitDisabled = true;
64
+ formData.value.displayErrorMessages = formData.value.errorCount > 0;
65
+ formData.value.submitAttempted = true;
66
+ }
67
+
68
+ if (formData.value.submitDisabled) {
69
+ formData.value.submitDisabled = !formData.value.formIsValid;
70
+ }
71
+
72
+ // update fieldHasError ref
73
+ // if (typeof formData.value!.formFieldsC12[name] !== 'undefined') {
74
+ // fieldHasError.value = formData.value!.submitAttempted && !formData.value!.formFieldsC12[name].isValid;
75
+ // } else {
76
+ // fieldHasError.value = false;
77
+ // }
78
+
43
79
  return formData.value.errorCount;
44
80
  };
45
81
 
46
82
  // Function to count items with "useCustomError" set to true
47
- const countItemsWithCustomError = (obj: ICustomErrorMessagesArr) => {
83
+ const countItemsWithCustomError = (obj: IErrorMessagesArr) => {
48
84
  let count = 0;
49
85
 
50
86
  for (const key in obj) {
@@ -59,44 +95,115 @@ export function useFormControl(fieldsInitialState: IFieldsInitialState | Ref<IFi
59
95
  /*
60
96
  * Useage:
61
97
  *
62
- * const { updateCustomErrors } = useFormControl();
98
+ * const { updateErrorMessages } = useFormControl();
63
99
  *
64
100
  * Add/Update entry
65
101
  * const sampleCustomErrorEmail = {
66
102
  * useCustomError: true,
67
103
  * message: "This is a sample custom error for error EMAIL",
68
104
  * };
69
- * updateCustomErrors("email", sampleCustomErrorEmail);
105
+ * updateErrorMessages("email", sampleCustomErrorEmail);
70
106
  */
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
- };
107
+ const updateErrorMessages = async (name: string, message: string = '', valid: boolean = false) => {
108
+ if (!valid) {
109
+ // formData.value.validityState[name] = valid;
110
+ // formData.value.errorMessages[name] = {
111
+ // useCustomError: true,
112
+ // message,
113
+ // };
114
+
115
+ formData.value.formFieldsC12[name].useCustomError = true;
116
+
117
+ // if (typeof message === 'string') {
118
+ // formData.value.formFieldsC12[name].customErrors = message;
119
+ // } else if (typeof message === 'object') {
120
+ // formData.value.formFieldsC12[name].customErrors = message;
121
+ // }
122
+
123
+ formData.value.formFieldsC12[name].customErrors = message;
124
+ formData.value.formFieldsC12[name].isValid = valid;
125
+
126
+ // formData.value.errorMessages[name].useCustomError = true;
127
+ // formData.value.errorMessages[name].message = message;
78
128
  }
79
- formData.value.hasCustomErrorMessages = countItemsWithCustomError(formData.value.customErrorMessages) > 0;
129
+ formData.value.hasCustomErrorMessages = countItemsWithCustomError(formData.value.errorMessages) > 0;
80
130
  };
81
131
 
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;
132
+ const useApiErrors = async (errors: IApiErrorMessages) => {
133
+ // Object.keys(errors).forEach((key) => {
134
+ // updateErrorMessages(key, errors[key]);
135
+ // });
136
+
137
+ for (const [key, message] of Object.entries(errors)) {
138
+ // console.log(`${key}: ${message}`);
139
+ updateErrorMessages(key, message);
140
+ }
89
141
  };
90
142
 
91
- const showErrors = computed(() => {
92
- return formData.value.errorCount > 0 && formData.value.isPending;
93
- });
143
+ // const resetForm = () => {
144
+ // console.log('resetForm()');
145
+ // formData.value.data = toRaw(fieldsInitialState.value) as IFieldsInitialState;
146
+ // formData.value.validityState = {};
147
+ // formData.value.errorCount = 0;
148
+ // formData.value.isPending = false;
149
+ // formData.value.errorMessages = {};
150
+ // formData.value.formIsValid = false;
151
+ // };
152
+
153
+ const fieldIsDirty = (name: string) => {
154
+ if (typeof formData.value.formFieldsC12[name] !== 'undefined') {
155
+ return formData.value.formFieldsC12[name].isDirty;
156
+ } else {
157
+ return false;
158
+ }
159
+ };
160
+
161
+ // const fieldHasError = (name: string) => {
162
+ // const currentValidityState = formData.value.validityState[name];
163
+
164
+ // if (formData.value.submitAttempted) {
165
+ // return currentValidityState;
166
+ // }
167
+ // return false;
168
+ // };
169
+
170
+ // const fieldHasError = computed({
171
+ // // getter
172
+ // get() {
173
+ // console.log(`fieldHasError getter: ${name}`);
174
+ // if (typeof formData.value!.formFieldsC12[name] !== 'undefined') {
175
+ // return !formData.value!.formFieldsC12[name].isValid;
176
+ // }
177
+ // return formData.value.validityState[name];
178
+ // },
179
+ // // setter
180
+ // set(newValue) {
181
+ // if (formData.value.submitAttempted) {
182
+ // return newValue;
183
+ // }
184
+ // return false;
185
+ // },
186
+ // });
187
+
188
+ // const fieldHasError = ref(false);
94
189
 
95
190
  const formIsValid = computed(() => {
96
- return formData.value.errorCount === 0;
191
+ return formData.value.formIsValid;
192
+ });
193
+
194
+ const submitDisabled = computed(() => {
195
+ return formData.value.submitDisabled;
97
196
  });
98
197
 
99
198
  // Keep an eye on this for performance issue
199
+
200
+ // const updateFieldValidity = (name: string, valid: boolean) => {
201
+ // console.log(`updateFieldValidity: name:${name} - valid:${valid}`);
202
+ // console.log(formData.value);
203
+ // // formData.value.formFieldsC12[name].isValid = valid;
204
+ // formData.value.validityState[name] = valid;
205
+ // };
206
+
100
207
  watch(
101
208
  () => formData.value.validityState,
102
209
  () => {
@@ -105,12 +212,35 @@ export function useFormControl(fieldsInitialState: IFieldsInitialState | Ref<IFi
105
212
  { deep: true }
106
213
  );
107
214
 
108
- // watch(
109
- // () => savedInitialState,
110
- // () => {
111
- // console.log("savedInitialState UPDATED", savedInitialState);
112
- // }
113
- // );
215
+ watch(
216
+ () => formData.value.formFieldsC12,
217
+ () => {
218
+ formData.value.formFieldsC12;
219
+ },
220
+ { deep: true }
221
+ );
222
+
223
+ watch(
224
+ () => formData.value.isPending,
225
+ (newValue, oldValue) => {
226
+ if (newValue) {
227
+ updatePreviousValues();
228
+ }
229
+ }
230
+ );
114
231
 
115
- return { formData, initFormData, getErrorCount, updateCustomErrors, resetForm, showErrors, formIsValid };
232
+ return {
233
+ formData,
234
+ initFormData,
235
+ initFormFieldsC12,
236
+ getErrorCount,
237
+ updateErrorMessages,
238
+ // resetForm,
239
+ formIsValid,
240
+ submitDisabled,
241
+ useApiErrors,
242
+ // fieldHasError,
243
+ fieldIsDirty,
244
+ // updateFieldValidity,
245
+ };
116
246
  }
@@ -1,10 +1,18 @@
1
1
  <template>
2
2
  <div class="page-layout">
3
3
  <div>
4
- <h1>Header</h1>
4
+ <h1><NuxtLink to="/">Home</NuxtLink></h1>
5
+ <ul class="flex-group">
6
+ <li>
7
+ <NuxtLink to="/forms/examples/material/text-fields">Material UI text fields</NuxtLink>
8
+ </li>
9
+ <li>
10
+ <NuxtLink to="/forms/examples/buttons">Buttons</NuxtLink>
11
+ </li>
12
+ </ul>
5
13
  </div>
6
14
 
7
- <div>
15
+ <div class="page-layout-content">
8
16
  <slot name="layout-content"></slot>
9
17
  </div>
10
18
 
@@ -20,7 +28,7 @@ useHead({
20
28
  class: 'body-default',
21
29
  id: 'body',
22
30
  },
23
- })
31
+ });
24
32
  </script>
25
33
 
26
34
  <style lang="css">
@@ -28,4 +36,21 @@ useHead({
28
36
  display: grid;
29
37
  grid-template-rows: auto 1fr auto;
30
38
  }
39
+
40
+ .page-layout-content {
41
+ container: content / inline-size;
42
+ }
43
+
44
+ .flex-group {
45
+ align-items: flex-start;
46
+ display: flex;
47
+ flex-wrap: wrap;
48
+ gap: 24px;
49
+ margin-bottom: 32px;
50
+ }
51
+
52
+ ul.flex-group {
53
+ list-style-type: none;
54
+ padding: 0;
55
+ }
31
56
  </style>
package/nuxt.config.ts CHANGED
@@ -1,20 +1,43 @@
1
1
  // https://nuxt.com/docs/api/configuration/nuxt-config
2
- import { createResolver } from '@nuxt/kit'
3
- const { resolve } = createResolver(import.meta.url)
2
+ import { createResolver } from '@nuxt/kit';
3
+ const { resolve } = createResolver(import.meta.url);
4
4
 
5
5
  export default defineNuxtConfig({
6
6
  devtools: { enabled: true },
7
+
8
+ app: {
9
+ head: {
10
+ htmlAttrs: {
11
+ lang: 'en',
12
+ },
13
+ titleTemplate: '%s - Website name',
14
+ meta: [{ charset: 'utf-8' }, { name: 'viewport', content: 'width=device-width, initial-scale=1' }],
15
+ },
16
+ pageTransition: {
17
+ name: 'page',
18
+ mode: 'out-in',
19
+ },
20
+ layoutTransition: {
21
+ name: 'layout',
22
+ mode: 'out-in',
23
+ },
24
+ },
7
25
  css: [resolve('./assets/styles/main.css')],
26
+
8
27
  runtimeConfig: {
9
28
  public: {
10
29
  validatorLocale: 'en-GB',
11
30
  },
12
31
  },
13
32
 
33
+ modules: ['@nuxt/icon'],
34
+
14
35
  components: [
15
36
  {
16
37
  path: './components',
17
38
  pathPrefix: false,
18
39
  },
19
40
  ],
20
- })
41
+
42
+ compatibilityDate: '2024-07-13',
43
+ });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "srcdev-nuxt-forms",
3
3
  "type": "module",
4
- "version": "0.0.23",
4
+ "version": "0.2.0",
5
5
  "main": "./nuxt.config.ts",
6
6
  "scripts": {
7
7
  "reinstall": "rm -rf node_modules && npm install",
@@ -14,10 +14,13 @@
14
14
  "release": "release-it"
15
15
  },
16
16
  "devDependencies": {
17
- "@nuxt/eslint-config": "^0.3.13",
18
- "eslint": "^9.5.0",
19
- "nuxt": "^3.12.2",
20
- "release-it": "^17.4.0",
21
- "typescript": "^5.5.2"
17
+ "@iconify-json/material-symbols": "^1.1.88",
18
+ "@iconify-json/radix-icons": "^1.1.15",
19
+ "@nuxt/eslint-config": "^0.5.0",
20
+ "@nuxt/icon": "^1.4.5",
21
+ "eslint": "^9.9.0",
22
+ "nuxt": "^3.12.4",
23
+ "release-it": "^17.6.0",
24
+ "typescript": "^5.5.4"
22
25
  }
23
26
  }
@@ -0,0 +1,155 @@
1
+ <template>
2
+ <div>
3
+ <NuxtLayout name="default">
4
+ <template #layout-content>
5
+ <div>
6
+ <h1>Example buttons</h1>
7
+ <p>Primary submit</p>
8
+
9
+ <p>Themes switcher</p>
10
+ <ul class="flex-group">
11
+ <li>
12
+ <InputButtonSubmit type="button" @click.stop.prevent="swapTheme('primary')" :is-pending="false" button-text="Primary" theme="primary" size="normal" />
13
+ </li>
14
+ <li>
15
+ <InputButtonSubmit type="button" @click.stop.prevent="swapTheme('secondary')" :is-pending="false" button-text="Secondary" theme="secondary" size="normal" />
16
+ </li>
17
+ <li>
18
+ <InputButtonSubmit type="button" @click.stop.prevent="swapTheme('tertiary')" :is-pending="false" button-text="Tertiary" theme="tertiary" size="normal" />
19
+ </li>
20
+ <li>
21
+ <InputButtonSubmit type="button" @click.stop.prevent="swapTheme('warning')" :is-pending="false" button-text="Warning" theme="warning" size="normal" />
22
+ </li>
23
+ <li>
24
+ <InputButtonSubmit type="button" @click.stop.prevent="swapTheme('success')" :is-pending="false" button-text="Success" theme="success" size="normal" />
25
+ </li>
26
+ <li>
27
+ <InputButtonSubmit type="button" @click.stop.prevent="swapTheme('error')" :is-pending="false" button-text="Error" theme="error" size="normal" />
28
+ </li>
29
+ <li>
30
+ <InputButtonSubmit type="button" @click.stop.prevent="swapTheme('ghost')" :is-pending="false" button-text="Ghost" theme="ghost" size="normal" />
31
+ </li>
32
+ </ul>
33
+
34
+ <FormWrapper width="medium">
35
+ <template #default>
36
+ <form @submit.prevent="submitForm">
37
+ <div class="flex-group">
38
+ <InputButtonSubmit type="button" @click.stop.prevent="submitForm" :is-pending="false" button-text="Submit" :theme size="x-small" />
39
+
40
+ <InputButtonSubmit type="button" @click.stop.prevent="submitForm" :is-pending="false" button-text="Submit" :theme size="small" />
41
+
42
+ <InputButtonSubmit type="button" @click.stop.prevent="submitForm" :is-pending="false" button-text="Submit" :theme size="normal" />
43
+ <InputButtonSubmit type="button" @click.stop.prevent="submitForm" :is-pending="false" button-text="Submit" :theme size="medium" />
44
+ <InputButtonSubmit type="button" @click.stop.prevent="submitForm" :is-pending="false" button-text="Submit" :theme size="large" />
45
+ </div>
46
+
47
+ <div class="flex-group">
48
+ <InputButtonConfirm @click.stop.prevent="submitForm" :is-pending="false" button-text="Confirm" :theme size="x-small" />
49
+ <InputButtonConfirm @click.stop.prevent="submitForm" :is-pending="false" button-text="Confirm" :theme size="small" />
50
+ <InputButtonConfirm @click.stop.prevent="submitForm" :is-pending="false" button-text="Confirm" :theme size="normal" />
51
+ <InputButtonConfirm @click.stop.prevent="submitForm" :is-pending="false" button-text="Confirm" :theme size="medium" />
52
+ <InputButtonConfirm @click.stop.prevent="submitForm" :is-pending="false" button-text="Confirm" :theme size="large" />
53
+ </div>
54
+ <div class="flex-group">
55
+ <InputButtonCore @click.stop.prevent="submitForm" :is-pending="false" button-text="Submit" :theme size="x-small">
56
+ <template #iconOnly>
57
+ <Icon name="radix-icons:eye-none" class="icon" />
58
+ </template>
59
+ </InputButtonCore>
60
+
61
+ <InputButtonCore @click.stop.prevent="submitForm" :is-pending="false" button-text="Submit" :theme size="small">
62
+ <template #iconOnly>
63
+ <Icon name="radix-icons:eye-none" class="icon" />
64
+ </template>
65
+ </InputButtonCore>
66
+
67
+ <InputButtonCore @click.stop.prevent="submitForm" :is-pending="false" button-text="Submit" :theme size="normal">
68
+ <template #iconOnly>
69
+ <Icon name="radix-icons:eye-none" class="icon" />
70
+ </template>
71
+ </InputButtonCore>
72
+
73
+ <InputButtonCore @click.stop.prevent="submitForm" :is-pending="false" button-text="Submit" :theme size="medium">
74
+ <template #iconOnly>
75
+ <Icon name="radix-icons:eye-none" class="icon" />
76
+ </template>
77
+ </InputButtonCore>
78
+
79
+ <InputButtonCore @click.stop.prevent="submitForm" :is-pending="false" button-text="Submit" :theme size="large">
80
+ <template #iconOnly>
81
+ <Icon name="radix-icons:eye-none" class="icon" />
82
+ </template>
83
+ </InputButtonCore>
84
+ </div>
85
+ </form>
86
+ </template>
87
+ </FormWrapper>
88
+ </div>
89
+ </template>
90
+ </NuxtLayout>
91
+ </div>
92
+ </template>
93
+
94
+ <script setup lang="ts">
95
+ import type { IFieldsInitialState, IOptionsConfig } from '@/types/types.forms';
96
+
97
+ definePageMeta({
98
+ layout: false,
99
+ });
100
+
101
+ useHead({
102
+ title: 'Homepage',
103
+ meta: [{ name: 'description', content: 'Homepage' }],
104
+ bodyAttrs: {
105
+ class: '',
106
+ },
107
+ });
108
+
109
+ const theme = ref('primary');
110
+
111
+ const swapTheme = (newTheme: string) => {
112
+ theme.value = newTheme;
113
+ };
114
+
115
+ /*
116
+ * Setup forms
117
+ */
118
+ const fieldsInitialState = ref<IFieldsInitialState>({
119
+ emailAddress: '',
120
+ username: '',
121
+ password: '',
122
+ });
123
+
124
+ // Setup formData
125
+ const { formData, initFormData, getErrorCount, updateErrorMessages, formIsValid, submitDisabled, useApiErrors } = useFormControl();
126
+ await initFormData(fieldsInitialState);
127
+
128
+ const submitForm = async () => {
129
+ await getErrorCount(true);
130
+
131
+ if (formIsValid.value) {
132
+ formData.value.isPending = true;
133
+ console.log('Form is good - post it!');
134
+ // await useSleep(2000);
135
+ // formData.value.isPending = false;
136
+ } else {
137
+ console.warn('Form has errors');
138
+ }
139
+ };
140
+ </script>
141
+
142
+ <style lang="css">
143
+ .flex-group {
144
+ align-items: flex-start;
145
+ display: flex;
146
+ flex-wrap: wrap;
147
+ gap: 24px;
148
+ margin-bottom: 32px;
149
+ }
150
+
151
+ ul.flex-group {
152
+ list-style-type: none;
153
+ padding: 0;
154
+ }
155
+ </style>