Claude Skills Guide

Claude Code ARIA Label Automation for React Components

Manually adding ARIA labels to React components is tedious and error-prone. Claude Code transforms this workflow through intelligent automation, enabling you to generate accessible components at scale while maintaining consistency across your codebase.

The Accessibility Challenge in React

React’s component-based architecture creates unique accessibility challenges. Each button, input, and interactive element needs proper ARIA attributes. When building complex UIs with dozens or hundreds of components, maintaining consistent ARIA labeling becomes overwhelming. Common issues include:

Claude Code addresses these challenges through specialized skills that understand React patterns and accessibility best practices.

Key Claude Code Skills for ARIA Automation

1. The Frontend-Design Skill

The frontend-design skill generates React components with built-in accessibility patterns. When you describe a component, it automatically includes appropriate ARIA attributes:

// Describe: "a search button with an icon"
function SearchButton({ onClick }) {
  return (
    <button 
      onClick={onClick}
      aria-label="Search"
      type="button"
    >
      <SearchIcon />
    </button>
  );
}

The skill recognizes common patterns like icon buttons, form inputs, and modal dialogs, applying the appropriate ARIA attributes without explicit prompting.

2. The TDD Skill for Accessibility Testing

Pair the frontend-design skill with the tdd (Test-Driven Development) skill to verify accessibility compliance. In Claude Code, skills are invoked in conversation—reference the tdd skill by name when describing your task.

The tdd skill generates Jest tests that check for proper ARIA attributes:

describe('SearchButton accessibility', () => {
  it('has proper aria-label', () => {
    render(<SearchButton onClick={() => {}} />);
    const button = screen.getByRole('button');
    expect(button).toHaveAttribute('aria-label', 'Search');
  });
  
  it('is keyboard accessible', () => {
    render(<SearchButton onClick={() => {}} />);
    const button = screen.getByRole('button');
    button.focus();
    expect(button).toHaveFocus();
  });
});

3. The Accessibility Testing Skill

For comprehensive testing, use the axe-accessibility-testing skill by referencing it in Claude Code conversation.

This skill integrates axe-core testing into your test suite, automatically detecting ARIA violations:

import { axe, toHaveNoViolations } from 'jest-axe';

expect.extend(toHaveNoViolations);

test('SearchButton should have no accessibility violations', async () => {
  const { container } = render(<SearchButton onClick={() => {}} />);
  const results = await axe(container);
  expect(results).toHaveNoViolations();
});

Automated ARIA Label Generation Workflow

Here’s how to automate ARIA label implementation in your React project:

Step 1: Create an Accessibility Specification

Define your component library’s ARIA conventions in a CLAUDE.md file:

# Accessibility Conventions

All interactive elements must have proper ARIA labels:

1. Icon-only buttons: aria-label describing the action
2. Form inputs: aria-label or associated label element
3. Modals: aria-modal="true" and aria-labelledby
4. Live regions: aria-live for dynamic content
5. Navigation: proper role and aria-current for links

Step 2: Generate Components with ARIA

When creating new components, instruct Claude Code:

Create a FileUpload component with:
- Drag-and-drop zone
- File type validation display
- Progress indicator
- Remove file button
- Include proper ARIA labels for all interactive elements

Claude Code will generate:

function FileUpload({ onFileSelect, onFileRemove, progress }) {
  const [isDragging, setIsDragging] = useState(false);
  
  return (
    <div
      role="region"
      aria-label="File upload area"
      onDragOver={(e) => {
        e.preventDefault();
        setIsDragging(true);
      }}
      onDragLeave={() => setIsDragging(false)}
      onDrop={(e) => {
        e.preventDefault();
        setIsDragging(false);
        const files = Array.from(e.dataTransfer.files);
        onFileSelect(files);
      }}
      aria-invalid="false"
    >
      <input
        type="file"
        id="file-upload-input"
        onChange={(e) => onFileSelect(Array.from(e.target.files))}
        className="sr-only"
        aria-describedby="file-upload-help"
      />
      <label
        htmlFor="file-upload-input"
        className="upload-zone"
        aria-hidden="true"
      >
        <UploadIcon />
        <span>Drag files here or click to browse</span>
      </label>
      <p id="file-upload-help" className="sr-only">
        Accepted file types: PDF, Images, Documents
      </p>
      
      {progress !== undefined && (
        <div
          role="progressbar"
          aria-valuenow={progress}
          aria-valuemin={0}
          aria-valuemax={100}
          aria-label={`Upload progress: ${progress}%`}
        >
          <div style={{ width: `${progress}%` }} />
        </div>
      )}
    </div>
  );
}

Step 3: Run Accessibility Audits

After component generation, use Claude Code to audit your entire component library:

Run an accessibility audit on all React components in the components/ directory. Check for:
- Missing aria-labels on icon buttons
- Improper form label associations
- Missing keyboard navigation
- Live region configuration

Claude Code will scan your components and generate a report:

Found issues:
- components/IconButton.jsx: Missing aria-label prop
- components/Dialog.jsx: Missing aria-modal="true"
- components/SearchInput.jsx: Missing aria-describedby for error message
- components/Menu.jsx: Missing aria-expanded on toggle button

Step 4: Auto-Fix Issues

Let Claude Code automatically fix the identified issues:

Fix all the accessibility issues identified in the previous audit

The skill will update each component with the appropriate ARIA attributes while preserving your existing code and styling.

Advanced Patterns for Complex Components

Dynamic ARIA Labels

For components with changing states, use computed ARIA labels:

function ToggleButton({ isOn, onToggle }) {
  const label = isOn ? 'Turn off dark mode' : 'Turn on dark mode';
  
  return (
    <button
      onClick={onToggle}
      aria-label={label}
      aria-pressed={isOn}
    >
      {isOn ? <MoonIcon /> : <SunIcon />}
    </button>
  );
}

Form Input Associations

The frontend-design skill automatically generates proper label associations:

function FormField({ label, error, id, ...props }) {
  const errorId = `${id}-error`;
  
  return (
    <div>
      <label htmlFor={id}>{label}</label>
      <input
        id={id}
        aria-invalid={!!error}
        aria-describedby={error ? errorId : undefined}
        {...props}
      />
      {error && (
        <span id={errorId} role="alert" aria-live="polite">
          {error}
        </span>
      )}
    </div>
  );
}

Complex Widget ARIA

For compound components like tabs or accordions, Claude Code generates complete ARIA patterns:

function Tabs({ tabs, activeTab, onChange }) {
  return (
    <div role="tablist" aria-label="Document sections">
      {tabs.map((tab, index) => (
        <button
          key={tab.id}
          role="tab"
          aria-selected={activeTab === tab.id}
          aria-controls={`panel-${tab.id}`}
          id={`tab-${tab.id}`}
          onClick={() => onChange(tab.id)}
        >
          {tab.label}
        </button>
      ))}
      {tabs.map((tab) => (
        <div
          key={tab.id}
          role="tabpanel"
          id={`panel-${tab.id}`}
          aria-labelledby={`tab-${tab.id}`}
          hidden={activeTab !== tab.id}
        >
          {tab.content}
        </div>
      ))}
    </div>
  );
}

Integrating with Your Development Workflow

Pre-Commit Hooks

Add accessibility validation to your pre-commit workflow:

# .husky/pre-commit
npm run test:accessibility

CI/CD Integration

Include accessibility tests in your continuous integration:

# .github/workflows/accessibility.yml
- name: Run accessibility tests
  run: npm run test:accessibility --if-present
  
- name: Audit with axe
  run: npx axe-cli build/**/*.{html,jsx,tsx}

Component Library Documentation

Generate accessibility documentation automatically:

Document the accessibility features of all components in the components/ directory. Include:
- ARIA attributes used
- Keyboard interactions
- Screen reader behavior
- Known limitations

Measuring Accessibility Success

Track your accessibility improvements over time:

  1. axe-core violations: Count decreases with each commit
  2. Test coverage: Percentage of components with accessibility tests
  3. Manual testing: Track issues found in user testing
  4. Screen reader compatibility: Test with VoiceOver, NVDA, and JAWS

Claude Code can generate weekly accessibility reports:

Generate an accessibility report for this week's changes. Compare:
- Number of ARIA attributes added
- New accessibility tests added
- Violations fixed vs. introduced
- WCAG 2.1 AA compliance status

Conclusion

Automating ARIA label implementation in React components through Claude Code transforms accessibility from a burdensome chore into an integral part of your development workflow. By leveraging the frontend-design, tdd, and axe-accessibility-testing skills together, you can:

The result is a more inclusive user experience with significantly less manual effort. Start by using the key skills in Claude Code, defining your accessibility conventions in CLAUDE.md, and gradually automating ARIA label implementation across your React codebase.

Built by theluckystrike — More at zovo.one