diff --git a/demos/platform/src/app/app.tsx b/demos/platform/src/app/app.tsx index dcafc2ee..da8e7c82 100644 --- a/demos/platform/src/app/app.tsx +++ b/demos/platform/src/app/app.tsx @@ -399,10 +399,9 @@ export default function App() { - -
{contextMarker}
+
+            {contextMarker}
+          
{isOptionsDefined && ( <> diff --git a/libs/shared-react/src/plugins/usj/CommandMenuPlugin.tsx b/libs/shared-react/src/plugins/usj/CommandMenuPlugin.tsx index 444da07f..9aef7e02 100644 --- a/libs/shared-react/src/plugins/usj/CommandMenuPlugin.tsx +++ b/libs/shared-react/src/plugins/usj/CommandMenuPlugin.tsx @@ -6,7 +6,6 @@ import { LoggerBasic } from "shared"; /** * This plugin prevents the backslash or forward slash key from being typed, or pasted or dragged. - * Later this plugin will open the command menu to insert USJ elements. * @returns `null`. This plugin has no DOM presence. */ export function CommandMenuPlugin({ logger }: { logger?: LoggerBasic }): null { diff --git a/libs/shared-react/src/plugins/usj/DisableHistoryShortcutsPlugin.tsx b/libs/shared-react/src/plugins/usj/DisableHistoryShortcutsPlugin.tsx new file mode 100644 index 00000000..e45b44c0 --- /dev/null +++ b/libs/shared-react/src/plugins/usj/DisableHistoryShortcutsPlugin.tsx @@ -0,0 +1,34 @@ +import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext"; +import { IS_APPLE } from "@lexical/utils"; +import { COMMAND_PRIORITY_CRITICAL, KEY_DOWN_COMMAND } from "lexical"; +import { useEffect } from "react"; + +/** + * Prevent undo and redo keyboard shortcuts while preserving command-based undo/redo. + * @returns `null`. This plugin has no DOM presence. + */ +export function DisableHistoryShortcutsPlugin(): null { + const [editor] = useLexicalComposerContext(); + + useEffect(() => { + return editor.registerCommand( + KEY_DOWN_COMMAND, + (event: KeyboardEvent) => { + const { key, shiftKey, metaKey, ctrlKey, altKey } = event; + if (!(IS_APPLE ? metaKey : ctrlKey) || altKey) return false; + + const normalizedKey = key.toLowerCase(); + const isUndo = normalizedKey === "z" && !shiftKey; + const isRedo = normalizedKey === "y" || (normalizedKey === "z" && shiftKey); + + if (!isUndo && !isRedo) return false; + + event.preventDefault(); + return true; + }, + COMMAND_PRIORITY_CRITICAL, + ); + }, [editor]); + + return null; +} diff --git a/libs/shared-react/src/plugins/usj/index.ts b/libs/shared-react/src/plugins/usj/index.ts index 78277f34..d925eb8e 100644 --- a/libs/shared-react/src/plugins/usj/index.ts +++ b/libs/shared-react/src/plugins/usj/index.ts @@ -7,6 +7,7 @@ export * from "./clipboard.utils"; export * from "./ClipboardPlugin"; export * from "./CommandMenuPlugin"; export * from "./ContextMenuPlugin"; +export * from "./DisableHistoryShortcutsPlugin"; export * from "./EditablePlugin"; export * from "./LoadStatePlugin"; export * from "./NoteNodePlugin"; diff --git a/packages/platform/src/editor/Editor.tsx b/packages/platform/src/editor/Editor.tsx index 086f3bdd..742fb491 100644 --- a/packages/platform/src/editor/Editor.tsx +++ b/packages/platform/src/editor/Editor.tsx @@ -64,6 +64,7 @@ import { ContextMenuPlugin, DeltaOnChangePlugin, DeltaOp, + DisableHistoryShortcutsPlugin, EditablePlugin, getDefaultViewOptions, getInsertedNodeKey, @@ -362,11 +363,12 @@ const Editor = forwardRef(function Editor( placeholder={} ErrorBoundary={LexicalErrorBoundary} /> + {hasExternalUI && } {scrRef && onScrRefChange && ( )} - {scrRef && ( + {scrRef && !hasExternalUI && (