Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
3232379
wip: add A11y Devtools plugin with accessibility auditing features
LadyBluenotes Jan 13, 2026
6bf0698
wip: enhance accessibility panel with improved issue handling and UI …
LadyBluenotes Jan 13, 2026
e52240c
wip: refine issue highlighting to respect threshold settings in acces…
LadyBluenotes Jan 13, 2026
83fb022
wip: implement settings panel for managing accessibility rules and co…
LadyBluenotes Jan 13, 2026
c5b1138
wip: add custom accessibility rules for enhanced auditing and issue d…
LadyBluenotes Jan 13, 2026
2e2c405
wip: enhance tooltip positioning logic for better visibility and acce…
LadyBluenotes Jan 13, 2026
fc24498
wip: remove live monitoring feature and related configurations
LadyBluenotes Jan 13, 2026
bde001a
wip: enhance tooltip functionality to display all issues per element …
LadyBluenotes Jan 13, 2026
49e24f4
wip: reorganize plugin registry and update tags for accessibility plugin
LadyBluenotes Jan 13, 2026
faa6128
wip: add rootSelector option for scoped accessibility audits and enha…
LadyBluenotes Jan 13, 2026
b15c9f7
wip: implement live monitoring feature with customizable delay and en…
LadyBluenotes Jan 19, 2026
ecb4333
ci: apply automated fixes
autofix-ci[bot] Jan 21, 2026
9ec4090
wip: refactor to Solid etcetc using AI
LadyBluenotes Jan 21, 2026
7be0dab
wip: refactor accessibility components and introduce issue filtering …
LadyBluenotes Jan 24, 2026
91bda6f
ci: apply automated fixes
autofix-ci[bot] Jan 24, 2026
93bb55c
wip: update type imports for panel styles in accessibility components
LadyBluenotes Jan 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
262 changes: 262 additions & 0 deletions docs/plugins/a11y.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
---
title: Accessibility Plugin
id: a11y-plugin
---

The TanStack Devtools Accessibility (A11y) Plugin provides real-time accessibility auditing for your web applications, powered by [axe-core](https://github.com/dequelabs/axe-core). It helps you identify and fix accessibility issues during development.

## Features

- **Full Page Scanning** - Audit your entire page for accessibility violations
- **Component-Level Scanning** - Scope audits to specific components using React hooks
- **Live Monitoring** - Automatically re-scan when the DOM changes
- **Visual Overlays** - Highlight problematic elements with severity-based colors
- **Click-to-Navigate** - Click on an issue to automatically scroll to and highlight the element
- **Dark Mode Support** - Automatically adapts to the devtools theme
- **Devtools-Aware** - Automatically excludes devtools panels from scanning
- **Configurable Rule Sets** - Support for WCAG 2.0/2.1/2.2 (A/AA/AAA), Section 508, and best practices
- **Export Reports** - Download results as JSON or CSV
- **Persistent Settings** - Configuration saved to localStorage

## Installation

```bash
npm install @tanstack/devtools-a11y
# or
pnpm add @tanstack/devtools-a11y
# or
yarn add @tanstack/devtools-a11y
```

## Quick Start (React)

```tsx
import { createRoot } from 'react-dom/client'
import { TanStackDevtools } from '@tanstack/react-devtools'
import { a11yDevtoolsPlugin } from '@tanstack/devtools-a11y/react'

createRoot(document.getElementById('root')!).render(
<>
<App />
<TanStackDevtools plugins={[a11yDevtoolsPlugin()]} />
</>,
)
```

## Quick Start (Solid)

```tsx
import { render } from 'solid-js/web'
import { TanStackDevtools } from '@tanstack/solid-devtools'
import { a11yDevtoolsPlugin } from '@tanstack/devtools-a11y/solid'

render(
() => (
<>
<App />
<TanStackDevtools plugins={[a11yDevtoolsPlugin()]} />
</>
),
document.getElementById('root')!,
)
```

## Quick Start (Vue)

```ts
import { createA11yDevtoolsVuePlugin } from '@tanstack/devtools-a11y/vue'

const plugins = [createA11yDevtoolsVuePlugin()]
```

## Click-to-Navigate

When you click on an issue in the panel, the plugin will:

1. **Scroll** the problematic element into view (centered in the viewport)
2. **Highlight** the element with a pulsing overlay matching its severity color
3. **Show a tooltip** with the rule ID and impact level

This makes it easy to locate and inspect issues directly on the page.

## Panel Configuration

Initial configuration can be provided via the vanilla plugin API:

```ts
import { createA11yPlugin } from '@tanstack/devtools-a11y'

const plugin = createA11yPlugin({
ruleSet: 'wcag21aa',
threshold: 'moderate',
runOnMount: true,
liveMonitoring: true,
liveMonitoringDelay: 1000,
showOverlays: true,
})
```

Common `options` fields:

- `threshold`: minimum impact level to show
- `ruleSet`: rule preset (`'wcag2a' | 'wcag2aa' | 'wcag21aa' | 'wcag22aa' | 'section508' | 'best-practice' | 'all'`)
- `disabledRules`: rule IDs to ignore
- `showOverlays`: highlight issues in the page
- `runOnMount`: auto-scan when panel mounts
- `persistSettings`: store config in localStorage
- `liveMonitoring`: watch DOM mutations and re-scan automatically
- `liveMonitoringDelay`: debounce delay (ms)

If you don't need to provide initial configuration, you can use the framework plugin helpers
directly (the settings UI persists changes to localStorage by default).

## Severity Levels

Issues are categorized by impact level with corresponding overlay colors:

| Impact | Color | Description |
|--------|-------|-------------|
| Critical | Red | Must be fixed - prevents users from accessing content |
| Serious | Orange | Should be fixed - significantly impacts user experience |
| Moderate | Yellow | Consider fixing - affects some users |
| Minor | Blue | Optional improvement - minor impact |

## Framework Support

The panel UI is implemented in Solid and wrapped for React, Solid, Preact, and Vue
using `@tanstack/devtools-utils`.

## Vanilla JavaScript API

For non-React applications, `createA11yPlugin()` exposes a small programmatic API in addition to the TanStack Devtools `render()` integration:

```ts
import { createA11yPlugin } from '@tanstack/devtools-a11y'

const plugin = createA11yPlugin({
ruleSet: 'wcag21aa',
liveMonitoring: true,
showOverlays: true,
})

// Run a scan
const result = await plugin.scan?.()

// Subscribe to scan results (manual or live)
const unsubscribe = plugin.onScan?.((next) => {
console.log('Issues found:', next.issues.length)
})

// Control live monitoring
plugin.startLiveMonitoring?.()
plugin.stopLiveMonitoring?.()

// Clean up
unsubscribe?.()
plugin.destroy?.()
```

## Export Formats

### JSON Export

```ts
import { exportToJSON } from '@tanstack/devtools-a11y'

const jsonString = exportToJSON(auditResult)
```

### CSV Export

```ts
import { exportToCSV } from '@tanstack/devtools-a11y'

const csvString = exportToCSV(auditResult)
```

## Supported Standards

The plugin supports the following accessibility standards:

- **WCAG 2.0** Level A, AA, AAA
- **WCAG 2.1** Level A, AA, AAA
- **WCAG 2.2** Level AA
- **Section 508**
- **Best Practices** (non-standard recommendations)

## Types

```ts
interface A11yIssue {
id: string
ruleId: string
impact: 'critical' | 'serious' | 'moderate' | 'minor'
description: string
help: string
helpUrl: string
selector: string
html: string
failureSummary: string
tags: string[]
}

interface A11yAuditResult {
timestamp: number
url: string
standard: string
issues: A11yIssue[]
passes: number
violations: number
incomplete: number
scanDuration: number
}

interface A11yConfig {
standard: string
liveMonitoring: boolean
showOverlays: boolean
scopedMode: boolean
scopeSelector?: string
excludeSelectors: string[]
includeRules: string[]
excludeRules: string[]
}
```

## Performance Considerations

- **Live monitoring** uses a debounced MutationObserver to avoid excessive re-scanning
- **Scoped scanning** is recommended for large pages to reduce scan time
- **Exclude selectors** can skip third-party widgets or known-good sections
- The first scan may be slower as axe-core initializes

## Troubleshooting

### Issues not appearing

1. Check that the element is visible in the viewport
2. Ensure the element is not excluded by `excludeSelectors`
3. Verify the selected standard includes the relevant rule

### Overlays not showing

1. Confirm overlays are enabled in the panel settings
2. Check for CSS conflicts with `z-index` or `pointer-events`
3. Ensure the container element exists in the DOM

### Performance issues

1. Disable live monitoring for large/complex pages
2. Use scoped scanning to limit the audit area
3. Increase the debounce delay for live monitoring

## Example

See the full working example at:
`examples/react/a11y-devtools/`

Run it with:
```bash
cd examples/react/a11y-devtools
pnpm dev
```
16 changes: 16 additions & 0 deletions examples/react/a11y-devtools/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/emblem-light.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />

<title>A11y Devtools - TanStack Devtools</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="module" src="/src/index.tsx"></script>
</body>
</html>
35 changes: 35 additions & 0 deletions examples/react/a11y-devtools/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"name": "@tanstack/devtools-a11y-example",
"private": true,
"type": "module",
"scripts": {
"dev": "vite --port=3002",
"build": "vite build",
"preview": "vite preview",
"test:types": "tsc"
},
"dependencies": {
"@tanstack/devtools-a11y": "workspace:*",
"@tanstack/react-devtools": "workspace:*",
"react": "^19.2.0",
"react-dom": "^19.2.0"
},
"devDependencies": {
"@types/react": "^19.2.0",
"@types/react-dom": "^19.2.0",
"@vitejs/plugin-react": "^5.0.4",
"vite": "^7.1.7"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
Loading
Loading