Price
bun add flootletsnpx shadcn@latest add https://dyeoh.github.io/flootlets/r/price.jsonBoth need Tailwind CSS v4; see Installation for the setup.
Price takes money as { amount, currency } with amount in the currency’s smallest unit (as
most payment APIs send it), and formats it with the browser’s built-in Intl.NumberFormat. Each
currency gets its own number of decimals: 2 for MYR, none for JPY, 3 for BHD.
export default function PriceExamples() { return ( <> <Price amount={{ amount: 2920, currency: 'MYR' }} locale="en-MY" /> <Price amount={{ amount: 2500, currency: 'MYR' }} compareAt={{ amount: 3500, currency: 'MYR' }} locale="en-MY" size="lg" /> <Price amount={{ amount: 500, currency: 'JPY' }} locale="ja-JP" /> <Price amount={{ amount: 1250, currency: 'BHD' }} locale="en" /> <Price amount={{ amount: 123456, currency: 'EUR' }} locale="de-DE" size="sm" /> </> );}Pass compareAt with the original price. It’s shown struck through, and only when it’s really
higher and in the same currency. Screen readers hear “Sale price RM 25.00, Original price
RM 35.00” rather than two unexplained numbers.
Locale
Section titled “Locale”Always pass locale, and the same one on the server and in the browser. If it came from the
environment, a server in one locale and a visitor in another would render different text and
break hydration. The default is "en".
| Prop | Type | Default | |
|---|---|---|---|
amount |
{ amount: number; currency: string } |
required | Minor units |
compareAt |
Money | null |
Original price, struck through | |
locale |
string |
'en' |
e.g. 'en-MY', 'ms-MY', 'ja-JP' |
size |
'sm' | 'default' | 'lg' |
'default' |
|
labels |
{ current?: string; original?: string } |
Sale price / Original price |
Screen-reader labels, for translation |
Need the text without the component? formatMoney(money, locale) returns the same string.
Styling
Section titled “Styling”Parts: data-slot="price", price-current, price-was. A sale sets data-sale, which turns
the current price text-destructive.
flootlets 0.2.3 · Changelog