feat:add funtionality of home and end hotkeys on web version (#43)

Co-authored-by: Pavan <pavannaik20@gmail.com>
This commit is contained in:
Pavan Naik
2025-02-05 08:22:39 +05:30
committed by GitHub
parent 69862adb4b
commit 7b13cf7d77
2 changed files with 432 additions and 415 deletions

View File

@@ -12,183 +12,486 @@ import { Editor, Text, Range, Transforms, BasePoint, Path, Element } from 'slate
import { ReactEditor, useReadOnly } from 'slate-react';
import smoothScrollIntoViewIfNeeded from 'smooth-scroll-into-view-if-needed';
export function useShortcuts (editor: ReactEditor) {
export function useShortcuts(editor: ReactEditor) {
const yjsEditor = editor as YjsEditor;
const { viewId } = useEditorContext();
const readOnly = useReadOnly();
const focusedFocusableElement = useCallback((toStart?: boolean) => {
if (readOnly) return;
const title = document.getElementById(`editor-title-${viewId}`);
const focusedFocusableElement = useCallback(
(toStart?: boolean) => {
if (readOnly) return;
const title = document.getElementById(`editor-title-${viewId}`);
if (!title) return;
if (!title) return;
const selection = window.getSelection();
const range = document.createRange();
const selection = window.getSelection();
const range = document.createRange();
const textNode = title.childNodes[0] as Node;
const textNode = title.childNodes[0] as Node;
if (textNode) {
range.setStart(textNode, toStart ? 0 : (textNode?.textContent?.length || 0));
} else {
range.setStart(title, 0);
}
if (textNode) {
range.setStart(textNode, toStart ? 0 : textNode?.textContent?.length || 0);
} else {
range.setStart(title, 0);
}
selection?.removeAllRanges();
selection?.addRange(range);
}, [readOnly, viewId]);
selection?.removeAllRanges();
selection?.addRange(range);
},
[readOnly, viewId]
);
const onKeyDown = useCallback((event: KeyboardEvent<HTMLDivElement>) => {
const e = event.nativeEvent;
const { selection } = editor;
const onKeyDown = useCallback(
(event: KeyboardEvent<HTMLDivElement>) => {
const e = event.nativeEvent;
const { selection } = editor;
// Add more cases here for general shortcuts
switch (true) {
/**
* Escape: Esc
* Default behavior: Deselect editor
*/
case createHotkey(HOT_KEY_NAME.ESCAPE)(e):
editor.deselect();
break;
default:
break;
}
if (selection && Range.isCollapsed(selection)) {
// Add more cases here for general shortcuts
switch (true) {
case createHotkey(HOT_KEY_NAME.UP)(e): {
const path = editor.start(selection).path;
/**
* Escape: Esc
* Default behavior: Deselect editor
*/
case createHotkey(HOT_KEY_NAME.ESCAPE)(e):
editor.deselect();
break;
default:
break;
}
if (selection && Range.isCollapsed(selection)) {
switch (true) {
case createHotkey(HOT_KEY_NAME.UP)(e): {
const path = editor.start(selection).path;
if (Path.isAncestor([0, 0], path)) {
e.preventDefault();
focusedFocusableElement(false);
break;
}
const before = Editor.before(editor, selection, { unit: 'offset' });
const beforeText = findInlineTextNode(editor, before);
if (before && beforeText) {
e.preventDefault();
Transforms.move(editor, { unit: 'line', reverse: true, distance: 2 });
return;
}
if (Path.isAncestor([0, 0], path)) {
e.preventDefault();
focusedFocusableElement(false);
break;
}
const before = Editor.before(editor, selection, { unit: 'offset' });
const beforeText = findInlineTextNode(editor, before);
case createHotkey(HOT_KEY_NAME.BACKSPACE)(e): {
const [node] = getBlockEntry(yjsEditor);
const type = node.type as BlockType;
if (before && beforeText) {
e.preventDefault();
Transforms.move(editor, { unit: 'line', reverse: true, distance: 2 });
return;
}
if (type !== BlockType.Paragraph) {
break;
}
break;
}
const path = editor.start(selection).path;
const currentLineText = CustomEditor.getBlockTextContent(node);
case createHotkey(HOT_KEY_NAME.BACKSPACE)(e): {
const [node] = getBlockEntry(yjsEditor);
const type = node.type as BlockType;
if (
editor.children.length > 1 &&
(editor.children[0] as Element).blockId === node.blockId &&
currentLineText === ''
) {
CustomEditor.deleteBlock(yjsEditor, node.blockId as string);
}
const before = Editor.before(editor, selection, { unit: 'offset' });
if (!before && Path.isAncestor([0, 0], path)) {
e.preventDefault();
focusedFocusableElement(false);
}
if (type !== BlockType.Paragraph) {
break;
}
const path = editor.start(selection).path;
const currentLineText = CustomEditor.getBlockTextContent(node);
case createHotkey(HOT_KEY_NAME.LEFT)(e): {
const path = editor.start(selection).path;
const before = Editor.before(editor, selection, { unit: 'offset' });
if (editor.children.length > 1 && (editor.children[0] as Element).blockId === node.blockId && currentLineText === '') {
CustomEditor.deleteBlock(yjsEditor, node.blockId as string);
if (!before && Path.isAncestor([0, 0], path)) {
focusedFocusableElement(false);
}
break;
}
const before = Editor.before(editor, selection, { unit: 'offset' });
case createHotkey(HOT_KEY_NAME.DOWN)(e): {
const after = Editor.after(editor, selection, { unit: 'offset' });
const afterText = findInlineTextNode(editor, after);
if (!before && Path.isAncestor([0, 0], path)) {
e.preventDefault();
focusedFocusableElement(false);
if (afterText) {
e.preventDefault();
Transforms.move(editor, { unit: 'line', distance: 2 });
return;
}
break;
}
case createHotkey(HOT_KEY_NAME.OPEN_LINK)(e): {
event.preventDefault();
const marks = CustomEditor.getAllMarks(editor);
const link = marks.find((mark) => !!mark[EditorMarkFormat.Href])?.[EditorMarkFormat.Href];
if (link) {
void openUrl(link, '_blank');
return;
}
break;
}
case createHotkey(HOT_KEY_NAME.DELETE_LEFT_SENTENCE)(e): {
event.preventDefault();
const focus = editor.start(selection);
const anchor = Editor.before(editor, focus, { unit: 'line' });
if (anchor) {
editor.delete({
at: {
anchor,
focus,
},
});
}
break;
}
case createHotkey(HOT_KEY_NAME.DELETE_LEFT_WORD)(e): {
event.preventDefault();
const focus = editor.start(selection);
const anchor = Editor.before(editor, focus, { unit: 'word' });
if (anchor) {
editor.delete({
at: {
anchor,
focus,
},
});
}
break;
}
case createHotkey(HOT_KEY_NAME.DELETE_RIGHT_WORD)(e): {
event.preventDefault();
const focus = editor.start(selection);
const anchor = Editor.after(editor, focus, { unit: 'word' });
if (anchor) {
editor.delete({
at: {
anchor,
focus,
},
});
}
break;
}
default:
break;
}
}
// Do not process shortcuts if editor is read-only or no selection
if (readOnly || !selection) return;
const [point] = editor.edges(selection);
const node = getBlockEntry(yjsEditor, point);
// Add more cases here for editing shortcuts
switch (!readOnly) {
/**
* Select all: Mod+A
* Default behavior: Select all text in the editor
* Special case for select all in code block: Only select all text in code block
*/
case createHotkey(HOT_KEY_NAME.SELECT_ALL)(e):
if (node && node[0].type === BlockType.CodeBlock) {
event.preventDefault();
editor.select(node[1]);
}
break;
}
/**
* Indent block: Tab
* Default behavior: Indent block
*/
case createHotkey(HOT_KEY_NAME.INDENT_BLOCK)(e):
event.preventDefault();
case createHotkey(HOT_KEY_NAME.LEFT)(e): {
const path = editor.start(selection).path;
const before = Editor.before(editor, selection, { unit: 'offset' });
if (SOFT_BREAK_TYPES.includes(node[0]?.type as BlockType)) {
editor.insertText('\t');
break;
}
if (!before && Path.isAncestor([0, 0], path)) {
focusedFocusableElement(false);
CustomEditor.tabEvent(yjsEditor, e);
break;
/**
* Outdent block: Shift+Tab
* Default behavior: Outdent block
*/
case createHotkey(HOT_KEY_NAME.OUTDENT_BLOCK)(e):
event.preventDefault();
if (SOFT_BREAK_TYPES.includes(node[0]?.type as BlockType)) {
editor.deleteBackward('character');
break;
}
CustomEditor.tabEvent(yjsEditor, e);
break;
/**
* Split block: Enter
* Default behavior: Split block
* Special case for soft break types: Insert \n
*/
case createHotkey(HOT_KEY_NAME.SPLIT_BLOCK)(e):
if (SOFT_BREAK_TYPES.includes(node[0]?.type as BlockType)) {
event.preventDefault();
editor.insertText('\n');
}
break;
}
case createHotkey(HOT_KEY_NAME.DOWN)(e): {
const after = Editor.after(editor, selection, { unit: 'offset' });
const afterText = findInlineTextNode(editor, after);
if (afterText) {
e.preventDefault();
Transforms.move(editor, { unit: 'line', distance: 2 });
return;
/**
* Insert soft break: Shift+Enter
* Default behavior: Insert \n
* Special case for soft break types: Split block
*/
case createHotkey(HOT_KEY_NAME.INSERT_SOFT_BREAK)(e):
event.preventDefault();
if (node && SOFT_BREAK_TYPES.includes(node[0]?.type as BlockType)) {
editor.insertBreak();
} else {
editor.insertText('\n');
}
break;
}
/**
* Toggle todo: Mod+Enter
* Default behavior: Toggle todo
* Special case for toggle list block: Toggle collapse
*/
case createHotkey(HOT_KEY_NAME.TOGGLE_TODO)(e):
case createHotkey(HOT_KEY_NAME.TOGGLE_COLLAPSE)(e):
event.preventDefault();
case createHotkey(HOT_KEY_NAME.OPEN_LINK)(e): {
if (node[0].type === BlockType.ToggleListBlock) {
CustomEditor.toggleToggleList(yjsEditor, node[0].blockId as string);
} else if (node[0].type === BlockType.TodoListBlock) {
CustomEditor.toggleTodoList(yjsEditor, node[0].blockId as string, false);
}
break;
/**
* Open link: Opt + SHIFT + Enter
*/
case createHotkey(HOT_KEY_NAME.OPEN_LINKS)(e): {
event.preventDefault();
const marks = CustomEditor.getAllMarks(editor);
const links = marks.map((mark) => mark[EditorMarkFormat.Href]).filter(Boolean);
const link = marks.find((mark) => !!mark[EditorMarkFormat.Href])?.[EditorMarkFormat.Href];
if (links.length === 0) break;
links.forEach((link) => {
if (link) void openUrl(link, '_blank');
});
break;
}
if (link) {
void openUrl(link, '_blank');
return;
}
/**
* Extend document backward: Mod + Shift + Up
*/
case createHotkey(HOT_KEY_NAME.EXTEND_DOCUMENT_BACKWARD)(e): {
event.preventDefault();
const { selection } = editor;
if (!selection) return;
const focus = editor.start(selection);
const anchor = editor.start([0, 0]);
editor.select({
anchor,
focus,
});
break;
}
/**
* Extend document forward: Mod + Shift + Down
*/
case createHotkey(HOT_KEY_NAME.EXTEND_DOCUMENT_FORWARD)(e): {
event.preventDefault();
const { selection } = editor;
if (!selection) return;
const anchor = editor.end(selection);
const focus = editor.end([editor.children.length - 1, 0]);
editor.select({
anchor,
focus,
});
break;
}
/**
* Extend line backward: Opt + Shift + Left
*/
case createHotkey(HOT_KEY_NAME.EXTEND_LINE_BACKWARD)(e):
event.preventDefault();
Transforms.move(editor, {
unit: 'word',
reverse: true,
});
break;
/**
* Extend line forward: Opt + Shift + Right
*/
case createHotkey(HOT_KEY_NAME.EXTEND_LINE_FORWARD)(e):
event.preventDefault();
Transforms.move(editor, { unit: 'word' });
break;
/**
* Paste Text: Mod + Shift + V
*/
case createHotkey(HOT_KEY_NAME.PASTE_PLAIN_TEXT)(e):
event.preventDefault();
void navigator.clipboard.readText().then((text) => {
CustomEditor.pastedText(yjsEditor, text);
});
break;
/**
* Scroll to top: control+ Home
*/
case createHotkey(HOT_KEY_NAME.SCROLL_TO_TOP)(e): {
event.preventDefault();
const point = Editor.start(editor, [0, 0]);
if (!point) return;
const dom = ReactEditor.toDOMNode(editor, editor);
void smoothScrollIntoViewIfNeeded(dom, {
behavior: 'smooth',
block: 'start',
});
editor.select({
anchor: point,
focus: point,
});
break;
}
/**
* Scroll to bottom: Control + End
*/
case createHotkey(HOT_KEY_NAME.SCROLL_TO_BOTTOM)(e): {
event.preventDefault();
const point = Editor.end(editor, [editor.children.length - 1, 0]);
if (!point) return;
const dom = ReactEditor.toDOMNode(editor, editor);
void smoothScrollIntoViewIfNeeded(dom, {
behavior: 'smooth',
block: 'end',
});
editor.select({
anchor: point,
focus: point,
});
break;
}
case createHotkey(HOT_KEY_NAME.DELETE_LEFT_SENTENCE)(e): {
/**
* Align left: Control + Shift + L
*/
case createHotkey(HOT_KEY_NAME.ALIGN_LEFT)(e): {
event.preventDefault();
const focus = editor.start(selection);
const anchor = Editor.before(editor, focus, { unit: 'line' });
if (anchor) {
editor.delete({
at: {
anchor,
focus,
},
});
}
const blockId = node[0].blockId as string;
CustomEditor.setBlockData(yjsEditor, blockId, {
align: AlignType.Left,
});
break;
}
/**
* Align center: Control + Shift + E
*/
case createHotkey(HOT_KEY_NAME.ALIGN_CENTER)(e): {
event.preventDefault();
const blockId = node[0].blockId as string;
CustomEditor.setBlockData(yjsEditor, blockId, {
align: AlignType.Center,
});
break;
}
/**
* Align right: Control + Shift + R
*/
case createHotkey(HOT_KEY_NAME.ALIGN_RIGHT)(e): {
event.preventDefault();
const blockId = node[0].blockId as string;
CustomEditor.setBlockData(yjsEditor, blockId, {
align: AlignType.Right,
});
break;
}
case createHotkey(HOT_KEY_NAME.MOVE_CURSOR_TO_BOTTOM)(e): {
event.preventDefault();
const point = Editor.end(editor, [editor.children.length - 1, 0]);
if (!point) return;
const dom = ReactEditor.toDOMNode(editor, editor);
void smoothScrollIntoViewIfNeeded(dom, {
behavior: 'smooth',
block: 'end',
});
editor.select({
anchor: point,
focus: point,
});
break;
}
case createHotkey(HOT_KEY_NAME.DELETE_LEFT_WORD)(e): {
case createHotkey(HOT_KEY_NAME.MOVE_CURSOR_TO_TOP)(e): {
event.preventDefault();
const focus = editor.start(selection);
const anchor = Editor.before(editor, focus, { unit: 'word' });
const point = Editor.start(editor, [0, 0]);
if (anchor) {
editor.delete({
at: {
anchor,
focus,
},
});
}
if (!point) return;
const dom = ReactEditor.toDOMNode(editor, editor);
break;
}
case createHotkey(HOT_KEY_NAME.DELETE_RIGHT_WORD)(e): {
event.preventDefault();
const focus = editor.start(selection);
const anchor = Editor.after(editor, focus, { unit: 'word' });
if (anchor) {
editor.delete({
at: {
anchor,
focus,
},
});
}
void smoothScrollIntoViewIfNeeded(dom, {
behavior: 'smooth',
block: 'start',
});
editor.select({
anchor: point,
focus: point,
});
break;
}
@@ -196,301 +499,16 @@ export function useShortcuts (editor: ReactEditor) {
default:
break;
}
}
// Do not process shortcuts if editor is read-only or no selection
if (readOnly || !selection) return;
const [point] = editor.edges(selection);
const node = getBlockEntry(yjsEditor, point);
// Add more cases here for editing shortcuts
switch (!readOnly) {
/**
* Select all: Mod+A
* Default behavior: Select all text in the editor
* Special case for select all in code block: Only select all text in code block
*/
case createHotkey(HOT_KEY_NAME.SELECT_ALL)(e):
if (node && node[0].type === BlockType.CodeBlock) {
event.preventDefault();
editor.select(node[1]);
}
break;
/**
* Indent block: Tab
* Default behavior: Indent block
*/
case createHotkey(HOT_KEY_NAME.INDENT_BLOCK)(e):
event.preventDefault();
if (SOFT_BREAK_TYPES.includes(node[0]?.type as BlockType)) {
editor.insertText('\t');
break;
}
CustomEditor.tabEvent(yjsEditor, e);
break;
/**
* Outdent block: Shift+Tab
* Default behavior: Outdent block
*/
case createHotkey(HOT_KEY_NAME.OUTDENT_BLOCK)(e):
event.preventDefault();
if (SOFT_BREAK_TYPES.includes(node[0]?.type as BlockType)) {
editor.deleteBackward('character');
break;
}
CustomEditor.tabEvent(yjsEditor, e);
break;
/**
* Split block: Enter
* Default behavior: Split block
* Special case for soft break types: Insert \n
*/
case createHotkey(HOT_KEY_NAME.SPLIT_BLOCK)(e):
if (SOFT_BREAK_TYPES.includes(node[0]?.type as BlockType)) {
event.preventDefault();
editor.insertText('\n');
}
break;
/**
* Insert soft break: Shift+Enter
* Default behavior: Insert \n
* Special case for soft break types: Split block
*/
case createHotkey(HOT_KEY_NAME.INSERT_SOFT_BREAK)(e):
event.preventDefault();
if (node && SOFT_BREAK_TYPES.includes(node[0]?.type as BlockType)) {
editor.insertBreak();
} else {
editor.insertText('\n');
}
break;
/**
* Toggle todo: Mod+Enter
* Default behavior: Toggle todo
* Special case for toggle list block: Toggle collapse
*/
case createHotkey(HOT_KEY_NAME.TOGGLE_TODO)(e):
case createHotkey(HOT_KEY_NAME.TOGGLE_COLLAPSE)(e):
event.preventDefault();
if (node[0].type === BlockType.ToggleListBlock) {
CustomEditor.toggleToggleList(yjsEditor, node[0].blockId as string);
} else if (node[0].type === BlockType.TodoListBlock) {
CustomEditor.toggleTodoList(yjsEditor, node[0].blockId as string, false);
}
break;
/**
* Open link: Opt + SHIFT + Enter
*/
case createHotkey(HOT_KEY_NAME.OPEN_LINKS)(e): {
event.preventDefault();
const marks = CustomEditor.getAllMarks(editor);
const links = marks.map((mark) => mark[EditorMarkFormat.Href]).filter(Boolean);
if (links.length === 0) break;
links.forEach((link) => {
if (link) void openUrl(link, '_blank');
});
break;
}
/**
* Extend document backward: Mod + Shift + Up
*/
case createHotkey(HOT_KEY_NAME.EXTEND_DOCUMENT_BACKWARD)(e): {
event.preventDefault();
const { selection } = editor;
if (!selection) return;
const focus = editor.start(selection);
const anchor = editor.start([0, 0]);
editor.select({
anchor,
focus,
});
break;
}
/**
* Extend document forward: Mod + Shift + Down
*/
case createHotkey(HOT_KEY_NAME.EXTEND_DOCUMENT_FORWARD)(e): {
event.preventDefault();
const { selection } = editor;
if (!selection) return;
const anchor = editor.end(selection);
const focus = editor.end([editor.children.length - 1, 0]);
editor.select({
anchor,
focus,
});
break;
}
/**
* Extend line backward: Opt + Shift + Left
*/
case createHotkey(HOT_KEY_NAME.EXTEND_LINE_BACKWARD)(e):
event.preventDefault();
Transforms.move(editor, {
unit: 'word',
reverse: true,
});
break;
/**
* Extend line forward: Opt + Shift + Right
*/
case createHotkey(HOT_KEY_NAME.EXTEND_LINE_FORWARD)(e):
event.preventDefault();
Transforms.move(editor, { unit: 'word' });
break;
/**
* Paste Text: Mod + Shift + V
*/
case createHotkey(HOT_KEY_NAME.PASTE_PLAIN_TEXT)(e):
event.preventDefault();
void navigator.clipboard.readText().then((text) => {
CustomEditor.pastedText(yjsEditor, text);
});
break;
/**
* Scroll to top: Home
*/
case createHotkey(HOT_KEY_NAME.SCROLL_TO_TOP)(e): {
event.preventDefault();
const dom = ReactEditor.toDOMNode(editor, editor);
void smoothScrollIntoViewIfNeeded(dom, {
behavior: 'smooth',
block: 'start',
});
break;
}
/**
* Scroll to bottom: End
*/
case createHotkey(HOT_KEY_NAME.SCROLL_TO_BOTTOM)(e): {
event.preventDefault();
const dom = ReactEditor.toDOMNode(editor, editor);
void smoothScrollIntoViewIfNeeded(dom, {
behavior: 'smooth',
block: 'end',
});
break;
}
/**
* Align left: Control + Shift + L
*/
case createHotkey(HOT_KEY_NAME.ALIGN_LEFT)(e): {
event.preventDefault();
const blockId = node[0].blockId as string;
CustomEditor.setBlockData(yjsEditor, blockId, {
align: AlignType.Left,
});
break;
}
/**
* Align center: Control + Shift + E
*/
case createHotkey(HOT_KEY_NAME.ALIGN_CENTER)(e): {
event.preventDefault();
const blockId = node[0].blockId as string;
CustomEditor.setBlockData(yjsEditor, blockId, {
align: AlignType.Center,
});
break;
}
/**
* Align right: Control + Shift + R
*/
case createHotkey(HOT_KEY_NAME.ALIGN_RIGHT)(e): {
event.preventDefault();
const blockId = node[0].blockId as string;
CustomEditor.setBlockData(yjsEditor, blockId, {
align: AlignType.Right,
});
break;
}
case createHotkey(HOT_KEY_NAME.MOVE_CURSOR_TO_BOTTOM)(e): {
event.preventDefault();
const point = Editor.end(editor, [editor.children.length - 1, 0]);
if (!point) return;
const dom = ReactEditor.toDOMNode(editor, editor);
void smoothScrollIntoViewIfNeeded(dom, {
behavior: 'smooth',
block: 'end',
});
editor.select({
anchor: point,
focus: point,
});
break;
}
case createHotkey(HOT_KEY_NAME.MOVE_CURSOR_TO_TOP)(e): {
event.preventDefault();
const point = Editor.start(editor, [0, 0]);
if (!point) return;
const dom = ReactEditor.toDOMNode(editor, editor);
void smoothScrollIntoViewIfNeeded(dom, {
behavior: 'smooth',
block: 'start',
});
editor.select({
anchor: point,
focus: point,
});
break;
}
default:
break;
}
}, [focusedFocusableElement, editor, yjsEditor, readOnly]);
},
[focusedFocusableElement, editor, yjsEditor, readOnly]
);
return {
onKeyDown,
};
}
function findInlineTextNode (editor: Editor, point?: BasePoint) {
function findInlineTextNode(editor: Editor, point?: BasePoint) {
const [node] = editor.nodes({
at: point,
match: (n) => {
@@ -499,4 +517,4 @@ function findInlineTextNode (editor: Editor, point?: BasePoint) {
});
return node;
}
}

View File

@@ -93,8 +93,8 @@ const defaultHotKeys = {
[HOT_KEY_NAME.HIGH_LIGHT]: ['mod+shift+h'],
[HOT_KEY_NAME.EXTEND_DOCUMENT_BACKWARD]: ['mod+shift+up'],
[HOT_KEY_NAME.EXTEND_DOCUMENT_FORWARD]: ['mod+shift+down'],
[HOT_KEY_NAME.SCROLL_TO_TOP]: ['Home'],
[HOT_KEY_NAME.SCROLL_TO_BOTTOM]: ['end'],
[HOT_KEY_NAME.SCROLL_TO_TOP]: ['control+Home'],
[HOT_KEY_NAME.SCROLL_TO_BOTTOM]: ['control+end'],
[HOT_KEY_NAME.TOGGLE_THEME]: ['mod+shift+l'],
[HOT_KEY_NAME.TOGGLE_SIDEBAR]: ['mod+.'],
[HOT_KEY_NAME.FORMAT_LINK]: ['mod+k'],
@@ -130,7 +130,6 @@ export const createHotkey = (hotkeyName: HOT_KEY_NAME, customHotKeys?: Record<HO
const keys = customHotKeys || defaultHotKeys;
const hotkeys = keys[hotkeyName];
return (event: KeyboardEvent) => {
return hotkeys.some((hotkey) => {
return isHotkey(hotkey, event);
@@ -155,7 +154,7 @@ export const createHotKeyLabel = (hotkeyName: HOT_KEY_NAME, customHotKeys?: Reco
.map((key) => {
return key === ' ' ? 'Space' : key.charAt(0).toUpperCase() + key.slice(1);
})
.join(' + '),
.join(' + ')
)
.join(' / ');
};