Skip to content

Instantly share code, notes, and snippets.

@gtindo
Created January 22, 2025 15:24
Show Gist options
  • Select an option

  • Save gtindo/f640e59f2baf7eee7cf7dd8281adae91 to your computer and use it in GitHub Desktop.

Select an option

Save gtindo/f640e59f2baf7eee7cf7dd8281adae91 to your computer and use it in GitHub Desktop.
Counter Element
<!DOCTYPE html>
<html lang="en">
<head>
<title>Counter element</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<script type="module" src="./counter.js"></script>
</head>
<body>
<x-counter></x-counter>
<template id="x-counter">
<div>
<button id="min-btn">-</button>
<span id="counter-display">0</span>
<button id="plus-btn">+</button>
</div>
</template>
</body>
</html>
class XCounter extends HTMLElement {
constructor() {
super();
this.counter = 0; // Start the counter at 0
this.elements = {}; // To store references to our buttons and display
}
connectedCallback() {
// This runs when the element is added to the page
const template = document.getElementById('x-counter');
this.attachShadow({ mode: 'open' });
// Add styles to the component
const sheet = new CSSStyleSheet();
sheet.replaceSync(this.styles());
this.shadowRoot.adoptedStyleSheets = [sheet];
// Clone the template and add it to our custom element's shadow DOM
this.shadowRoot.appendChild(template.content.cloneNode(true));
// Get references to the buttons and display
this.elements = {
plusBtn: this.shadowRoot.querySelector('#plus-btn'),
minBtn: this.shadowRoot.querySelector('#min-btn'),
counterDisplay: this.shadowRoot.querySelector('#counter-display'),
};
// Show the initial counter value
this.displayCount();
// Add event listeners for the buttons
this.elements.plusBtn.onclick = () => this.increment();
this.elements.minBtn.onclick = () => this.decrement();
}
increment() {
this.counter += 1;
this.displayCount();
}
decrement() {
this.counter -= 1;
this.displayCount();
}
displayCount() {
this.elements.counterDisplay.textContent = this.counter;
}
styles() {
return `
:host {
display: block;
border: dotted 3px #333;
width: fit-content;
height: fit-content;
padding: 15px;
}
button {
border: solid 1px #333;
padding: 10px;
min-width: 35px;
background: #333;
color: #fff;
cursor: pointer;
}
button:hover {
background: #222;
}
span {
display: inline-block;
padding: 10px;
width: 50px;
text-align: center;
}
`;
}
}
// Register the custom element so we can use it in HTML
customElements.define('x-counter', XCounter);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment