GlassTabBar class

The iOS 26 structural bottom navigation bar.

Two named constructors cover the two UITabBarController use-cases:

  • GlassTabBar.bottom — floating pill at the screen bottom with safe area handling, jelly physics, and optional extra action button. Replaces the legacy GlassBottomBar.

  • GlassTabBar.searchable — bottom pill that morphs into a search bar. Replaces the legacy GlassSearchableBottomBar.

  • GlassTabBar.minimizable — the searchable placement's morph without the search: the tab pill minimizes to the selected tab's circle (typically on scroll), mirroring SwiftUI's tabBarMinimizeBehavior, with an optional plain GlassTabBarTrailingButton in the slot the search pill occupies — the generalized Tab(role: .search) trailing circle, for bars whose trailing affordance is an action rather than a search field.

For in-page / inline tab switching, use GlassSegmentedControl instead.

Migration from v0.x

// BEFORE
GlassBottomBar(tabs: [...], ...)
GlassSearchableBottomBar(tabs: [...], searchConfig: ..., ...)

// AFTER
GlassTabBar.bottom(tabs: [...], ...)
GlassTabBar.searchable(tabs: [...], searchConfig: ..., ...)
Inheritance
Implemented types
Available extensions

Constructors

GlassTabBar.bottom({required List<GlassTab> tabs, required int selectedIndex, required ValueChanged<int> onTabSelected, Key? key, GlassTabBarExtraButton? extraButton, ScrollController? scrollController, Widget? bottomAccessory, bool bottomAccessoryEnabled = true, double bottomAccessorySpacing = 6.0, double? bottomAccessoryHeight, double spacing = 8, double horizontalPadding = 20, double verticalPadding = 20, double barHeight = 64, double barBorderRadius = _kDefaultBottomBorderRadius, EdgeInsetsGeometry tabPadding = const EdgeInsets.symmetric(horizontal: 4), double iconLabelSpacing = 4, bool enableBlend = true, bool groupBackdrop = true, double blendAmount = 10, LiquidGlassSettings? settings, bool showIndicator = true, Color? indicatorColor, LiquidGlassSettings? indicatorSettings, double indicatorPinchStrength = 0.4, Color? selectedIconColor, Color? unselectedIconColor, Color? selectedLabelColor, Color? unselectedLabelColor, TextStyle? selectedLabelStyle, TextStyle? unselectedLabelStyle, double iconSize = 24, double labelFontSize = 11, TextStyle? textStyle, Duration glowDuration = const Duration(milliseconds: 300), double glowBlurRadius = 32, double glowSpreadRadius = 8, double glowOpacity = 0.6, GlassQuality? quality, GlassQuality? backgroundQuality, double magnification = 1.15, double innerBlur = 0.0, MaskingQuality maskingQuality = MaskingQuality.high, GlobalKey<State<StatefulWidget>>? backgroundKey, double? tabWidth, double? indicatorBorderRadius, EdgeInsetsGeometry indicatorExpansion = const EdgeInsets.symmetric(horizontal: 12, vertical: 8), Color? interactionGlowColor, double? interactionGlowRadius, GlassInteractionBehavior interactionBehavior = GlassInteractionBehavior.full, double pressScale = 1.04, bool platformViewBackdrop = false, bool adaptiveBrightness = false, ValueChanged<Brightness>? onBrightnessChanged, ValueListenable<Brightness>? brightnessOverride})
Creates a floating bottom tab bar — the iOS 26 UITabBarController equivalent.
const
GlassTabBar.inline({required List<GlassTab> tabs, required int selectedIndex, required ValueChanged<int> onTabSelected, Key? key, double horizontalPadding = 0, double verticalPadding = 0, double barHeight = 40, double barBorderRadius = 100, double labelFontSize = 13, double iconSize = 18, EdgeInsetsGeometry tabPadding = const EdgeInsets.symmetric(horizontal: 8), EdgeInsetsGeometry indicatorExpansion = const EdgeInsets.symmetric(horizontal: 12, vertical: 10), double magnification = 1.0, double innerBlur = 0.0, double spacing = 4, double blendAmount = 10, bool enableBlend = true, bool groupBackdrop = true, bool showIndicator = true, Color? indicatorColor, LiquidGlassSettings? indicatorSettings, double indicatorPinchStrength = 0.4, double? indicatorBorderRadius, Color? selectedIconColor, Color? unselectedIconColor, Color? selectedLabelColor, Color? unselectedLabelColor, TextStyle? selectedLabelStyle, TextStyle? unselectedLabelStyle, TextStyle? textStyle, double? tabWidth, LiquidGlassSettings? settings, GlassQuality? quality, GlassQuality? backgroundQuality, MaskingQuality maskingQuality = MaskingQuality.high, GlobalKey<State<StatefulWidget>>? backgroundKey, double iconLabelSpacing = 4, Duration glowDuration = const Duration(milliseconds: 300), double glowBlurRadius = 20, double glowSpreadRadius = 4, double glowOpacity = 0.5, GlassInteractionBehavior interactionBehavior = GlassInteractionBehavior.full, double pressScale = 1.02, Color? interactionGlowColor, double? interactionGlowRadius, bool platformViewBackdrop = false, bool adaptiveBrightness = false, ValueChanged<Brightness>? onBrightnessChanged, ValueListenable<Brightness>? brightnessOverride, SpringDescription? springDescription})
Creates a compact, in-page glass tab bar with a refracting glass track.
const
GlassTabBar.minimizable({required List<GlassTab> tabs, required int selectedIndex, required ValueChanged<int> onTabSelected, Key? key, bool minimized = false, GlassTabBarMinimizeController? minimizeController, VoidCallback? onMinimizedTabTap, GlassTabBarTrailingButton? trailingButton, GlassTabBarExtraButton? extraButton, Widget? bottomAccessory, GlassTabBarAccessoryPlacement? bottomAccessoryPlacement, bool bottomAccessoryEnabled = true, double bottomAccessorySpacing = 6.0, double? bottomAccessoryHeight, double spacing = 8, double horizontalPadding = 20, double verticalPadding = 20, double barHeight = 64, double minimizedBarHeight = 50, double barBorderRadius = _kDefaultBottomBorderRadius, EdgeInsetsGeometry tabPadding = const EdgeInsets.symmetric(horizontal: 4), double iconLabelSpacing = 4, bool enableBlend = true, bool groupBackdrop = true, double blendAmount = 10, LiquidGlassSettings? settings, bool showIndicator = true, Color? indicatorColor, LiquidGlassSettings? indicatorSettings, double indicatorPinchStrength = 0.4, Color? selectedIconColor, Color? unselectedIconColor, Color? selectedLabelColor, Color? unselectedLabelColor, TextStyle? selectedLabelStyle, TextStyle? unselectedLabelStyle, double iconSize = 24, double labelFontSize = 11, TextStyle? textStyle, Duration glowDuration = const Duration(milliseconds: 300), double glowBlurRadius = 32, double glowSpreadRadius = 8, double glowOpacity = 0.6, GlassInteractionBehavior interactionBehavior = GlassInteractionBehavior.full, double? pressScale, Color? interactionGlowColor, double? interactionGlowRadius, GlassQuality? quality, GlassQuality? backgroundQuality, double magnification = 1.15, double innerBlur = 0.0, bool platformViewBackdrop = false, bool passthroughOverPlatformView = false, MaskingQuality maskingQuality = MaskingQuality.high, GlobalKey<State<StatefulWidget>>? backgroundKey, SpringDescription? springDescription, GlassTabPillAnchor tabPillAnchor = GlassTabPillAnchor.start, double? tabWidth, double? indicatorBorderRadius, EdgeInsetsGeometry indicatorExpansion = const EdgeInsets.symmetric(horizontal: 12, vertical: 8), VoidCallback? onBarTap, bool whitenAtBottom = true, double whitenBottomThreshold = 45.0, double whitenAtBottomTarget = 1.0, ScrollController? scrollController, bool adaptiveBrightness = false, ValueChanged<Brightness>? onBrightnessChanged, ValueListenable<Brightness>? brightnessOverride})
Creates a bottom bar that minimizes to the selected tab's circle — SwiftUI's tabBarMinimizeBehavior, i.e. the GlassTabBar.searchable morph without the search.
const
GlassTabBar.searchable({required List<GlassTab> tabs, required int selectedIndex, required ValueChanged<int> onTabSelected, required GlassSearchBarConfig searchConfig, Key? key, SearchableBottomBarController? controller, bool isSearchActive = false, GlassTabBarExtraButton? extraButton, GlassTabBarAccessoryPlacement? bottomAccessoryPlacement, Widget? bottomAccessory, bool bottomAccessoryEnabled = true, double bottomAccessorySpacing = 6.0, double? bottomAccessoryHeight, double spacing = 8, double horizontalPadding = 20, double verticalPadding = 20, double barHeight = 64, double searchBarHeight = 50, double barBorderRadius = _kDefaultBottomBorderRadius, EdgeInsetsGeometry tabPadding = const EdgeInsets.symmetric(horizontal: 4), double iconLabelSpacing = 4, bool enableBlend = true, bool groupBackdrop = true, double blendAmount = 10, LiquidGlassSettings? settings, bool showIndicator = true, Color? indicatorColor, LiquidGlassSettings? indicatorSettings, double indicatorPinchStrength = 0.4, Color? selectedIconColor, Color? unselectedIconColor, Color? selectedLabelColor, Color? unselectedLabelColor, TextStyle? selectedLabelStyle, TextStyle? unselectedLabelStyle, double iconSize = 24, double labelFontSize = 11, TextStyle? textStyle, Duration glowDuration = const Duration(milliseconds: 300), double glowBlurRadius = 32, double glowSpreadRadius = 8, double glowOpacity = 0.6, GlassInteractionBehavior interactionBehavior = GlassInteractionBehavior.full, double? pressScale, Color? interactionGlowColor, double? interactionGlowRadius, GlassQuality? quality, GlassQuality? backgroundQuality, double magnification = 1.15, double innerBlur = 0.0, bool platformViewBackdrop = false, bool passthroughOverPlatformView = false, MaskingQuality maskingQuality = MaskingQuality.high, GlobalKey<State<StatefulWidget>>? backgroundKey, SpringDescription? springDescription, GlassTabPillAnchor tabPillAnchor = GlassTabPillAnchor.start, double? tabWidth, double? indicatorBorderRadius, EdgeInsetsGeometry indicatorExpansion = const EdgeInsets.symmetric(horizontal: 12, vertical: 8), VoidCallback? onBarTap, bool whitenAtBottom = true, double whitenBottomThreshold = 45.0, double whitenAtBottomTarget = 1.0, ScrollController? scrollController, bool adaptiveBrightness = false, ValueChanged<Brightness>? onBrightnessChanged, ValueListenable<Brightness>? brightnessOverride})
Creates a bottom bar with a morphing search pill.
const

Properties

adaptiveBrightness → bool
Adapts brightness to content scrolling underneath. Defaults to false.
final
backgroundKey → GlobalKey<State<StatefulWidget>>?
Optional background key for Skia/Web refraction.
final
backgroundQuality → GlassQuality?
Rendering quality for the tab bar track/background container.
final
barBorderRadius → double
Corner radius of the pill (bottom/searchable). Defaults to 32.
final
barHeight → double
Height of the pill (bottom/searchable). Defaults to 64.
final
blendAmount → double
Blend amount for the shared glass layer. Defaults to 10.
final
bottomAccessory → Widget?
The accessory widget rendered above (expanded) or beside (inline) the tab bar pill. Typically a mini-player or contextual action row.
final
bottomAccessoryEnabled → bool
Controls whether the bottomAccessory is shown.
final
bottomAccessoryHeight → double?
The known height of the bottomAccessory.
final
bottomAccessoryPlacement → GlassTabBarAccessoryPlacement?
The widget to display above the tab bar pill (e.g. a mini-player).
final
bottomAccessorySpacing → double
Vertical gap between the bottomAccessory and the glass tab bar.
final
brightnessOverride → ValueListenable<Brightness>?
External brightness source that bypasses the content sampler.
final
controller → SearchableBottomBarController?
Optional external controller for the search state machine.
final
enableBlend → bool
Enables organic liquid blending between adjacent pills. Defaults to true.
final
extraButton → GlassTabBarExtraButton?
Optional extra action button (bottom/searchable only).
final
followsVerticalBar → bool
Whether this bar moves into iPhone Duo's vertical bar strip where a GlassNavigationShell has resolved one (GlassVerticalBar.maybeOf).
no setter
glowBlurRadius → double
Blur radius of the tab glow effect. Defaults to 32.
final
glowDuration → Duration
Duration of the per-tab glow animation. Defaults to 300 ms.
final
glowOpacity → double
Opacity of the tab glow effect. Defaults to 0.6.
final
glowSpreadRadius → double
Spread radius of the tab glow effect. Defaults to 8.
final
groupBackdrop → bool
Whether the bar's glass reads the backdrop together, in one GlassBackdropGroup: the pill, the search and minimize pills. The selected-tab indicator lies over the pill and stays out of it, and so do the search pill while the keyboard moves it, the searchable bar's extra button (it fades out when search opens) and the bottom accessory. On Impeller with premium glass this saves a full-screen backdrop copy per surface. Inside a GlassBackdropGroup of your own the bar joins that group, so one group around an app bar and a tab bar makes them share a single read. Defaults to true; set false to keep the bar out of any group, e.g. when glass of your own lies over it.
final
hashCode → int
The hash code for this object.
no setterinherited
horizontalPadding → double
Horizontal padding around the full bar content. Defaults to 20.
final
iconLabelSpacing → double
Vertical spacing between icon and label. Defaults to 4.
final
iconSize → double
Size of the icons.
final
indicatorBorderRadius → double?
Override border radius for the indicator. Null = inherits from barBorderRadius.
final
indicatorColor → Color?
Color of the pill indicator.
final
indicatorExpansion → EdgeInsetsGeometry
Expansion padding applied to the active indicator pill during interaction.
final
indicatorPinchStrength → double
Maximum concave lens pinch strength for the sliding indicator pill.
final
indicatorSettings → LiquidGlassSettings?
Glass settings for the sliding indicator.
final
innerBlur → double
Blur applied to content inside the indicator (bottom/searchable).
final
interactionBehavior → GlassInteractionBehavior
Which physical interaction effects are active. Defaults to GlassInteractionBehavior.full.
final
interactionGlowColor → Color?
Directional glow color on press. Null = theme default.
final
interactionGlowRadius → double?
Spread radius of the directional glow. Defaults to 1.5. Radius of the interaction glow, as a fraction of the layer's shortest side.
final
isSearchActive → bool
Whether the search bar is currently expanded (searchable only). For GlassTabBar.minimizable this carries minimized, which drives the identical morph.
final
key → Key?
Controls how one widget replaces another widget in the tree.
finalinherited
labelFontSize → double
Font size for tab labels (bottom/searchable). Defaults to 11.
final
magnification → double
Selected-icon magnification inside the indicator (bottom/searchable).
final
maskingQuality → MaskingQuality
Controls indicator clipping quality.
final
minimizeController → GlassTabBarMinimizeController?
Drives minimized from scrolling on the minimizable placement — the equivalent of SwiftUI's .tabBarMinimizeBehavior(_:).
final
onBarTap → VoidCallback?
Optional tap callback for the whole bar (searchable only).
final
onBrightnessChanged → ValueChanged<Brightness>?
Called when the content-aware brightness verdict flips.
final
onMinimizedTabTap → VoidCallback?
Tapping the minimized tab circle (minimizable only) — the "bring my tabs back" control.
final
onTabSelected → ValueChanged<int>
Called when a tab is selected.
final
passthroughOverPlatformView → bool
Lifts the selected tab's content above the indicator's glass over a platform view, for the searchable and minimizable placements.
final
platformViewBackdrop → bool
Forces BackdropFilter rendering over iOS PlatformViews. Defaults to false.
final
preferredSize → Size
The size this widget would prefer if it were otherwise unconstrained.
no setteroverride
preferredSizeListenable → Listenable?
The bar only changes height on its own when a minimize controller drives it — otherwise the size follows the widget's own props and the scaffold re-reads it on the rebuild that changed them.
no setter
pressScale → double?
Peak scale applied at maximum press depth.
final
quality → GlassQuality?
Rendering quality for the glass effect.
final
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited
scrollController → ScrollController?
Scroll controller wired for searchable whitening and bottom-bar collapse.
final
searchBarHeight → double
Height of the pills while search is active. Defaults to 50.
final
searchConfig → GlassSearchBarConfig?
Configuration for the morphing search bar. Required for GlassTabBar.searchable.
final
selectedIconColor → Color?
Icon color for selected tab.
final
selectedIndex → int
Index of the currently selected tab.
final
selectedLabelColor → Color?
Label color for selected tab.
final
selectedLabelStyle → TextStyle?
Per-state label text style, merged over the base label style — overrides font / weight / letter-spacing while keeping the resolved label color unless the style sets its own. Null leaves existing behavior unchanged.
final
settings → LiquidGlassSettings?
Glass effect settings.
final
showIndicator → bool
Whether to show the draggable indicator. Defaults to true.
final
spacing → double
Spacing between adjacent pills (bottom/searchable only). Defaults to 8.
final
springDescription → SpringDescription?
Custom spring for the pill morph animation. Null = iOS 26 default.
final
tabPadding → EdgeInsetsGeometry
Internal padding within the tab pill. Defaults to 4 px horizontal.
final
tabPillAnchor → GlassTabPillAnchor
How the tab pill is anchored during the morph animation.
final
tabs → List<GlassTab>
List of tabs to display.
final
tabWidth → double?
Fixed width per tab slot. Null = fill all available space.
final
textStyle → TextStyle?
Text style for tab labels (bottom/searchable). Overrides labelFontSize.
final
trailingButton → GlassTabBarTrailingButton?
The optional plain action button in the trailing slot (minimizable only). Null means no trailing pill at all, in either state.
final
unselectedIconColor → Color?
Icon color for unselected tabs.
final
unselectedLabelColor → Color?
Label color for unselected tabs.
final
unselectedLabelStyle → TextStyle?
See selectedLabelStyle.
final
verticalPadding → double
Vertical padding (top + bottom) around the bar content. Defaults to 20.
final
whitenAtBottom → bool
Whiten glass at page bottom in light mode. Defaults to true.
final
whitenAtBottomTarget → double
Maximum whitening amount. Defaults to 1.0.
final
whitenBottomThreshold → double
Scroll offset at which whitening begins. Defaults to 45.0.
final

Methods

createElement() → StatefulElement
Creates a StatefulElement to manage this widget's location in the tree.
inherited
createState() → State<GlassTabBar>
Creates the mutable state for this widget at a given location in the tree.
override
debugDescribeChildren() → List<DiagnosticsNode>
Returns a list of DiagnosticsNode objects describing this node's children.
inherited
debugFillProperties(DiagnosticPropertiesBuilder properties) → void
Add additional properties associated with the node.
inherited
glassContextMenu({Key? key, required List<Widget> actions, WidgetBuilder? previewBuilder, bool enabled = true, bool enableHaptics = true, double borderRadius = 32.0, double? previewBorderRadius, double rowBorderRadius = 16.0, BorderRadius? rowCorners, Color? originSlotColor, Color? backgroundColor, LiquidGlassSettings? settings, GlassQuality? quality, double backdropBlur = 0.0, Color? barrierColor, double menuWidth = 250.0, VoidCallback? onOpened, VoidCallback? onDismissed, Duration longPressDuration = const Duration(milliseconds: 700)}) → Widget

Available on Widget, provided by the GlassContextMenuExtension extension

Wraps this widget in a GlassContextMenu displaying actions on long-press or right-click.
glassFullScreenCover({required bool isPresented, VoidCallback? onDismiss, required WidgetBuilder content, bool enableSwipeToDismiss = true, double dismissThreshold = 140.0, LiquidGlassSettings? settings, GlassQuality? quality}) → Widget

Available on Widget, provided by the GlassFullScreenCoverExtension extension

Presents a full-viewport modal cover whenever isPresented is true.

Available on Widget, provided by the GlassNavigationTitleExtension extension

Annotates this widget with a navigation title that drives enclosing or descendant GlassAppBar / GlassAppBar.pinned bars (when their explicit title is null) as well as header accessibility semantics.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toDiagnosticsNode({String? name, DiagnosticsTreeStyle? style}) → DiagnosticsNode
Returns a debug representation of the object that is used by debugging tools and by DiagnosticsNode.toStringDeep.
inherited
toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) → String
A string representation of this object.
inherited
toStringDeep({String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug, int wrapWidth = 65}) → String
Returns a string representation of this node and its descendants.
inherited
toStringShallow({String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) → String
Returns a one-line detailed description of the object.
inherited
toStringShort() → String
A short, textual description of this widget.
inherited

Operators

operator ==(Object other) → bool
The equality operator.
inherited