Skip to content
This repository was archived by the owner on Jun 27, 2023. It is now read-only.

Commit 157d111

Browse files
committed
feat(validation): error messages now lives at input level
1 parent 505114e commit 157d111

File tree

10 files changed

+203
-86
lines changed

10 files changed

+203
-86
lines changed

src/components/checkbox-input/CheckboxInput.vue

+26-8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { defineComponent, h, PropType } from 'vue';
33
import { FormControl, CheckboxInput } from '@/core/models';
44
import { useInputEvents } from '@/composables/input-events';
5+
import { useInputValidation } from '@/composables/use-validation';
56
67
const props = {
78
control: Object as PropType<FormControl<CheckboxInput>>,
@@ -12,15 +13,21 @@ export default defineComponent({
1213
props,
1314
setup(props, { emit }) {
1415
const { onCheck, onFocus, onBlur } = useInputEvents(props, emit);
16+
17+
const { errorMessages, isPendingValidation } = useInputValidation(
18+
props,
19+
emit,
20+
);
21+
1522
const renderCheckbox = [
1623
h('input', {
17-
name: props?.control?.name || '',
18-
type: props?.control?.type,
19-
id: props?.control?.name,
20-
disabled: props?.control?.disabled,
24+
name: props.control.name || '',
25+
type: props.control.type,
26+
id: props.control.name,
27+
disabled: props.control.disabled,
2128
class: ['checkbox-control'],
22-
value: props?.control?.value,
23-
checked: props?.control?.value,
29+
value: props.control.value,
30+
checked: props.control.value,
2431
onFocus,
2532
onBlur,
2633
onChange: onCheck,
@@ -29,9 +36,9 @@ export default defineComponent({
2936
'label',
3037
{
3138
class: ['checkbox-label'],
32-
for: props?.control?.name,
39+
for: props.control.name,
3340
},
34-
props?.control?.label,
41+
props.control.label,
3542
),
3643
];
3744
@@ -45,6 +52,17 @@ export default defineComponent({
4552
},
4653
renderCheckbox,
4754
),
55+
isPendingValidation.value
56+
? null
57+
: h(
58+
'div',
59+
{
60+
class: 'form-errors',
61+
},
62+
errorMessages.value.map(error =>
63+
h('p', { class: 'form-error' }, error),
64+
),
65+
),
4866
];
4967
},
5068
});

src/components/dynamic-input/DynamicInput.vue

+1-10
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import {
2828
InputEvent,
2929
} from '@/core/models';
3030
31-
import { values, keys, isArray, isObject } from '@/core/utils/helpers';
31+
import { values, isArray, isObject } from '@/core/utils/helpers';
3232
import { useInputEvents } from '@/composables/input-events';
3333
import { dynamicFormsSymbol } from '@/useApi';
3434
@@ -234,15 +234,6 @@ export default defineComponent({
234234
)
235235
: null,
236236
component,
237-
h(
238-
'div',
239-
{
240-
class: 'form-errors',
241-
},
242-
errorMessages.value.map(error =>
243-
h('p', { class: 'form-error' }, error),
244-
),
245-
),
246237
],
247238
);
248239
};

src/components/number-input/NumberInput.vue

+28-12
Original file line numberDiff line numberDiff line change
@@ -13,30 +13,46 @@ export default defineComponent({
1313
props,
1414
setup(props, { emit }) {
1515
const { onInput, onFocus, onBlur } = useInputEvents(props, emit);
16-
const { isRequired } = useInputValidation(props, emit);
16+
const {
17+
isRequired,
18+
errorMessages,
19+
isPendingValidation,
20+
} = useInputValidation(props, emit);
1721
18-
return () =>
22+
return () => [
1923
h('input', {
2024
id: props.control.name,
21-
name: props?.control?.name || '',
22-
type: props?.control?.type,
25+
name: props.control.name || '',
26+
type: props.control.type,
2327
class: ['form-control'],
24-
value: props?.control?.value,
25-
min: props?.control?.min,
26-
max: props?.control?.max,
27-
step: props?.control?.step,
28-
disabled: props?.control?.disabled,
29-
placeholder: props?.control?.placeholder,
28+
value: props.control.value,
29+
min: props.control.min,
30+
max: props.control.max,
31+
step: props.control.step,
32+
disabled: props.control.disabled,
33+
placeholder: props.control.placeholder,
3034
required: isRequired.value,
31-
readonly: props?.control.readonly,
35+
readonly: props.control.readonly,
3236
autocomplete: props.control.autocomplete,
3337
ariaLabel: props.control.ariaLabel,
3438
ariaLabelledBy: props.control.ariaLabelledBy,
3539
ariaRequired: isRequired.value,
3640
onFocus,
3741
onBlur,
3842
onInput,
39-
});
43+
}),
44+
isPendingValidation.value
45+
? null
46+
: h(
47+
'div',
48+
{
49+
class: 'form-errors',
50+
},
51+
errorMessages.value.map(error =>
52+
h('p', { class: 'form-error' }, error),
53+
),
54+
),
55+
];
4056
},
4157
});
4258
</script>

src/components/radio-input/RadioInput.vue

+18
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { defineComponent, h, PropType } from 'vue';
33
import { FormControl, RadioInput } from '@/core/models';
44
import { useInputEvents } from '@/composables/input-events';
5+
import { useInputValidation } from '@/composables/use-validation';
56
67
const props = {
78
control: Object as PropType<FormControl<RadioInput>>,
@@ -12,6 +13,12 @@ export default defineComponent({
1213
props,
1314
setup(props, { emit }) {
1415
const { onInput, onFocus, onBlur } = useInputEvents(props, emit);
16+
17+
const { errorMessages, isPendingValidation } = useInputValidation(
18+
props,
19+
emit,
20+
);
21+
1522
const renderRadios = props?.control?.options?.map(option => {
1623
return h('div', { class: 'radio-input' }, [
1724
h('input', {
@@ -45,6 +52,17 @@ export default defineComponent({
4552
},
4653
renderRadios,
4754
),
55+
isPendingValidation.value
56+
? null
57+
: h(
58+
'div',
59+
{
60+
class: 'form-errors',
61+
},
62+
errorMessages.value.map(error =>
63+
h('p', { class: 'form-error' }, error),
64+
),
65+
),
4866
];
4967
},
5068
});

src/components/select-input/SelectInput.vue

+38-21
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ export default defineComponent({
1515
setup(props, { emit }) {
1616
return () => {
1717
const { onInput, onFocus, onBlur } = useInputEvents(props, emit);
18-
const { isRequired } = useInputValidation(props, emit);
18+
const {
19+
isRequired,
20+
errorMessages,
21+
isPendingValidation,
22+
} = useInputValidation(props, emit);
1923
2024
const formattedOptions = computed(() => {
2125
if (isObject(props?.control?.options)) {
@@ -27,26 +31,39 @@ export default defineComponent({
2731
const options = formattedOptions.value.map(({ key, value, disabled }) =>
2832
h('option', { key, value: key, disabled }, value),
2933
);
30-
return h(
31-
'select',
32-
{
33-
id: props.control.name,
34-
name: props?.control?.name || '',
35-
class: ['form-control'],
36-
value: props?.control?.value,
37-
disabled: props?.control?.disabled,
38-
placeholder: props?.control?.placeholder,
39-
required: isRequired.value,
40-
readonly: props?.control.readonly,
41-
ariaLabel: props.control.ariaLabel,
42-
ariaLabelledBy: props.control.ariaLabelledBy,
43-
ariaRequired: isRequired.value,
44-
onFocus,
45-
onBlur,
46-
onInput,
47-
},
48-
options,
49-
);
34+
return [
35+
h(
36+
'select',
37+
{
38+
id: props.control.name,
39+
name: props?.control?.name || '',
40+
class: ['form-control'],
41+
value: props?.control?.value,
42+
disabled: props?.control?.disabled,
43+
placeholder: props?.control?.placeholder,
44+
required: isRequired.value,
45+
readonly: props?.control.readonly,
46+
ariaLabel: props.control.ariaLabel,
47+
ariaLabelledBy: props.control.ariaLabelledBy,
48+
ariaRequired: isRequired.value,
49+
onFocus,
50+
onBlur,
51+
onInput,
52+
},
53+
options,
54+
),
55+
isPendingValidation.value
56+
? null
57+
: h(
58+
'div',
59+
{
60+
class: 'form-errors',
61+
},
62+
errorMessages.value.map(error =>
63+
h('p', { class: 'form-error' }, error),
64+
),
65+
),
66+
];
5067
};
5168
},
5269
});

src/components/text-area-input/TextAreaInput.vue

+26-10
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,44 @@ export default defineComponent({
1212
props,
1313
setup(props, { emit }) {
1414
const { onInput, onFocus, onBlur } = useInputEvents(props, emit);
15-
const { isRequired } = useInputValidation(props, emit);
15+
const {
16+
isRequired,
17+
errorMessages,
18+
isPendingValidation,
19+
} = useInputValidation(props, emit);
1620
17-
return () =>
21+
return () => [
1822
h('textarea', {
1923
id: props.control.name,
20-
name: props?.control?.name || '',
24+
name: props.control.name || '',
2125
class: ['form-control'],
22-
value: props?.control?.value,
23-
rows: props?.control?.rows,
24-
cols: props?.control?.cols,
25-
disabled: props?.control?.disabled,
26-
placeholder: props?.control?.placeholder,
26+
value: props.control.value,
27+
rows: props.control.rows,
28+
cols: props.control.cols,
29+
disabled: props.control.disabled,
30+
placeholder: props.control.placeholder,
2731
required: isRequired.value,
2832
autocomplete: props.control.autocomplete,
29-
readonly: props?.control.readonly,
33+
readonly: props.control.readonly,
3034
ariaLabel: props.control.ariaLabel,
3135
ariaLabelledBy: props.control.ariaLabelledBy,
3236
ariaRequired: isRequired.value,
3337
onFocus,
3438
onBlur,
3539
onInput,
36-
});
40+
}),
41+
isPendingValidation.value
42+
? null
43+
: h(
44+
'div',
45+
{
46+
class: 'form-errors',
47+
},
48+
errorMessages.value.map(error =>
49+
h('p', { class: 'form-error' }, error),
50+
),
51+
),
52+
];
3753
},
3854
});
3955
</script>

src/components/text-input/TextInput.vue

+21-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script lang="ts">
2-
import { defineComponent, h, PropType, ref } from 'vue';
2+
import { defineComponent, h, PropType } from 'vue';
33
import {
44
ColorInput,
55
EmailInput,
@@ -25,9 +25,12 @@ export default defineComponent({
2525
props,
2626
emit,
2727
);
28-
const { isRequired } = useInputValidation(props, emit);
29-
30-
return () =>
28+
const {
29+
isRequired,
30+
errorMessages,
31+
isPendingValidation,
32+
} = useInputValidation(props, emit);
33+
return () => [
3134
h('input', {
3235
id: props.control.name,
3336
name: props.control.name || '',
@@ -37,15 +40,27 @@ export default defineComponent({
3740
disabled: props.control.disabled,
3841
placeholder: props.control.placeholder,
3942
required: isRequired.value,
40-
readonly: props?.control.readonly,
43+
readonly: props.control.readonly,
4144
autocomplete: props.control.autocomplete,
4245
ariaRequired: isRequired.value,
4346
ariaLabel: props.control.ariaLabel,
4447
ariaLabelledBy: props.control.ariaLabelledBy,
4548
onFocus,
4649
onBlur,
4750
onInput,
48-
});
51+
}),
52+
isPendingValidation.value
53+
? null
54+
: h(
55+
'div',
56+
{
57+
class: 'form-errors',
58+
},
59+
errorMessages.value.map(error =>
60+
h('p', { class: 'form-error' }, error),
61+
),
62+
),
63+
];
4964
},
5065
});
5166
</script>

0 commit comments

Comments
 (0)