Comparison block
BlockThe switch, row by row: the same task the old way and with your product, side by side.
pnpm dlx shadcn@latest add https://caliperui.site/r/comparison-block.jsonWhy switch
Month end, before and after
Matching bank lines
Spreadsheets: VLOOKUPs across three exports, rerun after every correction.
With Halden: Matched as each line lands, with the rule that matched it.
Finding a mismatch
Spreadsheets: Scroll until the totals stop disagreeing.
With Halden: Six lines, each with the likeliest invoice and who approved it.
Audit evidence
Spreadsheets: Forty files, renamed by hand in October.
With Halden: One export auditors can sample.
Time to close
Spreadsheets: Nine working days.
With Halden: A morning.
When to use #
Use it for
- Buyers already do the job another way and need a reason to change.
- Each difference is concrete enough to fit one line.
Skip it when
- Naming competitors you cannot substantiate.
- A feature checklist; use the pricing comparison.
Installation #
pnpm dlx shadcn@latest add https://caliperui.site/r/comparison-block.json
Adds its 4 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.
Usage #
This is the code behind the preview above.
import { type ReactNode } from "react" import { ComparisonBlock } from "@/components/ui/comparison-block" function Frame({ children }: { children: ReactNode }) { return <div className="w-full overflow-hidden rounded-[14px] shadow-[0_0_0_1px_var(--border)]">{children}</div>; } const comparisons: Parameters<typeof ComparisonBlock>[0] = { eyebrow: "Why switch", title: "Month end, before and after", beforeLabel: "Spreadsheets", afterLabel: "With Halden", rows: [ { topic: "Matching bank lines", before: "VLOOKUPs across three exports, rerun after every correction.", after: "Matched as each line lands, with the rule that matched it." }, { topic: "Finding a mismatch", before: "Scroll until the totals stop disagreeing.", after: "Six lines, each with the likeliest invoice and who approved it." }, { topic: "Audit evidence", before: "Forty files, renamed by hand in October.", after: "One export auditors can sample." }, { topic: "Time to close", before: "Nine working days.", after: "A morning." }, ] }; export function ComparisonBlockDemo() { return <Frame><ComparisonBlock {...comparisons} /></Frame>; }
API reference #
ComparisonBlock
component
Accessibility #
It is built on native elements and keeps aria-hidden in step with state.
No custom key handling; Tab and the native activation keys do the work.
Motion #
It declares no animation in its component source. Any transition comes from its stylesheet, which uses the duration tokens that collapse to instant under prefers-reduced-motion.