Направление текста RTL/LTR

React Aria предоставляет мощный набор хуков и утилит для создания доступных интерфейсов, включая управление направлением текста. Направление текста определяет, как браузер отображает содержимое: слева направо (LTR) или справа налево (RTL). Это критично для поддержки многоязычных интерфейсов, таких как арабский, иврит или персидский язык.

Использование useLocale для определения направления

Базовым инструментом для работы с локализацией и направлением текста в React Aria является хук useLocale. Он возвращает объект с информацией о локали, включая направление текста.

import {useLocale} from '@react-aria/i18n';

function MyComponent() {
  const {locale, direction} = useLocale();

  return (
    <div>
      <p>Текущая локаль: {locale}</p>
      <p>Направление текста: {direction}</p>
    </div>
  );
}
  • locale — строка с идентификатором локали, например "en-US" или "ar-SA".
  • direction — строка "ltr" или "rtl", определяющая направление текста.

Этот хук позволяет адаптировать компоненты и стили в зависимости от направления текста без ручного анализа локали.

Контейнеры с направлением текста

Для корректного рендеринга компонентов важно оборачивать части интерфейса в контейнер с атрибутом dir. React Aria предоставляет компонент <LocaleProvider>, который автоматически передает направление текста всем дочерним компонентам через контекст.

import {LocaleProvider} from '@react-aria/i18n';

function App() {
  return (
    <LocaleProvider locale="ar-SA">
      <div>
        <MyComponent />
      </div>
    </LocaleProvider>
  );
}

В этом примере все компоненты внутри LocaleProvider будут понимать, что направление текста RTL, что позволяет корректно позиционировать элементы, стрелки, иконки и выпадающие списки.

Хуки для работы с направлением текста в компонентах

React Aria предоставляет несколько хуков для прямой работы с направлением текста:

  • useDirection — возвращает текущее направление текста из контекста. Можно использовать для динамического изменения стилей или поведения компонентов.
import {useDirection} from '@react-aria/i18n';

function Button() {
  const direction = useDirection();

  return (
    <button style={{paddingLeft: direction === 'rtl' ? '0' : '10px', paddingRight: direction === 'rtl' ? '10px' : '0'}}>
      Нажми меня
    </button>
  );
}
  • useLocale + CSS-переменные — позволяет задавать стили, зависящие от направления текста. Например, для меню или тултипов можно использовать динамическое смещение:
.tooltip {
  left: var(--tooltip-offset-left, 10px);
  right: var(--tooltip-offset-right, auto);
}
const direction = useDirection();
const style = direction === 'rtl' 
  ? {'--tooltip-offset-left': 'auto', '--tooltip-offset-right': '10px'} 
  : {'--tooltip-offset-left': '10px', '--tooltip-offset-right': 'auto'};

Поддержка RTL в интерактивных компонентах

Многие компоненты React Aria автоматически учитывают направление текста, если они обернуты в <LocaleProvider>:

  • Меню (Menu, MenuTrigger) — стрелки выпадающего меню и позиции элементов автоматически отражают RTL.
  • Тултипы (Tooltip) — позиционирование относительно элемента учитывает направление текста.
  • Слайдеры (Slider) — направление увеличения значения изменяется в зависимости от direction.

Пример использования Slider с поддержкой RTL:

import {Slider, SliderTrack, SliderThumb} from '@react-aria/slider';
import {useSliderState} from '@react-stately/slider';

function MySlider() {
  const state = useSliderState({minValue: 0, maxValue: 100, defaultValue: 50});
  
  return (
    <Slider orientation="horizontal" state={state}>
      <SliderTrack>
        <SliderThumb index={0} />
      </SliderTrack>
    </Slider>
  );
}

Если LocaleProvider установлен с локалью "ar-SA", слайдер будет работать справа налево без дополнительной логики.

Динамическая смена направления

React Aria позволяет менять направление текста во время работы приложения. Для этого достаточно обновить locale в <LocaleProvider>. Все дочерние компоненты автоматически пересчитают направление и обновят свои стили и поведение:

const [locale, setLocale] = useState('en-US');

return (
  <LocaleProvider locale={locale}>
    <button onCl ick={() => setLocale('ar-SA')}>Сменить на RTL</button>
    <MyComponent />
  </LocaleProvider>
);

Особенности интеграции с CSS и styled-components

Для компонентов, где требуется точный контроль над позиционированием, полезно использовать CSS-переменные или styled-components, учитывая направление:

import styled from 'styled-components';
import {useDirection} from '@react-aria/i18n';

const Box = styled.div`
  padding-left: ${props => props.direction === 'rtl' ? '0' : '16px'};
  padding-right: ${props => props.direction === 'rtl' ? '16px' : '0'};
`;

function AppBox() {
  const direction = useDirection();
  return <Box direction={direction}>Контент</Box>;
}

Такой подход делает интерфейс полностью адаптивным к локалям с различным направлением текста.

Вывод

Направление текста в React Aria управляется через локаль и контекст, предоставляемый хуками useLocale и useDirection. Компоненты библиотеки автоматически адаптируются под LTR и RTL, а стили и позиционирование можно настраивать через CSS-переменные и динамическое изменение стилей. Интеграция с <LocaleProvider> обеспечивает глобальную поддержку многоязычных интерфейсов без ручного вмешательства в каждый компонент.