fix(field): the FormatMixin should work without an inputElement

This commit is contained in:
Thomas Allmer 2019-07-15 13:43:46 +02:00 committed by Thomas Allmer
parent 398198502c
commit 2511bf6f8d
2 changed files with 26 additions and 10 deletions

View file

@ -230,7 +230,7 @@ export const FormatMixin = dedupeMixin(
// imperatively, we DO want to format a value (it is the only way to get meaningful
// input into `.inputElement` with modelValue as input)
if (this.__isHandlingUserInput && this.errorState) {
if (this.__isHandlingUserInput && this.errorState && this.inputElement) {
return this.inputElement ? this.value : undefined;
}
return this.formatter(this.modelValue, this.formatOptions);
@ -335,8 +335,6 @@ export const FormatMixin = dedupeMixin(
// is guaranteed to be calculated
setTimeout(this._reflectBackFormattedValueToUser);
};
this.inputElement.addEventListener(this.formatOn, this._reflectBackFormattedValueDebounced);
this.inputElement.addEventListener('input', this._proxyInputEvent);
this.addEventListener('user-input-changed', this._onUserInputChanged);
// Connect the value found in <input> to the formatting/parsing/serializing loop as a
// fallback mechanism. Assume the user uses the value property of the
@ -347,16 +345,26 @@ export const FormatMixin = dedupeMixin(
this._syncValueUpwards();
}
this._reflectBackFormattedValueToUser();
if (this.inputElement) {
this.inputElement.addEventListener(
this.formatOn,
this._reflectBackFormattedValueDebounced,
);
this.inputElement.addEventListener('input', this._proxyInputEvent);
}
}
disconnectedCallback() {
super.disconnectedCallback();
this.inputElement.removeEventListener('input', this._proxyInputEvent);
this.removeEventListener('user-input-changed', this._onUserInputChanged);
this.inputElement.removeEventListener(
this.formatOn,
this._reflectBackFormattedValueDebounced,
);
if (this.inputElement) {
this.inputElement.removeEventListener('input', this._proxyInputEvent);
this.inputElement.removeEventListener(
this.formatOn,
this._reflectBackFormattedValueDebounced,
);
}
}
},
);

View file

@ -1,7 +1,7 @@
import { expect, fixture, html, aTimeout, defineCE, unsafeStatic } from '@open-wc/testing';
import sinon from 'sinon';
import { LionLitElement } from '@lion/core/src/LionLitElement.js';
import { LitElement } from '@lion/core';
import { Unparseable } from '@lion/validate';
import { FormatMixin } from '../src/FormatMixin.js';
@ -17,7 +17,7 @@ describe('FormatMixin', () => {
before(async () => {
const tagString = defineCE(
class extends FormatMixin(LionLitElement) {
class extends FormatMixin(LitElement) {
render() {
return html`
<slot name="input"></slot>
@ -176,6 +176,14 @@ describe('FormatMixin', () => {
expect(el.inputElement.value).to.equal('foo: test2');
});
it('works if there is no underlying inputElement', async () => {
const tagNoInputString = defineCE(class extends FormatMixin(LitElement) {});
const tagNoInput = unsafeStatic(tagNoInputString);
expect(async () => {
await fixture(html`<${tagNoInput}></${tagNoInput}>`);
}).to.not.throw();
});
describe('parsers/formatters/serializers', () => {
it('should call the parser|formatter|serializer provided by user', async () => {
const formatterSpy = sinon.spy(value => `foo: ${value}`);