UNPKG

ecom-widget

Version:
129 lines (116 loc) 5.13 kB
(function(){"use strict";window.EcomWidget={init(c){const b=c.selector||"#my-ecom-widget",p=document.querySelector(b);if(!p)return console.warn("Container not found");const n=c.visibleCount||5,l=500,f=16,s=p.attachShadow({mode:"open"});s.innerHTML=` <style> :host { all: initial; } .widget-wrapper { position: relative; } .widget-box { --visible: ${n}; --gap: ${f}px; font-family: 'Inter', sans-serif; background: #fff; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.08); overflow: hidden; position: relative; } /* Edge fade overlays */ .widget-box::before, .widget-box::after { content: ""; position: absolute; top: 0; bottom: 0; width: calc((100% - (100% - (var(--visible) - 1) * var(--gap))) / 2); pointer-events: none; z-index: 5; } .widget-box::before { left: 0; background: linear-gradient(to right, #fff, transparent); } .widget-box::after { right: 0; background: linear-gradient(to left, #fff, transparent); } #products { display: flex; gap: var(--gap); transition: transform ${l}ms ease; will-change: transform; } .product { flex: 0 0 calc((100% - (var(--visible) - 1) * var(--gap)) / var(--visible)); background: #fff; border: 1px solid #e2e8f0; border-radius: 8px; box-shadow: 0 1px 4px rgba(0,0,0,0.06); padding: 12px; display: flex; flex-direction: column; align-items: center; justify-content: space-between; } .product img { width: 80px; height: 80px; object-fit: contain; margin-bottom: 8px; } .info { text-align: center; } .info h4 { font-size: 14px; margin: 0 0 4px; color: #111; height: 32px; overflow: hidden; } .info p { font-size: 13px; margin: 0; color: #666; } .action-btn { margin-top: 8px; padding: 6px 12px; font-size: 13px; border: none; border-radius: 4px; background: #0070f3; color: #fff; cursor: pointer; transition: background 0.2s; } .action-btn:hover { background: #0055aa; } .action-btn:disabled { background: #ccc; cursor: default; } .nav-button { position: absolute; top: 50%; transform: translateY(-50%); width: 32px; height: 32px; border: none; background: rgba(255,255,255,0.9); border-radius: 50%; box-shadow: 0 1px 4px rgba(0,0,0,0.1); cursor: pointer; font-size: 16px; line-height: 32px; text-align: center; padding: 0; z-index: 10; } .prev { left: 8px; } .next { right: 8px; } </style> <div class="widget-wrapper"> <button class="nav-button prev">&#10094;</button> <div class="widget-box"><div id="products">Loading…</div></div> <button class="nav-button next">&#10095;</button> </div> `;const t=s.getElementById("products"),x=s.querySelector(".prev"),u=s.querySelector(".next");let e;fetch(`https://fakestoreapi.com/products/category/${c.category||"electronics"}`).then(o=>o.json()).then(o=>{const g=o.length,h=o.slice(0,n),v=[...o.slice(-n),...o,...h];t.innerHTML="",v.forEach(a=>{const d=document.createElement("div");d.className="product",d.innerHTML=` <img src="${a.image}" alt="${a.title}" /> <div class="info"> <h4>${a.title}</h4> <p>$${a.price}</p> </div> <button class="action-btn">Add</button> `;const r=d.querySelector("button");r.addEventListener("click",()=>{r.disabled=!0,r.textContent="Adding…",fetch("https://fakestoreapi.com/carts",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userId:1,date:new Date().toISOString(),products:[{productId:a.id,quantity:1}]})}).then(()=>r.textContent="Added!").catch(()=>{r.textContent="Error",r.disabled=!1})}),t.appendChild(d)});const i=t.children[0].getBoundingClientRect().width+f;e=n,t.style.transform=`translateX(-${i*e}px)`,t.addEventListener("transitionend",()=>{t.style.transition="",e>=g+n&&(e=n,t.style.transition="none",t.style.transform=`translateX(-${i*e}px)`),e<n&&(e=g+n-1,t.style.transition="none",t.style.transform=`translateX(-${i*e}px)`)}),x.addEventListener("click",()=>{t.style.transition=`transform ${l}ms ease`,e--,t.style.transform=`translateX(-${i*e}px)`}),u.addEventListener("click",()=>{t.style.transition=`transform ${l}ms ease`,e++,t.style.transform=`translateX(-${i*e}px)`})}).catch(()=>{t.innerHTML='<p style="padding:16px;color:#900">Error loading products.</p>'})}}})();