Tabs
In-page tabs are an intuitive way to present lots of content at once, without overwhelming the viewer. Use tabs only when users don’t need to see content from multiple tabs simultaneously.
Loading...
Overview
Resources
Install
yarn add @camp/tabsUpgrading to Next Gen
🎨 Updated color palette and style refresh: Aligned styling with our refreshed brand standards, delivering a modernized and cohesive look and feel.
🪶 Light weight: Follows a ‘compositional’ approach, enabling users to only pull in the pieces they need to fit their use case.
📏 New size prop: Offers a prop called size, allowing users to optionally add some additional padding / height to the TabTrigger. By default, the size is set to "small".
🔆 New themed prop: Allows users to enable light and dark theming for the Tabs component.
More about theming here.
Previous implementation
Not much has changed in the way of component API / consumption of the Tabs component, aside from the naming of subcomponents that we export.
Both implementations (Camp 1 and Next Gen) rely heavily on the use of the Radix Tabs ‘Primitives’ .
import { Root, List, TriggerAsset, Trigger, Content } from '@activecampaign/camp-components-tabs';
 
<Root>
  <List>
    <Trigger value={'tab 1'}>
      <TriggerAsset>...</TriggerAsset>
      Tab 1
    </Trigger>
    <Trigger value={'tab 2'}>Tab 2</Trigger>
  </List>
  <Content value={'tab 1'}>Content 1</Content>
  <Content value={'tab 2'}>Content 2</Content>
  ...
</Root>;New implementation
Since we’re just restyling the radix tabs primitive, the composition pattern remains the same as it did in the previous approach.
We’ve added the size prop to the Tabs component, which defaults to "small" if not explicitly specified. This will modify the padding / height for all instances of TabTrigger within the Tabs component.
When the Tabs are in the ‘horizontal’ orientation, the iconAlignment prop can be used to easily position the icon on top of / to the left of the text content.
In the new @camp/tabs, the TriggerAsset component has been deprecated as it’s no longer needed to position the Icon.
import { Tabs, TabLists, TabTrigger, TabContent } from '@camp/tabs';
 
<Tabs size="medium">
  <TabLists>
    <TabTrigger value={'tab 1'}>Tab 1</TabTrigger>
    <TabTrigger value={'tab 2'}>Tab 2</TabTrigger>
  </TabLists>
  <TabContent value={'tab 1'}>Content 1</TabContent>
  <TabContent value={'tab 2'}>Content 2</TabContent>
  ...
</Tabs>;Migration steps
- Update import path: Replace the old tabs imports from 
@camp/tabsper the section above titled “New Implementation”. - Remove the 
<TriggerAsset />component: This is no longer available in the new implementation. You can simply apply margin direcly to the asset / icon directly if you choose to render it within theTabTriggercomponent. - Specify 
sizeprop: This is optional, as thesizehas a default value of"small"already applied to it. Optionally override thesizeprop to"medium"if you’d like to add some additional padding / height to theTabTrigger. 
Usage
Set up ThemeProvider
The Tabs component requires a styled-components ThemeProvider to be set up in your application. This is required for all versions 0.7.0 and above, regardless of whether you plan to use theming features. See the Styled Components & ThemeProvider guide for more details on setting up the ThemeProvider.
Note: Even if you don’t need theming support, you still need the ThemeProvider wrapper. The Tabs component will default to light mode styling, unless you explicitly set the themed prop to true.
Controlled State
import { Tabs, TabLists, TabTrigger, TabContent } from '@camp/tabs';
import React from 'react';
 
const [value, setValue] = React.useState('tab 1');
 
...
 
<Tabs value={value} onValueChange={(value) => setValue(value)}>
  <TabLists>
    <TabTrigger value={'tab 1'}>Tab 1</TabTrigger>
  ...
</Tabs>;Uncontrolled State
import { Tabs, TabLists, TabTrigger, TabContent } from '@camp/tabs';
 
<Tabs defaultValue="tab 1">
  <TabLists>
    <TabTrigger value={'tab 1'}>Tab 1</TabTrigger>
  ...
</Tabs>;Variations
Toggle theming
Prop: themed 
Type: boolean 
Default value: false
The themed prop enables light and dark mode support for the Tabs component. This is useful for applications that support theme switching, such as AI agent interfaces or other areas with dark mode capabilities.
When to use themed:
- ✅ If you need light and dark mode support, use 
themed={true}. This is useful in AI agent interfaces or other areas with dark mode capabilities. - ❌ If you need light mode support only, themed is not required as it is set to 
falseby default. This is useful in standard application areas that only support light mode. - 🔨 If light mode support is not working as expected, try explicitly setting 
themed={false}(and check that your component has been updated to the latest version). 
Behavior:
- With 
themed={true}: Tabs will respond to theme changes and display appropriate colors for light/dark modes - Without 
themedprop: Tabs will always display in light mode styling, regardless of the current theme 
import { Tabs, TabLists, TabTrigger } from '@camp/tabs';
 
<Tabs themed>
  <TabLists>...</TabLists>
</Tabs>;Orientation
The Tabs component can be used in both horizontal and vertical orientations.
import { Tabs, TabLists, TabTrigger, TabContent } from '@camp/tabs';
 
<Tabs orientation="vertical">
  <TabLists>
  ...
</Tabs>;import { Tabs, TabLists, TabTrigger, TabContent } from '@camp/tabs';
 
<Tabs orientation="horizontal">
  <TabLists>
  ...
</Tabs>;
 Size
The Tabs component can be used in both small and medium sizes.
import { Tabs, TabLists, TabTrigger, TabContent } from '@camp/tabs';
 
<Tabs size="small">
  <TabLists>
  ...
</Tabs>;import { Tabs, TabLists, TabTrigger, TabContent } from '@camp/tabs';
 
<Tabs size="medium">
  <TabLists>
  ...
</Tabs>;Icons
The Tabs component can be used with icons.
Icon Alignment
When the Tabs orientation is ‘horizontal’, the iconAlignment prop can be used to easily specify the alignment of an icon relative to the text.
top: Aligns the icon above the text. This should be used only with ‘medium’ sized Icons
import { Tabs, TabLists, TabTrigger, TabContent } from '@camp/tabs';
import { CalendarEventMedium } from '@camp/icons';
import { SemanticColors } from '@camp/tokens';
 
<Tabs iconAlignment="top" orientation="horizontal">
  <TabLists>
    <TabTrigger value="tab 1">
      <CalendarEventMedium fill={SemanticColors['icon-decorative']} title="calendar event" />
      <span>Tab 1</span>
    </TabTrigger>
    <TabTrigger value="tab 2">Tab 2</TabTrigger>
    ...
  </TabLists>
</Tabs>;left: Aligns the icon to the left of the text. This should ideally be used with ‘small’ sized Icons
import { Tabs, TabLists, TabTrigger, TabContent } from '@camp/tabs';
import { CalendarEventSmall } from '@camp/icons';
import { SemanticColors } from '@camp/tokens';
 
<Tabs iconAlignment="left" orientation="horizontal">
  <TabLists>
    <TabTrigger value="tab 1">
      <CalendarEventSmall fill={SemanticColors['icon-decorative']} title="calendar event" />
      <span>Tab 1</span>
    </TabTrigger>
    <TabTrigger value="tab 2">Tab 2</TabTrigger>
    ...
  </TabLists>
</Tabs>;Disabled
The Tabs component can be used with disabled tabs.
To disable a specific Tab, simply pass the disabled prop to a TabTrigger.
import { Tabs, TabLists, TabTrigger } from '@camp/tabs';
 
<Tabs>
  <TabLists>
    ...
    <TabTrigger value="tab 2" disabled>
      Tab 2
    </TabTrigger>
  </TabLists>
</Tabs>;Best practices
Icon Usage
- Use icons sparingly to keep tabs from becoming too busy
 - Left icons (small size, 12px) should be used by default
 - Top icons (medium size, 16px) should only be used when the icon needs more prominence
 - Never use top icons in page header tabs
 - Icons are helpful when users may not understand the different categories being organized
 
Size Guidelines
- Small tabs (36px) are the default and should be used in most cases
 - Page headers should only use small tabs
 - Medium tabs (52px) can be used in modals where greater presence is needed
 - Use medium tabs sparingly compared to small tabs
 
General Guidelines
- Keep tab labels concise and descriptive
 - Limit the number of tabs to avoid overwhelming users
 - Ensure tab content is meaningful and distinct
 - Use consistent styling across all tabs in a set
 
Accessibility
per the official Radix documentation, the Tabs component is fully accessible, and adheres to the Tabs WAI-ARIA design pattern .
Keyboard support
tabto focus on the first tabtabagain to focus on tab content- Interactive elements (such as a link or button) within a tab will integrate into the tab order by default
 - When focused on first tab, 
leftorrightarrows to navigate between tabs 
The Tabs component keyboard interactions are identical to those of the Radix Tabs ‘Primitive’. Reference their official documentation around keyboard interactions for more details.