SectionTabs
SectionTabs is a navigation pattern for switching between content sections within the same page or view, without changing the overall page context.
Code example
import { SectionTabs, SectionTabList, SectionTab, SectionTabPanel } from '@yleisradio/yds-components-react';
<SectionTabs>
<SectionTabList>
<SectionTab index={0}>Tab 1</SectionTab>
<SectionTab index={1}>Tab 2</SectionTab>
<SectionTab index={2}>Tab 3</SectionTab>
</SectionTabList>
<SectionTabPanel index={0}>Content for Tab 1</SectionTabPanel>
<SectionTabPanel index={1}>Content for Tab 2</SectionTabPanel>
<SectionTabPanel index={2}>Content for Tab 3</SectionTabPanel>
</SectionTabs>
Why to use
SectionTabs helps organize large amounts of related content into clearly separated sections within the same view. It allows users to focus on one section at a time without navigating away or reloading the page, improving clarity and usability in content-dense layouts.
When to use
Use SectionTabs when users need to switch between different content sections within the same page or view, while staying in the same context.
- Use SectionTabs to divide complex or content-heavy views into logical sections.
- Use when switching tabs updates only part of the page, not the route or page context.
- Use when users need to compare or explore related content areas without leaving the view.
- Use when all tabs belong to the same conceptual level.
- Don’t use SectionTabs for page-level navigation — use NavigationTabs instead.
- Don’t use SectionTabs for filtering or state toggling — use ButtonGroup instead.
- Don’t use SectionTabs when options must stay visible at all times — use ButtonGroup.
- Don’t use too many tabs; consider other patterns if the list becomes long.
Differences between navigation components
| Component | Use case | Description |
|---|---|---|
| NavigationTabs | Navigation between pages or top-level views | Used when selecting a tab takes the user to a different page or changes the overall view context. Clearly communicates movement to a different “place” in the service. |
| SectionTabs | Switching content within the same page | Used to divide content within a single view into logical sections. Changing tabs does not change the route, only the visible content. |
| ButtonGroup | Filtering or toggling state | Used for filtering content or toggling between different states within the same context. Options remain visible at all times. |
Content Guidelines
SectionTab labels should clearly describe the content shown in the panel.
- Use short, descriptive labels (e.g., “Omat”, “Tulokset”).
- Keep labels parallel and at the same level of abstraction.
- Prefer nouns that describe content, not actions.
- The content of tab panels should be balanced in length and complexity.
- Don’t use long sentences or explanations as tab labels.
- Don’t mix unrelated content under the same tab set.
- Don’t use vague labels like “Muut” or “Sekalaista”.
Anatomy
- Tab list container – Wraps the row and controls alignment, padding, and scrolling.
- Tab – A single navigation destination.
- Selection indicator – Visual cue for the active tab.
- Label – The visible tab text.
Key SectionTabs Props
Use these props to configure the SectionTabs component.
defaultTab
Initial active tab index for uncontrolled component.
| Type | Example | Description |
|---|---|---|
number | Initial active tab index |
Code example
<SectionTabs defaultTab={1}>
<SectionTabList>
<SectionTab index={0}>Tab 1</SectionTab>
<SectionTab index={1}>Tab 2</SectionTab>
<SectionTab index={2}>Tab 3</SectionTab>
</SectionTabList>
<SectionTabPanel index={0}>Content for Tab 1</SectionTabPanel>
<SectionTabPanel index={1}>Content for Tab 2</SectionTabPanel>
<SectionTabPanel index={2}>Content for Tab 3</SectionTabPanel>
</SectionTabs>
tab
Current active tab index for controlled component.
| Type | Example | Description |
|---|---|---|
number | Controlled active tab index |
Code example
const [activeTab, setActiveTab] = useState(0);
<SectionTabs tab={activeTab} onTabChange={(e) => setActiveTab(e.currentTab)}>
<SectionTabList>
<SectionTab index={0}>Tab 1</SectionTab>
<SectionTab index={1}>Tab 2</SectionTab>
<SectionTab index={2}>Tab 3</SectionTab>
</SectionTabList>
<SectionTabPanel index={0}>Content for Tab 1</SectionTabPanel>
<SectionTabPanel index={1}>Content for Tab 2</SectionTabPanel>
<SectionTabPanel index={2}>Content for Tab 3</SectionTabPanel>
</SectionTabs>
onTabChange
Callback fired when the active tab changes.
| Type | Example | Description |
|---|---|---|
(event: TabChangeEvent) => void | Callback with tab change event |
Code example
<SectionTabs
onTabChange={(event) => {
console.log('Previous tab:', event.previousTab);
console.log('Current tab:', event.currentTab);
}}
>
<SectionTabList>
<SectionTab index={0}>Tab 1</SectionTab>
<SectionTab index={1}>Tab 2</SectionTab>
<SectionTab index={2}>Tab 3</SectionTab>
</SectionTabList>
<SectionTabPanel index={0}>Content for Tab 1</SectionTabPanel>
<SectionTabPanel index={1}>Content for Tab 2</SectionTabPanel>
<SectionTabPanel index={2}>Content for Tab 3</SectionTabPanel>
</SectionTabs>
Key SectionTabList Props
Use these props to configure the SectionTabList component.
enableTransitions
Controls whether transitions should be enabled.
| Type | Example | Description |
|---|---|---|
boolean | undefined | Content for Tab 1 | Controls transition behavior |
Code example
<SectionTabs>
<SectionTabList enableTransitions={false}>
<SectionTab index={0}>Tab 1</SectionTab>
<SectionTab index={1}>Tab 2</SectionTab>
<SectionTab index={2}>Tab 3</SectionTab>
</SectionTabList>
<SectionTabPanel index={0}>Content for Tab 1</SectionTabPanel>
<SectionTabPanel index={1}>Content for Tab 2</SectionTabPanel>
<SectionTabPanel index={2}>Content for Tab 3</SectionTabPanel>
</SectionTabs>
Key SectionTab Props
Use these props to configure the SectionTab component.
disabled
Whether the tab is disabled.
| Type | Example | Description |
|---|---|---|
boolean | Disables the tab |
Code example
<SectionTab index={0} disabled>Disabled Tab</SectionTab>
isActiveUncontrolled
Whether the tab should appear active regardless of parent state.
| Type | Example | Description |
|---|---|---|
boolean | Forces active appearance |
Code example
<SectionTab index={0} isActiveUncontrolled>Tab</SectionTab>
Key SectionTabPanel Props
Use these props to configure the SectionTabPanel component.
index
Index of the panel (0-based). Must match the corresponding tab index.
| Type | Example | Description |
|---|---|---|
number | Content for Tab 1 | Panel index for identification |
Code example
<SectionTabPanel index={0}>Content for Tab 1</SectionTabPanel>
<SectionTabPanel index={1}>Content for Tab 2</SectionTabPanel>
Behavior
- Only one tab panel is visible at a time.
- Selecting a tab updates the visible panel without changing the page context.
- Tabs are always rendered in a single horizontal row.
- Disabled tabs cannot be activated.
- Transitions can be enabled or disabled via SectionTabList.
- Height of the tab panel should not generally exceed the viewport height.
- Nested SectionTabs should be avoided.
Accessibility
- Tabs must be reachable and operable with a keyboard. (WCAG 2.1.1 — Keyboard)
API Reference
SectionTabs Props
The SectionTabs component accepts all standard HTML <div> attributes in addition to the following props:
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | React.ReactNode | Yes | — | SectionTabList and SectionTabPanel components |
defaultTab | number | No | 0 | Initial active tab index (uncontrolled) |
tab | number | No | — | Current active tab index (controlled) |
onTabChange | (event: TabChangeEvent) => void | No | — | Callback fired when tab changes |
SectionTabList Props
The SectionTabList component accepts all standard HTML <div> attributes in addition to the following props:
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | React.ReactNode | Yes | — | SectionTab components |
enableTransitions | boolean | undefined | No | undefined | Controls transition behavior (undefined = disabled on initial render, enabled afterwards) |
SectionTab Props
The SectionTab component accepts all standard HTML <button> attributes (except onClick) in addition to the following props:
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
index | number | Yes | — | Tab index (0-based) |
disabled | boolean | No | false | Whether the tab is disabled |
isActiveUncontrolled | boolean | No | false | Forces active appearance |
onClick | (index: number) => void | No | — | Callback fired when tab is clicked |
children | React.ReactNode | Yes | — | Tab content |
SectionTabPanel Props
The SectionTabPanel component accepts all standard HTML <div> attributes in addition to the following props:
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
index | number | Yes | — | Panel index (must match corresponding tab) |
children | React.ReactNode | Yes | — | Panel content |
Type Definitions
export interface TabChangeEvent {
previousTab: number;
currentTab: number;
}
export interface SectionTabsDSProps {
children: React.ReactNode;
defaultTab?: number;
tab?: number;
onTabChange?: (event: TabChangeEvent) => void;
}
export type SectionTabsProps = HTMLAttributes<HTMLDivElement> & SectionTabsDSProps;
export interface SectionTabListDSProps {
children: React.ReactNode;
enableTransitions?: boolean;
}
export type SectionTabListProps = HTMLAttributes<HTMLDivElement> & SectionTabListDSProps;
export interface SectionTabDSProps {
children: React.ReactNode;
index: number;
disabled?: boolean;
isActiveUncontrolled?: boolean;
onClick?: (index: number) => void;
}
export type SectionTabProps = Omit<HTMLAttributes<HTMLButtonElement>, 'onClick'> & SectionTabDSProps;
export interface SectionTabPanelDSProps {
children: React.ReactNode;
index: number;
}
export type SectionTabPanelProps = HTMLAttributes<HTMLDivElement> & SectionTabPanelDSProps;
Related Components
- NavigationTab – Alternative component for navigation tabs
- PageIndicator – For indicating current page/section