Hacker News new | ask | show | jobs
by LorenzA 1048 days ago
you can just have an unnamed slot. I'm probably missing something here haven't build a tabs thing in a long time. But just trying this out for a couple of minutes the thing you want seems to be possible. I didn't do any styling here and the code is just something I hacked down to test it. Where hn-tabs is your tab-area and hn-tab your tab-

   class HnTabs extends HTMLElement {
       constructor() {
           super();
           this._tabs = {}
           this.attachShadow({ mode: 'open' })
           const ul = document.createElement('ul')
           this.shadowRoot.appendChild(ul)
           const slot = document.createElement('slot')         
           this.shadowRoot.appendChild(slot)
           slot.addEventListener('slotchange', () => {
             ul.innerHTML = ''
             const tabs = Array.from(this.querySelectorAll('hn-
             if (!tabs.some((tab) => tab.hasAttribute('active')
               tabs[0].setAttribute('active', '')
             }
             tabs.forEach((tab) => {
               const li = document.createElement('li')
               li.innerText = tab.getAttribute('text')
               ul.appendChild(li)
               li.addEventListener('click', (e) => {
                 tabs.forEach((t) => t.removeAttribute('active'
                 tab.setAttribute('active', '')
               })
             })
           })
       }
   }
   customElements.define('hn-tabs', HnTabs);
   
   class HnTab extends HTMLElement {
       static get observedAttributes() {
         return ['active'];
       }
       constructor() {
           super()
           this.attachShadow({ mode: 'open' });
           this._slot = document.createElement('slot')         
           this.shadowRoot.appendChild(this._slot)
           this._slot.style.display = 'none'
           console.log(this.slot)
       }
       attributeChangedCallback() {
         this.#activeStatus()
       }
       connectedCallback() {
         this.#activeStatus()
       }
       #activeStatus(){
         const active = this.hasAttribute('active');
         this._slot.style.display = active ? 'block' : 'none'
       }
   }
   customElements.define('hn-tab', HnTab);
2 comments

When I have some time I'll play around with this: I'm certainly open to the idea that there's some stuff I don't know about slots. But I have a question: When you append the slot to the shadow root, doesn't that mean that you lose styling in the slot contents?
no things inside slots keep the styling from the outside
Hm, I stand by my comment that slots are overcomplicated, but that might actually make it worth it.
Okay, I got around to trying this out, and that's cool. Thanks for explaining this.
you are welcome happy to help.
Unless you are still in the IE world (which is challenging when using WCs), use one `append` instead of multiple `appendChild`