@vaadin/field-base
Advanced tools
Comparing version 22.0.0-alpha1 to 22.0.0-alpha2
@@ -0,1 +1,3 @@ | ||
export { AriaLabelMixin } from './src/aria-label-mixin.js'; | ||
export { CharLengthMixin } from './src/char-length-mixin.js'; | ||
export { ClearButtonMixin } from './src/clear-button-mixin.js'; | ||
@@ -6,10 +8,12 @@ export { DelegateFocusMixin } from './src/delegate-focus-mixin.js'; | ||
export { FocusMixin } from './src/focus-mixin.js'; | ||
export { ForwardInputPropsMixin } from './src/forward-input-props-mixin.js'; | ||
export { HelperTextMixin } from './src/helper-text-mixin.js'; | ||
export { InputAriaMixin } from './src/input-aria-mixin.js'; | ||
export { InputFieldMixin } from './src/input-field-mixin.js'; | ||
export { InputMixin } from './src/input-mixin.js'; | ||
export { InputPropsMixin } from './src/input-props-mixin.js'; | ||
export { InputSlotMixin } from './src/input-slot-mixin.js'; | ||
export { LabelMixin } from './src/label-mixin.js'; | ||
export { PatternMixin } from './src/pattern-mixin.js'; | ||
export { SlotMixin } from './src/slot-mixin.js'; | ||
export { TextAreaSlotMixin } from './src/text-area-slot-mixin.js'; | ||
export { TextFieldMixin } from './src/text-field-mixin.js'; | ||
export { ValidateMixin } from './src/validate-mixin.js'; |
@@ -0,1 +1,3 @@ | ||
export { AriaLabelMixin } from './src/aria-label-mixin.js'; | ||
export { CharLengthMixin } from './src/char-length-mixin.js'; | ||
export { ClearButtonMixin } from './src/clear-button-mixin.js'; | ||
@@ -6,10 +8,12 @@ export { DelegateFocusMixin } from './src/delegate-focus-mixin.js'; | ||
export { FocusMixin } from './src/focus-mixin.js'; | ||
export { ForwardInputPropsMixin } from './src/forward-input-props-mixin.js'; | ||
export { HelperTextMixin } from './src/helper-text-mixin.js'; | ||
export { InputAriaMixin } from './src/input-aria-mixin.js'; | ||
export { InputFieldMixin } from './src/input-field-mixin.js'; | ||
export { InputMixin } from './src/input-mixin.js'; | ||
export { InputPropsMixin } from './src/input-props-mixin.js'; | ||
export { InputSlotMixin } from './src/input-slot-mixin.js'; | ||
export { LabelMixin } from './src/label-mixin.js'; | ||
export { PatternMixin } from './src/pattern-mixin.js'; | ||
export { SlotMixin } from './src/slot-mixin.js'; | ||
export { TextAreaSlotMixin } from './src/text-area-slot-mixin.js'; | ||
export { TextFieldMixin } from './src/text-field-mixin.js'; | ||
export { ValidateMixin } from './src/validate-mixin.js'; |
{ | ||
"name": "@vaadin/field-base", | ||
"version": "22.0.0-alpha1", | ||
"version": "22.0.0-alpha2", | ||
"description": "Vaadin field base mixins", | ||
@@ -28,3 +28,3 @@ "main": "index.js", | ||
"devDependencies": { | ||
"@esm-bundle/chai": "^4.1.5", | ||
"@esm-bundle/chai": "^4.3.4", | ||
"@vaadin/testing-helpers": "^0.2.1", | ||
@@ -36,3 +36,3 @@ "sinon": "^9.2.1" | ||
}, | ||
"gitHead": "c9694d6549bff1f7fffb9ece26178e57fc228a51" | ||
"gitHead": "179d38f5146be752853ea4b7997b1446a2ab1fd4" | ||
} |
@@ -24,7 +24,2 @@ /** | ||
/** | ||
* Clear the value of this field. | ||
*/ | ||
clear(): void; | ||
readonly _clearOnEsc: boolean; | ||
@@ -31,0 +26,0 @@ } |
@@ -53,9 +53,2 @@ /** | ||
/** | ||
* Clear the value of this field. | ||
*/ | ||
clear() { | ||
this.value = this._inputNode.value = ''; | ||
} | ||
/** | ||
* @param {Event} event | ||
@@ -66,6 +59,6 @@ * @protected | ||
event.preventDefault(); | ||
this._inputNode.focus(); | ||
this.inputElement.focus(); | ||
this.clear(); | ||
this._inputNode.dispatchEvent(new Event('input', { bubbles: true, composed: true })); | ||
this._inputNode.dispatchEvent(new Event('change', { bubbles: true })); | ||
this.inputElement.dispatchEvent(new Event('input', { bubbles: true, composed: true })); | ||
this.inputElement.dispatchEvent(new Event('change', { bubbles: true })); | ||
} | ||
@@ -81,3 +74,3 @@ | ||
this.clear(); | ||
dispatchChange && this._inputNode.dispatchEvent(new Event('change', { bubbles: true })); | ||
dispatchChange && this.inputElement.dispatchEvent(new Event('change', { bubbles: true })); | ||
} | ||
@@ -84,0 +77,0 @@ } |
@@ -6,6 +6,7 @@ /** | ||
*/ | ||
import { AriaLabelMixin } from './aria-label-mixin.js'; | ||
import { ClearButtonMixin } from './clear-button-mixin.js'; | ||
import { DelegateFocusMixin } from './delegate-focus-mixin.js'; | ||
import { FieldAriaMixin } from './field-aria-mixin.js'; | ||
import { InputPropsMixin } from './input-props-mixin.js'; | ||
import { ForwardInputPropsMixin } from './forward-input-props-mixin.js'; | ||
@@ -21,5 +22,8 @@ /** | ||
interface InputFieldMixin extends ClearButtonMixin, DelegateFocusMixin, FieldAriaMixin, InputPropsMixin { | ||
readonly inputElement: HTMLElement | undefined; | ||
interface InputFieldMixin | ||
extends AriaLabelMixin, | ||
ClearButtonMixin, | ||
DelegateFocusMixin, | ||
FieldAriaMixin, | ||
ForwardInputPropsMixin { | ||
/** | ||
@@ -56,14 +60,4 @@ * Whether the value of the control can be automatically completed by the browser. | ||
autoselect: boolean; | ||
/** | ||
* The value of the field. | ||
*/ | ||
value: string; | ||
/** | ||
* Returns true if the current input value satisfies all constraints (if any). | ||
*/ | ||
checkValidity(): boolean; | ||
} | ||
export { InputFieldMixin, InputFieldMixinConstructor }; |
@@ -9,9 +9,12 @@ /** | ||
import { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js'; | ||
import { AriaLabelMixin } from './aria-label-mixin.js'; | ||
import { ClearButtonMixin } from './clear-button-mixin.js'; | ||
import { DelegateFocusMixin } from './delegate-focus-mixin.js'; | ||
import { FieldAriaMixin } from './field-aria-mixin.js'; | ||
import { InputPropsMixin } from './input-props-mixin.js'; | ||
import { ForwardInputPropsMixin } from './forward-input-props-mixin.js'; | ||
const InputFieldMixinImplementation = (superclass) => | ||
class InputFieldMixinClass extends ClearButtonMixin(FieldAriaMixin(InputPropsMixin(DelegateFocusMixin(superclass)))) { | ||
class InputFieldMixinClass extends ClearButtonMixin( | ||
FieldAriaMixin(ForwardInputPropsMixin(AriaLabelMixin(DelegateFocusMixin(superclass)))) | ||
) { | ||
static get properties() { | ||
@@ -58,12 +61,2 @@ return { | ||
value: false | ||
}, | ||
/** | ||
* The value of the field. | ||
*/ | ||
value: { | ||
type: String, | ||
value: '', | ||
observer: '_valueChanged', | ||
notify: true | ||
} | ||
@@ -73,4 +66,4 @@ }; | ||
static get hostProps() { | ||
return [...super.hostProps, 'autocapitalize', 'autocomplete', 'autocorrect']; | ||
static get forwardProps() { | ||
return [...super.forwardProps, 'autocapitalize', 'autocomplete', 'autocorrect']; | ||
} | ||
@@ -87,3 +80,3 @@ | ||
get _ariaTarget() { | ||
return this._inputNode; | ||
return this.inputElement; | ||
} | ||
@@ -96,3 +89,3 @@ | ||
get focusElement() { | ||
return this._inputNode; | ||
return this.inputElement; | ||
} | ||
@@ -103,3 +96,2 @@ | ||
this._boundOnInput = this._onInput.bind(this); | ||
this._boundOnBlur = this._onBlur.bind(this); | ||
@@ -113,14 +105,11 @@ this._boundOnFocus = this._onFocus.bind(this); | ||
if (this._inputNode) { | ||
this._addInputListeners(this._inputNode); | ||
if (this.inputElement) { | ||
// Discard value set on the custom slotted input. | ||
if (this._inputNode.value !== this.value) { | ||
if (this.inputElement.value && this.inputElement.value !== this.value) { | ||
console.warn(`Please define value on the <${this.localName}> component!`); | ||
this._inputNode.value = ''; | ||
this.inputElement.value = ''; | ||
} | ||
if (this.value) { | ||
this._inputNode.value = this.value; | ||
this.validate(); | ||
this.inputElement.value = this.value; | ||
} | ||
@@ -131,11 +120,2 @@ } | ||
/** @protected */ | ||
disconnectedCallback() { | ||
super.disconnectedCallback(); | ||
if (this._inputNode) { | ||
this._removeInputListeners(this._inputNode); | ||
} | ||
} | ||
/** @protected */ | ||
ready() { | ||
@@ -154,14 +134,2 @@ super.ready(); | ||
/** | ||
* Returns true if the current input value satisfies all constraints (if any). | ||
* @return {boolean} | ||
*/ | ||
checkValidity() { | ||
if (this.required) { | ||
return this._inputNode ? this._inputNode.checkValidity() : undefined; | ||
} else { | ||
return !this.invalid; | ||
} | ||
} | ||
// Workaround for https://github.com/Polymer/polymer/issues/5259 | ||
@@ -177,19 +145,21 @@ get __data() { | ||
/** | ||
* @param {HTMLElement} node | ||
* @param {HTMLInputElement} input | ||
* @protected | ||
*/ | ||
_addInputListeners(node) { | ||
node.addEventListener('input', this._boundOnInput); | ||
node.addEventListener('blur', this._boundOnBlur); | ||
node.addEventListener('focus', this._boundOnFocus); | ||
_addInputListeners(input) { | ||
super._addInputListeners(input); | ||
input.addEventListener('blur', this._boundOnBlur); | ||
input.addEventListener('focus', this._boundOnFocus); | ||
} | ||
/** | ||
* @param {HTMLElement} node | ||
* @param {HTMLInputElement} input | ||
* @protected | ||
*/ | ||
_removeInputListeners(node) { | ||
node.removeEventListener('input', this._boundOnInput); | ||
node.removeEventListener('blur', this._boundOnBlur); | ||
node.removeEventListener('focus', this._boundOnFocus); | ||
_removeInputListeners(input) { | ||
super._addInputListeners(input); | ||
input.removeEventListener('blur', this._boundOnBlur); | ||
input.removeEventListener('focus', this._boundOnFocus); | ||
} | ||
@@ -199,4 +169,4 @@ | ||
_onFocus() { | ||
if (this.autoselect && this._inputNode) { | ||
this._inputNode.select(); | ||
if (this.autoselect && this.inputElement) { | ||
this.inputElement.select(); | ||
} | ||
@@ -211,13 +181,2 @@ } | ||
/** | ||
* @param {Event} event | ||
* @protected | ||
*/ | ||
_onInput(event) { | ||
// Ignore manual clear button events | ||
this.__userInput = event.isTrusted; | ||
this.value = event.target.value; | ||
this.__userInput = false; | ||
} | ||
/** | ||
* Dispatch an event if a specific size measurement property has changed. | ||
@@ -248,38 +207,11 @@ * Supporting multiple properties here is needed for `vaadin-text-area`. | ||
/** | ||
* @param {unknown} newVal | ||
* @param {unknown} oldVal | ||
* Override a method from `InputMixin` to validate the field | ||
* when a new value is set programmatically. | ||
* @param {string} value | ||
* @protected | ||
* @override | ||
*/ | ||
_valueChanged(newVal, oldVal) { | ||
// Setting initial value to empty string, skip validation | ||
if (newVal === '' && oldVal === undefined) { | ||
return; | ||
} | ||
_forwardInputValue(value) { | ||
super._forwardInputValue(value); | ||
if (newVal !== '' && newVal != null) { | ||
this.setAttribute('has-value', ''); | ||
} else { | ||
this.removeAttribute('has-value'); | ||
} | ||
// Value is set before an element is connected to the DOM: | ||
// this case is handled separately in `connectedCallback`. | ||
if (!this._inputNode) { | ||
return; | ||
} | ||
// Value is set by the user, no need to sync it back to input. | ||
// Also no need to validate, as we call `validate` on blur. | ||
if (this.__userInput) { | ||
return; | ||
} | ||
// Setting a value programmatically, sync it to input element. | ||
if (newVal != undefined) { | ||
this._inputNode.value = newVal; | ||
} else { | ||
this.clear(); | ||
} | ||
// Validate the field after a new value is set programmatically. | ||
if (this.invalid) { | ||
@@ -286,0 +218,0 @@ this.validate(); |
@@ -6,6 +6,6 @@ /** | ||
*/ | ||
import { SlotMixin } from './slot-mixin.js'; | ||
/** | ||
* A mixin to add `<input>` element to the corresponding named slot. | ||
* A mixin to store the reference to an input element | ||
* and add input and change event listeners to it. | ||
*/ | ||
@@ -18,9 +18,25 @@ declare function InputMixin<T extends new (...args: any[]) => {}>(base: T): T & InputMixinConstructor; | ||
interface InputMixin extends SlotMixin { | ||
interface InputMixin { | ||
/** | ||
* String used to define input type. | ||
* A reference to the input element controlled by the mixin. | ||
* Any component implementing this mixin is expected to provide it | ||
* by using `this._setInputElement(input)` Polymer API. | ||
* | ||
* A typical case is using `InputSlotMixin` that does this automatically. | ||
* However, the input element does not have to always be native <input>: | ||
* as an example, <vaadin-combo-box-light> accepts other components. | ||
*/ | ||
readonly type: string; | ||
readonly inputElement: HTMLInputElement; | ||
/** | ||
* The value of the field. | ||
*/ | ||
value: string; | ||
/** | ||
* Clear the value of the field. | ||
*/ | ||
clear(): void; | ||
} | ||
export { InputMixinConstructor, InputMixin }; | ||
export { InputMixin, InputMixinConstructor }; |
@@ -7,14 +7,33 @@ /** | ||
import { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js'; | ||
import { SlotMixin } from './slot-mixin.js'; | ||
const InputMixinImplementation = (superclass) => | ||
class InputMixinClass extends SlotMixin(superclass) { | ||
class InputMixinClass extends superclass { | ||
static get properties() { | ||
/** | ||
* String used to define input type. | ||
*/ | ||
return { | ||
type: { | ||
/** | ||
* A reference to the input element controlled by the mixin. | ||
* Any component implementing this mixin is expected to provide it | ||
* by using `this._setInputElement(input)` Polymer API. | ||
* | ||
* A typical case is using `InputSlotMixin` that does this automatically. | ||
* However, the input element does not have to always be native <input>: | ||
* as an example, <vaadin-combo-box-light> accepts other components. | ||
* | ||
* @protected | ||
* @type {!HTMLElement} | ||
*/ | ||
inputElement: { | ||
type: Object, | ||
readOnly: true, | ||
observer: '_inputElementChanged' | ||
}, | ||
/** | ||
* The value of the field. | ||
*/ | ||
value: { | ||
type: String, | ||
readOnly: true | ||
value: '', | ||
observer: '_valueChanged', | ||
notify: true | ||
} | ||
@@ -24,43 +43,122 @@ }; | ||
get slots() { | ||
return { | ||
...super.slots, | ||
input: () => { | ||
const native = document.createElement('input'); | ||
const value = this.getAttribute('value'); | ||
if (value) { | ||
native.setAttribute('value', value); | ||
} | ||
const name = this.getAttribute('name'); | ||
if (name) { | ||
native.setAttribute('name', name); | ||
} | ||
if (this.type) { | ||
native.setAttribute('type', this.type); | ||
} | ||
return native; | ||
} | ||
}; | ||
constructor() { | ||
super(); | ||
this._boundOnInput = this._onInput.bind(this); | ||
this._boundOnChange = this._onChange.bind(this); | ||
} | ||
/** @protected */ | ||
get _inputNode() { | ||
return this._getDirectSlotChild('input'); | ||
/** | ||
* Clear the value of the field. | ||
*/ | ||
clear() { | ||
this.value = ''; | ||
} | ||
constructor() { | ||
super(); | ||
/** | ||
* Add event listeners to the input element instance. | ||
* Override this method to add custom listeners. | ||
* @param {!HTMLElement} input | ||
*/ | ||
_addInputListeners(input) { | ||
input.addEventListener('input', this._boundOnInput); | ||
input.addEventListener('change', this._boundOnChange); | ||
} | ||
// Ensure every instance has unique ID | ||
const uniqueId = (InputMixinClass._uniqueId = 1 + InputMixinClass._uniqueId || 0); | ||
this._inputId = `${this.localName}-${uniqueId}`; | ||
/** | ||
* Remove event listeners from the input element instance. | ||
* @param {!HTMLElement} input | ||
*/ | ||
_removeInputListeners(input) { | ||
input.removeEventListener('input', this._boundOnInput); | ||
input.removeEventListener('change', this._boundOnChange); | ||
} | ||
/** | ||
* A method to forward the value property set on the field | ||
* programmatically back to the input element value. | ||
* Override this method to perform additional checks, | ||
* for example to skip this in certain conditions. | ||
* @param {string} value | ||
* @protected | ||
* @override | ||
*/ | ||
_forwardInputValue(value) { | ||
// Value might be set before an input element is initialized. | ||
// This case should be handled separately by a component that | ||
// implements this mixin, for example in `connectedCallback`. | ||
if (!this.inputElement) { | ||
return; | ||
} | ||
if (value != undefined) { | ||
this.inputElement.value = value; | ||
} else { | ||
this.inputElement.value = ''; | ||
} | ||
} | ||
/** @protected */ | ||
connectedCallback() { | ||
super.connectedCallback(); | ||
_inputElementChanged(input, oldInput) { | ||
if (input) { | ||
this._addInputListeners(input); | ||
} else if (oldInput) { | ||
this._removeInputListeners(oldInput); | ||
} | ||
} | ||
if (this._inputNode) { | ||
this._inputNode.id = this._inputId; | ||
/** | ||
* An input event listener used to update the field value. | ||
* Override this method with an actual implementation. | ||
* @param {Event} _event | ||
* @protected | ||
* @override | ||
*/ | ||
_onInput(event) { | ||
// Ignore fake input events e.g. used by clear button. | ||
this.__userInput = event.isTrusted; | ||
this.value = event.target.value; | ||
this.__userInput = false; | ||
} | ||
/** | ||
* A change event listener. | ||
* Override this method with an actual implementation. | ||
* @param {Event} _event | ||
* @protected | ||
* @override | ||
*/ | ||
_onChange(_event) {} | ||
/** | ||
* Toggle the has-value attribute based on the value property. | ||
* @param {boolean} hasValue | ||
* @protected | ||
*/ | ||
_toggleHasValue(hasValue) { | ||
this.toggleAttribute('has-value', hasValue); | ||
} | ||
/** | ||
* Observer called when a value property changes. | ||
* @param {string | undefined} newVal | ||
* @param {string | undefined} oldVal | ||
* @protected | ||
* @override | ||
*/ | ||
_valueChanged(newVal, oldVal) { | ||
this._toggleHasValue(newVal !== '' && newVal != null); | ||
// Setting initial value to empty string, do nothing. | ||
if (newVal === '' && oldVal === undefined) { | ||
return; | ||
} | ||
// Value is set by the user, no need to sync it back to input. | ||
if (this.__userInput) { | ||
return; | ||
} | ||
// Setting a value programmatically, sync it to input element. | ||
this._forwardInputValue(newVal); | ||
} | ||
@@ -70,4 +168,5 @@ }; | ||
/** | ||
* A mixin to add `<input>` element to the corresponding named slot. | ||
* A mixin to store the reference to an input element | ||
* and add input and change event listeners to it. | ||
*/ | ||
export const InputMixin = dedupingMixin(InputMixinImplementation); |
@@ -6,3 +6,5 @@ /** | ||
*/ | ||
import { CharLengthMixin } from './char-length-mixin.js'; | ||
import { InputFieldMixin } from './input-field-mixin.js'; | ||
import { PatternMixin } from './pattern-mixin.js'; | ||
@@ -18,32 +20,4 @@ /** | ||
interface TextFieldMixin extends InputFieldMixin { | ||
/** | ||
* Maximum number of characters (in Unicode code points) that the user can enter. | ||
*/ | ||
maxlength: number | null | undefined; | ||
interface TextFieldMixin extends CharLengthMixin, InputFieldMixin, PatternMixin {} | ||
/** | ||
* Minimum number of characters (in Unicode code points) that the user can enter. | ||
*/ | ||
minlength: number | null | undefined; | ||
/** | ||
* A regular expression that the value is checked against. | ||
* The pattern must match the entire value, not just some subset. | ||
*/ | ||
pattern: string | null | undefined; | ||
/** | ||
* When set to true, user is prevented from typing a value that | ||
* conflicts with the given `pattern`. | ||
* @attr {boolean} prevent-invalid-input | ||
*/ | ||
preventInvalidInput: boolean | null | undefined; | ||
/** | ||
* Returns true if the current input value satisfies all constraints (if any). | ||
*/ | ||
checkValidity(): boolean; | ||
} | ||
export { TextFieldMixin, TextFieldMixinConstructor }; |
@@ -6,118 +6,10 @@ /** | ||
*/ | ||
import { Debouncer } from '@polymer/polymer/lib/utils/debounce.js'; | ||
import { timeOut } from '@polymer/polymer/lib/utils/async.js'; | ||
import { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js'; | ||
import { CharLengthMixin } from './char-length-mixin.js'; | ||
import { InputFieldMixin } from './input-field-mixin.js'; | ||
import { PatternMixin } from './pattern-mixin.js'; | ||
const TextFieldMixinImplementation = (superclass) => | ||
class TextFieldMixinClass extends InputFieldMixin(superclass) { | ||
static get properties() { | ||
return { | ||
/** | ||
* Maximum number of characters (in Unicode code points) that the user can enter. | ||
*/ | ||
maxlength: { | ||
type: Number | ||
}, | ||
class TextFieldMixinClass extends InputFieldMixin(CharLengthMixin(PatternMixin(superclass))) {}; | ||
/** | ||
* Minimum number of characters (in Unicode code points) that the user can enter. | ||
*/ | ||
minlength: { | ||
type: Number | ||
}, | ||
/** | ||
* A regular expression that the value is checked against. | ||
* The pattern must match the entire value, not just some subset. | ||
*/ | ||
pattern: { | ||
type: String | ||
}, | ||
/** | ||
* When set to true, user is prevented from typing a value that | ||
* conflicts with the given `pattern`. | ||
* @attr {boolean} prevent-invalid-input | ||
*/ | ||
preventInvalidInput: { | ||
type: Boolean | ||
} | ||
}; | ||
} | ||
static get hostProps() { | ||
return [...super.hostProps, 'pattern', 'maxlength', 'minlength']; | ||
} | ||
/** @protected */ | ||
ready() { | ||
super.ready(); | ||
this._createConstraintsObserver(); | ||
} | ||
/** @protected */ | ||
_createConstraintsObserver() { | ||
// This complex observer needs to be added dynamically instead of using `static get observers()` | ||
// to make it possible to tweak this behavior in classes that apply this mixin. | ||
// An example is `vaadin-email-field` where the pattern is set before defining the observer. | ||
this._createMethodObserver('_constraintsChanged(required, minlength, maxlength, pattern)'); | ||
} | ||
/** | ||
* @param {boolean | undefined} required | ||
* @param {number | undefined} minlength | ||
* @param {number | undefined} maxlength | ||
* @param {string | undefined} maxlength | ||
* @protected | ||
*/ | ||
_constraintsChanged(required, minlength, maxlength, pattern) { | ||
// Prevent marking field as invalid when setting required state | ||
// or any other constraint before a user has entered the value. | ||
if (!this.invalid) { | ||
return; | ||
} | ||
if (!required && !minlength && !maxlength && !pattern) { | ||
this.invalid = false; | ||
} else { | ||
this.validate(); | ||
} | ||
} | ||
/** | ||
* @param {Event} e | ||
* @protected | ||
*/ | ||
_onInput(e) { | ||
if (this.preventInvalidInput) { | ||
const input = this._inputNode; | ||
if (input && input.value.length > 0 && !this.checkValidity()) { | ||
input.value = this.value || ''; | ||
// add input-prevented attribute for 200ms | ||
this.setAttribute('input-prevented', ''); | ||
this._inputDebouncer = Debouncer.debounce(this._inputDebouncer, timeOut.after(200), () => { | ||
this.removeAttribute('input-prevented'); | ||
}); | ||
return; | ||
} | ||
} | ||
super._onInput(e); | ||
} | ||
/** | ||
* Returns true if the current input value satisfies all constraints (if any) | ||
* @return {boolean} | ||
*/ | ||
checkValidity() { | ||
if (this.required || this.pattern || this.maxlength || this.minlength) { | ||
return this._inputNode ? this._inputNode.checkValidity() : undefined; | ||
} else { | ||
return !this.invalid; | ||
} | ||
} | ||
}; | ||
/** | ||
@@ -124,0 +16,0 @@ * A mixin to provide validation constraints for vaadin-text-field and related components. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
79987
45
2043