From dee496bf1e78fe669dc26429440136affb3baf99 Mon Sep 17 00:00:00 2001 From: Conner Blanton Date: Sat, 18 Nov 2023 09:31:46 -0600 Subject: [PATCH 1/3] feat: (Input & Textarea) Add eagerValidation prop --- src/runtime/components/forms/Input.vue | 4 ++++ src/runtime/components/forms/Textarea.vue | 4 ++++ src/runtime/composables/useFormGroup.ts | 3 ++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/runtime/components/forms/Input.vue b/src/runtime/components/forms/Input.vue index 2da9bcb19d..01098e0ad1 100644 --- a/src/runtime/components/forms/Input.vue +++ b/src/runtime/components/forms/Input.vue @@ -161,6 +161,10 @@ export default defineComponent({ modelModifiers: { type: Object as PropType<{ trim?: boolean, lazy?: boolean, number?: boolean }>, default: () => ({}) + }, + eagerValidation: { + type: Boolean, + default: false } }, emits: ['update:modelValue', 'blur'], diff --git a/src/runtime/components/forms/Textarea.vue b/src/runtime/components/forms/Textarea.vue index 9b10d6c9c1..7e167816eb 100644 --- a/src/runtime/components/forms/Textarea.vue +++ b/src/runtime/components/forms/Textarea.vue @@ -124,6 +124,10 @@ export default defineComponent({ modelModifiers: { type: Object as PropType<{ trim?: boolean, lazy?: boolean, number?: boolean }>, default: () => ({}) + }, + eagerValidation: { + type: Boolean, + default: false } }, emits: ['update:modelValue', 'blur'], diff --git a/src/runtime/composables/useFormGroup.ts b/src/runtime/composables/useFormGroup.ts index e05cb949cf..dfe5267728 100644 --- a/src/runtime/composables/useFormGroup.ts +++ b/src/runtime/composables/useFormGroup.ts @@ -9,6 +9,7 @@ type InputProps = { color?: string name?: string isFieldset?: boolean + eagerValidation?: boolean } export const useFormGroup = (inputProps?: InputProps, config?: any) => { @@ -49,7 +50,7 @@ export const useFormGroup = (inputProps?: InputProps, config?: any) => { } const emitFormInput = useDebounceFn(() => { - if (blurred.value) { + if (blurred.value || inputProps?.eagerValidation) { emitFormEvent('input', formGroup?.name.value) } }, 300) From b79315017a9b758be2f29c769eabe9e7f08a59ac Mon Sep 17 00:00:00 2001 From: Conner Blanton Date: Sat, 18 Nov 2023 09:45:28 -0600 Subject: [PATCH 2/3] docs: add callout about eager-validation --- docs/content/3.forms/10.form.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/content/3.forms/10.form.md b/docs/content/3.forms/10.form.md index 7ebb2244bd..00dff2ae60 100644 --- a/docs/content/3.forms/10.form.md +++ b/docs/content/3.forms/10.form.md @@ -161,6 +161,10 @@ async function onSubmit (event: FormSubmitEvent) { The Form component automatically triggers validation upon `submit`, `input`, `blur` or `change` events. This ensures that any errors are displayed as soon as the user interacts with the form elements. You can control when validation happens this using the `validate-on` prop. +::callout{icon="i-heroicons-light-bulb"} +Note that the `input` event is not triggered on the [`Input`](/forms/input) and [`Textarea`](/forms/textarea) components until after the initial `blur` event. This is to prevent the form from being validated as the user is typing. You can override this behavior by setting the `eagerValidation` prop on these components to `true`. +:: + ::component-example --- component: 'form-example-elements' From 8f9f6d99311c19a4f861bb3602f990893d2e8cdf Mon Sep 17 00:00:00 2001 From: Conner Blanton Date: Tue, 21 Nov 2023 13:35:42 -0600 Subject: [PATCH 3/3] moving eager validation to FormGroup --- .../FormGroupEagerValidationExample.vue | 19 +++++++++++++++++++ docs/content/3.forms/10.form.md | 2 +- docs/content/3.forms/9.form-group.md | 6 ++++++ src/runtime/components/forms/FormGroup.vue | 7 ++++++- src/runtime/components/forms/Input.vue | 4 ---- src/runtime/components/forms/Textarea.vue | 4 ---- src/runtime/composables/useFormGroup.ts | 2 +- src/runtime/types/form.d.ts | 1 + 8 files changed, 34 insertions(+), 11 deletions(-) create mode 100644 docs/components/content/examples/FormGroupEagerValidationExample.vue diff --git a/docs/components/content/examples/FormGroupEagerValidationExample.vue b/docs/components/content/examples/FormGroupEagerValidationExample.vue new file mode 100644 index 0000000000..d17d5a9a28 --- /dev/null +++ b/docs/components/content/examples/FormGroupEagerValidationExample.vue @@ -0,0 +1,19 @@ + + + diff --git a/docs/content/3.forms/10.form.md b/docs/content/3.forms/10.form.md index 00dff2ae60..1dbd20a615 100644 --- a/docs/content/3.forms/10.form.md +++ b/docs/content/3.forms/10.form.md @@ -162,7 +162,7 @@ async function onSubmit (event: FormSubmitEvent) { The Form component automatically triggers validation upon `submit`, `input`, `blur` or `change` events. This ensures that any errors are displayed as soon as the user interacts with the form elements. You can control when validation happens this using the `validate-on` prop. ::callout{icon="i-heroicons-light-bulb"} -Note that the `input` event is not triggered on the [`Input`](/forms/input) and [`Textarea`](/forms/textarea) components until after the initial `blur` event. This is to prevent the form from being validated as the user is typing. You can override this behavior by setting the `eagerValidation` prop on these components to `true`. +Note that the `input` event is not triggered until after the initial `blur` event. This is to prevent the form from being validated as the user is typing. You can override this behavior by setting the [`eager-validation`](/forms/form-group#eager-validation) prop on [`FormGroup`](/forms/form-group) to `true`. :: ::component-example diff --git a/docs/content/3.forms/9.form-group.md b/docs/content/3.forms/9.form-group.md index b8f7af0bad..605b22e776 100644 --- a/docs/content/3.forms/9.form-group.md +++ b/docs/content/3.forms/9.form-group.md @@ -163,6 +163,12 @@ code: >- This will only work with form elements that support the `size` prop. :: +### Eager Validation + +By default, validation is only triggered after the initial `blur` event. This is to prevent the form from being validated as the user is typing. You can override this behavior by setting the `eager-validation` prop to `true` + +:component-example{component="form-group-eager-validation-example"} + ## Slots ### `label` diff --git a/src/runtime/components/forms/FormGroup.vue b/src/runtime/components/forms/FormGroup.vue index 897f010f91..d253668c0f 100644 --- a/src/runtime/components/forms/FormGroup.vue +++ b/src/runtime/components/forms/FormGroup.vue @@ -94,6 +94,10 @@ export default defineComponent({ ui: { type: Object as PropType>, default: undefined + }, + eagerValidation: { + type: Boolean, + default: false } }, setup (props) { @@ -114,7 +118,8 @@ export default defineComponent({ error, inputId, name: computed(() => props.name), - size: computed(() => props.size) + size: computed(() => props.size), + eagerValidation: computed(() => props.eagerValidation) }) return { diff --git a/src/runtime/components/forms/Input.vue b/src/runtime/components/forms/Input.vue index 01098e0ad1..2da9bcb19d 100644 --- a/src/runtime/components/forms/Input.vue +++ b/src/runtime/components/forms/Input.vue @@ -161,10 +161,6 @@ export default defineComponent({ modelModifiers: { type: Object as PropType<{ trim?: boolean, lazy?: boolean, number?: boolean }>, default: () => ({}) - }, - eagerValidation: { - type: Boolean, - default: false } }, emits: ['update:modelValue', 'blur'], diff --git a/src/runtime/components/forms/Textarea.vue b/src/runtime/components/forms/Textarea.vue index 7e167816eb..9b10d6c9c1 100644 --- a/src/runtime/components/forms/Textarea.vue +++ b/src/runtime/components/forms/Textarea.vue @@ -124,10 +124,6 @@ export default defineComponent({ modelModifiers: { type: Object as PropType<{ trim?: boolean, lazy?: boolean, number?: boolean }>, default: () => ({}) - }, - eagerValidation: { - type: Boolean, - default: false } }, emits: ['update:modelValue', 'blur'], diff --git a/src/runtime/composables/useFormGroup.ts b/src/runtime/composables/useFormGroup.ts index dfe5267728..c185f67cc5 100644 --- a/src/runtime/composables/useFormGroup.ts +++ b/src/runtime/composables/useFormGroup.ts @@ -50,7 +50,7 @@ export const useFormGroup = (inputProps?: InputProps, config?: any) => { } const emitFormInput = useDebounceFn(() => { - if (blurred.value || inputProps?.eagerValidation) { + if (blurred.value || formGroup?.eagerValidation.value) { emitFormEvent('input', formGroup?.name.value) } }, 300) diff --git a/src/runtime/types/form.d.ts b/src/runtime/types/form.d.ts index c3e1507fa3..4ef7ccbf5e 100644 --- a/src/runtime/types/form.d.ts +++ b/src/runtime/types/form.d.ts @@ -32,4 +32,5 @@ export interface InjectedFormGroupValue { name: Ref size: Ref error: Ref + eagerValidation: Ref }