Skip to content

fix(a11y): add accessible labels to icon-only controls#50

Open
msmps wants to merge 4 commits intocloudflare:mainfrom
msmps:fix/a11y-icon-control-labels
Open

fix(a11y): add accessible labels to icon-only controls#50
msmps wants to merge 4 commits intocloudflare:mainfrom
msmps:fix/a11y-icon-control-labels

Conversation

@msmps
Copy link
Contributor

@msmps msmps commented Feb 8, 2026

Description

  • Add aria-labels to icon-only controls in MenuBar and Combobox

Problem

Several icon-only controls were missing explicit accessible labels, so screen readers could announce them as unlabeled buttons.

Controls:

  • MenuBar option buttons (icon-only)
  • Combobox.TriggerInput clear button
  • Combobox.TriggerInput dropdown trigger button
  • Combobox.ChipRemove button in multi-select chips

Solution

Add aria-label to each icon-only control:

@pkg-pr-new
Copy link

pkg-pr-new bot commented Feb 26, 2026

npm i https://pkg.pr.new/@cloudflare/kumo@50

commit: d6d2913

@github-actions
Copy link
Contributor

Docs Preview

View docs preview

Commit: d6d2913

Copy link
Collaborator

@mattrothenberg mattrothenberg left a comment

Choose a reason for hiding this comment

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

Can we make these props with a default values of the english text so that we can ultimately pass a translated string down where we consume this?

@github-actions
Copy link
Contributor

Visual Regression Report

1 screenshot(s) with visual changes:

Combobox (Open)

17 px (0%) changed

Before After Diff
Before After Diff
2 screenshot(s) unchanged
  • Menu Bar / Text Formatting
  • Menu Bar / Without Active State

Generated by Kumo Visual Regression

Copy link
Collaborator

@geoquant geoquant left a comment

Choose a reason for hiding this comment

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

Thanks for the contribution — the a11y gaps you identified are real and the fix direction is correct. Merge conflict is now resolved. A few changes needed before this can land:

1. Make labels configurable props (per @mattrothenberg's feedback)

Hardcoded English strings prevent i18n. Each label should be a prop with an English default.

TriggerInput:

function TriggerInput({
  clearLabel = "Clear selection",
  showOptionsLabel = "Show options",
  ...props
}: ComboboxBase.Input.Props & {
  /** Accessible label for the clear button. @default "Clear selection" */
  clearLabel?: string;
  /** Accessible label for the dropdown trigger. @default "Show options" */
  showOptionsLabel?: string;
}) {
  // ...
  <ComboboxBase.Clear aria-label={clearLabel} ...>
  <ComboboxBase.Trigger aria-label={showOptionsLabel} ...>
}

Chip:

function Chip({
  removeLabel = "Remove",
  ...props
}: ComboboxBase.Chip.Props & {
  /** Accessible label for the chip remove button. @default "Remove" */
  removeLabel?: string;
}) {
  // ...
  <ComboboxBase.ChipRemove aria-label={removeLabel} ...>
}

2. Chip label wording

Change "Remove selection""Remove". In chip context, the chip is the selection — "Remove selection" is ambiguous when there are multiple chips.

3. MenuBar — looks good as-is

aria-label={tooltip} on the icon-only button is correct and necessary — the Tooltip component provides aria-describedby (supplementary), not aria-label (name). No change needed here.

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.

3 participants