Skip to content

fix(Slider): bind form aria attributes on thumbs instead of root - #6768

Open
61021 wants to merge 2 commits into
nuxt:v4from
61021:fix/slider-aria-thumbs
Open

fix(Slider): bind form aria attributes on thumbs instead of root#6768
61021 wants to merge 2 commits into
nuxt:v4from
61021:fix/slider-aria-thumbs

Conversation

@61021

@61021 61021 commented Jul 23, 2026

Copy link
Copy Markdown

🔗 Linked issue

Resolves #6749

❓ Type of change

  • 📖 Documentation (updates to the documentation or readme)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • 👌 Enhancement (improving an existing functionality)
  • ✨ New feature (a non-breaking change that adds functionality)
  • 🧹 Chore (updates to the build process or auxiliary tools and libraries)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

📚 Description

useFormField's ariaAttrs (aria-invalid, aria-describedby) were bound on SliderRoot, which reka-ui renders as a plain <span> with no role and no tabindex — assistive technologies never announce attributes there. The focusable control is the thumb (role="slider", tabindex="0"), so this moves the binding onto each SliderThumb (both the tooltip and plain branches).

Per the APG slider pattern each thumb is a separate slider control, so both thumbs of a range slider sharing the same aria-describedby is correct. :id stays on the root (multiple thumbs can't share one id), keeping the existing label[for] association tests green. When used outside a UFormField, ariaAttrs is undefined and v-bind="undefined" is a no-op — no snapshot changes.

Includes a placement-specific regression test in FormField.spec.ts asserting the attributes land on the role="slider" element (exactly one match) rather than anywhere in the tree.

Credit: #6750 by @nononavasgit proposed the same direction before being closed by its author.

📝 Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.

aria-invalid and aria-describedby from useFormField were bound on
SliderRoot, which renders a span with no role or tabindex, so assistive
technologies never announced them. Bind them on each SliderThumb
(role=slider, tabindex=0) instead — per APG each thumb is a separate
slider control, so both thumbs of a range slider sharing the same
description is correct.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@61021
61021 requested a review from benjamincanac as a code owner July 23, 2026 14:37
@github-actions github-actions Bot added the v4 #4488 label Jul 23, 2026
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Slider form accessibility attributes are no longer applied to SliderRoot. They are now bound to tooltip-wrapped and regular SliderThumb elements. FormField integration tests verify aria-invalid, role="slider", and the expected aria-describedby value.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly states that Slider form ARIA attributes move from the root to the thumbs.
Description check ✅ Passed The description explains the Slider accessibility bug, the implementation, and the regression test.
Linked Issues check ✅ Passed The changes satisfy issue #6749 by applying form ARIA attributes to each focusable SliderThumb.
Out of Scope Changes check ✅ Passed The source and test changes are directly related to the Slider accessibility fix in issue #6749.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

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.

🧹 Nitpick comments (1)
test/components/FormField.spec.ts (1)

123-134: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Expand Slider accessibility coverage.

This test covers only the plain, single-thumb path and error-derived attributes. Add cases for the tooltip branch, multiple thumbs, and aria-labelledby/aria-required so both modified focusable-control paths are protected.

As per coding guidelines, component tests should cover props, slots, and accessibility.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/components/FormField.spec.ts` around lines 123 - 134, Expand the Slider
accessibility tests in the existing “Slider” block to cover the tooltip variant
and multiple-thumb rendering, in addition to the current error attributes. Add
assertions for aria-labelledby and aria-required on each modified focusable
thumb path, preserving the existing single-thumb error coverage.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@test/components/FormField.spec.ts`:
- Around line 123-134: Expand the Slider accessibility tests in the existing
“Slider” block to cover the tooltip variant and multiple-thumb rendering, in
addition to the current error attributes. Add assertions for aria-labelledby and
aria-required on each modified focusable thumb path, preserving the existing
single-thumb error coverage.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: dd1e686e-bc42-4ea6-b351-f6c055096fa3

📥 Commits

Reviewing files that changed from the base of the PR and between 8897318 and 474f791.

📒 Files selected for processing (2)
  • src/runtime/components/Slider.vue
  • test/components/FormField.spec.ts

@pkg-pr-new

pkg-pr-new Bot commented Jul 23, 2026

Copy link
Copy Markdown
npm i https://pkg.pr.new/@nuxt/ui@6768

commit: 00f9746

@61021

61021 commented Jul 31, 2026

Copy link
Copy Markdown
Author

Bumping this one — CI green. Small a11y correctness fix: the form aria attributes were landing on the root instead of the thumbs. Can add a test for the aria wiring if useful.

Comment thread test/components/FormField.spec.ts Outdated
Comment on lines +135 to +137
}

if (name !== 'RadioGroup') {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why not just leave the if-else statement from before and move this if (name === 'Slider') condition underneath it? Seems cleaner than shoving this new condition in between the old if-else blocks.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good call — done in 00f9746. The original if/else is back untouched and the Slider case is appended after it, so the diff on this file is purely additive now. Thanks!

Review feedback: keep the RadioGroup/label if/else pair intact and append
the Slider aria case after it, so the diff stays purely additive.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
test/components/FormField.spec.ts (1)

135-148: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Cover every focusable Slider thumb and all required ARIA attributes.

This test covers aria-invalid, aria-describedby, and role="slider" only. The PR objective also requires aria-labelledby and aria-required on each SliderThumb in both tooltip and plain branches. Render a multi-thumb Slider for each branch and assert the complete attribute set on every [role="slider"] element. Otherwise, a regression in a second thumb or one rendering branch can pass this test.

As per coding guidelines, component tests should cover props, slots, and accessibility, following the repository's Vitest and snapshot-testing patterns.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/components/FormField.spec.ts` around lines 135 - 148, Expand the Slider
accessibility test around the “Slider” branch to render multi-thumb sliders
through both tooltip and plain branches. For every element matching
[role="slider"], assert role, aria-invalid, aria-describedby, aria-labelledby,
and aria-required, ensuring all thumbs receive the complete attribute set and
preserving the repository’s Vitest test patterns.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@test/components/FormField.spec.ts`:
- Around line 135-148: Expand the Slider accessibility test around the “Slider”
branch to render multi-thumb sliders through both tooltip and plain branches.
For every element matching [role="slider"], assert role, aria-invalid,
aria-describedby, aria-labelledby, and aria-required, ensuring all thumbs
receive the complete attribute set and preserving the repository’s Vitest test
patterns.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9e4f8547-0e6d-44b8-b586-aa3f15c97b3d

📥 Commits

Reviewing files that changed from the base of the PR and between 474f791 and 00f9746.

📒 Files selected for processing (1)
  • test/components/FormField.spec.ts

@codspeed-hq

codspeed-hq Bot commented Aug 1, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 31 untouched benchmarks


Comparing 61021:fix/slider-aria-thumbs (00f9746) with v4 (4200e80)

Open in CodSpeed

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

Labels

v4 #4488

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Slider form accessibility attributes are applied to the non-focusable root

2 participants