useProgressBar для прогресса

Библиотека React Aria предоставляет хуки для реализации доступных компонентов интерфейса. Одним из таких хуков является useProgressBar, предназначенный для создания прогресс-баров, полностью совместимых с требованиями доступности (ARIA). Прогресс-бары используются для визуального отображения процесса выполнения задач, загрузки данных или выполнения длительных операций.


Основные принципы работы useProgressBar

useProgressBar обеспечивает следующие возможности:

  1. Управление значениями прогресса Хук принимает объект состояния, который включает:

    • value — текущее значение прогресса (число).
    • minValue — минимальное значение (по умолчанию 0).
    • maxValue — максимальное значение (по умолчанию 100).

    Хук автоматически вычисляет процент заполнения и добавляет необходимые ARIA-атрибуты для корректного восприятия экранными читалками.

  2. ARIA-атрибуты Для корректной работы с ассистивными технологиями хук генерирует:

    • role="progressbar"
    • aria-valuemin — минимальное значение.
    • aria-valuemax — максимальное значение.
    • aria-valuenow — текущее значение.
    • aria-valuetext — текстовое описание прогресса, если требуется кастомизация.
  3. Поддержка индикатора загрузки без фиксированного значения Если значение прогресса неизвестно (индетерминированный прогресс), можно не передавать value, и хук подготовит элемент как анимационный индикатор.


Синтаксис и использование

import { useProgressBar } from '@react-aria/progress';
import { useProgressBarState } from '@react-stately/progress';

function ProgressExample({ value, minValue = 0, maxValue = 100 }) {
  const state = useProgressBarState({ value, minValue, maxValue });
  const { progressBarProps, labelProps } = useProgressBar({ 
    value: state.value,
    minValue: state.minValue,
    maxValue: state.maxValue,
    'aria-label': 'Прогресс загрузки'
  });

  return (
    <div>
      <div {...labelProps}>Загрузка данных</div>
      <div {...progressBarProps} style={{ width: '100%', height: 20, background: '#eee', borderRadius: 4 }}>
        <div style={{ width: `${state.percentage * 100}%`, height: '100%', background: '#007aff', borderRadius: 4 }} />
      </div>
    </div>
  );
}

Разбор примера:

  • useProgressBarState — хук из React Stately, который хранит состояние прогресса и вычисляет процент заполнения через state.percentage.

  • useProgressBar — хук из React Aria, который возвращает набор пропсов:

    • progressBarProps — пропсы для контейнера прогресс-бара.
    • labelProps — пропсы для текста, описывающего прогресс.
  • Стилизация внутреннего div задаёт визуальное отображение заполнения на основе процента.


Особенности использования

  1. Доступность Все атрибуты ARIA автоматически добавляются к элементу прогресс-бара. Даже при кастомной разметке (например, при использовании div с фоном) элементы остаются корректно воспринимаемыми скринридерами.

  2. Индетерминированные прогресс-бары Если value не передан, хук создаёт прогресс-бар с aria-busy="true", что сигнализирует о загрузке без конкретного процента.

  3. Кастомизация текста прогресса Через aria-valuetext можно передавать собственное текстовое описание прогресса:

    <div {...progressBarProps} aria-valuetext={`${state.value} из ${state.maxValue}`}></div>
  4. Стилизация и анимация React Aria отвечает только за доступность. Визуальные эффекты, анимации и цвета задаются напрямую через CSS или inline-стили. Это позволяет гибко интегрировать прогресс-бары в любую систему дизайна.


Продвинутый пример: анимация с индикатором загрузки

function AnimatedProgress({ value }) {
  const state = useProgressBarState({ value, minValue: 0, maxValue: 100 });
  const { progressBarProps } = useProgressBar({ value: state.value, minValue: 0, maxValue: 100 });

  return (
    <div {...progressBarProps} style={{ width: '100%', height: 10, background: '#ccc', borderRadius: 5, overflow: 'hidden' }}>
      <div
        style={{
          width: `${state.percentage * 100}%`,
          height: '100%',
          background: 'linear-gradient(90deg, #4facfe, #00f2fe)',
          transition: 'width 0.3s ease'
        }}
      />
    </div>
  );
}

Ключевые моменты:

  • transition: 'width 0.3s ease' делает плавное изменение прогресса при обновлении значения.
  • Возможна интеграция с таймерами или событиями загрузки для динамического обновления.

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

  • Использовать useProgressBarState совместно с useProgressBar — стандартная практика для управления состоянием и доступностью.
  • Всегда добавлять метку или aria-label для элементов, если визуальный текст не описывает прогресс полностью.
  • Для индетерминированного прогресса можно использовать CSS-анимации (пульсирующая заливка, полосы движения) вместе с aria-busy.
  • Для крупных приложений рекомендуется создать кастомный компонент прогресс-бара с единым стилем, который повторно использует useProgressBar и useProgressBarState.

Хук useProgressBar обеспечивает легкую интеграцию прогресс-баров в React-проекты с гарантированной поддержкой доступности и полной совместимостью с ARIA, позволяя создавать как простые, так и анимированные индикаторы прогресса.