All files / client/src/components/ui panel-header.tsx

100% Statements 1/1
100% Branches 2/2
100% Functions 1/1
100% Lines 1/1

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49                                              57x                                                  
import type { ReactNode } from "react";
import { cn } from "@/lib/utils";
 
interface PanelHeaderProps {
  readonly title: ReactNode;
  readonly icon?: ReactNode;
  readonly leadingContent?: ReactNode;
  readonly centerAction?: ReactNode;
  readonly actions?: ReactNode;
  readonly className?: string;
  readonly testId?: string;
}
 
/** Shared visual contract for compact panel headers in the workspace. */
export function PanelHeader({
  title,
  icon,
  leadingContent,
  centerAction,
  actions,
  className,
  testId,
}: PanelHeaderProps) {
  return (
    <div
      className={cn(
        "relative flex h-[var(--ui-header-height)] shrink-0 items-center gap-2 border-b border-border bg-muted px-[var(--header-padding-x)]",
        className,
      )}
      data-testid={testId}
    >
      <div className="flex min-w-0 flex-1 items-center gap-2">
        <span className="flex shrink-0 items-center [&_svg]:!h-5 [&_svg]:!w-5">
          {icon}
        </span>
        <span
          className="font-semibold uppercase tracking-wide text-muted-foreground"
          style={{ fontSize: "var(--fs-body-xs)" }}
        >
          {title}
        </span>
        {leadingContent}
      </div>
      {centerAction}
      {actions && <div className="ml-auto flex items-center gap-2">{actions}</div>}
    </div>
  );
}