3 ms·
Most of the time you have the tab and the panel to display the content of the tab a super simple demo implementation of something like this https://web.dev/comp
by LorenzA 3y ago
Most of the time you have the tab and the panel to display the content of the tab a super simple demo implementation of something like this https://web.dev/components-howto-tabs/ https://web.dev/components-howto-tabs/
In regards of slots, they are a nice way to allow a user of you webcomponent to overwrite/replace parts of your component with something else. This is most of the time a more advanced feature and I find it quite nice to build headless components
- kerkeslager 3y ago> Most of the time you have the tab and the panel to display the content of the tab a super simple demo implementation of something like this https://web.dev/components-howto-tabs/ https://web.dev/components-howto-tabs/ That's exactly what I'm saying is bad. Why does the user of the howto-tabs have to type "slot='panel'" when that information is already communicated by the fact that it's a "howto-panel" inside a "howto-tabs"? This is a useless leaking of implementation details. And that page just keeps going and going. Sure, some of that is because they're implementing a few neat features, but most of it is because slots are way overcomplicated for something that's actually easier to do without them.
- dannye 3y agouse: slotAssignment: 'manual'
- LorenzA 3y agoyou 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);
- dannye 3y agoUnless you are still in the IE world (which is challenging when using WCs), use one `append` instead of multiple `appendChild`
- kerkeslager 3y agoWhen 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?
- LorenzA 3y agono things inside slots keep the styling from the outside
- kerkeslager 3y agoHm, I stand by my comment that slots are overcomplicated, but that might actually make it worth it.
- kerkeslager 3y agoOkay, I got around to trying this out, and that's cool. Thanks for explaining this.
- LorenzA 3y agoyou are welcome happy to help.