37 lines
1.1 KiB
TypeScript
37 lines
1.1 KiB
TypeScript
import { X } from 'lucide-react';
|
||
|
||
interface PanelHeaderProps {
|
||
title: string;
|
||
onClose?: () => void;
|
||
className?: string;
|
||
/**
|
||
* Title styling intent:
|
||
* - `'panel'` (default) — text-xs uppercase muted (Inspector, LyricsOverlay)
|
||
* - `'heading'` — text-sm semibold text-text (NowPlayingPanel)
|
||
*/
|
||
intent?: 'panel' | 'heading';
|
||
}
|
||
|
||
const TITLE_CLASSES = {
|
||
panel: 'text-xs font-semibold uppercase tracking-wider text-muted',
|
||
heading: 'text-sm font-semibold text-text',
|
||
};
|
||
|
||
/**
|
||
* Overlay/panel header bar — title label with an optional close button.
|
||
* Standardizes the pattern that was hand-rolled in Inspector (×2),
|
||
* NowPlayingPanel, LyricsOverlay, CommandPalette, and more.
|
||
*/
|
||
export function PanelHeader({ title, onClose, className = '', intent = 'panel' }: PanelHeaderProps) {
|
||
return (
|
||
<div className={`flex items-center justify-between px-4 py-2.5 border-b border-border ${className}`}>
|
||
<span className={TITLE_CLASSES[intent]}>{title}</span>
|
||
{onClose && (
|
||
<button onClick={onClose} className="text-muted hover:text-text p-0.5 rounded">
|
||
<X size={14} />
|
||
</button>
|
||
)}
|
||
</div>
|
||
);
|
||
}
|