01 · sections/bundle-progress.liquid
Barra de bundle por niveles
Entregada en Winona: 2 productos dan 10% de descuento, 3 dan 15% y 4 dan 20%. La barra está encima del header en todas las páginas, así la oferta se ve antes de abrir el carrito.
- Siempre muestra la siguiente recompensa, no solo la actual
- Los niveles viven en bloques de la sección, editables sin deploy
- El mismo HTML al cargar y después de cada cambio del carrito
Presiona + y − para cambiar el carrito
Arma tu bundle y ahorra
Agrega 1 producto más para desbloquear 10% de descuento
Datos de demo, no la tienda real
{%- liquid
assign count = cart.item_count
assign discount = 0
assign next_tier = nil
for block in section.blocks
if count >= block.settings.min_items
assign discount = block.settings.percent_off
elsif next_tier == nil
assign next_tier = block
endif
endfor
assign fill = count | minus: 1 | at_least: 0 | times: 100 | divided_by: 3
-%}
<bundle-progress
data-section-id="{{ section.id }}"
data-discount="{{ discount }}"
style="--fill: {{ fill | at_most: 100 }}%"
>
{%- if next_tier -%}
{%- assign left = next_tier.settings.min_items | minus: count -%}
{{ 'bundle.unlock' | t: count: left, percent: next_tier.settings.percent_off }}
{%- else -%}
{{ 'bundle.best_price' | t }}
{%- endif -%}
</bundle-progress>// Re-renders the bar through the Section Rendering API
// whenever the cart changes, so tiers stay merchant-editable.
class BundleProgress extends HTMLElement {
connectedCallback() {
document.addEventListener('cart:updated', this.refresh);
}
disconnectedCallback() {
document.removeEventListener('cart:updated', this.refresh);
}
refresh = async () => {
const url = `${Shopify.routes.root}?section_id=${this.dataset.sectionId}`;
const html = await (await fetch(url)).text();
const next = new DOMParser()
.parseFromString(html, 'text/html')
.querySelector('bundle-progress');
if (next) this.replaceWith(next);
};
}
customElements.define('bundle-progress', BundleProgress);






