frontend_nyla/src/components/UiComponents/Tabs/Tabs.tsx

59 lines
1.5 KiB
TypeScript

import React, { useState } from 'react';
import styles from './Tabs.module.css';
export interface Tab {
id: string;
label: string;
content: React.ReactNode;
}
export interface TabsProps {
tabs: Tab[];
defaultTabId?: string;
/** Controlled active tab. When provided, internal state is ignored. */
activeTabId?: string;
onTabChange?: (tabId: string) => void;
className?: string;
}
export function Tabs({ tabs, defaultTabId, activeTabId: controlledTabId, onTabChange, className = '' }: TabsProps) {
const [internalTabId, setInternalTabId] = useState<string>(
defaultTabId || tabs[0]?.id || ''
);
const activeTabId = controlledTabId ?? internalTabId;
const handleTabClick = (tabId: string) => {
if (!controlledTabId) setInternalTabId(tabId);
onTabChange?.(tabId);
};
const activeTab = tabs.find(tab => tab.id === activeTabId) || tabs[0];
if (!tabs || tabs.length === 0) {
return null;
}
return (
<div className={`${styles.tabsContainer} ${className}`}>
<div className={styles.tabsHeader}>
{tabs.map(tab => (
<button
key={tab.id}
className={`${styles.tabButton} ${activeTabId === tab.id ? styles.tabButtonActive : ''}`}
onClick={() => handleTabClick(tab.id)}
type="button"
>
{tab.label}
</button>
))}
</div>
<div className={styles.tabsContent}>
{activeTab && activeTab.content}
</div>
</div>
);
}
export default Tabs;