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 ? (
) : (
{"─◢"}
)}
);
}