@@ -47,41 +47,31 @@ export interface FormFieldSlots {
4747 </script >
4848
4949<script setup lang="ts">
50- import { computed , ref , inject , provide , useId , watch } from ' vue'
51- import type { Ref } from ' vue'
50+ import { computed , provide } from ' vue'
5251import { Primitive , Label } from ' reka-ui'
52+ import { useFormField } from ' @formwerk/core'
5353import { useAppConfig } from ' #imports'
54- import { formFieldInjectionKey , inputIdInjectionKey , formErrorsInjectionKey , formInputsInjectionKey } from ' ../composables/useFormField'
54+ import { formFieldInjectionKey } from ' ../composables/useFormField'
5555import { tv } from ' ../utils/tv'
56- import type { FormError , FormFieldInjectedOptions } from ' ../types/form'
56+ import type { FormFieldInjectedOptions } from ' ../types/form'
5757
5858const props = defineProps <FormFieldProps >()
5959const slots = defineSlots <FormFieldSlots >()
6060
6161const appConfig = useAppConfig () as FormField [' AppConfig' ]
6262
63+ const { labelProps, descriptionProps, errorMessageProps, state : { errorMessage, isTouched } } = useFormField ({
64+ path: props .name ,
65+ label: props .label ,
66+ description: props .description
67+ })
68+
6369const ui = computed (() => tv ({ extend: tv (theme ), ... (appConfig .ui ?.formField || {}) })({
6470 size: props .size ,
6571 required: props .required
6672}))
6773
68- const formErrors = inject <Ref <FormError []> | null >(formErrorsInjectionKey , null )
69-
70- const error = computed (() => props .error || formErrors ?.value ?.find (error => error .name === props .name || (props .errorPattern && error .name ?.match (props .errorPattern )))?.message )
71-
72- const id = ref (useId ())
73- // Copies id's initial value to bind aria-attributes such as aria-describedby.
74- // This is required for the RadioGroup component which unsets the id value.
75- const ariaId = id .value
76-
77- const formInputs = inject (formInputsInjectionKey , undefined )
78- watch (id , () => {
79- if (formInputs && props .name ) {
80- formInputs .value [props .name ] = { id: id .value , pattern: props .errorPattern }
81- }
82- }, { immediate: true })
83-
84- provide (inputIdInjectionKey , id )
74+ const error = computed (() => props .error || (errorMessage .value && isTouched .value ? errorMessage .value : undefined ))
8575
8676provide (formFieldInjectionKey , computed (() => ({
8777 error: error .value ,
@@ -92,28 +82,27 @@ provide(formFieldInjectionKey, computed(() => ({
9282 errorPattern: props .errorPattern ,
9383 hint: props .hint ,
9484 description: props .description ,
95- help: props .help ,
96- ariaId
85+ help: props .help
9786}) as FormFieldInjectedOptions <FormFieldProps >))
9887 </script >
9988
10089<template >
10190 <Primitive :as =" as" :class =" ui.root({ class: [props.ui?.root, props.class] })" >
10291 <div :class =" ui.wrapper({ class: props.ui?.wrapper })" >
10392 <div v-if =" label || !!slots.label" :class =" ui.labelWrapper({ class: props.ui?.labelWrapper })" >
104- <Label :for = " id " :class =" ui.label({ class: props.ui?.label })" >
93+ <Label v-bind = " labelProps " :class =" ui.label({ class: props.ui?.label })" >
10594 <slot name =" label" :label =" label" >
10695 {{ label }}
10796 </slot >
10897 </Label >
109- <span v-if =" hint || !!slots.hint" :id =" `${ariaId }-hint`" :class =" ui.hint({ class: props.ui?.hint })" >
98+ <span v-if =" hint || !!slots.hint" :id =" `${labelProps.id }-hint`" :class =" ui.hint({ class: props.ui?.hint })" >
11099 <slot name =" hint" :hint =" hint" >
111100 {{ hint }}
112101 </slot >
113102 </span >
114103 </div >
115104
116- <p v-if =" description || !!slots.description" :id = " `${ariaId}-description` " :class =" ui.description({ class: props.ui?.description })" >
105+ <p v-if =" description || !!slots.description" :v-bind = " descriptionProps " :class =" ui.description({ class: props.ui?.description })" >
117106 <slot name =" description" :description =" description" >
118107 {{ description }}
119108 </slot >
@@ -123,12 +112,12 @@ provide(formFieldInjectionKey, computed(() => ({
123112 <div :class =" [(label || !!slots.label || description || !!slots.description) && ui.container({ class: props.ui?.container })]" >
124113 <slot :error =" error" />
125114
126- <div v-if =" (typeof error === 'string' && error) || !!slots.error" :id = " `${ariaId}-error` " :class =" ui.error({ class: props.ui?.error })" >
115+ <div v-if =" (typeof error === 'string' && error) || !!slots.error" :v-bind = " errorMessageProps " :class =" ui.error({ class: props.ui?.error })" >
127116 <slot name =" error" :error =" error" >
128117 {{ error }}
129118 </slot >
130119 </div >
131- <div v-else-if =" help || !!slots.help" :id =" `${ariaId }-help`" :class =" ui.help({ class: props.ui?.help })" >
120+ <div v-else-if =" help || !!slots.help" :id =" `${labelProps.id }-help`" :class =" ui.help({ class: props.ui?.help })" >
132121 <slot name =" help" :help =" help" >
133122 {{ help }}
134123 </slot >
0 commit comments