A price display that formats amounts with Intl.NumberFormat and handles compare-at pricing with a strikethrough and a discount badge. Use it on product cards, pricing tables, and checkout summaries.
Install
pnpm dlx shadcn@latest add https://sitex.full.dev/r/price.jsonUsage
import { Price, PriceUnit, PriceValue } from "@/components/ui/price"
export function ProductPrice() {
return (
<Price>
<PriceValue
price={19.99}
compareAt={29.99}
currency="EUR"
locale="nl-NL"
/>
<PriceUnit>per month</PriceUnit>
</Price>
)
}Key parts:
Priceis a flex wrapper that lays out its children;PriceUnitrenders a muted suffix such as a billing period.PriceValueformatspriceand optionalcompareAt. Both accept aPriceValueType: a number, a numeric string, a range string like"10 - 20", or a[min, max]tuple (ranges render as"$10.00 - $20.00"). It renders nothing whenpriceis empty.currency(default"USD") andlocale(default"en-US") drive the currency formatting.- When
compareAtis higher thanprice, the original price is shown struck through with a "Save …" badge;discountFormatswitches the badge between"percentage"(default) and"amount", andshowDiscount={false}hides it. Thevariantprop styles the main value:"default"or"sale"(muted with line-through). - The helpers
formatPriceValue,formatPriceDiscount, andparseSinglePriceValueare exported for formatting prices outside the component, along withpriceValueVariants.