@lion/field
Advanced tools
Comparing version 0.3.7 to 0.4.0
@@ -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 @@ |
@@ -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); | ||
}); | ||
}); | ||
}); |
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
210142
2946
+ Added@lion/core@0.3.0(transitive)
+ Added@lion/localize@0.5.0(transitive)
+ Added@lion/validate@0.3.1(transitive)
- Removed@lion/core@0.2.1(transitive)
- Removed@lion/localize@0.4.21(transitive)
- Removed@lion/validate@0.2.40(transitive)
Updated@lion/core@^0.3.0
Updated@lion/validate@^0.3.0