Skip to content

Instantly share code, notes, and snippets.

@matthewp
Last active April 23, 2020 07:57
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save matthewp/7aad10707e460ddf9d3cfe3f7f71241d to your computer and use it in GitHub Desktop.
Save matthewp/7aad10707e460ddf9d3cfe3f7f71241d to your computer and use it in GitHub Desktop.
decorate-element
function decorate(tag, template) {
customElements.define(tag, class extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
let root = this.shadowRoot;
if(!root.firstChild) {
root.appendChild(document.importNode(template.content, true));
}
}
});
}
customElements.define('decorate-element', class extends HTMLElement {
connectedCallback() {
let tag = this.getAttribute('tag');
let template = this.firstElementChild;
if(template) {
decorate(tag, template);
} else {
let mo = new MutationObserver(() => {
template = this.firstElementChild;
if(template) {
mo.disconnect();
decorate(tag, template);
}
});
mo.observe(this, { childList: true });
}
}
});
<!doctype html>
<html lang="en">
<title>Example usage</title>
<script src="./decorate-element.js"></script>
<decorate-element tag="pricing-tier">
<template>
<style>
:host { display: block; }
</style>
<header>
<h1>$<slot name="price"></slot></h1>
<h2><slot name="name"></slot></h2>
</header>
<div class="features">
<slot name="features"></slot>
</div>
</template>
</decorate-element>
<pricing-tier>
<span slot="price">10</span>
<span slot="name">Basic</span>
<ul slot="features">
<li>Unlimited foo</li>
</ul>
</pricing-tier>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment