feat(button): move active to host for cross-browser support (fix #188)
This commit is contained in:
parent
e269b5d040
commit
471d662cb2
2 changed files with 72 additions and 4 deletions
|
|
@ -10,6 +10,10 @@ export class LionButton extends DisabledWithTabIndexMixin(
|
||||||
type: String,
|
type: String,
|
||||||
reflect: true,
|
reflect: true,
|
||||||
},
|
},
|
||||||
|
active: {
|
||||||
|
type: Boolean,
|
||||||
|
reflect: true,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,8 +87,8 @@ export class LionButton extends DisabledWithTabIndexMixin(
|
||||||
background: #f4f6f7;
|
background: #f4f6f7;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(:active) .btn,
|
:host(:active) .btn, /* keep native :active to render quickly where possible */
|
||||||
.btn[active] {
|
:host([active]) .btn /* use custom [active] to fix IE11 */ {
|
||||||
/* if you extend, please overwrite */
|
/* if you extend, please overwrite */
|
||||||
background: gray;
|
background: gray;
|
||||||
}
|
}
|
||||||
|
|
@ -128,6 +132,7 @@ export class LionButton extends DisabledWithTabIndexMixin(
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.role = 'button';
|
this.role = 'button';
|
||||||
|
this.active = false;
|
||||||
this.__setupDelegationInConstructor();
|
this.__setupDelegationInConstructor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -176,19 +181,31 @@ export class LionButton extends DisabledWithTabIndexMixin(
|
||||||
}
|
}
|
||||||
|
|
||||||
__setupDelegation() {
|
__setupDelegation() {
|
||||||
|
this.addEventListener('mousedown', this.__mousedownDelegationHandler);
|
||||||
|
this.addEventListener('mouseup', this.__mouseupDelegationHandler);
|
||||||
this.addEventListener('keydown', this.__keydownDelegationHandler);
|
this.addEventListener('keydown', this.__keydownDelegationHandler);
|
||||||
this.addEventListener('keyup', this.__keyupDelegationHandler);
|
this.addEventListener('keyup', this.__keyupDelegationHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
__teardownDelegation() {
|
__teardownDelegation() {
|
||||||
|
this.removeEventListener('mousedown', this.__mousedownDelegationHandler);
|
||||||
|
this.removeEventListener('mouseup', this.__mouseupDelegationHandler);
|
||||||
this.removeEventListener('keydown', this.__keydownDelegationHandler);
|
this.removeEventListener('keydown', this.__keydownDelegationHandler);
|
||||||
this.removeEventListener('keyup', this.__keyupDelegationHandler);
|
this.removeEventListener('keyup', this.__keyupDelegationHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__mousedownDelegationHandler() {
|
||||||
|
this.active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
__mouseupDelegationHandler() {
|
||||||
|
this.active = false;
|
||||||
|
}
|
||||||
|
|
||||||
__keydownDelegationHandler(e) {
|
__keydownDelegationHandler(e) {
|
||||||
if (e.keyCode === 32 /* space */ || e.keyCode === 13 /* enter */) {
|
if (e.keyCode === 32 /* space */ || e.keyCode === 13 /* enter */) {
|
||||||
e.preventDefault();
|
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
|
// and make click handlers on button work on space and enter
|
||||||
if (e.keyCode === 32 /* space */ || e.keyCode === 13 /* enter */) {
|
if (e.keyCode === 32 /* space */ || e.keyCode === 13 /* enter */) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.shadowRoot.querySelector('.btn').removeAttribute('active');
|
this.active = false;
|
||||||
this.shadowRoot.querySelector('.click-area').click();
|
this.shadowRoot.querySelector('.click-area').click();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,10 @@ import {
|
||||||
makeMouseEvent,
|
makeMouseEvent,
|
||||||
pressEnter,
|
pressEnter,
|
||||||
pressSpace,
|
pressSpace,
|
||||||
|
down,
|
||||||
|
up,
|
||||||
|
keyDownOn,
|
||||||
|
keyUpOn,
|
||||||
} from '@polymer/iron-test-helpers/mock-interactions.js';
|
} from '@polymer/iron-test-helpers/mock-interactions.js';
|
||||||
|
|
||||||
import '../lion-button.js';
|
import '../lion-button.js';
|
||||||
|
|
@ -57,6 +61,53 @@ describe('lion-button', () => {
|
||||||
expect(el.hasAttribute('disabled')).to.equal(true);
|
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', () => {
|
describe('a11y', () => {
|
||||||
it('has a role="button" by default', async () => {
|
it('has a role="button" by default', async () => {
|
||||||
const el = await fixture(`<lion-button>foo</lion-button>`);
|
const el = await fixture(`<lion-button>foo</lion-button>`);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue