RTL поддержка

Atomico предоставляет гибкий подход к разработке компонентов в JavaScript с возможностью полноценной поддержки Right-to-Left (RTL) интерфейсов. RTL критически важен для приложений на языках с письмом справа налево, таких как арабский, иврит или персидский. В Atomico это реализуется через сочетание встроенных механизмов стилей, реактивного состояния и атрибутов DOM.


Директива dir и реактивность

HTML поддерживает атрибут dir, который может принимать значения ltr (слева направо) и rtl (справа налево). В Atomico это используется как:

import { c, useHost } from "atomico";

function MyComponent() {
    const host = useHost();
    host.dir = "rtl"; // установка направления текста
    return <div>Пример текста справа налево</div>;
}

customElements.define("my-component", c(MyComponent));

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

  • useHost() возвращает объект элемента, позволяя напрямую управлять его свойствами.
  • Атрибут dir автоматически влияет на вложенные элементы, наследуя направление текста.
  • Реактивное обновление dir позволяет динамически менять направление без перерисовки всего компонента.

Динамическое переключение RTL/LTR

Atomico поддерживает реактивные состояния через useState. Это позволяет переключать интерфейс между направлениями в реальном времени:

import { c, useState, useHost } from "atomico";

function ToggleDirection() {
    const host = useHost();
    const [rtl, setRtl] = useState(true);

    host.dir = rtl ? "rtl" : "ltr";

    return (
        <button oncl ick={() => setRtl(!rtl)}>
            Переключить направление
        </button>
    );
}

customElements.define("toggle-direction", c(ToggleDirection));

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

  • Изменение состояния rtl автоматически меняет атрибут dir у хоста.
  • CSS-наследование обеспечивает правильное выравнивание текста, маргинов и паддингов для RTL.

Стилизация компонентов под RTL

Для корректного отображения элементов важно учитывать направление при использовании CSS. В Atomico можно определять стили прямо в компоненте:

import { c, css } from "atomico";

const style = css`
    :host([dir="rtl"]) {
        text-align: right;
        direction: rtl;
    }

    :host([dir="ltr"]) {
        text-align: left;
        direction: ltr;
    }

    .container {
        padding-inline-start: 1rem; /* автоматически учитывает направление */
    }
`;

export default style;

Основные моменты:

  • :host([dir="rtl"]) позволяет задавать специфические стили для RTL без изменения структуры DOM.
  • Свойства padding-inline-start и margin-inline-end автоматически адаптируются к текущему направлению.
  • Избегание абсолютных left и right делает компоненты более универсальными.

Интеграция с глобальными стилями

Atomico позволяет внедрять RTL-логику на уровне приложения через глобальные стили:

import { css, adoptStyles } from "atomico";

const globalStyle = css`
    body[dir="rtl"] {
        direction: rtl;
        text-align: right;
    }
`;

adoptStyles(globalStyle);

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

  • Все компоненты автоматически наследуют направление от body.
  • Комбинация локальных и глобальных стилей дает полный контроль над интерфейсом.

Поддержка RTL в динамических списках и Flexbox

RTL влияет на порядок элементов и их визуальное представление. Atomico позволяет использовать CSS-переменные и реактивные состояния для корректного позиционирования:

import { c, useState } from "atomico";

function List({ items }) {
    const [rtl, setRtl] = useState(true);

    return (
        <ul style={{ direction: rtl ? "rtl" : "ltr", display: "flex" }}>
            {items.map(item => <li>{item}</li>)}
        </ul>
    );
}
  • Flexbox корректно переставляет элементы при смене direction.
  • В сочетании с реактивными состояниями можно динамически изменять порядок и выравнивание списка.

Взаимодействие с пользовательскими событиями

RTL влияет на обработку событий, таких как drag-and-drop или swipe. Atomico позволяет учитывать это при создании интерактивных компонентов:

function SwipeComponent() {
    const handleSwipe = (event) => {
        const host = event.target.closest("swipe-component");
        const isRtl = host.dir === "rtl";
        if (isRtl) {
            console.log("Свайп влево для RTL");
        } else {
            console.log("Свайп влево для LTR");
        }
    };

    return <div ontouchm ove={handleSwipe}>Элемент для свайпа</div>;
}
  • Проверка host.dir позволяет корректно интерпретировать пользовательские действия.
  • RTL-совместимые компоненты автоматически адаптируют направление жестов и анимаций.

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

  • Использовать dir на уровне хоста компонента, а не на каждом дочернем элементе.
  • Применять padding-inline и margin-inline вместо фиксированных left/right.
  • Объединять локальные и глобальные стили для полного контроля.
  • Проверять интерактивные элементы на корректность работы жестов и фокуса в RTL.
  • Реактивные состояния в Atomico позволяют легко переключать направления без лишнего рендеринга.

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