Кратко
СкопированоCustomState — это интерфейс для управления внутренними состояниями автономных кастомных элементов. Позволяет добавлять и удалять состояния, которые затем можно использовать в CSS селекторах.
Пример
Скопировано
class MyCheckbox extends HTMLElement { constructor() { super(); this._internals = this.attachInternals(); this.addEventListener('click', () => this.toggle()); } connectedCallback() { this.attachShadow({ mode: 'open' }).innerHTML = ` <style> :host { display: flex; cursor: pointer; align-items: center; gap: .5rem; } :host::before { content: '[ ]'; font-family: monospace; } :host::after { content: 'Какой-то кастомный чекбокс'; font-family: monospace; } :host(:state(checked))::before { content: '[x]'; } :host(:state(checked))::after { content: 'Чекбокс cheked!'; } </style> `; } get checked() { return this._internals.states.has('checked'); } set checked(value) { if (value) { this._internals.states.add('checked'); } else { this._internals.states.delete('checked'); } } toggle() { this.checked = !this.checked; }}customElements.define('my-checkbox', MyCheckbox);
class MyCheckbox extends HTMLElement {
constructor() {
super();
this._internals = this.attachInternals();
this.addEventListener('click', () => this.toggle());
}
connectedCallback() {
this.attachShadow({ mode: 'open' }).innerHTML = `
<style>
:host { display: flex; cursor: pointer; align-items: center; gap: .5rem; }
:host::before { content: '[ ]'; font-family: monospace; }
:host::after { content: 'Какой-то кастомный чекбокс'; font-family: monospace; }
:host(:state(checked))::before { content: '[x]'; }
:host(:state(checked))::after { content: 'Чекбокс cheked!'; }
</style>
`;
}
get checked() {
return this._internals.states.has('checked');
}
set checked(value) {
if (value) {
this._internals.states.add('checked');
} else {
this._internals.states.delete('checked');
}
}
toggle() {
this.checked = !this.checked;
}
}
customElements.define('my-checkbox', MyCheckbox);
<my-checkbox>Этот текст не будет отображаться, потому что в кастомном элементе нету тега slot</my-checkbox>
<my-checkbox>Этот текст не будет отображаться, потому что в кастомном элементе нету тега slot</my-checkbox>
Как пишется
Скопировано
// Получение CustomStateSetconst internals = element.attachInternals();const states = internals.states;// Добавление состоянияstates.add('my-state');// Удаление состоянияstates.delete('my-state');// Проверка наличия состоянияstates.has('my-state');// Очистка всех состоянийstates.clear();
// Получение CustomStateSet
const internals = element.attachInternals();
const states = internals.states;
// Добавление состояния
states.add('my-state');
// Удаление состояния
states.delete('my-state');
// Проверка наличия состояния
states.has('my-state');
// Очистка всех состояний
states.clear();
Свойства
Скопировано-
Скопированоsize
Возвращает количество состояний в наборе.
const states = element.attachInternals().states;states.add('loading');states.add('error');console.log(states.size); // 2
const states = element.attachInternals().states;
states.add('loading');
states.add('error');
console.log(states.size); // 2
Методы
Скопировано-
Скопированоadd( value )
Добавляет состояние в набор. Если состояние уже существует, ничего не происходит.
states.add('checked');states.add('disabled');
states.add('checked');
states.add('disabled');
-
Скопированоclear( )
Удаляет все состояния из набора.
states.clear(); // Удаляет все состояния
states.clear(); // Удаляет все состояния
-
Скопированоdelete( value )
Удаляет конкретное состояние из набора. Возвращает true, если состояние было удалено, и false, если его не было.
const wasRemoved = states.delete('checked');console.log(wasRemoved); // true или false
const wasRemoved = states.delete('checked');
console.log(wasRemoved); // true или false
-
Скопированоhas( value )
Проверяет, есть ли состояние в наборе. Возвращает true или false.
if (states.has('loading')) { console.log('Элемент загружается');}
if (states.has('loading')) {
console.log('Элемент загружается');
}
-
СкопированоforEach ( callback )
Выполняет функцию для каждого состояния в наборе.
states.forEach((state, index) => { console.log(`Состояние ${index}: ${state}`);});
states.forEach((state, index) => {
console.log(`Состояние ${index}: ${state}`);
});
-
Скопированоentries( )
Возвращает итератор с парами [ключ для каждого состояния.
for (const [key, value] of states.entries()) { console.log(`${key} = ${value}`);}
for (const [key, value] of states.entries()) {
console.log(`${key} = ${value}`);
}
-
Скопированоvalues( )
Возвращает итератор со всеми значениями состояний.
for (const state of states.values()) { console.log(state);}
for (const state of states.values()) {
console.log(state);
}
-
Скопированоkeys( )
Алиас для values. Возвращает итератор со всеми значениями состояний.
for (const state of states.keys()) { console.log(state);}
for (const state of states.keys()) {
console.log(state);
}
Итерация
СкопированоCustomState поддерживает итерацию, как обычный Set:
// Через for...offor (const state of states) { console.log(state);}// Через spread операторconst stateArray = [...states];
// Через for...of
for (const state of states) {
console.log(state);
}
// Через spread оператор
const stateArray = [...states];
Как понять
СкопированоCustomState — это специальная коллекция, похожая на стандартный Set, но предназначенная для хранения и управления состояниями кастомных элементов (Web Components). Каждый элемент этого набора — это отдельное состояние, например: checked, open, active и т.д.
Когда вы добавляете или удаляете состояния через методы CustomState, эти изменения автоматически отражаются на элементе и могут быть использованы для стилизации через CSS-псевдокласс :state. Это позволяет динамически менять внешний вид компонента в зависимости от его состояния, не прибегая к ручному управлению классами или атрибутами.
Например, если в наборе состояний элемента появляется checked, то в CSS можно написать:
Подсказки
Скопировано💡 Состояния автоматически обновляют CSS, не требуя перерисовки DOM.
💡 Проверяйте поддержку через CSS.
💡 Используйте :state в CSS для стилизации элементов в определённом состоянии.
💡 Для состояний с несколькими значениями создавайте несколько булевых состояний, где только одно активно.
- Chrome 125, поддерживается
- Edge 125, поддерживается
- Firefox 126, поддерживается
- Safari 17.4, поддерживается