Skip to content

Instantly share code, notes, and snippets.

@WesleySmits
Last active May 1, 2022 08:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save WesleySmits/32985770f9e9465848b0ba2c080464dc to your computer and use it in GitHub Desktop.
Save WesleySmits/32985770f9e9465848b0ba2c080464dc to your computer and use it in GitHub Desktop.
Accessible Accordion: Custom Accordion Element
import { getAbsoluteHeight } from './utils.js';
class Curtain extends HTMLDetailsElement {
#summary = this.querySelector('summary');
#content = this.querySelector('.curtain__content');
#animation = null;
connectedCallback() {
this.#summary.addEventListener('click', this.#handleClick);
}
disconnectedCallback() {
this.#summary.removeEventListener('click', this.#handleClick);
}
#handleClick = (event) => {
event.preventDefault();
if (this.open === false) {
this.#open();
return;
}
this.close();
};
toggle() {
if (this.open === true) {
this.close();
return;
}
this.#open();
}
#open() {
this.style.height = `${this.offsetHeight}px`;
if (!this.open) {
this.open = true;
}
window.requestAnimationFrame(() => {
const startHeight = `${this.offsetHeight}px`;
const endHeight = `${this.#summary.offsetHeight + getAbsoluteHeight(this.#content)}px`;
if (this.#animation) {
this.#animation.cancel();
}
this.classList.add('nh-curtain-new--open');
this.#animation = this.animate(
{
height: [startHeight, endHeight]
},
{
duration: 400,
easing: 'ease-out'
}
);
this.#animation.onfinish = () => this.#onAnimationFinish(true);
});
}
close() {
const startHeight = `${this.offsetHeight}px`;
const endHeight = `${this.#summary.offsetHeight}px`;
if (this.#animation) {
this.#animation.cancel();
}
this.classList.remove('nh-curtain-new--open');
this.#animation = this.animate(
{
height: [startHeight, endHeight]
},
{
duration: 400,
easing: 'ease-out'
}
);
this.#animation.onfinish = () => this.#onAnimationFinish(false);
}
#onAnimationFinish(open) {
this.open = open;
this.#animation = null;
this.style.height = '';
}
}
customElements.define('curtain-component', Curtain, { extends: 'details' });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment