Bill Split Check

Checks a bill split against the printed receipt so nobody is quietly overcharged by double-counted tax, a tip on a service charge or a missed item.

StopsTip added on top of service charge

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/bill-split-check.json

The files land in your project. They're yours to edit.

Usage

bill-split-check-usage.tsx
import { BillSplitCheck, type Receipt, type SplitValue } from "@/components/ui/bill-split-check"

return <BillSplitCheck receipt={RECEIPT} people={PEOPLE} payerId="meera" currency="INR" locale="en-IN" defaultValue={START} />

What it catches

  • Items nobody claimed
  • Tax counted twice, or a tip added on top of a service charge
  • A split total that does not match the printed total (allowing for a round-off line)
  • How much an equal split costs the person who ordered least
  • Rounding drift, by largest-remainder rounding so shares add up exactly

Props

BillSplitCheck props
PropTypeDefault
receipt* (required)

The receipt as printed: items, tax lines, service charge and total.

Receipt—
people* (required)

Everyone at the table.

SplitPerson[]—
payerId* (required)

Who paid the bill; every other row says what they owe this person.

string—
currency* (required)

ISO currency code.

string—
value

Controlled claims, tip and options.

SplitValue—
defaultValue

Initial split when uncontrolled.

Partial<SplitValue>—
onValueChange

Called with the split whenever it changes.

(value: SplitValue) => void—
showServiceNote

Show the India service-charge note with the tip warning. Default true when currency is INR.

boolean—
locale

BCP 47 locale for money formatting.

string—
messages

Override any visible string.

Partial<BillSplitCheckMessages>—

* required. Also accepts the native props of <div> (className, aria-*, data-*…), passed through to it.

Accessibility

  • Per-person item toggles are buttons with aria-pressed and an aria-label naming person and item
  • Split mode is a role="radiogroup" with arrow-key navigation
  • The tip field has a <label> and aria-invalid when it duplicates a service charge
  • Status is announced in a role="status" region; motion respects prefers-reduced-motion

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

  • Works from the receipt lines you pass in; it does not read receipts
  • The tax-twice and wrong-total checks need the printed total

What it stops

Tip added on top of service charge

Also known as

split the bill · splitwise · restaurant bill · receipt · gst · service charge · tip · settle up

Field type

Dependencies

Pairs well with