/** * Shopping Bag Icon Web Component * A reusable shopping bag/cart icon element with optional badge count */ class ShoppingBagIcon extends HTMLElement { static get observedAttributes() { return ["size", "color", "stroke-width", "count"]; } constructor() { super(); this.attachShadow({ mode: "open" }); this.handleCartUpdate = this.handleCartUpdate.bind(this); } connectedCallback() { this.render(); // Listen for cart updates window.addEventListener("cart-updated", this.handleCartUpdate); // Initialize count from cart store if available this.initializeCount(); } disconnectedCallback() { window.removeEventListener("cart-updated", this.handleCartUpdate); } initializeCount() { // Wait for cart store to be available setTimeout(() => { if (window.cartStore) { const count = window.cartStore.getItemCount(); if (count > 0) { this.setAttribute("count", count.toString()); } } }, 0); } handleCartUpdate(event) { const { count } = event.detail; if (count > 0) { this.setAttribute("count", count.toString()); } else { this.removeAttribute("count"); } } attributeChangedCallback() { this.render(); } get size() { return this.getAttribute("size") || "32"; } get color() { return this.getAttribute("color") || "#ffffff"; } get strokeWidth() { return this.getAttribute("stroke-width") || "2"; } get count() { const countAttr = this.getAttribute("count"); return countAttr ? parseInt(countAttr, 10) : 0; } render() { const showBadge = this.count > 0; const displayCount = this.count > 99 ? "99+" : this.count.toString(); this.shadowRoot.innerHTML = `