useLabel для связи с метками

useLabel — это хук из библиотеки React Aria, предназначенный для обеспечения доступности компонентов путем корректного связывания элементов формы с их метками. Он является частью набора инструментов для создания компонентов, соответствующих стандартам WAI-ARIA.

Основная цель useLabel

Главная задача хука — предоставить свойства (props), которые можно безопасно применить к:

  • Основному элементу (например, input, textarea или кастомному компоненту поля формы)
  • Элементу метки (label)

Это позволяет:

  1. Автоматически связывать метку и контрол через атрибут htmlFor и id.
  2. Обеспечивать поддержку скринридеров, корректно объявляя контент метки как описание поля.
  3. Интегрироваться с другими хуками React Aria, такими как useTextField, useCheckbox, useSwitch.

Структура хука

const { labelProps, fieldProps } = useLabel(props);
  • props — объект с параметрами, где ключевым является label (строка с текстом метки).
  • labelProps — свойства, которые применяются к компоненту метки. Обычно содержат атрибут htmlFor.
  • fieldProps — свойства, которые применяются к полю ввода, включая id, необходимый для связи с меткой.

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

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

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

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

В этом примере React Aria автоматически создаёт уникальный id для поля ввода и связывает его с меткой через htmlFor. Если передан собственный id, хук использует его вместо генерации.

Передача дополнительных атрибутов

useLabel поддерживает передачу других атрибутов, таких как required, aria-label, aria-labelledby. Они передаются через объект props:

const { labelProps, fieldProps } = useLabel({
  label: "Email",
  required: true
});
  • required: true автоматически добавляет атрибут aria-required к полю.
  • Для компонентов без визуальной метки можно передать aria-label:
useLabel({ "aria-label": "Search input" });

Связь с другими хуками

useLabel часто комбинируется с:

  • useTextField — для текстовых полей
  • useCheckbox — для чекбоксов
  • useSwitch — для переключателей

Пример интеграции с useTextField:

import { useTextField } from "@react-aria/textfield";
import { useLabel } from "@react-aria/label";

function EmailInput({ label }) {
  const { labelProps, fieldProps } = useLabel({ label });
  const { inputProps } = useTextField(fieldProps);

  return (
    <div>
      <label {...labelProps}>{label}</label>
      <input {...inputProps} />
    </div>
  );
}

Здесь fieldProps передаются в useTextField, чтобы сохранить корректную работу всех ARIA-атрибутов и обработчиков событий.

Особенности при кастомных компонентах

При создании компонентов, которые визуально не используют стандартные HTML-поля (input, textarea), важно:

  1. Применять fieldProps к корневому элементу компонента.
  2. Сохранять семантическую связь между меткой и полем через id и aria-labelledby.
  3. Добавлять дополнительные ARIA-атрибуты при необходимости, например aria-describedby.

Пример кастомного поля:

function CustomInput({ label }) {
  const { labelProps, fieldProps } = useLabel({ label });
  
  return (
    <div>
      <span {...labelProps}>{label}</span>
      <div role="textbox" {...fieldProps} tabIndex={0}></div>
    </div>
  );
}

Важные нюансы

  • useLabel не создает визуальные элементы — метка должна быть отрисована отдельно.
  • Если поле уже имеет визуальную метку в другом месте, можно использовать aria-labelledby для привязки.
  • Хук поддерживает динамическое обновление label без необходимости перерендеривания всего компонента.

Резюме ключевых моментов

  • useLabel обеспечивает доступность через корректную связь метки и поля.
  • Автоматически генерирует id и связывает его с htmlFor.
  • Поддерживает стандартные ARIA-атрибуты и интеграцию с другими хуками React Aria.
  • Позволяет легко создавать как стандартные, так и кастомные компоненты формы с корректной семантикой.

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