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.
- package/.prettierrc +2 -1
- package/LICENSE +21 -0
- package/assets/styles/forms/index.css +1 -0
- package/assets/styles/forms/themes/_error.css +9 -0
- package/assets/styles/forms/themes/_ghost.css +11 -0
- package/assets/styles/forms/themes/_primary.css +11 -1
- package/assets/styles/forms/themes/_secondary.css +13 -0
- package/assets/styles/forms/themes/_success.css +12 -0
- package/assets/styles/forms/themes/_tertiary.css +11 -0
- package/assets/styles/forms/themes/_warning.css +11 -0
- package/assets/styles/forms/themes/index.css +5 -0
- package/assets/styles/forms/utils/_a11y.css +5 -0
- package/assets/styles/forms/utils/index.css +1 -0
- package/assets/styles/forms/variables/_theme.css +56 -2
- package/assets/styles/variables/colors/_gray.css +1 -0
- package/assets/styles/variables/colors/_orange.css +1 -1
- package/assets/styles/variables/colors/_red.css +1 -1
- package/components/forms/c12/prop-validators/index.ts +13 -0
- package/components/forms/c12/utils.ts +14 -0
- package/components/forms/c12/validation-patterns/en.json +13 -1
- package/components/forms/form-errors/InputError.vue +132 -0
- package/components/forms/input-button/InputButtonCore.vue +370 -0
- package/components/forms/input-button/variants/InputButtonConfirm.vue +78 -0
- package/components/forms/input-button/variants/InputButtonSubmit.vue +74 -0
- package/components/forms/input-checkbox/InputCheckboxCore.vue +407 -0
- package/components/forms/input-checkbox/InputCheckboxWithLabel.vue +125 -0
- package/components/forms/input-checkbox/variants/MultipleCheckboxes.vue +194 -0
- package/components/forms/input-checkbox/variants/SingleCheckbox.vue +157 -0
- package/components/forms/input-radio/InputRadioCore.vue +226 -0
- package/components/forms/input-radio/InputRadioWithLabel.vue +118 -0
- package/components/forms/input-radio/variants/MultipleRadio.vue +183 -0
- package/components/forms/input-radio/variants/SingleRadio.vue +131 -0
- package/components/forms/input-range/InputRangeCore.vue +171 -0
- package/components/forms/input-range/variants/InputRangeDefault.vue +131 -0
- package/components/forms/input-text/InputTextCore.vue +115 -79
- package/components/forms/input-text/variants/material/InputEmailMaterial.vue +72 -0
- package/components/forms/input-text/variants/material/InputPasswordMaterial.vue +114 -0
- package/components/forms/input-text/variants/material/InputTextMaterial.vue +68 -0
- package/components/forms/input-text/variants/material/InputTextMaterialCore.vue +313 -0
- package/components/forms/input-textarea/InputTextareaCore.vue +170 -0
- package/components/forms/input-textarea/variants/material/InputTextareaMaterial.vue +75 -0
- package/components/forms/input-textarea/variants/material/InputTextareaMaterialCore.vue +290 -0
- package/components/forms/ui/FormField.vue +7 -2
- package/components/forms/ui/FormWrapper.vue +2 -2
- package/components/ui/content-grid/ContentGrid.vue +85 -0
- package/composables/useErrorMessages.ts +21 -9
- package/composables/useFormControl.ts +171 -41
- package/layouts/default.vue +28 -3
- package/nuxt.config.ts +26 -3
- package/package.json +9 -6
- package/pages/forms/examples/buttons/index.vue +155 -0
- package/pages/forms/examples/material/text-fields.vue +372 -0
- package/pages/index.vue +2 -70
- package/pages/limit-text.vue +43 -0
- package/server/api/places/list.get.ts +23 -0
- package/server/api/textFields.post.ts +37 -0
- package/server/api/utils/index.get.ts +20 -0
- package/server/data/places/cities.json +37 -0
- package/server/data/places/countries.json +55 -0
- package/server/data/utils/title.json +49 -0
- package/types/types.forms.ts +38 -13
- package/types/types.places.ts +8 -0
- package/components/forms/input-text/InputTextField.vue +0 -22
- package/components/forms/input-text/variants/InputTextMaterial.vue +0 -192
|
@@ -1,31 +1,38 @@
|
|
|
1
|
-
import type { IFormData, IFieldsInitialState, ICustomErrorMessage,
|
|
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(
|
|
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
|
-
|
|
15
|
+
errorMessages: {},
|
|
16
|
+
formFieldsC12: {},
|
|
12
17
|
hasCustomErrorMessages: false,
|
|
13
18
|
formIsValid: false,
|
|
14
|
-
|
|
15
|
-
|
|
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((
|
|
21
|
-
|
|
22
|
-
return
|
|
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
|
-
|
|
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
|
|
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:
|
|
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 {
|
|
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
|
-
*
|
|
105
|
+
* updateErrorMessages("email", sampleCustomErrorEmail);
|
|
70
106
|
*/
|
|
71
|
-
const
|
|
72
|
-
if (
|
|
73
|
-
formData.value.validityState[name] = valid;
|
|
74
|
-
formData.value.
|
|
75
|
-
|
|
76
|
-
|
|
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.
|
|
129
|
+
formData.value.hasCustomErrorMessages = countItemsWithCustomError(formData.value.errorMessages) > 0;
|
|
80
130
|
};
|
|
81
131
|
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
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
|
|
92
|
-
|
|
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.
|
|
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
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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 {
|
|
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
|
}
|
package/layouts/default.vue
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="page-layout">
|
|
3
3
|
<div>
|
|
4
|
-
<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
|
|
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
|
-
"@
|
|
18
|
-
"
|
|
19
|
-
"nuxt": "^
|
|
20
|
-
"
|
|
21
|
-
"
|
|
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>
|