import { memo } from "react";
import { useStyletron } from "baseui";
import { LabelXSmall } from "baseui/typography";
import { FileCode, Plus, X } from "lucide-react";
import { ContextMenuOverlay, TabAvatar, useContextMenu } from "./ui";
import { diffTabId, fileName, type Handoff } from "./view-model";
export const TabStrip = memo(function TabStrip({
handoff,
activeTabId,
openDiffs,
editingSessionTabId,
editingSessionName,
onEditingSessionNameChange,
onSwitchTab,
onStartRenamingTab,
onCommitSessionRename,
onCancelSessionRename,
onSetTabUnread,
onCloseTab,
onCloseDiffTab,
onAddTab,
}: {
handoff: Handoff;
activeTabId: string | null;
openDiffs: string[];
editingSessionTabId: string | null;
editingSessionName: string;
onEditingSessionNameChange: (value: string) => void;
onSwitchTab: (tabId: string) => void;
onStartRenamingTab: (tabId: string) => void;
onCommitSessionRename: () => void;
onCancelSessionRename: () => void;
onSetTabUnread: (tabId: string, unread: boolean) => void;
onCloseTab: (tabId: string) => void;
onCloseDiffTab: (path: string) => void;
onAddTab: () => void;
}) {
const [css, theme] = useStyletron();
const contextMenu = useContextMenu();
return (
<>
{handoff.tabs.map((tab) => {
const isActive = tab.id === activeTabId;
return (
onSwitchTab(tab.id)}
onDoubleClick={() => onStartRenamingTab(tab.id)}
onMouseDown={(event) => {
if (event.button === 1 && handoff.tabs.length > 1) {
event.preventDefault();
onCloseTab(tab.id);
}
}}
onContextMenu={(event) =>
contextMenu.open(event, [
{ label: "Rename session", onClick: () => onStartRenamingTab(tab.id) },
{
label: tab.unread ? "Mark as read" : "Mark as unread",
onClick: () => onSetTabUnread(tab.id, !tab.unread),
},
...(handoff.tabs.length > 1 ? [{ label: "Close tab", onClick: () => onCloseTab(tab.id) }] : []),
])
}
data-tab
className={css({
display: "flex",
alignItems: "center",
gap: "6px",
padding: "4px 12px",
marginTop: "6px",
marginBottom: "6px",
borderRadius: "8px",
backgroundColor: isActive ? "rgba(255, 255, 255, 0.06)" : "transparent",
cursor: "pointer",
transition: "color 200ms ease, background-color 200ms ease",
flexShrink: 0,
":hover": { color: "#e4e4e7", backgroundColor: isActive ? "rgba(255, 255, 255, 0.06)" : "rgba(255, 255, 255, 0.04)" },
})}
>
{editingSessionTabId === tab.id ? (
onEditingSessionNameChange(event.target.value)}
onBlur={onCommitSessionRename}
onClick={(event) => event.stopPropagation()}
onDoubleClick={(event) => event.stopPropagation()}
onKeyDown={(event) => {
if (event.key === "Enter") {
onCommitSessionRename();
} else if (event.key === "Escape") {
onCancelSessionRename();
}
}}
className={css({
appearance: "none",
WebkitAppearance: "none",
background: "none",
border: "none",
padding: "0",
margin: "0",
outline: "none",
minWidth: "72px",
maxWidth: "180px",
fontSize: "11px",
fontWeight: 600,
color: theme.colors.contentPrimary,
borderBottom: "1px solid rgba(255, 255, 255, 0.3)",
})}
/>
) : (
{tab.sessionName}
)}
{handoff.tabs.length > 1 ? (
{
event.stopPropagation();
onCloseTab(tab.id);
}}
/>
) : null}
);
})}
{openDiffs.map((path) => {
const tabId = diffTabId(path);
const isActive = tabId === activeTabId;
return (
onSwitchTab(tabId)}
onMouseDown={(event) => {
if (event.button === 1) {
event.preventDefault();
onCloseDiffTab(path);
}
}}
data-tab
className={css({
display: "flex",
alignItems: "center",
gap: "6px",
padding: "4px 12px",
marginTop: "6px",
marginBottom: "6px",
borderRadius: "8px",
backgroundColor: isActive ? "rgba(255, 255, 255, 0.06)" : "transparent",
cursor: "pointer",
transition: "color 200ms ease, background-color 200ms ease",
flexShrink: 0,
":hover": { color: "#e4e4e7", backgroundColor: isActive ? "rgba(255, 255, 255, 0.06)" : "rgba(255, 255, 255, 0.04)" },
})}
>
{fileName(path)}
{
event.stopPropagation();
onCloseDiffTab(path);
}}
/>
);
})}
{contextMenu.menu ?