Skip to content

Commit

Permalink
feat(FormGroup): add eager validation (#992)
Browse files Browse the repository at this point in the history
  • Loading branch information
connerblanton committed Nov 21, 2023
1 parent 9df9b9a commit d39e2de
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<template>
<UForm :schema="schema" :state="state" class="space-y-4">
<UFormGroup label="Username" name="username" eager-validation>
<UInput v-model="state.username" placeholder="Choose Username" />
</UFormGroup>
</UForm>
</template>

<script setup>
import { z } from 'zod'
const schema = z.object({
username: z.string().min(10, 'Must be at least 10 characters')
})
const state = reactive({
username: undefined
})
</script>
4 changes: 4 additions & 0 deletions docs/content/3.forms/10.form.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ async function onSubmit (event: FormSubmitEvent<any>) {

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 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
---
component: 'form-example-elements'
Expand Down
6 changes: 6 additions & 0 deletions docs/content/3.forms/9.form-group.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
7 changes: 6 additions & 1 deletion src/runtime/components/forms/FormGroup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ export default defineComponent({
ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined
},
eagerValidation: {
type: Boolean,
default: false
}
},
setup (props) {
Expand All @@ -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 {
Expand Down
3 changes: 2 additions & 1 deletion src/runtime/composables/useFormGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type InputProps = {
color?: string
name?: string
isFieldset?: boolean
eagerValidation?: boolean
}

export const useFormGroup = (inputProps?: InputProps, config?: any) => {
Expand Down Expand Up @@ -49,7 +50,7 @@ export const useFormGroup = (inputProps?: InputProps, config?: any) => {
}

const emitFormInput = useDebounceFn(() => {
if (blurred.value) {
if (blurred.value || formGroup?.eagerValidation.value) {
emitFormEvent('input', formGroup?.name.value)
}
}, 300)
Expand Down
1 change: 1 addition & 0 deletions src/runtime/types/form.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,5 @@ export interface InjectedFormGroupValue {
name: Ref<string>
size: Ref<string | number | symbol>
error: Ref<string | boolean>
eagerValidation: Ref<boolean>
}

1 comment on commit d39e2de

@vercel
Copy link

@vercel vercel bot commented on d39e2de Nov 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

ui – ./

ui-git-dev-nuxt-js.vercel.app
ui.nuxt.com
ui-nuxt-js.vercel.app

Please sign in to comment.