---
## CurrencyInput
Locale-aware monetary input that stores values in **minor units**
(cents for EUR/USD, pennies for GBP, etc.). The field is a fixed-scale mask
rather than free text: it re-formats on every keystroke, the fraction is a
fixed row of slots (deleting a cent digit zeroes it instead of pulling the
separator along), and the caret is carried as a digit position so the grouping
separators appearing and disappearing under it never move it. The currency
symbol is rendered as a static adornment (left or right of the field) and
stays visible at all times.
Storing cents as integers avoids floating-point drift when summing, sorting,
or persisting amounts. Parsing also goes through string splits — never
`parseFloat * factor` — so `1,005` lands on the `100` minor units it reads as,
rather than the `99` IEEE-754 drift produces. A digit past the last place is
truncated, never rounded: `1,999` is `199`. Use
`CurrencyInputProps.precision` for currencies with non-2 decimal
places (JPY = 0, BHD = 3).
**Import:** `import { CurrencyInput } from '@urbicon-ui/blocks';`
### Examples
```svelte
```
```svelte
```
```svelte
```
### Api
| Prop | Type | Required | Default | Description |
| --- | --- | :---: | --- | --- |
| autoComplete | `string` | no | | HTML autocomplete hint for browser autofill. |
| children | `Snippet` | no | | Snippet content rendered below the input for advanced layouts. |
| class | `string` | no | | Extra classes merged onto the root wrapper element. In the same Tailwind bucket `class` wins over the `slotClasses` entry for the element it lands on. Presets and provider defaults sit below both. |
| clearable | `boolean` | no | false | Show a clear button when the input has a value. Press Escape or click the button to clear. Fires `onClear` after clearing. |
| currency | `string` | no | 'EUR' | ISO-4217 currency code. Determines the symbol when `CurrencyInputProps.symbolPosition` is `'prefix'` or `'suffix'`. |
| disabled | `boolean` | no | false | disabled property |
| error | `string` | no | | Error message below the input. When set, overrides `helper` and forces danger border styling regardless of `intent`. |
| helper | `string` | no | | Helper text below the input — hidden when `error` is present. |
| label | `string` | no | | Label text displayed above the input, auto-linked via `for`/`id`. |
| leftIcon | `Snippet` | no | | Icon snippet rendered on the left side of the input field. |
| leftIconAriaLabel | `string` | no | | Accessible label for the clickable left icon button. Required when `onLeftIconClick` is set so screen-reader users hear a name for the button (icons inside are `aria-hidden`). |
| locale | `string` | no | 'auto' | BCP 47 locale used for formatting (`Intl.NumberFormat`). Controls the grouping separator (`.` vs `,`) and decimal separator. Defaults to `'auto'`, which follows the active `` locale — SSR-safe (server and client resolve the same locale, no hydration flash) and consistent with the rest of the library's number formatting. Falls back to the base locale (`en`) when no provider is mounted. Pass an explicit BCP 47 string (e.g. `'de-DE'`, `'ja-JP'`) to override. `currency` is intentionally **not** auto-detected, since it is orthogonal to locale (a `de-CH` user may still bill in EUR). |
| mint | `InputProps['mint']` | no | 'none' | Micro-interaction preset forwarded to the inner Input. Redeclared from InputProps so the inheritance is a documented contract rather than an accident of the Omit list. |
| mint | `MintProp` | no | 'none' | Micro-interaction preset applied to the input element. Only applies while not disabled. |
| name | `string` | no | | Shared `name` for native form submission. When set, a hidden input is rendered carrying the integer minor-unit value (matching `CurrencyInputProps.value`) — never the locale-formatted display string. The visible Input itself stays unnamed so the formatted text is not submitted alongside. Empty / `null` values submit as `""` so the field still appears in the FormData payload (consumers can disambiguate "untouched" via server-side schema parsing). |
| onLeftIconClick | `() => void` | no | | When provided, the left icon becomes a clickable button. |
| onRightIconClick | `() => void` | no | | When provided, the right icon becomes a clickable button. |
| onValueChange | `(cents: number | null) => void` | no | | Fires whenever the parsed value changes. Receives the new value in minor units (or `null`). |
| persistDebounceMs | `number` | no | 300 | Debounce interval (ms) for storage writes. |
| persistKey | `string` | no | | Key for persisting the input value to storage. |
| persistNamespace | `string` | no | | Namespace (e.g. user id) to scope the persist key. |
| persistStorage | `'localStorage' | 'sessionStorage'` | no | 'localStorage' | Storage backend for persistence. |
| persistVersion | `number` | no | 1 | Version stamp included in the storage key. |
| precision | `number` | no | 2 | Number of fractional digits stored in `CurrencyInputProps.value`. For most currencies `2`; for JPY use `0`, for BHD/KWD use `3`. |
| preset | `string` | no | | Apply a named preset registered via ``. Resolved against the **`CurrencyInput`** key, not `Input`: a preset written for the money field would otherwise style every text field under the provider. `defaults.Input` still applies — the resolved preset reaches Input as instance `slotClasses`, so it wins over the provider's input-wide defaults and loses to `slotClasses` / `class` written on this component. A preset's `overrides` rules are matched against what you wrote here plus Input's own variant defaults; an axis Input derives or coerces for itself (`tier`, `messageType`, `error`, `hasRightIcon`, `iconPosition`) can match the wrong state — #360. |
| preset | `string` | no | | Apply a named preset registered via ``. Prefer this over `class` overrides when the requested look falls outside the semantic intent palette — presets keep hover/active/dark-mode logic coherent and make the custom look reusable across the project. |
| readonly | `boolean` | no | false | readonly property |
| required | `boolean` | no | false | Adds a required asterisk to the label and sets the native `required` attribute. |
| rightIcon | `Snippet` | no | | Icon snippet rendered on the right side of the input field. |
| rightIconAriaLabel | `string` | no | | Accessible label for the clickable right icon button. Required when `onRightIconClick` is set so screen-reader users hear a name for the button (icons inside are `aria-hidden`). |
| slotClasses | `Partial>` | no | | Per-slot class overrides merged with tv() styles. Slots: wrapper (root — what `class` also targets) | container | base (the `` element) | label | requiredMark | message | iconContainer | iconButton | iconDecoration. In the same Tailwind bucket `class` wins over the `slotClasses` entry for the element it lands on. Presets and provider defaults sit below both. |
| symbolPosition | `CurrencySymbolPosition` | no | 'suffix' | Where the currency symbol is rendered as a static adornment. The symbol is shown in the input's left or right icon slot (always visible, including while focused) — it is never embedded in the editable text. Use `'none'` for headless numeric editing (no symbol shown at all). |
| unstyled | `boolean` | no | | Remove all default tv() classes — only user-provided classes apply. |
| value | `number | null` | no | null | Current monetary value in **minor units** (e.g. cents). Use `null` for "no value entered yet"; the input renders empty. |
Inherited from:
- Omit (omit-pattern)
### Types
```ts
type CurrencySymbolPosition = 'prefix' | 'suffix' | 'none'
```
```ts
type MintProp = | MintName
| { name: MintName; config?: MintConfig & Record }
| Array
| Array }>
```
```ts
type VariantProps = Omit<
Exclude[0], undefined>,
'class'
>
```
```ts
type MintName = BuiltinMintName | 'none' | (string & {})
```
```ts
interface MintConfig {
/**
* `hover` and `focus` hold the effect while the pointer/visible focus stays
* on the element; `click` and `load` run it once.
*/
trigger?: 'hover' | 'click' | 'focus' | 'load';
/**
* Effect duration in ms. Written as an inline per-effect custom property
* (`--blocks-mint--duration`), so the CSS transition/animation
* actually runs at this speed; unset, the theme duration tokens apply.
*/
duration?: number;
/** Delay in ms before the effect applies. */
delay?: number;
/**
* CSS easing for the effect (`--blocks-mint--easing` inline);
* unset, the per-effect theme default applies.
*/
easing?: string;
disabled?: boolean;
}
```
```ts
type SlotNames = keyof ReturnType & string
```