Skip to content

fix(a11y): render a warning icon for Chip warning intent (WCAG 1.4.1)#3450

Open
bilal-karim wants to merge 1 commit into
mainfrom
a11y/1.4.1-chip-warning-icon
Open

fix(a11y): render a warning icon for Chip warning intent (WCAG 1.4.1)#3450
bilal-karim wants to merge 1 commit into
mainfrom
a11y/1.4.1-chip-warning-icon

Conversation

@bilal-karim
Copy link
Copy Markdown
Member

@bilal-karim bilal-karim commented May 25, 2026

Summary

The Chip primitive's warning intent previously applied bg-danger as the only severity signal. Sighted users with color-vision differences (deuteranopia, protanopia, achromatopsia) could not identify which chip in a list was the rejected one — all chips looked similar in shape.

This PR adds a leading warning icon when intent === 'warning'. Background color is unchanged. The icon is decorative (renders with aria-hidden="true" via svg.svelte when no title is passed); the existing aria-live="assertive" hint on the parent <ChipInput> continues to carry the AT-readable signal for validation failures.

 <span class={merge('chip', intent)}>
+  {#if intent === 'warning'}
+    <Icon name="warning" class="shrink-0" />
+  {/if}
   {#if button}

Before / After

Before — warning is color-only After — warning has icon + color
image image

Invalid chips were previously distinguished only by background color. Now they also carry a warning triangle (⚠) — visible to colorblind users.

Audit context

  • WCAG 2.2 SC 1.4.1 Use of Color (Level A) — Medium remediation priority.
  • Issue file: `audit-output/issues/1.4.1-chip-warning-icon.md` (part of the Wave 2 Holocene severity-primitive bundle — Chip is the third of four; Toast shipped in fix(a11y): pair Toast variant background with a severity icon (WCAG 1.4.1) #3449, Badge / Banner ship as separate PRs).
  • Affects ChipInput and Combobox where validity drives the intent per chip. Single primitive change resolves all consumers.

Affected callsites

A single-primitive fix at Chip resolves all severity callsites:

  • src/lib/holocene/input/chip-input.svelte:128, 189 (`intent={valid ? 'default' : 'warning'}`)
  • src/lib/holocene/combobox/combobox.svelte:518

Other Chip consumers use intent=\"default\" and are unaffected.

Functional impact: zero

Pure visual decoration. Verified:

  • Props API unchanged (intent, button, removeButtonLabel, disabled, onclick, onremove, children)
  • handleRemove callback flow unchanged
  • aria-label, data-track-* attributes on close button unchanged
  • .warning { @apply bg-danger } style unchanged
  • Existing aria-live hint on parent unchanged
  • New icon has no event handlers, no ARIA exposure (decorative)

Test plan

  • Storybook: chip.stories.sveltedefault and warning intents both render correctly
  • Render <ChipInput> with a mix of valid and invalid values; only invalid chips show the warning icon
  • axe-core run on a page consuming ChipInput (search-attribute filter): zero new violations
  • Color-blind simulator (deuteranopia, protanopia): the warning icon shape is perceptible against the chip background
  • Screen reader smoke test: the existing aria-live hint continues to announce on validation failure; the decorative icon does not double-announce

Out of scope

  • Adding success / info / error intents (intent set stays warning + default)
  • Restructuring ChipInput to tie a specific chip to a specific error message (that's 1.3.1 / 4.1.2 enhancement)
  • Adding aria-invalid to the chip wrapper (would require giving the chip a role — separate decision)

🤖 Generated with Claude Code

The Chip primitive's 'warning' intent previously applied bg-danger
as the only severity signal. Sighted users with color-vision
differences (deuteranopia, protanopia, achromatopsia) could not
identify which chip in a list was the rejected one -- all chips
looked similar in shape.

Render a leading 'warning' Icon when intent === 'warning'. The
icon is decorative (aria-hidden via svg.svelte's default when no
title is passed); the existing aria-live="assertive" hint on the
parent ChipInput continues to carry the AT-readable signal for
validation failures.

Affects ChipInput (chip-input.svelte:128, 189) and Combobox
(combobox.svelte:518) where intent={valid ? 'default' : 'warning'}
is set per chip. Search-attribute filtering, email/ID list inputs,
and similar form surfaces inherit the fix from the primitive.

Mirrors the pattern established by PR #3449 (Toast severity icon)
and the existing Alert primitive (icon defaults to intent).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@bilal-karim bilal-karim requested a review from a team as a code owner May 25, 2026 16:56
@vercel
Copy link
Copy Markdown

vercel Bot commented May 25, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
holocene Ready Ready Preview, Comment May 25, 2026 4:57pm

Request Review

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.

1 participant