How to Build a Counter Component with Web Components
November 29th, 2023In this video, learn how to build a basic counter component with JavaScript Web Components. If you're new to web components, this is a perfect beginners tutorial to start building your own custom elements and components.
Video Tutorial
Source Code
You can find the source code for this video below.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Counter with Web Components</title>
<script type="module" src="js/index.js"></script>
</head>
<body>
<counter-component id="myCounter"></counter-component>
</body>
</html>
components/Counter.js
export default class Counter extends HTMLElement {
css = `
:host {
display: block;
max-width: 150px;
background-color: white;
border-radius: 4px;
padding: 16px;
border: 1px solid #dddddd;
user-select: none;
}
.value {
padding: 24px 0;
text-align: center;
font-family: sans-serif;
font-size: 48px;
}
.buttons {
display: flex;
gap: 16px;
}
.button {
flex-grow: 1;
font-size: 24px;
padding: 16px 0;
background: #dddddd;
color: #333333;
cursor: pointer;
outline: none;
border: none;
border-radius: 4px;
}
.button:active {
background: #cccccc;
}
`
template = () => {
return `
<div class="value">${this.value}</div>
<div class="buttons">
<button type="button" class="button button--increment">+</button>
<button type="button" class="button button--decrement">-</button>
</div>
`;
}
constructor() {
super();
this.value = 0;
this.attachShadow({ mode: "open" });
this.render();
}
render() {
this.shadowRoot.innerHTML = `
<style>${this.css.trim()}</style>
${this.template().trim()}
`;
this.shadowRoot.querySelector(".button--increment").addEventListener("click", this.onIncrementButtonClick);
this.shadowRoot.querySelector(".button--decrement").addEventListener("click", this.onDecrementButtonClick);
}
onIncrementButtonClick = () => {
this.value++;
this.render();
}
onDecrementButtonClick = () => {
this.value = Math.max(0, this.value - 1);
this.render();
}
}
index.js
import Counter from "./components/Counter.js";
customElements.define("counter-component", Counter);
const myCounter = document.getElementById("myCounter");
setTimeout(() => console.log(myCounter.value), 2000);
If you have any questions about this code, please leave a comment on the video.