Skip to content
Back to skills

2747 Components And Accessibility 27dffc06

ASecurity

Component Architecture and Accessibility

  • 9 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 11, 2026
designtypescriptgoreactnode

Works with

  • cli

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 2747-components-and-accessibility_27dffc06 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 2747 Components And Accessibility 27dffc06?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 2747 Components And Accessibility 27dffc06
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-2747-components-and-accessibility-27dffc06/badge)](https://www.skillsdirectory.com/skills/tools-only-2747-components-and-accessibility-27dffc06)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
---
name: elegant-design-components-and-accessibility
description: Component Architecture and Accessibility
---

# Component Architecture and Accessibility

## Component Architecture

### Atomic Design Principles

Build from small to large:
- **Atoms**: Buttons, inputs, labels
- **Molecules**: Search bar (input + button), form field (label + input + error)
- **Organisms**: Header, card, form
- **Templates**: Page layouts
- **Pages**: Specific instances

### Component Structure

```typescript
interface ButtonProps {
  variant?: 'primary' | 'secondary' | 'ghost' | 'destructive';
  size?: 'sm' | 'md' | 'lg';
  loading?: boolean;
  disabled?: boolean;
  children: React.ReactNode;
  onClick?: () => void;
  type?: 'button' | 'submit' | 'reset';
}

export function Button({ 
  variant = 'primary',
  size = 'md',
  loading = false,
  disabled = false,
  children,
  onClick,
  type = 'button'
}: ButtonProps) {
  return (
    <button
      type={type}
      className={`btn btn-${variant} btn-${size}`}
      onClick={onClick}
      disabled={disabled || loading}
      aria-busy={loading}
    >
      {loading ? <Spinner /> : children}
    </button>
  );
}
```

### Composition Over Configuration

Prefer composable components:

```typescript
// Good: Composable
<Card>
  <CardHeader>
    <CardTitle>Title</CardTitle>
  </CardHeader>
  <CardContent>
    Content here
  </CardContent>
</Card>

// Avoid: Props hell
<Card 
  title="Title"
  content="Content"
  headerActions={[...]}
  footer={...}
/>
```

## Accessibility (WCAG 2.1 AA)

### Semantic HTML

Use proper HTML elements:

```tsx
// Good
<button onClick={handleClick}>Click me</button>
<nav>...</nav>
<main>...</main>
<article>...</article>

// Bad
<div onClick={handleClick}>Click me</div>
<div className="nav">...</div>
```

### ARIA Labels

```tsx
// Icon-only button
<button aria-label="Close dialog">
  <X size={16} />
</button>

// Form field with description
<div>
  <label htmlFor="email">Email</label>
  <input 
    id="email"
    type="email"
    aria-describedby="email-hint"
  />
  <p id="email-hint">We'll never share your email</p>
</div>

// Dynamic content
<div aria-live="polite" aria-atomic="true">
  {status}
</div>
```

### Keyboard Navigation

**All interactive elements must be keyboard accessible:**

```tsx
function Dialog({ open, onClose }: DialogProps) {
  useEffect(() => {
    if (!open) return;

    const handleEscape = (e: KeyboardEvent) => {
      if (e.key === 'Escape') onClose();
    };

    document.addEventListener('keydown', handleEscape);
    return () => document.removeEventListener('keydown', handleEscape);
  }, [open, onClose]);

  return (
    <div
      role="dialog"
      aria-modal="true"
      tabIndex={-1}
    >
      {/* Dialog content */}
    </div>
  );
}
```

**Focus management:**

```tsx
function Modal({ open }: { open: boolean }) {
  const modalRef = useRef<HTMLDivElement>(null);
  const previousFocus = useRef<HTMLElement | null>(null);

  useEffect(() => {
    if (open) {
      // Save current focus
      previousFocus.current = document.activeElement as HTMLElement;
      // Focus modal
      modalRef.current?.focus();
    } else {
      // Restore focus
      previousFocus.current?.focus();
    }
  }, [open]);

  return (
    <div ref={modalRef} tabIndex={-1} role="dialog">
      {/* Modal content */}
    </div>
  );
}
```

### Color Contrast

**WCAG Requirements:**
- Normal text: 4.5:1 minimum
- Large text (18pt+ or 14pt+ bold): 3:1 minimum
- UI components: 3:1 minimum

```css
/* Good contrast */
.good-text {
  background: #ffffff;
  color: #222222; /* 16.1:1 */
}

/* Poor contrast - fails WCAG */
.poor-text {
  background: #ffffff;
  color: #999999; /* 2.8:1 */
}
```

**Test with:**
- WebAIM Contrast Checker
- Chrome DevTools accessibility panel
- axe DevTools

### Screen Reader Support

```tsx
// Skip navigation
<a href="#main-content" className="skip-link">
  Skip to main content
</a>

// Alternative text for images
<img src="..." alt="Descriptive text" />

// Hidden labels for icon buttons
<button>
  <span className="sr-only">Delete item</span>
  <Trash size={16} aria-hidden="true" />
</button>
```

```css
/* Screen reader only content */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}
```

### Forms

```tsx
function FormField({ 
  label, 
  error, 
  required,
  ...inputProps 
}: FormFieldProps) {
  const id = useId();
  const errorId = `${id}-error`;

  return (
    <div className="form-field">
      <label htmlFor={id}>
        {label}
        {required && <span aria-label="required">*</span>}
      </label>
      <input
        id={id}
        aria-invalid={!!error}
        aria-describedby={error ? errorId : undefined}
        aria-required={required}
        {...inputProps}
      />
      {error && (
        <p id={errorId} className="error" role="alert">
          {error}
        </p>
      )}
    </div>
  );
}
```

## Best Practices

### Do:
- ✅ Use semantic HTML elements
- ✅ Provide ARIA labels for icon-only buttons
- ✅ Ensure keyboard navigation works
- ✅ Test with screen readers
- ✅ Maintain focus management in modals
- ✅ Provide skip navigation links
- ✅ Use proper heading hierarchy (h1-h6)
- ✅ Ensure 4.5:1 contrast for text
- ✅ Make forms accessible with labels and errors

### Don't:
- ❌ Use divs for buttons
- ❌ Forget alt text for images
- ❌ Trap keyboard focus
- ❌ Rely only on color to convey information
- ❌ Use tiny touch targets (< 44x44px)
- ❌ Forget to test with keyboard only
- ❌ Use placeholder as label
- ❌ Auto-play media without controls

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.