Haunted — это библиотека для создания веб-компонентов на базе функциональных реактивных хуков, вдохновлённая React. Она позволяет использовать декларативный подход к построению интерфейсов и обеспечивает встроенный механизм для реактивного обновления состояния. Стилизация компонентов в Haunted требует понимания как стандартных возможностей веб-компонентов, так и особенностей Shadow DOM.
В Haunted каждый компонент может быть изолированным с помощью Shadow DOM. Это изоляция влияет на стили:
Создание Shadow DOM в Haunted обычно выполняется через
attachShadow внутри функции-компонента с использованием
html шаблонного тега:
import { html, component } from 'haunted';
function MyButton() {
return html`
<style>
button {
background-color: #007bff;
color: white;
border: none;
padding: 0.5em 1em;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s ease;
}
button:hover {
background-color: #0056b3;
}
</style>
<button>Нажми меня</button>
`;
}
customElements.define('my-button', component(MyButton));
Особенности:
<style> должен находиться внутри
возвращаемого шаблона html.Хотя Shadow DOM изолирует стили, существуют методы передачи глобальных настроек:
--variable-name) можно
объявлять в глобальном стиле документа и использовать внутри
компонента:function MyCard() {
return html`
<style>
div {
background-color: var(--card-bg, #f0f0f0);
color: var(--card-color, #333);
padding: 1em;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
</style>
<div>Контент карточки</div>
`;
}
Haunted позволяет связывать CSS с состоянием компонента, используя
хуки useState и useEffect. Например, можно
динамически менять цвет кнопки при клике:
import { html, component } from 'haunted';
import { useState } from 'haunted';
function ToggleButton() {
const [active, setActive] = useState(false);
return html`
<style>
button {
background-color: ${active ? '#28a745' : '#dc3545'};
color: white;
padding: 0.5em 1em;
border: none;
border-radius: 4px;
cursor: pointer;
}
</style>
<button @click=${() => setActive(!active)}>
${active ? 'Активно' : 'Неактивно'}
</button>
`;
}
customElements.define('toggle-button', component(ToggleButton));
Особенности:
${}, обновляются вместе с DOM.Для крупных проектов удобно отделять стили в отдельные файлы. Haunted
поддерживает инъекцию внешних стилей через
adoptedStyleSheets в Shadow DOM:
import { html, component } from 'haunted';
import buttonStyles from './button.css.js';
function MyStyledButton() {
const div = document.createElement('div');
const shadow = div.attachShadow({ mode: 'open' });
shadow.adoptedStyleSheets = [buttonStyles];
shadow.innerHTML = `<button>Кнопка с внешним стилем</button>`;
return div;
}
customElements.define('my-styled-button', component(MyStyledButton));
CSSStyleSheet через JavaScript.Shadow DOM поддерживает стандартные CSS-псевдоклассы
(:hover, :focus, :active) и
медиазапросы:
function ResponsiveCard() {
return html`
<style>
div {
padding: 1em;
border-radius: 6px;
background-color: #fafafa;
}
@media (max-width: 600px) {
div {
background-color: #e0e0e0;
}
}
</style>
<div>Адаптивная карточка</div>
`;
}
Haunted поддерживает создание повторно используемых шаблонов стилей через функции:
export const cardStyles = html`
<style>
div {
padding: 1em;
border-radius: 8px;
box-shadow: 0 2px 6px rgba(0,0,0,0.1);
}
</style>
`;
function MyCard() {
return html`
${cardStyles}
<div>Карточка с повторно используемыми стилями</div>
`;
}
adoptedStyleSheets для масштабируемых проектов.Эффективная стилизация в Haunted строится на сочетании локальных стилей для компонентов, глобальных переменных и динамических реактивных изменений, что делает интерфейсы управляемыми, адаптивными и легко масштабируемыми.