diff --git a/.changeset/angry-dolls-approve.md b/.changeset/angry-dolls-approve.md new file mode 100644 index 000000000..bd46487bd --- /dev/null +++ b/.changeset/angry-dolls-approve.md @@ -0,0 +1,5 @@ +--- +"vee-validate": patch +--- + +feat: expose useFormContext closes #4490 diff --git a/packages/vee-validate/src/index.ts b/packages/vee-validate/src/index.ts index 586bc4964..a17994148 100644 --- a/packages/vee-validate/src/index.ts +++ b/packages/vee-validate/src/index.ts @@ -7,7 +7,7 @@ export { Form } from './Form'; export { FieldArray } from './FieldArray'; export { ErrorMessage } from './ErrorMessage'; export { useField, FieldOptions, RuleExpression } from './useField'; -export { useForm, FormOptions } from './useForm'; +export { useForm, useFormContext, FormOptions } from './useForm'; export { useFieldArray } from './useFieldArray'; export * from './types'; export { useResetForm } from './useResetForm'; diff --git a/packages/vee-validate/src/symbols.ts b/packages/vee-validate/src/symbols.ts index 34e2e1e5e..5229da718 100644 --- a/packages/vee-validate/src/symbols.ts +++ b/packages/vee-validate/src/symbols.ts @@ -1,8 +1,10 @@ import { InjectionKey } from 'vue'; -import { PrivateFormContext, PrivateFieldContext } from './types'; +import { PrivateFormContext, PrivateFieldContext, FormContext } from './types'; export const FormContextKey: InjectionKey = Symbol('vee-validate-form'); +export const PublicFormContextKey: InjectionKey = Symbol('vee-validate-form-context'); + export const FieldContextKey: InjectionKey> = Symbol('vee-validate-field-instance'); export const IS_ABSENT = Symbol('Default empty value'); diff --git a/packages/vee-validate/src/useForm.ts b/packages/vee-validate/src/useForm.ts index 9d1c18ce1..b5796cedb 100644 --- a/packages/vee-validate/src/useForm.ts +++ b/packages/vee-validate/src/useForm.ts @@ -16,6 +16,7 @@ import { toValue, MaybeRef, MaybeRefOrGetter, + inject, } from 'vue'; import { PartialDeep } from 'type-fest'; import { klona as deepCopy } from 'klona/full'; @@ -68,7 +69,7 @@ import { debounceNextTick, normalizeEventValue, } from './utils'; -import { FormContextKey } from './symbols'; +import { FormContextKey, PublicFormContextKey } from './symbols'; import { validateTypedSchema, validateObjectSchema } from './validate'; import { refreshInspector, registerFormWithDevTools } from './devtools'; import { isCallable, merge, normalizeFormPath } from '../../shared'; @@ -1197,12 +1198,16 @@ export function useForm< }); } - return { + const ctx: FormContext = { ...formCtx, values: readonly(formValues) as TValues, handleReset: () => resetForm(), submitForm, }; + + provide(PublicFormContextKey, ctx); + + return ctx; } /** @@ -1328,3 +1333,10 @@ function mergeValidationResults( errors: [...a.errors, ...b.errors], }; } + +export function useFormContext< + TValues extends GenericObject = GenericObject, + TOutput extends GenericObject = TValues, +>(): FormContext { + return inject(PublicFormContextKey) as FormContext; +}