Skip to content

fix(Slider): give the role=slider thumb an accessible name from the label - #1039

Open
waterWang wants to merge 1 commit into
frappe:mainfrom
waterWang:fix/slider-thumb-accessible-name-994
Open

waterWang wants to merge 1 commit into
frappe:mainfrom
waterWang:fix/slider-thumb-accessible-name-994

Conversation

@waterWang

@waterWang waterWang commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Slider puts its accessible name on SliderRoot, but reka-ui renders SliderRoot as a plain container with no role. The element that actually carries role="slider" is SliderThumb, which received no aria-label and no aria-labelledby — so every slider thumb was an unnamed control (failing WCAG 2.1 SC 4.1.2 Name, Role, Value).

This moves the labelling attributes (aria-labelledby, aria-describedby, aria-errormessage, aria-invalid) from SliderRoot onto each SliderThumb, so the role="slider" element now has an accessible name.

Changes

  • src/components/Slider/Slider.vue: move aria-labelledby / aria-describedby / aria-errormessage / aria-invalid from SliderRoot to each SliderThumb.
  • src/components/Slider/Slider.cy.ts: update the shared-labeling test to assert the attributes live on [role="slider"] directly (not on its parent).

Test

npm run test:cypress — updated Slider.cy.ts now asserts [role="slider"] carries the label and description IDs, and the label/description text resolves through them.

Fixes #994

The SliderRoot container carries aria-labelledby and aria-describedby,
but reka-ui renders SliderRoot as a container with no role. The element
that carries role=slider is SliderThumb, which received no accessible
name. Move the aria attributes from SliderRoot to each SliderThumb so
the actual slider control has a name.

Fixes frappe#994
@greptile-apps

greptile-apps Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Confidence Score: 4/5

The Cypress callback must be corrected before merging because the new regression test fails under the configured runner.

The Slider implementation change is sound, but its test invokes Cypress commands from a retried assertion callback that rejects nested commands.

Files Needing Attention: src/components/Slider/Slider.cy.ts

Fix All in Claude Code Fix All in Codex

Reviews (1): Last reviewed commit: "fix(Slider): give role=slider element an..." | Re-trigger Greptile

Comment on lines +93 to +100
cy.get('[role="slider"]').should(($thumb) => {
const labelledBy = $thumb.attr('aria-labelledby')!
const describedBy = $thumb.attr('aria-describedby')!
expect(labelledBy).to.exist
expect(describedBy).to.exist
cy.get(`#${labelledBy}`).should('contain.text', 'Volume')
cy.get(`#${describedBy}`).should('contain.text', 'Adjust volume.')
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Nested Cypress commands break test

When Cypress 15 runs this component spec, the .should() callback enqueues two cy.get() commands, which Cypress prohibits inside retried assertion callbacks and causes the regression test to fail.

Suggested change
cy.get('[role="slider"]').should(($thumb) => {
const labelledBy = $thumb.attr('aria-labelledby')!
const describedBy = $thumb.attr('aria-describedby')!
expect(labelledBy).to.exist
expect(describedBy).to.exist
cy.get(`#${labelledBy}`).should('contain.text', 'Volume')
cy.get(`#${describedBy}`).should('contain.text', 'Adjust volume.')
})
cy.get('[role="slider"]').then(($thumb) => {
const labelledBy = $thumb.attr('aria-labelledby')!
const describedBy = $thumb.attr('aria-describedby')!
expect(labelledBy).to.exist
expect(describedBy).to.exist
cy.get(`#${labelledBy}`).should('contain.text', 'Volume')
cy.get(`#${describedBy}`).should('contain.text', 'Adjust volume.')
})

Fix in Claude Code Fix in Codex

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Slider: the role="slider" element has no accessible name, and aria-label from a call site is dropped

1 participant