Доступ к содержимому слотов

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


Определение слотов

В Atomico слот создается с помощью стандартного элемента <slot>. Его можно использовать для передачи контента из родительского компонента внутрь дочернего.

import { c, html } from "atomico";

function Card() {
    return html`
        <div class="card">
            <slot name="header"></slot>
            <div class="body">
                <slot></slot>
            </div>
            <slot name="footer"></slot>
        </div>
    `;
}

Card.props = {};
export const card = c(Card);

В этом примере определены три слота:

  • Слот с именем "header" для верхней части карточки.
  • Слот по умолчанию для основного содержимого.
  • Слот с именем "footer" для нижней части.

Контент передается следующим образом:

<card>
    <div slot="header">Заголовок</div>
    Основной текст карточки
    <div slot="footer">Подпись</div>
</card>

Получение доступа к слоту

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

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

function TabPanel() {
    const tabs = useSlot("tab");
    
    return html`
        <div class="tabs">
            ${tabs.map(tab => html`<div class="tab">${tab.textContent}</div>`)}
        </div>
        <slot name="tab"></slot>
    `;
}

export const tabPanel = c(TabPanel);
  • useSlot("tab") возвращает массив элементов, вставленных в слот "tab".
  • Реактивность позволяет автоматически обновлять интерфейс при добавлении или удалении элементов из слота.
  • Элементы слота доступны как обычные DOM-узлы, что позволяет считывать их текст, атрибуты и свойства.

Слот по умолчанию

Если имя слота не указано, используется слот по умолчанию. Его можно получить, вызвав useSlot() без параметров:

const defaultContent = useSlot();

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


Работа с динамическим содержимым

С помощью useSlot можно строить динамические интерфейсы, которые реагируют на изменения содержимого слотов. Например, при добавлении нового элемента через JavaScript он автоматически появится в реактивном списке:

const container = document.querySelector("tab-panel");
const newTab = document.createElement("div");
newTab.setAttribute("slot", "tab");
newTab.textContent = "Новая вкладка";
container.appendChild(newTab);

Компонент TabPanel автоматически отобразит новую вкладку без необходимости перерисовки вручную.


Слоты с несколькими элементами

Слот может содержать любое количество элементов. useSlot возвращает их в виде массива, что упрощает итерацию и фильтрацию:

const buttons = useSlot("button").filter(el => el.tagName === "BUTTON");

В этом примере выбираются только элементы <button> из слота "button".


Особенности реактивного доступа

  1. Обновления при изменении содержимого: если элементы добавляются, удаляются или изменяются, массив, возвращаемый useSlot, автоматически обновляется.
  2. Доступ к атрибутам и свойствам: элементы слота можно читать и изменять напрямую через DOM-API.
  3. Синхронизация с JSX: использование useSlot полностью интегрировано с JSX-синтаксисом Atomico, что позволяет создавать гибкие шаблоны.

Примеры практического применения

  • Меню с динамическими пунктами: позволяет добавлять, удалять или переупорядочивать элементы меню без изменения кода компонента.
  • Карточки с настраиваемым содержимым: можно отдельно передавать шапку, тело и футер, обеспечивая полную кастомизацию.
  • Табы и аккордеоны: управление вкладками и панелями осуществляется через слоты, а useSlot обеспечивает реактивность интерфейса.

Итоговое понимание

Доступ к содержимому слотов в Atomico строится на сочетании стандартного <slot> и реактивного API useSlot. Это позволяет создавать динамичные, гибкие компоненты, полностью управляемые контентом, вставленным из родительских компонентов. Правильное использование слотов и реактивного доступа к ним становится ключевым инструментом при построении сложных интерфейсов.