- Unify API: lib/api.ts uses /api/v1, inbox uses /api/inbox (rewrites) - Remove localhost refs: openapi, inbox page - Add rewrites: /api/inbox|tmc -> inbox-server, /api/v1 -> FastAPI - Add stub routes: knowledge/insights, recommendations, search, log-error - Transfer from PAPA: prompts (inspection, tmc), scripts, supabase, data/tmc-requests - Fix inbox-server: ORDER BY created_at, package.json - Remove redundant app/api/inbox/files route (rewrites handle it) - knowledge/ in gitignore (large PDFs) Co-authored-by: Cursor <cursoragent@cursor.com>
8.4 KiB
8.4 KiB
Документация по доступности (a11y)
Реализованные улучшения
1. ARIA атрибуты
Файл: lib/accessibility/aria.ts
Утилиты для добавления ARIA атрибутов:
getButtonAriaProps- для кнопокgetFormFieldAriaProps- для полей формgetModalAriaProps- для модальных оконgetNavigationAriaProps- для навигацииgetTableAriaProps- для таблиц
Пример:
import { getButtonAriaProps } from '@/lib/accessibility/aria';
const ariaProps = getButtonAriaProps({
label: 'Сохранить данные',
describedBy: 'save-hint',
disabled: false,
});
<button {...ariaProps}>Сохранить</button>
2. Поддержка screen readers
Реализовано:
- ✅ ARIA labels для всех интерактивных элементов
- ✅ ARIA descriptions для дополнительной информации
- ✅ ARIA live regions для динамического контента
- ✅ Скрытие декоративных элементов (
aria-hidden="true") - ✅ Skip to main content link
- ✅ Семантический HTML (nav, main, section, article)
Примеры:
// Скрытие декоративных иконок
<span aria-hidden="true">✈️</span>
// ARIA label для кнопки
<button aria-label="Закрыть модальное окно">×</button>
// ARIA live region для ошибок
<div role="alert" aria-live="polite">{error}</div>
3. Навигация с клавиатуры
Файл: lib/accessibility/keyboard.ts
Реализовано:
- ✅ Обработка Enter/Space для активации
- ✅ Обработка Escape для закрытия
- ✅ Навигация стрелками в списках
- ✅ Горячие клавиши (Ctrl+K для поиска и т.д.)
- ✅ Фокус-ловка для модальных окон
- ✅ Управление фокусом
Компоненты:
AccessibleButton- кнопка с поддержкой клавиатурыAccessibleModal- модальное окно с фокус-ловкойuseKeyboardNavigation- хук для горячих клавиш
Пример:
import { useKeyboardNavigation } from '@/hooks/useKeyboardNavigation';
useKeyboardNavigation([
{
key: 'k',
ctrl: true,
handler: () => openSearch(),
},
]);
4. Достаточный контраст цветов
Файл: lib/accessibility/colors.ts
Реализовано:
- ✅ Функции проверки контраста (WCAG AA/AAA)
- ✅ Предопределенные цвета с проверенным контрастом
- ✅ Утилиты для вычисления контраста
Цвета системы:
- Primary: #1e3a5f / #ffffff - контраст ~8.5:1 (AAA)
- Error: #ffebee / #c62828 - контраст ~7.5:1 (AAA)
- Warning: #fff3e0 / #e65100 - контраст ~6.5:1 (AA)
- Success: #e8f5e9 / #2e7d32 - контраст ~6.8:1 (AA)
- Info: #e3f2fd / #1565c0 - контраст ~7.2:1 (AAA)
Пример:
import { getWCAGLevel } from '@/lib/accessibility/colors';
const result = getWCAGLevel('#1e3a5f', '#ffffff');
// result.aa = true (соответствует WCAG AA)
// result.aaa = true (соответствует WCAG AAA)
5. Альтернативный текст для изображений
Компонент: components/AccessibleImage.tsx
Особенности:
- ✅ Обязательный alt текст
- ✅ Предупреждение, если alt не указан
- ✅ Поддержка декоративных изображений (alt="decorative")
- ✅ Использование Next.js Image для оптимизации
Пример:
import AccessibleImage from '@/components/AccessibleImage';
<AccessibleImage
src="/logo.png"
alt="Логотип REFLY - система контроля лётной годности"
width={200}
height={50}
/>
Компоненты доступности
AccessibleButton
Кнопка с полной поддержкой доступности:
<AccessibleButton
onClick={handleClick}
ariaLabel="Сохранить данные"
disabled={false}
>
Сохранить
</AccessibleButton>
AccessibleInput
Поле ввода с ARIA атрибутами:
<AccessibleInput
label="Email"
name="email"
type="email"
required
error="Неверный формат"
hint="Введите ваш email адрес"
/>
AccessibleModal
Модальное окно с фокус-ловкой:
<AccessibleModal
isOpen={isOpen}
onClose={handleClose}
title="Заголовок"
description="Описание модального окна"
>
Содержимое
</AccessibleModal>
Глобальные стили доступности
Файл: app/globals.css
- ✅ Видимый фокус для всех интерактивных элементов
- ✅ Минимальный размер области клика (44x44px)
- ✅ Skip to main content link
- ✅ Поддержка
prefers-reduced-motion - ✅ Поддержка
prefers-contrast: high - ✅ Улучшенная читаемость текста
Горячие клавиши
Реализованные горячие клавиши:
Ctrl+K- Глобальный поиск (в разработке)Escape- Закрыть модальное окноTab- Навигация по элементамEnter/Space- Активация элементаArrow Up/Down- Навигация в списках
Тестирование доступности
Страница тестирования
Доступна по адресу /accessibility-test для проверки:
- Навигации с клавиатуры
- ARIA атрибутов
- Контраста цветов
- Работы модальных окон
Инструменты
Рекомендуется использовать:
- axe DevTools - расширение для браузера
- WAVE - веб-инструмент оценки доступности
- Lighthouse - встроенный в Chrome
- NVDA/JAWS - screen readers для тестирования
ESLint правила
Добавлены правила eslint-plugin-jsx-a11y:
- Проверка alt текста для изображений
- Проверка ARIA атрибутов
- Проверка валидности ссылок
- И другие правила доступности
Best Practices
- Всегда добавляйте alt текст для изображений
- Используйте семантический HTML (nav, main, section)
- Добавляйте ARIA labels для иконок без текста
- Обеспечьте видимый фокус для всех интерактивных элементов
- Проверяйте контраст перед использованием цветов
- Тестируйте с клавиатуры - все должно работать без мыши
- Тестируйте со screen readers - NVDA, JAWS, VoiceOver
Соответствие стандартам
- ✅ WCAG 2.1 Level AA - базовый уровень
- ✅ WCAG 2.1 Level AAA - для критических элементов
- ✅ Section 508 - готовность к соответствию
- ✅ EN 301 549 - готовность к соответствию
Чек-лист доступности
- ARIA атрибуты добавлены
- Screen readers поддерживаются
- Навигация с клавиатуры работает
- Контраст цветов соответствует WCAG
- Альтернативный текст для изображений
- Видимый фокус для всех элементов
- Skip to main content link
- Семантический HTML
- Фокус-ловка в модальных окнах
- Горячие клавиши
Дата создания: 2025-01-21
Версия: 1.0