Skip to content
weftGitHub

CurrencySelect

Pick a currency by name, code or symbol.

SourcePackage @weft-js/warp

Preview

tsx
import { CurrencySelect } from '@weft-js/warp'export function Basic() {  return (    <CurrencySelect label="Currency" preferred={NEAR_CURRENCIES} defaultValue="EUR" />  )}const NEAR_CURRENCIES = ['EUR', 'USD', 'GBP']

Installation

npm install @weft-js/warp

Usage

tsx
import { CurrencySelect } from '@weft-js/warp'<CurrencySelect label="Currency" preferred={NEAR_CURRENCIES} defaultValue="EUR" />

Only some currencies

options limits the list to the codes you can bill in.

tsx
import { CurrencySelect } from '@weft-js/warp'export function Limited() {  return (    <CurrencySelect label="Billing currency" options={['EUR', 'USD', 'GBP', 'SEK']} defaultValue="SEK" hint="Stripe pays out in these four." />  )}

Names in another language

locale names the currencies in Japanese here. The value is still the code.

tsx
import { CurrencySelect } from '@weft-js/warp'export function Locale() {  return (    <CurrencySelect label="通貨" locale="ja" preferred={['JPY', 'USD', 'EUR']} defaultValue="JPY" />  )}

States

Read-only also needs open={false}, which keeps the list shut.

tsx
import { CurrencySelect, Grid, Stack, Text } from '@weft-js/warp'export function States() {  return (    <Grid cols={3} gap="group">      <Cell name="Empty"><CurrencySelect label="Currency" /></Cell>      <Cell name="Filled"><CurrencySelect label="Currency" defaultValue="EUR" /></Cell>      <Cell name="Hint"><CurrencySelect label="Currency" hint="Applies from the next invoice." /></Cell>      <Cell name="Invalid"><CurrencySelect label="Currency" error="Choose a billing currency." /></Cell>      <Cell name="Disabled"><CurrencySelect label="Currency" defaultValue="EUR" disabled /></Cell>      <Cell name="Read-only"><CurrencySelect label="Currency" defaultValue="EUR" readonly /></Cell>    </Grid>  )}const Cell = (p: { name: string; children?: unknown }) => (  <Stack gap="tight">    <Text role="caption" subtle>{p.name}</Text>    {p.children}  </Stack>)

Price in the chosen currency

The value is an ISO code, so Intl.NumberFormat can format the price with it.

tsx
import { state } from '@weft-js/core'import { CurrencySelect, Row, Stack, Text } from '@weft-js/warp'export function Price() {  const cur = state<string | null>('EUR')  const price = () => new Intl.NumberFormat('en', { style: 'currency', currency: cur.value ?? 'EUR', maximumFractionDigits: 0 }).format(PLAN_PRICE[cur.value ?? 'EUR']!)  return (    <Stack gap="group">      <CurrencySelect label="Pay in" options={PRICED} value={cur} />      <Row justify="between">        <Text>Team plan, per seat</Text>        <Row gap="tight" align="baseline"><Text role="heading">{price()}</Text><Text subtle>a month</Text></Row>      </Row>    </Stack>  )}const PLAN_PRICE: Record<string, number> = { EUR: 20, USD: 22, GBP: 17, SEK: 229, JPY: 3300 }const PRICED = Object.keys(PLAN_PRICE)

Accessibility

EnterSpace
Opens the list
↑↓
Moves through the results
Enter
Picks the highlighted row
Esc
Closes and returns focus

API Reference

PropTypeDefaultDescription
labelstring—The visible name, and what screen readers announce.
hintunknown—A short line of help under the field.
errorunknown—Replaces the hint and marks the field invalid.
iconIconRef—Leading icon: it sweeps with the border.
prefixunknown—Text or an element inside the field before the value, such as $.
suffixunknown—Text or an element inside the field after the value, such as kg.
variant"floating" | "classic"—floating (default, or the app's warp({ fields })) · classic: the label above.
appearance"line"—line: only a bottom line under the value, no box or fill. The boxed field otherwise.
size"sm" | "md" | "lg"'md'Control size. md by default.
clearablebooleanfalseA clear button (shown once there is a value).
counternumber—Maximum length, shown as a counter.
idstring—The element id. One is made for you if you leave it out.
disabledbooleanfalseCan't be focused or changed.
readonlybooleanfalseShows the value and lets it be selected and copied, but not changed.
requiredbooleanfalseThe form will not submit without it.
namestring—Posts the value with a form.
localestring—The language names are shown in. Follows the page otherwise.
todaystring—Pins "today" (server render, tests); the browser's clock otherwise.
presentationPresentation—auto opens a popover, or a sheet when the viewport is under 600px wide; popover and sheet force one.
valuestring | State<string | null> | null—The code, or a State to bind.
defaultValuestring | null—The first value, when you don't hold it yourself.
openboolean | State<boolean>—A state box that holds whether it is open.
defaultOpenbooleanfalseStarts open, when the component keeps its own open state.
optionsstring[]—Limits the list to these codes.
preferredstring[]—Codes pinned to the top of the list.
EventTypeDefaultDescription
onInput((e: InputEvent & { currentTarget: HTMLInputElement & HTMLTextAreaElemen…—Called on each keystroke.
onValueChange((v: string | null, reason: ChangeReason) => void)—Hears the new value and why it changed.
onOpenChange((o: boolean) => void)—Called with true when it opens and false when it closes.

RelatedCountry selectNumber field