<!DOCTYPE html>
<html>

<head>

  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <title>Reactive web component example</title>

  <template id="template">
    <button id="decrement">-</button>
    <span id="value"></span>
    <button id="increment">+</button>
  </template>

  <script type="module">
    import ReactiveMixin from '../mixins/ReactiveMixin.js';
    import symbols from '../mixins/symbols.js';

    class IncrementDecrement extends ReactiveMixin(HTMLElement) {

      // Allow the value property to be set via an attribute.
      attributeChangedCallback(attributeName, oldValue, newValue) {
        if (attributeName === 'value') {
          this.value = parseInt(newValue);
        }
      }

      get defaultState() {
        return Object.assign({}, super.defaultState, {
          value: 0
        });
      }

      // Render the current state to the DOM.
      // ReactiveMixin invokes this method when the state changes.
      [symbols.render]() {
        if (super[symbols.render]) { super[symbols.render](); }
        if (!this.shadowRoot) {
          // First time we render, create the shadow subtree.
          const root = this.attachShadow({ mode: 'open' });
          const clone = document.importNode(template.content, true);
          root.appendChild(clone);
          // Wire up event handlers.
          root.querySelector('#decrement').addEventListener('click', () => {
            this.value--;
          });
          root.querySelector('#increment').addEventListener('click', () => {
            this.value++;
          });
        }
        // Render the state into the shadow.
        this.shadowRoot.querySelector('#value').textContent = this.state.value;
      }

      // Expose "value" as an attribute.
      static get observedAttributes() {
        return ['value'];
      }

      // Provide a public property that gets/sets state.
      get value() {
        return this.state.value;
      }
      set value(value) {
        this.setState({ value });
      }

    }

    customElements.define('increment-decrement', IncrementDecrement);
  </script>

</head>

<body>
  <increment-decrement value="10"></increment-decrement>
</body>

</html>

Add increment/decrement demo of ReactiveMixin.
Add increment/decrement demo of ReactiveMixin.
