Tabs
Tab navigation with filled and line variants, sizes, vertical layout, icons, disabled state, and RTL support.
Manage your account settings and preferences.
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
export function MyScreen() {
return (
<Tabs defaultValue="account">
<TabsList>
<TabsTrigger value="account">Account</TabsTrigger>
<TabsTrigger value="password">Password</TabsTrigger>
</TabsList>
<TabsContent value="account">
<Text>Account settings here.</Text>
</TabsContent>
<TabsContent value="password">
<Text>Password settings here.</Text>
</TabsContent>
</Tabs>
);
}Installation#
npx @aniui/cli add tabsUsage#
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
export function MyScreen() {
return (
<Tabs defaultValue="account">
<TabsList>
<TabsTrigger value="account">Account</TabsTrigger>
<TabsTrigger value="password">Password</TabsTrigger>
</TabsList>
<TabsContent value="account">
<Text>Account settings here.</Text>
</TabsContent>
<TabsContent value="password">
<Text>Password settings here.</Text>
</TabsContent>
</Tabs>
);
}Line Variant#
Use variant="line" for underline-style tabs instead of the filled background.
Project overview and summary.
<Tabs defaultValue="overview" variant="line">
<TabsList>
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="analytics">Analytics</TabsTrigger>
<TabsTrigger value="reports">Reports</TabsTrigger>
</TabsList>
<TabsContent value="overview">...</TabsContent>
</Tabs>Vertical#
Use orientation="vertical" for sidebar-style navigation. Works with both filled and line variants.
General account settings.
<Tabs defaultValue="general" orientation="vertical" variant="line">
<TabsList>
<TabsTrigger value="general">General</TabsTrigger>
<TabsTrigger value="security">Security</TabsTrigger>
<TabsTrigger value="notifications">Notifications</TabsTrigger>
</TabsList>
<TabsContent value="general">...</TabsContent>
</Tabs>Disabled#
Add disabled to individual triggers to prevent interaction. Disabled tabs show at reduced opacity.
This tab is active.
<Tabs defaultValue="active">
<TabsList>
<TabsTrigger value="active">Active</TabsTrigger>
<TabsTrigger value="disabled" disabled>Disabled</TabsTrigger>
<TabsTrigger value="other">Other</TabsTrigger>
</TabsList>
</Tabs>Icons#
Pass an icon prop to render an icon before the tab label.
Edit your profile information.
import Svg, { Path, Circle } from "react-native-svg";
const UserIcon = () => (
<Svg width={14} height={14} viewBox="0 0 24 24" fill="none"
stroke="#71717a" strokeWidth={2}>
<Path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2" />
<Circle cx={12} cy={7} r={4} />
</Svg>
);
<Tabs defaultValue="profile">
<TabsList>
<TabsTrigger value="profile" icon={<UserIcon />}>Profile</TabsTrigger>
<TabsTrigger value="settings" icon={<SettingsIcon />}>Settings</TabsTrigger>
</TabsList>
</Tabs>Sizes#
Set size on Tabs to control trigger height and text size. Useful for compact layouts on small screens.
<Tabs defaultValue="a" size="sm">
<TabsList>
<TabsTrigger value="a">Small</TabsTrigger>
<TabsTrigger value="b">Tabs</TabsTrigger>
</TabsList>
</Tabs>
<Tabs defaultValue="a" size="md">...</Tabs>
<Tabs defaultValue="a" size="lg">...</Tabs>RTL#
Tabs support right-to-left layouts automatically. Wrap in DirectionProvider for RTL languages.
محتوى الصفحة الرئيسية
import { DirectionProvider } from "@/components/ui/direction-provider";
<DirectionProvider defaultDirection="rtl">
<Tabs defaultValue="home" variant="line">
<TabsList>
<TabsTrigger value="home">الرئيسية</TabsTrigger>
<TabsTrigger value="settings">الإعدادات</TabsTrigger>
</TabsList>
<TabsContent value="home">...</TabsContent>
</Tabs>
</DirectionProvider>Components#
TabsRoot container. Controls variant, size, orientation, and state.
TabsListContainer for tab triggers. Adapts styling from variant and orientation.
TabsTriggerPressable tab button with active state, disabled, and icon support.
TabsContentContent panel shown when its tab is active.
Props#
Tabs#
defaultValuestringrequiredvariant"filled" | "line""filled"size"sm" | "md" | "lg""md"orientation"horizontal" | "vertical""horizontal"classNamestring-TabsTrigger#
valuestringrequireddisabledbooleanfalseiconReact.ReactNode-textClassNamestring-classNamestring-TabsContent#
valuestringrequiredclassNamestring-All sub-components also accept their respective React Native base props.
Accessibility#
accessibilityRole="tab"on triggers,accessibilityRole="tablist"on list,accessibilityRole="tabpanel"on content.accessibilityStatetracksselectedanddisabled.- Uses
will-change-variableto prevent NativeWind v5 state reset warnings. - RTL support via logical properties (
border-e,ms-4).
Source#
import React, { createContext, useContext, useState } from "react";
import { View, Pressable, Text } from "react-native";
import { cva } from "class-variance-authority";
import { cn } from "@/lib/utils";
type TabsVariant = "filled" | "line";
type TabsSize = "sm" | "md" | "lg";
type TabsOrientation = "horizontal" | "vertical";
const TabsCtx = createContext<{
value: string; onValueChange: (v: string) => void;
variant: TabsVariant; size: TabsSize; orientation: TabsOrientation;
}>({ value: "", onValueChange: () => {}, variant: "filled", size: "md", orientation: "horizontal" });
export interface TabsProps extends React.ComponentPropsWithoutRef<typeof View> {
className?: string; defaultValue: string;
variant?: TabsVariant; size?: TabsSize; orientation?: TabsOrientation;
children?: React.ReactNode;
}
export function Tabs({ defaultValue, variant = "filled", size = "md", orientation = "horizontal", className, children, ...props }: TabsProps) {
const [value, setValue] = useState(defaultValue);
return (
<TabsCtx.Provider value={{ value, onValueChange: setValue, variant, size, orientation }}>
<View className={cn(orientation === "vertical" && "flex-row", className)} {...props}>{children}</View>
</TabsCtx.Provider>
);
}
// ... TabsList, TabsTrigger, TabsContent (see source)