diff --git a/src/components/KeyboardShortcutPanel.tsx b/src/components/KeyboardShortcutPanel.tsx
new file mode 100644
index 00000000..caf07770
--- /dev/null
+++ b/src/components/KeyboardShortcutPanel.tsx
@@ -0,0 +1,101 @@
+"use client";
+
+import { useEffect } from "react";
+import { X } from "lucide-react";
+
+interface ShortcutPanelProps {
+ open: boolean;
+ onClose: () => void;
+}
+
+const shortcuts = [
+ { keys: ["Cmd/Ctrl", "+", "Enter"], action: "Start export" },
+ { keys: ["Space"], action: "Play / pause preview" },
+ { keys: ["?"], action: "Toggle this shortcut panel" },
+ { keys: ["Escape"], action: "Close overlay / cancel" },
+ { keys: ["M"], action: "Toggle audio mute" },
+];
+
+function ShortcutRow({ keys, action }: { keys: string[]; action: string }) {
+ return (
+
+ {action}
+
+ {keys.map((key) => (
+
+ {key}
+
+ ))}
+
+
+ );
+}
+
+export default function KeyboardShortcutPanel({ open, onClose }: ShortcutPanelProps) {
+ useEffect(() => {
+ if (!open) return;
+ const onKey = (e: KeyboardEvent) => {
+ if (e.key === "Escape") onClose();
+ };
+
+ const previousOverflow = document.body.style.overflow;
+
+ document.body.style.overflow = "hidden";
+ document.addEventListener("keydown", onKey);
+ return () => {
+ document.removeEventListener("keydown", onKey);
+ document.body.style.overflow = previousOverflow;
+ };
+ }, [open, onClose]);
+
+ if (!open) return null;
+
+ return (
+
+
+
+
+
+
Quick help
+
+ Keyboard Shortcuts
+
+
+
+
+
+
+
+ Keep the editor moving without hunting for controls.
+
+
+
+ {shortcuts.map(({ keys, action }) => (
+
+ ))}
+
+
+
+
+ );
+}
diff --git a/src/components/VideoEditor.tsx b/src/components/VideoEditor.tsx
index db5c3793..5f9ffddd 100644
--- a/src/components/VideoEditor.tsx
+++ b/src/components/VideoEditor.tsx
@@ -16,11 +16,12 @@ import ExportSettings from "./ExportSettings";
import ExportOverlay from "./ExportOverlay";
import DownloadResult from "./DownloadResult";
import ImageOverlay from "./ImageOverlay"
+import KeyboardShortcutPanel from "./KeyboardShortcutPanel";
import { cn } from "@/lib/utils";
import {
Layers, Crop, Scissors, RotateCw, Volume2,
- SlidersHorizontal, Zap, AlertTriangle, Github, Copy
+ SlidersHorizontal, Zap, AlertTriangle, Copy, HelpCircle
} from "lucide-react";
import OnboardingTour from "./OnboardingTour";
import { useKeyboardShortcuts } from "@/hooks/useKeyboardShortcuts";
@@ -50,94 +51,6 @@ function Section({ icon, title, children, delay = 0 }: SectionProps) {
);
}
-/** Inline keyboard hint badge. */
-function Kbd({ children }: { children: React.ReactNode }) {
- return (
-
- {children}
-
- );
-}
-
-/** Collapsible panel that lists all keyboard shortcuts. */
-function KeyboardShortcutsPanel() {
- const [open, setOpen] = useState(false);
-
- const shortcuts: { keys: React.ReactNode[]; label: string }[] = [
- {
- keys: [
- Ctrl,
- +,
- Shift,
- +,
- E
- ],
- label: "Export video",
- },
- {
- keys: [M],
- label: "Toggle audio mute",
- },
- {
- keys: [R],
- label: "Reset all settings",
- },
- {
- keys: [Esc],
- label: "Cancel export",
- },
- {
- keys: [1, –, 9],
- label: "Switch preset by index",
- },
- {
- keys: [?],
- label: "Toggle this panel",
- },
-];
-
- return (
-
-
-
- {open && (
-
- {shortcuts.map(({ keys, label }) => (
- -
- {label}
- {keys}
-
- ))}
-
- )}
-
- );
-}
-
export default function VideoEditor() {
const {
file, duration, recipe, status, progress,
@@ -149,6 +62,7 @@ export default function VideoEditor() {
overlayPosition, setOverlayPosition,
overlaySize, setOverlaySize,
overlayOpacity, setOverlayOpacity,
+ isShortcutPanelOpen, closeShortcutPanel, toggleShortcutPanel,
recommendedPreset,
toggleSound,
} = useVideoEditor();
@@ -203,6 +117,7 @@ export default function VideoEditor() {
return (
+
@@ -213,7 +128,7 @@ export default function VideoEditor() {
-
-
-