Skip to content

Commit

Permalink
[@mantine/core] NumberInput: Add thousandsSeparator (mantinedev#3990)
Browse files Browse the repository at this point in the history
  • Loading branch information
cyantree authored Apr 4, 2023
1 parent 0e9cb81 commit 19ca962
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 13 deletions.
4 changes: 2 additions & 2 deletions docs/src/docs/core/NumberInput.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ To use decimal steps set following props:

<Demo data={NumberInputDemos.decimal} />

## Decimal separator
## Decimal/Thousands separator

To change decimal separator set `decimalSeparator` prop:
To change the separators set `decimalSeparator` and `thousandsSeparator` props:

<Demo data={NumberInputDemos.decimalSeparator} />

Expand Down
1 change: 1 addition & 0 deletions src/mantine-core/src/NumberInput/NumberInput.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export function Usage() {
onChange={setValue}
precision={2}
decimalSeparator=","
thousandsSeparator="."
mb="md"
min={10}
defaultValue={12}
Expand Down
24 changes: 21 additions & 3 deletions src/mantine-core/src/NumberInput/NumberInput.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -162,15 +162,33 @@ describe('@mantine/core/NumberInput', () => {

it('supports changing decimal separator', async () => {
const spy = jest.fn();
render(
<NumberInput max={10} min={0} step={6} precision={2} onChange={spy} decimalSeparator="," />
);
render(<NumberInput precision={2} onChange={spy} decimalSeparator="," />);
await enterText('6,54');
blurInput();
expect(spy).toHaveBeenLastCalledWith(6.54);
expect(getInput()).toHaveValue('6,54');
});

it('supports changing thousands separator', async () => {
const spy = jest.fn();
render(<NumberInput precision={2} onChange={spy} thousandsSeparator="." />);
await enterText('1.000.000');
blurInput();
expect(spy).toHaveBeenLastCalledWith(1000000);
expect(getInput()).toHaveValue('1000000.00');
});

it('supports changing thousands and decimal separator', async () => {
const spy = jest.fn();
render(
<NumberInput precision={3} onChange={spy} decimalSeparator="," thousandsSeparator="." />
);
await enterText('1.000.000,355');
blurInput();
expect(spy).toHaveBeenLastCalledWith(1000000.355);
expect(getInput()).toHaveValue('1000000,355');
});

it('sets input value with a given precision', async () => {
const spy = jest.fn();
render(<NumberInput max={10} min={0} step={6} precision={2} onChange={spy} />);
Expand Down
16 changes: 10 additions & 6 deletions src/mantine-core/src/NumberInput/NumberInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ export interface NumberInputProps
/** The decimal separator */
decimalSeparator?: string;

/** The thousands separator */
thousandsSeparator?: string;

/** Maximum possible value */
max?: number;

Expand Down Expand Up @@ -118,6 +121,7 @@ const defaultProps: Partial<NumberInputProps> = {
precision: 0,
noClampOnBlur: false,
removeTrailingZeros: false,
decimalSeparator: '.',
formatter: defaultFormatter,
parser: defaultParser,
type: 'text',
Expand All @@ -130,6 +134,7 @@ export const NumberInput = forwardRef<HTMLInputElement, NumberInputProps>((props
value,
onChange,
decimalSeparator,
thousandsSeparator,
min,
max,
startValue,
Expand Down Expand Up @@ -175,19 +180,18 @@ export const NumberInput = forwardRef<HTMLInputElement, NumberInputProps>((props

if (removeTrailingZeros && precision > 0) {
result = result.replace(new RegExp(`[0]{0,${precision}}$`), '');
if (result.endsWith('.') || result.endsWith(decimalSeparator)) {
if (result.endsWith('.')) {
result = result.slice(0, -1);
}
}

return result;
};

const formatNum = (val: string | number = '') => {
let parsedStr = typeof val === 'number' ? String(val) : val;

const formatNum = (val: string) => {
let parsedStr = val;
if (decimalSeparator) {
parsedStr = parsedStr.replace(/\./g, decimalSeparator);
parsedStr = parsedStr.replace('.', decimalSeparator);
}

return formatter(parsedStr);
Expand All @@ -197,7 +201,7 @@ export const NumberInput = forwardRef<HTMLInputElement, NumberInputProps>((props
let num = val;

if (decimalSeparator) {
num = num.replace(new RegExp(`\\${decimalSeparator}`, 'g'), '.');
num = num.replaceAll(thousandsSeparator, '').replace(decimalSeparator, '.');
}

return parser(num);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ function Demo() {
return (
<NumberInput
decimalSeparator=","
label="Number input with a custom decimal separator"
thousandsSeparator="."
label="Number input with custom separators"
defaultValue={0.5}
precision={2}
step={0.5}
Expand All @@ -24,7 +25,8 @@ function Demo() {
maw={320}
mx="auto"
decimalSeparator=","
label="Number input with a custom decimal separator"
thousandsSeparator="."
label="Number input with custom separators"
placeholder="Decimal separator"
defaultValue={0.5}
precision={2}
Expand Down

0 comments on commit 19ca962

Please sign in to comment.