flutter_accessibility_scanner 1.1.0 copy "flutter_accessibility_scanner: ^1.1.0" to clipboard
flutter_accessibility_scanner: ^1.1.0 copied to clipboard

Scan Flutter widget trees for WCAG 2.1 accessibility issues (missing labels, low contrast, small tap targets, focus) with fix hints and JSON reports.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_accessibility_scanner/flutter_accessibility_scanner.dart';

void main() {
  runApp(const MyApp());
}

/// Demo app. The floating accessibility button (debug builds) scans the
/// current screen and outlines every issue it finds.
class MyApp extends StatelessWidget {
  /// Creates the demo app.
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Accessibility Scanner Demo',
      theme: ThemeData(colorSchemeSeed: Colors.indigo),
      builder: (context, child) => AccessibilityScannerWidget(
        onReport: (report) => debugPrint(report.summary),
        child: child!,
      ),
      home: const MyHomePage(),
    );
  }
}

/// A page with deliberately good and bad examples side by side.
class MyHomePage extends StatefulWidget {
  /// Creates the page.
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  AccessibilityReport? _report;

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    return Scaffold(
      appBar: AppBar(title: const Text('Accessibility Scanner Demo')),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          Text('Bad: tiny, unlabeled button',
              style: theme.textTheme.titleSmall),
          const SizedBox(height: 8),
          Align(
            alignment: Alignment.centerLeft,
            child: GestureDetector(
              onTap: () => _showSnackBar('Tapped bad button'),
              child: Container(
                width: 30,
                height: 30,
                color: Colors.grey[300],
                child: Icon(Icons.star, color: Colors.grey[400]),
              ),
            ),
          ),
          const SizedBox(height: 20),
          Text('Good: AccessibilityFixerButton',
              style: theme.textTheme.titleSmall),
          const SizedBox(height: 8),
          Align(
            alignment: Alignment.centerLeft,
            child: AccessibilityFixerButton(
              onPressed: () => _showSnackBar('Tapped good button'),
              semanticsLabel: 'Add to favorites',
              semanticsHint: 'Adds this item to your favorites list',
              child: const Icon(Icons.star, color: Colors.indigo),
            ),
          ),
          const SizedBox(height: 20),
          Text('Bad: low-contrast text', style: theme.textTheme.titleSmall),
          const SizedBox(height: 8),
          Text(
            'This text has poor contrast and is hard to read',
            style: TextStyle(color: Colors.grey[400]),
          ),
          const SizedBox(height: 20),
          Text('Good: AccessibilityFixerText',
              style: theme.textTheme.titleSmall),
          const SizedBox(height: 8),
          AccessibilityFixerText(
            text: 'This text is darkened just enough to pass WCAG AA',
            style: TextStyle(color: Colors.grey[400], fontSize: 16),
            backgroundColor: theme.colorScheme.surface,
          ),
          const SizedBox(height: 30),
          FilledButton.icon(
            onPressed: _performManualScan,
            icon: const Icon(Icons.accessibility),
            label: const Text('Run manual accessibility scan'),
          ),
          if (_report != null) ...[
            const SizedBox(height: 20),
            Text(
              'Found ${_report!.totalIssues} issues',
              style: theme.textTheme.titleMedium,
            ),
            for (final issue in _report!.issues)
              ListTile(
                dense: true,
                title: Text(issue.description),
                subtitle: Text(
                  '${issue.severity.name} · WCAG ${issue.wcagCriterion ?? '-'}'
                  '\n${issue.suggestion ?? ''}',
                ),
              ),
          ],
        ],
      ),
    );
  }

  void _showSnackBar(String message) {
    ScaffoldMessenger.of(context)
        .showSnackBar(SnackBar(content: Text(message)));
  }

  Future<void> _performManualScan() async {
    final report = await AccessibilityScanner().scan(context);
    if (!mounted) return;
    setState(() => _report = report);
    _showSnackBar('Scan complete: ${report.totalIssues} issues found');
  }
}
7
likes
160
points
15.5k
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Scan Flutter widget trees for WCAG 2.1 accessibility issues (missing labels, low contrast, small tap targets, focus) with fix hints and JSON reports.

Repository (GitHub)
View/report issues

Topics

#accessibility #a11y #wcag #semantics #testing

License

MIT (license)

Dependencies

flutter

More

Packages that depend on flutter_accessibility_scanner