JSFiddle - React, Tailwind, and code Playground
by Udi Talias
HTML
<header>
<div class="glitchButton" style="float:right;"></div>
<h1>Fancy Button Demo</h1>
</header>
<fancy-button>Hello</fancy-button>
<fancy-button icon="/refresh.svg">refresh</fancy-button>
<template>
<style>
:host {
align-items: center;
border: 2px solid currentColor;
border-radius: 2em;
color: #000;
cursor: pointer;
display: inline-flex;
font-family: sans-serif;
font-size: .8em;
height: 2.5em;
justify-content: center;
padding: 0 2em;
vertical-align: middle;
}
:host(:hover) {
box-shadow: 2px 2px 0 currentColor;
text-decoration: underline;
}
:host(:active) {
box-shadow: none;
transform: translate(2px, 2px);
}
img {
display: none;
height: 1em;
margin-right: .5em;
width: 1em;
}
</style>
<img><span><slot></slot></span>
</template>
CSS
/* CSS files add styling rules to your content */
body {
font-family: helvetica, arial, sans-serif;
margin: 2em;
}
h1 {
font-style: italic;
color: #373fff;
}
JavaScript
// Be sure to take a look at index.html as well!
let template = document.querySelector('template');
class FancyButton extends HTMLElement {
constructor() {
super(); // this is mandatory
this.setAttribute('role', 'button');
this.setAttribute('tabindex', '0');
}
connectedCallback() {
let shadowRoot = this.attachShadow({ mode: 'open' });
shadowRoot.appendChild(document.importNode(template.content, true));
this.iconEl = shadowRoot.querySelector('img');
this.setIcon(this.getAttribute('icon'));
}
attributeChangedCallback(attr, oldVal, newVal) {
if (attr === 'icon' && oldVal !== newVal) {
this.setIcon(newVal);
}
}
setIcon(url) {
if (!this.iconEl) return;
if (url === null) {
this.iconEl.style.display = 'none';
} else {
this.iconEl.src = url;
this.iconEl.style.display = 'block';
}
}
}
FancyButton.observedAttributes = ['icon'];
customElements.define('fancy-button', FancyButton);