- Accordion
- Action Bar
- Action Toast
- Alert Banner
- Alert Dialog
- Alert
- Alphabet Index
- Amount Field
- Aspect Ratio
- Attachment
- Availability List
- Avatar
- Badge
- Bank Card
- Breadcrumb
- Bubble
- Button Group
- Button
- Calendar
- Camera Frame
- Card Design Picker
- Card Details
- Card Peek
- Card Stack
- Card
- Carousel
- Chart
- Chat Thread
- Checkbox
- Chip Group
- Choice Tile
- Code Block
- Code Dots
- Collapsible
- Combobox
- Command
- Context Menu
- Copy Field
- Countdown
- Country Select
- Data Table
- Date Field
- Date Picker
- Date Range Picker
- Dialog
- Direction
- Document Paper
- Drawer
- Dropdown Menu
- Empty
- Entity Avatar
- Field
- File Trigger
- File Upload Item
- Hover Card
- Input Group
- Input OTP
- Input
- Item
- Kbd
- Key Value
- Keypad
- Label
- Live Region
- Marker
- Message Scroller
- Message
- Money Amount
- Native Select
- Number Field
- Pagination
- Percent Split Editor
- Phone Field
- Popover
- Progress
- QR Code
- Questionnaire
- Radio Group
- Range Histogram
- Rating
- Resizable
- Scroll Area
- Search Field
- Select
- Separator
- Share Bar
- Sheet
- Sidebar
- Skeleton
- Slider
- Sonner
- Sortable List
- Spinner
- Status Timeline
- Step Header
- Steps List
- Swipe Row
- Switch
- Table
- Tabs
- Text Field
- Textarea
- Tier Ladder
- Toggle Group
- Toggle
- Token Search Field
- Tooltip
- Trace
- Transaction Row
- Usage Meter
import { MoneyAmount } from "@/components/ui/money-amount"
export function MoneyAmountDemo() {MoneyAmount is the one way to show money across the kit: balances, transaction amounts, fees and rates. It formats the value with Intl.NumberFormat, sets the whole part at full size and the cents smaller, uses tabular digits and a true minus sign, and gives screen readers the full amount as one phrase. It only displays a value. To let people type an amount, use AmountField. Use NumberField for stepped limits.
Installation#
pnpm dlx shadcn@latest add @dots/money-amount
Usage#
import { MoneyAmount } from "@/components/ui/money-amount"<MoneyAmount value={1250.5} />Features#
- Locale-aware formatting through
Intl.NumberFormat, in USD by default - Smaller fraction, tabular digits and a real minus sign (−)
- Six sizes, including
inlinefor amounts inside a sentence - Plus sign for incoming money with
signDisplay="always" - Masked state that hides the digits and reads "Amount hidden"
- Struck amounts as a semantic
<del>, read with a "was" prefix - Asset codes Intl has no currency for, such as USDT or BTC, through
unit - Fraction control for whole amounts and unit prices
Sizes#
Use size to pick sm, default, lg, xl or 2xl. Use inline to keep the size of the surrounding text, for example in a sentence or a badge.
You sent $1,250.50$1,250.50 to Sam Carter.
import { MoneyAmount } from "@/components/ui/money-amount"
const sizes = ["sm", "default", "lg", "xl", "2xl"] as constSign#
Negative values show a minus by default. Set signDisplay="always" to add a plus to incoming money, and "never" for totals where the direction is already in the label, such as "Spent this month".
import { MoneyAmount } from "@/components/ui/money-amount"
export function MoneyAmountSign() {Masked#
Set masked when the user hides their balance. The currency symbol stays, the digits become dots, and screen readers hear "Amount hidden" instead of the dots.
"use client"
import * as React from "react"Struck and muted#
Set struck for an amount that no longer applies, such as an old fee next to the new one. It renders a <del> and reads struckLabel ("was") before the amount. Set tone="muted" for amounts that were not taken, such as a declined payment.
import { MoneyAmount } from "@/components/ui/money-amount"
export function MoneyAmountStruck() {Units and precision#
Pass unit for assets without an ISO currency code. The value is formatted as a decimal with up to 8 fraction digits and the code follows it. Use maximumFractionDigits for unit prices such as $1.0016, and showFraction={false} for whole amounts.
import { MoneyAmount } from "@/components/ui/money-amount"
export function MoneyAmountUnits() {<MoneyAmount value={245.8} unit="USDT" />
<MoneyAmount value={1.0016} maximumFractionDigits={4} />
<MoneyAmount value={980} currency="EUR" showFraction={false} />Accessibility#
The visible digits are split into parts for styling and are hidden with aria-hidden. A visually hidden copy carries the full formatted amount, so screen readers read "$1,250.50" as one phrase, not as separate pieces.
- A masked amount reads "Amount hidden", never the dots.
- A struck amount reads its
struckLabelfirst, for example "was $2.99", because screen readers rarely announce<del>. ChangestruckLabelwhen the context needs another word. - Color is never the only signal. The sign carries the direction, so keep
signDisplay="always"for incoming money rather than relying on a tint. - Give the amount context in nearby text, such as the merchant or "Balance".
API Reference#
MoneyAmount#
Renders a <span> and accepts all of its props except children.
| Prop | Type | Default | Description |
|---|---|---|---|
value | number | - | The amount in major units, e.g. 1250.5 for $1,250.50. |
currency | string | "USD" | ISO 4217 code. Cannot be combined with unit. |
unit | string | - | A non-ISO asset code, e.g. "USDT". Formats a decimal followed by the code. Empty falls back to currency. |
locale | string | "en-US" | The locale used for formatting. |
size | "inline" | "sm" | "default" | "lg" | "xl" | "2xl" | "default" | The type size. inline keeps the surrounding size. |
signDisplay | "auto" | "always" | "never" | "auto" | always adds a plus to positive values. Zero never gets a sign. |
showFraction | boolean | true | Show the fraction. Ignored when either fraction digits prop is set. |
minimumFractionDigits | number | - | Fewest fraction digits. Defaults to the currency's digits, or 0 in unit mode. |
maximumFractionDigits | number | - | Most fraction digits. Defaults to the currency's digits, or 8 in unit mode. |
masked | boolean | false | Replace the digits with dots and read "Amount hidden". |
struck | boolean | false | Render a <del> with the digits struck through. |
struckLabel | string | "was" | Read before a struck amount. |
tone | "default" | "muted" | "default" | muted for amounts that were not taken or are stale. |
className | string | - | Additional classes to apply to the root element. |