Zaidan

Command Palette

Search for a command to run...

GitHub43

Tabs

A set of layered sections of content—known as tab panels—that are displayed one at a time.

Installation

CLI

Manual

Copy and paste the following code into your project.

import type { PolymorphicProps } from "@kobalte/core";
import {
Content,
List,
Root,
type TabsContentProps as TabsContentPrimitiveProps,
type TabsListProps as TabsListPrimitiveProps,
type TabsRootProps,
type TabsTriggerProps as TabsTriggerPrimitiveProps,
Trigger,
} from "@kobalte/core/tabs";
import { cva, type VariantProps } from "class-variance-authority";
import { type ComponentProps, mergeProps, splitProps, type ValidComponent } from "solid-js";
import { cn } from "~/lib/utils";
type TabsProps<T extends ValidComponent = "div"> = PolymorphicProps<T, TabsRootProps<T>> &
Pick<ComponentProps<T>, "class" | "children">;
const Tabs = <T extends ValidComponent = "div">(props: TabsProps<T>) => {
const mergedProps = mergeProps({ orientation: "horizontal" }, props);
const [local, others] = splitProps(mergedProps, ["class", "orientation"]);
return (
<Root
data-slot="tabs"
data-orientation={local.orientation}
orientation={local.orientation}
class={cn("group/tabs z-tabs flex data-[orientation=horizontal]:flex-col", local.class)}
{...others}
/>
);
};
const tabsListVariants = cva(
"group/tabs-list z-tabs-list inline-flex w-fit items-center justify-center text-muted-foreground group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col",
{
variants: {
variant: {
default: "z-tabs-list-variant-default bg-muted",
line: "z-tabs-list-variant-line gap-1 bg-transparent",
},
},
defaultVariants: {
variant: "default",
},
},
);
type TabsListProps<T extends ValidComponent = "div"> = PolymorphicProps<
T,
TabsListPrimitiveProps<T>
> &
VariantProps<typeof tabsListVariants> &
Pick<ComponentProps<T>, "class" | "children">;
const TabsList = <T extends ValidComponent = "div">(props: TabsListProps<T>) => {
const [local, others] = splitProps(props as TabsListProps, ["variant", "class"]);
return (
<List
class={cn(tabsListVariants({ variant: local.variant }), local.class)}
data-slot="tabs-list"
data-variant={local.variant}
{...others}
/>
);
};
type TabTriggerProps<T extends ValidComponent = "button"> = PolymorphicProps<
T,
TabsTriggerPrimitiveProps<T>
> &
Pick<ComponentProps<T>, "class" | "children">;
const TabsTrigger = <T extends ValidComponent = "button">(props: TabTriggerProps<T>) => {
const [local, others] = splitProps(props as TabTriggerProps, ["class"]);
return (
<Trigger
data-slot="tabs-trigger"
class={cn(
"relative z-tabs-trigger inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center whitespace-nowrap text-foreground/60 transition-all hover:text-foreground focus-visible:border-ring focus-visible:outline-1 focus-visible:outline-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start dark:text-muted-foreground dark:hover:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0",
"group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-selected:bg-transparent dark:group-data-[variant=line]/tabs-list:data-selected:border-transparent dark:group-data-[variant=line]/tabs-list:data-selected:bg-transparent",
"data-selected:bg-background data-selected:text-foreground dark:data-selected:border-input dark:data-selected:bg-input/30 dark:data-selected:text-foreground",
"after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=horizontal]/tabs:after:bottom-[-5px] group-data-[orientation=horizontal]/tabs:after:h-0.5 group-data-[orientation=vertical]/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-selected:after:opacity-100",
local.class,
)}
{...others}
/>
);
};
type TabsContentProps<T extends ValidComponent = "div"> = PolymorphicProps<
T,
TabsContentPrimitiveProps<T>
> &
Pick<ComponentProps<T>, "class" | "children">;
const TabsContent = <T extends ValidComponent = "div">(props: TabsContentProps<T>) => {
const [local, others] = splitProps(props as TabsContentProps, ["class"]);
return (
<Content
data-slot="tabs-content"
class={cn("z-tabs-content flex-1 outline-none", local.class)}
{...others}
/>
);
};
export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants };

Examples

Here are the source code of all the examples from the preview page:

Basic

import { Tabs, TabsList, TabsTrigger } from "~/components/ui/tabs";
function TabsBasic() {
return (
<Example title="Basic">
<Tabs defaultValue="home">
<TabsList>
<TabsTrigger value="home">Home</TabsTrigger>
<TabsTrigger value="settings">Settings</TabsTrigger>
</TabsList>
</Tabs>
</Example>
);
}

Line

import { Tabs, TabsList, TabsTrigger } from "~/components/ui/tabs";
function TabsLine() {
return (
<Example title="Line">
<Tabs defaultValue="overview">
<TabsList variant="line">
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="analytics">Analytics</TabsTrigger>
<TabsTrigger value="reports">Reports</TabsTrigger>
</TabsList>
</Tabs>
</Example>
);
}

Variants Alignment

import { Tabs, TabsList, TabsTrigger } from "~/components/ui/tabs";
function TabsVariantsComparison() {
return (
<Example title="Variants Alignment">
<div class="flex gap-4">
<Tabs defaultValue="overview">
<TabsList>
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="analytics">Analytics</TabsTrigger>
</TabsList>
</Tabs>
<Tabs defaultValue="overview">
<TabsList variant="line">
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="analytics">Analytics</TabsTrigger>
</TabsList>
</Tabs>
</div>
</Example>
);
}

Disabled

import { Tabs, TabsList, TabsTrigger } from "~/components/ui/tabs";
function TabsDisabled() {
return (
<Example title="Disabled">
<Tabs defaultValue="home">
<TabsList>
<TabsTrigger value="home">Home</TabsTrigger>
<TabsTrigger value="settings" disabled>
Disabled
</TabsTrigger>
</TabsList>
</Tabs>
</Example>
);
}

With Icons

import { AppWindow, Code } from "lucide-solid";
import { Tabs, TabsList, TabsTrigger } from "~/components/ui/tabs";
function TabsWithIcons() {
return (
<Example title="With Icons">
<Tabs defaultValue="preview">
<TabsList>
<TabsTrigger value="preview">
<AppWindow />
Preview
</TabsTrigger>
<TabsTrigger value="code">
<Code />
Code
</TabsTrigger>
</TabsList>
</Tabs>
</Example>
);
}

Icon Only

import { Home, Search, Settings } from "lucide-solid";
import { Tabs, TabsList, TabsTrigger } from "~/components/ui/tabs";
function TabsIconOnly() {
return (
<Example title="Icon Only">
<Tabs defaultValue="home">
<TabsList>
<TabsTrigger value="home">
<Home />
</TabsTrigger>
<TabsTrigger value="search">
<Search />
</TabsTrigger>
<TabsTrigger value="settings">
<Settings />
</TabsTrigger>
</TabsList>
</Tabs>
</Example>
);
}

Multiple

import { Tabs, TabsList, TabsTrigger } from "~/components/ui/tabs";
function TabsMultiple() {
return (
<Example title="Multiple">
<Tabs defaultValue="overview">
<TabsList>
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="analytics">Analytics</TabsTrigger>
<TabsTrigger value="reports">Reports</TabsTrigger>
<TabsTrigger value="settings">Settings</TabsTrigger>
</TabsList>
</Tabs>
</Example>
);
}

With Content

import { Tabs, TabsContent, TabsList, TabsTrigger } from "~/components/ui/tabs";
function TabsWithContent() {
return (
<Example title="With Content">
<Tabs defaultValue="account">
<TabsList>
<TabsTrigger value="account">Account</TabsTrigger>
<TabsTrigger value="password">Password</TabsTrigger>
<TabsTrigger value="notifications">Notifications</TabsTrigger>
</TabsList>
<div class="rounded-lg border p-4">
<TabsContent value="account">
Manage your account preferences and profile information.
</TabsContent>
<TabsContent value="password">
Update your password to keep your account secure.
</TabsContent>
<TabsContent value="notifications">
Configure how you receive notifications and alerts.
</TabsContent>
</div>
</Tabs>
</Example>
);
}

Line With Content

import { Tabs, TabsContent, TabsList, TabsTrigger } from "~/components/ui/tabs";
function TabsLineWithContent() {
return (
<Example title="Line With Content">
<Tabs defaultValue="account">
<TabsList variant="line">
<TabsTrigger value="account">Account</TabsTrigger>
<TabsTrigger value="password">Password</TabsTrigger>
<TabsTrigger value="notifications">Notifications</TabsTrigger>
</TabsList>
<div class="rounded-lg border p-4">
<TabsContent value="account">
Manage your account preferences and profile information.
</TabsContent>
<TabsContent value="password">
Update your password to keep your account secure.
</TabsContent>
<TabsContent value="notifications">
Configure how you receive notifications and alerts.
</TabsContent>
</div>
</Tabs>
</Example>
);
}

Line Disabled

import { Tabs, TabsList, TabsTrigger } from "~/components/ui/tabs";
function TabsLineDisabled() {
return (
<Example title="Line Disabled">
<Tabs defaultValue="overview">
<TabsList variant="line">
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="analytics">Analytics</TabsTrigger>
<TabsTrigger value="reports" disabled>
Reports
</TabsTrigger>
</TabsList>
</Tabs>
</Example>
);
}

With Dropdown

import { MoreHorizontal } from "lucide-solid";
import { Button } from "~/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "~/components/ui/tabs";
function TabsWithDropdown() {
return (
<Example title="With Dropdown">
<Tabs defaultValue="overview">
<div class="flex items-center justify-between">
<TabsList>
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="analytics">Analytics</TabsTrigger>
<TabsTrigger value="reports">Reports</TabsTrigger>
</TabsList>
<DropdownMenu placement="bottom-end">
<DropdownMenuTrigger as={Button} variant="ghost" size="icon" class="size-8">
<MoreHorizontal />
<span class="sr-only">More options</span>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>Settings</DropdownMenuItem>
<DropdownMenuItem>Export</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>Archive</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
<div class="rounded-lg border p-4">
<TabsContent value="overview">
View your dashboard metrics and key performance indicators.
</TabsContent>
<TabsContent value="analytics">
Detailed analytics and insights about your data.
</TabsContent>
<TabsContent value="reports">Generate and view custom reports.</TabsContent>
</div>
</Tabs>
</Example>
);
}

Vertical

import { Tabs, TabsContent, TabsList, TabsTrigger } from "~/components/ui/tabs";
function TabsVertical() {
return (
<Example title="Vertical">
<Tabs defaultValue="account" orientation="vertical">
<TabsList>
<TabsTrigger value="account">Account</TabsTrigger>
<TabsTrigger value="password">Password</TabsTrigger>
<TabsTrigger value="notifications">Notifications</TabsTrigger>
</TabsList>
<div class="rounded-lg border p-4">
<TabsContent value="account">
Manage your account preferences and profile information.
</TabsContent>
<TabsContent value="password">
Update your password to keep your account secure. Use a strong password with a mix of
letters, numbers, and symbols.
</TabsContent>
<TabsContent value="notifications">
Configure how you receive notifications and alerts. Choose which types of notifications
you want to receive and how you want to receive them.
</TabsContent>
</div>
</Tabs>
</Example>
);
}

With Input and Button

import { Button } from "~/components/ui/button";
import { Input } from "~/components/ui/input";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "~/components/ui/tabs";
function TabsWithInputAndButton() {
return (
<Example title="With Input and Button" containerClass="col-span-full">
<Tabs defaultValue="overview" class="mx-auto w-full max-w-lg">
<div class="flex items-center gap-4">
<TabsList>
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="analytics">Analytics</TabsTrigger>
</TabsList>
<div class="ml-auto flex items-center gap-2">
<Input placeholder="Search..." class="w-44" />
<Button>Action</Button>
</div>
</div>
<div class="rounded-lg border p-4">
<TabsContent value="overview">
View your dashboard metrics and key performance indicators.
</TabsContent>
<TabsContent value="analytics">
Detailed analytics and insights about your data.
</TabsContent>
<TabsContent value="reports">Generate and view custom reports.</TabsContent>
</div>
</Tabs>
</Example>
);
}