bigbullui logobigbullui
Componentdata

Checkout Summary

Cart summary with quantity steppers, tax row and checkout CTA.

Preview

Live Preview
Premium Headphones
25%

Premium Headphones

$299$399

Jordan Daisy

Product Designer

AvailableRemote
The Future of Design Systems

The Future of Design Systems

Alex Rivera8 min read
Oc
t 14

Tech Conference 2026

21:00
Berlin Arena
Invoice #INV-2026-0987draft
Date: 2026-09-15Due: 2026-10-15
ItemQtyPrice
Design Services1$150
Development Hours5$100
SubtotalNaN
Tax (10%)NaN
TotalNaN
THERMAL RECEIPT#LJJDO3
Design Consultation$150
Development Hours$200
Total$385.00
Thank you for your purchase!
Premium Headphones
1
Phone Case
2
Subtotal$377.00
Tax$30.16
Total$407.16
Color
Size
Order #102938Processing
Design Services1x
Development5x
VIP

LOYALTY TIER

$100

Jordan Daisy

Happy Birthday!

J

Jordan Daisy

Product Designer

UX

Badge: EMP-8942

Wedding Reception

Please confirm your attendance

Installation

Tokens guide →

Add to your project via CLI (zero dependencies, code you own):

npx bigbullui add checkout-summary

Or install the full npm package:

npm install bigbullui

Usage

import { CheckoutSummary } from "@/components/ui/checkout-summary";

<CheckoutSummary />

Source code

checkout-summary.tsx

Zero dependencies (only React + utils). Copy and paste directly into your project:

"use client";

import * as React from "react";
import { cn } from "./lib/utils";

export interface CheckoutSummaryProps {
  items: { id: string; title: string; price: string; qty: number }[];
  subtotal?: string;
  tax?: string;
  total?: string;
  cta?: string;
  className?: string;
}

const StepSlide = "checkout-step-slide";
const FadeIn = "checkout-fade-in";

export function CheckoutSummary({
  items,
  subtotal = "$0.00",
  tax = "$0.00",
  total = "$0.00",
  cta = "Checkout",
  className,
}: CheckoutSummaryProps) {
  return (
    <div
      className={cn(
        "rounded-lg border border-foreground bg-card text-card-foreground p-6 shadow-sm motion-reduce:shadow-none",
        className
      )}
    >
      {/* Items section */}
      <div className="space-y-3 max-h-80 overflow-y-auto">
        {items.map((it, i) => (
          <div
            key={i}
            className={cn(
              "flex items-baseline justify-between py-2 border-b border-border/50 last:border-0",
              StepSlide
            )}
          >
            <span className="font-medium line-clamp-1">{it.title}</span>
            <div className="flex items-baseline gap-2">
              <button
                className={cn(
                  "rounded border border-border w-6 h-6 flex items-center justify-center text-xs font-mono",
                  "motion-reduce:transition-none"
                )}
                aria-label="decrease qty"
              >
                −
              </button>
              <span className="font-mono w-8 text-center">{it.qty}</span>
              <button
                className={cn(
                  "rounded border border-border w-6 h-6 flex items-center justify-center text-xs font-mono",
                  "motion-reduce:transition-none"
                )}
                aria-label="increase qty"
              >
                +
              </button>
            </div>
          </div>
        ))}
      </div>

      {/* Totals */}
      <div className="mt-4 flex items-baseline justify-between pt-4 border-t border-border/50">
        <span className="text-sm font-mono text-muted-foreground">Subtotal</span>
        <span className="font-mono text-right">{subtotal}</span>

        {tax && (
          <div className="ml-2 flex items-baseline gap-2">
            <span className="text-sm font-mono text-muted-foreground">Tax</span>
            <span className="font-mono text-right ml-2">{tax}</span>
          </div>
        )}

        <div className="mt-1 flex items-baseline gap-2">
          <span className="font-medium text-sm font-mono">Total</span>
          <span className="font-mono text-right text-accent font-bold">{total}</span>
        </div>
      </div>

      {/* CTA */}
      {cta && (
        <button
          className={cn(
            "mt-4 w-full rounded-md bg-accent text-accent-foreground px-4 py-2 text-sm font-semibold uppercase tracking-widest hover:bg-accent/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent transition-colors duration-150 motion-reduce:transition-none motion-reduce:focus-visible:ring-0",
            FadeIn
          )}
        >
          {cta}
        </button>
      )}
    </div>
  );
}

Props

PropTypeDescription
items{ id: string; title: string; price: string; qty: number }[]Summary line items (required).
subtotalstringSubtotal display string.
taxstringTax display string.
totalstringGrand total display string.
ctastringCheckout button label.