ensure we forward attributes when using providers
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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`
|
||||
<RadioGroup v-model="deliveryMethod" as="div" class="abc">
|
||||
<RadioGroupLabel>Pizza Delivery</RadioGroupLabel>
|
||||
<RadioGroupOption v-for="option in options" key="option.id" :value="option" v-slot="data"
|
||||
>{{option.label}}</RadioGroupOption
|
||||
>
|
||||
</RadioGroup>
|
||||
`,
|
||||
setup() {
|
||||
let deliveryMethod = ref(undefined)
|
||||
let options = ref([{ id: 1, label: 'Pickup' }])
|
||||
return { deliveryMethod, options }
|
||||
},
|
||||
})
|
||||
|
||||
await new Promise<void>(nextTick)
|
||||
|
||||
expect(document.querySelector('[id^="headlessui-radiogroup-"]')).toHaveClass('abc')
|
||||
})
|
||||
|
||||
it('should be possible to put classes on a RadioGroupOption', async () => {
|
||||
renderTemplate({
|
||||
template: html`
|
||||
<RadioGroup v-model="deliveryMethod">
|
||||
<RadioGroupLabel>Pizza Delivery</RadioGroupLabel>
|
||||
<RadioGroupOption
|
||||
v-for="option in options"
|
||||
key="option.id"
|
||||
:value="option"
|
||||
v-slot="data"
|
||||
class="abc"
|
||||
>{{option.label}}</RadioGroupOption
|
||||
>
|
||||
</RadioGroup>
|
||||
`,
|
||||
setup() {
|
||||
let deliveryMethod = ref(undefined)
|
||||
let options = ref([{ id: 1, label: 'Pickup' }])
|
||||
return { deliveryMethod, options }
|
||||
},
|
||||
})
|
||||
|
||||
await new Promise<void>(nextTick)
|
||||
|
||||
expect(getByText('Pickup')).toHaveClass('abc')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Keyboard interactions', () => {
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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`
|
||||
<SwitchGroup>
|
||||
<SwitchLabel class="abc">Label A</SwitchLabel>
|
||||
<Switch v-model="checked" />
|
||||
</SwitchGroup>
|
||||
`,
|
||||
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`
|
||||
<SwitchGroup>
|
||||
<SwitchDescription class="abc">Description A</SwitchDescription>
|
||||
<Switch v-model="checked" />
|
||||
</SwitchGroup>
|
||||
`,
|
||||
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`
|
||||
<SwitchGroup as="div" class="abc" id="group">
|
||||
<Switch v-model="checked" />
|
||||
</SwitchGroup>
|
||||
`,
|
||||
setup: () => ({ checked: ref(false) }),
|
||||
})
|
||||
|
||||
await new Promise(requestAnimationFrame)
|
||||
|
||||
assertSwitch({ state: SwitchState.Off })
|
||||
|
||||
expect(document.getElementById('group')).toHaveClass('abc')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Keyboard interactions', () => {
|
||||
|
||||
@@ -30,6 +30,7 @@ let GroupContext = Symbol('GroupContext') as InjectionKey<StateDefinition>
|
||||
|
||||
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',
|
||||
}),
|
||||
]
|
||||
),
|
||||
])
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user