<custom-menu>

💾 replit, codepen

/* ---------- helper methods ---------- */

// root.$()
DocumentFragment.prototype.$ = function(selector){
    return this.querySelector(selector);
};

// ⭐️ get/set attribute
//    get: elem.attr(name)
//    set: elem.attr(name, value)
Element.prototype.attr = function(name, value=undefined){
    if(value !== undefined){ this.setAttribute(name, value) };
    return this.getAttribute(name) || undefined;
};

/* ---------- custom element ---------- */

class CustomMenu extends HTMLElement {

    // connected to document
    connectedCallback() {

        // attach shadow root
        let root = this.attachShadow({mode: 'open'});

        // ⭐️ clone nodes from <template>
        let clone = tmpl.content.cloneNode(true);
        root.append( clone );

        this.menu = root.$('.menu');
        this.menuTitle = root.$('slot[name="title"]');

        // we can't select light DOM nodes, 
        // so let's handle clicks on the slot
        this.menuTitle.onclick = () => {
            // open/close the menu
            this.menu.classList.toggle('closed');
            console.log(this.menu.classList);
        };
    }
}

customElements.define('custom-menu', CustomMenu);

Last updated