Измерения и позиционирование

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


Управление размерами компонентов

Размеры компонентов в Atomico можно задавать несколькими способами: через CSS, через реактивные свойства и через DOM API.

1. Размеры через CSS

Каждый компонент Atomico поддерживает использование классов и стилей. Для задания ширины и высоты применяются стандартные свойства:

:host {
    display: block;
    width: 300px;
    height: 150px;
}

Использование :host позволяет задавать стиль именно для корневого элемента компонента, что особенно важно при создании изолированных веб-компонентов.

2. Реактивные размеры через свойства

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

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

function Box() {
    const [size, setSize] = useState({ width: 200, height: 100 });

    return html`
        <div
            style="width: ${size.width}px; height: ${size.height}px; background: lightblue;"
        ></div>
    `;
}

Box.props = {
    size: Object
};

export default c(Box);

Изменение состояния size автоматически перерисует компонент с новыми размерами.

3. Динамическое измерение через DOM API

Для компонентов, размеры которых зависят от содержимого, применяются стандартные методы DOM:

const boxRef = useRef();

useEffect(() => {
    console.log(boxRef.current.getBoundingClientRect());
}, []);

Метод getBoundingClientRect возвращает точные ширину, высоту, координаты и позиции элемента относительно окна.


Позиционирование компонентов

Позиционирование в Atomico полностью наследуется от CSS, но библиотека добавляет гибкость через реактивные состояния и слоты. Основные методы позиционирования:

1. Статическое и относительное

По умолчанию компоненты ведут себя как блоки:

:host {
    display: block;
    position: relative;
    top: 10px;
    left: 20px;
}

Использование position: relative позволяет смещать компонент внутри родителя без влияния на поток других элементов.

2. Абсолютное позиционирование

Абсолютное позиционирование важно для модальных окон, всплывающих панелей и элементов интерфейса:

:host {
    position: absolute;
    top: 50px;
    left: 100px;
}

В комбинации с родителем position: relative можно точно размещать элементы внутри контейнера.

3. Flex и Grid

Atomico компоненты поддерживают современные методы flexbox и grid, что позволяет создавать сложные макеты без лишних обёрток:

:host {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
}

Flex и Grid можно комбинировать с реактивными свойствами для динамической перестановки элементов и изменения их размеров.


Отслеживание изменений размеров

Atomico предоставляет возможности реактивного отслеживания изменений. Для этого можно использовать ResizeObserver, интегрированный с жизненным циклом компонентов:

import { useEffect, useRef, useState } from "atomico";

function ResponsiveBox() {
    const boxRef = useRef();
    const [rect, setRect] = useState({ width: 0, height: 0 });

    useEffect(() => {
        const observer = new ResizeObserver(([entry]) => {
            setRect(entry.contentRect);
        });
        observer.observe(boxRef.current);
        return () => observer.disconnect();
    }, []);

    return html`
        <div ref=${boxRef} style="width: 100%; height: auto; background: lightcoral;">
            Ширина: ${rect.width}px, Высота: ${rect.height}px
        </div>
    `;
}

Это позволяет создавать компоненты, которые адаптируются к изменениям размера контейнера или окна без лишнего перерисовывания.


Взаимодействие позиционирования и событий

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

function DraggableBox() {
    const boxRef = useRef();
    const [position, setPosition] = useState({ x: 0, y: 0 });

    const onMouseM ove = (event) => {
        setPosition({ x: event.clientX, y: event.clientY });
    };

    return html`
        <div
            ref=${boxRef}
            style="position: absolute; left: ${position.x}px; top: ${position.y}px; width: 100px; height: 100px; background: lightgreen;"
            onmousem ove=${onMouseMove}
        ></div>
    `;
}

Реактивное состояние position автоматически обновляет координаты элемента на странице, обеспечивая плавное и точное позиционирование.


Советы по оптимизации размеров и позиционирования

  • Избегать inline-стилей для всех компонентов — лучше связывать реактивные свойства с CSS-переменными.
  • Использовать ResizeObserver для адаптивных компонентов, чтобы не проверять размеры вручную.
  • Сохранять координаты и размеры в состоянии только при необходимости, чтобы не перегружать ререндеринг.
  • Комбинировать flex/grid с абсолютным позиционированием для сложных интерфейсов, где часть элементов должна оставаться на фиксированных местах, а другие — динамически адаптироваться.

Управление размерами и позиционированием в Atomico сочетает мощь CSS и реактивные возможности JavaScript, позволяя создавать гибкие, адаптивные и интерактивные компоненты с минимальным количеством кода и высокой производительностью.