Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@vaadin/field-base

Package Overview
Dependencies
Maintainers
19
Versions
412
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@vaadin/field-base - npm Package Compare versions

Comparing version 22.0.0-alpha1 to 22.0.0-alpha2

src/active-mixin.d.ts

8

index.d.ts

@@ -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.

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc