Skip to content

Cart drawer

A slide-in cart drawer with line items, steppers, totals, and a checkout link.

A slide-in cart panel available on every page, plus a cart button with a live count in your nav. The drawer opens after a successful add to cart, and while open it is a full modal dialog (focus trap, Escape to close, focus returned to the opener) with no ARIA work on your part.

<header class="site-header">
<open-cart class="cart-button">
Cart (<show-cart-count>0</show-cart-count>)
</open-cart>
</header>
<storesynk-cart class="drawer" close-on-outside>
<close-cart class="close">×</close-cart>
<h2>Your cart</h2>
<p class="cart-empty-message">Your cart is empty.</p>
<cart-line-list>
<!-- First cart-line = the per-line TEMPLATE; cloned once per cart line. -->
<cart-line>
<show-line-image class="cart-img"></show-line-image>
<div class="line-info">
<show-line-title></show-line-title>
<show-line-variant class="muted"></show-line-variant>
<show-line-price></show-line-price>
</div>
<div class="qty">
<decrease-line-quantity>−</decrease-line-quantity>
<show-line-quantity></show-line-quantity>
<increase-line-quantity>+</increase-line-quantity>
</div>
<remove-cart-line class="muted">×</remove-cart-line>
</cart-line>
</cart-line-list>
<div class="cart-foot">
<div>Subtotal: <show-cart-subtotal></show-cart-subtotal></div>
<div>Total: <show-cart-total></show-cart-total></div>
<checkout-link><a class="checkout-btn" href="#">Checkout</a></checkout-link>
</div>
</storesynk-cart>
  • <storesynk-cart> registers the global open-cart action, so any <open-cart> on the page opens this drawer. <close-cart> must be inside the drawer.
  • <cart-line-list> clones its first <cart-line> child once per line; everything inside reads that line’s context. Totals and <checkout-link> are store-level, so keep them outside the template.
  • The drawer opens on a successful add by default. The site-wide opt-out is {"cart":{"openOnAdd":false}} in the centralized config block.
TagAttributeType / defaultWhat it does
storesynk-cartopen-on-addbooleanOpens the drawer after a successful add. Already the default; the attribute only forces it back on over a config-level openOnAdd: false.
storesynk-cartclose-on-outsidebooleanA pointerdown outside the open drawer closes it. Style your own scrim; clicks on it count as outside.

The line tags, show-cart-* displayers, checkout-link, open-cart, and close-cart take no attributes.

.drawer {
position: fixed; top: 0; right: 0; height: 100%; width: 340px; background: #fff;
transform: translateX(100%); transition: transform .25s ease, visibility .25s;
visibility: hidden; /* a closed drawer must be untabbable, not just off-screen */
}
.drawer[ss-open] { transform: translateX(0); visibility: visible; }
.cart-empty-message { display: none; }
storesynk-cart[ss-empty] .cart-empty-message { display: block; }
cart-line[ss-loading] { opacity: .5; pointer-events: none; }

[ss-loading] lands on a <cart-line> while its own quantity or remove mutation is in flight; the engine also disables that line’s controls until it settles.

  • The drawer won’t open from the cart icon when there is no <storesynk-cart> on the page (or no <storesynk-store> around it). See cart troubleshooting.
  • No lines, or blank line titles: the first-child <cart-line> template is missing (SSK-107), or show-line-* sits outside <cart-line> (SSK-105).
  • Never use <clear-cart> as the empty-state container. It is a destructive control that removes every line.