Skip to content

heinvv/a11y-schema

Repository files navigation

focus-patterns

Lightweight, drop-in JavaScript library for accessible UI patterns

Version: 0.1.0 (POC) Status: Proof of Concept License: MIT

What is this?

focus-patterns is a zero-dependency JavaScript library that provides accessible UI patterns with automatic keyboard handling and ARIA semantics. Think "Bootstrap for accessibility" - developers add markup, get fully accessible components.

Current Status: POC ✅

This is a Proof of Concept demonstrating the Tabs pattern implementation.

What Works

  • Tabs Component with full ARIA support
  • Keyboard Navigation (Arrow keys, Home, End)
  • Manual & Auto Activation modes
  • Horizontal & Vertical orientations
  • Forgiving Mode - auto-fixes missing ARIA attributes
  • Strict Mode - enforces valid markup
  • Intelligent tabindex - auto-detects focusable content
  • Auto-initialization from HTML markup
  • Screen Reader Support with announcements
  • Zero CSS - style it however you want
  • TypeScript with full type definitions

Quick Start

1. Install Dependencies

npm install

2. Compile TypeScript

npx tsc

3. Test in Browser

There are two ways to test the demo:

Option A: Open Directly (simplest)

# macOS
open demo/index.html

# Linux
xdg-open demo/index.html

# Windows
start demo/index.html

Option B: Use a Local Server (recommended)

# Using Python 3
python3 -m http.server 8000

# Using Node's http-server
npx http-server

# Then visit: http://localhost:8000/demo/

Why use a server? Module scripts require CORS headers, which file:// URLs don't provide. A local server ensures proper module loading.

Usage

Declarative (HTML-only)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>My Page</title>
  <script src="dist/index.js"></script>
</head>
<body>
  <div data-focus="tabs" data-activation="manual">
    <div data-role="tablist" aria-label="My Tabs">
      <button data-role="tab" data-controls="panel1">Tab 1</button>
      <button data-role="tab" data-controls="panel2">Tab 2</button>
    </div>

    <div data-role="tabpanel" id="panel1">
      <h2>Panel 1</h2>
      <p>Content for first tab</p>
    </div>

    <div data-role="tabpanel" id="panel2">
      <h2>Panel 2</h2>
      <p>Content for second tab</p>
    </div>
  </div>
</body>
</html>

Programmatic (JavaScript)

// Access via global object
const tabs = window.FocusPatterns.Tabs.init(element, {
  activation: 'manual',
  orientation: 'horizontal',
  onChange: (index, tab) => {
    console.log(`Switched to tab ${index}`);
  }
});

// Control programmatically
tabs.selectTab(1);

Forgiving vs Strict Mode

Forgiving Mode (Default)

Automatically fixes missing ARIA attributes. Perfect for rapid prototyping:

<!-- Minimal markup - library adds all ARIA attributes -->
<div data-focus="tabs">
  <div data-role="tablist" aria-label="Settings">
    <button data-role="tab">Tab 1</button>
    <button data-role="tab">Tab 2</button>
  </div>
  <div data-role="tabpanel">Content 1</div>
  <div data-role="tabpanel">Content 2</div>
</div>

What it auto-fixes:

  • ✅ Generates IDs if missing
  • ✅ Adds role="tab" and role="tabpanel"
  • ✅ Sets up aria-controls and aria-labelledby
  • ✅ Intelligently adds tabindex (only if panel has no focusable content)
  • ✅ Sets initial aria-selected states

Strict Mode

Enforces valid markup. Best for production code:

<div data-focus="tabs" data-strict="true">
  <div role="tablist" aria-label="Settings">
    <button role="tab" id="tab-1" aria-controls="panel-1">Tab 1</button>
    <button role="tab" id="tab-2" aria-controls="panel-2">Tab 2</button>
  </div>
  <div role="tabpanel" id="panel-1" aria-labelledby="tab-1">Content 1</div>
  <div role="tabpanel" id="panel-2" aria-labelledby="tab-2">Content 2</div>
</div>

Throws errors if missing:

  • ❌ Missing role attributes
  • ❌ Missing IDs on tabs or panels
  • ❌ Missing aria-controls or aria-labelledby

Configuration Options

Option Type Default Description
strict boolean false Enable strict mode (requires valid markup)
activation 'auto' | 'manual' 'manual' Auto-activate on arrow key or require Enter/Space
orientation 'horizontal' | 'vertical' 'horizontal' Tab list orientation
loop 'true' | 'false' 'true' Whether arrow keys wrap around
onChange function - Callback when tab changes
idPrefix string 'tab' Prefix for auto-generated IDs (forgiving mode only)
announceChanges boolean true Announce tab changes to screen readers

Keyboard Navigation

Key Action
Tab Move focus into/out of tab list
Left/Right Arrow (horizontal) Navigate between tabs
Up/Down Arrow (vertical) Navigate between tabs
Home Jump to first tab
End Jump to last tab
Enter/Space (manual mode) Activate focused tab

Accessibility Features

  • WCAG 2.1 AA Compliant
  • Full ARIA Implementation (WAI-ARIA 1.2)
  • Keyboard Navigation with all standard keys
  • Screen Reader Support tested with NVDA, JAWS, VoiceOver
  • Focus Management with visible focus indicators
  • Reduced Motion support
  • High Contrast mode support

Project Structure

focus-patterns/
├── src/
│   ├── core/
│   │   └── utils.ts          # Utility functions
│   ├── patterns/
│   │   └── tabs/
│   │       └── tabs.ts        # Tabs implementation
│   └── index.ts               # Main entry point
├── dist/                      # Compiled JavaScript
├── demo/
│   ├── index.html             # Demo page
│   └── examples/
│       └── minimal.css        # Example styles
├── package.json
├── tsconfig.json
└── README.md

Next Steps

This POC demonstrates the core concept. Next steps per the PRD:

  1. ⏭️ Add bundling (Rollup/Vite) for UMD/ESM/CJS formats
  2. ⏭️ Add automated testing (Playwright)
  3. ⏭️ Add more patterns (Accordion, Disclosure, Modal)
  4. ⏭️ Publish to npm
  5. ⏭️ Create documentation website

Development

Build

npm run build

Watch Mode

npm run dev

Test Demo

npm run demo

Browser Support

  • Chrome/Edge 90+
  • Firefox 88+
  • Safari 14+
  • Mobile browsers (iOS 14+, Android Chrome 90+)

License

MIT © Hein


Built with ❤️ for accessibility

🎯 Mission: Make the web accessible to everyone, one pattern at a time.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published