Slide-over Cart Drawer
A right-anchored cart panel over a dimmed backdrop, with line items, a subtotal and a checkout button.
3 frameworksIntermediate
Cart rows with working minus/plus quantity steppers that recompute each line and the subtotal live.
<!--
Static markup for one stepper row. The minus/plus are real <button>s with
aria-labels; the live quantity is an aria-live="polite" span so a screen
reader hears the new value after each press. Wire the state in the React tab -
Tailwind alone cannot recompute the subtotal.
-->
<div class="mx-auto w-full max-w-2xl">
<div class="flex flex-col gap-3 border-b border-gray-100 py-4 sm:flex-row sm:items-center dark:border-gray-800">
<div class="h-16 w-16 flex-none rounded-lg bg-gradient-to-br from-amber-400 to-orange-500" aria-hidden="true"></div>
<div class="min-w-0 flex-1"><p class="text-sm font-medium text-gray-900 dark:text-gray-100">Canvas Tote</p><p class="text-xs text-gray-500 dark:text-gray-400">$24.00 each</p></div>
<div class="flex items-center justify-between gap-4 sm:justify-end">
<div class="inline-flex items-center rounded-lg border border-gray-200 dark:border-gray-700">
<button type="button" class="flex h-9 w-9 items-center justify-center rounded-l-lg text-gray-600 hover:bg-gray-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-blue-600 dark:text-gray-300 dark:hover:bg-gray-800" aria-label="Decrease quantity of Canvas Tote">-</button>
<span class="w-10 text-center text-sm font-medium tabular-nums text-gray-900 dark:text-gray-100" aria-live="polite">2</span>
<button type="button" class="flex h-9 w-9 items-center justify-center rounded-r-lg text-gray-600 hover:bg-gray-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-blue-600 dark:text-gray-300 dark:hover:bg-gray-800" aria-label="Increase quantity of Canvas Tote">+</button>
</div>
<span class="w-20 text-right text-sm font-semibold tabular-nums text-gray-900 dark:text-gray-100">$48.00</span>
</div>
</div>
<div class="flex items-center justify-between px-1 pt-4 text-sm">
<span class="font-medium text-gray-600 dark:text-gray-400">Subtotal</span>
<span class="text-base font-bold tabular-nums text-gray-900 dark:text-gray-100">$48.00</span>
</div>
</div>| Prop | Type | Default | Description |
|---|---|---|---|
itemsrequired | CartLine[] | - | The array of items to render. |
currency | string | '$' | Currency |
className | string | - | Additional classes merged onto the root element. |
The steppers are real `<button>`s with `aria-label`s and the quantity is an `aria-live` span, so a screen reader hears each new value; quantity is clamped to a minimum of 1. State lives in the component - the line total and the subtotal both recompute from it, so the numbers can never lie.