Plus · HotKeys

HotKeys

used to facilitate the customization of keyboard shortcut

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

import { HotKeys } from '@fibrous/semi-ui-react';

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.

values reference

It's also recommended to use the HotKeys.Keys wrapper to set hotkeys.

control+Shift+a
Code
import { useState } from 'react';
import { HotKeys, Modal } from '@fibrous/semi-ui-react';

export default function HotKeysDemo() {
    const [visible, setVisible] = useState(false);
    const showDialog = () => {
        setVisible(true);
    };
    const handleOk = () => {
        setVisible(false);
    };
    const handleCancel = () => {
        setVisible(false);
    };
    const hotKeys = [HotKeys.Keys.Control, 'Shift', HotKeys.Keys.A];

    return (
        <div>
            <HotKeys hotKeys={hotKeys} onHotKey={showDialog} />
            <Modal title="Dialog" visible={visible} onOk={handleOk} onCancel={handleCancel}>
                This is the Modal opened by hotkey: {hotKeys.join('+')}.
            </Modal>
        </div>
    );
}

Custom content

Set the characters through content

Ctrl+Shift+B
Code
import { useState } from 'react';
import { HotKeys, Modal } from '@fibrous/semi-ui-react';

export default function HotKeysDemo() {
    const [visible, setVisible] = useState(false);
    const showDialog = () => {
        setVisible(true);
    };
    const handleOk = () => {
        setVisible(false);
    };
    const handleCancel = () => {
        setVisible(false);
    };
    const hotKeys = [HotKeys.Keys.Control, 'Shift', HotKeys.Keys.B];

    return (
        <div>
            <HotKeys hotKeys={hotKeys} onHotKey={showDialog} content={['Ctrl', 'Shift', 'B']} />
            <Modal title="Dialog" visible={visible} onOk={handleOk} onCancel={handleCancel}>
                This is the Modal opened by hotkey: {hotKeys.join('+')}.
            </Modal>
        </div>
    );
}

Replace the element through render

Press Ctrl+R to Open Modal
Code
import { useState } from 'react';
import { HotKeys, Modal, Tag } from '@fibrous/semi-ui-react';

export default function HotKeysDemo() {
    const [visible, setVisible] = useState(false);
    const showDialog = () => {
        setVisible(true);
    };
    const handleOk = () => {
        setVisible(false);
    };
    const handleCancel = () => {
        setVisible(false);
    };
    const hotKeys = [HotKeys.Keys.Control, HotKeys.Keys.R];

    const newHotKeys = <Tag>Press Ctrl+R to Open Modal</Tag>;
    return (
        <div>
            <HotKeys hotKeys={hotKeys} onHotKey={showDialog} render={newHotKeys} />
            <Modal title="Dialog" visible={visible} onOk={handleOk} onCancel={handleCancel}>
                This is the Modal opened by hotkey: {hotKeys.join('+')}.
            </Modal>
        </div>
    );
}

prevent Default event

Control the default event by setting preventDefault.

meta+s

control+s
Code
import { useState } from 'react';
import { HotKeys, Modal } from '@fibrous/semi-ui-react';

export default function HotKeysDemo() {
    const [visible, setVisible] = useState(false);
    const showDialog = () => {
        setVisible(true);
    };
    const handleOk = () => {
        setVisible(false);
    };
    const handleCancel = () => {
        setVisible(false);
    };
    const hotKeys = [HotKeys.Keys.Meta, HotKeys.Keys.S];

    return (
        <div>
            <HotKeys hotKeys={hotKeys} onHotKey={showDialog} preventDefault />
            <br />
            <HotKeys hotKeys={[HotKeys.Keys.Control, HotKeys.Keys.S]} onHotKey={showDialog} preventDefault />
            <Modal title="Dialog" visible={visible} onOk={handleOk} onCancel={handleCancel}>
                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

Control+q
Code
import { useState, useRef } from 'react';
import { HotKeys, Input, Modal, type InputHandle } from '@fibrous/semi-ui-react';

export default function HotKeysDemo() {
    const hotKeys = ['Control', 'q'];
    const [visible, setVisible] = useState(false);
    const showDialog = () => {
        setVisible(true);
    };
    const handleOk = () => {
        setVisible(false);
    };
    const handleCancel = () => {
        setVisible(false);
    };

    const inputRef = useRef<InputHandle>(null);
    return (
        <div>
            <Input ref={inputRef} placeholder="test for target" />
            <HotKeys hotKeys={hotKeys} onHotKey={showDialog} getListenerTarget={() => inputRef.current?.input} />
            <Modal title="Dialog" visible={visible} onOk={handleOk} onCancel={handleCancel}>
                This is the Modal opened by hotkey: {hotKeys.join('+')}.
            </Modal>
        </div>
    );
}

API Reference

HotKeys

Props

PropertyDescriptionTypeDefault
classNameClass name of the root element.string""
contentKey labels to show. Defaults to hotKeys.string[]null
getListenerTargetReturns the element that listens for keydown. When omitted, or when it returns null or undefined, document.body is used. It is read again after mount, so a ref of a parent container works; the listener moves when the returned element changes.Type() => HTMLElement | null | undefined-
hotKeysKey combination: any number of modifiers (Shift, Control, Meta, Alt) plus one other key, as KeyboardEvent.key values matched by physical key position. An invalid combination throws, including after an update.KeyboardEvent['key'][]-
onHotKeyCalled when the full key combination is pressed, with the native KeyboardEvent.Type(e: KeyboardEvent) => void-
preventDefaultWhether the default behavior of the key combination is prevented.booleanfalse
refReference to the root div element. When render is null or returns null no root element is rendered, and the reference is null.TypeReact.Ref<HTMLDivElement>-
renderReplaces the key hint. Accepts a React node or a function returning one. null, or a function returning null, renders no root element and the hot keys stay active.Type(() => ReactNode) | ReactNode-
styleStyle of the root element.React.CSSPropertiesnull

Other native attributes (such as id, aria-* and onClick) land on the root element (div). When render is null or returns null there is no root element, so they have nowhere to land.

Design Tokens

These are the component's internal Sass variables and cannot be overridden. To customize styles, override the --semi-* CSS variables (see the Design Token page) or write unlayered CSS rules.
Sass variableValueUsage
$color-hotKeys-bgvar(--semi-color-fill-0)快捷键背景颜色
$color-hotKeys-textvar(--semi-color-text-2)快捷键文字颜色
$color-hotKeys-splitvar(--semi-color-text-0)快捷键文字颜色
$width-hotKeys-border1px快捷键描边宽度
$radius-hotKeys2px边框半径
$height-hotKeys20px快捷键高度
$spacing-hotKeys-paddingY2px
$spacing-hotKeys-paddingX$spacing-tight