import { Box, Text, useUiCapabilities } from "../../ui"; import type { ReactNode } from "react"; import { colors, floatingPaneBg } from "../../theme/colors"; import { PaneBodyFrame, getPaneWindowAttributes } from "./pane/frame"; import { PaneHeader, type PaneHeaderQuickSetting } from "./pane/header"; import { PaneHeaderTabsProvider, usePaneHeaderTabsHost } from "./pane/header-tabs"; import { hasPaneFooterContent, PaneFooterBar, type CombinedPaneFooter } from "./pane/footer"; import { resolvePaneBodyFrame, shouldReservePaneFooter } from "./pane/sizing"; interface FloatingPaneWrapperProps { paneId?: string; title: string; x: number; y: number; width: number; height: number; zIndex: number; /** Fully covered by windows above it: skip drawing, keep the tree mounted. */ hidden?: boolean; focused: boolean; windowModeSelected?: boolean; locked?: boolean; showActions?: boolean; quickSettings?: PaneHeaderQuickSetting[]; onMouseDown?: (event: any) => void; onMouseDownCapture?: (event: any) => void; onHeaderMouseMove?: (event: any) => void; onHeaderMouseDown?: (event: any) => void; onHeaderMouseDrag?: (event: any) => void; onHeaderMouseDragEnd?: (event: any) => void; onHeaderContextMenu?: (event: any) => void; onActionMouseDown?: (event: any) => void; onCloseMouseDown?: (event: any) => void; onResizeMouseDown?: (event: any) => void; onResizeMouseDrag?: (event: any) => void; onResizeMouseDragEnd?: (event: any) => void; footer?: CombinedPaneFooter | null; children: ReactNode; } function TerminalFloatingPaneBorder({ width, height }: { width: number; height: number }) { const borderWidth = Math.max(0, Math.floor(width)); const borderHeight = Math.max(0, Math.floor(height)); const bodyHeight = Math.max(0, borderHeight - 2); if (borderWidth < 2 || bodyHeight <= 0) return null; return ( <> {"│".repeat(bodyHeight)} {"│".repeat(bodyHeight)} ); } /** Pure visual wrapper; Shell owns the interaction state and supplies handlers. */ export function FloatingPaneWrapper({ paneId, title, x, y, width, height, zIndex, hidden = false, focused, windowModeSelected = false, locked = false, showActions = false, quickSettings, onMouseDown, onMouseDownCapture, onHeaderMouseMove, onHeaderMouseDown, onHeaderMouseDrag, onHeaderMouseDragEnd, onHeaderContextMenu, onActionMouseDown, onCloseMouseDown, onResizeMouseDown, onResizeMouseDrag, onResizeMouseDragEnd, footer, children, }: FloatingPaneWrapperProps) { const { nativePaneChrome } = useUiCapabilities(); const { headerTabs, contextValue: headerTabsContext } = usePaneHeaderTabsHost(nativePaneChrome === true); const bg = floatingPaneBg(focused); const showFooter = hasPaneFooterContent(footer); const reserveFooter = shouldReservePaneFooter(nativePaneChrome, showFooter); const renderFooter = reserveFooter || showFooter; const bodyFrame = resolvePaneBodyFrame({ height, nativePaneChrome, footerVisible: renderFooter, reserveFooter }); return ( {children} {renderFooter && ( )} {!nativePaneChrome && !focused && } {nativePaneChrome ? ( ) : ( {"─◢"} )} ); }