@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:shortcut
CustomEvent , in which case it is recommended to give each trigger a uniqueid
for 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}
/>
KeyboardEvent
Original 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! 👨💻