Skip to content

Instantly share code, notes, and snippets.

@rikschennink
Last active October 22, 2023 05:53
Show Gist options
  • Save rikschennink/7b953848db8e7cb2951fde534812c677 to your computer and use it in GitHub Desktop.
Save rikschennink/7b953848db8e7cb2951fde534812c677 to your computer and use it in GitHub Desktop.
⌨️ A Svelte action to add arrow key interaction to an element
export default (element: HTMLElement, options: any = {}) => {
// if added as action on non focusable element you should add tabindex=0 attribute
const {
direction = undefined,
shiftMultiplier = 10,
bubbles = false,
stopKeydownPropagation = true,
} = options;
const isHorizontalDirection = direction === 'horizontal';
const isVerticalDirection = direction === 'vertical';
const handleKeydown = (e: KeyboardEvent) => {
const { key } = e;
const isShift = e.shiftKey;
const isHorizontalAction = /up|down/i.test(key);
const isVerticalAction = /left|right/i.test(key);
// no directional key
if (!isHorizontalAction && !isVerticalAction) return;
// is horizontal but up or down pressed
if (isHorizontalDirection && isVerticalAction) return;
// is vertical but left or right pressed
if (isVerticalDirection && isHorizontalAction) return;
// if holding shift move by a factor 10
const multiplier = isShift ? shiftMultiplier : 1;
if (stopKeydownPropagation) e.stopPropagation();
element.dispatchEvent(
new CustomEvent('nudge', {
bubbles,
detail: {
x: (/left/i.test(key) ? -1 : /right/i.test(key) ? 1 : 0) * multiplier,
y: (/up/i.test(key) ? -1 : /down/i.test(key) ? 1 : 0) * multiplier
},
})
);
};
element.addEventListener('keydown', handleKeydown);
return () => {
element.removeEventListener('keydown', handleKeydown);
};
};
@swyxio
Copy link

swyxio commented Nov 2, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment