Project Structure

Last updated on 2026-04-14

The A11y Starter Kit follows Next.js App Router conventions with a clean separation between pages, components, hooks, and data.

Directory Layout

a11y-starter-kit/
├── app/
│   ├── layout.tsx            # Root layout with skip link, theme provider
│   ├── page.tsx              # Landing page
│   ├── globals.css           # Design tokens (oklch)
│   ├── dashboard/
│   │   └── page.tsx          # Dashboard page
│   ├── data-table/
│   │   └── page.tsx          # Data table page
│   ├── settings/
│   │   └── page.tsx          # Settings page
│   ├── login/
│   │   └── page.tsx          # Login page
│   └── notifications/
│       └── page.tsx          # Notifications page
├── components/
│   ├── a11y/                 # Accessibility utility components
│   │   ├── live-region.tsx   # ARIA live region for announcements
│   │   └── visually-hidden.tsx # Screen-reader-only text
│   ├── dashboard/            # Dashboard-specific composites
│   ├── data-table/           # Table composites
│   ├── forms/                # Form composites
│   ├── layout/               # Layout components (sidebar, header, skip link)
│   ├── notifications/        # Notification composites
│   └── ui/                   # shadcn/ui primitives
├── hooks/
│   ├── use-announce.ts       # Screen reader announcements via live region
│   ├── use-focus-trap.ts     # Focus trapping for modals and dialogs
│   ├── use-keyboard-navigation.ts # Arrow key navigation for lists/menus
│   ├── use-mobile.ts         # Mobile breakpoint detection
│   └── use-reduced-motion.ts # Respects prefers-reduced-motion
├── data/
│   └── seed.ts               # Mock data for all pages
├── types/
│   └── index.ts              # TypeScript interfaces
└── public/                   # Static assets

Component Hierarchy (3-Tier)

The kit follows a three-tier component hierarchy:

1. Primitives (components/ui/)

shadcn/ui components -- Button, Input, Card, Table, Tabs, Dialog, etc. These are never modified directly.

2. Composites (components/{domain}/)

Domain-specific components built from primitives:

  • components/dashboard/ -- StatCard, ActivityFeed, SidebarNav
  • components/data-table/ -- SortableHeader, FilterBar, Pagination
  • components/forms/ -- FormField, FormError, PasswordInput
  • components/layout/ -- AppSidebar, Header, SkipLink, Breadcrumbs
  • components/notifications/ -- NotificationList, NotificationModal

3. Pages (app/{route}/page.tsx)

Pages wire composites with seed data. Each page is a thin orchestrator.

Accessibility Layer (components/a11y/ + hooks/)

The accessibility utilities live in two places:

  • components/a11y/ -- Reusable components: LiveRegion (ARIA live announcements), VisuallyHidden (screen-reader-only text)
  • hooks/ -- Custom React hooks: useFocusTrap, useKeyboardNavigation, useAnnounce, useReducedMotion, useMobile

These are standalone and can be copied into any React project.

Data Layer

  • All mock data lives in data/seed.ts
  • Types are defined in types/index.ts
  • Pages import directly from seed data -- replace with API calls for production