chore(release): snapshot 1.4.2
This commit is contained in:
102
front-end-dash.aggios.app/components/ui/Tabs.tsx
Normal file
102
front-end-dash.aggios.app/components/ui/Tabs.tsx
Normal file
@@ -0,0 +1,102 @@
|
||||
'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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user