Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/vuetify/src/components/VBtn/VBtn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ export const VBtn = genericComponent<VBtnSlots>()({
props.style,
]}
aria-busy={ props.loading ? true : undefined }
aria-disabled={ isDisabled.value ? true : undefined }
disabled={ isDisabled.value || undefined }
tabindex={ props.loading || props.readonly ? -1 : undefined }
onClick={ onClick }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,68 @@ describe('VBtn', () => {
})
})

describe('Accessibility', () => {
it('should add aria-disabled when disabled prop is true', async () => {
const { wrapper } = render(() => (
<VBtn disabled>Disabled Button</VBtn>
))

expect(wrapper.element).toHaveAttribute('aria-disabled', 'true')
expect(wrapper.element).toHaveAttribute('disabled')
})

it('should not have aria-disabled when disabled prop is false', async () => {
const { wrapper } = render(() => (
<VBtn disabled={ false }>Enabled Button</VBtn>
))

expect(wrapper.element).not.toHaveAttribute('aria-disabled')
expect(wrapper.element).not.toHaveAttribute('disabled')
})

it('should reactively update aria-disabled attribute', async () => {
const disabled = ref(true)
const { wrapper } = render(() => (
<VBtn disabled={ disabled.value }>Toggle Button</VBtn>
))

// Initially disabled
expect(wrapper.element).toHaveAttribute('aria-disabled', 'true')
expect(wrapper.element).toHaveAttribute('disabled')

// Enable the button
disabled.value = false
await expect.element(wrapper.element).not.toHaveAttribute('aria-disabled')
await expect.element(wrapper.element).not.toHaveAttribute('disabled')

// Disable again
disabled.value = true
await expect.element(wrapper.element).toHaveAttribute('aria-disabled', 'true')
await expect.element(wrapper.element).toHaveAttribute('disabled')
})

it('should handle group disabled state with aria-disabled', async () => {
// Test disabled state from isDisabled computed property
const { wrapper } = render(() => (
<VBtn disabled>Disabled Button</VBtn>
))

expect(wrapper.element).toHaveAttribute('aria-disabled', 'true')
expect(wrapper.element).toHaveAttribute('disabled')
expect(wrapper.element).toHaveClass('v-btn--disabled')
})

it('should work with default disabled prop', async () => {
const { wrapper } = render(() => (
<VBtn>Default Button</VBtn>
))

expect(wrapper.element).not.toHaveAttribute('aria-disabled')
expect(wrapper.element).not.toHaveAttribute('disabled')
expect(wrapper.element).not.toHaveClass('v-btn--disabled')
})
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests are all completely useless, it's safe to assume that prop -> computed -> attribute won't break.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@KaelWD Thanks for the feedback, I totally agree, sorry for not catching it.


describe('Showcase', () => {
generate({ stories, props, component: VBtn })
})
Expand Down