Created
January 23, 2025 20:06
-
-
Save cferdinandi/57c0734439eb4de9ae255bd5201af94e to your computer and use it in GitHub Desktop.
Watch the tutorial: https://youtu.be/yisEDBIl9Yk
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 lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>Ecommerce 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%; | |
} | |
cart-link, | |
product-listing { | |
display: block; | |
margin-bottom: 1em; | |
} | |
</style> | |
</head> | |
<body> | |
<cart-link></cart-link> | |
<p><strong>Jolly Roger T-Shirt</strong></p> | |
<product-listing price="39" uid="tshirt-jolly-roger"></product-listing> | |
<p><strong>Anchor (gently used)</strong></p> | |
<product-listing price="79" uid="anchor"></product-listing> | |
<p><strong>Parrot</strong></p> | |
<product-listing price="189" uid="parrot"></product-listing> | |
<script src="main.js"></script> | |
</body> | |
</html> |
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
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 = {}; | |
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>`; | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment