showing results for - "webcomponent listen to changes"
Mariangel
27 Feb 2018
1(function() {
2  const template = document.createElement('template');
3
4  template.innerHTML = `
5    <style>
6      button,
7      span {
8        font-size: 3rem;
9        font-family: monospace;
10        padding: 0 .5rem;
11      }
12
13      button {
14        background: pink;
15        color: black;
16        border: 0;
17        border-radius: 6px;
18        box-shadow: 0 0 5px rgba(173, 61, 85, .5);
19      }
20
21      button:active {
22        background: #ad3d55;
23        color: white;
24      }
25    </style>
26    <div>
27      <button type="button" increment>+</button>
28      <span></span>
29      <button type="button" decrement>-</button>
30    </div>
31  `;
32
33  class MyCounter extends HTMLElement {
34    constructor() {
35      super();
36
37      this.increment = this.increment.bind(this);
38      this.decrement = this.decrement.bind(this);
39
40      this.attachShadow({ mode: 'open' });
41      this.shadowRoot.appendChild(template.content.cloneNode(true));
42
43      this.incrementBtn = this.shadowRoot.querySelector('[increment]');
44      this.decrementBtn = this.shadowRoot.querySelector('[decrement]');
45      this.displayVal = this.shadowRoot.querySelector('span');
46    }
47
48    connectedCallback() {
49      this.incrementBtn.addEventListener('click', this.increment);
50      this.decrementBtn.addEventListener('click', this.decrement);
51
52      if (!this.hasAttribute('value')) {
53        this.setAttribute('value', 1);
54      }
55    }
56
57    increment() {
58      // using +myVariable coerces myVariable into a number,
59      // we do this because the attribute's value is received as a string
60      const step = +this.step || 1;
61      const newValue = +this.value + step;
62
63      if (this.max) {
64        this.value = newValue > +this.max ? +this.max : +newValue;
65      } else {
66        this.value = +newValue;
67      }
68    }
69
70    decrement() {
71      const step = +this.step || 1;
72      const newValue = +this.value - step;
73
74      if (this.min) {
75        this.value = newValue <= +this.min ? +this.min : +newValue;
76      } else {
77        this.value = +newValue;
78      }
79    }
80
81    static get observedAttributes() {
82      return ['value'];
83    }
84
85    attributeChangedCallback(name, oldValue, newValue) {
86      this.displayVal.innerText = this.value;
87    }
88
89    get value() {
90      return this.getAttribute('value');
91    }
92
93    get step() {
94      return this.getAttribute('step');
95    }
96
97    get min() {
98      return this.getAttribute('min');
99    }
100
101    get max() {
102      return this.getAttribute('max');
103    }
104
105    set value(newValue) {
106      this.setAttribute('value', newValue);
107    }
108
109    set step(newValue) {
110      this.setAttribute('step', newValue);
111    }
112
113    set min(newValue) {
114      this.setAttribute('min', newValue);
115    }
116
117    set max(newValue) {
118      this.setAttribute('max', newValue);
119    }
120
121    disconnectedCallback() {
122      this.incrementBtn.removeEventListener('click', this.increment);
123      this.decrementBtn.removeEventListener('click', this.decrement);
124    }
125  }
126
127  window.customElements.define('my-counter', MyCounter);
128})();