Tabs

A tabbed interface component for organizing content into separate panels

A tabbed interface component for organizing content into separate switchable panels.

When to use this

  • Content organization: Group related content into separate sections
  • Navigation: Switch between different views or categories
  • Settings panels: Organize settings into categorized tabs
  • Multi-step forms: Break complex forms into manageable sections

Basic implementation

Basic implementation
import 'package:flutter/material.dart';
import 'package:remix/remix.dart';

class TabsExample extends StatefulWidget {
  const TabsExample({super.key});

  @override
  State<TabsExample> createState() => _TabsExampleState();
}

class _TabsExampleState extends State<TabsExample> {
  String _tab = 'tab1';

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: 320,
      height: 280,
      child: RemixTabs(
        selectedTabId: _tab,
        onChanged: (id) => setState(() => _tab = id),
        child: Column(
          mainAxisSize: MainAxisSize.max,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            RemixTabBar(
              style: tabBarStyle,
              child: Row(
                mainAxisSize: MainAxisSize.max,
                children: [
                  RemixTab(tabId: 'tab1', style: tabStyle, label: 'Tab 1'),
                  const SizedBox(width: 8),
                  RemixTab(tabId: 'tab2', style: tabStyle, label: 'Tab 2'),
                ],
              ),
            ),
            const SizedBox(height: 8),
            Expanded(
              child: RemixTabView(
                tabId: 'tab1',
                style: tabViewStyle,
                child: const Text('Content for Tab 1'),
              ),
            ),
            Expanded(
              child: RemixTabView(
                tabId: 'tab2',
                style: tabViewStyle,
                child: const Text('Content for Tab 2'),
              ),
            ),
          ],
        ),
      ),
    );
  }

  RemixTabBarStyle get tabBarStyle {
    return RemixTabBarStyle()
        .paddingAll(4)
        .borderRounded(12)
        .color(const Color(0xFFF4F6FF))
        .borderAll(color: Colors.indigo.shade100);
  }

  RemixTabStyle get tabStyle {
    return RemixTabStyle()
        .paddingX(18)
        .paddingY(10)
        .borderRounded(10)
        .color(Colors.transparent)
        .labelFontSize(14)
        .labelFontWeight(FontWeight.w600)
        .labelColor(Colors.indigo.shade600)
        .iconColor(Colors.indigo.shade500)
        .onHovered(
          RemixTabStyle()
              .color(Colors.indigo.shade50)
              .labelColor(Colors.indigo.shade700),
        )
        .onSelected(
          RemixTabStyle()
              .color(Colors.white)
              .borderAll(color: Colors.indigo.shade400, width: 2)
              .labelColor(Colors.indigo.shade700)
              .iconColor(Colors.indigo.shade600),
        );
  }

  RemixTabViewStyle get tabViewStyle {
    return RemixTabViewStyle()
        .paddingAll(20)
        .borderRounded(14)
        .color(Colors.white)
        .borderAll(color: Colors.indigo.shade100);
  }
}

Fortal styles

Remix includes Fortal-themed style helpers for this component:

Fortal base style
import 'package:flutter/material.dart';
import 'package:remix/remix.dart';

class FortalTabsExample extends StatefulWidget {
  const FortalTabsExample({super.key});

  @override
  State<FortalTabsExample> createState() => _FortalTabsExampleState();
}

class _FortalTabsExampleState extends State<FortalTabsExample> {
  String _tab = 'tab1';

  @override
  Widget build(BuildContext context) {
    return RemixTabs(
      selectedTabId: _tab,
      onChanged: (id) => setState(() => _tab = id),
      child: Column(
        children: [
          RemixTabBar(
            style: FortalTabBarStyle.base(),
            child: Row(
              children: [
                RemixTab(tabId: 'tab1', label: 'Tab 1', style: FortalTabStyle.base()),
                RemixTab(tabId: 'tab2', label: 'Tab 2', style: FortalTabStyle.base()),
              ],
            ),
          ),
          RemixTabView(tabId: 'tab1', style: FortalTabViewStyle.base(), child: Text('Content 1')),
          RemixTabView(tabId: 'tab2', style: FortalTabViewStyle.base(), child: Text('Content 2')),
        ],
      ),
    );
  }
}

See the FortalTabsStyle source code for all available options.

Constructor

Constructor
// Tabs Container
const RemixTabs({
  Key? key,
  required String selectedTabId,
  required ValueChanged<String> onChanged,
  required Widget child,
})

// Tab Bar
const RemixTabBar({
  Key? key,
  required Widget child,
  RemixTabBarStyle style = const RemixTabBarStyle.create(),
  RemixTabBarSpec? styleSpec,
})

// Individual Tab
const RemixTab({
  Key? key,
  required String tabId,
  String? label,
  IconData? icon,
  RemixTabStyle style = const RemixTabStyle.create(),
  RemixTabSpec? styleSpec,
})

// Tab View
const RemixTabView({
  Key? key,
  required String tabId,
  required Widget child,
  RemixTabViewStyle style = const RemixTabViewStyle.create(),
  RemixTabViewSpec? styleSpec,
})

Properties

Widget Properties

keyKey?

Optional. Controls how one widget replaces another widget in the tree.

childWidget

Required. The tabs content.

controllerNakedTabController?

Optional. Optional controller for managing tab state.

selectedTabIdString?

Optional. The identifier of the currently selected tab.

onChangedValueChanged<String>?

Optional. Called when the selected tab changes.

orientationAxis

Optional. The tab list orientation.

enabledbool

Optional. Whether the tabs are enabled.

onEscapePressedVoidCallback?

Optional. Called when Escape is pressed while a tab has focus.

Style Methods

alignment(Alignment value)

Sets container alignment

container(FlexBoxStyler value)

label(TextStyler value)

icon(IconStyler value)

animate(AnimationConfig animation)

wrap(WidgetModifierConfig value)

flex(FlexStyler value)

foregroundDecoration(DecorationMix value)

transform(Matrix4 value, AlignmentGeometry alignment = Alignment.center)

color(Color value)

constraints(BoxConstraintsMix value)

decoration(DecorationMix value)

margin(EdgeInsetsGeometryMix value)

padding(EdgeInsetsGeometryMix value)

labelTextStyle(TextStyleMix value)

Sets label/text style using TextStyleMix directly

labelColor(Color value)

Sets label/text color

labelFontSize(double value)

Sets label/text font size

labelFontWeight(FontWeight value)

Sets label/text font weight

labelFontStyle(FontStyle value)

Sets label/text font style (italic/normal)

labelLetterSpacing(double value)

Sets label/text letter spacing

labelDecoration(TextDecoration value)

Sets label/text decoration (underline, strikethrough, etc.)

labelFontFamily(String value)

Sets label/text font family

labelHeight(double value)

Sets label/text line height

labelWordSpacing(double value)

Sets label/text word spacing

labelDecorationColor(Color value)

Sets label/text decoration color

iconColor(Color value)

Sets icon color

iconSize(double value)

Sets icon size

iconOpacity(double value)

Sets icon opacity

iconWeight(double value)

Sets icon weight (useful for variable icons like Material Symbols)

iconGrade(double value)

Sets icon grade (useful for Material Icons)

iconFill(double value)

Sets icon fill (useful for Material Icons filled variants)

iconOpticalSize(double value)

Sets icon optical size (useful for Material Icons)

iconBlendMode(BlendMode value)

Sets icon blend mode

iconTextDirection(TextDirection value)

Sets icon text direction

iconShadows(List<ShadowMix> value)

Sets icon shadows

iconShadow(ShadowMix value)

Sets single icon shadow