fix(button): do not override user provided tabindex
This commit is contained in:
parent
92760e8ca3
commit
76ccb94435
2 changed files with 83 additions and 30 deletions
|
|
@ -8,6 +8,14 @@ export class LionButton extends DelegateMixin(SlotMixin(LionLitElement)) {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
reflect: true,
|
reflect: true,
|
||||||
},
|
},
|
||||||
|
role: {
|
||||||
|
type: String,
|
||||||
|
reflect: true,
|
||||||
|
},
|
||||||
|
tabindex: {
|
||||||
|
type: Number,
|
||||||
|
reflect: true,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -93,10 +101,10 @@ export class LionButton extends DelegateMixin(SlotMixin(LionLitElement)) {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
update(changedProperties) {
|
_requestUpdate(name, oldValue) {
|
||||||
super.update(changedProperties);
|
super._requestUpdate(name, oldValue);
|
||||||
if (changedProperties.has('disabled')) {
|
if (name === 'disabled') {
|
||||||
this.__onDisabledChanged();
|
this.__onDisabledChanged(oldValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -125,12 +133,13 @@ export class LionButton extends DelegateMixin(SlotMixin(LionLitElement)) {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.disabled = false;
|
this.disabled = false;
|
||||||
|
this.role = 'button';
|
||||||
|
this.tabindex = 0;
|
||||||
this.__keydownDelegationHandler = this.__keydownDelegationHandler.bind(this);
|
this.__keydownDelegationHandler = this.__keydownDelegationHandler.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
this.__setupA11y();
|
|
||||||
this.__setupKeydownDelegation();
|
this.__setupKeydownDelegation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -144,11 +153,6 @@ export class LionButton extends DelegateMixin(SlotMixin(LionLitElement)) {
|
||||||
this.$$slot('_button').click();
|
this.$$slot('_button').click();
|
||||||
}
|
}
|
||||||
|
|
||||||
__setupA11y() {
|
|
||||||
this.setAttribute('role', 'button');
|
|
||||||
this.setAttribute('tabindex', this.disabled ? -1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
__setupKeydownDelegation() {
|
__setupKeydownDelegation() {
|
||||||
this.addEventListener('keydown', this.__keydownDelegationHandler);
|
this.addEventListener('keydown', this.__keydownDelegationHandler);
|
||||||
}
|
}
|
||||||
|
|
@ -167,6 +171,11 @@ export class LionButton extends DelegateMixin(SlotMixin(LionLitElement)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
__onDisabledChanged() {
|
__onDisabledChanged() {
|
||||||
this.setAttribute('tabindex', this.disabled ? -1 : 0);
|
if (this.disabled) {
|
||||||
|
this.__originalTabIndex = this.tabindex;
|
||||||
|
this.tabindex = -1;
|
||||||
|
} else {
|
||||||
|
this.tabindex = this.__originalTabIndex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,43 +6,87 @@ import '../lion-button.js';
|
||||||
|
|
||||||
describe('lion-button', () => {
|
describe('lion-button', () => {
|
||||||
it('behaves like native `button` in terms of a11y', async () => {
|
it('behaves like native `button` in terms of a11y', async () => {
|
||||||
const lionButton = await fixture(`<lion-button>foo</lion-button>`);
|
const el = await fixture(`<lion-button>foo</lion-button>`);
|
||||||
expect(lionButton.getAttribute('role')).to.equal('button');
|
expect(el.getAttribute('role')).to.equal('button');
|
||||||
expect(lionButton.getAttribute('tabindex')).to.equal('0');
|
expect(el.getAttribute('tabindex')).to.equal('0');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('has no type by default on the native button', async () => {
|
it('has no type by default on the native button', async () => {
|
||||||
const lionButton = await fixture(`<lion-button>foo</lion-button>`);
|
const el = await fixture(`<lion-button>foo</lion-button>`);
|
||||||
const nativeButton = lionButton.$$slot('_button');
|
const nativeButton = el.$$slot('_button');
|
||||||
expect(nativeButton.getAttribute('type')).to.be.null;
|
expect(nativeButton.getAttribute('type')).to.be.null;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('has type="submit" on the native button when set', async () => {
|
it('has type="submit" on the native button when set', async () => {
|
||||||
const lionButton = await fixture(`<lion-button type="submit">foo</lion-button>`);
|
const el = await fixture(`<lion-button type="submit">foo</lion-button>`);
|
||||||
const nativeButton = lionButton.$$slot('_button');
|
const nativeButton = el.$$slot('_button');
|
||||||
expect(nativeButton.getAttribute('type')).to.equal('submit');
|
expect(nativeButton.getAttribute('type')).to.equal('submit');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('hides the native button in the UI', async () => {
|
it('hides the native button in the UI', async () => {
|
||||||
const lionButton = await fixture(`<lion-button>foo</lion-button>`);
|
const el = await fixture(`<lion-button>foo</lion-button>`);
|
||||||
const nativeButton = lionButton.$$slot('_button');
|
const nativeButton = el.$$slot('_button');
|
||||||
expect(nativeButton.getAttribute('tabindex')).to.equal('-1');
|
expect(nativeButton.getAttribute('tabindex')).to.equal('-1');
|
||||||
expect(window.getComputedStyle(nativeButton).visibility).to.equal('hidden');
|
expect(window.getComputedStyle(nativeButton).visibility).to.equal('hidden');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be disabled imperatively', async () => {
|
it('can be disabled imperatively', async () => {
|
||||||
const lionButton = await fixture(`<lion-button disabled>foo</lion-button>`);
|
const el = await fixture(`<lion-button disabled>foo</lion-button>`);
|
||||||
expect(lionButton.getAttribute('tabindex')).to.equal('-1');
|
expect(el.getAttribute('tabindex')).to.equal('-1');
|
||||||
|
|
||||||
lionButton.disabled = false;
|
el.disabled = false;
|
||||||
await lionButton.updateComplete;
|
await el.updateComplete;
|
||||||
expect(lionButton.getAttribute('tabindex')).to.equal('0');
|
expect(el.getAttribute('tabindex')).to.equal('0');
|
||||||
expect(lionButton.hasAttribute('disabled')).to.equal(false);
|
expect(el.hasAttribute('disabled')).to.equal(false);
|
||||||
|
|
||||||
lionButton.disabled = true;
|
el.disabled = true;
|
||||||
await lionButton.updateComplete;
|
await el.updateComplete;
|
||||||
expect(lionButton.getAttribute('tabindex')).to.equal('-1');
|
expect(el.getAttribute('tabindex')).to.equal('-1');
|
||||||
expect(lionButton.hasAttribute('disabled')).to.equal(true);
|
expect(el.hasAttribute('disabled')).to.equal(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('a11y', () => {
|
||||||
|
it('has a role="button" by default', async () => {
|
||||||
|
const el = await fixture(`<lion-button>foo</lion-button>`);
|
||||||
|
expect(el.getAttribute('role')).to.equal('button');
|
||||||
|
el.role = 'foo';
|
||||||
|
await el.updateComplete;
|
||||||
|
expect(el.getAttribute('role')).to.equal('foo');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not override user provided role', async () => {
|
||||||
|
const el = await fixture(`<lion-button role="foo">foo</lion-button>`);
|
||||||
|
expect(el.getAttribute('role')).to.equal('foo');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('has a tabindex="0" by default', async () => {
|
||||||
|
const el = await fixture(`<lion-button>foo</lion-button>`);
|
||||||
|
expect(el.getAttribute('tabindex')).to.equal('0');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('has a tabindex="-1" when disabled', async () => {
|
||||||
|
const el = await fixture(`<lion-button disabled>foo</lion-button>`);
|
||||||
|
expect(el.getAttribute('tabindex')).to.equal('-1');
|
||||||
|
el.disabled = false;
|
||||||
|
await el.updateComplete;
|
||||||
|
expect(el.getAttribute('tabindex')).to.equal('0');
|
||||||
|
el.disabled = true;
|
||||||
|
await el.updateComplete;
|
||||||
|
expect(el.getAttribute('tabindex')).to.equal('-1');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not override user provided tabindex', async () => {
|
||||||
|
const el = await fixture(`<lion-button tabindex="5">foo</lion-button>`);
|
||||||
|
expect(el.getAttribute('tabindex')).to.equal('5');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('disabled does not override user provided tabindex', async () => {
|
||||||
|
const el = await fixture(`<lion-button tabindex="5" disabled>foo</lion-button>`);
|
||||||
|
expect(el.getAttribute('tabindex')).to.equal('-1');
|
||||||
|
el.disabled = false;
|
||||||
|
await el.updateComplete;
|
||||||
|
expect(el.getAttribute('tabindex')).to.equal('5');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('form integration', () => {
|
describe('form integration', () => {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue