Recipe 12.7

Creating a Styled Button Component

Demo

Default Primary Danger

Code

JavaScript
const template = document.createElement('template');
template.innerHTML = `
  <style>
    button {
      background: #333;
      padding: 0.5em 1.25em;
      font-size: 1rem;
      border: none;
      border-radius: 5px;
      color: white;
    }

    button.primary {
      background: #2563eb;
    }

    button.danger {
      background: #dc2626;
    }
  </style>

  <button>
    <slot></slot>
  </button>
`;

class StyledButton extends HTMLElement {
  static observedAttributes = ['variant', 'type'];

  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
    this.shadowRoot.appendChild(template.content.cloneNode(true));
    this.button = this.shadowRoot.querySelector('button');
  }

  attributeChangedCallback(name, oldValue, newValue) {
    if (name === 'variant') {
      this.button.className = newValue;
    } else if (name === 'type') {
      this.button.type = newValue;
    }
  }
}

if (!customElements.get('styled-button')) {
  customElements.define('styled-button', StyledButton);
}

document.querySelector('#default-button').addEventListener('click', () => {
  alert('Clicked the default button');
});

document.querySelector('#primary-button').addEventListener('click', () => {
  alert('Clicked the primary button');
});

document.querySelector('#danger-button').addEventListener('click', () => {
  alert('Clicked the danger button');
});

HTML
<style>
  styled-button:not(:defined) {
    display: none;
  }
</style>

<styled-button id="default-button" type="button">Default</styled-button>
<styled-button id="primary-button" type="button" variant="primary">Primary</styled-button>
<styled-button id="danger-button" type="button" variant="danger">Danger</styled-button>
Web API Cookbook
Joe Attardi