UNPKG

joicomponents

Version:

Design patterns to build native web components

76 lines (68 loc) 1.87 kB
<script> class TreeNode extends HTMLElement { constructor() { super(); this.attachShadow({mode: "open"}); this.shadowRoot.innerHTML = ` <style> :host { display: block; } span { cursor: pointer; display: inline-block; transform: rotate(45deg); transition: 300ms ease-in-out; } :host([open]) span { transform: rotate(0deg); } slot { display: none; } :host([open]) slot { display: inline; } </style> <span>+</span> <slot></slot>`; this.shadowRoot.querySelector("span").addEventListener("click", this.onClick.bind(this)); } static get observedAttributes() { return ["open"]; } attributeChangedCallback(name, oldValue, newValue) { if (name === "open") newValue === null ? this.closeChildren() : this.openParent(); } closeChildren() { for (let child of this.children) { if (child.tagName === "TREE-NODE" && child.hasAttribute("open")) child.removeAttribute("open"); } } openParent() { const parent = this.parentNode; if (parent.tagName && parent.tagName === "TREE-NODE" && !parent.hasAttribute("open")) parent.setAttribute("open", ""); } onClick(e) { e.stopPropagation(); this.hasAttribute("open") ? this.removeAttribute("open") : this.setAttribute("open", ""); } } customElements.define("tree-node", TreeNode); </script> <style> tree-node { border: 2px solid grey; padding: 10px; } </style> <tree-node> <tree-node>hello world</tree-node> <tree-node> <tree-node>hello sunshine</tree-node> <tree-node>hello blue skies</tree-node> </tree-node> </tree-node>