| 1 | "use client"; |
| 2 | |
| 3 | /** |
| 4 | * Typed window-event bus for preview-panel actions. Lets the global |
| 5 | * keybinding handler in `routes/_chat.tsx` reach `ChatView`'s URL-aware |
| 6 | * arbitration without prop drilling or shared refs. |
| 7 | */ |
| 8 | export type PreviewAction = |
| 9 | | "toggle-panel" |
| 10 | | "refresh" |
| 11 | | "focus-url" |
| 12 | | "zoom-in" |
| 13 | | "zoom-out" |
| 14 | | "reset-zoom"; |
| 15 | |
| 16 | const EVENT_NAME = "t3code:preview-action"; |
| 17 | |
| 18 | export function dispatchPreviewAction(action: PreviewAction): void { |
| 19 | if (typeof window === "undefined") return; |
| 20 | window.dispatchEvent(new CustomEvent<PreviewAction>(EVENT_NAME, { detail: action })); |
| 21 | } |
| 22 | |
| 23 | export function subscribePreviewAction(listener: (action: PreviewAction) => void): () => void { |
| 24 | if (typeof window === "undefined") return () => {}; |
| 25 | const handler = (event: Event) => { |
| 26 | const detail = (event as CustomEvent<PreviewAction>).detail; |
| 27 | if (typeof detail === "string") listener(detail); |
| 28 | }; |
| 29 | window.addEventListener(EVENT_NAME, handler); |
| 30 | return () => window.removeEventListener(EVENT_NAME, handler); |
| 31 | } |