# Tabs

Organize content into tabbed views with animated transitions and indicators.

## Imports

Note: Before importing this component, ensure you have completed the setup as per the [Quick Start guide](../../../README.md).

```tsx
import { Tabs } from 'heroui-native';
```

## Usage

### Basic Usage

The Tabs component uses compound parts to create navigable content sections.

```tsx
<Tabs value="tab1" onValueChange={setActiveTab}>
  <Tabs.List>
    <Tabs.Indicator />
    <Tabs.Trigger value="tab1">
      <Tabs.Label>Tab 1</Tabs.Label>
    </Tabs.Trigger>
    <Tabs.Trigger value="tab2">
      <Tabs.Label>Tab 2</Tabs.Label>
    </Tabs.Trigger>
  </Tabs.List>
  <Tabs.Content value="tab1">...</Tabs.Content>
  <Tabs.Content value="tab2">...</Tabs.Content>
</Tabs>
```

### Pill Variant

Default rounded pill style for tab triggers.

```tsx
<Tabs value={activeTab} onValueChange={setActiveTab} variant="pill">
  <Tabs.List>
    <Tabs.Indicator />
    <Tabs.Trigger value="settings">
      <Tabs.Label>Settings</Tabs.Label>
    </Tabs.Trigger>
    <Tabs.Trigger value="profile">
      <Tabs.Label>Profile</Tabs.Label>
    </Tabs.Trigger>
  </Tabs.List>
  <Tabs.Content value="settings">...</Tabs.Content>
  <Tabs.Content value="profile">...</Tabs.Content>
</Tabs>
```

### Line Variant

Underline style indicator for a more minimal appearance.

```tsx
<Tabs value={activeTab} onValueChange={setActiveTab} variant="line">
  <Tabs.List>
    <Tabs.Indicator />
    <Tabs.Trigger value="overview">
      <Tabs.Label>Overview</Tabs.Label>
    </Tabs.Trigger>
    <Tabs.Trigger value="analytics">
      <Tabs.Label>Analytics</Tabs.Label>
    </Tabs.Trigger>
  </Tabs.List>
  <Tabs.Content value="overview">...</Tabs.Content>
  <Tabs.Content value="analytics">...</Tabs.Content>
</Tabs>
```

### Scrollable Tabs

Handle many tabs with horizontal scrolling.

```tsx
<Tabs value={activeTab} onValueChange={setActiveTab}>
  <Tabs.List>
    <Tabs.ScrollView scrollAlign="center">
      <Tabs.Indicator />
      <Tabs.Trigger value="tab1">
        <Tabs.Label>First Tab</Tabs.Label>
      </Tabs.Trigger>
      <Tabs.Trigger value="tab2">
        <Tabs.Label>Second Tab</Tabs.Label>
      </Tabs.Trigger>
      <Tabs.Trigger value="tab3">
        <Tabs.Label>Third Tab</Tabs.Label>
      </Tabs.Trigger>
      <Tabs.Trigger value="tab4">
        <Tabs.Label>Fourth Tab</Tabs.Label>
      </Tabs.Trigger>
      <Tabs.Trigger value="tab5">
        <Tabs.Label>Fifth Tab</Tabs.Label>
      </Tabs.Trigger>
    </Tabs.ScrollView>
  </Tabs.List>
  <Tabs.Content value="tab1">...</Tabs.Content>
  <Tabs.Content value="tab2">...</Tabs.Content>
  <Tabs.Content value="tab3">...</Tabs.Content>
  <Tabs.Content value="tab4">...</Tabs.Content>
  <Tabs.Content value="tab5">...</Tabs.Content>
</Tabs>
```

### Disabled Tabs

Disable specific tabs to prevent interaction.

```tsx
<Tabs value={activeTab} onValueChange={setActiveTab}>
  <Tabs.List>
    <Tabs.Indicator />
    <Tabs.Trigger value="active">
      <Tabs.Label>Active</Tabs.Label>
    </Tabs.Trigger>
    <Tabs.Trigger value="disabled" isDisabled>
      <Tabs.Label>Disabled</Tabs.Label>
    </Tabs.Trigger>
    <Tabs.Trigger value="another">
      <Tabs.Label>Another</Tabs.Label>
    </Tabs.Trigger>
  </Tabs.List>
  <Tabs.Content value="active">...</Tabs.Content>
  <Tabs.Content value="another">...</Tabs.Content>
</Tabs>
```

### With Icons

Combine icons with labels for enhanced visual context.

```tsx
<Tabs value={activeTab} onValueChange={setActiveTab}>
  <Tabs.List>
    <Tabs.Indicator />
    <Tabs.Trigger value="home">
      <Icon name="home" size={16} />
      <Tabs.Label>Home</Tabs.Label>
    </Tabs.Trigger>
    <Tabs.Trigger value="search">
      <Icon name="search" size={16} />
      <Tabs.Label>Search</Tabs.Label>
    </Tabs.Trigger>
  </Tabs.List>
  <Tabs.Content value="home">...</Tabs.Content>
  <Tabs.Content value="search">...</Tabs.Content>
</Tabs>
```

### With Render Function

Use a render function on `Tabs.Trigger` to access state and customize content based on selection.

```tsx
<Tabs value={activeTab} onValueChange={setActiveTab}>
  <Tabs.List>
    <Tabs.Indicator />
    <Tabs.Trigger value="settings">
      {({ isSelected, value, isDisabled }) => (
        <Tabs.Label
          className={isSelected ? 'text-accent font-medium' : 'text-foreground'}
        >
          Settings
        </Tabs.Label>
      )}
    </Tabs.Trigger>
    <Tabs.Trigger value="profile">
      {({ isSelected }) => (
        <>
          <Icon name="user" size={16} />
          <Tabs.Label className={isSelected ? 'text-accent' : 'text-muted'}>
            Profile
          </Tabs.Label>
        </>
      )}
    </Tabs.Trigger>
  </Tabs.List>
  <Tabs.Content value="settings">...</Tabs.Content>
  <Tabs.Content value="profile">...</Tabs.Content>
</Tabs>
```

## Example

```tsx
import { Tabs, TextField, FormField, Checkbox, Button } from 'heroui-native';
import { useState } from 'react';
import { View, Text } from 'react-native';
import Animated, {
  FadeIn,
  FadeOut,
  LinearTransition,
} from 'react-native-reanimated';

const AnimatedContentContainer = ({
  children,
}: {
  children: React.ReactNode;
}) => (
  <Animated.View
    entering={FadeIn.duration(200)}
    exiting={FadeOut.duration(200)}
    className="gap-6"
  >
    {children}
  </Animated.View>
);

export default function TabsExample() {
  const [activeTab, setActiveTab] = useState('general');

  const [showSidebar, setShowSidebar] = useState(true);
  const [accountActivity, setAccountActivity] = useState(true);
  const [name, setName] = useState('');

  return (
    <Tabs value={activeTab} onValueChange={setActiveTab} variant="pill">
      <Tabs.List>
        <Tabs.ScrollView>
          <Tabs.Indicator />
          <Tabs.Trigger value="general">
            <Tabs.Label>General</Tabs.Label>
          </Tabs.Trigger>
          <Tabs.Trigger value="notifications">
            <Tabs.Label>Notifications</Tabs.Label>
          </Tabs.Trigger>
          <Tabs.Trigger value="profile">
            <Tabs.Label>Profile</Tabs.Label>
          </Tabs.Trigger>
        </Tabs.ScrollView>
      </Tabs.List>

      <Animated.View
        layout={LinearTransition.duration(200)}
        className="px-4 py-6 border border-border rounded-xl"
      >
        <Tabs.Content value="general">
          <AnimatedContentContainer>
            <FormField
              isSelected={showSidebar}
              onSelectedChange={setShowSidebar}
            >
              <FormField.Indicator variant="checkbox" />
              <View className="flex-1">
                <FormField.Label>Show sidebar</FormField.Label>
                <FormField.Description>
                  Display the sidebar navigation panel
                </FormField.Description>
              </View>
            </FormField>
          </AnimatedContentContainer>
        </Tabs.Content>

        <Tabs.Content value="notifications">
          <AnimatedContentContainer>
            <FormField
              isSelected={accountActivity}
              onSelectedChange={setAccountActivity}
            >
              <FormField.Indicator variant="checkbox" />
              <View className="flex-1">
                <FormField.Label>Account activity</FormField.Label>
                <FormField.Description>
                  Notifications about your account activity
                </FormField.Description>
              </View>
            </FormField>
          </AnimatedContentContainer>
        </Tabs.Content>

        <Tabs.Content value="profile">
          <AnimatedContentContainer>
            <TextField isRequired>
              <TextField.Label>Name</TextField.Label>
              <TextField.Input
                value={name}
                onChangeText={setName}
                placeholder="Enter your full name"
              />
            </TextField>
            <Button size="sm" className="self-start">
              <Button.Label>Update profile</Button.Label>
            </Button>
          </AnimatedContentContainer>
        </Tabs.Content>
      </Animated.View>
    </Tabs>
  );
}
```

## Anatomy

```tsx
<Tabs>
  <Tabs.List>
    <Tabs.ScrollView>
      <Tabs.Indicator />
      <Tabs.Trigger>
        <Tabs.Label>...</Tabs.Label>
      </Tabs.Trigger>
    </Tabs.ScrollView>
  </Tabs.List>
  <Tabs.Content>...</Tabs.Content>
</Tabs>
```

- **Tabs**: Main container that manages tab state and selection. Controls active tab, handles value changes, and provides context to child components.
- **Tabs.List**: Container for tab triggers. Groups triggers together with optional styling variants (pill or line).
- **Tabs.ScrollView**: Optional scrollable wrapper for tab triggers. Enables horizontal scrolling when tabs overflow with automatic centering of active tab.
- **Tabs.Trigger**: Interactive button for each tab. Handles press events to change active tab and measures its position for indicator animation.
- **Tabs.Label**: Text content for tab triggers. Displays the tab title with appropriate styling.
- **Tabs.Indicator**: Animated visual indicator for active tab. Smoothly transitions between tabs using spring or timing animations.
- **Tabs.Content**: Container for tab panel content. Shows content when its value matches the active tab.

## API Reference

### Tabs

| prop            | type                         | default     | description                                                                               |
| --------------- | ---------------------------- | ----------- | ----------------------------------------------------------------------------------------- |
| `children`      | `React.ReactNode`            | -           | Children elements to be rendered inside tabs                                              |
| `value`         | `string`                     | -           | Currently active tab value                                                                |
| `variant`       | `'pill' \| 'line'`           | `'pill'`    | Visual variant of the tabs                                                                |
| `className`     | `string`                     | -           | Additional CSS classes for the container                                                  |
| `animation`     | `"disable-all" \| undefined` | `undefined` | Animation configuration. Use `"disable-all"` to disable all animations including children |
| `onValueChange` | `(value: string) => void`    | -           | Callback when the active tab changes                                                      |
| `...ViewProps`  | `ViewProps`                  | -           | All standard React Native View props are supported                                        |

### Tabs.List

| prop           | type              | default | description                                        |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children`     | `React.ReactNode` | -       | Children elements to be rendered inside the list   |
| `className`    | `string`          | -       | Additional CSS classes                             |
| `...ViewProps` | `ViewProps`       | -       | All standard React Native View props are supported |

### Tabs.ScrollView

| prop                        | type                                     | default    | description                                              |
| --------------------------- | ---------------------------------------- | ---------- | -------------------------------------------------------- |
| `children`                  | `React.ReactNode`                        | -          | Children elements to be rendered inside the scroll view  |
| `scrollAlign`               | `'start' \| 'center' \| 'end' \| 'none'` | `'center'` | Scroll alignment variant for the selected item           |
| `className`                 | `string`                                 | -          | Additional CSS classes for the scroll view               |
| `contentContainerClassName` | `string`                                 | -          | Additional CSS classes for the content container         |
| `...ScrollViewProps`        | `ScrollViewProps`                        | -          | All standard React Native ScrollView props are supported |

### Tabs.Trigger

| prop                | type                                                                      | default | description                                                               |
| ------------------- | ------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------- |
| `children`          | `React.ReactNode \| ((props: TabsTriggerRenderProps) => React.ReactNode)` | -       | Children elements to be rendered inside the trigger, or a render function |
| `value`             | `string`                                                                  | -       | The unique value identifying this tab                                     |
| `isDisabled`        | `boolean`                                                                 | `false` | Whether the trigger is disabled                                           |
| `className`         | `string`                                                                  | -       | Additional CSS classes                                                    |
| `...PressableProps` | `PressableProps`                                                          | -       | All standard React Native Pressable props are supported                   |

#### TabsTriggerRenderProps

When using a render function for `children`, the following props are provided:

| property     | type      | description                                |
| ------------ | --------- | ------------------------------------------ |
| `isSelected` | `boolean` | Whether this trigger is currently selected |
| `value`      | `string`  | The value of the trigger                   |
| `isDisabled` | `boolean` | Whether the trigger is disabled            |

### Tabs.Label

| prop           | type              | default | description                                        |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children`     | `React.ReactNode` | -       | Text content to be rendered as label               |
| `className`    | `string`          | -       | Additional CSS classes                             |
| `...TextProps` | `TextProps`       | -       | All standard React Native Text props are supported |

### Tabs.Indicator

| prop                    | type                     | default | description                                                  |
| ----------------------- | ------------------------ | ------- | ------------------------------------------------------------ |
| `children`              | `React.ReactNode`        | -       | Custom indicator content                                     |
| `className`             | `string`                 | -       | Additional CSS classes                                       |
| `animation`             | `TabsIndicatorAnimation` | -       | Animation configuration                                      |
| `isAnimatedStyleActive` | `boolean`                | `true`  | Whether animated styles (react-native-reanimated) are active |
| `...Animated.ViewProps` | `Animated.ViewProps`     | -       | All Reanimated Animated.View props are supported             |

#### TabsIndicatorAnimation

Animation configuration for Tabs.Indicator component. Can be:

- `false` or `"disabled"`: Disable all animations
- `true` or `undefined`: Use default animations
- `object`: Custom animation configuration

| prop            | type                                   | default                                                                      | description                                     |
| --------------- | -------------------------------------- | ---------------------------------------------------------------------------- | ----------------------------------------------- |
| `state`         | `'disabled' \| boolean`                | -                                                                            | Disable animations while customizing properties |
| `width.type`    | `'spring' \| 'timing'`                 | `'spring'`                                                                   | Type of animation to use                        |
| `width.config`  | `WithSpringConfig \| WithTimingConfig` | `{ stiffness: 1200, damping: 120 }` (spring) or `{ duration: 200 }` (timing) | Reanimated animation configuration              |
| `height.type`   | `'spring' \| 'timing'`                 | `'spring'`                                                                   | Type of animation to use                        |
| `height.config` | `WithSpringConfig \| WithTimingConfig` | `{ stiffness: 1200, damping: 120 }` (spring) or `{ duration: 200 }` (timing) | Reanimated animation configuration              |
| `left.type`     | `'spring' \| 'timing'`                 | `'spring'`                                                                   | Type of animation to use                        |
| `left.config`   | `WithSpringConfig \| WithTimingConfig` | `{ stiffness: 1200, damping: 120 }` (spring) or `{ duration: 200 }` (timing) | Reanimated animation configuration              |

### Tabs.Content

| prop           | type              | default | description                                         |
| -------------- | ----------------- | ------- | --------------------------------------------------- |
| `children`     | `React.ReactNode` | -       | Children elements to be rendered inside the content |
| `value`        | `string`          | -       | The value of the tab this content belongs to        |
| `className`    | `string`          | -       | Additional CSS classes                              |
| `...ViewProps` | `ViewProps`       | -       | All standard React Native View props are supported  |

### useTabs

Hook to access tabs root context values within custom components or compound components.

```tsx
import { useTabs } from 'heroui-native';

const CustomComponent = () => {
  const { value, onValueChange, nativeID } = useTabs();
  // ... your implementation
};
```

**Returns:** `UseTabsReturn`

| property        | type                      | description                                |
| --------------- | ------------------------- | ------------------------------------------ |
| `value`         | `string`                  | Currently active tab value                 |
| `onValueChange` | `(value: string) => void` | Callback function to change the active tab |
| `nativeID`      | `string`                  | Unique identifier for the tabs instance    |

**Note:** This hook must be used within a `Tabs` component. It will throw an error if called outside of the tabs context.

### useTabsMeasurements

Hook to access tab measurements context values for managing tab trigger positions and dimensions.

```tsx
import { useTabsMeasurements } from 'heroui-native';

const CustomIndicator = () => {
  const { measurements, variant } = useTabsMeasurements();
  // ... your implementation
};
```

**Returns:** `UseTabsMeasurementsReturn`

| property          | type                                                    | description                                       |
| ----------------- | ------------------------------------------------------- | ------------------------------------------------- |
| `measurements`    | `Record<string, ItemMeasurements>`                      | Record of measurements for each tab trigger       |
| `setMeasurements` | `(key: string, measurements: ItemMeasurements) => void` | Function to update measurements for a tab trigger |
| `variant`         | `'pill' \| 'line'`                                      | Visual variant of the tabs                        |

#### ItemMeasurements

| property | type     | description                         |
| -------- | -------- | ----------------------------------- |
| `width`  | `number` | Width of the tab trigger in pixels  |
| `height` | `number` | Height of the tab trigger in pixels |
| `x`      | `number` | X position of the tab trigger       |

**Note:** This hook must be used within a `Tabs` component. It will throw an error if called outside of the tabs context.

### useTabsTrigger

Hook to access tab trigger context values within custom components or compound components.

```tsx
import { useTabsTrigger } from 'heroui-native';

const CustomLabel = () => {
  const { value, isSelected, nativeID } = useTabsTrigger();
  // ... your implementation
};
```

**Returns:** `UseTabsTriggerReturn`

| property     | type      | description                                |
| ------------ | --------- | ------------------------------------------ |
| `value`      | `string`  | The value of this trigger                  |
| `nativeID`   | `string`  | Unique identifier for this trigger         |
| `isSelected` | `boolean` | Whether this trigger is currently selected |

**Note:** This hook must be used within a `Tabs.Trigger` component. It will throw an error if called outside of the trigger context.
