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
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,65 @@ describe("mt-number-field", () => {
expect(input).toHaveValue("1000");
});

it("normalizes pasted numbers with mixed decimal and grouping separators", async () => {
// ARRANGE
const inputChangeHandler = vi.fn();
const updateHandler = vi.fn();

render(MtNumberField, {
props: {
"onInput-change": inputChangeHandler,
"onUpdate:modelValue": updateHandler,
},
});

const input = screen.getByRole("textbox") as HTMLInputElement;

// ACT
await userEvent.click(input);
await userEvent.paste("333,33");

// ASSERT
expect(inputChangeHandler).toHaveBeenLastCalledWith(333.33);
expect(updateHandler).not.toHaveBeenCalled();
expect(input.value).toBe("333,33");

// ACT
await userEvent.click(document.body);

// ASSERT
expect(updateHandler).toHaveBeenLastCalledWith(333.33);
expect(input.value).toBe("333.33");

// ACT
await userEvent.clear(input);
await userEvent.paste("1.333,33");

// ASSERT
expect(inputChangeHandler).toHaveBeenLastCalledWith(1333.33);

// ACT
await userEvent.click(document.body);

// ASSERT
expect(updateHandler).toHaveBeenLastCalledWith(1333.33);
expect(input.value).toBe("1333.33");

// ACT
await userEvent.clear(input);
await userEvent.paste("1,333.33");

// ASSERT
expect(inputChangeHandler).toHaveBeenLastCalledWith(1333.33);

// ACT
await userEvent.click(document.body);

// ASSERT
expect(updateHandler).toHaveBeenLastCalledWith(1333.33);
expect(input.value).toBe("1333.33");
});

it("rounds a decimal value to an integer on blur for int type", async () => {
// ARRANGE
const updateHandler = vi.fn();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -367,11 +367,11 @@ export default defineComponent({
return;
}

const val = Number.parseFloat(inputValue);
const val = this.getNumberFromString(inputValue);

if (!Number.isNaN(val)) {
this.computeValue(val.toString(), true);
this.$emit("input-change", val);
this.computeValue(inputValue, true);
this.$emit("input-change", this.currentValue);
} else if (inputValue === "" || inputValue === "-" || inputValue === ".") {
// @ts-expect-error - defined in parent
this.currentValue = null;
Expand Down Expand Up @@ -427,28 +427,31 @@ export default defineComponent({
},

getNumberFromString(value: any) {
const normalizedValue = value.toString().replace(/,/g, ".");
const normalizedValue = value.toString().trim().replace(/\s/g, "");

if (normalizedValue.toLowerCase().includes("e")) {
return Number.parseFloat(normalizedValue);
return Number.parseFloat(normalizedValue.replace(/,/g, "."));
}

let splits = normalizedValue;
splits = splits.replace(/,/g, ".").split(".");
const commaIndex = normalizedValue.lastIndexOf(",");
const dotIndex = normalizedValue.lastIndexOf(".");
const decimalSeparatorIndex = Math.max(commaIndex, dotIndex);

if (splits.length === 1) {
return parseFloat(splits[0]);
if (decimalSeparatorIndex === -1) {
return Number.parseFloat(normalizedValue);
}

const integerPart = normalizedValue.slice(0, decimalSeparatorIndex).replace(/[,.]/g, "");
const decimalPart = normalizedValue.slice(decimalSeparatorIndex + 1).replace(/[,.]/g, "");
const parsedValue = Number.parseFloat(`${integerPart}.${decimalPart}`);

if (this.numberType === "int") {
// Keep the decimal point and let checkForInteger round the result. Joining
// without "." would concatenate the digit groups and turn 1.05 into 105.
return parseFloat(splits.join("."));
return parsedValue;
}
const decimals = splits[splits.length - 1].length;
const float = parseFloat(splits.join(".")).toFixed(decimals);

return decimals > this.digits ? this.roundToDigits(float, this.digits) : Number(float);
return decimalPart.length > this.digits
? this.roundToDigits(parsedValue.toString(), this.digits)
: parsedValue;
},

roundToDigits(value: string, digits: number): number {
Expand Down
Loading