Кратко
Скопировано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('Элемент загружается'); }
-
Скопированоfor
Each ( 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, поддерживается