@selenite/commons
Version:
This typescript package provides a set of frequently used utilities, types and svelte actions for building projects with Typescript and Svelte.
67 lines (66 loc) • 2.23 kB
JavaScript
export {};
export const keyboardNavigation = (node) => {
node.classList.add('selenite-kb-nav');
function handleKeydown(e) {
if (!['ArrowUp', 'ArrowDown'].includes(e.key))
return;
const getNext = e.key === 'ArrowUp'
? (node) => node.previousElementSibling ?? node.parentElement?.lastElementChild
: (node) => node.nextElementSibling ?? node.parentElement?.firstElementChild;
let candidate;
while ((!candidate || !candidate.classList.contains('selenite-kb-nav')) && candidate !== node) {
const next = getNext(node);
if (next instanceof HTMLElement) {
candidate = next;
}
}
if (candidate && candidate.classList.contains('selenite-kb-nav')) {
candidate.focus();
}
}
function handleFocusIn() {
console.debug('Add keydown listener');
node.addEventListener('keydown', handleKeydown);
}
function handleFocusOut() {
console.debug('Remove keydown listener');
node.removeEventListener('keydown', handleKeydown);
}
document.addEventListener('focusin', handleFocusIn);
document.addEventListener('focusout', handleFocusOut);
return {
destroy() {
document.removeEventListener('focusin', handleFocusIn);
document.removeEventListener('focusout', handleFocusOut);
}
};
};
export function keys(node, params) {
function kbListener(e_) {
const e = e_;
const keyToHandler = {
ArrowUp: params.up,
ArrowLeft: params.left,
ArrowDown: params.down,
ArrowRight: params.right,
Enter: params.enter,
Escape: params.escape,
Backspace: params.backspace
};
const handler = keyToHandler[e.key];
if (handler) {
if (params.preventDefault)
e.preventDefault();
handler(e);
}
}
node.addEventListener('keydown', kbListener);
return {
destroy() {
node.removeEventListener('keydown', kbListener);
},
update(newParams = {}) {
params = newParams;
}
};
}