Tabs

Tabs is the peer-section switcher for one screen region.
Use it when several sections belong to the same level of navigation and users should move between them without leaving the current screen. Tabs work best when the number of choices is small and each tab represents a clear slice of the same feature area.

Example

use fission::prelude::*;

let widget: Widget = Tabs {
    active_index: view.state().active_settings_tab,
    items: vec![
        TabItem {
            title: "General".into(),
            content: general_settings_node,
            on_press: Some(select_general_tab_action),
        },
        TabItem {
            title: "Security".into(),
            content: security_settings_node,
            on_press: Some(select_security_tab_action),
        },
    ],
}
.into();

Field table

Field
Type
Meaning
Notes / default behavior
active_index
usize
Which tab is currently selected.
Controlled by app state.
items
Vec<TabItem>
Tab definitions in display order.
Defaults to an empty list.

State ownership and rendering behavior

Tabs does not own selection state. Each tab button emits its own on_press action, and the reducer updates active_index. The checked-in widget renders only the active tab's content below the tab bar.
This is an important architectural choice. Even though tabs feel interactive, they still follow the same explicit state loop as the rest of Fission.

Specific advice

Keep tab counts small. If the bar starts wrapping, scrolling, or forcing cryptic labels, the information architecture usually wants a different pattern.

Production checklist

For Tabs, review the fields that change behavior before treating the widget as finished: active_index, items. The goal is to make the product rule visible in state and actions, not hidden inside ad-hoc construction code.
If this widget appears inside an interactive flow, keep the surrounding action binding in the parent component and test that the flow still has one clear reducer path.
When child widgets are generated from data, give reordered or filtered rows an explicit WidgetId so retained local state and scroll behavior do not drift between items.
Check the semantics tree for the user-facing label or role that makes this widget understandable without relying only on pixels.
Add at least one component or harness test that confirms the visible text, semantic role, action dispatch, and layout constraint that matter for this widget in context.
If a screen starts repeating the same Tabs setup, extract a named component around this widget. That keeps the reference API small while making product code easier to read and safer for generated code to copy.
TabItem, SegmentedControl, Accordion, and Breadcrumb.
Fission
A cross-platform, GPU-accelerated user interface framework for Rust. MIT licensed.
Copyright (c) 2026 Fission
Ready to use today. Widget APIs are expected to remain stable; some runtime and shell APIs may change before 1.0.0.
Fission 0.7.0