fix(accordion): navigating with tab confuses the arrow key navigation (#2056)
* fix(accordion): Handle focusin event, when tabbing to an invoker * fix(accordion): Add changeset * fix(accordion): Test if the index equals to the focusedIndex
This commit is contained in:
parent
9b9485dbaa
commit
857d47a933
3 changed files with 35 additions and 2 deletions
5
.changeset/stale-tips-begin.md
Normal file
5
.changeset/stale-tips-begin.md
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'@lion/ui': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Handle focusin event in invokers in LionAccordion. Fix tabbing issues.
|
||||||
|
|
@ -10,6 +10,7 @@ import { uuid } from '@lion/ui/core.js';
|
||||||
* @property {HTMLElement} content content node
|
* @property {HTMLElement} content content node
|
||||||
* @property {(event: Event) => unknown} clickHandler executed on click event
|
* @property {(event: Event) => unknown} clickHandler executed on click event
|
||||||
* @property {(event: Event) => unknown} keydownHandler executed on keydown event
|
* @property {(event: Event) => unknown} keydownHandler executed on keydown event
|
||||||
|
* @property {(event: Event) => unknown} focusHandler executed on focusin event
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -197,6 +198,7 @@ export class LionAccordion extends LitElement {
|
||||||
content,
|
content,
|
||||||
clickHandler: this.__createInvokerClickHandler(index),
|
clickHandler: this.__createInvokerClickHandler(index),
|
||||||
keydownHandler: this.__handleInvokerKeydown.bind(this),
|
keydownHandler: this.__handleInvokerKeydown.bind(this),
|
||||||
|
focusHandler: this.__createInvokerFocusHandler(index),
|
||||||
};
|
};
|
||||||
this._setupContent(entry);
|
this._setupContent(entry);
|
||||||
this._setupInvoker(entry);
|
this._setupInvoker(entry);
|
||||||
|
|
@ -248,6 +250,19 @@ export class LionAccordion extends LitElement {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} index
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
__createInvokerFocusHandler(index) {
|
||||||
|
return () => {
|
||||||
|
if (index === this.focusedIndex) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.focusedIndex = index;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Event} e
|
* @param {Event} e
|
||||||
* @private
|
* @private
|
||||||
|
|
@ -304,7 +319,7 @@ export class LionAccordion extends LitElement {
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
_setupInvoker(entry) {
|
_setupInvoker(entry) {
|
||||||
const { invoker, uid, index, clickHandler, keydownHandler } = entry;
|
const { invoker, uid, index, clickHandler, keydownHandler, focusHandler } = entry;
|
||||||
invoker.style.setProperty('order', `${index + 1}`);
|
invoker.style.setProperty('order', `${index + 1}`);
|
||||||
const firstChild = invoker.firstElementChild;
|
const firstChild = invoker.firstElementChild;
|
||||||
if (firstChild) {
|
if (firstChild) {
|
||||||
|
|
@ -312,6 +327,7 @@ export class LionAccordion extends LitElement {
|
||||||
firstChild.setAttribute('aria-controls', `content-${uid}`);
|
firstChild.setAttribute('aria-controls', `content-${uid}`);
|
||||||
firstChild.addEventListener('click', clickHandler);
|
firstChild.addEventListener('click', clickHandler);
|
||||||
firstChild.addEventListener('keydown', keydownHandler);
|
firstChild.addEventListener('keydown', keydownHandler);
|
||||||
|
firstChild.addEventListener('focusin', focusHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -320,13 +336,14 @@ export class LionAccordion extends LitElement {
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
_cleanInvoker(entry) {
|
_cleanInvoker(entry) {
|
||||||
const { invoker, clickHandler, keydownHandler } = entry;
|
const { invoker, clickHandler, keydownHandler, focusHandler } = entry;
|
||||||
const firstChild = invoker.firstElementChild;
|
const firstChild = invoker.firstElementChild;
|
||||||
if (firstChild) {
|
if (firstChild) {
|
||||||
firstChild.removeAttribute('id');
|
firstChild.removeAttribute('id');
|
||||||
firstChild.removeAttribute('aria-controls');
|
firstChild.removeAttribute('aria-controls');
|
||||||
firstChild.removeEventListener('click', clickHandler);
|
firstChild.removeEventListener('click', clickHandler);
|
||||||
firstChild.removeEventListener('keydown', keydownHandler);
|
firstChild.removeEventListener('keydown', keydownHandler);
|
||||||
|
firstChild.removeEventListener('focusin', focusHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -213,6 +213,17 @@ describe('<lion-accordion>', () => {
|
||||||
el.focusedIndex = 1;
|
el.focusedIndex = 1;
|
||||||
expect(spy).to.have.been.calledOnce;
|
expect(spy).to.have.been.calledOnce;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('tabbing sets the focusedIndex correctly', async () => {
|
||||||
|
const el = /** @type {LionAccordion} */ (await fixture(basicAccordion));
|
||||||
|
const invokers = getInvokers(el);
|
||||||
|
el.focusedIndex = 0;
|
||||||
|
expect(el.focusedIndex).to.equal(0);
|
||||||
|
invokers[2].firstElementChild?.dispatchEvent(new Event('focusin'));
|
||||||
|
expect(el.focusedIndex).to.equal(2);
|
||||||
|
invokers[1].firstElementChild?.dispatchEvent(new Event('focusin'));
|
||||||
|
expect(el.focusedIndex).to.equal(1);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Accordion Contents (slot=content)', () => {
|
describe('Accordion Contents (slot=content)', () => {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue