|
import * as React from "react" |
|
import { cn } from "../../lib/utils" |
|
|
|
const TabContext = React.createContext({ |
|
selectedTab: '', |
|
setSelectedTab: () => {} |
|
}) |
|
|
|
const Tabs = React.forwardRef(({ defaultValue, value, onValueChange, className, children, ...props }, ref) => { |
|
const [selectedTab, setSelectedTab] = React.useState(value || defaultValue); |
|
|
|
React.useEffect(() => { |
|
if (value !== undefined) { |
|
setSelectedTab(value); |
|
} |
|
}, [value]); |
|
|
|
const handleTabChange = (newValue) => { |
|
if (value === undefined) { |
|
setSelectedTab(newValue); |
|
} |
|
onValueChange?.(newValue); |
|
}; |
|
|
|
return ( |
|
<TabContext.Provider value={{ selectedTab, setSelectedTab: handleTabChange }}> |
|
<div ref={ref} className={cn("w-full", className)} {...props}> |
|
{children} |
|
</div> |
|
</TabContext.Provider> |
|
); |
|
}); |
|
Tabs.displayName = "Tabs" |
|
|
|
const TabsList = React.forwardRef(({ 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(({ className, value, children, ...props }, ref) => { |
|
const { selectedTab, setSelectedTab } = React.useContext(TabContext); |
|
const isSelected = selectedTab === value; |
|
|
|
return ( |
|
<button |
|
ref={ref} |
|
type="button" |
|
role="tab" |
|
aria-selected={isSelected} |
|
data-state={isSelected ? "active" : "inactive"} |
|
onClick={() => setSelectedTab(value)} |
|
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", |
|
isSelected && "bg-background text-foreground shadow-sm", |
|
className |
|
)} |
|
{...props} |
|
> |
|
{children} |
|
</button> |
|
); |
|
}); |
|
TabsTrigger.displayName = "TabsTrigger" |
|
|
|
const TabsContent = React.forwardRef(({ className, value, children, ...props }, ref) => { |
|
const { selectedTab } = React.useContext(TabContext); |
|
const isSelected = selectedTab === value; |
|
|
|
if (!isSelected) return null; |
|
|
|
return ( |
|
<div |
|
ref={ref} |
|
role="tabpanel" |
|
data-state={isSelected ? "active" : "inactive"} |
|
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 } |