diff --git a/packages/@headlessui-vue/src/components/dialog/dialog.ts b/packages/@headlessui-vue/src/components/dialog/dialog.ts
index 60e382b..c0d64f7 100644
--- a/packages/@headlessui-vue/src/components/dialog/dialog.ts
+++ b/packages/@headlessui-vue/src/components/dialog/dialog.ts
@@ -75,15 +75,15 @@ export let Dialog = defineComponent({
},
render() {
let propsWeControl = {
+ // Manually passthrough the attributes, because Vue can't automatically pass
+ // it to the underlying div because of all the wrapper components below.
+ ...this.$attrs,
ref: 'el',
id: this.id,
role: 'dialog',
'aria-modal': this.dialogState === DialogStates.Open ? true : undefined,
'aria-labelledby': this.titleId,
'aria-describedby': this.describedby,
- // Manually passthrough the attributes, because Vue can't automatically pass
- // it to the underlying div because of all the wrapper components below.
- ...this.$attrs,
}
let { open, onClose, initialFocus, ...passThroughProps } = this.$props
let containers = this.containers
diff --git a/packages/@headlessui-vue/src/components/radio-group/radio-group.test.ts b/packages/@headlessui-vue/src/components/radio-group/radio-group.test.ts
index 9f2a64c..29a6a30 100644
--- a/packages/@headlessui-vue/src/components/radio-group/radio-group.test.ts
+++ b/packages/@headlessui-vue/src/components/radio-group/radio-group.test.ts
@@ -244,6 +244,55 @@ describe('Rendering', () => {
`Dine in - ${JSON.stringify({ checked: false, active: false })}`
)
})
+
+ it('should be possible to put classes on a RadioGroup', async () => {
+ renderTemplate({
+ template: html`
+
+ Pizza Delivery
+ {{option.label}}
+
+ `,
+ setup() {
+ let deliveryMethod = ref(undefined)
+ let options = ref([{ id: 1, label: 'Pickup' }])
+ return { deliveryMethod, options }
+ },
+ })
+
+ await new Promise(nextTick)
+
+ expect(document.querySelector('[id^="headlessui-radiogroup-"]')).toHaveClass('abc')
+ })
+
+ it('should be possible to put classes on a RadioGroupOption', async () => {
+ renderTemplate({
+ template: html`
+
+ Pizza Delivery
+ {{option.label}}
+
+ `,
+ setup() {
+ let deliveryMethod = ref(undefined)
+ let options = ref([{ id: 1, label: 'Pickup' }])
+ return { deliveryMethod, options }
+ },
+ })
+
+ await new Promise(nextTick)
+
+ expect(getByText('Pickup')).toHaveClass('abc')
+ })
})
describe('Keyboard interactions', () => {
diff --git a/packages/@headlessui-vue/src/components/radio-group/radio-group.ts b/packages/@headlessui-vue/src/components/radio-group/radio-group.ts
index 52e013d..f867577 100644
--- a/packages/@headlessui-vue/src/components/radio-group/radio-group.ts
+++ b/packages/@headlessui-vue/src/components/radio-group/radio-group.ts
@@ -60,6 +60,7 @@ function useRadioGroupContext(component: string) {
export let RadioGroup = defineComponent({
name: 'RadioGroup',
emits: ['update:modelValue'],
+ inheritAttrs: false, // Manually handling this
props: {
as: { type: [Object, String], default: 'div' },
disabled: { type: [Boolean], default: false },
@@ -69,6 +70,9 @@ export let RadioGroup = defineComponent({
let { modelValue, disabled, ...passThroughProps } = this.$props
let propsWeControl = {
+ // Manually passthrough the attributes, because Vue can't automatically pass
+ // it to the underlying div because of all the wrapper components below.
+ ...this.$attrs,
ref: 'el',
id: this.id,
role: 'radiogroup',
@@ -225,6 +229,7 @@ enum OptionState {
export let RadioGroupOption = defineComponent({
name: 'RadioGroupOption',
+ inheritAttrs: false, // Manually handling this
props: {
as: { type: [Object, String], default: 'div' },
value: { type: [Object, String] },
@@ -246,6 +251,9 @@ export let RadioGroupOption = defineComponent({
let slot = { checked: this.checked, active: Boolean(this.state & OptionState.Active) }
let propsWeControl = {
+ // Manually passthrough the attributes, because Vue can't automatically pass
+ // it to the underlying div because of all the wrapper components below.
+ ...this.$attrs,
id: this.id,
ref: 'el',
role: 'radio',
diff --git a/packages/@headlessui-vue/src/components/switch/switch.test.tsx b/packages/@headlessui-vue/src/components/switch/switch.test.tsx
index 910c0df..c7198ad 100644
--- a/packages/@headlessui-vue/src/components/switch/switch.test.tsx
+++ b/packages/@headlessui-vue/src/components/switch/switch.test.tsx
@@ -8,6 +8,7 @@ import {
getSwitch,
assertActiveElement,
getSwitchLabel,
+ getByText,
} from '../../test-utils/accessibility-assertions'
import { press, click, Keys } from '../../test-utils/interactions'
import { html } from '../../test-utils/html'
@@ -215,6 +216,65 @@ describe('Render composition', () => {
description: 'This is an important feature',
})
})
+
+ it('should be possible to put classes on a SwitchLabel', async () => {
+ renderTemplate({
+ template: html`
+
+ Label A
+
+
+ `,
+ setup: () => ({ checked: ref(false) }),
+ })
+
+ await new Promise(requestAnimationFrame)
+
+ assertSwitch({
+ state: SwitchState.Off,
+ label: 'Label A',
+ })
+
+ expect(getByText('Label A')).toHaveClass('abc')
+ })
+
+ it('should be possible to put classes on a SwitchDescription', async () => {
+ renderTemplate({
+ template: html`
+
+ Description A
+
+
+ `,
+ setup: () => ({ checked: ref(false) }),
+ })
+
+ await new Promise(requestAnimationFrame)
+
+ assertSwitch({
+ state: SwitchState.Off,
+ description: 'Description A',
+ })
+
+ expect(getByText('Description A')).toHaveClass('abc')
+ })
+
+ it('should be possible to put classes on a SwitchGroup', async () => {
+ renderTemplate({
+ template: html`
+
+
+
+ `,
+ setup: () => ({ checked: ref(false) }),
+ })
+
+ await new Promise(requestAnimationFrame)
+
+ assertSwitch({ state: SwitchState.Off })
+
+ expect(document.getElementById('group')).toHaveClass('abc')
+ })
})
describe('Keyboard interactions', () => {
diff --git a/packages/@headlessui-vue/src/components/switch/switch.ts b/packages/@headlessui-vue/src/components/switch/switch.ts
index c46a907..ba29216 100644
--- a/packages/@headlessui-vue/src/components/switch/switch.ts
+++ b/packages/@headlessui-vue/src/components/switch/switch.ts
@@ -30,6 +30,7 @@ let GroupContext = Symbol('GroupContext') as InjectionKey
export let SwitchGroup = defineComponent({
name: 'SwitchGroup',
+ inheritAttrs: false, // Manually handling this
props: {
as: { type: [Object, String], default: 'template' },
},
@@ -56,7 +57,20 @@ export let SwitchGroup = defineComponent({
},
},
},
- () => [render({ props, slot: {}, slots, attrs, name: 'SwitchGroup' })]
+ () => [
+ render({
+ props: {
+ // Manually passthrough the attributes, because Vue can't automatically pass
+ // it to the underlying div because of all the wrapper components below.
+ ...attrs,
+ ...props,
+ },
+ slot: {},
+ slots,
+ attrs,
+ name: 'SwitchGroup',
+ }),
+ ]
),
])
},