diff --git a/.changeset/shortcuts.md b/.changeset/shortcuts.md new file mode 100644 index 0000000000..4812dcc3d8 --- /dev/null +++ b/.changeset/shortcuts.md @@ -0,0 +1,5 @@ +--- +"@emdash-cms/admin": patch +--- + +Fixes the content editor's distraction-free mode shortcut so `⌘⇧\` (or `Ctrl+Shift+\`) toggles the mode both in and out, keeps the exit button visible without hovering, and no longer treats `Escape` as an exit trigger. diff --git a/packages/admin/src/components/ContentEditor.tsx b/packages/admin/src/components/ContentEditor.tsx index ef1b0f1fea..44d9ba3ee1 100644 --- a/packages/admin/src/components/ContentEditor.tsx +++ b/packages/admin/src/components/ContentEditor.tsx @@ -23,6 +23,7 @@ import { } from "@phosphor-icons/react"; import type { Editor } from "@tiptap/react"; import * as React from "react"; +import { useHotkeys } from "react-hotkeys-hook"; import type { BylineCreditInput, @@ -884,22 +885,20 @@ export function ContentEditor({ // Distraction-free mode state const [isDistractionFree, setIsDistractionFree] = React.useState(false); - // Escape exits distraction-free mode - React.useEffect(() => { - if (!isDistractionFree) return; - - const handleKeyDown = (e: KeyboardEvent) => { - if (e.key === "Escape") { - if (scheduleDialogOpen || publishingMenuOpen) return; - e.preventDefault(); - e.stopPropagation(); - setIsDistractionFree(false); - } - }; - - document.addEventListener("keydown", handleKeyDown, { capture: true }); - return () => document.removeEventListener("keydown", handleKeyDown, { capture: true }); - }, [isDistractionFree, publishingMenuOpen, scheduleDialogOpen]); + // The title advertises ⌘⇧\\ as the shortcut, so register it globally. + // It toggles both into and out of the mode, but is disabled while a + // publishing menu or schedule dialog is open. + const canToggleDistractionFree = !scheduleDialogOpen && !publishingMenuOpen; + useHotkeys( + "mod+shift+\\", + (e) => { + if (!canToggleDistractionFree) return; + e.preventDefault(); + setIsDistractionFree((prev) => !prev); + }, + { enableOnFormTags: true, useKey: true }, + [canToggleDistractionFree], + ); return (