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
35 changes: 17 additions & 18 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,17 @@ class CurrencyInput extends React.Component<CurrencyInputProps, CurrencyInputSta
// Check if the VALUE prop itself changed (parent is controlling the input)
const valueChanged = nextProps.value !== previousProps.value;

// Check if allowNegative changed (affects whether negative values are allowed)
const allowNegativeChanged = nextProps.allowNegative !== previousProps.allowNegative;

// Check if separators or display formatting changed (these require reformatting the current value)
const formatChanged =
nextProps.decimalSeparator !== previousProps.decimalSeparator ||
nextProps.thousandSeparator !== previousProps.thousandSeparator ||
nextProps.precision !== previousProps.precision ||
nextProps.prefix !== previousProps.prefix ||
nextProps.suffix !== previousProps.suffix;
nextProps.suffix !== previousProps.suffix ||
allowNegativeChanged;

if (valueChanged) {
// Parent changed the value prop - use the new value
Expand All @@ -204,33 +208,28 @@ class CurrencyInput extends React.Component<CurrencyInputProps, CurrencyInputSta
}

if (formatChanged) {
// Display formatting changed - reformat the current value with new formatting
const propsWithCurrentValue = { ...nextProps, value: prevState.value };
const newState = CurrencyInput.prepareProps(propsWithCurrentValue);
return { ...newState, previousProps: nextProps };
}
// Display formatting or allowNegative changed - reformat the current value
// First, determine the value to use. Start with the current state value,
// which may be adjusted below if allowNegative was disabled and value is negative.
let valueToFormat = prevState.value;

// Check if allowNegative changed
const allowNegativeChanged = nextProps.allowNegative !== previousProps.allowNegative;

if (allowNegativeChanged) {
if (!nextProps.allowNegative) {
// allowNegative was disabled
// If current value is negative, make it positive
if (allowNegativeChanged && !nextProps.allowNegative) {
// allowNegative was disabled - if current value is negative, make it positive
const parsedValue = typeof prevState.value === 'number'
? prevState.value
: prevState.value === null
? 0
: CurrencyInput.stringValueToFloat(String(prevState.value), nextProps.thousandSeparator, nextProps.decimalSeparator);

if (parsedValue < 0) {
const propsWithPositiveValue = { ...nextProps, value: Math.abs(parsedValue) };
const newState = CurrencyInput.prepareProps(propsWithPositiveValue);
return { ...newState, previousProps: nextProps };
valueToFormat = Math.abs(parsedValue);
}
}
// allowNegative toggled on or no sign change needed: still advance previousProps
return { ...prevState, previousProps: nextProps };

// Reformat with new formatting and potentially adjusted value
const propsWithCurrentValue = { ...nextProps, value: valueToFormat };
const newState = CurrencyInput.prepareProps(propsWithCurrentValue);
return { ...newState, previousProps: nextProps };
}

// Other props changed but value and display formatting didn't
Expand Down
32 changes: 32 additions & 0 deletions tests/base.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,38 @@ test.describe('component parameters', () => {
value = await currencyInput.inputValue();
expect(value).not.toContain('-');
});

test('removes negative sign when allowNegative is disabled and format changes simultaneously', async ({ page }) => {
// First enable allowNegative
const allowNegativeCheckbox = page.locator('[name=allowNegative]');
const prefixInput = page.locator('[name=prefix]');
const applyBtn = page.locator('[name=apply]');
const currencyInput = page.locator('#currency-input');

await allowNegativeCheckbox.check();
await applyBtn.click();
await expect(currencyInput).toHaveValue('$0.00 USD');
await currencyInput.focus();
await currencyInput.selectText();

// Input a negative number
await currencyInput.pressSequentially('50');
await currencyInput.press('Minus');

let value = await currencyInput.inputValue();
expect(value).toContain('-');

// Now disable allowNegative AND change prefix at the same time
await allowNegativeCheckbox.uncheck();
await prefixInput.fill('€');
await applyBtn.click();

// Value should now be positive AND have the new prefix
value = await currencyInput.inputValue();
expect(value).not.toContain('-');
expect(value).toContain('€');
expect(value).toContain('50');
});
});

test.describe('allowEmpty', () => {
Expand Down