fix(switch): dispatch checked-changed on checked change
This commit is contained in:
parent
175e6bea6f
commit
6aacbc4403
4 changed files with 83 additions and 12 deletions
|
|
@ -51,12 +51,18 @@ export class LionSwitch extends ScopedElementsMixin(ChoiceInputMixin(LionField))
|
||||||
return html`${this._inputGroupTemplate()}`;
|
return html`${this._inputGroupTemplate()}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.role = 'switch';
|
||||||
|
this.checked = false;
|
||||||
|
this.__handleButtonSwitchCheckedChanged = this.__handleButtonSwitchCheckedChanged.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
this._inputNode.addEventListener(
|
if (this._inputNode) {
|
||||||
'checked-changed',
|
this._inputNode.addEventListener('checked-changed', this.__handleButtonSwitchCheckedChanged);
|
||||||
this.__handleButtonSwitchCheckedChanged.bind(this),
|
}
|
||||||
);
|
|
||||||
if (this._labelNode) {
|
if (this._labelNode) {
|
||||||
this._labelNode.addEventListener('click', this.__toggleChecked);
|
this._labelNode.addEventListener('click', this.__toggleChecked);
|
||||||
}
|
}
|
||||||
|
|
@ -65,6 +71,12 @@ export class LionSwitch extends ScopedElementsMixin(ChoiceInputMixin(LionField))
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnectedCallback() {
|
disconnectedCallback() {
|
||||||
|
if (this._inputNode) {
|
||||||
|
this._inputNode.removeEventListener(
|
||||||
|
'checked-changed',
|
||||||
|
this.__handleButtonSwitchCheckedChanged,
|
||||||
|
);
|
||||||
|
}
|
||||||
if (this._labelNode) {
|
if (this._labelNode) {
|
||||||
this._labelNode.removeEventListener('click', this.__toggleChecked);
|
this._labelNode.removeEventListener('click', this.__toggleChecked);
|
||||||
}
|
}
|
||||||
|
|
@ -86,7 +98,6 @@ export class LionSwitch extends ScopedElementsMixin(ChoiceInputMixin(LionField))
|
||||||
}
|
}
|
||||||
|
|
||||||
_syncButtonSwitch() {
|
_syncButtonSwitch() {
|
||||||
this._inputNode.checked = this.checked;
|
|
||||||
this._inputNode.disabled = this.disabled;
|
this._inputNode.disabled = this.disabled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,29 +74,43 @@ export class LionSwitchButton extends DisabledWithTabIndexMixin(LitElement) {
|
||||||
super();
|
super();
|
||||||
this.role = 'switch';
|
this.role = 'switch';
|
||||||
this.checked = false;
|
this.checked = false;
|
||||||
this.addEventListener('click', this.__handleToggleStateChange);
|
this.__toggleChecked = this.__toggleChecked.bind(this);
|
||||||
this.addEventListener('keydown', this.__handleKeydown);
|
this.__handleKeydown = this.__handleKeydown.bind(this);
|
||||||
this.addEventListener('keyup', this.__handleKeyup);
|
this.__handleKeyup = this.__handleKeyup.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
this.setAttribute('aria-checked', `${this.checked}`);
|
this.setAttribute('aria-checked', `${this.checked}`);
|
||||||
|
this.addEventListener('click', this.__toggleChecked);
|
||||||
|
this.addEventListener('keydown', this.__handleKeydown);
|
||||||
|
this.addEventListener('keyup', this.__handleKeyup);
|
||||||
}
|
}
|
||||||
|
|
||||||
__handleToggleStateChange() {
|
disconnectedCallback() {
|
||||||
|
super.disconnectedCallback();
|
||||||
|
this.removeEventListener('click', this.__toggleChecked);
|
||||||
|
this.removeEventListener('keydown', this.__handleKeydown);
|
||||||
|
this.removeEventListener('keyup', this.__handleKeyup);
|
||||||
|
}
|
||||||
|
|
||||||
|
__toggleChecked() {
|
||||||
if (this.disabled) {
|
if (this.disabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Force IE11 to focus the component.
|
// Force IE11 to focus the component.
|
||||||
this.focus();
|
this.focus();
|
||||||
this.checked = !this.checked;
|
this.checked = !this.checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
__checkedStateChange() {
|
||||||
this.dispatchEvent(
|
this.dispatchEvent(
|
||||||
new Event('checked-changed', {
|
new Event('checked-changed', {
|
||||||
composed: true,
|
composed: true,
|
||||||
bubbles: true,
|
bubbles: true,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
this.setAttribute('aria-checked', `${this.checked}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line class-methods-use-this
|
// eslint-disable-next-line class-methods-use-this
|
||||||
|
|
@ -109,7 +123,7 @@ export class LionSwitchButton extends DisabledWithTabIndexMixin(LitElement) {
|
||||||
|
|
||||||
__handleKeyup(e) {
|
__handleKeyup(e) {
|
||||||
if ([32 /* space */, 13 /* enter */].indexOf(e.keyCode) !== -1) {
|
if ([32 /* space */, 13 /* enter */].indexOf(e.keyCode) !== -1) {
|
||||||
this.__handleToggleStateChange();
|
this.__toggleChecked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -126,8 +140,8 @@ export class LionSwitchButton extends DisabledWithTabIndexMixin(LitElement) {
|
||||||
*/
|
*/
|
||||||
requestUpdateInternal(name, oldValue) {
|
requestUpdateInternal(name, oldValue) {
|
||||||
super.requestUpdateInternal(name, oldValue);
|
super.requestUpdateInternal(name, oldValue);
|
||||||
if (this.isConnected && name === 'checked') {
|
if (this.isConnected && name === 'checked' && this.checked !== oldValue) {
|
||||||
this.setAttribute('aria-checked', `${this.checked}`);
|
this.__checkedStateChange();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,23 @@ describe('lion-switch-button', () => {
|
||||||
checkCall(handlerSpy.getCall(1), false);
|
checkCall(handlerSpy.getCall(1), false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should dispatch "checked-changed" event when checked changed', () => {
|
||||||
|
const handlerSpy = sinon.spy();
|
||||||
|
el.addEventListener('checked-changed', handlerSpy);
|
||||||
|
el.checked = true;
|
||||||
|
el.checked = false;
|
||||||
|
expect(handlerSpy.callCount).to.equal(2);
|
||||||
|
const checkCall = call => {
|
||||||
|
expect(call.args).to.have.a.lengthOf(1);
|
||||||
|
const e = call.args[0];
|
||||||
|
expect(e).to.be.an.instanceof(Event);
|
||||||
|
expect(e.bubbles).to.be.true;
|
||||||
|
expect(e.composed).to.be.true;
|
||||||
|
};
|
||||||
|
checkCall(handlerSpy.getCall(0), true);
|
||||||
|
checkCall(handlerSpy.getCall(1), false);
|
||||||
|
});
|
||||||
|
|
||||||
it('should not dispatch "checked-changed" event if disabled', () => {
|
it('should not dispatch "checked-changed" event if disabled', () => {
|
||||||
const handlerSpy = sinon.spy();
|
const handlerSpy = sinon.spy();
|
||||||
el.disabled = true;
|
el.disabled = true;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { expect, fixture, html } from '@open-wc/testing';
|
import { expect, fixture, html } from '@open-wc/testing';
|
||||||
|
import sinon from 'sinon';
|
||||||
import '../lion-switch.js';
|
import '../lion-switch.js';
|
||||||
|
|
||||||
describe('lion-switch', () => {
|
describe('lion-switch', () => {
|
||||||
|
|
@ -68,6 +69,34 @@ describe('lion-switch', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should dispatch "checked-changed" event when toggled via button or label', async () => {
|
||||||
|
const handlerSpy = sinon.spy();
|
||||||
|
const el = await fixture(html`<lion-switch .choiceValue=${'foo'}></lion-switch>`);
|
||||||
|
el.addEventListener('checked-changed', handlerSpy);
|
||||||
|
el._inputNode.click();
|
||||||
|
el._labelNode.click();
|
||||||
|
await el.updateComplete;
|
||||||
|
expect(handlerSpy.callCount).to.equal(2);
|
||||||
|
const checkCall = call => {
|
||||||
|
expect(call.args).to.have.a.lengthOf(1);
|
||||||
|
const e = call.args[0];
|
||||||
|
expect(e).to.be.an.instanceof(Event);
|
||||||
|
expect(e.bubbles).to.be.true;
|
||||||
|
expect(e.composed).to.be.true;
|
||||||
|
};
|
||||||
|
checkCall(handlerSpy.getCall(0), true);
|
||||||
|
checkCall(handlerSpy.getCall(1), false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should dispatch "checked-changed" event when checked changed', async () => {
|
||||||
|
const handlerSpy = sinon.spy();
|
||||||
|
const el = await fixture(html`<lion-switch .choiceValue=${'foo'}></lion-switch>`);
|
||||||
|
el.addEventListener('checked-changed', handlerSpy);
|
||||||
|
el.checked = true;
|
||||||
|
await el.updateComplete;
|
||||||
|
expect(handlerSpy.callCount).to.equal(1);
|
||||||
|
});
|
||||||
|
|
||||||
it('is submitted by default', async () => {
|
it('is submitted by default', async () => {
|
||||||
const el = await fixture(html`<lion-switch></lion-switch>`);
|
const el = await fixture(html`<lion-switch></lion-switch>`);
|
||||||
expect(el.submitted).to.be.true;
|
expect(el.submitted).to.be.true;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue