import { type ReactNode } from "react"; import { isElectron } from "~/env";import { getPreviewPanelMaxWidth, type PreviewPanelInlineSize, usePreviewPanelInlineSize,} from "~/hooks/usePreviewPanelInlineSize"; export { getPreviewPanelMaxWidth };import { cn } from "~/lib/utils"; import { RightPanelResizeHandle } from "./RightPanelResizeHandle"; export type PreviewPanelMode = "inline" | "sheet" | "sidebar" | "embedded"; /** * Shell for the preview panel. In inline mode the panel is user-resizable * via a drag handle on the left edge; width persists per browser. In * sheet/sidebar modes the parent owns the size. */interface PreviewPanelShellProps { mode: PreviewPanelMode; maximized?: boolean; inlineSize?: PreviewPanelInlineSize; children: ReactNode;} export function PreviewPanelShell(props: PreviewPanelShellProps) { if (props.inlineSize) { return <PreviewPanelShellFrame {...props} inlineSize={props.inlineSize} />; } return <ResizablePreviewPanelShell {...props} />;} function ResizablePreviewPanelShell(props: PreviewPanelShellProps) { const inlineSize = usePreviewPanelInlineSize(); return <PreviewPanelShellFrame {...props} inlineSize={inlineSize} />;} function PreviewPanelShellFrame( props: PreviewPanelShellProps & { inlineSize: PreviewPanelInlineSize },) { const useDragRegion = isElectron && props.mode !== "sheet" && props.mode !== "embedded"; const isInline = props.mode === "inline"; const { width, handlers } = props.inlineSize; return ( <div className={cn( "relative flex h-full min-h-0 min-w-0 flex-col self-stretch bg-background", isInline ? props.maximized ? "flex-1 border-l border-border" : "shrink-0 border-l border-border" : "w-full", )} style={isInline && !props.maximized ? { width: `${width}px` } : undefined} data-preview-panel-mode={props.mode} data-preview-panel-maximized={props.maximized ? "true" : "false"} > {isInline && !props.maximized ? <RightPanelResizeHandle handlers={handlers} /> : null} {useDragRegion ? <div className="electron-drag-region h-0 w-full" aria-hidden /> : null} {props.children} </div> );}
import { type ReactNode } from "react";
import { isElectron } from "~/env";
import {
getPreviewPanelMaxWidth,
type PreviewPanelInlineSize,
usePreviewPanelInlineSize,
} from "~/hooks/usePreviewPanelInlineSize";
export { getPreviewPanelMaxWidth };
import { cn } from "~/lib/utils";
import { RightPanelResizeHandle } from "./RightPanelResizeHandle";
export type PreviewPanelMode = "inline" | "sheet" | "sidebar" | "embedded";
/**
* Shell for the preview panel. In inline mode the panel is user-resizable
* via a drag handle on the left edge; width persists per browser. In
* sheet/sidebar modes the parent owns the size.
*/
interface PreviewPanelShellProps {
mode: PreviewPanelMode;
maximized?: boolean;
inlineSize?: PreviewPanelInlineSize;
children: ReactNode;
}
export function PreviewPanelShell(props: PreviewPanelShellProps) {
if (props.inlineSize) {
return <PreviewPanelShellFrame {...props} inlineSize={props.inlineSize} />;
}
return <ResizablePreviewPanelShell {...props} />;
}
function ResizablePreviewPanelShell(props: PreviewPanelShellProps) {
const inlineSize = usePreviewPanelInlineSize();
return <PreviewPanelShellFrame {...props} inlineSize={inlineSize} />;
}
function PreviewPanelShellFrame(
props: PreviewPanelShellProps & { inlineSize: PreviewPanelInlineSize },
) {
const useDragRegion = isElectron && props.mode !== "sheet" && props.mode !== "embedded";
const isInline = props.mode === "inline";
const { width, handlers } = props.inlineSize;
return (
<div
className={cn(
"relative flex h-full min-h-0 min-w-0 flex-col self-stretch bg-background",
isInline
? props.maximized
? "flex-1 border-l border-border"
: "shrink-0 border-l border-border"
: "w-full",
)}
style={isInline && !props.maximized ? { width: `${width}px` } : undefined}
data-preview-panel-mode={props.mode}
data-preview-panel-maximized={props.maximized ? "true" : "false"}
>
{isInline && !props.maximized ? <RightPanelResizeHandle handlers={handlers} /> : null}
{useDragRegion ? <div className="electron-drag-region h-0 w-full" aria-hidden /> : null}
{props.children}
</div>
);
}