UNPKG

@grail-ui/svelte

Version:

[![NPM](https://img.shields.io/npm/v/@grail-ui/svelte)](https://www.npmjs.com/package/@grail-ui/svelte) [![minified](https://img.shields.io/bundlephobia/min/@grail-ui/svelte)](https://bundlephobia.com/package/@grail-ui/svelte) [![minified + zipped](https:

60 lines (59 loc) 2.19 kB
import { addEventListener } from '../eventListener/eventListener.js'; import { isClient } from '../util/is.js'; import { tryOnDestroy } from '../util/lifecycle.js'; import { noop } from '../util/noop.js'; const ALIAS = { plus: '+' }; export const createKeyStroke = (params) => { if (!isClient) return noop; const { key, handler, target = document, eventName = 'keydown', passive = false, preventDefault = false, autoStop = true, } = params; const matches = (key, event) => { const matchEvent = key .replace(/\s/g, '') // Remove whitespace .replace(/\+{2}/g, '+plus') .split('+') .map((value) => ALIAS[value] ?? value) .reduce((current, keyCode) => { keyCode = keyCode.toLocaleLowerCase(); if (keyCode === 'alt' || keyCode === 'shift' || keyCode === 'ctrl' || keyCode === 'meta') { current[`${keyCode}Key`] = true; } else { current['key'] = keyCode; } return current; }, {}); return (event.key.toLocaleUpperCase() === matchEvent.key.toLocaleUpperCase() && event.altKey === !!matchEvent.altKey && event.shiftKey === !!matchEvent.shiftKey && event.ctrlKey === !!matchEvent.ctrlKey && event.metaKey === !!matchEvent.metaKey); }; const keyPredicate = (keyFilter, event) => { if (keyFilter === true) return true; if (typeof keyFilter === 'function') return keyFilter(event); return [].concat(keyFilter).some((key) => matches(key, event)); }; const listener = (e) => { if (keyPredicate(key, e)) { if (preventDefault) e.preventDefault(); handler(e); } }; const stop = addEventListener(target, eventName, listener, { passive }); if (autoStop) { tryOnDestroy(stop); } return stop; }; export const useKeyStroke = (node, parameters) => { const removeEvent = createKeyStroke({ ...parameters, target: node }); return { destroy() { removeEvent(); }, }; };