Recipe 12.6
Creating a Disclosure Component
This example builds a disclosure element, which has a toggle button and some child content. The toggle button will show and hide the child content.
Demo
Details
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras feugiat quis ipsum in ultrices. Maecenas dignissim urna
a odio sagittis consectetur. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos
himenaeos. Nunc sed porttitor lacus. Pellentesque eu facilisis libero. Mauris malesuada gravida sem, sit amet ornare
elit rutrum ut. Proin ut urna sit amet arcu pellentesque scelerisque a vitae augue. Sed viverra tellus nec libero
molestie, quis ultricies sapien vestibulum. Cras nibh nibh, consequat non eros ullamcorper, gravida tincidunt nunc.
Code
JavaScript
const template = document.createElement('template');
template.innerHTML = `
<div>
<button type="button" class="toggle-button">
<slot name="title"></slot>
</button>
<div class="content">
<slot></slot>
</div>
</div>
`;
class Disclosure extends HTMLElement {
static observedAttributes = ['open'];
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.appendChild(template.content.cloneNode(true));
this.content = this.shadowRoot.querySelector('.content');
}
connectedCallback() {
this.content.hidden = !this.hasAttribute('open');
this.shadowRoot.querySelector('.toggle-button')
.addEventListener('click', () => {
if (this.hasAttribute('open')) {
this.removeAttribute('open');
this.content.hidden = true;
} else {
this.setAttribute('open', '');
this.content.hidden = false;
}
});
}
attributeChangedCallback(name, oldValue, newValue) {
if (newValue !== null) {
this.content.hidden = false;
} else {
this.content.hidden = true;
}
}
}
if (!customElements.get('x-disclosure')) {
customElements.define('x-disclosure', Disclosure);
}
HTML
<style>
x-disclosure:not(:defined) {
display: none;
}
</style>
<x-disclosure>
<div slot="title">Details</div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras feugiat quis ipsum in ultrices. Maecenas dignissim urna
a odio sagittis consectetur. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos
himenaeos. Nunc sed porttitor lacus. Pellentesque eu facilisis libero. Mauris malesuada gravida sem, sit amet ornare
elit rutrum ut. Proin ut urna sit amet arcu pellentesque scelerisque a vitae augue. Sed viverra tellus nec libero
molestie, quis ultricies sapien vestibulum. Cras nibh nibh, consequat non eros ullamcorper, gravida tincidunt nunc.
</x-disclosure>