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());
|
||||
};
|
||||
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
|
|||
Loading…
Reference in a new issue