A Svelte 5 form input with currency masking and internationalization support
bun add @canutin/svelte-currency-input<script lang="ts">
import { CurrencyInput } from '@canutin/svelte-currency-input';
let value = $state('1234.56');
</script>
<CurrencyInput
bind:value
intlConfig={{ locale: 'en-US', currency: 'USD' }}
/><script lang="ts">
import { CurrencyInput } from '@canutin/svelte-currency-input';
const presets = [
{ label: 'de-DE (EUR)', intlConfig: { locale: 'de-DE', currency: 'EUR' } },
{ label: 'ja-JP (JPY)', intlConfig: { locale: 'ja-JP', currency: 'JPY' } },
{ label: 'en-IN (INR)', intlConfig: { locale: 'en-IN', currency: 'INR' } },
{ label: 'es-PE (PEN)', intlConfig: { locale: 'es-PE', currency: 'PEN' } },
{ label: 'es-CR (CRC)', intlConfig: { locale: 'es-CR', currency: 'CRC' } },
{ label: 'th-TH (THB)', intlConfig: { locale: 'th-TH', currency: 'THB' } },
{ label: 'he-IL (ILS)', intlConfig: { locale: 'he-IL', currency: 'ILS' } }
];
let selectedIndex = $state(0);
let intlConfig = $derived(presets[selectedIndex].intlConfig);
let value = $state('1234.56');
</script>
<select bind:value={selectedIndex}>
{#each presets as preset, i}
<option value={i}>{preset.label}</option>
{/each}
</select>
<CurrencyInput
bind:value
{intlConfig}
/><script lang="ts">
import { CurrencyInput } from '@canutin/svelte-currency-input';
let value = $state('');
</script>
<!-- Type 1k, 2.5m, or 1b -->
<CurrencyInput
bind:value
intlConfig={{ locale: 'en-US', currency: 'USD' }}
/><script lang="ts">
import { CurrencyInput } from '@canutin/svelte-currency-input';
let value = $state('99.99');
</script>
<CurrencyInput
bind:value
intlConfig={{ locale: 'en-US', currency: 'USD' }}
decimalsLimit={2}
decimalScale={2}
/><script lang="ts">
import { CurrencyInput } from '@canutin/svelte-currency-input';
let value = $state('50');
</script>
<!-- Use arrow keys to step -->
<CurrencyInput
bind:value
intlConfig={{ locale: 'en-US', currency: 'USD' }}
min={0}
max={100}
step={10}
/><CurrencyInput
suffix=" pts"
decimalsLimit={0}
/>
<CurrencyInput
prefix="₿ "
decimalsLimit={8}
/><script lang="ts">
import { CurrencyInput } from '@canutin/svelte-currency-input';
let value = $state('-3.14');
const getValueColor = (val: string) => {
if (!val || val === '-') return '';
const num = parseFloat(val);
if (num === 0) return 'text-slate-400';
return num < 0 ? 'text-rose-500' : 'text-emerald-500';
};
</script>
<CurrencyInput
bind:value
intlConfig={{ locale: 'en-GB', currency: 'GBP' }}
class={getValueColor(value)}
/><script lang="ts">
import { CurrencyInput } from '@canutin/svelte-currency-input';
let value = $state('1000');
</script>
<CurrencyInput
bind:value
intlConfig={{ locale: 'en-US', currency: 'USD' }}
/>
<CurrencyInput
bind:value
intlConfig={{ locale: 'de-DE', currency: 'EUR' }}
/>
<CurrencyInput
bind:value
intlConfig={{ locale: 'en-GB', currency: 'GBP' }}
disabled
/><script lang="ts">
import { formatValue } from '@canutin/svelte-currency-input';
let value = $state('1234567.89');
let prefix = $state('$');
let groupSeparator = $state(',');
let decimalSeparator = $state('.');
let formattedResult = $derived(
formatValue({
value,
prefix,
groupSeparator,
decimalSeparator
})
);
</script>
{formattedResult}| Oficial | US$ 1.495 | $ 1.495 ARS |
| MEP | US$ 1.503,6 | $ 1.503,6 ARS |
| Blue | US$ 1.530 | $ 1.530 ARS |
| CCL | US$ 1.534,9 | $ 1.534,9 ARS |
| Cripto | US$ 1.549,72 | $ 1.549,72 ARS |
| Tarjeta | US$ 1.943,5 | $ 1.943,5 ARS |
<script lang="ts">
import { CurrencyInput, formatValue } from '@canutin/svelte-currency-input';
const arsConfig = { locale: 'es-AR', currency: 'ARS' };
const usdConfig = { locale: 'es-AR', currency: 'USD' };
const dollarRates = [
{ name: 'Oficial', rate: 1495 },
{ name: 'MEP', rate: 1503.6 },
{ name: 'Blue', rate: 1530 },
{ name: 'CCL', rate: 1534.9 },
{ name: 'Cripto', rate: 1549.72 },
{ name: 'Tarjeta', rate: 1943.5 }
];
let usdAmount = $state<number | null>(1);
function formatUSD(value: number): string {
return formatValue({ value: value.toFixed(2), intlConfig: usdConfig });
}
function formatARS(value: number): string {
return formatValue({ value: value.toFixed(2), intlConfig: arsConfig });
}
</script>
<CurrencyInput
value={usdAmount != null ? String(usdAmount) : ''}
oninputvalue={(v) => (usdAmount = v.float)}
intlConfig={usdConfig}
/>
<table>
{#each dollarRates as { name, rate } (name)}
<tr>
<td>{name}</td>
<td>{formatUSD(rate)}</td>
<td>{formatARS((usdAmount ?? 0) * rate)}</td>
</tr>
{/each}
</table>