@lion/field
Advanced tools
Comparing version 0.1.26 to 0.1.27
@@ -6,2 +6,18 @@ # Change Log | ||
## [0.1.27](https://github.com/ing-bank/lion/compare/@lion/field@0.1.26...@lion/field@0.1.27) (2019-07-15) | ||
### Bug Fixes | ||
* **field:** make InteractionState leaveEvent protected ([3981985](https://github.com/ing-bank/lion/commit/3981985)) | ||
* **field:** move FocusMixin out of InteractionStateMixin ([b398f40](https://github.com/ing-bank/lion/commit/b398f40)) | ||
* **field:** no DomHelpers for FormControl and apply all needed mixins ([bb1c702](https://github.com/ing-bank/lion/commit/bb1c702)) | ||
* **field:** remove CssClassMixin from InteractionStateMixin ([dcf8726](https://github.com/ing-bank/lion/commit/dcf8726)) | ||
* **field:** remove unused EventMixin from FormatMixin ([901fc8c](https://github.com/ing-bank/lion/commit/901fc8c)) | ||
* **field:** the FormatMixin should work without an inputElement ([2511bf6](https://github.com/ing-bank/lion/commit/2511bf6)) | ||
## [0.1.26](https://github.com/ing-bank/lion/compare/@lion/field@0.1.25...@lion/field@0.1.26) (2019-07-09) | ||
@@ -8,0 +24,0 @@ |
{ | ||
"name": "@lion/field", | ||
"version": "0.1.26", | ||
"version": "0.1.27", | ||
"description": "Fields are the most fundamental building block of the Form System", | ||
@@ -36,3 +36,3 @@ "author": "ing-bank", | ||
"@lion/core": "^0.1.9", | ||
"@lion/validate": "^0.2.12" | ||
"@lion/validate": "^0.2.13" | ||
}, | ||
@@ -45,3 +45,3 @@ "devDependencies": { | ||
}, | ||
"gitHead": "a598a47dabccc92e68f12411b7b613a8e5132762" | ||
"gitHead": "688fcb6690d3cb29b0812056f5b27a1f9d0544b6" | ||
} |
/* eslint-disable class-methods-use-this */ | ||
import { dedupeMixin } from '@lion/core'; | ||
import { EventMixin } from '@lion/core/src/EventMixin.js'; | ||
import { ObserverMixin } from '@lion/core/src/ObserverMixin.js'; | ||
@@ -24,3 +23,3 @@ import { Unparseable } from '@lion/validate'; | ||
// eslint-disable-next-line no-unused-vars, no-shadow | ||
class FormatMixin extends EventMixin(ObserverMixin(superclass)) { | ||
class FormatMixin extends ObserverMixin(superclass) { | ||
static get properties() { | ||
@@ -235,3 +234,3 @@ return { | ||
if (this.__isHandlingUserInput && this.errorState) { | ||
if (this.__isHandlingUserInput && this.errorState && this.inputElement) { | ||
return this.inputElement ? this.value : undefined; | ||
@@ -341,4 +340,2 @@ } | ||
}; | ||
this.inputElement.addEventListener(this.formatOn, this._reflectBackFormattedValueDebounced); | ||
this.inputElement.addEventListener('input', this._proxyInputEvent); | ||
this.addEventListener('user-input-changed', this._onUserInputChanged); | ||
@@ -354,2 +351,10 @@ // Connect the value found in <input> to the formatting/parsing/serializing loop as a | ||
this._reflectBackFormattedValueToUser(); | ||
if (this.inputElement) { | ||
this.inputElement.addEventListener( | ||
this.formatOn, | ||
this._reflectBackFormattedValueDebounced, | ||
); | ||
this.inputElement.addEventListener('input', this._proxyInputEvent); | ||
} | ||
} | ||
@@ -359,10 +364,12 @@ | ||
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, | ||
); | ||
} | ||
} | ||
}, | ||
); |
@@ -1,2 +0,2 @@ | ||
import { html, css, nothing, dedupeMixin } from '@lion/core'; | ||
import { html, css, nothing, dedupeMixin, SlotMixin } from '@lion/core'; | ||
import { ObserverMixin } from '@lion/core/src/ObserverMixin.js'; | ||
@@ -17,3 +17,3 @@ | ||
// eslint-disable-next-line no-shadow, no-unused-vars | ||
class FormControlMixin extends ObserverMixin(superclass) { | ||
class FormControlMixin extends ObserverMixin(SlotMixin(superclass)) { | ||
static get properties() { | ||
@@ -79,6 +79,19 @@ return { | ||
/** @deprecated will be this._inputNode in next breaking release */ | ||
get inputElement() { | ||
return (this.$$slot && this.$$slot('input')) || this.querySelector('[slot=input]'); // eslint-disable-line | ||
return this.__getDirectSlotChild('input'); | ||
} | ||
get _labelNode() { | ||
return this.__getDirectSlotChild('label'); | ||
} | ||
get _helpTextNode() { | ||
return this.__getDirectSlotChild('help-text'); | ||
} | ||
get _feedbackNode() { | ||
return this.__getDirectSlotChild('feedback'); | ||
} | ||
constructor() { | ||
@@ -112,25 +125,27 @@ super(); | ||
_enhanceLightDomA11y() { | ||
if (this.inputElement) { | ||
this.inputElement.id = this.inputElement.id || this._inputId; | ||
const { inputElement, _labelNode, _helpTextNode, _feedbackNode } = this; | ||
if (inputElement) { | ||
inputElement.id = inputElement.id || this._inputId; | ||
} | ||
if (this.$$slot('label')) { | ||
this.$$slot('label').setAttribute('for', this._inputId); | ||
this.$$slot('label').id = this.$$slot('label').id || `label-${this._inputId}`; | ||
const labelledById = ` ${this.$$slot('label').id}`; | ||
if (_labelNode) { | ||
_labelNode.setAttribute('for', this._inputId); | ||
_labelNode.id = _labelNode.id || `label-${this._inputId}`; | ||
const labelledById = ` ${_labelNode.id}`; | ||
if (this._ariaLabelledby.indexOf(labelledById) === -1) { | ||
this._ariaLabelledby += ` ${this.$$slot('label').id}`; | ||
this._ariaLabelledby += ` ${_labelNode.id}`; | ||
} | ||
} | ||
if (this.$$slot('help-text')) { | ||
this.$$slot('help-text').id = this.$$slot('help-text').id || `help-text-${this._inputId}`; | ||
const describeIdHelpText = ` ${this.$$slot('help-text').id}`; | ||
if (_helpTextNode) { | ||
_helpTextNode.id = _helpTextNode.id || `help-text-${this._inputId}`; | ||
const describeIdHelpText = ` ${_helpTextNode.id}`; | ||
if (this._ariaDescribedby.indexOf(describeIdHelpText) === -1) { | ||
this._ariaDescribedby += ` ${this.$$slot('help-text').id}`; | ||
this._ariaDescribedby += ` ${_helpTextNode.id}`; | ||
} | ||
} | ||
if (this.$$slot('feedback')) { | ||
this.$$slot('feedback').id = this.$$slot('feedback').id || `feedback-${this._inputId}`; | ||
const describeIdFeedback = ` ${this.$$slot('feedback').id}`; | ||
if (_feedbackNode) { | ||
_feedbackNode.id = _feedbackNode.id || `feedback-${this._inputId}`; | ||
const describeIdFeedback = ` ${_feedbackNode.id}`; | ||
if (this._ariaDescribedby.indexOf(describeIdFeedback) === -1) { | ||
this._ariaDescribedby += ` ${this.$$slot('feedback').id}`; | ||
this._ariaDescribedby += ` ${_feedbackNode.id}`; | ||
} | ||
@@ -187,3 +202,3 @@ } | ||
additionalSlots.forEach(additionalSlot => { | ||
const element = this.$$slot(additionalSlot); | ||
const element = this.__getDirectSlotChild(additionalSlot); | ||
if (element) { | ||
@@ -225,4 +240,4 @@ element.id = element.id || `${additionalSlot}-${this._inputId}`; | ||
_onLabelChanged({ label }) { | ||
if (this.$$slot && this.$$slot('label')) { | ||
this.$$slot('label').textContent = label; | ||
if (this._labelNode) { | ||
this._labelNode.textContent = label; | ||
} | ||
@@ -232,4 +247,4 @@ } | ||
_onHelpTextChanged({ helpText }) { | ||
if (this.$$slot && this.$$slot('help-text')) { | ||
this.$$slot('help-text').textContent = helpText; | ||
if (this._helpTextNode) { | ||
this._helpTextNode.textContent = helpText; | ||
} | ||
@@ -561,3 +576,3 @@ } | ||
_getAriaDescriptionElements() { | ||
return [this.$$slot('help-text'), this.$$slot('feedback')]; | ||
return [this._helpTextNode, this._feedbackNode]; | ||
} | ||
@@ -584,3 +599,7 @@ | ||
} | ||
__getDirectSlotChild(slotName) { | ||
return [...this.children].find(el => el.slot === slotName); | ||
} | ||
}, | ||
); |
import { dedupeMixin } from '@lion/core'; | ||
import { CssClassMixin } from '@lion/core/src/CssClassMixin.js'; | ||
import { ObserverMixin } from '@lion/core/src/ObserverMixin.js'; | ||
import { Unparseable } from '@lion/validate'; | ||
import { FocusMixin } from './FocusMixin.js'; | ||
@@ -19,3 +17,3 @@ /** | ||
// eslint-disable-next-line no-unused-vars, no-shadow | ||
class InteractionStateMixin extends CssClassMixin(FocusMixin(ObserverMixin(superclass))) { | ||
class InteractionStateMixin extends ObserverMixin(superclass) { | ||
static get properties() { | ||
@@ -29,3 +27,3 @@ return { | ||
type: Boolean, | ||
nonEmptyToClass: 'state-touched', | ||
reflect: true, | ||
}, | ||
@@ -38,3 +36,3 @@ | ||
type: Boolean, | ||
nonEmptyToClass: 'state-dirty', | ||
reflect: true, | ||
}, | ||
@@ -81,3 +79,3 @@ | ||
this.prefilled = false; | ||
this.leaveEvent = 'blur'; | ||
this._leaveEvent = 'blur'; | ||
this._valueChangedEvent = 'model-value-changed'; | ||
@@ -96,3 +94,3 @@ | ||
} | ||
this.addEventListener(this.leaveEvent, this._iStateOnLeave); | ||
this.addEventListener(this._leaveEvent, this._iStateOnLeave); | ||
this.addEventListener(this._valueChangedEvent, this._iStateOnValueChange); | ||
@@ -106,6 +104,17 @@ this.initInteractionState(); | ||
} | ||
this.removeEventListener(this.leaveEvent, this._iStateOnLeave); | ||
this.removeEventListener(this._leaveEvent, this._iStateOnLeave); | ||
this.removeEventListener(this._valueChangedEvent, this._iStateOnValueChange); | ||
} | ||
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'); | ||
} | ||
} | ||
/** | ||
@@ -159,3 +168,17 @@ * 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; | ||
} | ||
}, | ||
); |
@@ -11,2 +11,3 @@ import { DelegateMixin, SlotMixin } from '@lion/core'; | ||
import { FormatMixin } from './FormatMixin.js'; | ||
import { FocusMixin } from './FocusMixin.js'; | ||
@@ -33,5 +34,7 @@ /** | ||
InteractionStateMixin( | ||
FormatMixin( | ||
ValidateMixin( | ||
CssClassMixin(ElementMixin(DelegateMixin(SlotMixin(ObserverMixin(LionLitElement))))), | ||
FocusMixin( | ||
FormatMixin( | ||
ValidateMixin( | ||
CssClassMixin(ElementMixin(DelegateMixin(SlotMixin(ObserverMixin(LionLitElement))))), | ||
), | ||
), | ||
@@ -38,0 +41,0 @@ ), |
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'; | ||
@@ -20,3 +20,3 @@ import { FormatMixin } from '../src/FormatMixin.js'; | ||
const tagString = defineCE( | ||
class extends FormatMixin(LionLitElement) { | ||
class extends FormatMixin(LitElement) { | ||
render() { | ||
@@ -180,2 +180,10 @@ return html` | ||
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', () => { | ||
@@ -182,0 +190,0 @@ it('should call the parser|formatter|serializer provided by user', async () => { |
@@ -1,4 +0,12 @@ | ||
import { expect, fixture, unsafeStatic, html, defineCE } from '@open-wc/testing'; | ||
import { | ||
expect, | ||
fixture, | ||
unsafeStatic, | ||
html, | ||
defineCE, | ||
triggerFocusFor, | ||
triggerBlurFor, | ||
} from '@open-wc/testing'; | ||
import sinon from 'sinon'; | ||
import { LionLitElement } from '@lion/core/src/LionLitElement.js'; | ||
import { LitElement } from '@lion/core'; | ||
@@ -8,6 +16,12 @@ import { InteractionStateMixin } from '../src/InteractionStateMixin.js'; | ||
describe('InteractionStateMixin', async () => { | ||
let elem; | ||
let tagString; | ||
let tag; | ||
before(() => { | ||
elem = defineCE( | ||
class IState extends InteractionStateMixin(LionLitElement) { | ||
tagString = defineCE( | ||
class IState extends InteractionStateMixin(LitElement) { | ||
connectedCallback() { | ||
super.connectedCallback(); | ||
this.tabIndex = 0; | ||
} | ||
set modelValue(v) { | ||
@@ -23,89 +37,78 @@ this._modelValue = v; | ||
} | ||
get inputElement() { | ||
return this.querySelector('input'); | ||
} | ||
}, | ||
); | ||
tag = unsafeStatic(tagString); | ||
}); | ||
it('sets states to false on init', async () => { | ||
const input = await fixture(`<${elem}><input slot="input"></${elem}>`); | ||
expect(input.dirty).to.equal(false); | ||
expect(input.touched).to.equal(false); | ||
expect(input.prefilled).to.equal(false); | ||
const el = await fixture(html`<${tag}></${tag}>`); | ||
expect(el.dirty).to.be.false; | ||
expect(el.touched).to.be.false; | ||
expect(el.prefilled).to.be.false; | ||
}); | ||
it('sets dirty when value changed', async () => { | ||
const input = await fixture(`<${elem}><input slot="input"></${elem}>`); | ||
input.modelValue = 'foobar'; | ||
expect(input.dirty).to.equal(true); | ||
const el = await fixture(html`<${tag}></${tag}>`); | ||
expect(el.dirty).to.be.false; | ||
el.modelValue = 'foobar'; | ||
expect(el.dirty).to.be.true; | ||
}); | ||
// Skipping, since this issue (not being able to set focus on element extending from LitElement) | ||
// only occurs in WCT context (not in Storybook/Stackblitz). | ||
// See: https://stackblitz.com/edit/lit-element-request-update-bug-g59tjq?file=blurry.js | ||
// it.skip | ||
it('sets touched to true when field left after focus', async () => { | ||
// const formElement = await LionTest.htmlFixture(`<${elem}><input type="text" slot="input"></${elem}>`); | ||
// await triggerFocusFor(formElement.inputElement); // focus/blur can't be delegated | ||
// await triggerBlurFor(formElement.inputElement); | ||
// expect(formElement.touched).to.equal(true); | ||
const el = await fixture(html`<${tag}></${tag}>`); | ||
await triggerFocusFor(el); | ||
await triggerBlurFor(el); | ||
expect(el.touched).to.be.true; | ||
}); | ||
// classes are added only for backward compatibility - they are deprecated | ||
it('sets a class "state-(touched|dirty)"', async () => { | ||
const state = await fixture(`<${elem}><input slot="input"></${elem}>`); | ||
state.touched = true; | ||
await state.updateComplete; | ||
expect(state.classList.contains('state-touched')).to.equal(true, 'has class "state-touched"'); | ||
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"'); | ||
state.dirty = true; | ||
await state.updateComplete; | ||
expect(state.classList.contains('state-dirty')).to.equal(true, 'has class "state-dirty"'); | ||
el.dirty = true; | ||
await el.updateComplete; | ||
expect(el.classList.contains('state-dirty')).to.equal(true, 'has class "state-dirty"'); | ||
}); | ||
it('fires "(touched|dirty)-state-changed" event when state changes', async () => { | ||
const iState = await fixture(`<${elem}><input slot="input"></${elem}>`); | ||
const cbTouched = sinon.spy(); | ||
const cbDirty = sinon.spy(); | ||
it('sets an attribute "touched', async () => { | ||
const el = await fixture(html`<${tag}></${tag}>`); | ||
el.touched = true; | ||
await el.updateComplete; | ||
expect(el.hasAttribute('touched')).to.be.true; | ||
}); | ||
iState.addEventListener('touched-changed', cbTouched); | ||
iState.addEventListener('dirty-changed', cbDirty); | ||
it('sets an attribute "dirty', async () => { | ||
const el = await fixture(html`<${tag}></${tag}>`); | ||
el.dirty = true; | ||
await el.updateComplete; | ||
expect(el.hasAttribute('dirty')).to.be.true; | ||
}); | ||
iState.touched = true; | ||
expect(cbTouched.callCount).to.equal(1); | ||
it('fires "(touched|dirty)-state-changed" event when state changes', async () => { | ||
const touchedSpy = sinon.spy(); | ||
const dirtySpy = sinon.spy(); | ||
const el = await fixture( | ||
html`<${tag} @touched-changed=${touchedSpy} @dirty-changed=${dirtySpy}></${tag}>`, | ||
); | ||
iState.dirty = true; | ||
expect(cbDirty.callCount).to.equal(1); | ||
}); | ||
el.touched = true; | ||
expect(touchedSpy.callCount).to.equal(1); | ||
// Skipping, since this issue (not being able to set focus on element extending from LitElement) | ||
// only occurs in WCT context (not in Storybook/Stackblitz). | ||
// See: https://stackblitz.com/edit/lit-element-request-update-bug-g59tjq?file=blurry.js | ||
// it.skip | ||
it('sets prefilled to true when field left and value non-empty', async () => { | ||
// const iState = await LionTest.htmlFixture(`<${elem}><input slot="input"></${elem}>`); | ||
// await triggerFocusFor(iState.inputElement); | ||
// iState.modelValue = externalVariables.prefilledModelValue || '000'; | ||
// await triggerBlurFor(iState.inputElement); | ||
// expect(iState.prefilled).to.equal(true); | ||
// await triggerFocusFor(iState.inputElement); | ||
// iState.modelValue = externalVariables.nonPrefilledModelValue || ''; | ||
// await triggerBlurFor(iState.inputElement); | ||
// expect(iState.prefilled).to.equal(false); | ||
el.dirty = true; | ||
expect(dirtySpy.callCount).to.equal(1); | ||
}); | ||
it('sets prefilled once instantiated', async () => { | ||
const tag = unsafeStatic(elem); | ||
const element = await fixture(html` | ||
<${tag} | ||
.modelValue=${'prefilled'} | ||
><input slot="input"></${tag}>`); | ||
expect(element.prefilled).to.equal(true); | ||
const el = await fixture(html` | ||
<${tag} .modelValue=${'prefilled'}></${tag}> | ||
`); | ||
expect(el.prefilled).to.be.true; | ||
const nonPrefilled = await fixture(html` | ||
<${tag} | ||
.modelValue=''} | ||
><input slot="input"></${tag}>`); | ||
expect(nonPrefilled.prefilled).to.equal(false); | ||
<${tag} .modelValue=${''}></${tag}> | ||
`); | ||
expect(nonPrefilled.prefilled).to.be.false; | ||
}); | ||
@@ -116,55 +119,74 @@ | ||
Booleans, Strings)`, async () => { | ||
const input = await fixture(`<${elem}><input slot="input"></${elem}>`); | ||
const el = await fixture(html`<${tag}></${tag}>`); | ||
const changeModelValueAndLeave = modelValue => { | ||
input.dispatchEvent(new Event('focus', { bubbles: true })); | ||
input.modelValue = modelValue; | ||
input.dispatchEvent(new Event('blur', { bubbles: true })); | ||
el.dispatchEvent(new Event('focus', { bubbles: true })); | ||
el.modelValue = modelValue; | ||
el.dispatchEvent(new Event('blur', { bubbles: true })); | ||
}; | ||
// Prefilled | ||
changeModelValueAndLeave(input, ['bla']); | ||
expect(input.prefilled).to.equal(false, 'empty array should be considered "prefilled"'); | ||
changeModelValueAndLeave(input, { bla: 'bla' }); | ||
expect(input.prefilled).to.equal(false, 'empty object should be considered "prefilled"'); | ||
changeModelValueAndLeave(input, 0); | ||
expect(input.prefilled).to.equal(false, 'numbers should be considered "prefilled"'); | ||
changeModelValueAndLeave(input, false); | ||
expect(input.prefilled).to.equal(false, 'Booleans should be considered "prefilled"'); | ||
changeModelValueAndLeave(input, ''); | ||
expect(input.prefilled).to.equal(false, 'empty string should be considered "prefilled"'); | ||
changeModelValueAndLeave(['not-empty']); | ||
expect(el.prefilled, 'not empty array should be "prefilled"').to.be.true; | ||
changeModelValueAndLeave({ not: 'empty' }); | ||
expect(el.prefilled, 'not empty object should be "prefilled"').to.be.true; | ||
changeModelValueAndLeave(0); | ||
expect(el.prefilled, 'numbers should be "prefilled"').to.be.true; | ||
changeModelValueAndLeave(false); | ||
expect(el.prefilled, 'booleans should be "prefilled"').to.be.true; | ||
// Not prefilled | ||
changeModelValueAndLeave(input, []); | ||
expect(input.prefilled).to.equal(false, 'empty array should not be considered "prefilled"'); | ||
changeModelValueAndLeave(input, {}); | ||
expect(input.prefilled).to.equal(false, 'empty object should not be considered "prefilled"'); | ||
changeModelValueAndLeave(input, ''); | ||
expect(input.prefilled).to.equal(false, 'empty string should not be considered "prefilled"'); | ||
changeModelValueAndLeave(input, null); | ||
expect(input.prefilled).to.equal(false, 'null should not be considered "prefilled"'); | ||
changeModelValueAndLeave(input, undefined); | ||
expect(input.prefilled).to.equal(false, 'undefined should not be considered "prefilled"'); | ||
changeModelValueAndLeave([]); | ||
expect(el.prefilled, 'empty array should not be "prefilled"').to.be.false; | ||
changeModelValueAndLeave({}); | ||
expect(el.prefilled, 'empty object should not be "prefilled"').to.be.false; | ||
changeModelValueAndLeave(''); | ||
expect(el.prefilled, 'empty string should not be "prefilled"').to.be.false; | ||
changeModelValueAndLeave(null); | ||
expect(el.prefilled, 'null should not be "prefilled"').to.be.false; | ||
changeModelValueAndLeave(undefined); | ||
expect(el.prefilled, 'undefined should not be "prefilled"').to.be.false; | ||
}); | ||
it('has a method resetInteractionState()', async () => { | ||
const input = await fixture(`<${elem}><input slot="input"></${elem}>`); | ||
input.dirty = true; | ||
input.touched = true; | ||
input.prefilled = true; | ||
input.resetInteractionState(); | ||
expect(input.dirty).to.equal(false); | ||
expect(input.touched).to.equal(false); | ||
expect(input.prefilled).to.equal(false); | ||
const el = await fixture(html`<${tag}></${tag}>`); | ||
el.dirty = true; | ||
el.touched = true; | ||
el.prefilled = true; | ||
el.resetInteractionState(); | ||
expect(el.dirty).to.be.false; | ||
expect(el.touched).to.be.false; | ||
expect(el.prefilled).to.be.false; | ||
input.dirty = true; | ||
input.touched = true; | ||
input.prefilled = false; | ||
input.modelValue = 'Some value'; | ||
input.resetInteractionState(); | ||
expect(input.dirty).to.equal(false); | ||
expect(input.touched).to.equal(false); | ||
expect(input.prefilled).to.equal(true); | ||
el.dirty = true; | ||
el.touched = true; | ||
el.prefilled = false; | ||
el.modelValue = 'Some value'; | ||
el.resetInteractionState(); | ||
expect(el.dirty).to.be.false; | ||
expect(el.touched).to.be.false; | ||
expect(el.prefilled).to.be.true; | ||
}); | ||
describe('SubClassers', () => { | ||
it('can override the `_leaveEvent`', async () => { | ||
const tagLeaveString = defineCE( | ||
class IState extends InteractionStateMixin(LitElement) { | ||
constructor() { | ||
super(); | ||
this._leaveEvent = 'custom-blur'; | ||
} | ||
}, | ||
); | ||
const tagLeave = unsafeStatic(tagLeaveString); | ||
const el = await fixture(html`<${tagLeave}></${tagLeave}>`); | ||
el.dispatchEvent(new Event('custom-blur')); | ||
expect(el.touched).to.be.true; | ||
}); | ||
it('can override the deprecated `leaveEvent`', async () => { | ||
const el = await fixture(html`<${tag} .leaveEvent=${'custom-blur'}></${tag}>`); | ||
expect(el._leaveEvent).to.equal('custom-blur'); | ||
}); | ||
}); | ||
}); |
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
175818
2270
Updated@lion/validate@^0.2.13