Componentdata
Receipt
Thermal receipt with zigzag tear edge, mono lines and barcode footer.
Preview
Live Preview

25%
Premium Headphones
$299$399
Jordan Daisy
Product Designer
AvailableRemote

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
| Item | Qty | Price |
|---|---|---|
| Design Services | 1 | $150 |
| Development Hours | 5 | $100 |
SubtotalNaN
Tax (10%)NaN
TotalNaN
THERMAL RECEIPT#1ORJKS
Design Consultation$150
Development Hours$200
Total$385.00
Thank you for your purchase!
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 receiptOr install the full npm package:
npm install bigbulluiUsage
import { Receipt } from "@/components/ui/receipt";
<Receipt />Source code
receipt.tsxZero 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 ReceiptProps {
items: { label: string; price: string }[];
taxRate?: number;
total: string;
className?: string;
}
const FadeIn = "receipt-fade-in";
const ZigZag = "receipt-zig-zag";
export function Receipt({
items,
taxRate = 0.1,
total,
className,
}: ReceiptProps) {
const subtotal = items.reduce((sum, it) => sum + parseFloat(it.price), 0);
const tax = subtotal * taxRate;
return (
<div
className={cn(
"w-full rounded-lg border border-foreground bg-secondary text-secondary-foreground shadow-sm",
FadeIn,
className
)}
>
{/* Receipt header */}
<div className="border-b border-border/80 pb-4 mb-4">
<div className="flex items-center justify-between">
<span className="font-mono text-xs uppercase tracking-widest text-muted-thermal">THERMAL RECEIPT</span>
<span className="font-mono text-xs uppercase tracking-wider">#{Math.random().toString(36).slice(2, 8).toUpperCase()}</span>
</div>
</div>
{/* Items list with zig-zag bottom */}
<div className="space-y-2 max-h-96 overflow-y-auto">
{items.map((it, i) => (
<div
key={i}
className={cn(
"flex items-baseline py-1.5",
ZigZag
)}
>
<span className="font-mono text-xs flex-1 line-clamp-1">{it.label}</span>
<span className="font-mono text-right text-xs opacity-80">{it.price}</span>
</div>
))}
</div>
{/* Totals row with dashed separator */}
<div
className={cn(
"flex items-baseline justify-between pt-2 border-t border-dashed border-border/50",
ZigZag
)}
>
<span className="text-xs font-mono text-muted-foreground">Total</span>
<span className="font-mono text-right font-bold">{total}</span>
</div>
{/* Footer */}
<div className="mt-3 text-xs uppercase tracking-wider text-muted-foreground">
Thank you for your purchase!
</div>
</div>
);
}Props
| Prop | Type | Description |
|---|---|---|
| items | { label: string; price: string }[] | Receipt lines (required). |
| total | string | Total string (required). |
| taxRate | number | Tax rate decimal. |