import { useState } from "react";
import { Text } from "react-native";
import { useKitTheme } from "@/component-lib/shared/native";
import { Tab, TabList, TabPanel, Tabs } from "@/component-lib/tabs";
import { Section } from "./layout"; // Section and Row: page layout for the demo
function Body({ children }: { children: string }) {
const { tokens } = useKitTheme();
return <Text style={{ color: tokens.fg, fontSize: tokens.fontSize, paddingVertical: 8 }}>{children}</Text>;
}
export function TabsDemo() {
const [value, setValue] = useState("invoices");
return (
<>
<Section title="Tabs · line (scrolls when it does not fit)">
<Tabs value={value} onValueChange={setValue}>
<TabList>
<Tab value="overview">Overview</Tab>
<Tab value="invoices" badge={12}>
Invoices
</Tab>
<Tab value="payments">Payments</Tab>
<Tab value="reports">Reports</Tab>
<Tab value="settings">Settings</Tab>
<Tab value="archived" disabled>
Archived
</Tab>
</TabList>
<TabPanel value="overview">
<Body>Overview: revenue and outstanding at a glance.</Body>
</TabPanel>
<TabPanel value="invoices">
<Body>12 invoices waiting for approval.</Body>
</TabPanel>
<TabPanel value="payments">
<Body>Payments received this month.</Body>
</TabPanel>
<TabPanel value="reports">
<Body>Reports: GST, TDS and ledgers.</Body>
</TabPanel>
<TabPanel value="settings">
<Body>Settings for this workspace.</Body>
</TabPanel>
</Tabs>
</Section>
<Section title="Tabs · pills, small">
<Tabs variant="pills" size="sm" defaultValue="week">
<TabList>
<Tab value="day">Day</Tab>
<Tab value="week">Week</Tab>
<Tab value="month">Month</Tab>
<Tab value="year">Year</Tab>
</TabList>
<TabPanel value="day">
<Body>Today's numbers.</Body>
</TabPanel>
<TabPanel value="week">
<Body>This week's numbers.</Body>
</TabPanel>
<TabPanel value="month">
<Body>This month's numbers.</Body>
</TabPanel>
<TabPanel value="year">
<Body>This year's numbers.</Body>
</TabPanel>
</Tabs>
</Section>
<Section title="Tabs · enclosed (segmented), keepMounted">
<Tabs variant="enclosed" keepMounted>
<TabList>
<Tab value="list">List</Tab>
<Tab value="board">Board</Tab>
<Tab value="calendar">Calendar</Tab>
</TabList>
<TabPanel value="list">
<Body>No value given: the first tab is selected.</Body>
</TabPanel>
<TabPanel value="board">
<Body>Board view; the list keeps its state while hidden.</Body>
</TabPanel>
<TabPanel value="calendar">
<Body>Calendar view.</Body>
</TabPanel>
</Tabs>
</Section>
<Section title="Tabs · vertical">
<Tabs orientation="vertical" defaultValue="profile">
<TabList>
<Tab value="profile">Profile</Tab>
<Tab value="security">Security</Tab>
<Tab value="billing">Billing</Tab>
</TabList>
<TabPanel value="profile">
<Body>Name, photo and contact details.</Body>
</TabPanel>
<TabPanel value="security">
<Body>Password and two-factor sign-in.</Body>
</TabPanel>
<TabPanel value="billing">
<Body>Plan and payment method.</Body>
</TabPanel>
</Tabs>
</Section>
</>
);
}Install
npx @grampro/kit@native add TabsUsage
import { Tabs, TabList, Tab, TabPanel } from "@/component-lib/tabs";
<Tabs defaultValue="open">
<TabList>
<Tab value="open">Open</Tab>
<Tab value="paid">Paid</Tab>
</TabList>
<TabPanel value="open">…</TabPanel>
<TabPanel value="paid">…</TabPanel>
</Tabs>Props
TabsProps
| Prop | Type | Description |
|---|---|---|
value | string | Selected tab (controlled). |
defaultValue | string | Selected tab at first. Without either, the first enabled tab is selected. |
onValueChange | (value: string) => void | The newly selected tab. Not fired when the same tab is pressed again. |
orientation | TabsOrientation | Default horizontal. |
activation | TabsActivation | Kept for API parity with the web. Touch has no arrow-key focus to follow, so a press always selects. |
variant | TabsVariant | Default line. |
size | TabsSize | Default md. |
keepMounted | boolean | Keep hidden panels mounted, preserving their state (form input, scroll) through React's <Activity>. Default false. |
children | ReactNode |
Also accepts the props of Omit<ViewProps, "children">.
TabProps
| Prop | Type | Description |
|---|---|---|
value (required) | string | Identifies the tab and its panel. |
disabled | boolean | |
icon | ReactNode | An icon before the tab's text. |
badge | ReactNode | A small count or label after the text, e.g. unread items. |
children | ReactNode | |
style | StyleProp<ViewStyle> | ((state: TabStyleState) => StyleProp<ViewStyle>) | |
styles | Partial<{ label: StyleProp<TextStyle>; badge: StyleProp<ViewStyle>; icon: StyleProp<Vie… |
Also accepts the props of Omit<PressableProps, "children" | "style" | "disabled">.
TabPanelProps
| Prop | Type | Description |
|---|---|---|
value (required) | string | |
keepMounted | boolean | Overrides keepMounted on Tabs for this panel. |
children | ReactNode |
Also accepts the props of Omit<ViewProps, "children">.
Native and web
activationis accepted for parity but a tap always selects.- Web version: Tabs on the web.