Связывание label и input

Правильная семантика форм является ключевым аспектом доступности веб-приложений. В библиотеке React Aria управление связью между элементами <label> и <input> осуществляется через специальные хуки, которые обеспечивают корректное взаимодействие с ассистивными технологиями, такими как экранные читалки.


Хук useLabel

Основной инструмент для связывания метки с полем ввода — хук useLabel. Он генерирует необходимые атрибуты для компонента <label>, учитывая идентификатор поля ввода, состояние ошибки, обязательность и подсказки.

Пример базового использования:

import {useLabel} from '@react-aria/label';

function TextInput({label, id}) {
  const {labelProps, fieldProps} = useLabel({label, id});

  return (
    <div>
      <label {...labelProps}>{label}</label>
      <input {...fieldProps} id={id} />
    </div>
  );
}

Объяснение ключевых моментов:

  • labelProps — объект с атрибутами для <label> (htmlFor, id), которые гарантируют корректную связь.
  • fieldProps — атрибуты для <input>, включая aria-labelledby, если необходимо.
  • id — уникальный идентификатор, который связывает поле и метку.

Автоматическая генерация id

React Aria позволяет автоматически генерировать идентификаторы через useId, что удобно для динамических форм:

import {useId} from '@react-aria/utils';
import {useLabel} from '@react-aria/label';

function EmailInput({label}) {
  const id = useId();
  const {labelProps, fieldProps} = useLabel({label, id});

  return (
    <div>
      <label {...labelProps}>{label}</label>
      <input type="email" {...fieldProps} id={id} />
    </div>
  );
}

Таким образом можно избежать ручного назначения id и минимизировать риск коллизий.


Связь с описаниями и подсказками

React Aria поддерживает ассоциацию полей ввода с вспомогательными текстами через aria-describedby. Для этого можно передать опцию description в useLabel:

function PasswordInput({label, description}) {
  const id = useId();
  const {labelProps, fieldProps} = useLabel({label, id, description});

  return (
    <div>
      <label {...labelProps}>{label}</label>
      <input type="password" {...fieldProps} id={id} />
      <p id={`${id}-description`}>{description}</p>
    </div>
  );
}

Пояснение:

  • description добавляется к aria-describedby автоматически.
  • Экранные читалки будут озвучивать подсказку вместе с меткой.

Поддержка обязательных и невалидных полей

React Aria учитывает состояния обязательности (required) и ошибки (invalid) при связывании метки и поля:

function UsernameInput({label, isRequired, validationState}) {
  const id = useId();
  const {labelProps, fieldProps} = useLabel({
    label,
    id,
    isRequired,
    validationState
  });

  return (
    <div>
      <label {...labelProps}>{label}</label>
      <input {...fieldProps} id={id} required={isRequired} />
    </div>
  );
}

Особенности:

  • isRequired автоматически добавляет визуальный и семантический индикатор обязательного поля.
  • validationState="invalid" добавляет aria-invalid, что позволяет экранным читалкам озвучивать ошибку.

Использование с кастомными компонентами

React Aria позволяет использовать <label> и <input> с кастомными компонентами, сохраняя доступность:

import {useLabel} from '@react-aria/label';

function CustomCheckbox({label}) {
  const id = useId();
  const {labelProps, fieldProps} = useLabel({label, id});

  return (
    <div>
      <label {...labelProps}>
        <input type="checkbox" {...fieldProps} id={id} />
        {label}
      </label>
    </div>
  );
}

Преимущество:

  • Метка оборачивает элемент, что особенно удобно для нестандартных UI-компонентов.
  • Все aria-связи сохраняются автоматически.

Советы по интеграции

  1. Единообразие идентификаторов: использовать useId для всех полей формы.
  2. Поддержка состояния ошибок: передавать validationState и description для доступности.
  3. Оборачивание кастомных компонентов: всегда применять labelProps к <label> и fieldProps к основному интерактивному элементу.
  4. Комбинация с другими хуками React Aria: useField и useTextField расширяют функциональность, сохраняя правильные связи.

Использование хуков React Aria для связывания меток и полей ввода гарантирует соблюдение стандартов доступности, упрощает поддержку форм и снижает риск ошибок при динамических интерфейсах.