Доступность
@lh-ui/react разделяет с остальными библиотеками семейства единый контракт доступности: семантические теги, ARIA-атрибуты и клавиатурное взаимодействие определяются внутри @lh-ui/share/core, поэтому все платформы реализуют их одинаково. Эта библиотека дополнительно гарантирует, что типичные ошибки a11y из экосистемы React в ней не встречаются.
Семантика и ARIA
LhSwitchрендерит<div role="switch" aria-checked>, а не визуально замаскированный checkboxLhSelectиспользуетrole="combobox"для триггера,role="listbox"для раскрывающейся панели,role="option"для вариантов иaria-activedescendantдля синхронизации подсветки с клавиатурыLhDialogиспользуетrole="dialog" aria-modal; заголовок обеспечивает и запасной вариантaria-label, и точную связь черезaria-labelledbyLhTooltipсвязывает подсказку с триггером черезaria-describedbyLhTagпри кликабельности повышается доrole="button"и реагирует на Enter / SpaceLhFormItemпри провале валидации рендерит сообщение об ошибке сrole="alert"и устанавливаетaria-invalid
Клавиатурное взаимодействие
| Компонент | Клавиши |
|---|---|
LhButton / LhTag | Enter / Space вызывает клик |
LhSwitch | Enter / Space переключает |
LhSelect | ArrowUp / ArrowDown подсвечивает вариант, Enter выбирает, Escape сворачивает |
LhDialog | Escape закрывает (отвечает только верхний оверлей) |
LhTooltip | Escape закрывает |
Когда открыто несколько оверлеев, useLhOverlayStack поддерживает стек порядка открытия; Escape закрывает только верхний, и одно нажатие не может закрыть сразу все оверлеи.
Управление фокусом
LhDialogпри открытии используетuseLhFocusTrap, чтобы удерживать фокус внутри диалогового окна (Tab / Shift+Tab не выходят наружу); при закрытии фокус возвращается триггеруLhFormItemпри клике на label ф окусирует первый доступный для фокуса элемент области содержимого (focusControl), поскольку нативное поведение обёрнутого label на составных элементах управления ненадёжно
Декоративные иконки
LhIcon по умолчанию decorative: выводит aria-hidden="true" и невидим для скринридеров. Если иконка несёт смысл, передайте decorative={false} + ariaLabel:
<LhIcon name="search" decorative={false} ariaLabel="Поиск" />
В этом случае рендерится <svg role="img" aria-label="Поиск">.
Безопасность в StrictMode
Все компоненты безопасны в React StrictMode: очистка эффектов и повторные монтирования идемпотентны (регистрация / удаление в стеке оверлеев, проверка владельца блокировки прокрутки, освобождение focus trap).
Единообразие семейства
Поведение доступности зарегистрировано в docs/设计语言基线.md как единый контракт обоих направлений (web / native). Все платформы реализуют одну и ту же логику из @lh-ui/share/core, поэтому ARIA-атрибуты и семантика клавиш остаются согласованными.