fix(tabs): prevent scrolling when initially focussing a tab

This commit is contained in:
Wessel Loth 2020-02-21 19:17:24 +01:00 committed by Thomas Allmer
parent 2df061a17f
commit e3bbc3ecf1
2 changed files with 53 additions and 3 deletions

View file

@ -37,8 +37,12 @@ const cleanButton = (element, clickHandler, keydownHandler) => {
element.removeEventListener('keydown', e => e.preventDefault());
};
const selectButton = element => {
const selectButton = (element, firstUpdate = false) => {
// Don't focus on first update, as the component might be lower on the page
if (!firstUpdate) {
element.focus();
}
element.setAttribute('selected', true);
element.setAttribute('aria-selected', true);
element.setAttribute('tabindex', 0);
@ -109,6 +113,7 @@ export class LionTabs extends LitElement {
firstUpdated() {
super.firstUpdated();
this.__firstUpdate = true;
this.__setupSlots();
}
@ -198,6 +203,7 @@ export class LionTabs extends LitElement {
}
set selectedIndex(value) {
this.__firstUpdate = false;
const stale = this.__selectedIndex;
this.__selectedIndex = value;
this.__updateSelected();
@ -231,7 +237,7 @@ export class LionTabs extends LitElement {
}
const { button: currentButton, panel: currentPanel } = this.__store[this.selectedIndex];
if (currentButton) {
selectButton(currentButton);
selectButton(currentButton, this.__firstUpdate);
}
if (currentPanel) {
selectPanel(currentPanel);

View file

@ -243,6 +243,50 @@ describe('<lion-tabs>', () => {
});
});
describe('Initializing without Focus', () => {
it('keeps track of when the component is updated', async () => {
const el = await fixture(html`
<lion-tabs>
<button slot="tab">tab 1</button>
<div slot="panel">panel 1</div>
<button slot="tab">tab 2</button>
<div slot="panel">panel 2</div>
</lion-tabs>
`);
expect(el.__firstUpdate).to.be.true;
el.selectedIndex = 1;
expect(el.__firstUpdate).to.be.false;
});
it('does not focus a tab on firstUpdate', async () => {
const el = await fixture(html`
<lion-tabs>
<button slot="tab">tab 1</button>
<div slot="panel">panel 1</div>
<button slot="tab">tab 2</button>
<div slot="panel">panel 2</div>
</lion-tabs>
`);
const tabs = Array.from(el.children).filter(child => child.slot === 'tab');
expect(tabs.some(tab => tab === document.activeElement)).to.be.false;
});
it('focuses on a tab when switching the selectedIndex', async () => {
const el = await fixture(html`
<lion-tabs>
<button slot="tab">tab 1</button>
<div slot="panel">panel 1</div>
<button slot="tab">tab 2</button>
<div slot="panel">panel 2</div>
</lion-tabs>
`);
el.selectedIndex = 1;
const tab = Array.from(el.children).filter(child => child.slot === 'tab')[1];
expect(tab).to.equal(document.activeElement);
});
});
describe('Accessibility', () => {
it('does not make panels focusable', async () => {
const el = await fixture(html`