# TabbedChipsAlpha
A chip component commonly used in filter context to refine a date source
## Import
```tsx
import { TabbedChips } from '@coinbase/cds-web/alpha/tabbed-chips/TabbedChips'
```
## Examples
### Basic usage
```jsx live
function ExampleDefault() {
const tabs = [
{ id: 'all', label: 'All' },
{ id: 'swap', label: 'Swap' },
{ id: 'collect', label: 'Collect' },
{ id: 'bridge', label: 'Bridge' },
];
const [activeTab, setActiveTab] = useState(tabs[0]);
return ;
}
```
### Compact
```jsx live
function ExampleCompactNoStart() {
const tabs = [
{ id: 'all', label: 'All' },
{ id: 'swap', label: 'Swap' },
{ id: 'collect', label: 'Collect' },
{ id: 'bridge', label: 'Bridge' },
];
const [activeTab, setActiveTab] = useState(tabs[0]);
return ;
}
```
### Many tabs (paddles)
:::tip Paddles & overflow
Paddles appear automatically when the tab list overflows.
:::
```jsx live
function ExampleWithPaddles() {
const tabs = Array.from({ length: 12 }).map((_, i) => ({
id: `tab_${i + 1}`,
label: `Tab ${i + 1}`,
}));
const [activeTab, setActiveTab] = useState(tabs[0]);
return ;
}
```
### With custom sized paddles
:::tip Paddle styling
You can adjust the size of the paddles via `styles.paddle`.
:::
```jsx live
function ExampleCustomPaddles() {
const tabs = Array.from({ length: 10 }).map((_, i) => ({
id: `t_${i + 1}`,
label: `Item ${i + 1}`,
}));
const [activeTab, setActiveTab] = useState(tabs[0]);
return (
);
}
```
### Long text tabs
```jsx live
function ExampleLongText() {
const tabs = [
{ id: 'a', label: 'Very long tab label that can wrap on small widths' },
{ id: 'b', label: 'Another extra long label to test overflow' },
{ id: 'c', label: 'Short' },
];
const [activeTab, setActiveTab] = useState(tabs[0]);
return ;
}
```
### Disabled tab
```jsx live
function ExampleDisabled() {
const tabs = [
{ id: 'first', label: 'First' },
{ id: 'second', label: 'Second', disabled: true },
{ id: 'third', label: 'Third' },
];
const [activeTab, setActiveTab] = useState(tabs[0]);
return ;
}
```
### With start media
:::tip Media sizing
For start media, use circular images sized 24×24 for regular chips and 16×16 for compact chips.
:::
```jsx live
function ExampleWithStart() {
const icon = { height: 24, width: 24, shape: 'circle', source: assets.eth.imageUrl };
const compactIcon = { height: 16, width: 16, shape: 'circle', source: assets.eth.imageUrl };
const tabs = [
{ id: 'all', label: 'All', start: },
{ id: 'swap', label: 'Swap', start: },
{ id: 'collect', label: 'Collect', start: },
{ id: 'bridge', label: 'Bridge', start: },
];
const compactTabs = tabs.map((tab) => ({ ...tab, start: }));
const [activeTab, setActiveTab] = useState(tabs[0]);
return (
);
}
```
### Custom TabComponent
:::tip Custom Tab behavior
When providing a custom TabComponent, use `useTabsContext()` and call `updateActiveTab(id)` to update selection state. Reflect the active state (e.g., end icon state) based on `activeTab?.id === id`.
:::
```jsx live noInline
function CustomTab({ id, label, ...props }: TabbedChipProps) {
const { activeTab, updateActiveTab } = useTabsContext();
const isActive = activeTab?.id === id;
return (
}
onClick={() => updateActiveTab(id)}
{...props}
>
{label}
);
}
const tabs = [
{ id: 'all', label: 'All' },
{ id: 'swap', label: 'Swap' },
{ id: 'collect', label: 'Collect' },
];
function Example() {
const [activeTab, setActiveTab] = useState(tabs[0]);
return (
);
}
render();
```
## Props
| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `activeTab` | `TabValue \| null` | Yes | `-` | React state for the currently active tab. Setting it to null results in no active tab. |
| `onChange` | `(activeTab: TabValue \| null) => void` | Yes | `-` | Callback that is fired when the active tab changes. Use this callback to update the activeTab state. |
| `tabs` | `TabbedChipProps[]` | Yes | `-` | - |
| `TabComponent` | `FC>` | No | `-` | - |
| `TabsActiveIndicatorComponent` | `TabsActiveIndicatorComponent` | No | `-` | - |
| `background` | `currentColor \| fg \| fgMuted \| fgInverse \| fgPrimary \| fgWarning \| fgPositive \| fgNegative \| bg \| bgAlternate \| bgInverse \| bgOverlay \| bgElevation1 \| bgElevation2 \| bgPrimary \| bgPrimaryWash \| bgSecondary \| bgTertiary \| bgSecondaryWash \| bgNegative \| bgNegativeWash \| bgPositive \| bgPositiveWash \| bgWarning \| bgWarningWash \| bgLine \| bgLineHeavy \| bgLineInverse \| bgLinePrimary \| bgLinePrimarySubtle \| accentSubtleRed \| accentBoldRed \| accentSubtleGreen \| accentBoldGreen \| accentSubtleBlue \| accentBoldBlue \| accentSubtlePurple \| accentBoldPurple \| accentSubtleYellow \| accentBoldYellow \| accentSubtleGray \| accentBoldGray \| transparent` | No | `-` | - |
| `classNames` | `{ root?: string; scrollContainer?: string \| undefined; tabs?: string \| undefined; } \| undefined` | No | `-` | - |
| `compact` | `boolean` | No | `false` | Turn on to use a compact Chip component for each tab. |
| `disabled` | `boolean` | No | `-` | Disable interactions on all the tabs. |
| `gap` | `0 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9` | No | `1` | The spacing between Tabs |
| `nextArrowAccessibilityLabel` | `string` | No | `-` | - |
| `previousArrowAccessibilityLabel` | `string` | No | `-` | - |
| `ref` | `null \| (instance: HTMLElement \| null) => void \| MutableRefObject` | No | `-` | - |
| `styles` | `{ root?: CSSProperties; scrollContainer?: CSSProperties \| undefined; paddle?: CSSProperties \| undefined; tabs?: CSSProperties \| undefined; } \| undefined` | No | `-` | - |
| `testID` | `string` | No | `-` | Used to locate this element in unit and end-to-end tests. Under the hood, testID translates to data-testid on Web. On Mobile, testID stays the same - testID |
| `width` | `ResponsiveProp>` | No | `100%` | The width of the scroll container, defaults to 100% of the parent container If the tabs are wider than the width of the container, paddles will be shown to scroll the tabs. |