Skip to content

Instantly share code, notes, and snippets.

@cjc
Last active July 17, 2021 10:54
Show Gist options
  • Save cjc/6ad026eacce25581542e190bf792d8a7 to your computer and use it in GitHub Desktop.
Save cjc/6ad026eacce25581542e190bf792d8a7 to your computer and use it in GitHub Desktop.
Webcomponent reference and boilerplates
<test-component>
<span>Slotted</span>
</test-component>
<!-------------------------->
<template id="test">
<style>
:host {
display:inline-block;
content:contain;
border: 1px solid grey;
}
</style>
Shadow <slot></slot>
</template>
<script>
class TestComponent extends HTMLElement {
constructor() {
super();
this.template = document.querySelector('template#test');
}
connectedCallback() {
this.attachShadow({ mode: 'open' });
this.shadowRoot.appendChild(document.importNode(this.template.content, true));
}
}
window.addEventListener('DOMContentLoaded', function() {
customElements.define('test-component', TestComponent);
});
</script>
<slot-watcher>
<div title="Apples" slot="a">Apple</div>
<div title="Bananas" slot="b">Banana</div>
<div title="Cherries" slot="c">Cherry</div>
</slot-watcher>
<label><input type="radio" name="slot" value="a">a</label>
<label><input type="radio" name="slot" value="b">b</label>
<label><input type="radio" name="slot" value="c">c</label>
<label><input type="radio" name="slot" value="" checked>default</label>
<button id="add">Add a slotted element</button>
<script>
var counter = 0;
document.getElementById('add').addEventListener('click',(ev) => {
var elem = document.createElement('div');
elem.innerText = Math.random();
counter += 1;
elem.title = 'dyn'+counter;
elem.setAttribute('slot',Array.from(document.querySelectorAll('input[name=slot]')).find(input => input.checked).value);
document.querySelector('slot-watcher').append(elem);
});
</script>
<!--------------------------->
<template id="test">
<fieldset>
<legend>Slot watcher</legend>
<fieldset><legend>Slot a - </legend><slot name="a"></slot></fieldset>
<fieldset><legend>Slot b - </legend><slot name="b"></slot></fieldset>
<fieldset><legend>Slot c - </legend><slot name="c"></slot></fieldset>
<fieldset><legend>Default slot - </legend><slot></slot></fieldset>
</fieldset>
</template>
<script>
class SlotWatcher extends HTMLElement {
constructor() {
super();
this.template = document.querySelector('template#test');
}
connectedCallback() {
this.attachShadow({ mode: 'open' });
this.shadowRoot.appendChild(document.importNode(this.template.content, true));
this.shadowRoot.addEventListener('slotchange',function(ev) {
var elems = ev.srcElement.assignedElements();
ev.srcElement.parentNode.querySelector('legend').innerText = "Slot " + ev.srcElement.name + " - " + Array.from(elems).map(e => e.title).join(',');
});
}
}
window.addEventListener('DOMContentLoaded', function() {
customElements.define('slot-watcher', SlotWatcher);
});
</script>
@cjc
Copy link
Author

cjc commented Jul 17, 2021

Snippet for detecting whether an element is in the shadowRoot of the current webcomponent, or in the light dom, using getRootNode()

if (elem.getRootNode() == this.shadowRoot) {
    console.log(elem, 'in shadow');
    pane.slot = elem.closest('section').querySelector('slot').name;
} else {
    console.log(ev, elem, 'in light');
    window.debug = elem;
    pane.slot = elem.closest('*[name]').name
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment