| 1 | // Measures the transcript surface the launcher card floats over and reports |
| 2 | // whether the card still fits. The card yields the space entirely below |
| 3 | // HIDE_BELOW_WIDTH so it never crowds the chat. |
| 4 | // |
| 5 | // The mode is mirrored onto <html> so siblings OUTSIDE the transcript surface |
| 6 | // (the footer/composer) reserve the same right inset via plain CSS — no |
| 7 | // App-level re-render on every resize tick. |
| 8 | import { useEffect, useState } from "react"; |
| 9 | import type { RefObject } from "react"; |
| 10 | import type { SpaceMode } from "./launcherCardState"; |
| 11 | |
| 12 | // Space priority for the docked launcher: the panel yields FIRST. The panel |
| 13 | // only appears when the surface is at least 1010px wide (history keeps ~770px |
| 14 | // of the 800px comfort target while the panel is docked); below that the |
| 15 | // panel hides and the history stretches/compresses to fill the whole window. |
| 16 | const HIDE_BELOW_WIDTH = 1010; |
| 17 | |
| 18 | export function useDockLauncherSpace( |
| 19 | rootRef: RefObject<HTMLElement | null>, |
| 20 | onSpaceModeChange?: (mode: SpaceMode) => void, |
| 21 | ): SpaceMode { |
| 22 | const [spaceMode, setSpaceMode] = useState<SpaceMode>("full"); |
| 23 | |
| 24 | useEffect(() => { |
| 25 | const host = rootRef.current?.parentElement; |
| 26 | if (!host || typeof ResizeObserver === "undefined") return; |
| 27 | const observer = new ResizeObserver((entries) => { |
| 28 | const width = entries[0]?.contentRect.width ?? 0; |
| 29 | const next = width < HIDE_BELOW_WIDTH ? "hidden" : "full"; |
| 30 | setSpaceMode(next); |
| 31 | onSpaceModeChange?.(next); |
| 32 | }); |
| 33 | observer.observe(host); |
| 34 | return () => observer.disconnect(); |
| 35 | }, [rootRef, onSpaceModeChange]); |
| 36 | |
| 37 | useEffect(() => { |
| 38 | document.documentElement.dataset.dockLauncher = spaceMode; |
| 39 | return () => { |
| 40 | delete document.documentElement.dataset.dockLauncher; |
| 41 | }; |
| 42 | }, [spaceMode]); |
| 43 | |
| 44 | return spaceMode; |
| 45 | } |
| 46 |