Amount in Words

Spells an amount in words and names each digit group, so ₹2,50,000 isn't written or read as ₹25,00,000.

StopsExtra zero on a transfer

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/amount-in-words.json

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

Usage

amount-in-words-usage.tsx
import { AmountInWords } from "@/components/ui/amount-in-words"

return <AmountInWords amount={250000} currency="INR" value={words} onValueChange={setWords} />

What it catches

  • An extra or missing zero, by naming each digit group
  • Typed words that do not match the figure, with a one-tap correction
  • Confusion between lakh/crore and million/billion, via the other system shown alongside
  • Mismatches that are a power of ten apart ("10× more")

Props

AmountInWords props
PropTypeDefault
amount* (required)

The amount in figures, in major units (250000.5 is ₹2,50,000.50).

number—
currency

ISO currency code. INR, USD, EUR, GBP, AED and SGD have cheque wording built in.

string"INR"
system

Number system for grouping and words. Defaults to `indian` for INR, `international` otherwise.

NumberSystemcurrency === "INR" ? "indian" : "international"
showOtherSystem

Shows the amount in the other system too (2.5 lakh = 250 thousand) for readers used to it.

booleantrue
verify

Shows a field that checks words someone typed or wrote against the figure.

booleantrue
value

Controlled words typed into the check field.

string—
defaultValue

Initial words when uncontrolled.

string""
onValueChange

Called with the words as they are typed or fixed.

(value: string) => void—
verifyLabel

Label of the check field.

string"Amount in words, as written"
mismatchMessage

Shown when the words describe a different amount. Receives the amount the words describe.

(wordsAmount: string, gap: string) => string(words, gap) => `These words say ${words}, ${gap} than th…
mismatchNote

Why a mismatch matters. Indian law (NI Act §18) pays the amount in words.

string"If they differ, the amount in words is the one paid."
matchMessage

Shown when the words match the figure.

string"Words match the figure."
onlyMessage

Shown when the words don't end in "Only".

string"End with “Only” so nothing can be added after it."

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

Accessibility

  • The grouped figure has an aria-label with the full amount; the visual group labels are aria-hidden
  • Words input has a <label>, aria-invalid on mismatch and aria-describedby to its status
  • Match status is aria-live="polite"; a mismatch uses role="alert"
  • Copy button has an aria-label that changes to "Copied"

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

Limitations

  • Words are English only, with cheque wording built in for INR, USD, EUR, GBP, AED and SGD
  • Takes the amount as a JavaScript number in major units, so very large values lose precision
  • Word matching is a text comparison; unusual spellings may be reported as a mismatch

What it stops

Extra zero on a transfer

Also known as

amount in words · cheque · lakh · crore · rupees · number to words · neft · invoice

Field type

Dependencies

Pairs well with