Skip to main content
Urbicon UI
source

CurrencyInput

A monetary input that stores its value in minor units (cents) and formats it for the active locale.

Playground

Locale
Currency
Symbol Position
<CurrencyInput
  label="Price"
  locale="de-DE"
/>

01 Examples

Follows the active locale

With no locale prop, grouping and decimal separators follow the active <I18nProvider> locale, applied on every keystroke. The bound value stays an integer count of cents; the currency symbol is a fixed adornment.
<script>
  import { CurrencyInput } from '@urbicon-ui/blocks';
  let priceCents = $state(1234_56); // grouped per the active locale
</script>
<CurrencyInput label="Price" bind:value={priceCents} />

USD with prefix symbol

<CurrencyInput
  label="Amount"
  bind:value={amountCents}
  locale="en-US"
  currency="USD"
  symbolPosition="prefix"
/>

JPY: zero decimal precision

Currencies like JPY have no minor units. Set precision={0} so the integer value is treated as-is.
<CurrencyInput
  bind:value={yen}
  locale="ja-JP"
  currency="JPY"
  precision={0}
/>

02 Working with major units

CurrencyInput stores values in minor units (cents) so summing, sorting, and persisting amounts stay free of floating-point drift. When integrating with an API or datastore that uses major-unit floats (e.g. 1234.56 for €1.234,56), use the exported centsToMajor / majorToCents helpers at the boundary, and keep the in-memory value in cents.

Cents in, major units out

majorToCents on ingest, centsToMajor on export. The bound value stays in cents.

Stored as cents: 123456 · Exported as major: 1234.56

<script>
  import { CurrencyInput, centsToMajor, majorToCents } from '@urbicon-ui/blocks';

  // Major-unit float arrives from an external API.
  const apiAmount = 1234.56;
  let cents = $state(majorToCents(apiAmount)); // 123456
  const exportedAsMajor = $derived(centsToMajor(cents)); // 1234.56
</script>

<CurrencyInput label="Price" bind:value={cents} />
<p>Major: {exportedAsMajor}</p>

Float-precision caveat: a major-unit value that has already lost precision before reaching majorToCents (e.g. 0.1 + 0.2) cannot be recovered. For values that must round-trip exactly across system boundaries, transport them as minor-unit integers (or as strings) instead of major-unit floats.

03 Customization

CurrencyInput builds on <Input>, so its InputProps (label, helper, error, slotClasses, …) apply here too. The cents-based value, locale, currency, symbolPosition, and precision props add the locale-aware behaviour.

Use symbolPosition="none" for headless numeric editing where you want the locale formatting (grouping / decimal separator) without the currency symbol.

04 Accessibility

Inherited from Input

Inherits aria-invalid / aria-describedby wiring from the underlying <Input> via the label, error, and helper props.

Numeric keyboard

Sets inputmode="decimal" so mobile keyboards open the numeric pad with a decimal separator.

The caret stays where the user put it

The field re-formats on every keystroke, so grouping separators appear and disappear under the caret. It is carried across as a digit position rather than a character offset, and the fraction is a fixed row of slots: deleting a cent digit zeroes it instead of pulling the separator along.

05 API Reference

34 props
32 props
Prop
Type
Default
Description

06 Types

Local type definitions used by this component.

10 types
Name
Kind
Category
Used by
Description

07 Installation

Import

import { CurrencyInput } from '@urbicon-ui/blocks';