mirror of
https://github.com/home-assistant/frontend.git
synced 2025-11-14 05:20:31 +00:00
Refactor
This commit is contained in:
@@ -1,8 +1,27 @@
|
||||
import { tinykeys } from "tinykeys";
|
||||
import { canOverrideAlphanumericInput } from "../dom/can-override-input";
|
||||
|
||||
/**
|
||||
* A function to handle a keyboard shortcut.
|
||||
*/
|
||||
export type ShortcutHandler = (event: KeyboardEvent) => void;
|
||||
|
||||
/**
|
||||
* Configuration for a keyboard shortcut.
|
||||
*/
|
||||
export interface ShortcutConfig {
|
||||
/**
|
||||
* The handler function to call when the shortcut is triggered.
|
||||
*/
|
||||
handler: ShortcutHandler;
|
||||
/**
|
||||
* If true, the shortcut will be triggered even when the user is selecting text.
|
||||
* By default (false), shortcuts are blocked during text selection to avoid
|
||||
* interrupting copy/paste operations.
|
||||
*/
|
||||
allowWhenTextSelected?: boolean;
|
||||
}
|
||||
|
||||
interface ShortcutEntry {
|
||||
/**
|
||||
* The key that the shortcut is registered to.
|
||||
@@ -17,25 +36,26 @@ interface ShortcutEntry {
|
||||
/**
|
||||
* Register keyboard shortcuts using tinykeys.
|
||||
*
|
||||
* @param shortcuts - Key combinations mapped to handler functions.
|
||||
* @param shortcuts - Key combinations mapped to shortcut configurations.
|
||||
* @returns A function to remove the shortcuts.
|
||||
*/
|
||||
function registerShortcuts(
|
||||
shortcuts: Record<string, ShortcutHandler>
|
||||
shortcuts: Record<string, ShortcutConfig>
|
||||
): () => void {
|
||||
const wrappedShortcuts: Record<string, ShortcutHandler> = {};
|
||||
|
||||
Object.entries(shortcuts).forEach(([key, handler]) => {
|
||||
Object.entries(shortcuts).forEach(([key, config]) => {
|
||||
wrappedShortcuts[key] = (event: KeyboardEvent) => {
|
||||
// Don't capture the event if the user is focused on an input field
|
||||
if (!canOverrideAlphanumericInput(event.composedPath())) {
|
||||
return;
|
||||
}
|
||||
// Don't capture the event if the user is selecting text
|
||||
if (window.getSelection()?.toString()) {
|
||||
// Don't capture the event if the user is selecting text to avoid
|
||||
// interrupting copy/paste operations or text manipulation
|
||||
if (!config.allowWhenTextSelected && window.getSelection()?.toString()) {
|
||||
return;
|
||||
}
|
||||
handler(event);
|
||||
config.handler(event);
|
||||
};
|
||||
});
|
||||
|
||||
@@ -51,12 +71,12 @@ export class ShortcutManager {
|
||||
/**
|
||||
* Add a group of keyboard shortcuts to the manager.
|
||||
*
|
||||
* @param shortcuts - Key combinations mapped to handler functions.
|
||||
* @param shortcuts - Key combinations mapped to shortcut configurations.
|
||||
* Uses tinykeys syntax. See https://github.com/jamiebuilds/tinykeys#usage.
|
||||
*/
|
||||
public add(shortcuts: Record<string, ShortcutHandler>) {
|
||||
Object.entries(shortcuts).forEach(([key, handler]) => {
|
||||
const disposer = registerShortcuts({ [key]: handler });
|
||||
public add(shortcuts: Record<string, ShortcutConfig>) {
|
||||
Object.entries(shortcuts).forEach(([key, config]) => {
|
||||
const disposer = registerShortcuts({ [key]: config });
|
||||
const entry: ShortcutEntry = { key, disposer };
|
||||
this.shortcutEntries.push(entry);
|
||||
});
|
||||
|
||||
@@ -64,19 +64,19 @@ export default <T extends Constructor<HassElement>>(superClass: T) =>
|
||||
const shortcutManager = new ShortcutManager();
|
||||
shortcutManager.add({
|
||||
// Those are for latin keyboards that have e, c, m keys
|
||||
e: (ev) => this._showQuickBar(ev),
|
||||
c: (ev) => this._showQuickBar(ev, QuickBarMode.Command),
|
||||
m: (ev) => this._createMyLink(ev),
|
||||
a: (ev) => this._showVoiceCommandDialog(ev),
|
||||
d: (ev) => this._showQuickBar(ev, QuickBarMode.Device),
|
||||
e: { handler: (ev) => this._showQuickBar(ev) },
|
||||
c: { handler: (ev) => this._showQuickBar(ev, QuickBarMode.Command) },
|
||||
m: { handler: (ev) => this._createMyLink(ev) },
|
||||
a: { handler: (ev) => this._showVoiceCommandDialog(ev) },
|
||||
d: { handler: (ev) => this._showQuickBar(ev, QuickBarMode.Device) },
|
||||
// Workaround see https://github.com/jamiebuilds/tinykeys/issues/130
|
||||
"Shift+?": (ev) => this._showShortcutDialog(ev),
|
||||
"Shift+?": { handler: (ev) => this._showShortcutDialog(ev) },
|
||||
// Those are fallbacks for non-latin keyboards that don't have e, c, m keys (qwerty-based shortcuts)
|
||||
KeyE: (ev) => this._showQuickBar(ev),
|
||||
KeyC: (ev) => this._showQuickBar(ev, QuickBarMode.Command),
|
||||
KeyM: (ev) => this._createMyLink(ev),
|
||||
KeyA: (ev) => this._showVoiceCommandDialog(ev),
|
||||
KeyD: (ev) => this._showQuickBar(ev, QuickBarMode.Device),
|
||||
KeyE: { handler: (ev) => this._showQuickBar(ev) },
|
||||
KeyC: { handler: (ev) => this._showQuickBar(ev, QuickBarMode.Command) },
|
||||
KeyM: { handler: (ev) => this._createMyLink(ev) },
|
||||
KeyA: { handler: (ev) => this._showVoiceCommandDialog(ev) },
|
||||
KeyD: { handler: (ev) => this._showQuickBar(ev, QuickBarMode.Device) },
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user