Skip to content

Commit

Permalink
refactor!: return a marker string to help Flow identify bad input (#8413
Browse files Browse the repository at this point in the history
)
  • Loading branch information
vursen authored Dec 31, 2024
1 parent 10577e5 commit 8e8ce8a
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 34 deletions.
2 changes: 0 additions & 2 deletions packages/field-base/src/input-mixin.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,4 @@ export declare class InputMixinClass {
protected _toggleHasValue(hasValue: boolean): void;

protected _valueChanged(value?: string, oldValue?: string): void;

protected _setHasInputValue(event: InputEvent): void;
}
16 changes: 1 addition & 15 deletions packages/field-base/src/input-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ export const InputMixin = dedupingMixin(
* @private
*/
__onInput(event) {
this._setHasInputValue(event);
this._hasInputValue = !!this._inputElementValue;
this._onInput(event);
}

Expand Down Expand Up @@ -267,19 +267,5 @@ export const InputMixin = dedupingMixin(
// Setting a value programmatically, sync it to input element.
this._forwardInputValue(newVal);
}

/**
* Sets the `_hasInputValue` property based on the `input` event.
*
* @param {InputEvent} event
* @protected
*/
_setHasInputValue(event) {
// In the case a custom web component is passed as `inputElement`,
// the actual native input element, on which the event occurred,
// can be inside shadow trees.
const target = event.composedPath()[0];
this._hasInputValue = target.value.length > 0;
}
},
);
41 changes: 24 additions & 17 deletions packages/number-field/src/vaadin-number-field-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ import { InputController } from '@vaadin/field-base/src/input-controller.js';
import { InputFieldMixin } from '@vaadin/field-base/src/input-field-mixin.js';
import { LabelledInputController } from '@vaadin/field-base/src/labelled-input-controller.js';

// [type=number] value returns an empty string for invalid numbers,
// while valueAsNumber returns NaN for empty strings, which makes
// invalid and empty values indistinguishable. It's only possible
// to detect unparsable input by checking the validity.badInput
// boolean property. This string is used in _inputElementValue
// as a marker to help Flow detect and clear unparsable values
// through that property.
const BAD_INPUT_STRING = 'NaN';

/**
* A mixin providing common number field functionality.
*
Expand Down Expand Up @@ -111,7 +120,7 @@ export const NumberFieldMixin = (superClass) =>
* @private
*/
get __hasUnparsableValue() {
return this.inputElement.validity.badInput;
return this._inputElementValue === BAD_INPUT_STRING;
}

/** @protected */
Expand Down Expand Up @@ -405,22 +414,6 @@ export const NumberFieldMixin = (superClass) =>
super._onKeyDown(event);
}

/**
* Native [type=number] inputs don't update their value
* when you are entering input that the browser is unable to parse
* e.g. "--5", hence we have to override this method from `InputMixin`
* so that, when value is empty, it would additionally check
* for bad input based on the native `validity.badInput` property.
*
* @param {InputEvent} event
* @protected
* @override
*/
_setHasInputValue(event) {
const target = event.composedPath()[0];
this._hasInputValue = target.value.length > 0 || this.__hasUnparsableValue;
}

/**
* Override this method from `InputMixin` to prevent
* the value change caused by user input from being treated
Expand Down Expand Up @@ -527,4 +520,18 @@ export const NumberFieldMixin = (superClass) =>
this.__committedValue = this.value;
this.__committedUnparsableValueStatus = this.__hasUnparsableValue;
}

/** @override */
get _inputElementValue() {
if (this.inputElement && this.inputElement.validity.badInput) {
return BAD_INPUT_STRING;
}

return super._inputElementValue;
}

/** @override */
set _inputElementValue(value) {
super._inputElementValue = value;
}
};

0 comments on commit 8e8ce8a

Please # to comment.