Tabs
Tabs Primitive
Text Component
Terminal window
~/components/ui/tabs.tsx
Demo
A collection of layered content sections, referred to as tab panels, displayed individually.
Installation
npx @react-native-reusables/cli@latest add tabs
Copy/paste the following code to ~/components/ui/tabs.tsx
:
import * as TabsPrimitive from '@rn-primitives/tabs';import * as React from 'react';import { cn } from '~/lib/utils';import { TextClassContext } from '~/components/ui/text';
const Tabs = TabsPrimitive.Root;
const TabsList = React.forwardRef<TabsPrimitive.ListRef, TabsPrimitive.ListProps>( ({ className, ...props }, ref) => ( <TabsPrimitive.List ref={ref} className={cn( 'web:inline-flex h-10 native:h-12 items-center justify-center rounded-md bg-muted p-1 native:px-1.5', className )} {...props} /> ));TabsList.displayName = TabsPrimitive.List.displayName;
const TabsTrigger = React.forwardRef<TabsPrimitive.TriggerRef, TabsPrimitive.TriggerProps>( ({ className, ...props }, ref) => { const { value } = TabsPrimitive.useRootContext(); return ( <TextClassContext.Provider value={cn( 'text-sm native:text-base font-medium text-muted-foreground web:transition-all', value === props.value && 'text-foreground' )} > <TabsPrimitive.Trigger ref={ref} className={cn( 'inline-flex items-center justify-center shadow-none web:whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium web:ring-offset-background web:transition-all web:focus-visible:outline-none web:focus-visible:ring-2 web:focus-visible:ring-ring web:focus-visible:ring-offset-2', props.disabled && 'web:pointer-events-none opacity-50', props.value === value && 'bg-background shadow-lg shadow-foreground/10', className )} {...props} /> </TextClassContext.Provider> ); });TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
const TabsContent = React.forwardRef<TabsPrimitive.ContentRef, TabsPrimitive.ContentProps>( ({ className, ...props }, ref) => ( <TabsPrimitive.Content ref={ref} className={cn( 'web:ring-offset-background web:focus-visible:outline-none web:focus-visible:ring-2 web:focus-visible:ring-ring web:focus-visible:ring-offset-2', className )} {...props} /> ));TabsContent.displayName = TabsPrimitive.Content.displayName;
export { Tabs, TabsContent, TabsList, TabsTrigger };
Usage
import * as React from 'react';import { View } from 'react-native';import { Button } from '~/components/ui/button';import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle,} from '~/components/ui/card';import { Input } from '~/components/ui/input';import { Label } from '~/components/ui/label';import { Tabs, TabsContent, TabsList, TabsTrigger } from '~/components/ui/tabs';import { Text } from '~/components/ui/text';
export default function TabsScreen() { const [value, setValue] = React.useState('account'); return ( <View className='flex-1 justify-center p-6'> <Tabs value={value} onValueChange={setValue} className='w-full max-w-[400px] mx-auto flex-col gap-1.5' > <TabsList className='flex-row w-full'> <TabsTrigger value='account' className='flex-1'> <Text>Account</Text> </TabsTrigger> <TabsTrigger value='password' className='flex-1'> <Text>Password</Text> </TabsTrigger> </TabsList> <TabsContent value='account'> <Card> <CardHeader> <CardTitle>Account</CardTitle> <CardDescription> Make changes to your account here. Click save when you're done. </CardDescription> </CardHeader> <CardContent className='gap-4 native:gap-2'> <View className='gap-1'> <Label nativeID='name'>Name</Label> <Input aria-aria-labelledby='name' defaultValue='Pedro Duarte' /> </View> <View className='gap-1'> <Label nativeID='username'>Username</Label> <Input id='username' defaultValue='@peduarte' /> </View> </CardContent> <CardFooter> <Button> <Text>Save changes</Text> </Button> </CardFooter> </Card> </TabsContent> <TabsContent value='password'> <Card> <CardHeader> <CardTitle>Password</CardTitle> <CardDescription> Change your password here. After saving, you'll be logged out. </CardDescription> </CardHeader> <CardContent className='gap-4 native:gap-2'> <View className='gap-1'> <Label nativeID='current'>Current password</Label> <Input placeholder='********' aria-labelledby='current' secureTextEntry /> </View> <View className='gap-1'> <Label nativeID='new'>New password</Label> <Input placeholder='********' aria-labelledby='new' secureTextEntry /> </View> </CardContent> <CardFooter> <Button> <Text>Save password</Text> </Button> </CardFooter> </Card> </TabsContent> </Tabs> </View> );}
Props
Tabs
Extends View
props
Prop | Type | Note |
---|---|---|
value | string | |
onValueChange | (value: string ) => void | |
asChild | boolean | (optional) |
disabled | boolean | (optional) |
orientation | ’horizontal’ | ‘vertical’ | Web Only (optional) |
dir | ’ltr’ | ‘rtl’ | Web Only (optional) |
activationMode | ’automatic’ | ‘manual’ | Web Only (optional) |
TabsList
Extends View
props
Prop | Type | Note |
---|---|---|
asChild | boolean | (optional) |
TabsTrigger
Extends Pressable
props
Prop | Type | Note |
---|---|---|
asChild | boolean | (optional) |
TabsContent
Extends View
props
Prop | Type | Note |
---|---|---|
value | string | |
forceMount | boolean | (optional) |
asChild | boolean | (optional) |