import { X } from 'lucide-react';
import {
DndContext,
PointerSensor,
useSensor,
useSensors,
closestCenter,
type DragEndEvent,
} from '@dnd-kit/core';
import {
SortableContext,
horizontalListSortingStrategy,
useSortable,
} from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { useFileStore, type OpenTab } from '@/stores/file-store';
import { cn } from '@/lib/utils';
function SortableTab({
tab,
isActive,
onSelect,
onClose,
}: {
tab: OpenTab;
isActive: boolean;
onSelect: (id: string) => void;
onClose: (id: string) => void;
}) {
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
id: tab.id,
});
const style = {
transform: CSS.Transform.toString(transform),
transition,
opacity: isDragging ? 0.5 : 1,
};
return (
onSelect(tab.id)}
>
{tab.dirty && (
)}
{tab.title}
);
}
export function TabBar() {
const openTabs = useFileStore((s) => s.openTabs);
const activeTabId = useFileStore((s) => s.activeTabId);
const setActiveTab = useFileStore((s) => s.setActiveTab);
const closeTab = useFileStore((s) => s.closeTab);
const reorderTabs = useFileStore((s) => s.reorderTabs);
// Require a small drag distance before activating — so a click on the tab
// body still triggers `onClick` (dnd-kit's PointerSensor default is 0).
const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 6 } }));
if (openTabs.length === 0) {
return (
No files open
);
}
function handleDragEnd(e: DragEndEvent) {
const { active, over } = e;
if (!over || active.id === over.id) return;
const fromIndex = openTabs.findIndex((t) => t.id === active.id);
const toIndex = openTabs.findIndex((t) => t.id === over.id);
if (fromIndex === -1 || toIndex === -1) return;
reorderTabs(fromIndex, toIndex);
}
return (
t.id)} strategy={horizontalListSortingStrategy}>
{openTabs.map((tab) => (
))}
);
}