From af0245de437cf8ed52567385a6a4f242eea720a3 Mon Sep 17 00:00:00 2001 From: elvira Date: Thu, 17 Sep 2026 21:56:58 +0300 Subject: [PATCH] ux fix on product increase --- resources/js/checkout/bbk-cart-controller.js | 25 ++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/resources/js/checkout/bbk-cart-controller.js b/resources/js/checkout/bbk-cart-controller.js index d3eb98b..dfe5901 100644 --- a/resources/js/checkout/bbk-cart-controller.js +++ b/resources/js/checkout/bbk-cart-controller.js @@ -18,6 +18,7 @@ export default class extends Controller { connect() { this.onChanged = this.onChanged.bind(this) this.onKeydown = this.onKeydown.bind(this) + this.updateTimers = new Map() // line id -> pending debounce timer window.addEventListener('bbk-cart:changed', this.onChanged) window.addEventListener('bbk-cart:open', this.open.bind(this)) @@ -30,6 +31,7 @@ export default class extends Controller { disconnect() { window.removeEventListener('bbk-cart:changed', this.onChanged) document.removeEventListener('keydown', this.onKeydown) + this.updateTimers.forEach((timer) => clearTimeout(timer)) } onChanged(event) { @@ -63,7 +65,11 @@ export default class extends Controller { submit(event) { event.preventDefault() const form = event.target.closest('form') - if (form) this.send(form) + if (!form) return + + // A remove is a deliberate, one-shot action — only the quantity form + // (typing, or the +/- stepper below) benefits from debouncing. + form.classList.contains('bbk-cart-qty') ? this.scheduleSend(form) : this.send(form) } // +/- stepper buttons inside a line @@ -73,7 +79,22 @@ export default class extends Controller { const input = form.querySelector('input[type="number"]') const next = Math.max(0, parseInt(input.value || '0', 10) + Number(event.params.dir)) input.value = String(next) - this.send(form) + this.scheduleSend(form) + } + + // Repeated clicks (or spinner nudges) update the input instantly but only + // send once they settle for 300ms — sending on every single click was + // firing overlapping requests that raced each other and made the drawer + // visibly flicker/lag under quick clicking. + scheduleSend(form) { + const lineId = form.closest('[data-bbk-line-id]')?.dataset.bbkLineId + if (!lineId) return this.send(form) + + clearTimeout(this.updateTimers.get(lineId)) + this.updateTimers.set(lineId, setTimeout(() => { + this.updateTimers.delete(lineId) + this.send(form) + }, 300)) } async send(form) {