MoneyInput
A monetary input component that stores values in cents for precision. Supports CAD and USD currencies with voice input for natural language amounts in smrt mode.
Installation
import { MoneyInput } from '@happyvertical/smrt-svelte';Basic Usage
A simple money input. The value is stored in cents (e.g., 15000 = $150.00).
<script lang="ts">
let value = $state<number | null>(null);
</script>
<MoneyInput
name="amount"
label="Amount"
bind:value
/>Currency Selection
Use currency to switch between CAD (default) and USD.
<MoneyInput
name="usd-amount"
label="Price (USD)"
currency="USD"
value={15000}
/>With Constraints
Use min and max to constrain the value range (in cents).
<MoneyInput
name="donation"
label="Donation Amount"
min={500}
max={100000}
description="Between $5.00 and $1,000.00"
/>Required Field
Add required to mark the field as required.
<MoneyInput
name="payment"
label="Payment Amount"
required
/>Disabled State
Use disabled to prevent user interaction.
<MoneyInput
name="total"
label="Order Total"
value={24999}
disabled
/>With Error
Display validation errors using the error prop.
<MoneyInput
name="budget"
label="Budget"
error="Budget exceeds available funds"
value={500000}
/>Voice Input (smrt Mode)
In smrt mode, users can speak monetary amounts naturally. The component parses phrases like:
- "one hundred fifty dollars" = 15000 cents
- "twenty five fifty" = 2550 cents ($25.50)
- "fifty cents" = 50 cents
- "a thousand bucks" = 100000 cents
<!-- Voice example: "one hundred fifty dollars" -->
<MoneyInput
name="voice"
label="Enter Amount"
description="A monetary amount in dollars"
/>Interactive Example
Enter an amount to see the cents value:
Value in cents: null
Display: (empty)
<script lang="ts">
let value = $state<number | null>(null);
</script>
<MoneyInput
name="interactive"
label="Enter Price"
bind:value
/>
<p>Value in cents: {value ?? 'null'}</p>
<p>Display: {value ? '$' + (value / 100).toFixed(2) : '(empty)'}</p>Props
| Prop | Type | Default | Description |
|---|---|---|---|
name * | string | - | Field name for form submission |
label | string | undefined | Field label displayed above the input |
description | string | undefined | Description text for voice extraction context |
placeholder | string | '0.00' | Placeholder text shown when empty |
value | number | null | null | Current value in cents (bindable) |
currency | 'CAD' | 'USD' | 'CAD' | Currency code for display |
min | number | undefined | Minimum value in cents |
max | number | undefined | Maximum value in cents |
disabled | boolean | false | Disables the input |
required | boolean | false | Marks field as required |
error | string | undefined | Error message to display |
onchange | (cents: number | null) => void | undefined | Callback when value changes |
TypeScript
import { MoneyInput } from '@happyvertical/smrt-svelte';
// Props interface
interface Props {
name: string;
label?: string;
description?: string;
placeholder?: string;
value?: number | null; // Value in cents
currency?: 'CAD' | 'USD';
min?: number; // In cents
max?: number; // In cents
disabled?: boolean;
required?: boolean;
error?: string;
onchange?: (cents: number | null) => void;
}Value Format
The component stores values in cents to avoid floating-point precision issues common with monetary calculations:
$150.00is stored as15000$25.50is stored as2550$0.99is stored as99
A hidden input {name}_cents is included for form submission with the cents value.