---
title: "Tabs — React"
canonical: https://sky-ui.cf.sky.com/components/tabs/react
apiPackages: [{"name":"@sky-uk/ui-core","representedVersion":"13.2.0"}]
---

# Tabs — React

Tabs are used to organise and switch between blocks of related content.

```js
import { Tabs } from "@sky-uk/ui-core";
```

---

**Note:** If you need a tab-style component where the panel content cannot be passed in
  up front and must be conditionally rendered, use the [`Navigation
  Bar`](/navigation-bar/react/) component instead.

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| $appearance | string | default | The `$appearance` prop sets tab styles for various backgrounds, including a light version for dark backgrounds. It's [responsive](/core/hooks/use-responsive-props/), allowing breakpoint-specific adjustments.<br><br>`'default'` \| `'light'` |
| $fill | boolean | false | Dictates whether the Tabs proportionately fill the available space. This prop is [responsive](/core/hooks/use-responsive-props/) and can be used to set the `$fill` value at different breakpoints. |
| id | string |  | The `id` attribute assigns the relevant ARIA attributes to establish a semantic relationship between the Tab and its corresponding Panel. |
| onTabChange | (index: number) => void |  | The `onTabChange` callback triggers when a tab is changed, providing the index of the changed tab as a number. This enables custom actions based on the specific tab interaction. |

### Tabs.Tab

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| $active | boolean |  | Indicates the current tab selection. |
| $hover | boolean |  | Indicates if a tab is being hovered over. |
| $theme | string |  | The theme of the active indicator as a Sky [gradient](/foundations/gradients/)<br><br>Note: if `$appearance` is set to `light`, the theme will be ignored. |

## Basic Tabs

```tsx
<Tabs id="example-1">
    <Tabs.Tab>
        Video Doorbell
    </Tabs.Tab>
    <Tabs.Tab>
        Indoor Camera
    </Tabs.Tab>
    <Tabs.Tab>
        Motion & Contact Sensors
    </Tabs.Tab>

    <Tabs.Panel>
       See who's at your door from anywhere on your smart phone. Even chat with them.
    </Tabs.Panel>
    <Tabs.Panel>
        The ultimate house sitter. Keeps an eye on any room.
    </Tabs.Panel>
    <Tabs.Panel>
        If something moves or opens when it shouldn't, you'll know via the Sky Protect app.
    </Tabs.Panel>
</Tabs>
```

## Tabs Props

### $appearance

`$appearance` can be set to `light` or `default` to provide contrast with backgrounds.

```tsx
<Tabs id="example-2" $appearance="light">
    <Tabs.Tab $active>
        Video Doorbell
    </Tabs.Tab>
    <Tabs.Tab>
        Indoor Camera
    </Tabs.Tab>
    <Tabs.Tab>
        Motion & Contact Sensors
    </Tabs.Tab>

    <Tabs.Panel>
        <Text $color="white">See who's at your door from anywhere on your smart phone. Even chat with them.</Text>
    </Tabs.Panel>
    <Tabs.Panel>
        <Text $color="white">The ultimate house sitter. Keeps an eye on any room.</Text>
    </Tabs.Panel>
    <Tabs.Panel>
        <Text $color="white">If something moves or opens when it shouldn't, you'll know via the Sky Protect app.</Text>
    </Tabs.Panel>
</Tabs>
```

---

### $fill

Set `$fill` to have `Tabs` proportionately take up the available space

```tsx
<Tabs id="example-3" $fill={{ xs: false, md: true }}>
    <Tabs.Tab $active>
        Video Doorbell
    </Tabs.Tab>
    <Tabs.Tab>
        Indoor Camera
    </Tabs.Tab>
    <Tabs.Tab>
        Motion & Contact Sensors
    </Tabs.Tab>

    <Tabs.Panel>
        See who's at your door from anywhere on your smart phone. Even chat with them.
    </Tabs.Panel>
    <Tabs.Panel>
        The ultimate house sitter. Keeps an eye on any room.
    </Tabs.Panel>
    <Tabs.Panel>
        If something moves or opens when it shouldn't, you'll know via the Sky Protect app.
    </Tabs.Panel>
</Tabs>
```

---

### id

The `id` attribute sets the appropriate `aria` attributes to provide semantic relationship between the Tab and Panel.

```jsx
<Tabs id="example-4">
```

**Important:** The **`id`** is essential for the Tabs to function correctly and must be a
  unique value when multiple Tabs are used on a page.

---

### onTabChange

The `onTabChange` callback is triggered when a tab is changed. It receives the index of the changed tab as a number. This allows you to determine which tab was activated and perform additional actions or updates based on the selected tab.

```tsx
function Example(){
  const [tabState, setTabState] = React.useState(null);

  const handleTabChange = index => {
    setTabState(index);
  };

  return (
    <Flex $flexDirection="column" $gap={5}>
      <Text>Current Tab index: {tabState}</Text>
      <Tabs id="example-5" onTabChange={handleTabChange}>
        <Tabs.Tab $active>Video Doorbell</Tabs.Tab>
        <Tabs.Tab>Indoor Camera</Tabs.Tab>
        <Tabs.Tab>Motion & Contact Sensors</Tabs.Tab>

        <Tabs.Panel>See who's at your door from anywhere on your smartphone. Even chat with them.</Tabs.Panel>
        <Tabs.Panel>The ultimate house sitter. Keeps an eye on any room.</Tabs.Panel>
        <Tabs.Panel>If something moves or opens when it shouldn't, you'll know via the Sky Protect app.</Tabs.Panel>
      </Tabs>
    </Flex>
  );
}
```

---

## Tabs.Tab Props

### $active

Add `$active` to indicate current selection on the initial render.

**Note:** You can only have one tab with the `$active` prop. If no tab has the `$active` prop, the first tab will be set as active by default.

```tsx
<Tabs id="example-6">
    <Tabs.Tab $active>
        Video Doorbell
    </Tabs.Tab>
    <Tabs.Tab>
        Indoor Camera
    </Tabs.Tab>
    <Tabs.Tab>
        Motion & Contact Sensors
    </Tabs.Tab>

    <Tabs.Panel>
        See who's at your door from anywhere on your smart phone. Even chat with them.
    </Tabs.Panel>
    <Tabs.Panel>
        The ultimate house sitter. Keeps an eye on any room.
    </Tabs.Panel>
    <Tabs.Panel>
        If something moves or opens when it shouldn't, you'll know via the Sky Protect app.
    </Tabs.Panel>
</Tabs>
```

---

### $theme

Set `$theme` on an individual `Tab` to use any predefined [gradient](/foundations/gradients/).

**Note:** Takes Precedence over `Tabs` `$appearance`

```tsx
<Tabs id="example-7">
    <Tabs.Tab $active $theme="sky">
        Video Doorbell
    </Tabs.Tab>
    <Tabs.Tab $theme="products.tv">
        Indoor Camera
    </Tabs.Tab>
    <Tabs.Tab $theme="products.broadband">
        Motion & Contact Sensors
    </Tabs.Tab>

    <Tabs.Panel>
        See who's at your door from anywhere on your smart phone. Even chat with them.
    </Tabs.Panel>
    <Tabs.Panel>
        The ultimate house sitter. Keeps an eye on any room.
    </Tabs.Panel>
    <Tabs.Panel>
        If something moves or opens when it shouldn't, you'll know via the Sky Protect app.
    </Tabs.Panel>
</Tabs>
```

---

## States

The hover and focus state can be set via `$hover` and `$focused` respectively to override default behavior.

```tsx
<Tabs id="example-8">
    <Tabs.Tab $active>
        Video Doorbell
    </Tabs.Tab>
    <Tabs.Tab $hover>
        Indoor Camera
    </Tabs.Tab>
    <Tabs.Tab $focused>
        Motion & Contact Sensors
    </Tabs.Tab>

    <Tabs.Panel>
        See who's at your door from anywhere on your smart phone. Even chat with them.
    </Tabs.Panel>
    <Tabs.Panel>
        The ultimate house sitter. Keeps an eye on any room.
    </Tabs.Panel>
    <Tabs.Panel>
        If something moves or opens when it shouldn't, you'll know via the Sky Protect app.
    </Tabs.Panel>
</Tabs>
```

---

## Tabs with Icons

You can enhance the `Tabs` component by including `Icon` for a more visual representation.

**Note:** Ensure `$size` is implemented in accordance with guidance.

```tsx
<Tabs id="example-9">
    <Tabs.Tab $active>
        <Icon src={wifiHouseLinear} $size={{ xs: 'medium', xl: 'large' }} />
        Broadband
    </Tabs.Tab>
    <Tabs.Tab>
        <Icon src={tvLinear} $size={{ xs: 'medium', xl: 'large' }} />
        TV
    </Tabs.Tab>
    <Tabs.Tab>
        <Icon src={mobileLinear} $size={{ xs: 'medium', xl: 'large' }} />
       Mobile
    </Tabs.Tab>

    <Tabs.Panel>
        We've got speeds for every household. Check out our broadband plans to find your perfect match.
    </Tabs.Panel>
    <Tabs.Panel>
        Built for the best entertainment. Sky Stream pairs brilliantly with our content. Stream your favourites over WiFi.
    </Tabs.Panel>
    <Tabs.Panel>
        Explore a world of possibilities and switch to Sky Mobile, the award-winning network
    </Tabs.Panel>
</Tabs>
```

---

## System Modifiers

The `Tabs` component supports the props applied using the following system modifiers:

- [display](/core/system/display/)
- [flex-child](/core/system/flex-child/)
- [grid-child](/core/system/grid-child/)
- [margin](/core/system/margin/)
- [width](/core/system/width/)

The `Tabs.Panel` component supports the props applied using the following system modifiers:

- [padding](/core/system/padding/)
