Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor!: use inputmode instead of number type #3071

Closed
wants to merge 11 commits into from

Conversation

web-padawan
Copy link
Member

@web-padawan web-padawan commented Nov 17, 2021

Description

  1. Updated to use <input type="text"> but not extend vaadin-text-field for now (IMO, that should be done separately, because it would also mean having to bring back pattern and preventInvalidInput properties and tests for them).
  2. Implemented validation logic based on AbstractNumberField because we no longer use <input type="number"> and can't rely on its built-in logic. Note, the Flow counterpart will still override client-side validation.

Fixes #1169
Fixes #1224

Type of change

  • Feature

Checklist

  • I have read the contribution guide: https://vaadin.com/docs-beta/latest/guide/contributing/overview/
  • I have added a description following the guideline.
  • The issue is created in the corresponding repository and I have referenced it.
  • I have added tests to ensure my change is effective and works as intended.
  • New and existing tests are passing locally with my change.
  • I have performed self-review and corrected misspellings.

@web-padawan web-padawan marked this pull request as ready for review November 18, 2021 11:35
@@ -441,6 +460,16 @@ export class NumberField extends InputFieldMixin(SlotStylesMixin(ThemableMixin(E
super._valueChanged(this.value, oldVal);
}

/** @private */
__isValidByStep(value) {
Copy link
Member

@tomivirkki tomivirkki Nov 18, 2021

Choose a reason for hiding this comment

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

Something fishy about the validation. With the following:
<vaadin-number-field label="Required" required step="0.3"></vaadin-number-field>
if I focus the field and hit up arrow 3 times so that the value is 0.9, the field becomes invalid when blurred.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks, I will add tests for fractional steps.

Copy link
Member Author

Choose a reason for hiding this comment

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

@tomivirkki Fixed, and added validate() calls to existing tests for problematic values.

Copy link
Member

Choose a reason for hiding this comment

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

The following number field still claims to be invalid if I change the value with arrow keys:
<vaadin-number-field min="1" step="0.3"></vaadin-number-field>

@tomivirkki
Copy link
Member

Since BigDecimalField sets the decimal separator (for the <vaadin-big-decimal-field>) based on the locale, we should eventually have the same logic in NumberField also. That would require an API for explicitly setting the decimal separator to the <vaadin-number-field> as well. Not sure if it's better to do it as part of this PR or in a separate feat PR.

@web-padawan
Copy link
Member Author

That would require an API for explicitly setting the decimal separator to the as well.

Created an issue to handle it separately for the sake of cleaner release notes: #3096

@web-padawan
Copy link
Member Author

We might want to change isAndroid and isIPhone helpers to make them functions to make using stubs possible.
However, if we decide to do that, let's refactor corresponding code separately as it will affect several packages.


/**
* Handle problematic values when calculating a remainder.
* Source: Source: https://stackoverflow.com/a/31711034
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* Source: Source: https://stackoverflow.com/a/31711034
* Source: https://stackoverflow.com/a/31711034

) {
return this.inputElement.checkValidity();
if (this.value == null || this.value == '') {
Copy link
Member

Choose a reason for hiding this comment

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

The input value should be sanitized so that the field wouldn't get a non-numeric value and the validation works as expected:

With the following
<vaadin-number-field step="0.5"></vaadin-number-field>

typed value field value invalid
"0.5" "0.5" false
"0,5" "0,5" true
".5" ".5" false
",5" "" false
"1-" "1-" true

Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like there are some assumptions about localization in this table. For me 0,5 is certainly a valid value. Same for ,5, which results in an input value of 0.5, when comparing the behaviour with a native number input in Firefox.

Copy link
Member

@tomivirkki tomivirkki Nov 23, 2021

Choose a reason for hiding this comment

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

Clarification: The table represent how the current revision of the PR works

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks, I will update the validation logic to cover values with , separator.

type: Number,
value: 1,
observer: '_stepChanged'
type: Number
}
};
Copy link
Member

Choose a reason for hiding this comment

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

Let's use _enabledCharPattern in number field also to prevent user from typing arbitrary characters.

) {
return this.inputElement.checkValidity();
if (this.value == null || this.value == '') {
Copy link
Member

Choose a reason for hiding this comment

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

Seems I can programmatically set a non-numeric value for the field as long as the value starts with a number:
Screenshot 2021-11-23 at 12 17 07

Copy link
Contributor

@sissbruecker sissbruecker left a comment

Choose a reason for hiding this comment

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

I'm not very enthusiastic about the keyboard layout detection feature. It looks brittle, and neither of the linked tickets are about implementing such a feature.

Also the main issue of the first ticket (#1169) is that preventing invalid inputs should work consistently between browsers, which isn't addressed at all here.

packages/number-field/src/vaadin-number-field.js Outdated Show resolved Hide resolved
packages/number-field/src/vaadin-number-field.js Outdated Show resolved Hide resolved
return super.checkValidity();
} else {
// Mimic validation logic provided by native `<input type="number">` as we don't use it.
return !(this.value > this.max || this.value < this.min || !this.__isValidByStep(this.value));
Copy link
Contributor

Choose a reason for hiding this comment

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

This does not cover the native input validation logic regarding localization. Setting a min of 1.5 and entering a value of 1,3, which is an internal value of 1.3, does not mark the input invalid.

Also value is still a string, while min and max are numbers, which indicates an implicit type coersion in the comparison. Value should be parsed to a number instead, which of course requires us to take the users locale into account.

I also could not find any tests regarding this validation. I assume the previous version relied on the fact that the browser implemented this check. Now that we are doing this on our own we would need tests to cover it.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thank you for very valid points regarding the implementation. I will update the PR accordingly tomorrow.

@sonarcloud
Copy link

sonarcloud bot commented Nov 23, 2021

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
0.7% 0.7% Duplication

@web-padawan
Copy link
Member Author

Short summary from a meeting where we discussed the ticket that this PR is targeting:

  1. We agreed that this PR already took more time than originally planned and turned out to be complex. We knew that there are unknowns when taking it into progress.
  2. For now we close this PR as the research part is done. We keep the original ticket open but remove a11y label from it, as it’s not related to any TetraLogical issues and that’s where our focus should be.
  3. We use the new issue [number-field] Consider using input type="text" for number and integer fields #3102 as an epic to discuss all the aspects of switching number field to use input type="text".
  4. This change will not land in Vaadin 23 but we consider it an important improvement worth handling in Vaadin 24+, but it has to be planned accordingly before we can start working on it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants