Slide-over Cart Drawer
A right-anchored cart panel over a dimmed backdrop, with line items, a subtotal and a checkout button.
3 frameworksIntermediate
An apply-code form that validates against a code map and shows the discount and new total live.
<!--
A real <form> with a real <label> (sr-only, not absent - a placeholder is not
a name). The field and Apply button stack below sm: because a 90px promo field
is a rumour. The status line is aria-live so the accept/reject message is
announced, not just shown. Wire the discount math in the React tab.
-->
<form class="mx-auto w-full max-w-md rounded-xl border border-gray-200 bg-white p-4 dark:border-gray-800 dark:bg-gray-900">
<label for="promo" class="sr-only">Promo code</label>
<div class="flex flex-col gap-2 sm:flex-row">
<input id="promo" name="promo" type="text" placeholder="Enter promo code" class="min-w-0 flex-1 rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm text-gray-900 placeholder:text-gray-400 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 dark:border-gray-700 dark:bg-gray-950 dark:text-gray-100" />
<button type="submit" class="rounded-lg bg-gray-900 px-4 py-2 text-sm font-semibold text-white hover:bg-gray-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 focus-visible:ring-offset-2 dark:bg-gray-100 dark:text-gray-900 dark:hover:bg-white dark:focus-visible:ring-offset-gray-900">Apply</button>
</div>
<p class="mt-3 text-sm text-emerald-600 dark:text-emerald-400" aria-live="polite">Code SAVE10 applied - you saved $12.00.</p>
<dl class="mt-3 space-y-1.5 border-t border-gray-100 pt-3 text-sm dark:border-gray-800">
<div class="flex justify-between"><dt class="text-gray-600 dark:text-gray-400">Subtotal</dt><dd class="tabular-nums text-gray-900 dark:text-gray-100">$120.00</dd></div>
<div class="flex justify-between"><dt class="text-gray-600 dark:text-gray-400">Discount</dt><dd class="tabular-nums text-emerald-600 dark:text-emerald-400">-$12.00</dd></div>
<div class="flex justify-between border-t border-gray-100 pt-1.5 text-base font-semibold dark:border-gray-800"><dt class="text-gray-900 dark:text-gray-100">Total</dt><dd class="tabular-nums text-gray-900 dark:text-gray-100">$108.00</dd></div>
</dl>
</form>| Prop | Type | Default | Description |
|---|---|---|---|
subtotalCentsrequired | number | - | Subtotal cents |
currency | string | '$' | Currency |
codes | Record<string, number> | - | Codes |
className | string | - | Additional classes merged onto the root element. |
A real `<form>` with an `sr-only` label - a placeholder is not a name. Pass a `codes` map of upper-case code to discount fraction; a valid entry shows the saved amount and recomputes the total, an invalid one shows an error, both through an `aria-live` status line. The field and Apply button stack below `sm:`.