AniUI

Tabs

Tab navigation with filled and line variants, sizes, vertical layout, icons, disabled state, and RTL support.

Manage your account settings and preferences.

Web preview — components render natively on iOS & Android
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 tabs

Usage#

app/index.tsx
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.

Web preview — components render natively on iOS & Android
<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.

Web preview — components render natively on iOS & Android
<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.

Web preview — components render natively on iOS & Android
<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.

Web preview — components render natively on iOS & Android
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.

Web preview — components render natively on iOS & Android
<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.

محتوى الصفحة الرئيسية

Web preview — components render natively on iOS & Android
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#

ComponentDescription
Tabs

Root container. Controls variant, size, orientation, and state.

TabsList

Container for tab triggers. Adapts styling from variant and orientation.

TabsTrigger

Pressable tab button with active state, disabled, and icon support.

TabsContent

Content panel shown when its tab is active.

Props#

Tabs#

PropTypeDefault
defaultValue
string
required
variant
"filled" | "line"
"filled"
size
"sm" | "md" | "lg"
"md"
orientation
"horizontal" | "vertical"
"horizontal"
className
string
-

TabsTrigger#

PropTypeDefault
value
string
required
disabled
boolean
false
icon
React.ReactNode
-
textClassName
string
-
className
string
-

TabsContent#

PropTypeDefault
value
string
required
className
string
-

All sub-components also accept their respective React Native base props.

Accessibility#

  • accessibilityRole="tab" on triggers, accessibilityRole="tablist" on list, accessibilityRole="tabpanel" on content.
  • accessibilityState tracks selected and disabled.
  • Uses will-change-variable to prevent NativeWind v5 state reset warnings.
  • RTL support via logical properties (border-e, ms-4).

Source#

components/ui/tabs.tsx
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)