Currency Hint

Shows an approximate, dated conversion of a foreign price and prices a merchant's currency conversion, so budgets abroad use the right number.

StopsBudgeted on the wrong currency abroad

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/currency-hint.json

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

Usage

currency-hint-usage.tsx
import { CurrencyHint, type ExchangeRates } from "@/components/ui/currency-hint"

<CurrencyHint
  amount={49}
  currency="EUR"
  viewerCurrency="INR"
  rates={rates}
  source="ECB"
  locale="en-IN"
  defaultValue="INR"
  dccAmount={4790}
  cardFeePercent={3.5}
  feeTaxPercent={18}
/>

What it catches

  • Foreign prices read as home-currency prices
  • Dynamic currency conversion that costs more than the reference rate
  • Card foreign-transaction fees and tax on them, when you pass the percentages
  • Exchange rates older than staleAfterDays

Props

CurrencyHint props
PropTypeDefault
amount* (required)

Price in the merchant's currency.

number—
currency* (required)

Merchant's currency, ISO 4217 ("EUR").

string—
viewerCurrency* (required)

The viewer's home or card currency ("INR").

string—
rates* (required)

Reference rates (mid-market), passed in by you.

ExchangeRates—
value

Controlled currency the card will be charged in.

string—
defaultValue

Initial charge currency when uncontrolled. Defaults to `currency`.

string—
onValueChange

Called when the viewer picks the other charge currency.

(currency: string) => void—
dccAmount

The merchant's own quote in `viewerCurrency` (dynamic currency conversion). Adds a "Pay in" choice.

number—
cardFeePercent

The card's foreign transaction fee in percent, e.g. 3.5.

number—
feeTaxPercent

Tax charged on that fee in percent, e.g. 18 (GST in India).

number0
staleAfterDays

Warn when the rates are older than this many days.

number4
locale

Locale for numbers and dates, e.g. "en-IN" for ₹4,52,000 grouping.

string—
source

Name of the rate source, e.g. "ECB".

string—
approxText

Templates. `{rate}`, `{date}`, `{source}`, `{extra}`, `{percent}`, `{fee}`, `{days}` and `{currency}` are filled in.

string"Approximate, at {rate}{source} on {date}. Your bank sets…
staleText

Warning when the rate is older than staleAfterDays.

string"This rate is {days} days old."
dccText

Message comparing the merchant's conversion with the reference rate.

string"Paying in {currency} costs about {extra} ({percent}) mor…
dccUnknownText

Message when the merchant's converted amount is unknown.

string"Paying in {currency} uses the merchant's own rate, usual…
feeText

Message estimating card fees.

string"Your card may add about {fee} in foreign transaction fees."
payInLabel

Label for the pay-in currency choice.

string"Pay in"
localHint

Small text under the local-currency option.

string"local currency"
merchantHint

Small text under the converted option.

string"merchant's rate"
fixLabel

Text for switching back to local currency.

string"Pay in {currency}"

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

Accessibility

  • Payment currency options use labels
  • Conversion and warnings are aria-live="polite"
  • Animation respects prefers-reduced-motion

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

Limitations

  • Rates come from your `rates` prop; the result is an estimate, not what the bank will charge
  • Card fee and fee tax default to 0% unless you pass them

What it stops

Budgeted on the wrong currency abroad

Also known as

currency converter · forex · dcc · exchange rate · inr · usd · international payment · card fees

Field type

Dependencies

Pairs well with