fix(switch): stop checked-changed event from propagating too far

This commit is contained in:
Joren Broekema 2021-06-10 10:28:44 +02:00
parent ead8264261
commit 077113bab2
5 changed files with 30 additions and 13 deletions

View file

@ -0,0 +1,5 @@
---
'@lion/switch': patch
---
Stop checked-changed event from propagating when caught by lion-switch element.

View file

@ -84,9 +84,7 @@ export class LionSwitch extends ScopedElementsMixin(ChoiceInputMixin(LionField))
connectedCallback() { connectedCallback() {
super.connectedCallback(); super.connectedCallback();
if (this._inputNode) { this.addEventListener('checked-changed', this.__handleButtonSwitchCheckedChanged);
this._inputNode.addEventListener('checked-changed', this.__handleButtonSwitchCheckedChanged);
}
if (this._labelNode) { if (this._labelNode) {
this._labelNode.addEventListener('click', this._toggleChecked); this._labelNode.addEventListener('click', this._toggleChecked);
} }
@ -95,10 +93,7 @@ export class LionSwitch extends ScopedElementsMixin(ChoiceInputMixin(LionField))
disconnectedCallback() { disconnectedCallback() {
if (this._inputNode) { if (this._inputNode) {
this._inputNode.removeEventListener( this.removeEventListener('checked-changed', this.__handleButtonSwitchCheckedChanged);
'checked-changed',
this.__handleButtonSwitchCheckedChanged,
);
} }
if (this._labelNode) { if (this._labelNode) {
this._labelNode.removeEventListener('click', this._toggleChecked); this._labelNode.removeEventListener('click', this._toggleChecked);
@ -120,8 +115,12 @@ export class LionSwitch extends ScopedElementsMixin(ChoiceInputMixin(LionField))
return false; return false;
} }
/** @private */ /**
__handleButtonSwitchCheckedChanged() { * @private
* @param {Event} ev
*/
__handleButtonSwitchCheckedChanged(ev) {
ev.stopPropagation();
this._isHandlingUserInput = true; this._isHandlingUserInput = true;
this.checked = this._inputNode.checked; this.checked = this._inputNode.checked;
this._isHandlingUserInput = false; this._isHandlingUserInput = false;

View file

@ -114,7 +114,6 @@ export class LionSwitchButton extends DisabledWithTabIndexMixin(LitElement) {
__checkedStateChange() { __checkedStateChange() {
this.dispatchEvent( this.dispatchEvent(
new Event('checked-changed', { new Event('checked-changed', {
composed: true,
bubbles: true, bubbles: true,
}), }),
); );

View file

@ -76,7 +76,6 @@ describe('lion-switch-button', () => {
const e = call.args[0]; const e = call.args[0];
expect(e).to.be.an.instanceof(Event); expect(e).to.be.an.instanceof(Event);
expect(e.bubbles).to.be.true; expect(e.bubbles).to.be.true;
expect(e.composed).to.be.true;
}; };
checkCall(handlerSpy.getCall(0)); checkCall(handlerSpy.getCall(0));
checkCall(handlerSpy.getCall(1)); checkCall(handlerSpy.getCall(1));
@ -93,7 +92,6 @@ describe('lion-switch-button', () => {
const e = call.args[0]; const e = call.args[0];
expect(e).to.be.an.instanceof(Event); expect(e).to.be.an.instanceof(Event);
expect(e.bubbles).to.be.true; expect(e.bubbles).to.be.true;
expect(e.composed).to.be.true;
}; };
checkCall(handlerSpy.getCall(0)); checkCall(handlerSpy.getCall(0));
checkCall(handlerSpy.getCall(1)); checkCall(handlerSpy.getCall(1));

View file

@ -142,7 +142,6 @@ describe('lion-switch', () => {
const e = call.args[0]; const e = call.args[0];
expect(e).to.be.an.instanceof(Event); expect(e).to.be.an.instanceof(Event);
expect(e.bubbles).to.be.true; expect(e.bubbles).to.be.true;
expect(e.composed).to.be.true;
}; };
checkCall(handlerSpy.getCall(0)); checkCall(handlerSpy.getCall(0));
checkCall(handlerSpy.getCall(1)); checkCall(handlerSpy.getCall(1));
@ -157,6 +156,23 @@ describe('lion-switch', () => {
expect(handlerSpy.callCount).to.equal(1); expect(handlerSpy.callCount).to.equal(1);
}); });
it('should not propagate the "checked-changed" event further up when caught by switch', async () => {
const handlerSpy = sinon.spy();
const parentHandlerSpy = sinon.spy();
const el = await fixture(
html`
<div @checked-changed=${parentHandlerSpy}>
<lion-switch @checked-changed=${handlerSpy} .choiceValue=${'foo'}></lion-switch>
</div>
`,
);
const switchEl = /** @type {LionSwitch} */ (el.firstElementChild);
switchEl.checked = true;
await switchEl.updateComplete;
expect(handlerSpy.callCount).to.equal(1);
expect(parentHandlerSpy.callCount).to.equal(0);
});
it('can be configured to show feedback messages immediately', async () => { it('can be configured to show feedback messages immediately', async () => {
const tagName = 'custom-switch'; const tagName = 'custom-switch';
if (!customElements.get(tagName)) { if (!customElements.get(tagName)) {