-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcollapsible-content.js
83 lines (67 loc) · 1.62 KB
/
collapsible-content.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
class CollapsibleContent extends HTMLElement {
constructor() {
super();
this.style.display = "block";
this.style.overflow = "hidden";
this.style.transitionTimingFunction = "cubic-bezier(0, 1, 0.5, 1)";
if (this.hasAttribute("observe")) {
this.observe();
}
}
static get observedAttributes() {
return ["open"];
}
get open() {
return this.hasAttribute("open");
}
set open(bool) {
if (bool === true) {
this.setAttribute("open", true);
} else {
this.removeAttribute("open");
}
}
attributeChangedCallback() {
this.onChange();
}
connectedCallback() {
this.onChange();
}
disconnectedCallback() {
if (this.observer) {
this.observer.disconnect();
}
}
onChange() {
this.setStyles();
this.sendEvent();
}
observe() {
this.observer = new MutationObserver((e) => {
this.onChange();
});
this.observer.observe(this, { childList: true, subtree: true });
}
sendEvent() {
this.dispatchEvent(
new CustomEvent("collapsible-content-open", {
detail: this.open,
bubbles: true,
})
);
}
setStyles() {
this.height = this.scrollHeight + 1; // scrollHeight + fix height decimals
if (this.open === true) {
this.style.transition = "height .4s, opacity .4s .2s";
this.style.height = `${this.height}px`;
this.style.opacity = 1;
}
if (this.open === false) {
this.style.transition = "height .4s .2s, opacity .4s";
this.style.height = 0;
this.style.opacity = 0;
}
}
}
customElements.define("collapsible-content", CollapsibleContent);