import { forwardRef, type ReactNode, type HTMLAttributes } from "react"; import { cn } from "@kandev/ui/lib/utils"; /** * Reusable dockview panel layout primitives. * * PanelRoot - outermost wrapper, fills the dockview content area * PanelBody - scrollable (or non-scrollable) content region * PanelToolbar - fixed header strip for panel actions */ const PANEL_ROOT_CLASS = "h-full min-h-0 flex flex-col bg-card text-card-foreground"; const PANEL_BAR_CLASS = "flex items-center gap-1.5 h-[30px] px-2.5 shrink-0 border-border/80 bg-card/95 text-xs text-foreground"; const PANEL_ACTION_CURSOR_CLASS = "[&_button:not(:disabled)]:cursor-pointer [&_[role=button]:not([aria-disabled=true])]:cursor-pointer"; type PanelRootProps = HTMLAttributes & { children: ReactNode; className?: string; }; /** Fills the dockview content slot. Use as the outermost element in every panel. */ export const PanelRoot = forwardRef(function PanelRoot( { children, className, ...rest }, ref, ) { return (
{children}
); }); type PanelBodyProps = Omit, "className"> & { children: ReactNode; className?: string; /** Add default p-2.5 padding. Default true. */ padding?: boolean; /** Enable overflow scrolling. Default true. */ scroll?: boolean; }; /** Flexible content area that grows to fill remaining space. */ export const PanelBody = forwardRef(function PanelBody( { children, className, padding = true, scroll = true, ...rest }, ref, ) { return (
{children}
); }); type PanelToolbarProps = { children: ReactNode; className?: string; }; type PanelBarProps = { children?: ReactNode; className?: string; borderClassName: "border-b" | "border-t"; }; function PanelBar({ children, className, borderClassName }: PanelBarProps) { return (
{children}
); } /** Fixed header toolbar strip. Doesn't scroll with content. */ export function PanelToolbar({ children, className }: PanelToolbarProps) { return {children}; } type PanelHeaderBarProps = { children?: ReactNode; className?: string; }; /** Fixed-height panel header bar. Renders children directly. */ export function PanelHeaderBar({ children, className }: PanelHeaderBarProps) { return ( {children} ); } type PanelHeaderBarSplitProps = { left?: ReactNode; right?: ReactNode; className?: string; }; /** Panel header bar with left/right slots separated by a spacer. */ export function PanelHeaderBarSplit({ left, right, className }: PanelHeaderBarSplitProps) { return (
{left}
{right}
); } /** Fixed-height panel footer bar with border-t. Mirrors PanelHeaderBar but anchors to the bottom. */ export function PanelFooterBar({ children, className }: PanelHeaderBarProps) { return ( {children} ); }