Skip to content

Commit

Permalink
fix(number-field): multiple separators use-cases in decimal inputs in…
Browse files Browse the repository at this point in the history
… iOS devices (#4571)

* fix(number-field): fixed multiple separators usecase in decimal inputs

* test(number-field): decimal interpretation iOS test
  • Loading branch information
mizgaionutalexandru authored Jun 19, 2024
1 parent aa2a334 commit 6319da8
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 8 deletions.
49 changes: 41 additions & 8 deletions packages/number-field/src/NumberField.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,18 +210,46 @@ export class NumberField extends TextfieldBase {
);
}

private decimalsChars = new Set(['.', ',']);
private valueBeforeFocus: string = '';
private isIntentDecimal: boolean = false;

private convertValueToNumber(value: string): number {
if (isIPhone() && this.inputElement.inputMode === 'decimal') {
const separators = this.valueBeforeFocus
.split('')
.filter((char) => this.decimalsChars.has(char));
const uniqueSeparators = new Set(separators);

if (
isIPhone() &&
this.inputElement.inputMode === 'decimal' &&
value !== this.valueBeforeFocus
) {
const parts = this.numberFormatter.formatToParts(1000.1);
const sourceDecimal = value
.split('')
.find((char) => char === ',' || char === '.');

const replacementDecimal = parts.find(
(part) => part.type === 'decimal'
)?.value;
if (sourceDecimal && replacementDecimal) {
value = value.replace(sourceDecimal, replacementDecimal);
)!.value;

for (const separator of uniqueSeparators) {
const isDecimalSeparator = separator === replacementDecimal;
if (!isDecimalSeparator && !this.isIntentDecimal) {
value = value.replace(new RegExp(separator, 'g'), '');
}
}

let hasReplacedDecimal = false;
const valueChars = value.split('');
for (let index = valueChars.length - 1; index >= 0; index--) {
const char = valueChars[index];
if (this.decimalsChars.has(char)) {
if (!hasReplacedDecimal) {
valueChars[index] = replacementDecimal;
hasReplacedDecimal = true;
} else valueChars[index] = '';
}
}
value = valueChars.join('');
}
return this.numberParser.parse(value);
}
Expand Down Expand Up @@ -379,12 +407,14 @@ export class NumberField extends TextfieldBase {
this._trackingValue = this.inputValue;
this.keyboardFocused = !this.readonly && true;
this.addEventListener('wheel', this.onScroll, { passive: false });
this.valueBeforeFocus = this.inputElement.value;
}

protected override onBlur(_event: FocusEvent): void {
super.onBlur(_event);
this.keyboardFocused = !this.readonly && false;
this.removeEventListener('wheel', this.onScroll);
this.isIntentDecimal = false;
}

private handleFocusin(): void {
Expand Down Expand Up @@ -441,7 +471,7 @@ export class NumberField extends TextfieldBase {
});
}

protected override handleInput(event: Event): void {
protected override handleInput(event: InputEvent): void {
if (this.isComposing) {
event.stopPropagation();
return;
Expand All @@ -454,6 +484,9 @@ export class NumberField extends TextfieldBase {
''
);
}
if (event.data && this.decimalsChars.has(event.data))
this.isIntentDecimal = true;

const { value: originalValue, selectionStart } = this.inputElement;
const value = originalValue
.split('')
Expand Down
34 changes: 34 additions & 0 deletions packages/number-field/test/number-field.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,40 @@ describe('NumberField', () => {
expect(el.focusElement.value).to.equal('13 377 331');
});
});
xit('correctly interprets decimal point on iPhone', async () => {
// setUserAgent is not currently supported by Playwright
await setUserAgent(
'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1'
);
const el = await getElFrom(decimals({ value: 1234 }));
expect(el.formattedValue).to.equal('1,234');

el.focus();
await sendKeys({ press: 'Backspace' });
el.blur();
expect(el.formattedValue).to.equal('123');

el.focus();
await sendKeys({ type: '45' });
el.blur();
expect(el.formattedValue).to.equal('12,345');

el.focus();
await sendKeys({ type: ',6' });
el.blur();
expect(el.formattedValue).to.equal('12,345.6');

el.focus();
await sendKeys({ type: ',7' });
el.blur();
expect(el.formattedValue).to.equal('123,456.7');

el.focus();
await sendKeys({ press: 'Backspace' });
await sendKeys({ press: 'Backspace' });
el.blur();
expect(el.formattedValue).to.equal('123,456');
});
describe('Step', () => {
it('can be 0', async () => {
const el = await getElFrom(
Expand Down

0 comments on commit 6319da8

Please sign in to comment.