Socket
Socket
Sign inDemoInstall

@lion/field

Package Overview
Dependencies
Maintainers
1
Versions
103
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@lion/field - npm Package Compare versions

Comparing version 0.3.7 to 0.4.0

11

CHANGELOG.md

@@ -6,2 +6,13 @@ # Change Log

# [0.4.0](https://github.com/ing-bank/lion/compare/@lion/field@0.3.7...@lion/field@0.4.0) (2019-11-13)
### Features
* remove all deprecations from lion ([66d3d39](https://github.com/ing-bank/lion/commit/66d3d390aebeaa61b6effdea7d5f7eea0e89c894))
## [0.3.7](https://github.com/ing-bank/lion/compare/@lion/field@0.3.6...@lion/field@0.3.7) (2019-11-06)

@@ -8,0 +19,0 @@

6

docs/CustomFieldsTutorial.md

@@ -64,3 +64,3 @@ # Creating a custom field

_proxyChangeEvent() {
this.inputElement.dispatchEvent(
this._inputNode.dispatchEvent(
new CustomEvent('user-input-changed', { bubbles: true, composed: true }),

@@ -72,7 +72,7 @@ );

get value() {
   return this.$$slot('input').mySliderValue;
   return this.querySelector('[slot=input]').mySliderValue;
}
set value(newV) {
   this.$$slot('input').mySliderValue = newV;
   this.querySelector('[slot=input]').mySliderValue = newV;
}

@@ -79,0 +79,0 @@ }

@@ -25,3 +25,3 @@ # FormatMixin

It will be stored as `.formattedValue` and synchronized to `.value` (a viewValue setter that
allows to synchronize to `.inputElement`).
allows to synchronize to `._inputNode`).
Synchronization happens conditionally and is (by default) the result of a blur. Other conditions

@@ -49,3 +49,3 @@ (like error state/validity and whether the a model value was set programatically) also play a role.

When no parser is available, the value is usually the same as the formattedValue (being inputElement.value)
When no parser is available, the value is usually the same as the formattedValue (being \_inputNode.value)

@@ -52,0 +52,0 @@ ## Formatters, parsers and (de)serializers

@@ -24,3 +24,3 @@ # Formatting and parsing

The view value is the result of the formatter function (when available).
The result will be stored in the native inputElement (usually an input[type=text]).
The result will be stored in the native \_inputNode (usually an input[type=text]).

@@ -46,3 +46,3 @@ Examples:

When no parser is available, the value is usually the same as the formattedValue (being inputElement.value)
When no parser is available, the value is usually the same as the formattedValue (being \_inputNode.value)

@@ -49,0 +49,0 @@ ## Formatters, parsers and (de)serializers

{
"name": "@lion/field",
"version": "0.3.7",
"version": "0.4.0",
"description": "Fields are the most fundamental building block of the Form System",

@@ -36,7 +36,7 @@ "author": "ing-bank",

"dependencies": {
"@lion/core": "^0.2.1",
"@lion/validate": "^0.2.40"
"@lion/core": "^0.3.0",
"@lion/validate": "^0.3.0"
},
"devDependencies": {
"@lion/localize": "^0.4.21",
"@lion/localize": "^0.5.0",
"@open-wc/demoing-storybook": "^0.2.0",

@@ -46,3 +46,3 @@ "@open-wc/testing": "^2.3.4",

},
"gitHead": "564a90dad1243cf124bada9d22cafea078328cd2"
"gitHead": "90e6b4ef36bb5c49cfe7e4b2b8a00128334c84ab"
}

@@ -36,3 +36,3 @@ import { dedupeMixin } from '@lion/core';

focus() {
const native = this.inputElement;
const native = this._inputNode;
if (native) {

@@ -44,3 +44,3 @@ native.focus();

blur() {
const native = this.inputElement;
const native = this._inputNode;
if (native) {

@@ -51,30 +51,12 @@ native.blur();

updated(changedProperties) {
super.updated(changedProperties);
// 'state-focused' css classes are deprecated
if (changedProperties.has('focused')) {
this.classList[this.focused ? 'add' : 'remove']('state-focused');
__onFocus() {
if (super.__onFocus) {
super.__onFocus();
}
}
/**
* Functions should be private
*
* @deprecated
*/
_onFocus() {
if (super._onFocus) {
super._onFocus();
}
this.focused = true;
}
/**
* Functions should be private
*
* @deprecated
*/
_onBlur() {
if (super._onBlur) {
super._onBlur();
__onBlur() {
if (super.__onBlur) {
super.__onBlur();
}

@@ -90,3 +72,3 @@ this.focused = false;

};
this.inputElement.addEventListener('focus', this.__redispatchFocus);
this._inputNode.addEventListener('focus', this.__redispatchFocus);

@@ -98,3 +80,3 @@ // blur

};
this.inputElement.addEventListener('blur', this.__redispatchBlur);
this._inputNode.addEventListener('blur', this.__redispatchBlur);

@@ -104,6 +86,6 @@ // focusin

ev.stopPropagation();
this._onFocus(ev);
this.__onFocus(ev);
this.dispatchEvent(new Event('focusin', { bubbles: true, composed: true }));
};
this.inputElement.addEventListener('focusin', this.__redispatchFocusin);
this._inputNode.addEventListener('focusin', this.__redispatchFocusin);

@@ -113,15 +95,15 @@ // focusout

ev.stopPropagation();
this._onBlur();
this.__onBlur();
this.dispatchEvent(new Event('focusout', { bubbles: true, composed: true }));
};
this.inputElement.addEventListener('focusout', this.__redispatchFocusout);
this._inputNode.addEventListener('focusout', this.__redispatchFocusout);
}
__teardownEventsForFocusMixin() {
this.inputElement.removeEventListener('focus', this.__redispatchFocus);
this.inputElement.removeEventListener('blur', this.__redispatchBlur);
this.inputElement.removeEventListener('focusin', this.__redispatchFocusin);
this.inputElement.removeEventListener('focusout', this.__redispatchFocusout);
this._inputNode.removeEventListener('focus', this.__redispatchFocus);
this._inputNode.removeEventListener('blur', this.__redispatchBlur);
this._inputNode.removeEventListener('focusin', this.__redispatchFocusin);
this._inputNode.removeEventListener('focusout', this.__redispatchFocusout);
}
},
);

@@ -26,6 +26,6 @@ /* eslint-disable class-methods-use-this */

* [1] Application Developer sets `.modelValue`:
* Flow: `.modelValue` (formatter) -> `.formattedValue` -> `.inputElement.value`
* Flow: `.modelValue` (formatter) -> `.formattedValue` -> `._inputNode.value`
* (serializer) -> `.serializedValue`
* [2] End user interacts with field:
* Flow: `@user-input-changed` (parser) -> `.modelValue` (formatter) -> `.formattedValue` - (debounce till reflect condition (formatOn) is met) -> `.inputElement.value`
* Flow: `@user-input-changed` (parser) -> `.modelValue` (formatter) -> `.formattedValue` - (debounce till reflect condition (formatOn) is met) -> `._inputNode.value`
* (serializer) -> `.serializedValue`

@@ -44,7 +44,7 @@ *

* Another difference is that formattedValue lives on `LionField`, whereas viewValue is shared
* across `LionField` and `.inputElement`.
* across `LionField` and `._inputNode`.
*
* For restoring serialized values fetched from a server, we could consider one extra flow:
* [3] Application Developer sets `.serializedValue`:
* Flow: serializedValue (deserializer) -> `.modelValue` (formatter) -> `.formattedValue` -> `.inputElement.value`
* Flow: serializedValue (deserializer) -> `.modelValue` (formatter) -> `.formattedValue` -> `._inputNode.value`
*/

@@ -75,3 +75,3 @@ export const FormatMixin = dedupeMixin(

* The view value is the result of the formatter function (when available).
* The result will be stored in the native inputElement (usually an input[type=text]).
* The result will be stored in the native _inputNode (usually an input[type=text]).
*

@@ -101,3 +101,3 @@ * Examples:

* When no parser is available, the value is usually the same as the formattedValue
* (being inputElement.value)
* (being _inputNode.value)
*

@@ -134,12 +134,6 @@ */

if (name === 'serializedValue' && this.serializedValue !== oldVal) {
this._onSerializedValueChanged(
{ serializedValue: this.serializedValue },
{ serializedValue: oldVal },
);
this._calculateValues({ source: 'serialized' });
}
if (name === 'formattedValue' && this.formattedValue !== oldVal) {
this._onFormattedValueChanged(
{ formattedValue: this.formattedValue },
{ formattedValue: oldVal },
);
this._calculateValues({ source: 'formatted' });
}

@@ -160,3 +154,3 @@ }

* Converts modelValue to formattedValue (formattedValue will be synced with
* `.inputElement.value`)
* `._inputNode.value`)
* For instance, a Date object to a localized date.

@@ -239,3 +233,3 @@ * @param {Object} value - modelValue: can be an Object, Number, String depending on the

// A.2) Handle edge cases We might have no view value yet, for instance because
// inputElement.value was not available yet
// _inputNode.value was not available yet
if (typeof value !== 'string') {

@@ -270,6 +264,6 @@ // This means there is nothing to find inside the view that can be of

// imperatively, we DO want to format a value (it is the only way to get meaningful
// input into `.inputElement` with modelValue as input)
// input into `._inputNode` with modelValue as input)
if (this.__isHandlingUserInput && this.errorState && this.inputElement) {
return this.inputElement ? this.value : undefined;
if (this.__isHandlingUserInput && this.errorState && this._inputNode) {
return this._inputNode ? this.value : undefined;
}

@@ -304,26 +298,4 @@

_onFormattedValueChanged() {
/** @deprecated */
this.dispatchEvent(
new CustomEvent('formatted-value-changed', {
bubbles: true,
composed: true,
}),
);
this._calculateValues({ source: 'formatted' });
}
_onSerializedValueChanged() {
/** @deprecated */
this.dispatchEvent(
new CustomEvent('serialized-value-changed', {
bubbles: true,
composed: true,
}),
);
this._calculateValues({ source: 'serialized' });
}
/**
* Synchronization from `.inputElement.value` to `LionField` (flow [2])
* Synchronization from `._inputNode.value` to `LionField` (flow [2])
*/

@@ -338,3 +310,3 @@ _syncValueUpwards() {

/**
* Synchronization from `LionField.value` to `.inputElement.value`
* Synchronization from `LionField.value` to `._inputNode.value`
* - flow [1] will always be reflected back

@@ -383,3 +355,3 @@ * - flow [2] will not be reflected back when this flow was triggered via

this._reflectBackFormattedValueDebounced = () => {
// Make sure this is fired after the change event of inputElement, so that formattedValue
// Make sure this is fired after the change event of _inputNode, so that formattedValue
// is guaranteed to be calculated

@@ -399,8 +371,5 @@ setTimeout(this._reflectBackFormattedValueToUser);

if (this.inputElement) {
this.inputElement.addEventListener(
this.formatOn,
this._reflectBackFormattedValueDebounced,
);
this.inputElement.addEventListener('input', this._proxyInputEvent);
if (this._inputNode) {
this._inputNode.addEventListener(this.formatOn, this._reflectBackFormattedValueDebounced);
this._inputNode.addEventListener('input', this._proxyInputEvent);
}

@@ -412,5 +381,5 @@ }

this.removeEventListener('user-input-changed', this._onUserInputChanged);
if (this.inputElement) {
this.inputElement.removeEventListener('input', this._proxyInputEvent);
this.inputElement.removeEventListener(
if (this._inputNode) {
this._inputNode.removeEventListener('input', this._proxyInputEvent);
this._inputNode.removeEventListener(
this.formatOn,

@@ -417,0 +386,0 @@ this._reflectBackFormattedValueDebounced,

import { html, css, nothing, dedupeMixin, SlotMixin } from '@lion/core';
import { ObserverMixin } from '@lion/core/src/ObserverMixin.js';
import { FormRegisteringMixin } from './FormRegisteringMixin.js';

@@ -18,7 +17,7 @@

// eslint-disable-next-line no-shadow, no-unused-vars
class FormControlMixin extends FormRegisteringMixin(ObserverMixin(SlotMixin(superclass))) {
class FormControlMixin extends FormRegisteringMixin(SlotMixin(superclass)) {
static get properties() {
return {
/**
* A list of ids that will be put on the inputElement as a serialized string
* A list of ids that will be put on the _inputNode as a serialized string
*/

@@ -30,3 +29,3 @@ _ariaDescribedby: {

/**
* A list of ids that will be put on the inputElement as a serialized string
* A list of ids that will be put on the _inputNode as a serialized string
*/

@@ -70,14 +69,23 @@ _ariaLabelledby: {

static get asyncObservers() {
return {
...super.asyncObservers,
_onAriaLabelledbyChanged: ['_ariaLabelledby'],
_onAriaDescribedbyChanged: ['_ariaDescribedby'],
_onLabelChanged: ['label'],
_onHelpTextChanged: ['helpText'],
};
updated(changedProps) {
super.updated(changedProps);
if (changedProps.has('_ariaLabelledby')) {
this._onAriaLabelledbyChanged({ _ariaLabelledby: this._ariaLabelledby });
}
if (changedProps.has('_ariaDescribedby')) {
this._onAriaDescribedbyChanged({ _ariaDescribedby: this._ariaDescribedby });
}
if (changedProps.has('label')) {
this._onLabelChanged({ label: this.label });
}
if (changedProps.has('helpText')) {
this._onHelpTextChanged({ helpText: this.helpText });
}
}
/** @deprecated will be this._inputNode in next breaking release */
get inputElement() {
get _inputNode() {
return this.__getDirectSlotChild('input');

@@ -118,4 +126,4 @@ }

_enhanceLightDomClasses() {
if (this.inputElement) {
this.inputElement.classList.add('form-control');
if (this._inputNode) {
this._inputNode.classList.add('form-control');
}

@@ -125,6 +133,6 @@ }

_enhanceLightDomA11y() {
const { inputElement, _labelNode, _helpTextNode, _feedbackNode } = this;
const { _inputNode, _labelNode, _helpTextNode, _feedbackNode } = this;
if (inputElement) {
inputElement.id = inputElement.id || this._inputId;
if (_inputNode) {
_inputNode.id = _inputNode.id || this._inputId;
}

@@ -186,4 +194,4 @@ if (_labelNode) {

_onAriaLabelledbyChanged({ _ariaLabelledby }) {
if (this.inputElement) {
this.inputElement.setAttribute('aria-labelledby', _ariaLabelledby);
if (this._inputNode) {
this._inputNode.setAttribute('aria-labelledby', _ariaLabelledby);
}

@@ -199,4 +207,4 @@ }

_onAriaDescribedbyChanged({ _ariaDescribedby }) {
if (this.inputElement) {
this.inputElement.setAttribute('aria-describedby', _ariaDescribedby);
if (this._inputNode) {
this._inputNode.setAttribute('aria-describedby', _ariaDescribedby);
}

@@ -297,3 +305,3 @@ }

inputGroupPrefixTemplate() {
return !this.$$slot('prefix')
return !this.querySelector('[slot=prefix]')
? nothing

@@ -317,3 +325,3 @@ : html`

inputGroupSuffixTemplate() {
return !this.$$slot('suffix')
return !this.querySelector('[slot=suffix]')
? nothing

@@ -320,0 +328,0 @@ : html`

@@ -107,13 +107,2 @@ import { dedupeMixin } from '@lion/core';

updated(changedProperties) {
super.updated(changedProperties);
// classes are added only for backward compatibility - they are deprecated
if (changedProperties.has('touched')) {
this.classList[this.touched ? 'add' : 'remove']('state-touched');
}
if (changedProperties.has('dirty')) {
this.classList[this.dirty ? 'add' : 'remove']('state-dirty');
}
}
/**

@@ -167,17 +156,3 @@ * Evaluations performed on connectedCallback. Since some components can be out of sync

}
/**
* @deprecated
*/
get leaveEvent() {
return this._leaveEvent;
}
/**
* @deprecated
*/
set leaveEvent(eventName) {
this._leaveEvent = eventName;
}
},
);
import { SlotMixin, LitElement } from '@lion/core';
import { ElementMixin } from '@lion/core/src/ElementMixin.js';
import { DisabledMixin } from '@lion/core/src/DisabledMixin.js';
import { ObserverMixin } from '@lion/core/src/ObserverMixin.js';
import { ValidateMixin } from '@lion/validate';

@@ -33,9 +31,7 @@ import { FormControlMixin } from './FormControlMixin.js';

*
* @customElement
* @customElement lion-field
*/
export class LionField extends FormControlMixin(
InteractionStateMixin(
FocusMixin(
FormatMixin(ValidateMixin(DisabledMixin(ElementMixin(SlotMixin(ObserverMixin(LitElement)))))),
),
FocusMixin(FormatMixin(ValidateMixin(DisabledMixin(SlotMixin(LitElement))))),
),

@@ -61,3 +57,3 @@ ) {

get selectionStart() {
const native = this.inputElement;
const native = this._inputNode;
if (native && native.selectionStart) {

@@ -70,3 +66,3 @@ return native.selectionStart;

set selectionStart(value) {
const native = this.inputElement;
const native = this._inputNode;
if (native && native.selectionStart) {

@@ -78,3 +74,3 @@ native.selectionStart = value;

get selectionEnd() {
const native = this.inputElement;
const native = this._inputNode;
if (native && native.selectionEnd) {

@@ -87,3 +83,3 @@ return native.selectionEnd;

set selectionEnd(value) {
const native = this.inputElement;
const native = this._inputNode;
if (native && native.selectionEnd) {

@@ -97,3 +93,3 @@ native.selectionEnd = value;

// if not yet connected to dom can't change the value
if (this.inputElement) {
if (this._inputNode) {
this._setValueAndPreserveCaret(value);

@@ -105,3 +101,3 @@ }

get value() {
return (this.inputElement && this.inputElement.value) || '';
return (this._inputNode && this._inputNode.value) || '';
}

@@ -130,3 +126,3 @@

this._onChange = this._onChange.bind(this);
this.inputElement.addEventListener('change', this._onChange);
this._inputNode.addEventListener('change', this._onChange);
this.classList.add('form-field'); // eslint-disable-line

@@ -137,3 +133,3 @@ }

super.disconnectedCallback();
this.inputElement.removeEventListener('change', this._onChange);
this._inputNode.removeEventListener('change', this._onChange);
}

@@ -146,6 +142,6 @@

if (this.disabled) {
this.inputElement.disabled = true;
this._inputNode.disabled = true;
this.classList.add('state-disabled'); // eslint-disable-line wc/no-self-class
} else {
this.inputElement.disabled = false;
this._inputNode.disabled = false;
this.classList.remove('state-disabled'); // eslint-disable-line wc/no-self-class

@@ -156,7 +152,7 @@ }

if (changedProps.has('name')) {
this.inputElement.name = this.name;
this._inputNode.name = this.name;
}
if (changedProps.has('autocomplete')) {
this.inputElement.autocomplete = this.autocomplete;
this._inputNode.autocomplete = this.autocomplete;
}

@@ -166,3 +162,3 @@ }

/**
* This is not done via 'get delegations', because this.inputElement.setAttribute('value')
* This is not done via 'get delegations', because this._inputNode.setAttribute('value')
* does not trigger a value change

@@ -229,14 +225,14 @@ */

try {
const start = this.inputElement.selectionStart;
this.inputElement.value = newValue;
const start = this._inputNode.selectionStart;
this._inputNode.value = newValue;
// The cursor automatically jumps to the end after re-setting the value,
// so restore it to its original position.
this.inputElement.selectionStart = start;
this.inputElement.selectionEnd = start;
this._inputNode.selectionStart = start;
this._inputNode.selectionEnd = start;
} catch (error) {
// Just set the value and give up on the caret.
this.inputElement.value = newValue;
this._inputNode.value = newValue;
}
} else {
this.inputElement.value = newValue;
this._inputNode.value = newValue;
}

@@ -243,0 +239,0 @@ }

@@ -10,3 +10,3 @@ import { expect, fixture, html, aTimeout, defineCE, unsafeStatic } from '@open-wc/testing';

formControl.value = newViewValue; // eslint-disable-line no-param-reassign
formControl.inputElement.dispatchEvent(new CustomEvent('input', { bubbles: true }));
formControl._inputNode.dispatchEvent(new CustomEvent('input', { bubbles: true }));
}

@@ -78,10 +78,10 @@

set value(newValue) {
this.inputElement.value = newValue;
this._inputNode.value = newValue;
}
get value() {
return this.inputElement.value;
return this._inputNode.value;
}
get inputElement() {
get _inputNode() {
return this.querySelector('input');

@@ -169,3 +169,3 @@ }

expect(fooFormat.value).to.equal('foo: string');
expect(fooFormat.inputElement.value).to.equal('foo: string');
expect(fooFormat._inputNode.value).to.equal('foo: string');
});

@@ -194,3 +194,3 @@

it('synchronizes inputElement.value as a fallback mechanism', async () => {
it('synchronizes _inputNode.value as a fallback mechanism', async () => {
// Note that in lion-field, the attribute would be put on <lion-field>, not on <input>

@@ -209,3 +209,3 @@ const formatElem = await fixture(html`

expect(formatElem.inputElement.value).to.equal('foo: string');
expect(formatElem._inputNode.value).to.equal('foo: string');

@@ -226,8 +226,8 @@ expect(formatElem.serializedValue).to.equal('[foo] string');

mimicUserInput(formatEl, generatedViewValue);
expect(formatEl.inputElement.value).to.not.equal(`foo: ${generatedModelValue}`);
expect(formatEl._inputNode.value).to.not.equal(`foo: ${generatedModelValue}`);
// user leaves field
formatEl.inputElement.dispatchEvent(new CustomEvent(formatEl.formatOn, { bubbles: true }));
formatEl._inputNode.dispatchEvent(new CustomEvent(formatEl.formatOn, { bubbles: true }));
await aTimeout();
expect(formatEl.inputElement.value).to.equal(`foo: ${generatedModelValue}`);
expect(formatEl._inputNode.value).to.equal(`foo: ${generatedModelValue}`);
});

@@ -247,10 +247,10 @@

mimicUserInput(el, 'test');
expect(el.inputElement.value).to.not.equal('foo: test');
expect(el._inputNode.value).to.not.equal('foo: test');
// Now see the difference for an imperative change
el.modelValue = 'test2';
expect(el.inputElement.value).to.equal('foo: test2');
expect(el._inputNode.value).to.equal('foo: test2');
});
it('works if there is no underlying inputElement', async () => {
it('works if there is no underlying _inputNode', async () => {
const tagNoInputString = defineCE(class extends FormatMixin(LitElement) {});

@@ -257,0 +257,0 @@ const tagNoInput = unsafeStatic(tagNoInputString);

@@ -70,14 +70,2 @@ import {

// classes are added only for backward compatibility - they are deprecated
it('sets a class "state-(touched|dirty)"', async () => {
const el = await fixture(html`<${tag}></${tag}>`);
el.touched = true;
await el.updateComplete;
expect(el.classList.contains('state-touched')).to.equal(true, 'has class "state-touched"');
el.dirty = true;
await el.updateComplete;
expect(el.classList.contains('state-dirty')).to.equal(true, 'has class "state-dirty"');
});
it('sets an attribute "touched', async () => {

@@ -129,3 +117,3 @@ const el = await fixture(html`<${tag}></${tag}>`);

const changeModelValueAndLeave = modelValue => {
const targetEl = el.inputElement || el;
const targetEl = el._inputNode || el;
targetEl.dispatchEvent(new Event('focus', { bubbles: true }));

@@ -206,9 +194,4 @@ el.modelValue = modelValue;

});
it('can override the deprecated `leaveEvent`', async () => {
const el = await fixture(html`<${tag} .leaveEvent=${'custom-blur'}></${tag}>`);
expect(el._leaveEvent).to.equal('custom-blur');
});
});
});
}

@@ -11,3 +11,3 @@ import { defineCE } from '@open-wc/testing';

...super.slots,
// LionField needs to have an inputElement defined in order to work...
// LionField needs to have an _inputNode defined in order to work...
input: () => document.createElement('input'),

@@ -14,0 +14,0 @@ };

@@ -27,4 +27,4 @@ import { expect, fixture, defineCE } from '@open-wc/testing';

`);
expect(lionField.$$slot('help-text')).to.equal(undefined);
expect(lionField.querySelector('[slot=help-text]')).to.equal(null);
});
});

@@ -18,3 +18,3 @@ import { expect, fixture, html, defineCE, unsafeStatic, oneEvent } from '@open-wc/testing';

get inputElement() {
get _inputNode() {
return this.querySelector('input');

@@ -33,5 +33,5 @@ }

el.focus();
expect(document.activeElement === el.inputElement).to.be.true;
expect(document.activeElement === el._inputNode).to.be.true;
el.blur();
expect(document.activeElement === el.inputElement).to.be.false;
expect(document.activeElement === el._inputNode).to.be.false;
});

@@ -57,21 +57,8 @@

expect(el.focused).to.be.false;
el.inputElement.focus();
el._inputNode.focus();
expect(el.focused).to.be.true;
el.inputElement.blur();
el._inputNode.blur();
expect(el.focused).to.be.false;
});
it('has a deprecated "state-focused" css class when focused', async () => {
const el = await fixture(html`
<${tag}><input slot="input"></${tag}>
`);
el.focus();
await el.updateComplete;
expect(el.classList.contains('state-focused')).to.be.true;
el.blur();
await el.updateComplete;
expect(el.classList.contains('state-focused')).to.be.false;
});
it('dispatches [focus, blur] events', async () => {

@@ -78,0 +65,0 @@ const el = await fixture(html`

import { expect, fixture, html, defineCE, unsafeStatic } from '@open-wc/testing';
import { SlotMixin } from '@lion/core';
import { LionLitElement } from '@lion/core/src/LionLitElement.js';
import { LitElement, SlotMixin } from '@lion/core';

@@ -13,3 +12,3 @@ import { FormControlMixin } from '../src/FormControlMixin.js';

before(async () => {
const FormControlMixinClass = class extends FormControlMixin(SlotMixin(LionLitElement)) {
const FormControlMixinClass = class extends FormControlMixin(SlotMixin(LitElement)) {
static get properties() {

@@ -32,3 +31,3 @@ return {

`);
expect(lionFieldAttr.$$slot('help-text').textContent).to.contain(
expect(lionFieldAttr.querySelector('[slot=help-text]').textContent).to.contain(
'This email address is already taken',

@@ -42,3 +41,3 @@ );

expect(lionFieldProp.$$slot('help-text').textContent).to.contain(
expect(lionFieldProp.querySelector('[slot=help-text]').textContent).to.contain(
'This email address is already taken',

@@ -60,3 +59,3 @@ );

const ariaAttribute = lionField
.$$slot('input')
.querySelector('[slot=input]')
.getAttribute(ariaAttributeName)

@@ -78,4 +77,4 @@ .trim()

expect(lionField.$$slot('feedback').getAttribute('aria-live')).to.equal('polite');
expect(lionField.querySelector('[slot=feedback]').getAttribute('aria-live')).to.equal('polite');
});
});

@@ -25,3 +25,3 @@ import {

formControl.value = newViewValue; // eslint-disable-line no-param-reassign
formControl.inputElement.dispatchEvent(new CustomEvent('input', { bubbles: true }));
formControl._inputNode.dispatchEvent(new CustomEvent('input', { bubbles: true }));
}

@@ -36,3 +36,3 @@

const el = await fixture(html`<${tag}>${inputSlot}</${tag}>`);
expect(el.$$slot('input').id).to.equal(el._inputId);
expect(el.querySelector('[slot=input]').id).to.equal(el._inputId);
});

@@ -45,11 +45,11 @@

const cbFocusNativeInput = sinon.spy();
el.inputElement.addEventListener('focus', cbFocusNativeInput);
el._inputNode.addEventListener('focus', cbFocusNativeInput);
const cbBlurHost = sinon.spy();
el.addEventListener('blur', cbBlurHost);
const cbBlurNativeInput = sinon.spy();
el.inputElement.addEventListener('blur', cbBlurNativeInput);
el._inputNode.addEventListener('blur', cbBlurNativeInput);
await triggerFocusFor(el);
expect(document.activeElement).to.equal(el.inputElement);
expect(document.activeElement).to.equal(el._inputNode);
expect(cbFocusHost.callCount).to.equal(1);

@@ -65,3 +65,3 @@ expect(cbFocusNativeInput.callCount).to.equal(1);

await triggerFocusFor(el);
expect(document.activeElement).to.equal(el.inputElement);
expect(document.activeElement).to.equal(el._inputNode);
expect(cbFocusHost.callCount).to.equal(2);

@@ -87,3 +87,3 @@ expect(cbFocusNativeInput.callCount).to.equal(2);

expect(elDisabled.disabled).to.equal(true);
expect(elDisabled.inputElement.disabled).to.equal(true);
expect(elDisabled._inputNode.disabled).to.equal(true);
});

@@ -95,3 +95,3 @@

await el.updateComplete;
expect(el.inputElement.disabled).to.equal(true);
expect(el._inputNode.disabled).to.equal(true);
});

@@ -122,3 +122,3 @@

const el = await fixture(html`<${tag} value="one">${inputSlot}</${tag}>`);
expect(el.$$slot('input').value).to.equal('one');
expect(el.querySelector('[slot=input]').value).to.equal('one');
});

@@ -128,20 +128,20 @@

const el = await fixture(html`<${tag}>${inputSlot}</${tag}>`);
expect(el.$$slot('input').value).to.equal('');
expect(el.querySelector('[slot=input]').value).to.equal('');
el.value = 'one';
expect(el.value).to.equal('one');
expect(el.$$slot('input').value).to.equal('one');
expect(el.querySelector('[slot=input]').value).to.equal('one');
});
// This is necessary for security, so that inputElements autocomplete can be set to 'off'
// This is necessary for security, so that _inputNodes autocomplete can be set to 'off'
it('delegates autocomplete property', async () => {
const el = await fixture(html`<${tag}>${inputSlot}</${tag}>`);
expect(el.inputElement.autocomplete).to.equal('');
expect(el.inputElement.hasAttribute('autocomplete')).to.be.false;
expect(el._inputNode.autocomplete).to.equal('');
expect(el._inputNode.hasAttribute('autocomplete')).to.be.false;
el.autocomplete = 'off';
await el.updateComplete;
expect(el.inputElement.autocomplete).to.equal('off');
expect(el.inputElement.getAttribute('autocomplete')).to.equal('off');
expect(el._inputNode.autocomplete).to.equal('off');
expect(el._inputNode.getAttribute('autocomplete')).to.equal('off');
});
// TODO: find out if we could put all listeners on this.value (instead of this.inputElement.value)
// TODO: find out if we could put all listeners on this.value (instead of this._inputNode.value)
// and make it act on this.value again

@@ -163,8 +163,8 @@ it('has a class "state-filled" if this.value is filled', async () => {

await el.updateComplete;
el.inputElement.value = 'hello world';
el.inputElement.selectionStart = 2;
el.inputElement.selectionEnd = 2;
el._inputNode.value = 'hello world';
el._inputNode.selectionStart = 2;
el._inputNode.selectionEnd = 2;
el.value = 'hey there universe';
expect(el.inputElement.selectionStart).to.equal(2);
expect(el.inputElement.selectionEnd).to.equal(2);
expect(el._inputNode.selectionStart).to.equal(2);
expect(el._inputNode.selectionEnd).to.equal(2);
});

@@ -176,3 +176,3 @@

expect(el.classList.contains('state-disabled')).to.equal(false);
expect(el.inputElement.hasAttribute('disabled')).to.equal(false);
expect(el._inputNode.hasAttribute('disabled')).to.equal(false);

@@ -184,7 +184,7 @@ el.disabled = true;

expect(el.classList.contains('state-disabled')).to.equal(true);
expect(el.inputElement.hasAttribute('disabled')).to.equal(true);
expect(el._inputNode.hasAttribute('disabled')).to.equal(true);
const disabledel = await fixture(html`<${tag} disabled>${inputSlot}</${tag}>`);
expect(disabledel.classList.contains('state-disabled')).to.equal(true);
expect(disabledel.inputElement.hasAttribute('disabled')).to.equal(true);
expect(disabledel._inputNode.hasAttribute('disabled')).to.equal(true);
});

@@ -214,3 +214,3 @@

`);
const nativeInput = el.$$slot('input');
const nativeInput = el.querySelector('[slot=input]');

@@ -233,3 +233,3 @@ expect(nativeInput.getAttribute('aria-labelledby')).to.equal(` label-${el._inputId}`);

const nativeInput = el.$$slot('input');
const nativeInput = el.querySelector('[slot=input]');
expect(nativeInput.getAttribute('aria-labelledby')).to.contain(

@@ -261,14 +261,14 @@ ` before-${el._inputId} after-${el._inputId}`,

const { inputElement } = el;
const { _inputNode } = el;
// 1. addToAriaLabel()
// Check if the aria attr is filled initially
expect(inputElement.getAttribute('aria-labelledby')).to.contain(`label-${el._inputId}`);
expect(_inputNode.getAttribute('aria-labelledby')).to.contain(`label-${el._inputId}`);
el.addToAriaLabel('additionalLabel');
// Now check if ids are added to the end (not overridden)
expect(inputElement.getAttribute('aria-labelledby')).to.contain(`label-${el._inputId}`);
expect(_inputNode.getAttribute('aria-labelledby')).to.contain(`label-${el._inputId}`);
// Should be placed in the end
expect(
inputElement.getAttribute('aria-labelledby').indexOf(`label-${el._inputId}`) <
inputElement.getAttribute('aria-labelledby').indexOf('additionalLabel'),
_inputNode.getAttribute('aria-labelledby').indexOf(`label-${el._inputId}`) <
_inputNode.getAttribute('aria-labelledby').indexOf('additionalLabel'),
);

@@ -278,10 +278,10 @@

// Check if the aria attr is filled initially
expect(inputElement.getAttribute('aria-describedby')).to.contain(`feedback-${el._inputId}`);
expect(_inputNode.getAttribute('aria-describedby')).to.contain(`feedback-${el._inputId}`);
el.addToAriaDescription('additionalDescription');
// Now check if ids are added to the end (not overridden)
expect(inputElement.getAttribute('aria-describedby')).to.contain(`feedback-${el._inputId}`);
expect(_inputNode.getAttribute('aria-describedby')).to.contain(`feedback-${el._inputId}`);
// Should be placed in the end
expect(
inputElement.getAttribute('aria-describedby').indexOf(`feedback-${el._inputId}`) <
inputElement.getAttribute('aria-describedby').indexOf('additionalDescription'),
_inputNode.getAttribute('aria-describedby').indexOf(`feedback-${el._inputId}`) <
_inputNode.getAttribute('aria-describedby').indexOf('additionalDescription'),
);

@@ -416,6 +416,6 @@ });

const el = await fixture(html`<${tag}>${inputSlot}</${tag}>`);
expect(el.inputElement.value).to.equal('');
expect(el._inputNode.value).to.equal('');
el.value = 'one';
expect(el.value).to.equal('one');
expect(el.inputElement.value).to.equal('one');
expect(el._inputNode.value).to.equal('one');
});

@@ -432,6 +432,6 @@

el.selectionEnd = 12;
expect(el.inputElement.selectionStart).to.equal(5);
expect(el.inputElement.selectionEnd).to.equal(12);
expect(el._inputNode.selectionStart).to.equal(5);
expect(el._inputNode.selectionEnd).to.equal(12);
});
});
});
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