Haunted — это современная библиотека для создания веб-компонентов на базе функциональных подходов, аналогичных React Hooks, но ориентированных на нативный Custom Elements API. Одной из ключевых возможностей является интеграция с Shadow DOM, обеспечивающая изоляцию стилей и структуры компонента. С появлением декларативного Shadow DOM разработка компонентов становится более естественной и удобной.
Shadow DOM позволяет создавать изолированные поддеревья DOM, скрытые от глобального контекста страницы. Основные преимущества:
В традиционном подходе Shadow DOM создавался программно через
this.attachShadow({ mode: 'open' }) внутри конструктора
кастомного элемента. В Haunted этот процесс можно описывать
декларативно, что упрощает разработку и повышает читаемость кода.
В Haunted для декларативного Shadow DOM используется специальный синтаксис при создании функциональных компонентов. Основные функции:
import { component, html, useState } from 'haunted';
Функция html поддерживает возможность декларативного
оборачивания шаблона в Shadow DOM. Это достигается использованием
атрибута shadowRootMode:
const MyComponent = () => html`
<div shadowRootMode="open">
<p>Привет, Shadow DOM!</p>
</div>
`;
Ключевые моменты:
shadowRootMode может принимать значения
"open" или "closed".Haunted использует хуки для управления состоянием, и декларативный Shadow DOM полностью совместим с ними:
const Counter = () => {
const [count, setCount] = useState(0);
return html`
<div shadowRootMode="open">
<p>Счётчик: ${count}</p>
<button @click=${() => setCount(count + 1)}>Увеличить</button>
</div>
`;
};
customElements.define('my-counter', component(Counter));
Особенности такого подхода:
count) привязано к компоненту и его Shadow
DOM.@event.Стили можно объявлять внутри Shadow DOM декларативно:
const StyledComponent = () => html`
<div shadowRootMode="open">
<style>
p {
color: teal;
font-weight: bold;
}
</style>
<p>Текст с изолированными стилями</p>
</div>
`;
Преимущества:
Декларативный Shadow DOM поддерживает вложенные компоненты:
const InnerComponent = () => html`
<div shadowRootMode="open">
<span>Внутренний компонент</span>
</div>
`;
const OuterComponent = () => html`
<div shadowRootMode="open">
<p>Внешний компонент</p>
<${InnerComponent} />
</div>
`;
Особенности:
Haunted автоматически обновляет Shadow DOM при изменении состояния или свойств компонента:
const ToggleMessage = () => {
const [visible, setVisible] = useState(true);
return html`
<div shadowRootMode="open">
${visible ? html`<p>Сообщение видно</p>` : html`<p>Сообщение скрыто</p>`}
<button @click=${() => setVisible(!visible)}>Переключить</button>
</div>
`;
};
Особенности динамики:
Несмотря на изоляцию, Shadow DOM позволяет взаимодействовать с внешними событиями и API:
const GlobalListener = () => {
const [data, setData] = useState(null);
window.addEventListener('resize', () => {
setData(window.innerWidth);
});
return html`
<div shadowRootMode="open">
<p>Ширина окна: ${data}</p>
</div>
`;
};
Особенности:
shadowRootMode.useState,
useEffect).Декларативный Shadow DOM в Haunted сочетает функциональный подход к компонентам с мощной изоляцией DOM и стилей, обеспечивая современный, модульный и удобный способ разработки веб-компонентов.