fix(button): add mouseupHandler also on 'this', remove iron test helpers

This commit is contained in:
Joren Broekema 2020-06-30 16:29:40 +02:00
parent 530540a9e1
commit 9f9d49ebcf
3 changed files with 46 additions and 48 deletions

View file

@ -31,9 +31,6 @@
"dependencies": { "dependencies": {
"@lion/core": "0.7.2" "@lion/core": "0.7.2"
}, },
"devDependencies": {
"@polymer/iron-test-helpers": "^3.0.1"
},
"keywords": [ "keywords": [
"button", "button",
"lion", "lion",

View file

@ -8,7 +8,7 @@ import {
} from '@lion/core'; } from '@lion/core';
const isKeyboardClickEvent = e => e.keyCode === 32 /* space */ || e.keyCode === 13; /* enter */ const isKeyboardClickEvent = e => e.keyCode === 32 /* space */ || e.keyCode === 13; /* enter */
const isSpaceKeyboardClickEvent = e => e.keyCode === 32; /* space */ const isSpaceKeyboardClickEvent = e => e.keyCode === 32 || e.key === 32; /* space */
export class LionButton extends DisabledWithTabIndexMixin(SlotMixin(LitElement)) { export class LionButton extends DisabledWithTabIndexMixin(SlotMixin(LitElement)) {
static get properties() { static get properties() {
@ -229,8 +229,10 @@ export class LionButton extends DisabledWithTabIndexMixin(SlotMixin(LitElement))
const mouseupHandler = () => { const mouseupHandler = () => {
this.active = false; this.active = false;
document.removeEventListener('mouseup', mouseupHandler); document.removeEventListener('mouseup', mouseupHandler);
this.removeEventListener('mouseup', mouseupHandler);
}; };
document.addEventListener('mouseup', mouseupHandler); document.addEventListener('mouseup', mouseupHandler);
this.addEventListener('mouseup', mouseupHandler);
} }
__keydownHandler(e) { __keydownHandler(e) {

View file

@ -1,23 +1,13 @@
import { browserDetection } from '@lion/core'; import { browserDetection } from '@lion/core';
import { aTimeout, expect, fixture, html, oneEvent } from '@open-wc/testing'; import { aTimeout, expect, fixture, html, oneEvent } from '@open-wc/testing';
import {
down,
keyDownOn,
keyUpOn,
makeMouseEvent,
pressEnter,
pressSpace,
up,
} from '@polymer/iron-test-helpers/mock-interactions.js';
import sinon from 'sinon'; import sinon from 'sinon';
import '../lion-button.js'; import '../lion-button.js';
function getTopElement(el) { function getClickArea(el) {
const { left, top, width, height } = el.getBoundingClientRect(); if (el.shadowRoot) {
// to support elementFromPoint() in polyfilled browsers we have to use document return el.shadowRoot.querySelector('.click-area');
const crossBrowserRoot = }
el.shadowRoot && el.shadowRoot.elementFromPoint ? el.shadowRoot : document; return undefined;
return crossBrowserRoot.elementFromPoint(left + width / 2, top + height / 2);
} }
describe('lion-button', () => { describe('lion-button', () => {
@ -75,14 +65,13 @@ describe('lion-button', () => {
describe('active', () => { describe('active', () => {
it('updates "active" attribute on host when mousedown/mouseup on button', async () => { it('updates "active" attribute on host when mousedown/mouseup on button', async () => {
const el = await fixture(`<lion-button>foo</lion-button>`); const el = await fixture(`<lion-button>foo</lion-button>`);
const topEl = getTopElement(el); el.dispatchEvent(new Event('mousedown'));
down(topEl);
expect(el.active).to.be.true; expect(el.active).to.be.true;
await el.updateComplete; await el.updateComplete;
expect(el.hasAttribute('active')).to.be.true; expect(el.hasAttribute('active')).to.be.true;
up(topEl); el.dispatchEvent(new Event('mouseup'));
expect(el.active).to.be.false; expect(el.active).to.be.false;
await el.updateComplete; await el.updateComplete;
expect(el.hasAttribute('active')).to.be.false; expect(el.hasAttribute('active')).to.be.false;
@ -90,14 +79,13 @@ describe('lion-button', () => {
it('updates "active" attribute on host when mousedown on button and mouseup anywhere else', async () => { it('updates "active" attribute on host when mousedown on button and mouseup anywhere else', async () => {
const el = await fixture(`<lion-button>foo</lion-button>`); const el = await fixture(`<lion-button>foo</lion-button>`);
const topEl = getTopElement(el);
down(topEl); el.dispatchEvent(new Event('mousedown'));
expect(el.active).to.be.true; expect(el.active).to.be.true;
await el.updateComplete; await el.updateComplete;
expect(el.hasAttribute('active')).to.be.true; expect(el.hasAttribute('active')).to.be.true;
up(document.body); document.dispatchEvent(new Event('mouseup'));
expect(el.active).to.be.false; expect(el.active).to.be.false;
await el.updateComplete; await el.updateComplete;
expect(el.hasAttribute('active')).to.be.false; expect(el.hasAttribute('active')).to.be.false;
@ -105,14 +93,13 @@ describe('lion-button', () => {
it('updates "active" attribute on host when space keydown/keyup on button', async () => { it('updates "active" attribute on host when space keydown/keyup on button', async () => {
const el = await fixture(`<lion-button>foo</lion-button>`); const el = await fixture(`<lion-button>foo</lion-button>`);
const topEl = getTopElement(el);
keyDownOn(topEl, 32); el.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 32 }));
expect(el.active).to.be.true; expect(el.active).to.be.true;
await el.updateComplete; await el.updateComplete;
expect(el.hasAttribute('active')).to.be.true; expect(el.hasAttribute('active')).to.be.true;
keyUpOn(topEl, 32); el.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 32 }));
expect(el.active).to.be.false; expect(el.active).to.be.false;
await el.updateComplete; await el.updateComplete;
expect(el.hasAttribute('active')).to.be.false; expect(el.hasAttribute('active')).to.be.false;
@ -120,14 +107,13 @@ describe('lion-button', () => {
it('updates "active" attribute on host when space keydown on button and space keyup anywhere else', async () => { it('updates "active" attribute on host when space keydown on button and space keyup anywhere else', async () => {
const el = await fixture(`<lion-button>foo</lion-button>`); const el = await fixture(`<lion-button>foo</lion-button>`);
const topEl = getTopElement(el);
keyDownOn(topEl, 32); el.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 32 }));
expect(el.active).to.be.true; expect(el.active).to.be.true;
await el.updateComplete; await el.updateComplete;
expect(el.hasAttribute('active')).to.be.true; expect(el.hasAttribute('active')).to.be.true;
keyUpOn(document.body, 32); el.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 32 }));
expect(el.active).to.be.false; expect(el.active).to.be.false;
await el.updateComplete; await el.updateComplete;
expect(el.hasAttribute('active')).to.be.false; expect(el.hasAttribute('active')).to.be.false;
@ -135,14 +121,13 @@ describe('lion-button', () => {
it('updates "active" attribute on host when enter keydown/keyup on button', async () => { it('updates "active" attribute on host when enter keydown/keyup on button', async () => {
const el = await fixture(`<lion-button>foo</lion-button>`); const el = await fixture(`<lion-button>foo</lion-button>`);
const topEl = getTopElement(el);
keyDownOn(topEl, 13); el.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 13 }));
expect(el.active).to.be.true; expect(el.active).to.be.true;
await el.updateComplete; await el.updateComplete;
expect(el.hasAttribute('active')).to.be.true; expect(el.hasAttribute('active')).to.be.true;
keyUpOn(topEl, 13); el.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 13 }));
expect(el.active).to.be.false; expect(el.active).to.be.false;
await el.updateComplete; await el.updateComplete;
expect(el.hasAttribute('active')).to.be.false; expect(el.hasAttribute('active')).to.be.false;
@ -150,14 +135,13 @@ describe('lion-button', () => {
it('updates "active" attribute on host when enter keydown on button and space keyup anywhere else', async () => { it('updates "active" attribute on host when enter keydown on button and space keyup anywhere else', async () => {
const el = await fixture(`<lion-button>foo</lion-button>`); const el = await fixture(`<lion-button>foo</lion-button>`);
const topEl = getTopElement(el);
keyDownOn(topEl, 13); el.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 13 }));
expect(el.active).to.be.true; expect(el.active).to.be.true;
await el.updateComplete; await el.updateComplete;
expect(el.hasAttribute('active')).to.be.true; expect(el.hasAttribute('active')).to.be.true;
keyUpOn(document.body, 13); document.body.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 13 }));
expect(el.active).to.be.false; expect(el.active).to.be.false;
await el.updateComplete; await el.updateComplete;
expect(el.hasAttribute('active')).to.be.false; expect(el.hasAttribute('active')).to.be.false;
@ -247,7 +231,7 @@ describe('lion-button', () => {
`); `);
const button = form.querySelector('lion-button'); const button = form.querySelector('lion-button');
getTopElement(button).click(); getClickArea(button).click();
expect(formSubmitSpy.callCount).to.equal(1); expect(formSubmitSpy.callCount).to.equal(1);
}); });
@ -260,10 +244,11 @@ describe('lion-button', () => {
</form> </form>
`); `);
pressSpace(form.querySelector('lion-button')); form
.querySelector('lion-button')
.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 32 }));
await aTimeout(); await aTimeout();
await aTimeout(); await aTimeout();
expect(formSubmitSpy.callCount).to.equal(1); expect(formSubmitSpy.callCount).to.equal(1);
}); });
@ -275,7 +260,9 @@ describe('lion-button', () => {
</form> </form>
`); `);
pressEnter(form.querySelector('lion-button')); form
.querySelector('lion-button')
.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 13 }));
await aTimeout(); await aTimeout();
await aTimeout(); await aTimeout();
@ -316,7 +303,9 @@ describe('lion-button', () => {
</form> </form>
`); `);
pressEnter(form.querySelector('input[name="foo2"]')); form
.querySelector('input[name="foo2"]')
.dispatchEvent(new KeyboardEvent('keyup', { key: 13 }));
await aTimeout(); await aTimeout();
await aTimeout(); await aTimeout();
@ -334,7 +323,7 @@ describe('lion-button', () => {
`); `);
const button = form.querySelector('lion-button'); const button = form.querySelector('lion-button');
getTopElement(button).click(); getClickArea(button).click();
expect(formButtonClickedSpy.callCount).to.equal(1); expect(formButtonClickedSpy.callCount).to.equal(1);
}); });
@ -347,7 +336,9 @@ describe('lion-button', () => {
</form> </form>
`); `);
pressSpace(form.querySelector('lion-button')); form
.querySelector('lion-button')
.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 32 }));
await aTimeout(); await aTimeout();
await aTimeout(); await aTimeout();
@ -362,7 +353,9 @@ describe('lion-button', () => {
</form> </form>
`); `);
pressEnter(form.querySelector('lion-button')); form
.querySelector('lion-button')
.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 13 }));
await aTimeout(); await aTimeout();
await aTimeout(); await aTimeout();
@ -380,7 +373,9 @@ describe('lion-button', () => {
</form> </form>
`); `);
pressEnter(form.querySelector('input[name="foo2"]')); form
.querySelector('input[name="foo2"]')
.dispatchEvent(new KeyboardEvent('keyup', { key: 13 }));
await aTimeout(); await aTimeout();
await aTimeout(); await aTimeout();
@ -394,7 +389,7 @@ describe('lion-button', () => {
const clickSpy = sinon.spy(); const clickSpy = sinon.spy();
const el = await fixture(html`<lion-button @click="${clickSpy}">foo</lion-button>`); const el = await fixture(html`<lion-button @click="${clickSpy}">foo</lion-button>`);
getTopElement(el).click(); getClickArea(el).click();
// trying to wait for other possible redispatched events // trying to wait for other possible redispatched events
await aTimeout(); await aTimeout();
@ -406,7 +401,11 @@ describe('lion-button', () => {
describe('native button behavior', async () => { describe('native button behavior', async () => {
async function prepareClickEvent(el) { async function prepareClickEvent(el) {
setTimeout(() => { setTimeout(() => {
makeMouseEvent('click', { x: 11, y: 11 }, getTopElement(el)); if (getClickArea(el)) {
getClickArea(el).click();
} else {
el.click();
}
}); });
return oneEvent(el, 'click'); return oneEvent(el, 'click');
} }