name fix-accessibility description Audit and fix WCAG 2.1 Level AA accessibility issues in BEEQ StencilJS components. Use for: adding missing ARIA attributes, fixing keyboard navigation, managing focus, fixing color contrast issues, adding screen reader support, fixing role usage, and writing accessibility-related E2E tests for bq-* components. argument-hint Component name or path (e.g. "bq-button" or packages/beeq/src/components/button/bq-button.tsx)
Fix Accessibility in a BEEQ Component
When to Use
A component fails an accessibility audit or axe scan
A PR review flagged missing ARIA attributes
Keyboard navigation is broken or incomplete
Screen reader announces incorrect role, state, or label
Focus is lost after a user interaction
Before You Start
Read the accessibility instructions
Read the component's .tsx to understand its current HTML structure and shadow DOM
Note which semantic HTML elements are used and whether shadow DOM parts are exposed
Audit Checklist
Work through each category in order:
1. Semantic HTML
Interactive elements use native elements: <button>, <a href>, <input>, <select>, <textarea>
Use <button> for actions, <a> for navigation
Heading levels are not skipped inside complex components
<label> elements are associated to inputs via htmlFor / slotting, or aria-label/aria-labelledby
Use <ul>/<li> for lists, <nav> for navigation regions, <main>, <header>, <footer> for landmarks
Do not add role="button" to a <div> when a <button> can be used instead
2. Labels & Descriptions
3. Roles
4. State Attributes
Reflect interactive state with ARIA:
State Attribute Open/closed (accordion, drawer, dropdown) aria-expanded="true/false"Selected (tab, option) aria-selected="true/false"Checked (checkbox, radio, toggle) aria-checked="true/false"Disabled aria-disabled="true" (in addition to disabled where needed)Required aria-required="true"Invalid aria-invalid="true" + aria-describedby pointing to error messageBusy/loading aria-busy="true"Hidden decorative elements aria-hidden="true"
5. Keyboard Navigation
Component type Expected keyboard behavior Button Enter and Space activateLink Enter activatesCheckbox / Toggle Space togglesAccordion Enter/Space expand; Tab moves between itemsSelect / Listbox Enter/Space open; Arrow keys navigate options; Escape closesDialog / Drawer Escape closes; focus trapped inside while openTabs Arrow keys move between tabs; Tab moves to tab panel Date picker Arrow keys navigate calendar; Escape closes
Implement keyboard handling with @Listen('keydown') or inline onKeyDown. Use event.key values, not event.keyCode.
6. Focus Management
7. Live Regions
8. Color & Contrast
9. Screen reader support
Implementation Patterns
Icon-only button
<button
aria-label={this .label }
aria-disabled={this .disabled ? 'true' : undefined }
>
<slot />
</button>
@Prop ({ reflect : true }) label ?: string ;
Expandable element
<div
role="button"
aria-expanded={this .open ? 'true' : 'false' }
aria-controls="panel-id"
tabindex="0"
onKeyDown={this .handleKeyDown }
>
Error-linked input
<input
aria-describedby={this .hasError ? `${this .name} -error` : undefined }
aria-invalid={this .hasError ? 'true' : undefined }
/>
{this .hasError && (
<span id ={ `${this.name }-error `} role ="alert" > {this.errorMessage}</span >
)}
Writing Accessibility Tests
After fixing, add E2E assertions (see write-e2e-tests skill):
it ('should have aria-label on icon-only button' , async () => {
const { root } = await render (<bq-button only-icon label ="Close" /> );
const btn = (root as HTMLBqButtonElement ).shadowRoot ?.querySelector <HTMLButtonElement >('[part="button"]' );
expect (btn).toEqualAttribute ('aria-label' , 'Close' );
});
it ('should have aria-expanded when open' , async () => {
const { root, setProps } = await render (<bq-accordion /> );
await setProps ({ open : true });
const base = (root as HTMLBqAccordionElement ).shadowRoot ?.querySelector ('[part="header"]' );
expect (base).toEqualAttribute ('aria-expanded' , 'true' );
});
Report format
Issues
List each problem with:
Element / prop / line — location of the issue (markdown link, workspace-relative path).
WCAG criterion — which criterion is violated (e.g. 1.3.1, 4.1.2).
Severity — critical (blocks assistive technology) | serious (significant barrier) | moderate (inconvenience) | minor.
Fix — the concrete change needed.
Recommendations
Additional improvements that are not violations but would improve the experience for users of assistive technology.