Created
March 12, 2025 15:56
-
-
Save cferdinandi/71317b4881104e15d6a7b70f97c7f093 to your computer and use it in GitHub Desktop.
Watch the tutorial for this code: https://youtu.be/Ap26IwDVOV8
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
customElements.define('count-up-display', class extends HTMLElement { | |
/** | |
* The class constructor object | |
*/ | |
constructor () { | |
// Gives element access to the parent class properties | |
super(); | |
// Define properties | |
this.count = 0; | |
this.max = parseFloat(this.getAttribute('max-count')) ?? false; | |
// Create HTML | |
this.ui = document.createElement('div'); | |
this.ui.setAttribute('aria-live', 'polite'); | |
this.render(); | |
// Inject HTML | |
this.append(this.ui); | |
// Listen for countup events | |
let parent = this.closest('count-up'); | |
parent.addEventListener('countuptrigger', this); | |
parent.addEventListener('countupreset', this); | |
} | |
/** | |
* Handle events on the Web Component | |
* @param {Event} event The event object | |
*/ | |
handleEvent (event) { | |
this[`${event.type}Handler`](event); | |
} | |
/** | |
* Handle trigger events | |
* @param {Event} event The event object | |
*/ | |
countuptriggerHandler (event) { | |
// Make sure we're not at the max count | |
if (this.max && this.count === this.max) return; | |
// Increase the count | |
this.count = this.count + event.detail.interval; | |
this.render(); | |
} | |
/** | |
* Handle reset events | |
* @param {Event} event The event object | |
*/ | |
countupresetHandler (event) { | |
this.count = 0; | |
this.render(); | |
} | |
/** | |
* Render the updated UI | |
*/ | |
render () { | |
this.ui.textContent = `Clicked ${this.count} times`; | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
customElements.define('count-up-reset', class extends HTMLElement { | |
/** | |
* The class constructor object | |
*/ | |
constructor () { | |
// Gives element access to the parent class properties | |
super(); | |
// Define properties | |
this.confirmMessage = this.getAttribute('reset-confirm') ?? 'Are you sure? This cannot be undone.'; | |
// Create HTML | |
this.btn = document.createElement('button'); | |
this.btn.textContent = 'Reset the Count'; | |
// Inject HTML | |
this.append(this.btn); | |
// Listen for click events on the button | |
this.btn.addEventListener('click', this); | |
} | |
/** | |
* Handle events on the Web Component | |
* @param {Event} event The event object | |
*/ | |
handleEvent (event) { | |
let doubleCheck = confirm(this.confirmMessage); | |
if (!doubleCheck) return; | |
this.emit(); | |
} | |
/** | |
* Emit a custom event | |
*/ | |
emit () { | |
// Create a new event | |
let event = new CustomEvent('countupreset', { | |
bubbles: true | |
}); | |
// Dispatch the event | |
return this.dispatchEvent(event); | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
customElements.define('count-up-trigger', class extends HTMLElement { | |
/** | |
* The class constructor object | |
*/ | |
constructor () { | |
// Gives element access to the parent class properties | |
super(); | |
// Define properties | |
let interval = parseFloat(this.getAttribute('intervals')); | |
this.intervals = Number.isNaN(interval) ? 1 : interval; | |
// Create HTML | |
this.btn = document.createElement('button'); | |
this.btn.textContent = 'Click Me'; | |
// Inject HTML | |
this.append(this.btn); | |
// Listen for click events on the button | |
this.btn.addEventListener('click', this); | |
} | |
/** | |
* Handle events on the Web Component | |
* @param {Event} event The event object | |
*/ | |
handleEvent (event) { | |
this.emit({ | |
interval: this.intervals | |
}); | |
} | |
/** | |
* Emit a custom event | |
* @param {Object} detail Any details to pass along with the event | |
*/ | |
emit (detail = {}) { | |
// Create a new event | |
let event = new CustomEvent('countuptrigger', { | |
bubbles: true, | |
detail: detail | |
}); | |
// Dispatch the event | |
return this.dispatchEvent(event); | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
count-up-display { | |
display: block; | |
width: 100%; | |
margin-bottom: 1rem; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
customElements.define('count-up', class extends HTMLElement { | |
/** | |
* The class constructor object | |
*/ | |
constructor () { | |
// Gives element access to the parent class properties | |
super(); | |
// get options and settings | |
let maxCount = this.getAttribute('max-count'); | |
let intervals = this.getAttribute('intervals'); | |
let resetConfirm = this.getAttribute('reset-confirm'); | |
// Inject some HTML | |
this.innerHTML = | |
`<count-up-display ${maxCount ? `max-count="${maxCount}"` : ''}></count-up-display> | |
<count-up-trigger ${intervals ? `intervals="${intervals}"` : ''}></count-up-trigger> | |
<count-up-reset ${resetConfirm ? `reset-confirm="${resetConfirm}"` : ''}></count-up-reset>`; | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Count-Up</title> | |
<style type="text/css"> | |
body { | |
margin: 1em auto; | |
max-width: 30em; | |
width: 88%; | |
} | |
</style> | |
<link rel="stylesheet" type="text/css" href="count-up.css"> | |
</head> | |
<body> | |
<h1>Count-Up</h1> | |
<count-up max-count="21" intervals="3" reset-confirm="You sure yo? Bad idea!"></count-up> | |
<script src="count-up.js"></script> | |
<script src="count-up-display.js"></script> | |
<script src="count-up-trigger.js"></script> | |
<script src="count-up-reset.js"></script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment