mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-10 22:20:14 +00:00
refactor(studio): extract shared timeline components and deduplicate code (#1329)
Extract shared utilities to reduce duplication across timeline components: - PlayheadIndicator: shared playhead rendering (was duplicated in TimelineCanvas and TimelineEditorNotice) - useContextMenuDismiss: outside-click/Escape dismiss pattern (was duplicated in ClipContextMenu and KeyframeDiamondContextMenu) - TimelineCallbacks: shared callback interfaces for drop and edit operations (was duplicated in NLELayout and Timeline props) - useTimelineZoom: consolidated zoom store selectors - timelineElementSplit: shared canSplitElement, buildPatchTarget, and readFileContent utilities - gsapParser.test-helpers: shared test utilities for parser specs
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
import { useCallback, useEffect, useRef, type RefObject } from "react";
|
||||
|
||||
/**
|
||||
* Shared dismiss logic for context menus: closes on outside click or Escape.
|
||||
* Returns a ref to attach to the menu container element.
|
||||
*/
|
||||
export function useContextMenuDismiss(onClose: () => void): RefObject<HTMLDivElement | null> {
|
||||
const menuRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const dismiss = useCallback(
|
||||
(e: MouseEvent | KeyboardEvent) => {
|
||||
if (e instanceof KeyboardEvent && e.key !== "Escape") return;
|
||||
if (e instanceof MouseEvent && menuRef.current?.contains(e.target as Node)) return;
|
||||
onClose();
|
||||
},
|
||||
[onClose],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
document.addEventListener("mousedown", dismiss);
|
||||
document.addEventListener("keydown", dismiss);
|
||||
return () => {
|
||||
document.removeEventListener("mousedown", dismiss);
|
||||
document.removeEventListener("keydown", dismiss);
|
||||
};
|
||||
}, [dismiss]);
|
||||
|
||||
return menuRef;
|
||||
}
|
||||
Reference in New Issue
Block a user