diff --git a/packages/vee-validate/src/index.ts b/packages/vee-validate/src/index.ts index e3175bf5b..d687cded5 100644 --- a/packages/vee-validate/src/index.ts +++ b/packages/vee-validate/src/index.ts @@ -11,3 +11,4 @@ export * from './useErrors'; export { useResetForm } from './useResetForm'; export * from './useIsDirty'; export * from './useIsTouched'; +export * from './useIsValid'; diff --git a/packages/vee-validate/src/useIsValid.ts b/packages/vee-validate/src/useIsValid.ts new file mode 100644 index 000000000..182427982 --- /dev/null +++ b/packages/vee-validate/src/useIsValid.ts @@ -0,0 +1,25 @@ +import { computed } from 'vue'; +import { FormSymbol } from './symbols'; +import { injectWithSelf } from './utils'; + +/** + * If a field is validated and is valid + */ +export function useIsFieldValid(path: string) { + const form = injectWithSelf(FormSymbol); + + return computed(() => { + return form?.fields.value[path]?.meta.valid; + }); +} + +/** + * If the form has been validated and is valid + */ +export function useIsFormValid() { + const form = injectWithSelf(FormSymbol); + + return computed(() => { + return form?.meta.value.valid; + }); +} diff --git a/packages/vee-validate/tests/useIsValid.ts b/packages/vee-validate/tests/useIsValid.ts new file mode 100644 index 000000000..88cc70c9f --- /dev/null +++ b/packages/vee-validate/tests/useIsValid.ts @@ -0,0 +1,66 @@ +import flushPromises from 'flush-promises'; +import { useIsFormValid, useField, useIsFieldValid, useForm } from '@/vee-validate'; +import { mountWithHoc, setValue } from './helpers'; + +describe('useIsValid()', () => { + const REQUIRED_MESSAGE = 'Field is required'; + const validate = (val: any) => (val ? true : REQUIRED_MESSAGE); + + test('returns the validity of a single field', async () => { + mountWithHoc({ + setup() { + useForm(); + const { value } = useField('test', validate); + const isValid = useIsFieldValid('test'); + + return { + value, + isValid, + }; + }, + template: ` + + {{ isValid.toString() }} + `, + }); + await flushPromises(); + + const input = document.querySelector('input'); + const span = document.querySelector('span'); + setValue(input as any, ''); + await flushPromises(); + expect(span?.textContent).toBe('false'); + setValue(input as any, '12'); + await flushPromises(); + expect(span?.textContent).toBe('true'); + }); + + test('returns validity of the form', async () => { + mountWithHoc({ + setup() { + useForm(); + const { value } = useField('test', validate); + const isValid = useIsFormValid(); + + return { + value, + isValid, + }; + }, + template: ` + + {{ isValid.toString() }} + `, + }); + + await flushPromises(); + const input = document.querySelector('input'); + const span = document.querySelector('span'); + setValue(input as any, ''); + await flushPromises(); + expect(span?.textContent).toBe('false'); + setValue(input as any, '12'); + await flushPromises(); + expect(span?.textContent).toBe('true'); + }); +});