feat(button): move active to host for cross-browser support (fix #188)

This commit is contained in:
Mikhail Bashkirov 2019-07-26 15:40:12 +02:00
parent e269b5d040
commit 471d662cb2
2 changed files with 72 additions and 4 deletions

View file

@ -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();
}
}

View file

@ -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(`<lion-button>foo</lion-button>`);
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(`<lion-button>foo</lion-button>`);
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(`<lion-button>foo</lion-button>`);
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(`<lion-button>foo</lion-button>`);