@canutin/svelte-currency-input
v0.13.0
Published
A form input that converts numbers to currencies as you type in localized formats
Downloads
2,070
Maintainers
Readme
svelte-currency-input
A masked form input that converts numbers to localized currency formats as you type
Features
- Formats positive and negative values
- Leverages
Intl.NumberFormat
for localizing currency denominations and masking the input - Simple API
- Minimal default styling, easy to customize
Usage
npm install @canutin/svelte-currency-input --save
<script lang="ts">
import CurrencyInput from '@canutin/svelte-currency-input';
</script>
<CurrencyInput name="total" value={-420.69} locale="nl-NL" currency="EUR" />
How it works
When the form is submitted you get unformatted or formatted values from two <input />
's.
This is more or less what <CurrencyInput />
looks like under the hood:
<div class="currencyInput">
<!-- Unformatted value -->
<input
class="currencyInput__unformatted"
type="hidden"
name="total"
value="-420.69"
/>
<!-- Formatted value -->
<input
class="currencyInput__formatted"
type="text"
name="formatted-total"
value="€ -420,69"
/>
</div>
API
Option | Type | Default | Description |
----------------- | --------------- | ----------- | ----------- |
value | number
| undefined
| Initial value. If left undefined
a formatted value of 0
is visible as a placeholder |
locale | string
| en-US
| Overrides default locale. Examples |
currency | string
| USD
| Overrides default currency. Examples |
name | string
| total
| Applies the name to the input fields for unformatted (e.g [name=total]
) and formatted (e.g. [name=formatted-total]
) values |
id | string
| undefined
| Sets the id
attribute on the input |
required | boolean
| false
| Marks the input as required |
disabled | boolean
| false
| Marks the input as disabled |
placeholder | string
number
null
| 0
| A string
will override the default placeholder. A number
will override it by formatting it to the set currency. Setting it to null
will not show a placeholder |
isZeroNullish | boolean
| false
| If true
and when the value is 0
, it will override the default placeholder and render the formatted value in the field like any other value. Note: this option might become the default in future versions |
autocomplete | string
| undefined
| Sets the autocomplete attribute. Accepts any valid HTML autocomplete attribute values |
isNegativeAllowed | boolean
| true
| If false
, forces formatting only to positive values and ignores --positive
and --negative
styling modifiers |
fractionDigits | number
| 2
| Sets maximumFractionDigits
in Intl.NumberFormat()
constructor used for formatting the currency. Supported digits: 0
to 20
|
inputClasses | object
| See below | Selectively overrides any class names passed |
onValueChange | Callback
| undefined
| Runs a callback function after the value changes |
Styling
There are two ways of customizing the styling of the input:
- Passing it your own CSS classes
- Overriding the styles using the existing class names
You can override all of the class names by passing an object to inputClasses
that has one or more of these properties:
interface InputClasses {
wrapper?: string; // <div> that contains the two <input> elements
unformatted?: string; // <input type="hidden"> that contains the unformatted value
formatted?: string; // <input type="text"> that contains the formatted value
formattedPositive?: string; // Class added when the formatted input is positive
formattedNegative?: string; // Class added when the formatted input is negative
formattedZero?: string; // Class added when the formatted input is zero
}
Usage (with Tailwind CSS as an example):
<CurrencyInput name="total" value="{420.69}" inputClasses={
{
wrapper: "form-control block",
formatted: 'py-1.5 text-gray-700',
formattedPositive: 'text-green-700',
formattedNegative: 'text-red-700'
}
} />
Alternatively you can write your own CSS by overriding the default styles which use BEM naming conventions. To do so apply your styles as shown below:
<div class="my-currency-input">
<CurrencyInput name="total" value="{420.69}" />
</div>
<style>
/* Container */
div.my-currency-input :global(div.currencyInput) { /* ... */ }
/* Formatted input */
div.my-currency-input :global(input.currencyInput__formatted) { /* ... */ }
/* Formatted input when the it's disabled */
div.my-currency-input :global(input.currencyInput__formatted:disabled) { /* ... */ }
/* Formatted input when the value is zero */
div.my-currency-input :global(input.currencyInput__formatted--zero) { /* ... */ }
/* Formatted input when the value is positive */
div.my-currency-input :global(input.currencyInput__formatted--positive) { /* ... */ }
/* Formatted input when the value is negative */
div.my-currency-input :global(input.currencyInput__formatted--negative) { /* ... */ }
</style>
Contributing
Here's ways in which you can contribute:
- Found a bug? Open a new issue
- Comment or upvote existing issues
- Submit a pull request
Developing
This package was generated with SvelteKit. Install dependencies with npm install
, then start a development server:
npm run dev
# or start the server and open the app in a new browser tab
npm run dev -- --open
Integration tests
The component is tested using Playwright.
You can find the tests in tests/svelte-currency-input.test.ts
To run all tests on Chromium, Firefox and Webkit:
npm run test
To run all tests on a specific browser (e.g. Webkit):
npx playwright test --project=webkit
Additional debug commands can be found on Playwright's documentation.