When to use
When it is necessary to express the usage method of shortcut key combinations to users, using the Hotkeys component can quickly render the corresponding UI elements and automatically obtain event bindings.
Demos
How to import
<script lang="ts">
import { HotKeys } from '@fibrae/semi-ui-svelte';
</script>
Explanation
A hotkey is one regular key plus zero or more modifier keys (Shift, Control, Meta, Alt). A single regular key without modifiers (such as ['k']) is valid too. The listener is a keydown handler on document.body (or the element returned by getListenerTarget), so it also fires while focus is inside an input; check event.target in onHotKey (@hotKey in Vue) to skip typing contexts. Modifiers must match exactly: with ['k'], pressing Ctrl and K does not trigger it.
Keys are matched by physical key position. Symbols that need Shift to type, such as !, @ and ?, are not valid keys and throw when set. Write them as Shift plus the base key instead, for example ['Shift', '1'] or ['Shift', '/'].
Meta corresponds to Command on macOS and Win on Windows.
When setting a shortcut that overlaps with common shortcuts like Ctrl/Meta + C, the preventDefault setting can be used to control whether the default event is triggered.
Basic Usage
Pass in key combinations via hotKeys and bind a shortcut handler function using onHotKey (@hotKey in Vue) to respond to the action.
When pressing Ctrl + Shift + A, it opens the modal. By default, it listens on the body, making it effective globally.
It's also recommended to use the HotKeys.Keys wrapper to set hotkeys.
Code
<script lang="ts">
import { HotKeys, Modal } from '@fibrae/semi-ui-svelte';
let visible = $state(false);
const close = () => {
visible = false;
};
const hotKeys = [HotKeys.Keys.Control, 'Shift', HotKeys.Keys.A];
</script>
<div>
<HotKeys {hotKeys} onHotKey={() => (visible = true)} />
<Modal bind:visible onOk={close} title="Dialog">This is the Modal opened by hotkey: {hotKeys.join('+')}.</Modal>
</div>Custom content
Set the characters through content
Code
<script lang="ts">
import { HotKeys, Modal } from '@fibrae/semi-ui-svelte';
let visible = $state(false);
const close = () => {
visible = false;
};
const hotKeys = [HotKeys.Keys.Control, 'Shift', HotKeys.Keys.B];
</script>
<div>
<HotKeys content={['Ctrl', 'Shift', 'B']} {hotKeys} onHotKey={() => (visible = true)} />
<Modal bind:visible onOk={close} title="Dialog">This is the Modal opened by hotkey: {hotKeys.join('+')}.</Modal>
</div>Replace the element through the children snippet (written inside the HotKeys tag). With it the default key hint is not rendered and the hot keys stay active.
Code
<script lang="ts">
import { HotKeys, Modal, Tag } from '@fibrae/semi-ui-svelte';
let visible = $state(false);
const close = () => {
visible = false;
};
const hotKeys = [HotKeys.Keys.Control, HotKeys.Keys.R];
</script>
<div>
<HotKeys {hotKeys} onHotKey={() => (visible = true)}>
<Tag>Press Ctrl+R to Open Modal</Tag>
</HotKeys>
<Modal bind:visible onOk={close} title="Dialog">This is the Modal opened by hotkey: {hotKeys.join('+')}.</Modal>
</div>prevent Default event
Control the default event by setting preventDefault.
Code
<script lang="ts">
import { HotKeys, Modal } from '@fibrae/semi-ui-svelte';
let visible = $state(false);
const close = () => {
visible = false;
};
const metaKeys = [HotKeys.Keys.Meta, HotKeys.Keys.S];
const controlKeys = [HotKeys.Keys.Control, HotKeys.Keys.S];
</script>
<div>
<HotKeys hotKeys={metaKeys} onHotKey={() => (visible = true)} preventDefault />
<br />
<HotKeys hotKeys={controlKeys} onHotKey={() => (visible = true)} preventDefault />
<Modal bind:visible onOk={close} title="Dialog">This is the Modal opened by hotkey: Meta/Control + S.</Modal>
</div>change the DOM element the listener is mounted on
The hotkey is listened to on the body by default, through getListenerTarget
Code
<script lang="ts">
import { HotKeys, Input, Modal } from '@fibrae/semi-ui-svelte';
const hotKeys = ['Control', 'q'];
let visible = $state(false);
const close = () => {
visible = false;
};
let input = $state<ReturnType<typeof Input>>();
const getListenerTarget = () => input?.getInput();
</script>
<div>
<Input bind:this={input} placeholder="test for target" />
<HotKeys {getListenerTarget} {hotKeys} onHotKey={() => (visible = true)} />
<Modal bind:visible onOk={close} title="Dialog">This is the Modal opened by hotkey: {hotKeys.join('+')}.</Modal>
</div>API Reference
HotKeys
Props
| Property | Description | Type | Default |
|---|---|---|---|
| children | Replaces the key hint, written inside the tag. With children the default key hint is not rendered and the hot keys stay active. | Snippet | - |
| content | Key labels to show. Defaults to hotKeys. | string[] | - |
| getListenerTarget | Returns the element that listens for keydown. When omitted, or when it returns null or undefined, document.body is used. | Type() => HTMLElement | null | undefined | - |
| hotKeys | The key combination: any number of modifiers plus one other key, as KeyboardEvent.key values. An invalid combination throws on mount or when hotKeys changes. | KeyboardEvent['key'][] | - |
| onHotKey | Called when the full key combination is pressed, with the native KeyboardEvent. | Type(event: KeyboardEvent) => void | - |
| preventDefault | Whether the default behavior of the key combination is prevented. | boolean | false |
class, style (a string) and native attributes (such as id, aria-* and onclick) land on the root element (div). HotKeys.Keys is kept and used as in the other frameworks.
Design Tokens
| Sass variable | Value | Usage |
|---|---|---|
| $color-hotKeys-bg | var(--semi-color-fill-0) | 快捷键背景颜色 |
| $color-hotKeys-text | var(--semi-color-text-2) | 快捷键文字颜色 |
| $color-hotKeys-split | var(--semi-color-text-0) | 快捷键文字颜色 |
| $width-hotKeys-border | 1px | 快捷键描边宽度 |
| $radius-hotKeys | 2px | 边框半径 |
| $height-hotKeys | 20px | 快捷键高度 |
| $spacing-hotKeys-paddingY | 2px | |
| $spacing-hotKeys-paddingX | $spacing-tight |