Skip to content

Commit

Permalink
fix(FormField): remove id when used with RadioGroup
Browse files Browse the repository at this point in the history
  • Loading branch information
romhml committed Sep 9, 2024
1 parent d640e38 commit b3437bd
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 18 deletions.
8 changes: 4 additions & 4 deletions playground/app/components/FormElementsExample.vue
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,12 @@ function onSubmit(event: FormSubmitEvent<Schema>) {
<UInputMenu v-model="state.inputMenuMultiple" multiple :items="items" />
</UFormField>

<UFormField name="checkbox">
<UCheckbox v-model="state.checkbox" label="Check me" />
<UFormField name="checkbox" label="ksda">
<UCheckbox id="hello" v-model="state.checkbox" label="Check me" />
</UFormField>

<UFormField name="radioGroup">
<URadioGroup v-model="state.radioGroup" legend="Radio group" :items="items" />
<UFormField name="radioGroup" label="toto">
<URadioGroup id="toto" v-model="state.radioGroup" legend="Radio group" :items="items" />
</UFormField>

<UFormField name="switch">
Expand Down
5 changes: 3 additions & 2 deletions src/runtime/components/FormField.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export interface FormFieldSlots {
<script setup lang="ts">
import { computed, ref, inject, provide, type Ref, useId } from 'vue'
import { Label } from 'radix-vue'
import { formFieldInjectionKey } from '../composables/useFormField'
import { formFieldInjectionKey, inputIdInjectionKey } from '../composables/useFormField'
import type { FormError, FormFieldInjectedOptions } from '../types/form'
const props = defineProps<FormFieldProps>()
Expand All @@ -55,8 +55,9 @@ const error = computed(() => props.error || formErrors?.value?.find(error => err
const id = ref(useId())
provide(inputIdInjectionKey, id)
provide(formFieldInjectionKey, computed(() => ({
id: id.value,
error: error.value,
name: props.name,
size: props.size,
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/components/RadioGroup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const slots = defineSlots<RadioGroupSlots<T>>()
const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'modelValue', 'defaultValue', 'orientation', 'loop', 'required'), emits)
const { emitFormChange, emitFormInput, color, name, size, id: _id, disabled } = useFormField<RadioGroupProps<T>>(props)
const { emitFormChange, emitFormInput, color, name, size, id: _id, disabled } = useFormField<RadioGroupProps<T>>(props, { bind: false })
const id = _id.value ?? useId()
const ui = computed(() => radioGroup({
Expand Down
22 changes: 13 additions & 9 deletions src/runtime/composables/useFormField.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,26 @@ type Props<T> = {
export const formOptionsInjectionKey: InjectionKey<ComputedRef<FormInjectedOptions>> = Symbol('nuxt-ui.form-options')
export const formBusInjectionKey: InjectionKey<UseEventBusReturn<FormEvent, string>> = Symbol('nuxt-ui.form-events')
export const formFieldInjectionKey: InjectionKey<ComputedRef<FormFieldInjectedOptions<FormFieldProps>>> = Symbol('nuxt-ui.form-field')
export const inputIdInjectionKey: InjectionKey<Ref<string | undefined>> = Symbol('nuxt-ui.input-id')
export const formInputsInjectionKey: InjectionKey<Ref<Record<string, string>>> = Symbol('nuxt-ui.form-inputs')

export function useFormField<T>(props?: Props<T>) {
export function useFormField<T>(props?: Props<T>, opts?: { bind?: boolean }) {
const formOptions = inject(formOptionsInjectionKey, undefined)
const formBus = inject(formBusInjectionKey, undefined)
const formField = inject(formFieldInjectionKey, undefined)
const formInputs = inject(formInputsInjectionKey, undefined)
const inputId = inject(inputIdInjectionKey, undefined)

if (formField) {
if (props?.id) {
// Updates for="..." attribute on label if props.id is provided
formField.value.id = props?.id
if (formField && inputId) {
if (opts?.bind === false || props?.legend) {
// Removes for="..." attribute on label for RadioGroup and alike.
inputId.value = undefined
} if (props?.id) {
// Updates for="..." attribute on label if props.id is provided.
inputId.value = props?.id
}

if (formInputs && formField.value.name) {
formInputs.value[formField.value.name] = formField.value.id
if (formInputs && formField.value.name && inputId.value) {
formInputs.value[formField.value.name] = inputId.value
}
}

Expand Down Expand Up @@ -62,7 +66,7 @@ export function useFormField<T>(props?: Props<T>) {
)

return {
id: computed(() => props?.id ?? formField?.value.id),
id: computed(() => props?.id ?? inputId?.value),
name: computed(() => props?.name ?? formField?.value.name),
size: computed(() => props?.size ?? formField?.value.size),
color: computed(() => formField?.value.error ? 'error' : props?.color),
Expand Down
1 change: 0 additions & 1 deletion src/runtime/types/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ export interface FormInjectedOptions {
}

export interface FormFieldInjectedOptions<T> {
id: string
name?: string
size?: GetObjectField<T, 'size'>
error?: string | boolean
Expand Down
9 changes: 8 additions & 1 deletion test/components/RadioGroup.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ describe('RadioGroup', () => {
items: ['Option 1', 'Option 2']
},
slotTemplate: `
<UFormField name="value">
<UFormField name="value" label="Radio group">
<URadioGroup id="input" v-model="state.value" :items="items" />
</UFormField>
`
Expand Down Expand Up @@ -107,5 +107,12 @@ describe('RadioGroup', () => {
await flushPromises()
expect(wrapper.text()).not.toContain('Error message')
})


test('no label for=... on FormField', async () => {
const { wrapper } = await createForm()
const formFieldLabel = wrapper.findAll('label').map((label) => label.attributes()).filter((label) => !label.for?.includes('Option'))[0]
expect(formFieldLabel.for).toBeUndefined()
})
})
})

0 comments on commit b3437bd

Please sign in to comment.