Claude написал React DatePicker, но добиться WCAG-доступности заняло ещё 3 дня

Claude сгенерировал React DatePicker с ARIA-атрибутами и клавиатурной навигацией — за минуты. Но когда запустили NVDA и VoiceOver, обнаружились серьёзные проблемы: фокус выходил за диалог, даты озвучивались неверно, Escape оставлял пользователя без контекста, а режим высокой контрастности ломал визуальные состояния. На реальную WCAG-доступность ушло ещё три дня ручной работы.

AI-обработка оригинала Habr AI; редакция Hamidun News
Claude написал React DatePicker, но добиться WCAG-доступности заняло ещё 3 дня
Источник: Habr AI. Коллаж: Hamidun News.
Слушать статью

Команда разработчиков попросила Claude создать кастомный DatePicker на React для формы записи к врачу — с полноценной поддержкой клавиатурной навигации и скринридеров. AI справился с первой версией быстро. Потом начались три дня доработок.

Что

Claude сделал хорошо Claude сгенерировал рабочую основу компонента: структуру JSX, базовые ARIA-атрибуты (`role="dialog"`, `aria-label`, `aria-live`), обработчики клавиш для навигации стрелками и логику календарной сетки. Для стартовой точки — хорошо: код компилировался, визуально выглядел правильно, и ручная проверка ничего не ломала. Особенно полезным AI оказался в шаблонном коде: генерация 42 ячеек для сетки, вычисление смещения первого дня месяца, форматирование дат под `aria-label`. Это работа, которую неприятно делать вручную, и Claude справился с ней аккуратно. Проблема стала очевидна только после подключения настоящих вспомогательных технологий.

Где всё пошло не так

Настоящая проверка началась, когда запустили NVDA на Windows и VoiceOver на macOS. Проблем оказалось несколько: Ловушка фокуса не работала — при табуляции внутри диалога фокус уходил в основной документ Даты озвучивались неверно — скринридер читал «1» вместо «Понедельник, 1 июня 2026» Переключение месяца проходило тихо — `aria-live` регион не обновлялся при смене месяца Escape закрывал, но не возвращал — после закрытия календаря фокус терялся, а не возвращался на кнопку-триггер * Высокая контрастность Windows — выбранная дата визуально не отличалась от остальных: компонент полагался на CSS-цвет без атрибутов состояния Каждый из этих пунктов в сгенерированном коде выглядел как «обработчик есть» — но поведение с реальным скринридером отличалось от ожидаемого.

Как починили

Спасением стал WAI-ARIA APG — официальный гайд W3C с конкретным паттерном для DatePicker-диалога. Там прописано не просто «добавь `aria-modal`», а точная последовательность: какой элемент получает фокус при открытии, как держать ловушку фокуса, куда возвращать его при закрытии, какие `aria-label` нужны на кнопках навигации по месяцам.

«Прочитать сгенерированный код — не значит проверить доступность.

Только реальный скринридер покажет правду.» Ловушку фокуса переписали через `querySelectorAll` с ручным перехватом Tab и Shift+Tab. Каждая ячейка дня получила полный `aria-label` вида «Среда, 3 июня 2026» плюс `aria-pressed="true"` для выбранного состояния. Для режима высокой контрастности добавили `aria-selected` и обводку через `outline`, а не только фоновый цвет. Самым тонким местом оказался `aria-live`: регион должен присутствовать в DOM до того, как в него записывается текст, иначе скринридер его игнорирует. Claude вставил регион динамически — этот нюанс выяснился только в тесте.

Что это значит

Claude ускоряет написание доступного кода, но не заменяет тестирование со скринридерами. Хорошая новость: разобравшись с WAI-ARIA APG один раз и задокументировав решения, следующий доступный компонент пишется заметно быстрее. AI берёт на себя шаблонный труд — но финальную проверку с NVDA и VoiceOver пропускать нельзя.

Сюжет
ЖХ
Жемал Хамидун — CPO Alpina Digital, продакт-менеджер AlpinaGPT. Делает AI-продукты с 2019 года. Hamidun News — pet project, который вырос в production-агрегатор с 6000+ читателей.
✦ Закрытый клуб практиков · Vibe Club

Внедряйте ИИ быстрее рынка вместе с инженерами и фаундерами

Внутри Vibe Club (hamidun.com/club): еженедельные живые мастермайнды и разборы архитектуры с Жемалом Хамидуном, закрытый Tech Radar, LMS и обновляемая база из 370+ боевых скиллов.

Вступить в Vibe Club →Тест-драйв Академии (72ч)
Что вы думаете?
Загружаем комментарии…