diff --git a/packages/button/src/LionButton.js b/packages/button/src/LionButton.js
index f55e12558..23f027799 100644
--- a/packages/button/src/LionButton.js
+++ b/packages/button/src/LionButton.js
@@ -10,6 +10,10 @@ export class LionButton extends DisabledWithTabIndexMixin(
type: String,
reflect: true,
},
+ active: {
+ type: Boolean,
+ reflect: true,
+ },
};
}
@@ -83,8 +87,8 @@ export class LionButton extends DisabledWithTabIndexMixin(
background: #f4f6f7;
}
- :host(:active) .btn,
- .btn[active] {
+ :host(:active) .btn, /* keep native :active to render quickly where possible */
+ :host([active]) .btn /* use custom [active] to fix IE11 */ {
/* if you extend, please overwrite */
background: gray;
}
@@ -128,6 +132,7 @@ export class LionButton extends DisabledWithTabIndexMixin(
constructor() {
super();
this.role = 'button';
+ this.active = false;
this.__setupDelegationInConstructor();
}
@@ -176,19 +181,31 @@ export class LionButton extends DisabledWithTabIndexMixin(
}
__setupDelegation() {
+ this.addEventListener('mousedown', this.__mousedownDelegationHandler);
+ this.addEventListener('mouseup', this.__mouseupDelegationHandler);
this.addEventListener('keydown', this.__keydownDelegationHandler);
this.addEventListener('keyup', this.__keyupDelegationHandler);
}
__teardownDelegation() {
+ this.removeEventListener('mousedown', this.__mousedownDelegationHandler);
+ this.removeEventListener('mouseup', this.__mouseupDelegationHandler);
this.removeEventListener('keydown', this.__keydownDelegationHandler);
this.removeEventListener('keyup', this.__keyupDelegationHandler);
}
+ __mousedownDelegationHandler() {
+ this.active = true;
+ }
+
+ __mouseupDelegationHandler() {
+ this.active = false;
+ }
+
__keydownDelegationHandler(e) {
if (e.keyCode === 32 /* space */ || e.keyCode === 13 /* enter */) {
e.preventDefault();
- this.shadowRoot.querySelector('.btn').setAttribute('active', '');
+ this.active = true;
}
}
@@ -197,7 +214,7 @@ export class LionButton extends DisabledWithTabIndexMixin(
// and make click handlers on button work on space and enter
if (e.keyCode === 32 /* space */ || e.keyCode === 13 /* enter */) {
e.preventDefault();
- this.shadowRoot.querySelector('.btn').removeAttribute('active');
+ this.active = false;
this.shadowRoot.querySelector('.click-area').click();
}
}
diff --git a/packages/button/test/lion-button.test.js b/packages/button/test/lion-button.test.js
index 1d94aaa46..cb2c15580 100644
--- a/packages/button/test/lion-button.test.js
+++ b/packages/button/test/lion-button.test.js
@@ -4,6 +4,10 @@ import {
makeMouseEvent,
pressEnter,
pressSpace,
+ down,
+ up,
+ keyDownOn,
+ keyUpOn,
} from '@polymer/iron-test-helpers/mock-interactions.js';
import '../lion-button.js';
@@ -57,6 +61,53 @@ describe('lion-button', () => {
expect(el.hasAttribute('disabled')).to.equal(true);
});
+ describe('active', () => {
+ it('updates "active" attribute on host when mousedown/mouseup on button', async () => {
+ const el = await fixture(`foo`);
+ const topEl = getTopElement(el);
+
+ down(topEl);
+ expect(el.active).to.be.true;
+ await el.updateComplete;
+ expect(el.hasAttribute('active')).to.be.true;
+
+ up(topEl);
+ expect(el.active).to.be.false;
+ await el.updateComplete;
+ expect(el.hasAttribute('active')).to.be.false;
+ });
+
+ 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);
+ expect(el.active).to.be.true;
+ await el.updateComplete;
+ expect(el.hasAttribute('active')).to.be.true;
+
+ keyUpOn(topEl, 32);
+ expect(el.active).to.be.false;
+ await el.updateComplete;
+ expect(el.hasAttribute('active')).to.be.false;
+ });
+
+ 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);
+ expect(el.active).to.be.true;
+ await el.updateComplete;
+ expect(el.hasAttribute('active')).to.be.true;
+
+ keyUpOn(topEl, 13);
+ expect(el.active).to.be.false;
+ await el.updateComplete;
+ expect(el.hasAttribute('active')).to.be.false;
+ });
+ });
+
describe('a11y', () => {
it('has a role="button" by default', async () => {
const el = await fixture(`foo`);