diff --git a/src/app/dashboard/[subdomain]/editor/page.tsx b/src/app/dashboard/[subdomain]/editor/page.tsx index 598a7b8b..6feb98b1 100644 --- a/src/app/dashboard/[subdomain]/editor/page.tsx +++ b/src/app/dashboard/[subdomain]/editor/page.tsx @@ -34,7 +34,7 @@ import { Modal } from "~/components/ui/Modal" import { Switch } from "~/components/ui/Switch" import { TagInput } from "~/components/ui/TagInput" import { UniLink } from "~/components/ui/UniLink" -import { toolbars } from "~/editor" +import { toolbarShortcuts, toolbars } from "~/editor" import { editorUpload } from "~/editor/Multimedia" import { Values, @@ -619,6 +619,7 @@ export default function SubdomainEditor() { "h-full flex-1", isRendering ? "border-r" : "", )} + shortcuts={toolbarShortcuts} /> )} {!isMobileLayout && ( diff --git a/src/components/ui/CodeMirror.tsx b/src/components/ui/CodeMirror.tsx index 36173c5f..f68f5485 100644 --- a/src/components/ui/CodeMirror.tsx +++ b/src/components/ui/CodeMirror.tsx @@ -47,6 +47,7 @@ interface XLogCodeMirrorEditorProps { onCreateEditor?: (view: EditorView, state: EditorState) => void onMouseEnter?: () => void LoadingComponent?: () => JSX.Element + shortcuts?: KeyBinding[] } export const CodeMirrorEditor = forwardRef< @@ -189,6 +190,7 @@ const LazyCodeMirrorEditor = forwardRef< }), keymap.of([ + ...(props.shortcuts ?? []), ...defaultKeymap, ...historyKeymap, ...markdownKeymap, diff --git a/src/editor/Bold.tsx b/src/editor/Bold.tsx index b4402e5a..12b88808 100644 --- a/src/editor/Bold.tsx +++ b/src/editor/Bold.tsx @@ -1,10 +1,23 @@ -import { ICommand, wrapExecute } from "." +import { type EditorView } from "@codemirror/view" + +import { type ICommand, wrapExecute } from "." + +const action = (view: EditorView) => { + wrapExecute({ view, prepend: "**", append: "**" }) +} export const Bold: ICommand = { name: "bold", label: "Bold", icon: "icon-[mingcute--bold-line]", - execute: ({ view }) => { - wrapExecute({ view, prepend: "**", append: "**" }) + execute({ view }) { + action(view) + }, + shortcut: { + key: "Mod-b", + run(view) { + action(view) + return true + }, }, } diff --git a/src/editor/Italic.tsx b/src/editor/Italic.tsx index 10710f1b..ae5f9052 100644 --- a/src/editor/Italic.tsx +++ b/src/editor/Italic.tsx @@ -1,10 +1,23 @@ -import { ICommand, wrapExecute } from "." +import { type EditorView } from "@codemirror/view" + +import { type ICommand, wrapExecute } from "." + +const action = (view: EditorView) => { + wrapExecute({ view, prepend: "_", append: "_" }) +} export const Italic: ICommand = { name: "italic", label: "Italic", icon: "icon-[mingcute--italic-line]", - execute: ({ view }) => { - wrapExecute({ view, prepend: "_", append: "_" }) + execute({ view }) { + action(view) + }, + shortcut: { + key: "Mod-i", + run(view) { + action(view) + return true + }, }, } diff --git a/src/editor/Link.tsx b/src/editor/Link.tsx index 72fb038e..2290e7c8 100644 --- a/src/editor/Link.tsx +++ b/src/editor/Link.tsx @@ -1,10 +1,23 @@ -import { ICommand, wrapExecute } from "." +import { type EditorView } from "@codemirror/view" + +import { type ICommand, wrapExecute } from "." + +const action = (view: EditorView) => { + wrapExecute({ view, prepend: "[", append: "]()" }) +} export const Link: ICommand = { name: "link", label: "Link", icon: "icon-[mingcute--link-2-line]", - execute: ({ view }) => { - wrapExecute({ view, prepend: "[", append: "]()" }) + execute({ view }) { + action(view) + }, + shortcut: { + key: "Mod-k", + run(view) { + action(view) + return true + }, }, } diff --git a/src/editor/Underline.tsx b/src/editor/Underline.tsx index 17cd90ef..f07d96b7 100644 --- a/src/editor/Underline.tsx +++ b/src/editor/Underline.tsx @@ -1,10 +1,23 @@ -import { ICommand, wrapExecute } from "." +import { type EditorView } from "@codemirror/view" + +import { type ICommand, wrapExecute } from "." + +const action = (view: EditorView) => { + wrapExecute({ view, prepend: "", append: "" }) +} export const Underline: ICommand = { name: "underline", label: "Underline", icon: "icon-[mingcute--underline-line]", execute: ({ view }) => { - wrapExecute({ view, prepend: "", append: "" }) + action(view) + }, + shortcut: { + key: "Mod-u", + run(view) { + action(view) + return true + }, }, } diff --git a/src/editor/index.tsx b/src/editor/index.tsx index 75427579..48d0879e 100644 --- a/src/editor/index.tsx +++ b/src/editor/index.tsx @@ -1,7 +1,7 @@ import { Dispatch, SetStateAction } from "react" import { EditorSelection } from "@codemirror/state" -import { EditorView } from "@codemirror/view" +import { type EditorView, type KeyBinding } from "@codemirror/view" import { AlignCenter } from "./AlignCenter" import { AlignRight } from "./AlignRight" @@ -42,6 +42,8 @@ export type ICommand
= {
transferPayload: (payload: P) => void
view: EditorView
}) => JSX.Element
+
+ shortcut?: KeyBinding
}
export type IPrependExecute = {
@@ -106,5 +108,9 @@ export const toolbars: ICommand[] = [
Help,
]
+export const toolbarShortcuts = toolbars
+ .map((t) => t.shortcut)
+ .filter(