← Back to Website builders

Skill · Version 1.0.0

Accessible shared components

Makes shared interface components resilient across interaction states, assistive technologies, long translations and enlarged text.

accessible-component-engineering

Team members using this skill

See how it helps

When is it useful?

Use when a design system needs accessible defaults that carry through to every screen using its components.

What does it help you do?

  • Defines visible focus, loading, error, disabled and selected states consistently.
  • Connects labels, hints and errors automatically through reliable component identifiers.
  • Checks long labels, text zoom, touch targets and reduced motion.

Try asking this

Review our shared Button, FormField and Dialog components with German labels, enlarged text and keyboard-only navigation. Exercise loading, disabled and error states as well. A long validation message must stay associated with its field without covering the submit button.

Detailed documentation

Read the skill’s original instructions, examples and checks in their authored language.

Details…Show less

Accessible Component Engineering

When accessibility is baked into shared design-system primitives (Button, IconButton, TextField, Select, Checkbox, Dialog, Menu, Tabs, Toast, Tooltip), every screen using those primitives inherits accessible defaults automatically; when a shared primitive is broken, it multiplies barriers across the entire product.

1. Complete Interactive State Matrix

Every interactive component in the system must define and visually distinguish its full state matrix:

  • default (rest): clear affordance and >= 3:1 boundary contrast where applicable.
  • hover: pointer feedback paired with cursor rules.
  • focus-visible: high-contrast keyboard focus ring (>= 2px outline, outline-offset, >= 3:1 contrast against adjacent surface) that survives forced-colors: active mode.
  • active (pressed): tactile visual confirmation on pointer down or Space/Enter activation.
  • disabled / readonly: visually distinct, non-interactive (or aria-disabled="true" when focusability must be preserved), blocking click/submit side effects.
  • loading / pending: prevents double submission (aria-busy="true" or disabled), preserves button width so layout does not jump, and exposes accessible loading status.
  • invalid / error (for form controls): sets aria-invalid="true", pairs border/icon indicator with color (never color alone), and links the error message ID via aria-describedby.
  • selected / checked / expanded / current: synchronizes visual active styling with aria-selected, aria-checked, aria-expanded or aria-current.

2. Built-In ARIA & ID Wiring

Automate repetitive accessibility plumbing inside the component primitive so feature developers cannot forget it:

  • FormField wrapper: generate a deterministic unique ID (useId()), bind <label for={id}> to the input's id, and automatically assemble aria-describedby from the helper-text ID and error-message ID whenever either is rendered.
  • Dialog / Drawer primitive: automatically wire role="dialog", aria-modal="true", aria-labelledby={titleId}, initial focus placement, background inert / focus trapping, Escape dismissal and opener focus restoration.
  • IconButton primitive: require an explicit accessible label (aria-label or title/srOnlyLabel) in the component's type signature and automatically mark the child icon <svg> with aria-hidden="true" focusable="false".

3. Content Resilience, Reflow & Localization

Test every shared component against hostile real-world content before shipping:

  • Long & unbroken strings: handle 50-character German compound words, Hungarian suffixes, long email addresses and URLs via appropriate wrapping (overflow-wrap: break-word) or truncation (text-overflow: ellipsis only when full text remains accessible).
  • Multi-line button & badge labels: use min-height and vertical padding rather than fixed height: 36px so 200% text scaling or wrapped labels never clip vertically.
  • Touch targets & reduced motion: ensure interactive controls meet >= 24x24px (44x44px preferred on touch) and transitions respect @media (prefers-reduced-motion: reduce).
  • Coordinate complex widget semantics and keyboard navigation patterns with the accessibility developer.

Included files 1

  • SKILL.md