fix(tabs): prevent scrolling when initially focussing a tab
This commit is contained in:
parent
2df061a17f
commit
e3bbc3ecf1
2 changed files with 53 additions and 3 deletions
|
|
@ -37,8 +37,12 @@ const cleanButton = (element, clickHandler, keydownHandler) => {
|
||||||
element.removeEventListener('keydown', e => e.preventDefault());
|
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.focus();
|
||||||
|
}
|
||||||
|
|
||||||
element.setAttribute('selected', true);
|
element.setAttribute('selected', true);
|
||||||
element.setAttribute('aria-selected', true);
|
element.setAttribute('aria-selected', true);
|
||||||
element.setAttribute('tabindex', 0);
|
element.setAttribute('tabindex', 0);
|
||||||
|
|
@ -109,6 +113,7 @@ export class LionTabs extends LitElement {
|
||||||
|
|
||||||
firstUpdated() {
|
firstUpdated() {
|
||||||
super.firstUpdated();
|
super.firstUpdated();
|
||||||
|
this.__firstUpdate = true;
|
||||||
this.__setupSlots();
|
this.__setupSlots();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -198,6 +203,7 @@ export class LionTabs extends LitElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
set selectedIndex(value) {
|
set selectedIndex(value) {
|
||||||
|
this.__firstUpdate = false;
|
||||||
const stale = this.__selectedIndex;
|
const stale = this.__selectedIndex;
|
||||||
this.__selectedIndex = value;
|
this.__selectedIndex = value;
|
||||||
this.__updateSelected();
|
this.__updateSelected();
|
||||||
|
|
@ -231,7 +237,7 @@ export class LionTabs extends LitElement {
|
||||||
}
|
}
|
||||||
const { button: currentButton, panel: currentPanel } = this.__store[this.selectedIndex];
|
const { button: currentButton, panel: currentPanel } = this.__store[this.selectedIndex];
|
||||||
if (currentButton) {
|
if (currentButton) {
|
||||||
selectButton(currentButton);
|
selectButton(currentButton, this.__firstUpdate);
|
||||||
}
|
}
|
||||||
if (currentPanel) {
|
if (currentPanel) {
|
||||||
selectPanel(currentPanel);
|
selectPanel(currentPanel);
|
||||||
|
|
|
||||||
|
|
@ -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', () => {
|
describe('Accessibility', () => {
|
||||||
it('does not make panels focusable', async () => {
|
it('does not make panels focusable', async () => {
|
||||||
const el = await fixture(html`
|
const el = await fixture(html`
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue