Slide-over mini cart with a free-shipping meter and quick checkout.
Shipping and taxes are calculated at checkout.
Install with the CLI, or add the packages and paste the source below.
Add Cart to your app with its source-owned dependencies.
npx cronus-ui add cart
Install the Cronus UI packages, then paste the block below.
Copy the source for Drawer. Every class is a semantic token, so it re-themes with your app.
import { Badge, Button, Progress } from "@cronus-ui/ui";import { Package, ShoppingBag, X } from "lucide-react";import { CART, productById } from "../lib/demo-store.js";interface CartLine {id: string;name: string;option: string;price: string;qty: number;gradient: string;}// Derive the cart view from the shared demo-store CART (each line references a// PRODUCTS id): name/price/gradient come from the product, option/qty from the// cart line — the same items the order and invoice show.const cartLines: CartLine[] = CART.map((line) => {const product = productById(line.productId);return {id: line.productId,name: product?.name ?? line.productId,option: line.option,price: product?.price ?? "",qty: line.qty,gradient: product?.gradient ?? "",};});export function CartDrawerBlock() {return (<sectionaria-label="Cart drawer"className="mx-auto w-full max-w-3xl overflow-hidden rounded-2xl border border-border bg-surface-inset"><div className="flex justify-end p-4 sm:p-6 sm:ps-28"><div className="flex w-full max-w-sm flex-col rounded-xl border border-border bg-surface-raised shadow-lg"><div className="flex items-center justify-between border-b border-border p-4"><h2 className="font-display text-base font-semibold text-fg">Your cart</h2><div className="flex items-center gap-2"><Badge variant="secondary">4 items</Badge><Button variant="ghost" size="icon-sm"><X className="size-4" aria-hidden="true" /><span className="sr-only">Close cart</span></Button></div></div><div className="flex flex-col gap-2 border-b border-border p-4"><div className="flex items-center justify-between text-xs"><span className="text-fg-secondary">Free shipping unlocked</span><span className="font-medium text-success-strong">$75 of $75</span></div><Progress value={100} aria-label="Free shipping progress: unlocked" /></div><div className="flex flex-col gap-4 p-4">{cartLines.map((line) => (<div key={line.id} className="flex items-center gap-3"><divclassName={`flex size-14 shrink-0 items-center justify-center rounded-lg bg-gradient-to-br ${line.gradient}`}><Package className="size-5 text-fg/50" aria-hidden="true" /></div><div className="flex min-w-0 flex-1 flex-col"><span className="truncate text-sm font-medium text-fg">{line.name}</span><span className="text-xs text-fg-tertiary">{line.option} · Qty {line.qty}</span></div><span className="text-sm font-medium text-fg">{line.price}</span></div>))}</div><div className="flex flex-col gap-3 border-t border-border p-4"><div className="flex items-center justify-between text-sm"><span className="text-fg-secondary">Subtotal</span><span className="font-medium text-fg">$456.00</span></div><p className="text-xs text-fg-tertiary">Shipping and taxes are calculated at checkout.</p><Button variant="primary" className="w-full"><ShoppingBag className="size-4" aria-hidden="true" />Checkout — $456.00</Button><Button variant="ghost" className="w-full">Continue shopping</Button></div></div></div></section>);}
Shipping and taxes are calculated at checkout.