Skip to content

Tabs

Tabs renders a controlled tab list.

Tabs(
{
TabItem("Overview"),
TabItem(app::images::activity, "Activity"),
TabItem("Reports").Enabled(false),
},
selected
).OnChanged([selected](std::size_t index) {
selected = index;
})

Simple constructors accept string labels. TabItem adds raster or vector icons, icon-only presentation with a required semantic label, and per-item enabled state.

The selected index is controlled and must identify an item. OnChanged requests a new index; use that state to choose the corresponding page content.

Column {
Tabs({"Files", "Search", "History"}, selected)
.OnChanged([selected](std::size_t index) {
selected = index;
}),
selected == 0 ? FilesPage() : selected == 1 ? SearchPage() : HistoryPage(),
}

TabsStyle controls label states, icons, item geometry, optional equal expansion, divider, indicator color and sizing, and indicator motion. TabIndicatorSizing::Item follows the item; Content can produce a shorter content-width indicator.

Tabs expose tab-list, tab, selected, disabled, focus, and activation semantics.

  • Constructors: label lists or std::vector<TabItem>, followed by index or State<std::size_t>.
  • TabItem: label, icon plus label, IconOnly, and .Enabled(bool).
  • Event: .OnChanged(function) with std::size_t.
  • Theme style: TabsStyle and TabIndicatorSizing.

The constructor owns its item declarations, not the pages they describe. Label collections accept an initializer list or vector of StringVariant; richer collections accept a vector of TabItem. Both take an index or const State<std::size_t>&. TabItem::IconOnly(ImageVariant, StringVariant) keeps an accessible label without visible text. Enabled(false) belongs to one item; Enabled(false) on the Tabs view disables the entire control.

TabsStyle fields Use
background, label_style, selected_label, disabled_label Surface and text states.
item_padding, minimum_item_width, minimum_height Item sizing within parent constraints.
icon_size, icon_spacing Icon dimensions and distance to label.
expand_items Share available width between items instead of using their content widths.
indicator, indicator_sizing, indicator_min_width Indicator color and horizontal extent.
indicator_height, indicator_corner_radius Indicator thickness and rounding.
divider_color, divider_height Baseline under the tabs.
indication, indicator_animation_duration Interaction feedback and indicator transition time in seconds.

A short Material-style indicator uses Content; changing the whole tab width is not necessary. A Frame controls the list’s layout allocation, while the style controls the indicator inside that allocation. Copy the inherited style before changing a field so light/dark colors and unrelated theme choices survive; see style overrides.

Conditional content in the example replaces the inactive page. Use IndexedPages with the same selected index to retain page scopes, or Pager to add a swipe gesture. In the Pager case, handle both components’ OnChanged events by writing the same authoritative State. Tabs neither mounts pages nor pushes navigation history by itself.