@svelte-put/shortcut
add keyboard shortcuts to node
Installation
terminal
npm install --save-dev @svelte-put/shortcut Quick Start
quick start
<script lang="ts">
import { shortcut, type ShortcutEventDetail } from '@svelte-put/shortcut';
function handleK(detail: ShortcutEventDetail) {
console.log('attached node:', detail.node);
console.log('original trigger config:', detail.trigger);
}
</script>
<svelte:window
use:shortcut={{
trigger: {
key: 'k',
modifier: ['ctrl', 'meta'],
callback: handleK,
},
}}
/>
Key Combination
In each use:shortcut, one or an array of ShortcutTrigger can be
provided to the trigger parameter.
key
<script>
import { shortcut } from '@svelte-put/shortcut';
</script>
<svelte:window
use:shortcut={{ trigger: { key: 'k', modifier: 'ctrl' } }}
use:shortcut={{
trigger: [
{ key: 'k', modifier: 'ctrl' },
{ key: 'l', modifier: 'meta' },
],
}}
/>
One or multiple modifiers (
ctrl,
meta,
alt,
shift
) can be provided to trigger.modifier in both and & or
fashions.
modifier
<script>
import { shortcut } from '@svelte-put/shortcut';
</script>
<svelte:window
use:shortcut={{
// listen for one of many modifiers (or)
// ctrl+k or meta+k
trigger: {
key: 'k',
modifier: ['ctrl', 'meta'],
},
}}
use:shortcut={{
// listen for a combination of multiple modifiers (and)
// ctrl+shift+k
trigger: {
key: 'k',
modifier: [['ctrl', 'shift']],
},
}}
use:shortcut={{
// mix & match
// ctrl+shift+k or meta+k
trigger: {
key: 'k',
modifier: [['ctrl', 'shift'], ['meta']],
},
}}
/>
Event vs Callback
In cases where multiple key combinations are registered. You can either:
- provide a callback for each combination via
trigger.callback, or - use the
on:shortcutCustomEvent , in which case it is recommended to give each trigger a uniqueidfor easier identification in the event handler.
event vs callback
<script lang="ts">
import { shortcut, type ShortcutEventDetail } from '@svelte-put/shortcut';
let commandPalette = false;
function onOpenCommandPalette() {
commandPalette = true;
}
function onCloseCommandPalette() {
commandPalette = false;
}
function doSomethingElse(details: ShortcutEventDetail) {
console.log('Action was placed on:', details.node);
console.log('Trigger:', details.trigger);
}
function onShortcut(event: CustomEvent<ShortcutEventDetail>) {
if (event.detail.trigger.id === 'do-something-else') {
console.log('Same as doSomethingElse()');
// be careful here doSomethingElse would have been called too
}
}
</script>
<svelte:window
use:shortcut={{
trigger: [
{
key: 'k',
// trigger if either ctrl or meta is pressed
modifier: ['ctrl', 'meta'],
callback: onOpenCommandPalette,
preventDefault: true,
},
{
key: 'Escape',
// preferably avoid arrow functions here for better performance,
// with arrow functions the action has to be updated more frequently
callback: onCloseCommandPalette,
enabled: commandPalette,
preventDefault: true,
},
{
key: 'k',
// trigger if both ctrl & shift are pressed
modifier: [['ctrl', 'shift']],
id: 'do-something-else',
callback: doSomethingElse,
},
],
}}
on:shortcut={onShortcut}
/>
Original KeyboardEvent
You can access the original KeyboardEvent via detail.originalEvent
from ShortcutEventDetail, helpful for things like checking target or
invoking preventDefault.
Be aware that the event listener is placed on the node the action is attached to. For example,
if you use the action on svelte:window, calling
stopPropagation or preventDefault on originalEvent might
not result in the behavior you would expected. By the time the provided callback or
on:shortcut
event handler executes, the event has already reached window.
original KeyboardEvent
<script lang="ts">
import type { ShortcutEventDetail } from '@svelte-put/shortcut';
import { shortcut } from '@svelte-put/shortcut';
function onShortcut(event: CustomEvent<ShortcutEventDetail>) {
const keyboardEvent = event.detail.originalEvent;
// be cautious: `keyboardEvent` has already reached window here
keyboardEvent.preventDefault(); // prevent browser default
if ((keyboardEvent.target as HTMLElement)?.tagName === 'INPUT') {
console.log('some input is focused, should skip');
return;
}
// do things
}
</script>
<svelte:window
use:shortcut={{
trigger: {
key: 'k',
modifier: ['ctrl', 'meta'],
},
}}
on:shortcut={onShortcut}
/>
Happy making shortcuts! 👨💻