forked from baron/baron-sso
88 lines
2.6 KiB
TypeScript
88 lines
2.6 KiB
TypeScript
import * as React from "react";
|
|
import { cn } from "../../lib/utils";
|
|
|
|
const TabsContext = React.createContext<{
|
|
value?: string;
|
|
onValueChange?: (value: string) => void;
|
|
}>({});
|
|
|
|
const Tabs = React.forwardRef<
|
|
HTMLDivElement,
|
|
React.HTMLAttributes<HTMLDivElement> & {
|
|
value?: string;
|
|
onValueChange?: (value: string) => void;
|
|
}
|
|
>(({ className, value, onValueChange, ...props }, ref) => {
|
|
return (
|
|
<TabsContext.Provider value={{ value, onValueChange }}>
|
|
<div ref={ref} className={cn("w-full", className)} {...props} />
|
|
</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 { value: activeValue, onValueChange } = React.useContext(TabsContext);
|
|
const isSelected = activeValue === value;
|
|
|
|
return (
|
|
<button
|
|
ref={ref}
|
|
type="button"
|
|
role="tab"
|
|
aria-selected={isSelected}
|
|
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 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
|
|
className,
|
|
)}
|
|
data-state={isSelected ? "active" : "inactive"}
|
|
onClick={() => onValueChange?.(value)}
|
|
{...props}
|
|
/>
|
|
);
|
|
});
|
|
TabsTrigger.displayName = "TabsTrigger";
|
|
|
|
const TabsContent = React.forwardRef<
|
|
HTMLDivElement,
|
|
React.HTMLAttributes<HTMLDivElement> & { value: string }
|
|
>(({ className, value, ...props }, ref) => {
|
|
const { value: activeValue } = React.useContext(TabsContext);
|
|
const isSelected = activeValue === value;
|
|
|
|
if (!isSelected) return null;
|
|
|
|
return (
|
|
<div
|
|
ref={ref}
|
|
role="tabpanel"
|
|
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}
|
|
/>
|
|
);
|
|
});
|
|
TabsContent.displayName = "TabsContent";
|
|
|
|
export { Tabs, TabsContent, TabsList, TabsTrigger };
|