Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | 2x 2x 6x 6x 6x 1x 1x 6x 6x 6x 6x 6x 6x 6x 5x 5x 5x 5x 5x 5x 5x 5x 16x 16x 16x 2x 2x 13x 13x 13x 13x 13x 13x 13x 4x 9x 16x 16x 16x 16x 16x 16x 16x 16x 2x 2x 13x 16x 4x 4x 2x 1x | import * as React from 'react';
import { cn } from '../lib/utils';
type TabsProps = {
className?: string;
children: React.ReactNode;
defaultValue?: string;
};
function Tabs({ className, children, defaultValue }: TabsProps) {
const [activeTab, setActiveTab] = React.useState(defaultValue);
const handleTabChange = (value: string) => {
setActiveTab(value);
};
const contextValue = React.useMemo(
() => ({ activeTab, onChange: handleTabChange }),
[activeTab]
);
return (
<TabsContext.Provider value={contextValue}>
<div className={cn('flex flex-col gap-2', className)}>{children}</div>
</TabsContext.Provider>
);
}
type TabsListProps = {
className?: string;
children: React.ReactNode;
};
function TabsList({ className, children }: TabsListProps) {
return (
<div
className={cn(
'bg-muted inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]',
className
)}
>
{children}
</div>
);
}
type TabsTriggerProps = {
className?: string;
value: string;
children: React.ReactNode;
};
function TabsTrigger({ className, value, children }: TabsTriggerProps) {
const context = React.useContext(TabsContext);
if (!context) {
throw new Error('TabsTrigger must be used within a Tabs component');
}
const { activeTab, onChange } = context;
const isActive = activeTab === value;
return (
<button
className={cn(
'inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md px-2 py-1 text-sm font-medium transition-[color,box-shadow]',
isActive
? 'bg-background text-foreground shadow-sm'
: 'text-muted-foreground',
'focus-visible:ring-[3px] focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50',
className
)}
onClick={() => onChange(value)}
>
{children}
</button>
);
}
type TabsContentProps = {
className?: string;
value: string;
children: React.ReactNode;
};
function TabsContent({ className, value, children }: TabsContentProps) {
const context = React.useContext(TabsContext);
if (!context) {
throw new Error('TabsContent must be used within a Tabs component');
}
const { activeTab } = context;
if (activeTab !== value) return null;
return <div className={cn('flex-1 outline-none', className)}>{children}</div>;
}
type TabsContextType = {
activeTab: string | undefined;
onChange: (value: string) => void;
};
const TabsContext = React.createContext<TabsContextType | undefined>(undefined);
export { Tabs, TabsList, TabsTrigger, TabsContent };
|