Skip to content

Commit 471d662

Browse files
author
Mikhail Bashkirov
committed
feat(button): move active to host for cross-browser support (fix #188)
1 parent e269b5d commit 471d662

File tree

2 files changed

+72
-4
lines changed

2 files changed

+72
-4
lines changed

packages/button/src/LionButton.js

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ export class LionButton extends DisabledWithTabIndexMixin(
1010
type: String,
1111
reflect: true,
1212
},
13+
active: {
14+
type: Boolean,
15+
reflect: true,
16+
},
1317
};
1418
}
1519

@@ -83,8 +87,8 @@ export class LionButton extends DisabledWithTabIndexMixin(
8387
background: #f4f6f7;
8488
}
8589
86-
:host(:active) .btn,
87-
.btn[active] {
90+
:host(:active) .btn, /* keep native :active to render quickly where possible */
91+
:host([active]) .btn /* use custom [active] to fix IE11 */ {
8892
/* if you extend, please overwrite */
8993
background: gray;
9094
}
@@ -128,6 +132,7 @@ export class LionButton extends DisabledWithTabIndexMixin(
128132
constructor() {
129133
super();
130134
this.role = 'button';
135+
this.active = false;
131136
this.__setupDelegationInConstructor();
132137
}
133138

@@ -176,19 +181,31 @@ export class LionButton extends DisabledWithTabIndexMixin(
176181
}
177182

178183
__setupDelegation() {
184+
this.addEventListener('mousedown', this.__mousedownDelegationHandler);
185+
this.addEventListener('mouseup', this.__mouseupDelegationHandler);
179186
this.addEventListener('keydown', this.__keydownDelegationHandler);
180187
this.addEventListener('keyup', this.__keyupDelegationHandler);
181188
}
182189

183190
__teardownDelegation() {
191+
this.removeEventListener('mousedown', this.__mousedownDelegationHandler);
192+
this.removeEventListener('mouseup', this.__mouseupDelegationHandler);
184193
this.removeEventListener('keydown', this.__keydownDelegationHandler);
185194
this.removeEventListener('keyup', this.__keyupDelegationHandler);
186195
}
187196

197+
__mousedownDelegationHandler() {
198+
this.active = true;
199+
}
200+
201+
__mouseupDelegationHandler() {
202+
this.active = false;
203+
}
204+
188205
__keydownDelegationHandler(e) {
189206
if (e.keyCode === 32 /* space */ || e.keyCode === 13 /* enter */) {
190207
e.preventDefault();
191-
this.shadowRoot.querySelector('.btn').setAttribute('active', '');
208+
this.active = true;
192209
}
193210
}
194211

@@ -197,7 +214,7 @@ export class LionButton extends DisabledWithTabIndexMixin(
197214
// and make click handlers on button work on space and enter
198215
if (e.keyCode === 32 /* space */ || e.keyCode === 13 /* enter */) {
199216
e.preventDefault();
200-
this.shadowRoot.querySelector('.btn').removeAttribute('active');
217+
this.active = false;
201218
this.shadowRoot.querySelector('.click-area').click();
202219
}
203220
}

packages/button/test/lion-button.test.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ import {
44
makeMouseEvent,
55
pressEnter,
66
pressSpace,
7+
down,
8+
up,
9+
keyDownOn,
10+
keyUpOn,
711
} from '@polymer/iron-test-helpers/mock-interactions.js';
812

913
import '../lion-button.js';
@@ -57,6 +61,53 @@ describe('lion-button', () => {
5761
expect(el.hasAttribute('disabled')).to.equal(true);
5862
});
5963

64+
describe('active', () => {
65+
it('updates "active" attribute on host when mousedown/mouseup on button', async () => {
66+
const el = await fixture(`<lion-button>foo</lion-button>`);
67+
const topEl = getTopElement(el);
68+
69+
down(topEl);
70+
expect(el.active).to.be.true;
71+
await el.updateComplete;
72+
expect(el.hasAttribute('active')).to.be.true;
73+
74+
up(topEl);
75+
expect(el.active).to.be.false;
76+
await el.updateComplete;
77+
expect(el.hasAttribute('active')).to.be.false;
78+
});
79+
80+
it('updates "active" attribute on host when space keydown/keyup on button', async () => {
81+
const el = await fixture(`<lion-button>foo</lion-button>`);
82+
const topEl = getTopElement(el);
83+
84+
keyDownOn(topEl, 32);
85+
expect(el.active).to.be.true;
86+
await el.updateComplete;
87+
expect(el.hasAttribute('active')).to.be.true;
88+
89+
keyUpOn(topEl, 32);
90+
expect(el.active).to.be.false;
91+
await el.updateComplete;
92+
expect(el.hasAttribute('active')).to.be.false;
93+
});
94+
95+
it('updates "active" attribute on host when enter keydown/keyup on button', async () => {
96+
const el = await fixture(`<lion-button>foo</lion-button>`);
97+
const topEl = getTopElement(el);
98+
99+
keyDownOn(topEl, 13);
100+
expect(el.active).to.be.true;
101+
await el.updateComplete;
102+
expect(el.hasAttribute('active')).to.be.true;
103+
104+
keyUpOn(topEl, 13);
105+
expect(el.active).to.be.false;
106+
await el.updateComplete;
107+
expect(el.hasAttribute('active')).to.be.false;
108+
});
109+
});
110+
60111
describe('a11y', () => {
61112
it('has a role="button" by default', async () => {
62113
const el = await fixture(`<lion-button>foo</lion-button>`);

0 commit comments

Comments
 (0)