Очередь и приоритеты

В библиотеке Radix UI работа с очередями и приоритетами реализуется через систему управления состояниями компонентов и их событиями. Это особенно важно при создании интерфейсов с динамическими элементами, такими как модальные окна, тултипы, всплывающие панели и меню, где порядок появления и взаимодействия влияет на пользовательский опыт.

Компоненты с поддержкой очередей

Radix UI предоставляет несколько компонентов, для которых управление очередями является критически важным:

  1. Dialog (Модальные окна) Модальные окна в Radix UI можно настроить так, чтобы новые диалоги ставились в очередь и отображались с определённым приоритетом. Это достигается через свойства open, onOpenChange и forceMount, которые управляют состоянием монтирования и появления компонентов.

  2. Tooltip (Всплывающие подсказки) Tooltip поддерживает последовательное появление через delayDuration и skipDelayDuration. Эти параметры позволяют задавать временные интервалы между событиями, effectively формируя очередь отображения для множества подсказок на одной странице.

  3. Toast (Уведомления) Для уведомлений используется отдельный механизм очередей. Компонент ToastProvider управляет состоянием всех уведомлений, гарантируя, что они появляются и скрываются в порядке очереди. Важные свойства:

    • duration – время жизни уведомления;
    • swipeDirection – направление смахивания для удаления уведомления;
    • pauseOnHover – приостановка таймера при наведении.

Механизм приоритетов

Radix UI реализует приоритеты с помощью комбинации состояния компонента и внешнего управления очередями через React Context. Основные подходы:

  • Приоритет на основе состояния open Элементы с open={true} получают приоритет отображения. Остальные элементы остаются в очереди до изменения состояния.
  • Очередь с управлением вручную Можно использовать useState или useReducer для создания массивов компонентов в очереди, где каждому элементу присваивается свой приоритет через поле priority. Затем компоненты рендерятся в порядке убывания приоритета.
  • Асинхронное управление Для динамически создаваемых элементов, таких как уведомления или подсказки, Radix UI рекомендует применять хук useEffect с зависимостями, чтобы корректно управлять последовательностью добавления элементов в DOM.

Пример реализации очереди с приоритетами для уведомлений

import * as Toast from '@radix-ui/react-toast';
import { useState, useEffect } from 'react';

function PriorityToastProvider({ toasts }) {
  const [queue, setQueue] = useState([]);

  useEffect(() => {
    const sortedToasts = [...toasts].sort((a, b) => b.priority - a.priority);
    setQueue(sortedToasts);
  }, [toasts]);

  return (
    <Toast.Provider>
      {queue.map(({ id, message }) => (
        <Toast.Root key={id} open>
          <Toast.Title>{message}</Toast.Title>
        </Toast.Root>
      ))}
      <Toast.Viewport />
    </Toast.Provider>
  );
}

В этом примере уведомления сортируются по полю priority и отображаются в порядке убывания приоритета, что гарантирует, что более важные уведомления показываются первыми.

Управление сложными последовательностями

Для интерфейсов с несколькими компонентами, которые могут конфликтовать за внимание пользователя, Radix UI предоставляет гибкие инструменты:

  • forceMount – позволяет держать компонент в DOM даже при закрытом состоянии, что помогает избежать «мигания» при последовательном открытии нескольких элементов.
  • Контекстные провайдеры (Context) – дают возможность координировать состояние разных компонентов через единый источник правды.
  • Комбинация таймеров и очередей – при использовании всплывающих элементов можно комбинировать setTimeout и состояние очереди, чтобы контролировать порядок появления и скрытия элементов.

Практические рекомендации

  1. Всегда использовать один провайдер очереди на уровень приложения для компонентов одного типа (например, уведомления или диалоги).
  2. Для сложных интерфейсов с динамическим добавлением элементов стоит использовать сортировку по приоритету перед рендером.
  3. Использовать forceMount и delayDuration для плавного появления компонентов, чтобы избежать резких изменений интерфейса при управлении очередями.
  4. Применять контексты и хуки состояния для управления последовательностью событий между независимыми компонентами.

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

  • Очередь в Radix UI строится на основе состояния open и контекстного управления.
  • Приоритет определяется либо полем данных (например, priority), либо логикой состояния компонента.
  • Комбинация таймеров и состояния позволяет управлять асинхронным появлением компонентов.
  • Контекст и провайдеры дают возможность масштабировать управление очередями на уровень всего приложения.

Эти принципы позволяют создавать интерфейсы, где порядок отображения элементов и их взаимодействие полностью контролируемы и соответствуют UX-требованиям.