React

React Accessibility Audit Toolkit

Build an a11y testing tool that scans components for WCAG violations and suggests fixes.

ReactAccessibilityWCAGTesting

Thumbnail for React Accessibility Audit Toolkit

Overview

Build an a11y testing tool that scans components for WCAG violations and suggests fixes.

Project Setup

bash
npx create-react-app react-20-react-accessibility-audit-toolkit --template typescript
cd react-20-react-accessibility-audit-toolkit
npm install accessibility wcag testing

Component Architecture

tsx
import React, { useState, useCallback, useMemo } from 'react';

interface Item {
  id: string;
  title: string;
  status: 'active' | 'completed' | 'archived';
  createdAt: Date;
}

interface ReactProps {
  initialItems?: Item[];
  onUpdate?: (items: Item[]) => void;
}

export default function ReactManager({
  initialItems = [],
  onUpdate,
}: ReactProps) {
  const [items, setItems] = useState<Item[]>(initialItems);
  const [filter, setFilter] = useState<string>('all');

  const filteredItems = useMemo(
    () => filter === 'all' ? items : items.filter(i => i.status === filter),
    [items, filter]
  );

  const addItem = useCallback((title: string) => {
    const newItem: Item = {
      id: crypto.randomUUID(),
      title,
      status: 'active',
      createdAt: new Date(),
    };
    const updated = [...items, newItem];
    setItems(updated);
    onUpdate?.(updated);
  }, [items, onUpdate]);

  const updateStatus = useCallback((id: string, status: Item['status']) => {
    const updated = items.map(item =>
      item.id === id ? { ...item, status } : item
    );
    setItems(updated);
    onUpdate?.(updated);
  }, [items, onUpdate]);

  return (
    <div className="max-w-2xl mx-auto p-6">
      <h2 className="text-2xl font-bold mb-4">React Accessibility Audit Toolkit</h2>

      <div className="flex gap-2 mb-6">
        {['all', 'active', 'completed'].map(f => (
          <button
            key={f}
            onClick={() => setFilter(f)}
            className={\`px-4 py-2 rounded-lg \${
              filter === f ? 'bg-indigo-600 text-white' : 'bg-gray-100'
            }\`}
          >
            {f.charAt(0).toUpperCase() + f.slice(1)}
          </button>
        ))}
      </div>

      <ul className="space-y-3">
        {filteredItems.map(item => (
          <li key={item.id} className="flex items-center justify-between p-4 bg-white rounded-lg shadow">
            <span className={item.status === 'completed' ? 'line-through text-gray-400' : ''}>
              {item.title}
            </span>
            <button
              onClick={() => updateStatus(item.id, item.status === 'active' ? 'completed' : 'active')}
              className="text-sm text-indigo-600 hover:text-indigo-800"
            >
              {item.status === 'active' ? 'Complete' : 'Reopen'}
            </button>
          </li>
        ))}
      </ul>

      <p className="mt-4 text-sm text-gray-500">
        Showing {filteredItems.length} of {items.length} items
      </p>
    </div>
  );
}

Custom Hook

tsx
import { useState, useEffect } from 'react';

function useLocalStorage<T>(key: string, initialValue: T) {
  const [value, setValue] = useState<T>(() => {
    try {
      const stored = localStorage.getItem(key);
      return stored ? JSON.parse(stored) : initialValue;
    } catch {
      return initialValue;
    }
  });

  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(value));
  }, [key, value]);

  return [value, setValue] as const;
}

Key Features

- Built with React and TypeScript for type safety - Uses \useMemo\ and \useCallback\ for performance optimization - Responsive design with Tailwind CSS - React, Accessibility, WCAG, Testing integration

Related Projects

Comments (0)

Leave a Comment

No comments yet. Be the first to comment!