Skip to content

Instantly share code, notes, and snippets.

@cferdinandi
Created January 21, 2025 04:25
Show Gist options
  • Save cferdinandi/2a2654a4490ce9ec50e8e21eb70179ac to your computer and use it in GitHub Desktop.
Save cferdinandi/2a2654a4490ce9ec50e8e21eb70179ac to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Ecomerce Platform</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style type="text/css">
body {
margin: 1em auto;
max-width: 40em;
width: 88%;
}
</style>
</head>
<body>
<cart-link></cart-link>
<product-listing price="39" uid="tshirt-jolly-roger"></product-listing>
<script>
class Signal {
// Initialize the class
constructor (val) {
this.value = val;
}
// Add a new item
add (key, val) {
// Update the value
this.value[key] = val;
// Create a new event
let event = new CustomEvent('cart-updated', {
bubbles: true,
detail: {key, val}
});
// Dispatch the event
return document.dispatchEvent(event);
}
// Get the number of items in the cart
size () {
return Object.keys(this.value).length;
}
// Check if an item is in the object
has (key) {
return !!this.value[key];
}
}
let cart = new Signal({});
customElements.define('cart-link', class extends HTMLElement {
// Instantiate the Web Component
constructor () {
// Inherit parent class properties
super();
// Render the initial UI
this.render();
// Listen for cart events
document.addEventListener('cart-updated', this);
}
// Handle Events
handleEvent (event) {
this.render();
}
// Render the UI
render () {
this.innerHTML = `<a href="/checkout">🛒 ${cart.size()} Items</a>`;
}
});
customElements.define('product-listing', class extends HTMLElement {
/**
* Instantiate the Web Component
*/
constructor () {
// Inherit parent class properties
super();
// Set properties
this.uid = this.getAttribute('uid');
this.price = parseFloat(this.getAttribute('price'));
// Render the initial UI
this.render();
// Listen for events
document.addEventListener('cart-updated', this);
this.addEventListener('click', this);
}
// Handle events
handleEvent (event) {
// If it's a cart update event
if (event.type === 'cart-updated') {
this.render();
return;
}
// If it's a click on the button
if (event.type === 'click' && event.target.closest('button')) {
cart.add(this.uid, this.price);
}
}
// Render the UI
render () {
this.innerHTML = cart.has(this.uid) ? '<em>This is item in your cart</em>' : `<button>Add to Cart - $${this.price}</button>`;
}
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment