Files
aggios.app/front-end-dash.aggios.app/components/ui/Tabs.tsx
2025-12-17 13:36:23 -03:00

103 lines
4.2 KiB
TypeScript

'use client';
import { Tab } from '@headlessui/react';
import { ReactNode } from 'react';
function classNames(...classes: string[]) {
return classes.filter(Boolean).join(' ');
}
export interface TabItem {
name: string;
icon?: React.ComponentType<{ className?: string }>;
content: ReactNode;
}
interface TabsProps {
tabs: TabItem[];
defaultIndex?: number;
onChange?: (index: number) => void;
variant?: 'card' | 'modal'; // Novo: variante para diferentes contextos
}
export default function Tabs({ tabs, defaultIndex = 0, onChange, variant = 'card' }: TabsProps) {
if (variant === 'modal') {
// Versão para modais - sem card wrapper
return (
<Tab.Group defaultIndex={defaultIndex} onChange={onChange}>
<Tab.List className="flex border-b border-zinc-200 dark:border-zinc-700 px-6">
{tabs.map((tab) => (
<Tab
key={tab.name}
className={({ selected }) =>
classNames(
'px-4 py-3 text-sm font-medium border-b-2 transition-colors focus:outline-none whitespace-nowrap',
selected
? 'border-[var(--brand-color)] text-[var(--brand-color)]'
: 'border-transparent text-zinc-500 hover:text-zinc-700 dark:hover:text-zinc-300'
)
}
>
<div className="flex items-center justify-center gap-2">
{tab.icon && <tab.icon className="w-4 h-4 flex-shrink-0" />}
{tab.name}
</div>
</Tab>
))}
</Tab.List>
<Tab.Panels className="p-6">
{tabs.map((tab, idx) => (
<Tab.Panel
key={idx}
className="focus:outline-none"
>
{tab.content}
</Tab.Panel>
))}
</Tab.Panels>
</Tab.Group>
);
}
// Versão padrão para páginas - com card wrapper
return (
<Tab.Group defaultIndex={defaultIndex} onChange={onChange}>
<div className="bg-white dark:bg-zinc-900 rounded-xl border border-zinc-200 dark:border-zinc-800 overflow-hidden">
<Tab.List className="flex space-x-1 rounded-t-xl bg-zinc-100 dark:bg-zinc-800/50 p-1 overflow-x-auto scrollbar-hide">
{tabs.map((tab) => (
<Tab
key={tab.name}
className={({ selected }) =>
classNames(
'w-full rounded-lg py-2 sm:py-2.5 px-3 sm:px-4 text-xs sm:text-sm font-medium leading-5 transition-all duration-200 whitespace-nowrap',
'focus:outline-none',
selected
? 'bg-white dark:bg-zinc-800 text-zinc-900 dark:text-white shadow'
: 'text-zinc-500 hover:bg-white/[0.12] hover:text-zinc-700 dark:hover:text-zinc-300'
)
}
>
<div className="flex items-center justify-center gap-1.5 sm:gap-2">
{tab.icon && <tab.icon className="w-3.5 h-3.5 sm:w-4 sm:h-4 flex-shrink-0" />}
{tab.name}
</div>
</Tab>
))}
</Tab.List>
<Tab.Panels className="p-4 sm:p-6">
{tabs.map((tab, idx) => (
<Tab.Panel
key={idx}
className="focus:outline-none"
>
{tab.content}
</Tab.Panel>
))}
</Tab.Panels>
</div>
</Tab.Group>
);
}