MCPcopy Index your code
hub / github.com/claude-code-best/claude-code / FullscreenLayout

Function FullscreenLayout

src/components/FullscreenLayout.tsx:285–460  ·  view source on GitHub ↗
({
  scrollable,
  bottom,
  overlay,
  bottomFloat,
  modal,
  modalScrollRef,
  scrollRef,
  dividerYRef,
  hidePill = false,
  hideSticky = false,
  newMessageCount = 0,
  onPillClick,
}: Props)

Source from the content-addressed store, hash-verified

283 * so nothing can accidentally render outside it.
284 */
285export function FullscreenLayout({
286 scrollable,
287 bottom,
288 overlay,
289 bottomFloat,
290 modal,
291 modalScrollRef,
292 scrollRef,
293 dividerYRef,
294 hidePill = false,
295 hideSticky = false,
296 newMessageCount = 0,
297 onPillClick,
298}: Props): React.ReactNode {
299 const { rows: terminalRows, columns } = useTerminalSize();
300 // Scroll-derived chrome state lives HERE, not in REPL. StickyTracker
301 // writes via ScrollChromeContext; pillVisible subscribes directly to
302 // ScrollBox. Both change rarely (pill flips once per threshold crossing,
303 // sticky changes ~5-20×/transcript) — re-rendering FullscreenLayout on
304 // those is fine; re-rendering the 6966-line REPL + its 22+ useAppState
305 // selectors per-scroll-frame was not.
306 const [stickyPrompt, setStickyPrompt] = useState<StickyPrompt | null>(null);
307 const chromeCtx = useMemo(() => ({ setStickyPrompt }), []);
308 // Boolean-quantized scroll subscription. Snapshot is "is viewport bottom
309 // above the divider y?" — Object.is on a boolean → FullscreenLayout only
310 // re-renders when the pill should actually flip, not per-frame.
311 const subscribe = useCallback(
312 (listener: () => void) => scrollRef?.current?.subscribe(listener) ?? (() => {}),
313 [scrollRef],
314 );
315 const pillVisible = useSyncExternalStore(subscribe, () => {
316 const s = scrollRef?.current;
317 const dividerY = dividerYRef?.current;
318 if (!s || dividerY == null) return false;
319 return s.getScrollTop() + s.getPendingDelta() + s.getViewportHeight() < dividerY;
320 });
321 // Wire up hyperlink click handling — in fullscreen mode, mouse tracking
322 // intercepts clicks before the terminal can open OSC 8 links natively.
323 useLayoutEffect(() => {
324 if (!isFullscreenEnvEnabled()) return;
325 const ink = instances.get(process.stdout);
326 if (!ink) return;
327 ink.onHyperlinkClick = url => {
328 // Most OSC 8 links emitted by Claude Code are file:// URLs from
329 // FilePathLink (FileEdit/FileWrite/FileRead tool output). openBrowser
330 // rejects non-http(s) protocols — route file: to openPath instead.
331 if (url.startsWith('file:')) {
332 try {
333 void openPath(fileURLToPath(url));
334 } catch {
335 // Malformed file: URLs (e.g. file://host/path from plain-text
336 // detection) cause fileURLToPath to throw — ignore silently.
337 }
338 } else {
339 void openBrowser(url);
340 }
341 };
342 return () => {

Callers

nothing calls this directly

Calls 6

useTerminalSizeFunction · 0.85
isFullscreenEnvEnabledFunction · 0.85
openPathFunction · 0.85
openBrowserFunction · 0.85
getMethod · 0.65
subscribeMethod · 0.45

Tested by

no test coverage detected