import { cn } from "~/lib/utils"; import React, { useEffect, useMemo, useRef } from "react"; import ActionButton from "./action-button"; import { FiX } from "react-icons/fi"; import FileIcon from "./file-icon"; export type Tab = { title: string; icon?: React.ReactNode; render?: () => React.ReactNode; locked?: boolean; }; type Props = { tabs: Tab[]; current?: number; onChange?: (idx: number) => void; onClose?: (idx: number) => void; }; const Tabs = ({ tabs, current = 0, onChange, onClose }: Props) => { const tabContainerRef = useRef(null); const onWheel = (e: WheelEvent) => { e.cancelable && e.preventDefault(); if (tabContainerRef.current) { tabContainerRef.current.scrollLeft += e.deltaY + e.deltaX; } }; useEffect(() => { if (!tabs.length || !tabContainerRef.current) { return; } const container = tabContainerRef.current; container.addEventListener("wheel", onWheel); return () => { container.removeEventListener("wheel", onWheel); }; }, [tabs]); useEffect(() => { if (!tabs.length) { return; } const container = tabContainerRef.current; const tabEl: any = container?.querySelector(`[data-idx="${current}"]`); if (!container || !tabEl) { return; } const containerRect = container.getBoundingClientRect(); const scrollX = tabEl.offsetLeft - containerRect.left; container.scrollTo({ left: scrollX, behavior: "smooth" }); }, [tabs, current]); const tabView = useMemo(() => { const tab = tabs[current]; const element = tab?.render ? tab.render() : null; return element; }, [tabs, current]); return (
{tabs.length > 0 ? ( ) : null}
{tabView}
); }; type TabItemProps = { index: number; title: string; icon?: React.ReactNode; isActive?: boolean; onSelect: () => void; onClose?: (() => void) | null; }; const TabItem = ({ index, title, icon, isActive, onSelect, onClose, }: TabItemProps) => { const lastDotFile = title.lastIndexOf("."); const ext = title.substring(lastDotFile); const filename = title.substring(0, lastDotFile); return (
{onClose ? ( onClose()} /> ) : null}
); }; export default Tabs;