Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ name | `string` | `total` | Applies the name to the [inp
required | `boolean` | `false` | Marks the inputs as required |
disabled | `boolean` | `false` | Marks the inputs as disabled |
placeholder | `number` `null` | `0` | Overrides the default placeholder. Setting the value to a `number` will display it as formatted. 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](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete#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](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#minimumfractiondigits) used for formatting the currency. Supported digits: `0` to `20` |
Expand Down
6 changes: 4 additions & 2 deletions src/lib/CurrencyInput.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
export let placeholder: number | null = DEFAULT_VALUE;
export let autocomplete: string | null | undefined = undefined;
export let isNegativeAllowed: boolean = true;
export let isZeroNullish: boolean = false;
export let fractionDigits: number = DEFAULT_FRACTION_DIGITS;
export let inputClasses: InputClasses | null = null;
export let onValueChange: Callback = () => {};
Expand Down Expand Up @@ -141,7 +142,7 @@
const previousFormattedValueLength = formattedValue.length;

// Apply formatting to input
formattedValue = isZero ? '' : formatCurrency(value, fractionDigits, hasMinFractionDigits ? fractionDigits : 0);
formattedValue = isZero && !isZeroNullish ? '' : formatCurrency(value, fractionDigits, hasMinFractionDigits ? fractionDigits : 0);

// Update `value` after formatting
setUnformattedValue();
Expand All @@ -162,8 +163,9 @@
let formattedValue = '';
let formattedPlaceholder =
placeholder !== null ? formatCurrency(placeholder, fractionDigits, fractionDigits) : '';
$: isZero = value === 0;
$: isNegative = value < 0;
$: isPositive = value > 0;
$: isZero = !isNegative && !isPositive;
$: value, setFormattedValue();
</script>

Expand Down
1 change: 1 addition & 0 deletions src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
}}
/>
<CurrencyInput name="rupees" value={678} locale="hi-IN" currency="INR" fractionDigits={3} />
<CurrencyInput name="soles" value={0} isZeroNullish={true} placeholder={null} locale="es-PE" currency="PEN" />
</div>

<nav class="demoForm__output">
Expand Down
18 changes: 17 additions & 1 deletion tests/svelte-currency-input.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ test.describe('CurrencyInput', () => {
'formatted-pesos': '$ 999,00',
rupees: '678',
'formatted-rupees': '₹678.000',
soles: '0',
'formatted-soles': 'S/ 0.00',
},
null,
2
Expand Down Expand Up @@ -295,7 +297,7 @@ test.describe('CurrencyInput', () => {
// Tabbing in Webkit is broken: https://github.com/Canutin/svelte-currency-input/issues/40
if (testInfo.project.name !== 'webkit') {
const formattedInputs = page.locator('.currencyInput__formatted');
expect(await formattedInputs.count()).toBe(10);
expect(await formattedInputs.count()).toBe(11);

await formattedInputs.first().focus();
await expect(formattedInputs.nth(0)).toBeFocused();
Expand Down Expand Up @@ -372,6 +374,20 @@ test.describe('CurrencyInput', () => {
await expect(rupeesUnformattedInput).toHaveValue('123');
});

test("isZeroNullish doesn't render placeholder when the value is 0", async ({ page }) => {
const solesUnformattedInput = page.locator('.currencyInput__unformatted[name="soles"]');
const solesFormattedInput = page.locator('.currencyInput__formatted[name="formatted-soles"]');
await expect(solesUnformattedInput).toHaveValue('0');
await expect(solesFormattedInput).toHaveValue('S/ 0.00');
await expect(solesFormattedInput).toHaveAttribute('placeholder', '');

const colonUnformattedInput = page.locator('.currencyInput__unformatted[name=colon]');
const colonFormattedInput = page.locator('.currencyInput__formatted[name="formatted-colon"]');
await expect(colonUnformattedInput).toHaveValue('0');
await expect(colonFormattedInput).not.toHaveValue('₡0,00');
await expect(colonFormattedInput).toHaveAttribute('placeholder', '₡0,00');
});

test.skip('Updating chained inputs have the correct behavior', async () => {
// TODO
});
Expand Down