Структура переводов

Atomico — это современная библиотека для создания веб-компонентов на JavaScript с реактивным подходом. Основная идея заключается в использовании функционального компонента и реактивных сигналов для управления состоянием, что позволяет создавать гибкие и масштабируемые интерфейсы без необходимости подключения сторонних фреймворков.

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

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

function MyComponent() {
    const [count, setCount] = useState(0);
    return html`
        <button oncl ick=${() => setCount(count + 1)}>
            Счётчик: ${count}
        </button>
    `;
}

customElements.define("my-component", c(MyComponent));
  • c(Component) — превращает обычную функцию в веб-компонент.
  • html — шаблонизатор, похожий на lit-html, для декларативного описания разметки.
  • useState — реактивный сигнал для управления локальным состоянием компонента.

Работа с сигналами

Сигналы — ключевой механизм реактивности в Atomico. Они позволяют автоматически отслеживать изменения значений и перерисовывать интерфейс при их обновлении.

import { useSignal } from "atomico";

function Timer() {
    const time = useSignal(0);

    setInterval(() => {
        time.value += 1;
    }, 1000);

    return html`<p>Время: ${time}</p>`;
}

Особенности сигналов:

  • Сигнал создаётся через useSignal(initialValue).
  • Изменение свойства .value автоматически инициирует обновление шаблона.
  • Сигналы могут быть использованы для создания реактивных списков и вычисляемых свойств.
const items = useSignal([1, 2, 3]);
const doubled = () => items.value.map(x => x * 2);

Свойства компонентов (Props)

Atomico позволяет описывать свойства компонентов с помощью функции props внутри объекта c(Component, options). Это обеспечивает строгую типизацию и реактивное обновление при изменении внешних данных.

MyComponent.props = {
    name: String,
    age: Number
};

function MyComponent({ name, age }) {
    return html`<p>${name} — ${age} лет</p>`;
}
  • Типы свойств: String, Number, Boolean, Array, Object.
  • Изменение значения свойства извне автоматически обновляет компонент.
  • Свойства доступны через аргумент функции компонента.

Слоты и вложенные компоненты

Atomico поддерживает стандартные веб-слоты для передачи контента внутрь компонента. Слоты создаются с помощью обычного HTML и могут быть именованными.

function Card({ title }) {
    return html`
        <div class="card">
            <h2>${title}</h2>
            <slot></slot>
        </div>
    `;
}
  • <slot></slot> — универсальный слот для вложенного контента.
  • <slot name="footer"></slot> — именованный слот.
  • Передача контента в слот осуществляется через <div slot="footer">Подвал</div>.

Жизненный цикл компонентов

Atomico предоставляет несколько хуков жизненного цикла для работы с эффектами и реактивностью:

  • useEffect(callback, dependencies) — выполняется при изменении зависимостей.
  • useUpdate(callback) — вызывается после каждого обновления компонента.
  • useUnmount(callback) — вызывается при удалении компонента из DOM.

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

function Clock() {
    const time = useSignal(new Date().toLocaleTimeString());

    useEffect(() => {
        const timer = setInterval(() => {
            time.value = new Date().toLocaleTimeString();
        }, 1000);
        return () => clearInterval(timer);
    }, []);

    return html`<p>${time}</p>`;
}

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

Atomico позволяет инкапсулировать стили внутри компонентов с помощью тега css:

import { css } from "atomico";

const style = css`
    .button {
        background: blue;
        color: white;
        border: none;
        padding: 10px;
        border-radius: 4px;
    }
`;

function StyledButton() {
    return html`
        <button class="button">Нажми меня</button>
        ${style}
    `;
}
  • Стили автоматически изолированы в компоненте через Shadow DOM.
  • Можно использовать переменные CSS и реактивные сигналы для динамических стилей.

Композиция и повторное использование

Компоненты Atomico легко комбинировать друг с другом. Вложенные компоненты могут принимать свойства и сигналы:

function App() {
    const count = useSignal(0);

    return html`
        <my-counter .count=${count}></my-counter>
        <button oncl ick=${() => count.value += 1}>Увеличить</button>
    `;
}

function MyCounter({ count }) {
    return html`<p>Счёт: ${count}</p>`;
}
  • Свойства и сигналы могут передаваться вниз по иерархии компонентов.
  • Комбинирование компонентов позволяет строить сложные интерфейсы из маленьких модулей.

Работа с событиями

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

function CustomButton() {
    const handleClick = (event) => {
        event.target.dispatchEvent(
            new CustomEvent("increment", { bubbles: true, composed: true })
        );
    };

    return html`<button oncl ick=${handleClick}>+</button>`;
}
  • События можно слушать снаружи через атрибут onincrement.
  • bubbles: true позволяет событию всплывать по DOM-дереву.
  • composed: true делает событие доступным за пределами Shadow DOM.

Поддержка реактивных коллекций

Списки и массивы в Atomico можно отрисовывать реактивно с помощью обычного метода .map():

const items = useSignal(["яблоко", "банан", "вишня"]);

function List() {
    return html`
        <ul>
            ${items.value.map(item => html`<li>${item}</li>`)}
        </ul>
    `;
}
  • Любое изменение массива через items.value.push("груша") автоматически обновляет DOM.
  • Можно комбинировать с фильтрацией и сортировкой, создавая динамические интерфейсы.

Оптимизация производительности

  • Использование сигналов вместо состояний, связанных с ререндером всего компонента, снижает нагрузку на DOM.
  • useEffect с зависимостями позволяет избегать лишних вычислений.
  • Shadow DOM обеспечивает локальную область стилей и предотвращает утечки CSS в другие части приложения.

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