srcdev-nuxt-forms 0.2.0 → 1.0.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/assets/styles/brand/_brand.css +150 -0
- package/assets/styles/brand/_brand_dark.css +152 -0
- package/assets/styles/brand/_palette_dark.css +148 -0
- package/assets/styles/brand/_palette_light.css +148 -0
- package/assets/styles/brand/_typography.css +176 -0
- package/assets/styles/brand/index.css +1 -0
- package/assets/styles/forms/index.css +1 -2
- package/assets/styles/forms/themes/_default.css +3 -0
- package/assets/styles/forms/themes/_error.css +45 -11
- package/assets/styles/forms/themes/_ghost.css +42 -10
- package/assets/styles/forms/themes/_primary.css +42 -12
- package/assets/styles/forms/themes/_secondary.css +42 -12
- package/assets/styles/forms/themes/_success.css +42 -11
- package/assets/styles/forms/themes/_tertiary.css +42 -10
- package/assets/styles/forms/themes/_warning.css +42 -10
- package/assets/styles/forms/themes/index.css +1 -0
- package/assets/styles/forms/variables/_palette.css +104 -0
- package/assets/styles/forms/variables/_theme.css +1 -1
- package/assets/styles/forms/variables/index.css +2 -0
- package/assets/styles/main.css +2 -0
- package/assets/styles/scaffolding/_margin-helpers.css +308 -0
- package/assets/styles/scaffolding/_padding-helpers.css +308 -0
- package/assets/styles/scaffolding/_page.css +23 -0
- package/assets/styles/scaffolding/index.css +3 -0
- package/assets/styles/variables/colors/_blue.css +2 -2
- package/assets/styles/variables/colors/_gray.css +1 -1
- package/assets/styles/variables/colors/_green.css +2 -2
- package/assets/styles/variables/colors/_orange.css +2 -2
- package/assets/styles/variables/colors/_red.css +2 -2
- package/assets/styles/variables/colors/_yellow.css +1 -1
- package/components/forms/form-errors/InputError.vue +82 -37
- package/components/forms/input-button/InputButtonCore.vue +25 -104
- package/components/forms/input-checkbox/InputCheckboxCore.vue +37 -181
- package/components/forms/input-checkbox/InputCheckboxWithLabel.vue +42 -51
- package/components/forms/input-checkbox/variants/MultipleCheckboxes.vue +42 -69
- package/components/forms/input-checkbox/variants/SingleCheckbox.vue +126 -111
- package/components/forms/input-number/InputNumberCore.vue +184 -0
- package/components/forms/input-number/variants/InputNumberDefault.vue +155 -0
- package/components/forms/input-radio/InputRadiobuttonCore.vue +212 -0
- package/components/forms/input-radio/InputRadiobuttonWithLabel.vue +103 -0
- package/components/forms/input-radio/variants/MultipleRadiobuttons.vue +166 -0
- package/components/forms/input-range/InputRangeCore.vue +70 -88
- package/components/forms/input-range/variants/InputRangeDefault.vue +74 -46
- package/components/forms/input-text/InputTextCore.vue +141 -109
- package/components/forms/input-text/variants/material/InputPasswordWithLabel.vue +99 -0
- package/components/forms/input-text/variants/material/InputTextAsNumberWithLabel.vue +142 -0
- package/components/forms/input-text/variants/material/InputTextWithLabel.vue +125 -0
- package/components/forms/input-textarea/InputTextareaCore.vue +96 -105
- package/components/forms/input-textarea/variants/InputTextareaWithLabel.vue +106 -0
- package/components/scaffolding/footer/NavFooter.vue +62 -0
- package/composables/useApiRequest.ts +25 -0
- package/composables/useFormControl.ts +2 -0
- package/composables/useSleep.ts +2 -2
- package/composables/useStyleClassPassthrough.ts +30 -0
- package/composables/useZodValidation.ts +120 -0
- package/layouts/default.vue +21 -5
- package/package.json +13 -9
- package/pages/forms/examples/material/cssbattle.vue +60 -0
- package/pages/forms/examples/material/text-fields.vue +375 -153
- package/pages/index.vue +2 -2
- package/pages/typography.vue +83 -0
- package/server/data/places/cities.json +7 -1
- package/types/types.forms.ts +102 -0
- package/types/types.zodFormControl.ts +21 -0
- package/assets/styles/forms/utils/_a11y.css +0 -5
- package/assets/styles/forms/utils/index.css +0 -1
- package/components/forms/input-radio/InputRadioCore.vue +0 -226
- package/components/forms/input-radio/InputRadioWithLabel.vue +0 -118
- package/components/forms/input-radio/variants/MultipleRadio.vue +0 -183
- package/components/forms/input-radio/variants/SingleRadio.vue +0 -131
- package/components/forms/input-text/variants/material/InputEmailMaterial.vue +0 -72
- package/components/forms/input-text/variants/material/InputPasswordMaterial.vue +0 -114
- package/components/forms/input-text/variants/material/InputTextMaterial.vue +0 -68
- package/components/forms/input-text/variants/material/InputTextMaterialCore.vue +0 -313
- package/components/forms/input-textarea/variants/material/InputTextareaMaterial.vue +0 -75
- package/components/forms/input-textarea/variants/material/InputTextareaMaterialCore.vue +0 -290
- package/composables/useUpdateStyleClassPassthrough.ts +0 -29
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="input-checkbox-wrapper" :class="[size,
|
|
2
|
+
<div class="input-checkbox-wrapper" :data-form-theme="formTheme" :class="[size, checkboxAppearance, { error: fieldHasError }]">
|
|
3
3
|
<input
|
|
4
4
|
type="checkbox"
|
|
5
5
|
:true-value="trueValue"
|
|
6
6
|
:false-value="falseValue"
|
|
7
7
|
:id
|
|
8
8
|
:name
|
|
9
|
-
:required="
|
|
9
|
+
:required="required && !multipleOptions"
|
|
10
10
|
:value="trueValue"
|
|
11
|
-
:class="['input-checkbox-core',
|
|
12
|
-
v-model="modelValue
|
|
11
|
+
:class="['input-checkbox-core', size, checkboxAppearance, { error: fieldHasError }]"
|
|
12
|
+
v-model="modelValue"
|
|
13
13
|
ref="inputField"
|
|
14
14
|
/>
|
|
15
15
|
<div v-if="checkboxAppearance === 'with-decorator'" :class="['input-checkbox-decorator', size, checkboxStyle]">
|
|
@@ -21,13 +21,8 @@
|
|
|
21
21
|
|
|
22
22
|
<script setup lang="ts">
|
|
23
23
|
import propValidators from '../c12/prop-validators';
|
|
24
|
-
|
|
25
|
-
import type { InpuTextC12, IFormFieldC12, IFormData } from '@/types/types.forms';
|
|
26
|
-
// import { validationConfig } from '@/components/forms/c12/validation-patterns';
|
|
27
|
-
|
|
28
|
-
const props = defineProps({
|
|
24
|
+
const { id, name, required, trueValue, falseValue, multipleOptions, theme, styleClassPassthrough, size, checkboxAppearance, checkboxStyle, fieldHasError } = defineProps({
|
|
29
25
|
id: {
|
|
30
|
-
// type: String as PropType<string>,
|
|
31
26
|
type: String,
|
|
32
27
|
required: true,
|
|
33
28
|
},
|
|
@@ -39,10 +34,6 @@ const props = defineProps({
|
|
|
39
34
|
type: Boolean,
|
|
40
35
|
value: false,
|
|
41
36
|
},
|
|
42
|
-
c12: {
|
|
43
|
-
type: Object as PropType<InpuTextC12>,
|
|
44
|
-
required: true,
|
|
45
|
-
},
|
|
46
37
|
trueValue: {
|
|
47
38
|
type: [String, Number, Boolean],
|
|
48
39
|
default: true,
|
|
@@ -55,10 +46,6 @@ const props = defineProps({
|
|
|
55
46
|
type: Boolean,
|
|
56
47
|
default: false,
|
|
57
48
|
},
|
|
58
|
-
styleClassPassthrough: {
|
|
59
|
-
type: String,
|
|
60
|
-
default: '',
|
|
61
|
-
},
|
|
62
49
|
theme: {
|
|
63
50
|
type: String as PropType<string>,
|
|
64
51
|
default: 'primary',
|
|
@@ -87,162 +74,57 @@ const props = defineProps({
|
|
|
87
74
|
return propValidators.checkboxStyle.includes(value);
|
|
88
75
|
},
|
|
89
76
|
},
|
|
77
|
+
fieldHasError: {
|
|
78
|
+
type: Boolean,
|
|
79
|
+
default: false,
|
|
80
|
+
},
|
|
81
|
+
styleClassPassthrough: {
|
|
82
|
+
type: Array as PropType<string[]>,
|
|
83
|
+
default: () => [],
|
|
84
|
+
},
|
|
90
85
|
});
|
|
91
86
|
|
|
92
|
-
const
|
|
93
|
-
const hasLeftContent = computed(() => slots.left !== undefined);
|
|
94
|
-
const hasRightContent = computed(() => slots.right !== undefined);
|
|
87
|
+
const { elementClasses, updateElementClasses } = useStyleClassPassthrough(styleClassPassthrough);
|
|
95
88
|
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
// const updateFocus = (name: string, isFocused: boolean) => {
|
|
99
|
-
// modelValue.value.focusedField = isFocused ? name : '';
|
|
100
|
-
// };
|
|
101
|
-
|
|
102
|
-
// const isFocused = computed(() => {
|
|
103
|
-
// return modelValue.value.focusedField == name.value;
|
|
104
|
-
// });
|
|
105
|
-
|
|
106
|
-
const name = computed(() => {
|
|
107
|
-
return props.name !== null ? props.name : props.id;
|
|
89
|
+
const formTheme = computed(() => {
|
|
90
|
+
return fieldHasError ? 'error' : theme;
|
|
108
91
|
});
|
|
109
92
|
|
|
110
|
-
|
|
93
|
+
const modelValue = defineModel<any>();
|
|
111
94
|
|
|
112
|
-
// const componentValidation = validationConfig[validatorLocale.value][props.validation];
|
|
113
95
|
const inputField = ref<HTMLInputElement | null>(null);
|
|
114
96
|
|
|
115
|
-
const isArray = Array.isArray(modelValue.value
|
|
97
|
+
const isArray = Array.isArray(modelValue.value);
|
|
116
98
|
|
|
117
99
|
const isChecked = computed(() => {
|
|
118
100
|
if (isArray) {
|
|
119
|
-
|
|
120
|
-
const keyValue = modelValue.value.data[name.value] as any[];
|
|
121
|
-
const isValid = keyValue.indexOf(props.trueValue) > -1;
|
|
122
|
-
// modelValue.value.validityState[name.value] = isValid;
|
|
123
|
-
return isValid;
|
|
124
|
-
}
|
|
125
|
-
} else {
|
|
126
|
-
const isValid = modelValue.value.data[name.value] === props.trueValue;
|
|
127
|
-
modelValue.value.validityState[name.value] = isValid;
|
|
128
|
-
return isValid;
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
const isFocussed = ref(false);
|
|
133
|
-
|
|
134
|
-
// watch(isChecked, () => {
|
|
135
|
-
// console.log('inputField.value', inputField.value?.validity);
|
|
136
|
-
// });
|
|
137
|
-
|
|
138
|
-
// const fieldIsDirty = computed(() => {
|
|
139
|
-
// return modelValue.value!.formFieldsC12[name.value].isDirty;
|
|
140
|
-
// });
|
|
141
|
-
const fieldHasError = computed(() => {
|
|
142
|
-
return modelValue.value!.submitAttempted && !modelValue.value!.formFieldsC12[name.value].isValid;
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
// const { updateFieldValidity } = useFormControl(name.value);
|
|
146
|
-
|
|
147
|
-
if (
|
|
148
|
-
// !isArray &&
|
|
149
|
-
modelValue.value.formFieldsC12[name.value] === undefined
|
|
150
|
-
) {
|
|
151
|
-
const formFieldC12 = <IFormFieldC12>{
|
|
152
|
-
label: props.c12.label,
|
|
153
|
-
placeholder: props.c12.placeholder,
|
|
154
|
-
errorMessage: props.c12.errorMessage,
|
|
155
|
-
useCustomError: false,
|
|
156
|
-
customErrors: {},
|
|
157
|
-
isValid: false,
|
|
158
|
-
isDirty: false,
|
|
159
|
-
type: isArray ? 'array' : 'string',
|
|
160
|
-
previousValue: null,
|
|
161
|
-
};
|
|
162
|
-
modelValue.value.formFieldsC12[name.value] = formFieldC12;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// const { initFormFieldsC12 } = useFormControl();
|
|
166
|
-
// initFormFieldsC12(props.name, formFieldC12);
|
|
167
|
-
|
|
168
|
-
const fieldValue = computed(() => {
|
|
169
|
-
return modelValue.value.data[name.value];
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
watch(fieldValue, () => {
|
|
173
|
-
if (isArray) {
|
|
174
|
-
// console.log(Object.values(modelValue.value.data[name.value] ?? []).length);
|
|
175
|
-
modelValue.value.validityState[name.value] = Object.values(modelValue.value.data[name.value] ?? []).length > 0;
|
|
176
|
-
modelValue.value!.formFieldsC12[name.value].isValid = modelValue.value.validityState[name.value];
|
|
177
|
-
// console.log(Object.keys(modelValue.value.data[name.value]).length);
|
|
178
|
-
// if (name.value in modelValue.value.data) {
|
|
179
|
-
// const keyValue = modelValue.value.data[name.value] as any[];
|
|
180
|
-
// const isValid = keyValue.indexOf(props.trueValue) > -1;
|
|
181
|
-
// modelValue.value.validityState[name.value] = isValid;
|
|
182
|
-
// }
|
|
101
|
+
return modelValue.value.indexOf(trueValue) > -1;
|
|
183
102
|
} else {
|
|
184
|
-
|
|
185
|
-
if (!modelValue.value!.formFieldsC12[name.value].isDirty) {
|
|
186
|
-
modelValue.value!.formFieldsC12[name.value].isDirty = modelValue.value.data[name.value] !== '';
|
|
187
|
-
}
|
|
188
|
-
modelValue.value!.formFieldsC12[name.value].isValid = inputField.value?.validity.valid ?? false;
|
|
189
|
-
modelValue.value!.validityState[name.value] = inputField.value?.validity.valid ?? false;
|
|
103
|
+
return modelValue.value === trueValue;
|
|
190
104
|
}
|
|
191
|
-
|
|
192
|
-
// if (modelValue.value!.formFieldsC12[name.value].useCustomError && modelValue.value.data[props.name] === modelValue.value.formFieldsC12[props.name].previousValue) {
|
|
193
|
-
// modelValue.value!.validityState[name.value] = false;
|
|
194
|
-
// modelValue.value!.formFieldsC12[name.value].isValid = false;
|
|
195
|
-
// modelValue.value.displayErrorMessages = true;
|
|
196
|
-
// }
|
|
197
105
|
});
|
|
198
|
-
|
|
199
|
-
// const isValid = () => {
|
|
200
|
-
// setTimeout(() => {
|
|
201
|
-
// modelValue.value!.validityState[name.value] = inputField.value?.validity.valid ?? false;
|
|
202
|
-
// modelValue.value!.formFieldsC12[name.value].isValid = inputField.value?.validity.valid ?? false;
|
|
203
|
-
// if (!modelValue.value!.formFieldsC12[name.value].isDirty) {
|
|
204
|
-
// modelValue.value!.formFieldsC12[name.value].isDirty = modelValue.value.data[name.value] !== '';
|
|
205
|
-
// }
|
|
206
|
-
// }, 0);
|
|
207
|
-
// };
|
|
208
|
-
|
|
209
|
-
// onMounted(() => {
|
|
210
|
-
// isValid();
|
|
211
|
-
// });
|
|
212
106
|
</script>
|
|
213
107
|
|
|
214
108
|
<style scoped lang="css">
|
|
215
109
|
.input-checkbox-wrapper {
|
|
216
110
|
--_checkbox-size: initial;
|
|
217
111
|
--_checkbox-border-radius: 4px;
|
|
218
|
-
--_form-theme: var(--theme-form-primary);
|
|
219
112
|
--_outline-width: var(--input-outline-width-thin);
|
|
220
|
-
--_border-width: var(--input-border-width-thin);
|
|
221
|
-
--_border-color: var(--_form-theme);
|
|
222
|
-
--_focus-colour: var(--theme-form-primary-focus);
|
|
113
|
+
--_border-width: var(--input-border-width-thin); /* --input-border-width-default / 2px */
|
|
223
114
|
|
|
224
115
|
display: grid;
|
|
225
|
-
grid-template-areas: '
|
|
226
|
-
|
|
227
|
-
&.theme-secondary {
|
|
228
|
-
--_form-theme: var(--theme-form-secondary);
|
|
229
|
-
--_focus-colour: var(--theme-form-secondary-focus);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
&.error {
|
|
233
|
-
--_form-theme: var(--theme-error);
|
|
234
|
-
}
|
|
116
|
+
grid-template-areas: 'element-stack';
|
|
235
117
|
|
|
236
118
|
&.with-decorator {
|
|
237
119
|
border-radius: var(--_checkbox-border-radius);
|
|
238
|
-
border: var(--_border-width) solid var(--
|
|
120
|
+
border: var(--_border-width) solid var(--theme-form-input-border);
|
|
239
121
|
height: var(--_checkbox-size);
|
|
240
122
|
width: var(--_checkbox-size);
|
|
241
123
|
|
|
242
124
|
&:has(.input-checkbox-core:focus-visible) {
|
|
243
|
-
--_border-
|
|
244
|
-
|
|
245
|
-
|
|
125
|
+
border: var(--_border-width) solid var(--theme-form-input-border-focus);
|
|
126
|
+
outline: var(--_outline-width) solid hsl(from var(--theme-form-input-outline-focus) h s 50%);
|
|
127
|
+
box-shadow: var(--theme-form-focus-box-shadow);
|
|
246
128
|
}
|
|
247
129
|
}
|
|
248
130
|
|
|
@@ -265,7 +147,8 @@ watch(fieldValue, () => {
|
|
|
265
147
|
|
|
266
148
|
.input-checkbox-decorator {
|
|
267
149
|
display: grid;
|
|
268
|
-
grid-area:
|
|
150
|
+
grid-area: element-stack;
|
|
151
|
+
background-color: var(--theme-form-checkbox-bg);
|
|
269
152
|
|
|
270
153
|
height: var(--_checkbox-size);
|
|
271
154
|
width: var(--_checkbox-size);
|
|
@@ -284,10 +167,9 @@ watch(fieldValue, () => {
|
|
|
284
167
|
grid-area: stack;
|
|
285
168
|
width: calc(var(--_checkbox-size) * 0.2);
|
|
286
169
|
height: calc(var(--_checkbox-size) * 0.45);
|
|
287
|
-
border-bottom: 3px solid var(--
|
|
288
|
-
border-right: 3px solid var(--
|
|
170
|
+
border-bottom: 3px solid var(--theme-form-checkbox-symbol);
|
|
171
|
+
border-right: 3px solid var(--theme-form-checkbox-symbol);
|
|
289
172
|
transform: rotate(45deg) translate(-1px, -1px);
|
|
290
|
-
/* transform: translate(-3px, 0px); */
|
|
291
173
|
opacity: 0;
|
|
292
174
|
transition: opacity 0.2s ease-in-out;
|
|
293
175
|
|
|
@@ -300,7 +182,7 @@ watch(fieldValue, () => {
|
|
|
300
182
|
grid-area: stack;
|
|
301
183
|
width: calc(var(--_checkbox-size) * 0.65);
|
|
302
184
|
height: 3px;
|
|
303
|
-
background-color: var(--
|
|
185
|
+
background-color: var(--theme-form-checkbox-symbol);
|
|
304
186
|
transform: rotate(45deg);
|
|
305
187
|
opacity: 0;
|
|
306
188
|
transition: opacity 0.2s ease-in-out;
|
|
@@ -319,7 +201,7 @@ watch(fieldValue, () => {
|
|
|
319
201
|
display: block;
|
|
320
202
|
width: calc(var(--_checkbox-size) * 0.65);
|
|
321
203
|
height: 3px;
|
|
322
|
-
background-color: var(--
|
|
204
|
+
background-color: var(--theme-form-checkbox-symbol);
|
|
323
205
|
transform: rotate(-90deg);
|
|
324
206
|
opacity: 0;
|
|
325
207
|
transition: opacity 0.2s ease-in-out;
|
|
@@ -345,8 +227,8 @@ watch(fieldValue, () => {
|
|
|
345
227
|
}
|
|
346
228
|
|
|
347
229
|
.input-checkbox-core {
|
|
348
|
-
grid-area:
|
|
349
|
-
border: var(--_border-width) solid var(--
|
|
230
|
+
grid-area: element-stack;
|
|
231
|
+
border: var(--_border-width) solid var(--theme-form-input-border);
|
|
350
232
|
height: var(--_checkbox-size);
|
|
351
233
|
width: var(--_checkbox-size);
|
|
352
234
|
|
|
@@ -364,12 +246,9 @@ watch(fieldValue, () => {
|
|
|
364
246
|
}
|
|
365
247
|
|
|
366
248
|
&:focus-visible {
|
|
367
|
-
border
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
&:focus {
|
|
371
|
-
border: var(--_border-width) solid var(--_form-theme);
|
|
372
|
-
outline: var(--_outline-width) solid hsl(from var(--_form-theme) h s 50%);
|
|
249
|
+
border: var(--_border-width) solid var(--theme-form-input-border);
|
|
250
|
+
outline: var(--_outline-width) solid hsl(from var(--theme-form-input-outline-focus) h s 50%);
|
|
251
|
+
box-shadow: var(--theme-form-focus-box-shadow);
|
|
373
252
|
}
|
|
374
253
|
|
|
375
254
|
&:checked::after {
|
|
@@ -379,29 +258,6 @@ watch(fieldValue, () => {
|
|
|
379
258
|
place-content: center;
|
|
380
259
|
font-size: calc(var(--_checkbox-size) * 0.75);
|
|
381
260
|
}
|
|
382
|
-
&.error {
|
|
383
|
-
/* border-color: var(--theme-error); */
|
|
384
|
-
border: var(--_border-width) solid var(--theme-error);
|
|
385
|
-
outline: var(--_outline-width) solid hsl(from var(--theme-error) h s 75%);
|
|
386
|
-
background-color: hsl(from var(--theme-error) h s 95%);
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
&.theme-secondary {
|
|
390
|
-
--_form-theme: var(--theme-form-secondary);
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
/* &:valid {
|
|
394
|
-
border-color: var(--theme-success);
|
|
395
|
-
}
|
|
396
|
-
&:invalid {
|
|
397
|
-
border-color: var(--theme-error);
|
|
398
|
-
}
|
|
399
|
-
&:not(:placeholder-shown):valid {
|
|
400
|
-
border-color: var(--theme-success);
|
|
401
|
-
}
|
|
402
|
-
&:not(:placeholder-shown):invalid {
|
|
403
|
-
border-color: var(--theme-error);
|
|
404
|
-
} */
|
|
405
261
|
}
|
|
406
262
|
}
|
|
407
263
|
</style>
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="input-checkbox-with-label" :class="[
|
|
3
|
-
<InputCheckboxCore :id :name :required
|
|
4
|
-
<label class="input-checkbox-label" :for="id">
|
|
2
|
+
<div class="input-checkbox-with-label" :class="[elementClasses, optionsLayout, { error: fieldHasError }]">
|
|
3
|
+
<InputCheckboxCore :id :name :required v-model="modelValue" :size :trueValue :falseValue :checkboxAppearance :checkboxStyle :fieldHasError :theme />
|
|
4
|
+
<label v-if="hasLabelContent" class="input-checkbox-label body-normal" :for="id">
|
|
5
|
+
<slot name="labelContent"></slot>
|
|
6
|
+
</label>
|
|
7
|
+
<label v-else class="input-checkbox-label body-normal-semibold" :for="id">{{ label }}</label>
|
|
5
8
|
</div>
|
|
6
9
|
</template>
|
|
7
10
|
|
|
8
11
|
<script setup lang="ts">
|
|
9
12
|
import propValidators from '../c12/prop-validators';
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
// import { validationConfig } from '@/components/forms/c12/validation-patterns';
|
|
13
|
-
|
|
14
|
-
const props = defineProps({
|
|
14
|
+
const { id, name, label, required, fieldHasError, trueValue, falseValue, size, checkboxAppearance, checkboxStyle, optionsLayout, styleClassPassthrough, theme } = defineProps({
|
|
15
15
|
id: {
|
|
16
|
-
// type: String as PropType<string>,
|
|
17
16
|
type: String,
|
|
18
17
|
required: true,
|
|
19
18
|
},
|
|
@@ -21,13 +20,17 @@ const props = defineProps({
|
|
|
21
20
|
type: String,
|
|
22
21
|
required: true,
|
|
23
22
|
},
|
|
23
|
+
label: {
|
|
24
|
+
type: String,
|
|
25
|
+
required: true,
|
|
26
|
+
},
|
|
24
27
|
required: {
|
|
25
28
|
type: Boolean,
|
|
26
|
-
|
|
29
|
+
default: false,
|
|
27
30
|
},
|
|
28
|
-
|
|
29
|
-
type:
|
|
30
|
-
|
|
31
|
+
fieldHasError: {
|
|
32
|
+
type: Boolean,
|
|
33
|
+
default: false,
|
|
31
34
|
},
|
|
32
35
|
trueValue: {
|
|
33
36
|
type: [String, Number, Boolean],
|
|
@@ -37,21 +40,6 @@ const props = defineProps({
|
|
|
37
40
|
type: [String, Number, Boolean],
|
|
38
41
|
default: false,
|
|
39
42
|
},
|
|
40
|
-
multipleOptions: {
|
|
41
|
-
type: Boolean,
|
|
42
|
-
default: false,
|
|
43
|
-
},
|
|
44
|
-
styleClassPassthrough: {
|
|
45
|
-
type: String,
|
|
46
|
-
default: '',
|
|
47
|
-
},
|
|
48
|
-
theme: {
|
|
49
|
-
type: String as PropType<string>,
|
|
50
|
-
default: 'primary',
|
|
51
|
-
validator(value: string) {
|
|
52
|
-
return propValidators.theme.includes(value);
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
43
|
size: {
|
|
56
44
|
type: String as PropType<string>,
|
|
57
45
|
default: 'medium',
|
|
@@ -73,49 +61,52 @@ const props = defineProps({
|
|
|
73
61
|
return propValidators.checkboxStyle.includes(value);
|
|
74
62
|
},
|
|
75
63
|
},
|
|
64
|
+
optionsLayout: {
|
|
65
|
+
type: String as PropType<string>,
|
|
66
|
+
default: 'equal-widths',
|
|
67
|
+
validator(value: string) {
|
|
68
|
+
return propValidators.optionsLayout.includes(value);
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
styleClassPassthrough: {
|
|
72
|
+
type: Array as PropType<string[]>,
|
|
73
|
+
default: () => [],
|
|
74
|
+
},
|
|
75
|
+
theme: {
|
|
76
|
+
type: String as PropType<string>,
|
|
77
|
+
default: 'primary',
|
|
78
|
+
validator(value: string) {
|
|
79
|
+
return propValidators.theme.includes(value);
|
|
80
|
+
},
|
|
81
|
+
},
|
|
76
82
|
});
|
|
77
83
|
|
|
78
84
|
const slots = useSlots();
|
|
79
|
-
const
|
|
80
|
-
const
|
|
85
|
+
const hasLabelContent = computed(() => slots.labelContent !== undefined);
|
|
86
|
+
const { elementClasses, updateElementClasses } = useStyleClassPassthrough(styleClassPassthrough);
|
|
81
87
|
|
|
82
|
-
const modelValue = defineModel()
|
|
83
|
-
const name = computed(() => {
|
|
84
|
-
return props.name !== null ? props.name : props.id;
|
|
85
|
-
});
|
|
86
|
-
const fieldHasError = computed(() => {
|
|
87
|
-
return modelValue.value!.submitAttempted && !modelValue.value!.formFieldsC12[name.value].isValid;
|
|
88
|
-
});
|
|
88
|
+
const modelValue = defineModel();
|
|
89
89
|
</script>
|
|
90
90
|
|
|
91
91
|
<style lang="css">
|
|
92
92
|
.input-checkbox-with-label {
|
|
93
|
-
--
|
|
94
|
-
--_border-width: var(--input-border-width-default);
|
|
95
|
-
--_outline-width: var(--input-outline-width-thin);
|
|
96
|
-
--_label-padding-inline: 10px;
|
|
93
|
+
--_white-space: wrap;
|
|
97
94
|
|
|
98
95
|
display: flex;
|
|
99
96
|
align-items: center;
|
|
100
97
|
|
|
101
|
-
&.
|
|
102
|
-
--
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
&.error {
|
|
106
|
-
--_form-theme: var(--theme-error);
|
|
98
|
+
&.inline {
|
|
99
|
+
--_white-space: nowrap;
|
|
107
100
|
}
|
|
108
101
|
|
|
109
102
|
.input-checkbox-label {
|
|
110
|
-
color: var(--_form-theme);
|
|
111
|
-
font-family: var(--font-family);
|
|
112
|
-
font-size: 14px;
|
|
113
|
-
font-weight: 500;
|
|
114
103
|
display: flex;
|
|
115
104
|
width: 100%;
|
|
116
105
|
height: 100%;
|
|
117
106
|
align-items: center;
|
|
118
|
-
|
|
107
|
+
margin-block: 8px;
|
|
108
|
+
padding-inline: 8px;
|
|
109
|
+
white-space: var(--_white-space);
|
|
119
110
|
|
|
120
111
|
&:hover {
|
|
121
112
|
cursor: pointer;
|
|
@@ -1,30 +1,28 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<fieldset class="multiple-checkboxes-fieldset" :class="[
|
|
2
|
+
<fieldset class="multiple-checkboxes-fieldset" :class="[{ error: fieldHasError }]">
|
|
3
3
|
<legend :class="[{ 'has-description': hasDescription }]">{{ legend }}</legend>
|
|
4
4
|
<template v-if="hasDescription">
|
|
5
5
|
<slot name="description"></slot>
|
|
6
6
|
</template>
|
|
7
|
-
<InputError :errorMessaging :fieldHasError :id="name" :isDetached="true" />
|
|
8
7
|
<div class="multiple-checkboxes-items" :class="[optionsLayout]">
|
|
9
8
|
<template v-for="item in fieldData.data" :key="item.id">
|
|
10
9
|
<InputCheckboxWithLabel
|
|
11
10
|
:id="item.value"
|
|
12
11
|
:name
|
|
13
12
|
:required
|
|
14
|
-
:
|
|
15
|
-
|
|
16
|
-
placeholder: 'eg. Type something here',
|
|
17
|
-
errorMessage: 'Please accept our terms and conditions',
|
|
18
|
-
}"
|
|
13
|
+
:label="item.label"
|
|
14
|
+
:fieldHasError
|
|
19
15
|
v-model="modelValue"
|
|
20
16
|
:true-value="item.value"
|
|
21
|
-
:theme
|
|
22
17
|
:size
|
|
23
18
|
:checkboxAppearance
|
|
19
|
+
:optionsLayout
|
|
24
20
|
:checkboxStyle
|
|
21
|
+
:theme
|
|
25
22
|
/>
|
|
26
23
|
</template>
|
|
27
24
|
</div>
|
|
25
|
+
<InputError :errorMessage="errorMessage" :fieldHasError :id="name" :isDetached="true" />
|
|
28
26
|
</fieldset>
|
|
29
27
|
</template>
|
|
30
28
|
|
|
@@ -32,9 +30,13 @@
|
|
|
32
30
|
import propValidators from '../../c12/prop-validators';
|
|
33
31
|
import type { IOptionsConfig, IFormMultipleOptions } from '@/types/types.forms';
|
|
34
32
|
|
|
35
|
-
import type {
|
|
33
|
+
import type { C12nMultipleCheckboxes, IFormFieldC12, IFormData } from '@/types/types.forms';
|
|
36
34
|
|
|
37
|
-
const
|
|
35
|
+
const { id, name, legend, label, required, fieldHasError, placeholder, errorMessage, size, optionsLayout, equalCols, checkboxAppearance, checkboxStyle, styleClassPassthrough, theme } = defineProps({
|
|
36
|
+
id: {
|
|
37
|
+
type: String,
|
|
38
|
+
required: true,
|
|
39
|
+
},
|
|
38
40
|
name: {
|
|
39
41
|
type: String,
|
|
40
42
|
required: true,
|
|
@@ -43,28 +45,29 @@ const props = defineProps({
|
|
|
43
45
|
type: String,
|
|
44
46
|
required: true,
|
|
45
47
|
},
|
|
46
|
-
|
|
47
|
-
type:
|
|
48
|
-
|
|
48
|
+
label: {
|
|
49
|
+
type: String,
|
|
50
|
+
required: true,
|
|
51
|
+
},
|
|
52
|
+
placeholder: {
|
|
53
|
+
type: String,
|
|
54
|
+
default: '',
|
|
49
55
|
},
|
|
50
|
-
|
|
51
|
-
type: Object
|
|
56
|
+
errorMessage: {
|
|
57
|
+
type: [Object, String],
|
|
52
58
|
required: true,
|
|
53
59
|
},
|
|
54
|
-
|
|
60
|
+
required: {
|
|
55
61
|
type: Boolean,
|
|
56
62
|
default: false,
|
|
57
63
|
},
|
|
58
|
-
|
|
59
|
-
type:
|
|
60
|
-
default:
|
|
64
|
+
fieldHasError: {
|
|
65
|
+
type: Boolean,
|
|
66
|
+
default: false,
|
|
61
67
|
},
|
|
62
|
-
|
|
63
|
-
type:
|
|
64
|
-
default:
|
|
65
|
-
validator(value: string) {
|
|
66
|
-
return propValidators.theme.includes(value);
|
|
67
|
-
},
|
|
68
|
+
multipleOptions: {
|
|
69
|
+
type: Boolean,
|
|
70
|
+
default: false,
|
|
68
71
|
},
|
|
69
72
|
size: {
|
|
70
73
|
type: String as PropType<string>,
|
|
@@ -98,65 +101,36 @@ const props = defineProps({
|
|
|
98
101
|
return propValidators.checkboxStyle.includes(value);
|
|
99
102
|
},
|
|
100
103
|
},
|
|
104
|
+
styleClassPassthrough: {
|
|
105
|
+
type: Array as PropType<string[]>,
|
|
106
|
+
default: () => [],
|
|
107
|
+
},
|
|
108
|
+
theme: {
|
|
109
|
+
type: String as PropType<string>,
|
|
110
|
+
default: 'primary',
|
|
111
|
+
validator(value: string) {
|
|
112
|
+
return propValidators.theme.includes(value);
|
|
113
|
+
},
|
|
114
|
+
},
|
|
101
115
|
});
|
|
102
116
|
|
|
103
117
|
const slots = useSlots();
|
|
104
118
|
const hasDescription = computed(() => slots.description !== undefined);
|
|
119
|
+
const { elementClasses, updateElementClasses } = useStyleClassPassthrough(styleClassPassthrough);
|
|
105
120
|
|
|
106
|
-
const modelValue = defineModel()
|
|
121
|
+
const modelValue = defineModel();
|
|
107
122
|
const fieldData = defineModel('fieldData') as Ref<IFormMultipleOptions>;
|
|
108
|
-
|
|
109
|
-
// const isArray = Array.isArray(modelValue.value.data[props.name]);
|
|
110
|
-
// const formFieldC12 = <IFormFieldC12>{
|
|
111
|
-
// label: props.c12.label,
|
|
112
|
-
// placeholder: props.c12.placeholder,
|
|
113
|
-
// errorMessage: props.c12.errorMessage,
|
|
114
|
-
// useCustomError: false,
|
|
115
|
-
// customErrors: {},
|
|
116
|
-
// isValid: false,
|
|
117
|
-
// isDirty: false,
|
|
118
|
-
// type: isArray ? 'array' : 'string',
|
|
119
|
-
// previousValue: null,
|
|
120
|
-
// };
|
|
121
|
-
// modelValue.value.formFieldsC12[props.name] = formFieldC12;
|
|
122
|
-
|
|
123
|
-
const fieldHasError = computed(() => {
|
|
124
|
-
return modelValue.value!.submitAttempted && !modelValue.value!.formFieldsC12[props.name].isValid;
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
const errorMessaging = computed(() => {
|
|
128
|
-
if (
|
|
129
|
-
typeof modelValue.value!.formFieldsC12[props.name] !== 'undefined' &&
|
|
130
|
-
modelValue.value!.formFieldsC12[props.name].useCustomError &&
|
|
131
|
-
modelValue.value.data[props.name] === modelValue.value.formFieldsC12[props.name].previousValue
|
|
132
|
-
) {
|
|
133
|
-
return modelValue.value.formFieldsC12[props.name]?.customErrors || [];
|
|
134
|
-
} else {
|
|
135
|
-
return props.c12.errorMessage;
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
123
|
</script>
|
|
139
124
|
|
|
140
125
|
<style lang="css">
|
|
141
126
|
.multiple-checkboxes-fieldset {
|
|
142
|
-
--_form-theme: var(--theme-form-primary);
|
|
143
|
-
|
|
144
127
|
margin: 0;
|
|
145
128
|
padding: 0;
|
|
146
129
|
border: 0;
|
|
147
130
|
|
|
148
|
-
&.theme-secondary {
|
|
149
|
-
--_form-theme: var(--theme-form-secondary);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
&.error {
|
|
153
|
-
--_form-theme: var(--theme-error);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
131
|
legend {
|
|
157
|
-
color: var(--_form-theme);
|
|
158
132
|
font-family: var(--font-family);
|
|
159
|
-
font-size:
|
|
133
|
+
font-size: 16px;
|
|
160
134
|
font-weight: 500;
|
|
161
135
|
|
|
162
136
|
&.has-description {
|
|
@@ -168,7 +142,6 @@ const errorMessaging = computed(() => {
|
|
|
168
142
|
font-family: var(--font-family);
|
|
169
143
|
font-size: 16px;
|
|
170
144
|
margin-top: 12px;
|
|
171
|
-
color: var(--theme-form-secondary);
|
|
172
145
|
}
|
|
173
146
|
}
|
|
174
147
|
|