bb-plane-fork/packages/propel/src/tabs/tabs.tsx
sriram veeraghanta 02d0ee3e0f
chore: add copyright (#8584)
* feat: adding new copyright info on all files

* chore: adding CI
2026-01-27 13:54:22 +05:30

148 lines
4.7 KiB
TypeScript

/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import * as React from "react";
import { Tabs as TabsPrimitive } from "@base-ui-components/react/tabs";
import { cn } from "../utils/classname";
type TabsVariant = "contained";
type TabsContextType = {
variant?: TabsVariant;
};
const TabsContext = React.createContext<TabsContextType | undefined>(undefined);
type TabsCompound = React.ForwardRefExoticComponent<
React.ComponentProps<typeof TabsPrimitive.Root> & {
variant?: TabsVariant;
} & React.RefAttributes<React.ElementRef<typeof TabsPrimitive.Root>>
> & {
List: React.ForwardRefExoticComponent<
React.ComponentProps<typeof TabsPrimitive.List> & {
background?: TabsVariant;
} & React.RefAttributes<React.ElementRef<typeof TabsPrimitive.List>>
>;
Trigger: React.ForwardRefExoticComponent<
React.ComponentProps<typeof TabsPrimitive.Tab> & {
size?: "sm" | "md" | "lg";
variant?: TabsVariant;
} & React.RefAttributes<React.ElementRef<typeof TabsPrimitive.Tab>>
>;
Content: React.ForwardRefExoticComponent<
React.ComponentProps<typeof TabsPrimitive.Panel> & React.RefAttributes<React.ElementRef<typeof TabsPrimitive.Panel>>
>;
Indicator: React.ForwardRefExoticComponent<React.ComponentProps<"div"> & React.RefAttributes<HTMLDivElement>>;
};
const TabsRoot = React.forwardRef(function TabsRoot(
{ className, variant, ...props }: React.ComponentProps<typeof TabsPrimitive.Root> & { variant?: TabsVariant },
ref: React.ForwardedRef<React.ElementRef<typeof TabsPrimitive.Root>>
) {
return (
<TabsContext.Provider value={{ variant }}>
<TabsPrimitive.Root
data-slot="tabs"
className={cn("flex flex-col w-full h-full", className)}
{...props}
ref={ref}
/>
</TabsContext.Provider>
);
});
const TabsList = React.forwardRef(function TabsList(
{
className,
background = "contained",
...props
}: React.ComponentProps<typeof TabsPrimitive.List> & {
background?: TabsVariant;
},
ref: React.ForwardedRef<React.ElementRef<typeof TabsPrimitive.List>>
) {
return (
<TabsPrimitive.List
data-slot="tabs-list"
className={cn(
"flex w-full items-center justify-between gap-1.5 rounded-lg text-13 p-0.5 relative overflow-auto",
{
"bg-layer-3": background === "contained",
},
className
)}
{...props}
ref={ref}
/>
);
});
const TabsTrigger = React.forwardRef(function TabsTrigger(
{
className,
size = "md",
...props
}: React.ComponentProps<typeof TabsPrimitive.Tab> & { size?: "sm" | "md" | "lg"; variant?: TabsVariant },
ref: React.ForwardedRef<React.ElementRef<typeof TabsPrimitive.Tab>>
) {
return (
<TabsPrimitive.Tab
data-slot="tabs-trigger"
className={cn(
"flex items-center justify-center p-1 min-w-fit w-full font-medium text-primary outline-none focus:outline-none cursor-pointer transition-all duration-200 ease-in-out rounded-md border border-transparent",
" data-[selected]:text-primary data-[selected]:shadow-sm data-[selected]:bg-layer-2 data-[selected]:border data-[selected]:border-subtle-1 data-[selected]:raised-200",
"text-placeholder hover:text-tertiary hover:bg-layer-transparent-hover",
"disabled:text-placeholder disabled:cursor-not-allowed",
{
"text-11": size === "sm",
"text-13": size === "md",
"text-14": size === "lg",
},
className
)}
{...props}
ref={ref}
/>
);
});
const TabsContent = React.forwardRef(function TabsContent(
{ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Panel>,
ref: React.ForwardedRef<React.ElementRef<typeof TabsPrimitive.Panel>>
) {
return (
<TabsPrimitive.Panel
data-slot="tabs-content"
className={cn("relative outline-none", className)}
{...props}
ref={ref}
/>
);
});
const TabsIndicator = React.forwardRef(function TabsIndicator(
{ className, ...props }: React.ComponentProps<"div">,
ref: React.ForwardedRef<HTMLDivElement>
) {
return (
<div
className={cn(
"absolute left-0 top-[50%] z-[-1] h-6 w-[var(--active-tab-width)] translate-x-[var(--active-tab-left)] -translate-y-[50%] rounded-xs bg-surface-1 shadow-sm transition-[width,transform] duration-200 ease-in-out",
className
)}
{...props}
ref={ref}
/>
);
});
export const Tabs = Object.assign(TabsRoot, {
List: TabsList,
Trigger: TabsTrigger,
Content: TabsContent,
Indicator: TabsIndicator,
}) satisfies TabsCompound;
export { TabsList, TabsTrigger, TabsContent, TabsIndicator };