Skip to content

[Toolkit][Shadcn] Fix a caller's aria-label being ignored on pagination, breadcrumb and questionnaire - #4058

Merged
Kocal merged 1 commit into
symfony:3.xfrom
Kocal:claude/symfony-ux-4051-a3d11b
Oct 9, 2026
Merged

Kocal merged 1 commit into
symfony:3.xfrom
Kocal:claude/symfony-ux-4051-a3d11b

Conversation

@Kocal

@Kocal Kocal commented Oct 8, 2026

Copy link
Copy Markdown
Member
Q A
Bug fix? yes
New feature? no
Deprecations? no
Documentation? yes
Issues Fix #4051
License MIT

Pagination, Breadcrumb and Questionnaire:Progress wrote their aria-label as a literal attribute before {{ attributes }}, so a caller's own aria-label landed as a second, duplicate attribute instead of replacing it. Browsers keep the first one, so the hard-coded English label always won and the landmark could never be renamed or translated.

Each template now declares the label inside attributes.defaults(), for instance {{ attributes.defaults({'aria-label': 'pagination', class: ...}) }}. defaults() lets a caller's value win and emits the attribute once, which is exactly what an accessible name needs.

The Toolkit linter used to reject every aria-* key inside defaults(), a rule meant for state attributes such as aria-expanded that must always be present and must not be overridable. aria-label is an accessible name, not a state, so this PR relaxes the rule for it.

@Kocal Kocal self-assigned this Oct 8, 2026
@carsonbot carsonbot added Bug Bug Fix Documentation Improvements or additions to documentation Toolkit Status: Needs Review Needs to be reviewed labels Oct 8, 2026
@dragosprotung

Copy link
Copy Markdown

I quickly checked other components that i currently do not use, but same issue (aria-label="{{ label }}" before {{ attributes }}) in:

  • Calendar
  • Carousel
  • NavigationMenu
  • Sidebar
  • Sidebar:Rail
  • Sidebar:Trigger

The same attributes.defaults({'aria-label': label}) fix applies i guess.

One extra thing: hard-coded English aria-labels that can't be changed at all:

  • Sonner: "Notifications"
  • Toast: "Close notification"
  • Combobox: "Clear selection"
  • Calendar: "Month", "Year"

Those can not have the same fix, and not sure if they should be handled in this PR, but wanted to mention them

…cipes

| Q              | A
| -------------- | ---
| Bug fix?       | yes
| New feature?   | no
| Deprecations?  | no
| Documentation? | yes
| Issues         | Fix symfony#4051
| License        | MIT

The `breadcrumb`, `calendar`, `carousel`, `input-otp`, `navigation-menu`, `pagination`, `questionnaire` and `sidebar` recipes wrote `aria-label` as a literal attribute before `{{ attributes }}`, so a caller's own `aria-label` was emitted as a second, duplicate attribute. Browsers keep the first one, so the hard-coded default always won and the name could not be translated or made more specific.

Each template now declares the label inside `attributes.defaults()`, e.g. `{{ attributes.defaults({'aria-label': label, class: ...}) }}`, so a caller's value wins and the attribute is emitted once. For the five recipes with a `label` or `ariaLabel` prop, that prop stays the documented way to set the name; `pagination`, `breadcrumb` and `questionnaire` had none, so their README accessibility notes now say a caller's `aria-label` replaces the default.

The Toolkit linter rejected every `aria-*` key inside `defaults()`, a rule meant for state attributes such as `aria-expanded` that must always be present and must not be overridable. `aria-label` is an accessible name, not a state, so this PR lets it through.
@Kocal
Kocal force-pushed the claude/symfony-ux-4051-a3d11b branch from a202f22 to 6d1de57 Compare October 8, 2026 21:58
@Kocal

Kocal commented Oct 9, 2026

Copy link
Copy Markdown
Member Author

The aria-label for Calendar, Carousel, NavigationMenu, Sidebar, Sidebar:Rail, Sidebar:Trigger have been made configurable through attributes.defaults().

But not the other one you mentioned, I don't see a use-case when their aria-label could change in a specific context. Close (...) is good enough, if people need to add translations, they will do it.

@Kocal
Kocal merged commit 14b9ca5 into symfony:3.x Oct 9, 2026
44 checks passed
@Kocal
Kocal deleted the claude/symfony-ux-4051-a3d11b branch October 9, 2026 09:08
@dragosprotung

Copy link
Copy Markdown

Thank you for the fix!

For the others, it's not about changing the context, but more about applying a translation.
It is good enough for me as it is now and i can overwrite them in my project directly anyway.

@Kocal

Kocal commented Oct 9, 2026

Copy link
Copy Markdown
Member Author

For the others, it's not about changing the context, but more about applying a translation.

Maybe in the future we can add a new feature to UX Toolkit to update app's translations...?
'Not sure how it would works tho

@dragosprotung

Copy link
Copy Markdown

That would be of course nicer and even remove the need for overwriting the attributes

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

Labels

Bug Bug Fix Documentation Improvements or additions to documentation Status: Needs Review Needs to be reviewed Toolkit

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Toolkit][Shadcn] A caller's aria-label is ignored on Pagination, Breadcrumb and Questionnaire:Progress

3 participants