Merge pull request #783 from ing-bank/fix/keyboard-interactio-accordion
fix(accordion): fix keyboard interaction
This commit is contained in:
commit
9f6fbb66a1
3 changed files with 40 additions and 38 deletions
|
|
@ -2,41 +2,41 @@
|
||||||
"name": "@lion/accordion",
|
"name": "@lion/accordion",
|
||||||
"version": "0.1.1",
|
"version": "0.1.1",
|
||||||
"description": "Vertically stacked list of invokers that can be clicked to reveal or hide content associated with them.",
|
"description": "Vertically stacked list of invokers that can be clicked to reveal or hide content associated with them.",
|
||||||
|
"license": "MIT",
|
||||||
"author": "ing-bank",
|
"author": "ing-bank",
|
||||||
"homepage": "https://github.com/ing-bank/lion/",
|
"homepage": "https://github.com/ing-bank/lion/",
|
||||||
"license": "MIT",
|
|
||||||
"publishConfig": {
|
|
||||||
"access": "public"
|
|
||||||
},
|
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/ing-bank/lion.git",
|
"url": "https://github.com/ing-bank/lion.git",
|
||||||
"directory": "packages/accordion"
|
"directory": "packages/accordion"
|
||||||
},
|
},
|
||||||
|
"main": "index.js",
|
||||||
|
"module": "index.js",
|
||||||
|
"files": [
|
||||||
|
"*.js",
|
||||||
|
"docs",
|
||||||
|
"src",
|
||||||
|
"test",
|
||||||
|
"translations"
|
||||||
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepublishOnly": "../../scripts/npm-prepublish.js",
|
"prepublishOnly": "../../scripts/npm-prepublish.js",
|
||||||
"start": "cd ../../ && yarn dev-server --open packages/tabs/README.md",
|
"start": "cd ../../ && yarn dev-server --open packages/tabs/README.md",
|
||||||
"test": "cd ../../ && yarn test:browser --grep \"packages/tabs/test/**/*.test.js\"",
|
"test": "cd ../../ && yarn test:browser --grep \"packages/tabs/test/**/*.test.js\"",
|
||||||
"test:watch": "cd ../../ && yarn test:browser:watch --grep \"packages/tabs/test/**/*.test.js\""
|
"test:watch": "cd ../../ && yarn test:browser:watch --grep \"packages/tabs/test/**/*.test.js\""
|
||||||
},
|
},
|
||||||
"keywords": [
|
|
||||||
"lion",
|
|
||||||
"web-components",
|
|
||||||
"accordion"
|
|
||||||
],
|
|
||||||
"main": "index.js",
|
|
||||||
"module": "index.js",
|
|
||||||
"files": [
|
|
||||||
"docs",
|
|
||||||
"src",
|
|
||||||
"test",
|
|
||||||
"translations",
|
|
||||||
"*.js"
|
|
||||||
],
|
|
||||||
"sideEffects": [
|
"sideEffects": [
|
||||||
"lion-accordion.js"
|
"lion-accordion.js"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@lion/core": "0.7.2"
|
"@lion/core": "0.7.2"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"accordion",
|
||||||
|
"lion",
|
||||||
|
"web-components"
|
||||||
|
],
|
||||||
|
"publishConfig": {
|
||||||
|
"access": "public"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,14 +13,14 @@ const setupInvoker = ({ element, uid, index, clickHandler, keydownHandler }) =>
|
||||||
element.firstElementChild.setAttribute('id', `invoker-${uid}`);
|
element.firstElementChild.setAttribute('id', `invoker-${uid}`);
|
||||||
element.firstElementChild.setAttribute('aria-controls', `content-${uid}`);
|
element.firstElementChild.setAttribute('aria-controls', `content-${uid}`);
|
||||||
element.firstElementChild.addEventListener('click', clickHandler);
|
element.firstElementChild.addEventListener('click', clickHandler);
|
||||||
element.firstElementChild.addEventListener('keyup', keydownHandler);
|
element.firstElementChild.addEventListener('keydown', keydownHandler);
|
||||||
};
|
};
|
||||||
|
|
||||||
const cleanInvoker = (element, clickHandler, keydownHandler) => {
|
const cleanInvoker = (element, clickHandler, keydownHandler) => {
|
||||||
element.firstElementChild.removeAttribute('id');
|
element.firstElementChild.removeAttribute('id');
|
||||||
element.firstElementChild.removeAttribute('aria-controls');
|
element.firstElementChild.removeAttribute('aria-controls');
|
||||||
element.firstElementChild.removeEventListener('click', clickHandler);
|
element.firstElementChild.removeEventListener('click', clickHandler);
|
||||||
element.firstElementChild.removeEventListener('keyup', keydownHandler);
|
element.firstElementChild.removeEventListener('keydown', keydownHandler);
|
||||||
};
|
};
|
||||||
|
|
||||||
const focusInvoker = element => {
|
const focusInvoker = element => {
|
||||||
|
|
@ -190,18 +190,14 @@ export class LionAccordion extends LitElement {
|
||||||
case 'ArrowDown':
|
case 'ArrowDown':
|
||||||
case 'ArrowRight':
|
case 'ArrowRight':
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (this.focusedIndex + 1 >= this._pairCount) {
|
if (this.focusedIndex + 2 <= this._pairCount) {
|
||||||
this.focusedIndex = 0;
|
|
||||||
} else {
|
|
||||||
this.focusedIndex += 1;
|
this.focusedIndex += 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'ArrowUp':
|
case 'ArrowUp':
|
||||||
case 'ArrowLeft':
|
case 'ArrowLeft':
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (this.focusedIndex <= 0) {
|
if (this.focusedIndex >= 1) {
|
||||||
this.focusedIndex = this._pairCount - 1;
|
|
||||||
} else {
|
|
||||||
this.focusedIndex -= 1;
|
this.focusedIndex -= 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -199,10 +199,12 @@ describe('<lion-accordion>', () => {
|
||||||
const invokers = el.querySelectorAll('[slot=invoker]');
|
const invokers = el.querySelectorAll('[slot=invoker]');
|
||||||
el.focusedIndex = 0;
|
el.focusedIndex = 0;
|
||||||
invokers[0].firstElementChild.dispatchEvent(
|
invokers[0].firstElementChild.dispatchEvent(
|
||||||
new KeyboardEvent('keyup', { key: 'ArrowRight' }),
|
new KeyboardEvent('keydown', { key: 'ArrowRight' }),
|
||||||
);
|
);
|
||||||
expect(el.focusedIndex).to.equal(1);
|
expect(el.focusedIndex).to.equal(1);
|
||||||
invokers[0].firstElementChild.dispatchEvent(new KeyboardEvent('keyup', { key: 'ArrowDown' }));
|
invokers[0].firstElementChild.dispatchEvent(
|
||||||
|
new KeyboardEvent('keydown', { key: 'ArrowDown' }),
|
||||||
|
);
|
||||||
expect(el.focusedIndex).to.equal(2);
|
expect(el.focusedIndex).to.equal(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -219,9 +221,11 @@ describe('<lion-accordion>', () => {
|
||||||
`);
|
`);
|
||||||
const invokers = el.querySelectorAll('[slot=invoker]');
|
const invokers = el.querySelectorAll('[slot=invoker]');
|
||||||
el.focusedIndex = 2;
|
el.focusedIndex = 2;
|
||||||
invokers[2].firstElementChild.dispatchEvent(new KeyboardEvent('keyup', { key: 'ArrowLeft' }));
|
invokers[2].firstElementChild.dispatchEvent(
|
||||||
|
new KeyboardEvent('keydown', { key: 'ArrowLeft' }),
|
||||||
|
);
|
||||||
expect(el.focusedIndex).to.equal(1);
|
expect(el.focusedIndex).to.equal(1);
|
||||||
invokers[1].firstElementChild.dispatchEvent(new KeyboardEvent('keyup', { key: 'ArrowUp' }));
|
invokers[1].firstElementChild.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp' }));
|
||||||
expect(el.focusedIndex).to.equal(0);
|
expect(el.focusedIndex).to.equal(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -235,18 +239,18 @@ describe('<lion-accordion>', () => {
|
||||||
</lion-accordion>
|
</lion-accordion>
|
||||||
`);
|
`);
|
||||||
const invokers = el.querySelectorAll('[slot=invoker]');
|
const invokers = el.querySelectorAll('[slot=invoker]');
|
||||||
invokers[1].firstElementChild.dispatchEvent(new KeyboardEvent('keyup', { key: 'Home' }));
|
invokers[1].firstElementChild.dispatchEvent(new KeyboardEvent('keydown', { key: 'Home' }));
|
||||||
expect(el.focusedIndex).to.equal(0);
|
expect(el.focusedIndex).to.equal(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('selects last invoker on [end]', async () => {
|
it('selects last invoker on [end]', async () => {
|
||||||
const el = await fixture(basicAccordion);
|
const el = await fixture(basicAccordion);
|
||||||
const invokers = el.querySelectorAll('[slot=invoker]');
|
const invokers = el.querySelectorAll('[slot=invoker]');
|
||||||
invokers[0].firstElementChild.dispatchEvent(new KeyboardEvent('keyup', { key: 'End' }));
|
invokers[0].firstElementChild.dispatchEvent(new KeyboardEvent('keydown', { key: 'End' }));
|
||||||
expect(el.focusedIndex).to.equal(2);
|
expect(el.focusedIndex).to.equal(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('selects first invoker on [arrow-right] if on last invoker', async () => {
|
it('stays on last invoker on [arrow-right]', async () => {
|
||||||
const el = await fixture(html`
|
const el = await fixture(html`
|
||||||
<lion-accordion focusedIndex="2">
|
<lion-accordion focusedIndex="2">
|
||||||
<h2 slot="invoker"><button>invoker 1</button></h2>
|
<h2 slot="invoker"><button>invoker 1</button></h2>
|
||||||
|
|
@ -259,12 +263,12 @@ describe('<lion-accordion>', () => {
|
||||||
`);
|
`);
|
||||||
const invokers = el.querySelectorAll('[slot=invoker]');
|
const invokers = el.querySelectorAll('[slot=invoker]');
|
||||||
invokers[2].firstElementChild.dispatchEvent(
|
invokers[2].firstElementChild.dispatchEvent(
|
||||||
new KeyboardEvent('keyup', { key: 'ArrowRight' }),
|
new KeyboardEvent('keydown', { key: 'ArrowRight' }),
|
||||||
);
|
);
|
||||||
expect(el.focusedIndex).to.equal(0);
|
expect(el.focusedIndex).to.equal(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('selects last invoker on [arrow-left] if on first invoker', async () => {
|
it('stays on first invoker on [arrow-left]', async () => {
|
||||||
const el = await fixture(html`
|
const el = await fixture(html`
|
||||||
<lion-accordion>
|
<lion-accordion>
|
||||||
<h2 slot="invoker"><button>invoker 1</button></h2>
|
<h2 slot="invoker"><button>invoker 1</button></h2>
|
||||||
|
|
@ -276,8 +280,10 @@ describe('<lion-accordion>', () => {
|
||||||
</lion-accordion>
|
</lion-accordion>
|
||||||
`);
|
`);
|
||||||
const invokers = el.querySelectorAll('[slot=invoker]');
|
const invokers = el.querySelectorAll('[slot=invoker]');
|
||||||
invokers[0].firstElementChild.dispatchEvent(new KeyboardEvent('keyup', { key: 'ArrowLeft' }));
|
invokers[0].firstElementChild.dispatchEvent(
|
||||||
expect(el.focusedIndex).to.equal(2);
|
new KeyboardEvent('keydown', { key: 'ArrowLeft' }),
|
||||||
|
);
|
||||||
|
expect(el.focusedIndex).to.equal(null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue