fix(accessibility): properly set the label on Listbox when used with FormField - #6780
fix(accessibility): properly set the label on Listbox when used with FormField#6780ttcchhmm wants to merge 1 commit into
Conversation
📝 WalkthroughWalkthrough
Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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.
Inline comments:
In `@src/runtime/components/Listbox.vue`:
- Line 378: Update the Listbox component’s aria-labelledby binding on
ListboxContent to use the injected FormField label id rather than the control
id, and only set it when a label is actually rendered. Preserve no reference for
standalone Listboxes or FormFields without labels, and add regression coverage
for custom ids and unlabeled usage.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: fa30d2a7-0f28-4149-ada7-890f2a4accbd
⛔ Files ignored due to path filters (6)
test/components/__snapshots__/AuthForm-vue.spec.ts.snapis excluded by!**/*.snaptest/components/__snapshots__/AuthForm.spec.ts.snapis excluded by!**/*.snaptest/components/__snapshots__/FormField-vue.spec.ts.snapis excluded by!**/*.snaptest/components/__snapshots__/FormField.spec.ts.snapis excluded by!**/*.snaptest/components/__snapshots__/Listbox-vue.spec.ts.snapis excluded by!**/*.snaptest/components/__snapshots__/Listbox.spec.ts.snapis excluded by!**/*.snap
📒 Files selected for processing (2)
src/runtime/components/FormField.vuesrc/runtime/components/Listbox.vue
| </ListboxFilter> | ||
|
|
||
| <ListboxContent data-slot="content" :class="ui.content({ class: props.ui?.content })"> | ||
| <ListboxContent data-slot="content" :class="ui.content({ class: props.ui?.content })" :aria-labelledby="id !== undefined ? `${id}-label` : undefined"> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
Derive aria-labelledby from the FormField label id, not the control id.
When a Listbox supplies a custom id, Line 213 makes id differ from FormField’s stable ariaId; this emits ${customId}-label, while FormField renders ${ariaId}-label. Standalone Listboxes with explicit ids, and FormFields without labels, can also receive dangling ARIA references. Expose/use the injected label id and bind it only when a label is rendered; add regression tests for both cases.
🤖 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 `@src/runtime/components/Listbox.vue` at line 378, Update the Listbox
component’s aria-labelledby binding on ListboxContent to use the injected
FormField label id rather than the control id, and only set it when a label is
actually rendered. Preserve no reference for standalone Listboxes or FormFields
without labels, and add regression coverage for custom ids and unlabeled usage.
commit: |
🔗 Linked issue
Resolves #6756.
❓ Type of change
📚 Description
This PR fixes the missing ARIA attribute needed to link the label provided by
UFormFieldto a childUListbox. Since the component within theUListboxwithrole="listbox"is adiv, simply using theforattribute on the label won't work asdivs are not labelable. To work around that, I added an ID to the main label (like the one used for hints and descriptions) withinUFormFieldand used it witharia-labelledbyinUListbox. This allows the label to properly show within the accessibility tree.📝 Checklist