diff --git a/packages/button/package.json b/packages/button/package.json index 82a49510f..7d619c179 100644 --- a/packages/button/package.json +++ b/packages/button/package.json @@ -31,9 +31,6 @@ "dependencies": { "@lion/core": "0.7.2" }, - "devDependencies": { - "@polymer/iron-test-helpers": "^3.0.1" - }, "keywords": [ "button", "lion", diff --git a/packages/button/src/LionButton.js b/packages/button/src/LionButton.js index 74070d5de..03fdc1f31 100644 --- a/packages/button/src/LionButton.js +++ b/packages/button/src/LionButton.js @@ -8,7 +8,7 @@ import { } from '@lion/core'; 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)) { static get properties() { @@ -229,8 +229,10 @@ export class LionButton extends DisabledWithTabIndexMixin(SlotMixin(LitElement)) const mouseupHandler = () => { this.active = false; document.removeEventListener('mouseup', mouseupHandler); + this.removeEventListener('mouseup', mouseupHandler); }; document.addEventListener('mouseup', mouseupHandler); + this.addEventListener('mouseup', mouseupHandler); } __keydownHandler(e) { diff --git a/packages/button/test/lion-button.test.js b/packages/button/test/lion-button.test.js index f38d10611..ebfad70d0 100644 --- a/packages/button/test/lion-button.test.js +++ b/packages/button/test/lion-button.test.js @@ -1,23 +1,13 @@ import { browserDetection } from '@lion/core'; 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 '../lion-button.js'; -function getTopElement(el) { - const { left, top, width, height } = el.getBoundingClientRect(); - // to support elementFromPoint() in polyfilled browsers we have to use document - const crossBrowserRoot = - el.shadowRoot && el.shadowRoot.elementFromPoint ? el.shadowRoot : document; - return crossBrowserRoot.elementFromPoint(left + width / 2, top + height / 2); +function getClickArea(el) { + if (el.shadowRoot) { + return el.shadowRoot.querySelector('.click-area'); + } + return undefined; } describe('lion-button', () => { @@ -75,14 +65,13 @@ describe('lion-button', () => { describe('active', () => { it('updates "active" attribute on host when mousedown/mouseup on button', async () => { const el = await fixture(`foo`); - const topEl = getTopElement(el); + el.dispatchEvent(new Event('mousedown')); - down(topEl); expect(el.active).to.be.true; await el.updateComplete; expect(el.hasAttribute('active')).to.be.true; - up(topEl); + el.dispatchEvent(new Event('mouseup')); expect(el.active).to.be.false; await el.updateComplete; 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 () => { const el = await fixture(`foo`); - const topEl = getTopElement(el); - down(topEl); + el.dispatchEvent(new Event('mousedown')); expect(el.active).to.be.true; await el.updateComplete; expect(el.hasAttribute('active')).to.be.true; - up(document.body); + document.dispatchEvent(new Event('mouseup')); expect(el.active).to.be.false; await el.updateComplete; 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 () => { const el = await fixture(`foo`); - const topEl = getTopElement(el); - keyDownOn(topEl, 32); + el.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 32 })); expect(el.active).to.be.true; await el.updateComplete; expect(el.hasAttribute('active')).to.be.true; - keyUpOn(topEl, 32); + el.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 32 })); expect(el.active).to.be.false; await el.updateComplete; 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 () => { const el = await fixture(`foo`); - const topEl = getTopElement(el); - keyDownOn(topEl, 32); + el.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 32 })); expect(el.active).to.be.true; await el.updateComplete; expect(el.hasAttribute('active')).to.be.true; - keyUpOn(document.body, 32); + el.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 32 })); expect(el.active).to.be.false; await el.updateComplete; 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 () => { const el = await fixture(`foo`); - const topEl = getTopElement(el); - keyDownOn(topEl, 13); + el.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 13 })); expect(el.active).to.be.true; await el.updateComplete; expect(el.hasAttribute('active')).to.be.true; - keyUpOn(topEl, 13); + el.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 13 })); expect(el.active).to.be.false; await el.updateComplete; 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 () => { const el = await fixture(`foo`); - const topEl = getTopElement(el); - keyDownOn(topEl, 13); + el.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 13 })); expect(el.active).to.be.true; await el.updateComplete; 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; await el.updateComplete; expect(el.hasAttribute('active')).to.be.false; @@ -247,7 +231,7 @@ describe('lion-button', () => { `); const button = form.querySelector('lion-button'); - getTopElement(button).click(); + getClickArea(button).click(); expect(formSubmitSpy.callCount).to.equal(1); }); @@ -260,10 +244,11 @@ describe('lion-button', () => { `); - pressSpace(form.querySelector('lion-button')); + form + .querySelector('lion-button') + .dispatchEvent(new KeyboardEvent('keyup', { keyCode: 32 })); await aTimeout(); await aTimeout(); - expect(formSubmitSpy.callCount).to.equal(1); }); @@ -275,7 +260,9 @@ describe('lion-button', () => { `); - pressEnter(form.querySelector('lion-button')); + form + .querySelector('lion-button') + .dispatchEvent(new KeyboardEvent('keyup', { keyCode: 13 })); await aTimeout(); await aTimeout(); @@ -316,7 +303,9 @@ describe('lion-button', () => { `); - pressEnter(form.querySelector('input[name="foo2"]')); + form + .querySelector('input[name="foo2"]') + .dispatchEvent(new KeyboardEvent('keyup', { key: 13 })); await aTimeout(); await aTimeout(); @@ -334,7 +323,7 @@ describe('lion-button', () => { `); const button = form.querySelector('lion-button'); - getTopElement(button).click(); + getClickArea(button).click(); expect(formButtonClickedSpy.callCount).to.equal(1); }); @@ -347,7 +336,9 @@ describe('lion-button', () => { `); - pressSpace(form.querySelector('lion-button')); + form + .querySelector('lion-button') + .dispatchEvent(new KeyboardEvent('keyup', { keyCode: 32 })); await aTimeout(); await aTimeout(); @@ -362,7 +353,9 @@ describe('lion-button', () => { `); - pressEnter(form.querySelector('lion-button')); + form + .querySelector('lion-button') + .dispatchEvent(new KeyboardEvent('keyup', { keyCode: 13 })); await aTimeout(); await aTimeout(); @@ -380,7 +373,9 @@ describe('lion-button', () => { `); - pressEnter(form.querySelector('input[name="foo2"]')); + form + .querySelector('input[name="foo2"]') + .dispatchEvent(new KeyboardEvent('keyup', { key: 13 })); await aTimeout(); await aTimeout(); @@ -394,7 +389,7 @@ describe('lion-button', () => { const clickSpy = sinon.spy(); const el = await fixture(html`foo`); - getTopElement(el).click(); + getClickArea(el).click(); // trying to wait for other possible redispatched events await aTimeout(); @@ -406,7 +401,11 @@ describe('lion-button', () => { describe('native button behavior', async () => { async function prepareClickEvent(el) { setTimeout(() => { - makeMouseEvent('click', { x: 11, y: 11 }, getTopElement(el)); + if (getClickArea(el)) { + getClickArea(el).click(); + } else { + el.click(); + } }); return oneEvent(el, 'click'); }