Files
blackcanyontickets/reactrebuild0825/docs/ui-primitives.md
dzinesco f777ef760b docs: add comprehensive Phase 2 documentation
- Create detailed README.md with quick start and demo accounts
- Add complete UI primitives documentation with examples
- Document architecture patterns and design decisions
- Update REBUILD_PLAN.md marking Phase 2 as complete
- Include component usage guides and testing documentation
- Document accessibility compliance and performance considerations

Documentation provides complete developer onboarding experience
with practical examples and architectural guidance.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-16 12:46:03 -06:00

14 KiB

UI Primitives Documentation

A comprehensive guide to the Black Canyon Tickets component library featuring production-ready UI primitives with WCAG AA accessibility compliance.

Design System Foundation

Design Tokens Integration

All components use CSS custom properties from our design token system:

/* Automatically available in all components */
--color-primary-50 through --color-primary-950
--color-surface-primary, --color-surface-secondary
--color-text-primary, --color-text-secondary
--font-size-xs through --font-size-4xl
--spacing-1 through --spacing-20
--border-radius-sm through --border-radius-2xl

Theme Support

Every component automatically supports light and dark themes without additional configuration.

Core UI Primitives

Button Component

Production-ready button with multiple variants, sizes, and states.

Props Interface

interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger';
  size?: 'sm' | 'md' | 'lg' | 'xl';
  loading?: boolean;
  leftIcon?: React.ReactNode;
  rightIcon?: React.ReactNode;
  fullWidth?: boolean;
}

Usage Examples

import { Button } from '@/components/ui/Button';
import { PlusIcon, ArrowRightIcon } from 'lucide-react';

// Basic variants
<Button variant="primary">Primary Action</Button>
<Button variant="secondary">Secondary Action</Button>
<Button variant="outline">Outline Button</Button>
<Button variant="ghost">Ghost Button</Button>
<Button variant="danger">Delete Item</Button>

// Sizes
<Button size="sm">Small</Button>
<Button size="md">Medium (default)</Button>
<Button size="lg">Large</Button>
<Button size="xl">Extra Large</Button>

// With icons
<Button leftIcon={<PlusIcon size={16} />}>
  Add Event
</Button>

<Button rightIcon={<ArrowRightIcon size={16} />}>
  Continue
</Button>

// Loading state
<Button loading>Processing...</Button>

// Full width
<Button fullWidth variant="primary">
  Full Width Button
</Button>

Accessibility Features

  • Keyboard Navigation: Full keyboard support with Enter/Space activation
  • Focus Management: Visible focus indicators with proper contrast
  • Screen Reader: Proper button semantics and loading state announcements
  • Touch Targets: Minimum 44px touch target size on mobile

Input Component

Comprehensive form input with validation, labels, and help text.

Props Interface

interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
  label?: string;
  helperText?: string;
  error?: string;
  leftIcon?: React.ReactNode;
  rightIcon?: React.ReactNode;
  variant?: 'default' | 'filled';
}

Usage Examples

import { Input } from '@/components/ui/Input';
import { MailIcon, EyeIcon, EyeOffIcon } from 'lucide-react';

// Basic input with label
<Input
  label="Email Address"
  type="email"
  placeholder="enter your email"
  required
/>

// With helper text
<Input
  label="Password"
  type="password"
  helperText="Must be at least 8 characters"
/>

// With error state
<Input
  label="Username"
  error="Username is already taken"
  value={username}
  onChange={setUsername}
/>

// With icons
<Input
  label="Search Events"
  leftIcon={<SearchIcon size={16} />}
  placeholder="Search by name or venue"
/>

// Filled variant
<Input
  variant="filled"
  label="Event Description"
  placeholder="Describe your event"
/>

Validation Integration

// With React Hook Form
import { useForm } from 'react-hook-form';

const { register, formState: { errors } } = useForm();

<Input
  label="Email"
  {...register('email', { 
    required: 'Email is required',
    pattern: {
      value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
      message: 'Invalid email address'
    }
  })}
  error={errors.email?.message}
/>

Accessibility Features

  • Label Association: Proper label-input association with unique IDs
  • Error Announcement: Screen reader announcements for validation errors
  • Required Indicators: Visual and semantic required field indicators
  • Keyboard Navigation: Full keyboard support with Tab navigation

Select Component

Accessible dropdown selection with search and custom styling.

Props Interface

interface SelectOption {
  value: string;
  label: string;
  disabled?: boolean;
}

interface SelectProps {
  options: SelectOption[];
  value?: string;
  defaultValue?: string;
  placeholder?: string;
  label?: string;
  error?: string;
  disabled?: boolean;
  required?: boolean;
  onChange?: (value: string) => void;
}

Usage Examples

import { Select } from '@/components/ui/Select';

const ticketTypes = [
  { value: 'general', label: 'General Admission' },
  { value: 'vip', label: 'VIP Access' },
  { value: 'student', label: 'Student Discount' }
];

// Basic select
<Select
  label="Ticket Type"
  options={ticketTypes}
  placeholder="Choose ticket type"
  onChange={setSelectedType}
/>

// With error state
<Select
  label="Event Category"
  options={categories}
  error="Please select a category"
  required
/>

// Disabled option
const venues = [
  { value: 'main', label: 'Main Hall' },
  { value: 'ballroom', label: 'Grand Ballroom' },
  { value: 'outdoor', label: 'Outdoor Stage', disabled: true }
];

Accessibility Features

  • Keyboard Navigation: Arrow keys, Enter, Escape, Tab support
  • Screen Reader: Proper combobox semantics with expanded/collapsed states
  • Focus Management: Visible focus indicators for options
  • ARIA Labels: Comprehensive ARIA labeling for complex interactions

Card Component

Flexible container component with multiple variants and compositional API.

Props Interface

interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
  variant?: 'default' | 'outlined' | 'elevated';
  padding?: 'none' | 'sm' | 'md' | 'lg';
}

Usage Examples

import { Card } from '@/components/ui/Card';

// Basic card
<Card>
  <h3>Event Details</h3>
  <p>Join us for an unforgettable evening</p>
</Card>

// Card variants
<Card variant="outlined" padding="lg">
  <Card.Header>
    <h2>Premium Event</h2>
    <Badge variant="success">Available</Badge>
  </Card.Header>
  <Card.Content>
    <p>Exclusive access to premium seating</p>
  </Card.Content>
  <Card.Footer>
    <Button variant="primary">Purchase Tickets</Button>
  </Card.Footer>
</Card>

// Elevated card for important content
<Card variant="elevated" className="hover:shadow-lg transition-shadow">
  <EventCard event={event} />
</Card>

Compositional API

// Using sub-components for structured layout
<Card>
  <Card.Header className="border-b">
    <div className="flex justify-between items-center">
      <h3>Order Summary</h3>
      <Button variant="ghost" size="sm">Edit</Button>
    </div>
  </Card.Header>
  
  <Card.Content className="space-y-4">
    <OrderLineItem />
    <OrderLineItem />
  </Card.Content>
  
  <Card.Footer className="border-t bg-surface-secondary">
    <div className="flex justify-between font-semibold">
      <span>Total</span>
      <span>$149.00</span>
    </div>
  </Card.Footer>
</Card>

Alert Component

Status messages and notifications with multiple severity levels.

Props Interface

interface AlertProps {
  variant?: 'info' | 'success' | 'warning' | 'error';
  title?: string;
  children: React.ReactNode;
  icon?: React.ReactNode;
  dismissible?: boolean;
  onDismiss?: () => void;
}

Usage Examples

import { Alert } from '@/components/ui/Alert';
import { CheckCircleIcon, AlertTriangleIcon } from 'lucide-react';

// Success alert
<Alert variant="success" title="Order Confirmed">
  Your tickets have been purchased successfully. Check your email for confirmation.
</Alert>

// Warning alert
<Alert variant="warning" title="Limited Availability">
  Only 3 tickets remaining for this event.
</Alert>

// Error alert with custom icon
<Alert 
  variant="error" 
  icon={<AlertTriangleIcon size={20} />}
  dismissible
  onDismiss={hideAlert}
>
  Payment processing failed. Please try again or contact support.
</Alert>

// Info alert without title
<Alert variant="info">
  Event details have been updated. Refresh to see changes.
</Alert>

Accessibility Features

  • ARIA Roles: Proper alert/alertdialog roles for screen readers
  • Color Independence: Icons and text convey meaning beyond color
  • Focus Management: Dismissible alerts receive appropriate focus
  • Live Regions: Dynamic alerts announced to screen readers

Badge Component

Small status indicators and labels with semantic meaning.

Props Interface

interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
  variant?: 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'error';
  size?: 'sm' | 'md' | 'lg';
  pill?: boolean;
}

Usage Examples

import { Badge } from '@/components/ui/Badge';

// Status badges
<Badge variant="success">Available</Badge>
<Badge variant="warning">Limited</Badge>
<Badge variant="error">Sold Out</Badge>

// Different sizes
<Badge size="sm">New</Badge>
<Badge size="md">Featured</Badge>
<Badge size="lg">Premium</Badge>

// Pill style
<Badge variant="primary" pill>VIP Access</Badge>

// In context with event cards
<EventCard>
  <div className="flex justify-between items-start">
    <h3>Concert Night</h3>
    <Badge variant="success">Available</Badge>
  </div>
</EventCard>

Component Composition Patterns

Form Composition

import { Card, Input, Select, Button, Alert } from '@/components/ui';

function EventForm() {
  return (
    <Card variant="outlined" padding="lg">
      <Card.Header>
        <h2>Create New Event</h2>
      </Card.Header>
      
      <Card.Content className="space-y-6">
        {error && (
          <Alert variant="error" dismissible onDismiss={clearError}>
            {error}
          </Alert>
        )}
        
        <Input
          label="Event Name"
          placeholder="Enter event name"
          required
        />
        
        <Select
          label="Event Category"
          options={categories}
          placeholder="Select category"
        />
        
        <Input
          label="Description"
          multiline
          rows={4}
          placeholder="Describe your event"
        />
      </Card.Content>
      
      <Card.Footer>
        <div className="flex gap-3">
          <Button variant="outline" fullWidth>
            Save Draft
          </Button>
          <Button variant="primary" fullWidth>
            Publish Event
          </Button>
        </div>
      </Card.Footer>
    </Card>
  );
}

Status Display Pattern

import { Badge, Alert, Button } from '@/components/ui';

function TicketStatus({ ticket }) {
  const getStatusBadge = (status) => {
    const variants = {
      available: 'success',
      limited: 'warning', 
      sold_out: 'error'
    };
    
    return (
      <Badge variant={variants[status]}>
        {status.replace('_', ' ').toUpperCase()}
      </Badge>
    );
  };
  
  return (
    <div className="space-y-4">
      <div className="flex justify-between items-center">
        <h3>{ticket.name}</h3>
        {getStatusBadge(ticket.status)}
      </div>
      
      {ticket.status === 'limited' && (
        <Alert variant="warning">
          Only {ticket.remaining} tickets left
        </Alert>
      )}
      
      <Button 
        variant="primary" 
        disabled={ticket.status === 'sold_out'}
        fullWidth
      >
        {ticket.status === 'sold_out' ? 'Sold Out' : 'Purchase'}
      </Button>
    </div>
  );
}

Design Token Usage

Color System

// Using semantic color tokens
<div className="bg-surface-primary text-text-primary border border-border-primary">
  Content with theme-aware colors
</div>

// Status colors
<Alert variant="success"> // Uses --color-success-* tokens
<Badge variant="error">   // Uses --color-error-* tokens

Typography Scale

// Using typography tokens
<h1 className="text-4xl">Main Heading</h1>     // --font-size-4xl
<h2 className="text-2xl">Section Heading</h2>  // --font-size-2xl
<p className="text-base">Body text</p>         // --font-size-base
<small className="text-sm">Helper text</small> // --font-size-sm

Spacing System

// Using spacing tokens
<div className="p-4 m-2 space-y-6">          // --spacing-4, --spacing-2, --spacing-6
  <Card padding="lg">                         // --spacing-8 (internal)
    <div className="space-between-3">         // --spacing-3

Testing Components

All UI primitives include comprehensive test coverage:

// Example test for Button component
test('Button renders with correct variant styles', async ({ page }) => {
  await page.goto('/ui-showcase');
  
  // Test primary variant
  const primaryButton = page.getByTestId('button-primary');
  await expect(primaryButton).toHaveClass(/bg-primary/);
  
  // Test accessibility
  await expect(primaryButton).toBeEnabled();
  await primaryButton.focus();
  await expect(primaryButton).toBeFocused();
  
  // Test keyboard interaction
  await primaryButton.press('Enter');
  await expect(page.getByText('Button clicked')).toBeVisible();
});

Accessibility Compliance

WCAG AA Standards

All components meet WCAG AA requirements:

  • Color Contrast: 4.5:1 minimum ratio for normal text, 3:1 for large text
  • Keyboard Navigation: Full keyboard support for all interactive elements
  • Screen Reader Support: Proper semantic HTML and ARIA labels
  • Focus Management: Visible focus indicators with sufficient contrast

Testing Tools

# Run accessibility tests
npm run test:a11y

# Generate accessibility report  
npm run a11y:report

# Visual contrast validation
npm run test:contrast

Performance Considerations

Bundle Size Optimization

  • Tree Shaking: Import only the components you need
  • CSS Custom Properties: Reduced CSS bundle size with design tokens
  • Minimal Dependencies: Core components have zero external dependencies
// Efficient imports
import { Button, Input } from '@/components/ui'; // Tree-shaken

// Avoid importing entire library
import * as UI from '@/components/ui'; // Not recommended

Runtime Performance

  • Memoization: Components use React.memo where appropriate
  • Event Handling: Optimized event listeners with proper cleanup
  • Re-render Optimization: Props designed to minimize unnecessary re-renders

Component library built with CrispyGoat quality standards - accessible, performant, and developer-friendly.