Element Internals API представляет собой механизм, позволяющий создавать и управлять внутренними аспектами веб-компонентов, которые обычно недоступны извне. Этот API обеспечивает расширенные возможности для работы с состоянием компонента, формами и доступностью, сохраняя при этом инкапсуляцию.
Для использования Element Internals внутри компонента Stencil
необходимо создать приватное свойство типа
ElementInternals. Обычно это делается в классе компонента
через декоратор @Component и хук @Element:
import { Component, Element, h } from '@stencil/core';
@Component({
tag: 'my-element',
shadow: true
})
export class MyElement {
@Element() el!: HTMLElement;
private internals!: ElementInternals;
connectedCallback() {
this.internals = this.el.attachInternals();
}
render() {
return <div>Контент компонента</div>;
}
}
Ключевой момент: метод
attachInternals() возвращает объект
ElementInternals, через который реализуются расширенные
возможности компонента.
Element Internals позволяет компоненту взаимодействовать с формами
так, как если бы он был обычным <input> или
<select>. Основные возможности:
setFormValue): задает
значение компонента, которое будет отправлено при сабмите формы.setValidity): устанавливает
состояние валидности и сообщения об ошибке.form):
получение ссылки на <form>, в которой находится
компонент.Пример интеграции с формой:
connectedCallback() {
this.internals = this.el.attachInternals();
this.internals.setFormValue('initial value');
}
handleInputChange(value: string) {
this.internals.setFormValue(value);
}
validateInput(isValid: boolean) {
if (isValid) {
this.internals.setValidity({});
} else {
this.internals.setValidity({ customError: true }, 'Некорректное значение');
}
}
Особенность: компонент может участвовать в механизме
отправки формы и показывать собственные ошибки валидации без
использования стандартных <input> элементов.
Element Internals интегрируется с ARIA и предоставляет возможность управлять состоянием доступности:
internals.role можно
указать роль компонента для скринридеров.Пример установки роли и aria-меток:
connectedCallback() {
this.internals = this.el.attachInternals();
this.internals.role = 'checkbox';
this.internals.ariaChecked = 'false';
}
toggleCheck() {
const checked = this.internals.ariaChecked === 'true';
this.internals.ariaChecked = (!checked).toString();
}
Element Internals предоставляет возможность работать с псевдоклассами
CSS, такими как :hover, :focus, а также с
формой:
internals.states — набор состояний, который можно
использовать для стилизации через CSS.:valid и :invalid для
кастомных элементов.Пример установки состояния валидности:
checkValidity() {
const isValid = this.someValidationLogic();
this.internals.states.add(isValid ? 'valid' : 'invalid');
}
Это позволяет использовать стандартные селекторы CSS для визуального отображения состояния компонента.
Element Internals корректно работает с shadow DOM, что обеспечивает инкапсуляцию стилей и DOM-структуры компонента, сохраняя при этом интеграцию с формами и системой доступности:
setValidity и
setFormValue.Использование Element Internals в Stencil обеспечивает создание полностью интегрированных и доступных веб-компонентов, расширяя возможности стандартного DOM и формы, сохраняя при этом инкапсуляцию и удобство управления состояниями.