Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -1490,6 +1490,86 @@ describe("calcite-input-number", () => {
expect(await input.getProperty("value")).toBe(numberStringFormatter.localize(initialValue));
});

it("allows editing numbers that start with zeros and have a group separator and minus sign", async () => {
const page = await newE2EPage();
await page.setContent(html`<calcite-input-number group-separator></calcite-input-number>`);

const calciteInput = await page.find("calcite-input-number");
const input = await page.find("calcite-input-number >>> input");
await calciteInput.callMethod("setFocus");
await page.waitForChanges();
await typeNumberValue(page, "-7000");
await page.waitForChanges();
expect(await calciteInput.getProperty("value")).toBe("-7000");
expect(await input.getProperty("value")).toBe("-7,000");

await page.keyboard.press("ArrowLeft");
await page.keyboard.press("ArrowLeft");
await page.keyboard.press("ArrowLeft");
await page.keyboard.press("ArrowLeft");
await page.keyboard.press("Backspace");
await page.waitForChanges();
expect(await calciteInput.getProperty("value")).toBe("-0");
expect(await input.getProperty("value")).toBe("-000");

await page.keyboard.press("Home");
await page.keyboard.press("ArrowRight");
await page.keyboard.type("5");
await page.waitForChanges();
expect(await calciteInput.getProperty("value")).toBe("-5000");
expect(await input.getProperty("value")).toBe("-5,000");

await page.keyboard.press("Home");
await page.keyboard.press("ArrowRight");
await page.keyboard.press("ArrowRight");
await page.keyboard.press("Backspace");
await page.keyboard.press("Home");
await page.keyboard.press("ArrowRight");
await page.keyboard.type("7");
await page.waitForChanges();
expect(await calciteInput.getProperty("value")).toBe("-7000");
expect(await input.getProperty("value")).toBe("-7,000");
});

it("allows editing numbers that start with zeros and have decimals in the ar locale and arab numbering system", async () => {
const initialValue = "10000.0001";
numberStringFormatter.numberFormatOptions = {
locale: "ar",
numberingSystem: "arab",
useGrouping: false,
};

const page = await newE2EPage();
await page.setContent(
html`<calcite-input-number lang="ar" numbering-system="arab" value="${initialValue}"></calcite-input-number>`,
);

const calciteInput = await page.find("calcite-input-number");
const input = await page.find("calcite-input-number >>> input");
await calciteInput.callMethod("setFocus");
await page.waitForChanges();

expect(await calciteInput.getProperty("value")).toBe(initialValue);
expect(await input.getProperty("value")).toBe(numberStringFormatter.localize(initialValue));

await page.keyboard.press("Home");
await page.keyboard.press("Delete");
await page.waitForChanges();

expect(await calciteInput.getProperty("value")).toBe("0.0001");
expect(await input.getProperty("value")).toBe(
// the localize method converts the string to a number, which removes the leading zeros
// so we need to manually add them back in the test when confirming the expected value
`${numberStringFormatter.localize("0").repeat(3)}${numberStringFormatter.localize("0.0001")}`,
);

await typeNumberValue(page, "2");
await page.waitForChanges();

expect(await calciteInput.getProperty("value")).toBe("20000.0001");
expect(await input.getProperty("value")).toBe(numberStringFormatter.localize("20000.0001"));
});

it("cannot be modified when readOnly is true", async () => {
const page = await newE2EPage();
await page.setContent(html`<calcite-input-number read-only value="123" clearable></calcite-input-number>`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,9 @@ export class InputNumber
const hasTrailingDecimalSeparator =
valueHandleInteger.charAt(valueHandleInteger.length - 1) === ".";

const hasLeadingMinusSign = valueHandleInteger.charAt(0) === "-";
const hasLeadingZeros = valueHandleInteger.match(/^-?(0+)\d/);

const sanitizedValue =
hasTrailingDecimalSeparator && isValueDeleted
? valueHandleInteger
Expand All @@ -846,11 +849,20 @@ export class InputNumber
}

// adds localized trailing decimal separator
this.displayedValue =
hasTrailingDecimalSeparator && isValueDeleted
? `${newLocalizedValue}${numberStringFormatter.decimal}`
: newLocalizedValue;
if (hasTrailingDecimalSeparator && isValueDeleted) {
newLocalizedValue = `${newLocalizedValue}${numberStringFormatter.decimal}`;
}

// adds localized leading zeros
if (hasLeadingZeros) {
newLocalizedValue = `${
hasLeadingMinusSign ? newLocalizedValue.charAt(0) : ""
}${numberStringFormatter.localize("0").repeat(hasLeadingZeros[1].length)}${
hasLeadingMinusSign ? newLocalizedValue.slice(1) : newLocalizedValue
}`;
}

Copy link
Copy Markdown
Contributor

@benelan benelan Apr 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the regex change I suggested above, lines 851-871 could be changed to something like this:

    // adds localized trailing decimal separator
    if (hasTrailingDecimalSeparator && isValueDeleted) {
      newLocalizedValue = `${newLocalizedValue}${numberStringFormatter.decimal}`;
    }

    // adds localized leading zeros
    if (hasLeadingZeros) {
      newLocalizedValue = `${
        hasLeadingMinusSign ? newLocalizedValue.charAt(0) : ""
      }${numberStringFormatter.localize("0").repeat(hasLeadingZeros[1].length)}${
        hasLeadingMinusSign ? newLocalizedValue.slice(1) : newLocalizedValue
      }`;
    }

    this.displayedValue = newLocalizedValue;
Diff
-    //adds localized trailing decimal separator
-    this.displayedValue =
-      hasTrailingDecimalSeparator && isValueDeleted
-        ? `${newLocalizedValue}${numberStringFormatter.decimal}`
-        : newLocalizedValue;
- 
-    if (reResult) {
-      this.displayedValue = reResult[1]
-        ? `-${this.displayedValue
-            .substring(1, this.displayedValue.length)
-            .padStart(
-              valueHandleInteger.length - 1 - (hasTrailingDecimalSeparator ? 1 : 0),
-              numberStringFormatter.localize("0"),
-            )}`
-        : this.displayedValue.padStart(
-            valueHandleInteger.length,
-            numberStringFormatter.localize("0"),
-          );
-      this.displayedValue += hasTrailingDecimalSeparator ? numberStringFormatter.decimal : "";
-    }
+    // adds localized trailing decimal separator
+    if (hasTrailingDecimalSeparator && isValueDeleted) {
+      newLocalizedValue = `${newLocalizedValue}${numberStringFormatter.decimal}`;
+    }
+ 
+    // adds localized leading zeros
+    if (hasLeadingZeros) {
+      newLocalizedValue = `${
+        hasLeadingMinusSign ? newLocalizedValue.charAt(0) : ""
+      }${numberStringFormatter.localize("0").repeat(hasLeadingZeros[1].length)}${
+        hasLeadingMinusSign ? newLocalizedValue.slice(1) : newLocalizedValue
+      }`;
+    }
+ 
+    this.displayedValue = newLocalizedValue;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may want to use the isValueDeleted boolean for the hasLeadingZeros conditional too. Can you investigate?

this.displayedValue = newLocalizedValue;
this.setPreviousNumberValue(previousValue ?? this.value);
this.previousValueOrigin = origin;
this.userChangedValue = origin === "user" && this.value !== newValue;
Expand Down
10 changes: 8 additions & 2 deletions packages/calcite-components/src/demos/input-number.html
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,14 @@
<div class="child-flex font right-aligned-text">Number Vertical</div>
<div class="child-flex">
<calcite-label scale="s">
Input Label
<calcite-input-number placeholder="Placeholder" scale="s" value="123" step="1"></calcite-input-number>
Input Label AR2
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@josercarcamo for consistency, could you restore the previous HTML and either:

  • move this particular Arabic configuration to a new section or
  • omit it for now?

<calcite-input-number
placeholder="Placeholder"
scale="s"
value="123"
lang="ar"
numbering-system="arab"
></calcite-input-number>
</calcite-label>
</div>

Expand Down
Loading