side-panel: detect keyboard events to navigate the panel switcher

(tab, arrows, enter, space, escape)
This commit is contained in:
CloudHill 2020-12-08 00:24:01 +07:00
parent 6a8006823f
commit 07d0836e97
2 changed files with 42 additions and 6 deletions

View File

@ -213,6 +213,7 @@
overflow: hidden; overflow: hidden;
transition: background 300ms ease; transition: background 300ms ease;
} }
.enhancer-panel--switcher-item:hover { .enhancer-panel--switcher-item:hover,
.enhancer-panel--switcher-item:focus {
background: var(--theme--interactive_hover); background: var(--theme--interactive_hover);
} }

View File

@ -16,7 +16,7 @@ module.exports = {
tags: ['extension', 'panel'], tags: ['extension', 'panel'],
name: 'side panel', name: 'side panel',
desc: 'adds a side panel to notion.', desc: 'adds a side panel to notion.',
version: '1.0.0', version: '1.1.0',
author: 'CloudHill', author: 'CloudHill',
hacks: { hacks: {
'renderer/preload.js'(store, __exports) { 'renderer/preload.js'(store, __exports) {
@ -224,7 +224,7 @@ module.exports = {
function renderSwitcherItem(mod) { function renderSwitcherItem(mod) {
if (mod.panel) { if (mod.panel) {
const item = createElement( const item = createElement(
`<div class="enhancer-panel--switcher-item"> `<div class="enhancer-panel--switcher-item" tabindex="0">
<div class="enhancer-panel--icon">${mod.panel.icon}</div> <div class="enhancer-panel--icon">${mod.panel.icon}</div>
<div class="enhancer-panel--title">${mod.panel.name || mod.name}</div> <div class="enhancer-panel--title">${mod.panel.name || mod.name}</div>
</div>` </div>`
@ -235,7 +235,7 @@ module.exports = {
} }
function renderSwitcher() { function renderSwitcher() {
if (panel.querySelector('.enhancer-panel--overlay-container')) return; if (document.querySelector('.enhancer-panel--overlay-container')) return;
// Layer to close switcher // Layer to close switcher
const overlayContainer = createElement( const overlayContainer = createElement(
@ -261,10 +261,12 @@ module.exports = {
panelMods.forEach(mod => panelMods.forEach(mod =>
switcher.append(renderSwitcherItem(mod)) switcher.append(renderSwitcherItem(mod))
); );
overlayContainer.appendChild(div); overlayContainer.appendChild(div);
div.firstElementChild.appendChild(switcher); div.firstElementChild.appendChild(switcher);
switcher.firstElementChild.focus();
// Fade in // Fade in
switcher.animate( switcher.animate(
[ {opacity: 0}, {opacity: 1} ], [ {opacity: 0}, {opacity: 1} ],
@ -273,12 +275,16 @@ module.exports = {
// Prevent panel from closing if unlocked // Prevent panel from closing if unlocked
panel.removeEventListener('mouseleave', hidePanel); panel.removeEventListener('mouseleave', hidePanel);
// Escape key listener
document.addEventListener('keydown', switcherKeyEvent);
} }
function hideSwitcher() { function hideSwitcher() {
const overlayContainer = document.querySelector('.enhancer-panel--overlay-container'); const overlayContainer = document.querySelector('.enhancer-panel--overlay-container');
overlayContainer.removeEventListener('click', hideSwitcher); overlayContainer.removeEventListener('click', hideSwitcher);
document.removeEventListener('keydown', switcherKeyEvent);
// Fade out // Fade out
document.querySelector('.enhancer-panel--switcher').animate( document.querySelector('.enhancer-panel--switcher').animate(
[ {opacity: 1}, {opacity: 0} ], [ {opacity: 1}, {opacity: 0} ],
@ -363,6 +369,35 @@ module.exports = {
if (panel.dataset.locked === 'true') return true; if (panel.dataset.locked === 'true') return true;
else return false; else return false;
} }
function switcherKeyEvent(e) {
e.stopPropagation();
if (e.key === 'Escape') return hideSwitcher();
const currentFocus = document.activeElement;
if ([' ', 'Enter'].includes(e.key)) return currentFocus.click();
const focusNext = () => {
const nextEl = currentFocus.nextElementSibling;
if (nextEl) nextEl.focus();
else currentFocus.parentElement.firstElementChild.focus();
}
const focusPrevious = () => {
const prevEl = currentFocus.previousElementSibling;
if (prevEl) prevEl.focus();
else currentFocus.parentElement.lastElementChild.focus();
}
if (e.key === 'ArrowUp') focusPrevious();
else if (e.key === 'ArrowDown') focusNext();
else if (e.key === 'Tab') {
if (e.shiftKey) focusPrevious();
else focusNext();
e.preventDefault();
}
}
} }
}); });