Order Summary
The checkout sidebar with line items, discount codes and totals. Handles estimated taxes, unknown shipping and prices that changed since the cart was built.
OrderSummary is the column next to a checkout form. It takes a Cart in the same shape the cart block uses and shows each line with a small thumbnail, a quantity badge on the image corner, the variant and the line total. Lists longer than five lines fold behind “Show 3 more”, so the totals stay in view.
Totals come in the order shoppers expect: subtotal, one line per discount with its code as a chip, shipping, taxes and the total with its currency code, “USD $339.78”. Shipping reads “Calculated at next step” until you know it, shows a skeleton while it is being worked out and reads Free when it costs nothing. Taxes are labelled Estimated until you mark them final, with an optional basis such as “Estimated for 94110”. Store sales, discounts and free shipping add up to a “You saved” line.
Discount codes sit behind an “Add discount code” link. Codes are trimmed and uppercased, the Apply button turns into a spinner and then a check, and applied codes become chips you can remove. Automatic discounts show as chips without a remove button. Throw from onApplyCode and your message appears under the field. DiscountCodeError builds the common ones: expired with the date, the amount still needed to reach a minimum, codes that can’t be combined, and codes that don’t exist. The block catches codes that are already applied and the code limit without calling you.
Every amount uses Price, so when a code lands only the digits that changed roll, and nothing counts up on first render. New discount and savings lines grow in before their text fades in. If a line’s price changed since the last render, the row flashes once and keeps a note such as “Price dropped to $58”. With collapsible set, phones get a “Show order summary” bar that keeps the total visible and flashes it when it changes.
Obtenha o HextaUI Pro
Um único pagamento libera todos os blocos, incluindo os futuros. Ver preços.
Adicione o registro Pro ao components.json
components.json Adicione seu token
Crie um token na sua página de conta e coloque-o em
.env.localcomoHEXTAUI_PRO_TOKEN.Adicione o bloco
pnpm dlx shadcn@latest add @hextaui-pro/order-summary
Shopify discount codes
Send the full list of codes through cartDiscountCodesUpdate, refetch the cart and map it to Cart. Shopify accepts codes it can’t apply and marks them applicable: false, so the example removes those again and shows a specific error instead of a silent no-op.
Stripe promotion codes
Look up the promotion code on your server and turn Stripe’s restrictions into DiscountCodeError messages: the expiry date, or how much more the shopper needs to spend to reach the minimum amount.
With a server action
Next.js hides thrown error messages from server actions in production, so the action returns { ok: false, message } and the client throws it. The message then shows under the field, and a returned cart updates the totals right away.
Anatomia
As partes que você compõe, de fora para dentro.
| Parte | Descrição |
|---|---|
OrderSummary | Lines, discount code field, totals and the mobile summary bar. |
PromoCode | The discount code link, field, error message and code chips. Works on its own in a cart drawer. |
OrderSummarySkeleton | A loading placeholder with the same layout. |
DiscountCodeError | An Error with a reason and helpers for specific messages: expired, minimum, combination, notFound, alreadyApplied, limit. |
getSummaryTotals | The math behind the totals: discounts, shipping, tax, total and savings in minor units. |
OrderSummary
Also takes section props.
| Prop | Tipo | Padrão |
|---|---|---|
cartLines, discounts and currency. Discounts with target "shipping" are listed under shipping. | Cart | – |
shippingShipping cost. Defaults to cart.shipping, or "pending" when that is empty. | Money | "pending" | "calculating" | "free" | – |
shippingMethodShown under Shipping once the cost is known, such as “Standard · 3–5 business days”. | string | – |
taxTaxes. estimated defaults to true. included shows “Including $X in taxes” under the total instead of adding it. | { amount: Money | null; estimated?: boolean; included?: boolean; calculating?: boolean; basis?: string } | – |
onApplyCodeApply an uppercased, trimmed code. Throw to show the message under the field. Return a cart to show it before your own state updates. | (code: string) => Promise<Cart | void> | – |
onRemoveCodeRemove a code. The chip leaves right away and comes back if this throws. | (code: string) => Promise<Cart | void> | – |
maxCodesHow many codes one order can use. | number | 5 |
maxLinesLines shown before the rest fold behind “Show N more”. 0 shows every line. | number | 4 |
collapsibleBelow the md breakpoint, collapse the summary behind a bar that shows the total. | boolean | false |
openWhether the mobile summary is expanded, when controlled. | boolean | – |
defaultOpenWhether the mobile summary starts expanded. | boolean | false |
onOpenChangeCalled when the mobile bar is toggled. | (open: boolean) => void | – |
localeLocale for money. | Intl.LocalesArgument | "en-US" |
trailingZerosSet false to show $48 instead of $48.00. | boolean | true |
labelsEvery visible and announced string, plus promo for the PromoCode labels. | Partial<OrderSummaryLabels> | – |
PromoCode
Also takes div props.
| Prop | Tipo | Padrão |
|---|---|---|
discountsApplied codes and automatic discounts, shown as chips. | CartDiscount[] | – |
onApplyApply a code. Throw an Error to show its message. A DiscountCodeError with reason "minimum" reads as a hint instead of an error. | (code: string) => unknown | – |
onRemoveRemove a code. Without it, chips have no remove button. | (code: string) => unknown | – |
maxCodesHow many codes one order can use. | number | 5 |
defaultOpenStart with the field shown instead of the link. | boolean | false |
disabledDisable the link and the field. | boolean | false |
labelsWords for the link, field, button, chips and announcements. | Partial<PromoCodeLabels> | – |
OrderSummarySkeleton
Also takes div props.
| Prop | Tipo | Padrão |
|---|---|---|
linesHow many line placeholders to show. | number | 3 |
collapsibleMatch a collapsible summary: only the bar shows on phones. | boolean | false |
| Tecla | Ação |
|---|---|
| Enter | In the code field, apply the code. |
| Escape | In an empty code field, close it and return focus to the link. |
| Backspace | On a chip’s remove button, remove the code. Focus moves to the next chip. |
| SpaceEnter | On the summary bar or Show more, expand or collapse. |
- Totals are a description list, so each amount is read with its label. Discounts read “Discount WELCOME10, minus $36.80”, and each line reads its quantity.
- Code errors are in a role="alert" region linked to the field with aria-describedby and aria-invalid. The text stays in the field and focus returns to it. Applied and removed codes, price changes and the new total are announced politely, the total after it settles.
- The mobile bar is a button with aria-expanded and aria-controls whose name includes the total. Collapsed content is hidden from screen readers and the tab order.
- Changes are never shown by color alone: price notes have text and an arrow, and flashes are decorative. With reduced motion, digits change without rolling and rows appear without growing.
Construído com
Os componentes gratuitos do HextaUI de que Order Summary é feito. Cada um é instalado separadamente.
Código
7 arquivos, adicionados a components/blocks/order-summary.