'use client';
import * as React from 'react';
import { cn } from '@/lib/utils';
const TabsContext = React.createContext<{
value: string;
onValueChange: (value: string) => void;
}>({
value: '',
onValueChange: () => {},
});
interface TabsProps {
defaultValue?: string;
value?: string;
onValueChange?: (value: string) => void;
className?: string;
children: React.ReactNode;
}
const Tabs = React.forwardRef<HTMLDivElement, TabsProps>(
({ defaultValue, value: controlledValue, onValueChange, className, children }, ref) => {
const [uncontrolledValue, setUncontrolledValue] = React.useState(defaultValue || '');
const value = controlledValue ?? uncontrolledValue;
const setValue = onValueChange ?? setUncontrolledValue;
return (
<TabsContext.Provider value={{ value, onValueChange: setValue }}>
<div ref={ref} className={cn('', className)}>
{children}
</div>
</TabsContext.Provider>
);
}
);
Tabs.displayName = 'Tabs';
const TabsList = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
'inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground',
className
)}
{...props}
/>
));
TabsList.displayName = 'TabsList';
const TabsTrigger = React.forwardRef<
HTMLButtonElement,
React.ButtonHTMLAttributes<HTMLButtonElement> & { value: string }
>(({ className, value, ...props }, ref) => {
const context = React.useContext(TabsContext);
return (
<button
ref={ref}
type="button"
className={cn(
'inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5',
'text-sm font-medium ring-offset-background transition-all',
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
'disabled:pointer-events-none disabled:opacity-50',
context.value === value
? 'bg-background text-foreground shadow-sm'
: 'hover:bg-background/50',
className
)}
onClick={() => context.onValueChange(value)}
{...props}
/>
);
});
TabsTrigger.displayName = 'TabsTrigger';
const TabsContent = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement> & { value: string }
>(({ className, value, children, ...props }, ref) => {
const context = React.useContext(TabsContext);
if (context.value !== value) {
return null;
}
return (
<div
ref={ref}
className={cn(
'mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
className
)}
{...props}
>
{children}
</div>
);
});
TabsContent.displayName = 'TabsContent';
export { Tabs, TabsList, TabsTrigger, TabsContent };