Docs / Bottom bars / 05

SocketBottomBar

Floating pill whose selected icon lifts into a bubble, resting in a socket that glides from tab to tab.

  • Floating
  • Any tab
  • Icon + label

Preview

Light
Socket bottom bar in light theme, switching between tabs
Dark
Socket bottom bar in dark theme, switching between tabs

A floating pill where the selected icon lifts out of the bar into a bubble, resting in a socket cut into the top edge. Works with any number of tabs; the bubble and its socket glide from tab to tab.

Usage

SocketBarItem works like the others, but there is no center orb: any tab can be selected into the bubble, so pass any number of items (3 to 5 fit best). Every tab shows its label; the selected one's icon lifts into the bubble as its selectedIcon, and its label takes selectedContentColor.

Imports
import com.nameisjayant.bottombar.socket.SocketBarItem
import com.nameisjayant.bottombar.socket.SocketBottomBar
import com.nameisjayant.bottombar.socket.SocketBottomBarDefaults
SocketBottomBar.kt
val items = listOf(
    SocketBarItem("Home", Icons.Outlined.Home, Icons.Filled.Home),
    SocketBarItem("Search", Icons.Outlined.Search, Icons.Filled.Search),
    SocketBarItem("Cart", Icons.Outlined.ShoppingCart, Icons.Filled.ShoppingCart),
    SocketBarItem("Profile", Icons.Outlined.Person, Icons.Filled.Person),
)

SocketBottomBar(
    items = items,
    selectedIndex = selectedIndex,
    onItemClick = { selectedIndex = it },
    // A floating pill, so keep it off the screen edges.
    modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp),
)

Sizing and behavior

The pill is BarHeight (72dp) tall and the 52dp bubble (BubbleSize) rises BubbleOverhang (23dp) above it, all inside the bar's own bounds. The socket is shaped by SocketGap (the see-through ring around the bubble) and SocketShoulderRadius, and ContentPadding sets the space between the rounded ends and the outer tabs. The bar has no outer margin of its own, so pass one through modifier. As with the other cut-out bars, shadowElevation defaults to 0.dp and needs API 30+ because of the concave outline.

Colors

Colors come from SocketBottomBarDefaults.colors(darkTheme), lightColors(...) and darkColors(...). Start from either palette and override only what you need.

ColorUsed for
containerColorThe pill background
bubbleColorFill of the bubble; matches containerColor by default
selectedContentColorIcon inside the bubble and the selected tab's label
unselectedContentColorIcons of the other tabs
unselectedLabelColorLabels of the other tabs
Theming
SocketBottomBar(
    items = items,
    selectedIndex = selectedIndex,
    onItemClick = { selectedIndex = it },
    // Follow your app's theme instead of the system one.
    colors = SocketBottomBarDefaults.colors(darkTheme = isDarkTheme),
)

API

The full signature of the composable and its item class:

com.nameisjayant.bottombar.socket
fun SocketBottomBar(
    items: List<SocketBarItem>,
    selectedIndex: Int,
    onItemClick: (index: Int) -> Unit,
    modifier: Modifier = Modifier,
    colors: SocketBottomBarColors = SocketBottomBarDefaults.colors(),
    labelStyle: TextStyle = SocketBottomBarDefaults.LabelStyle,
    shadowElevation: Dp = 0.dp,
    windowInsets: WindowInsets = SocketBottomBarDefaults.windowInsets,
)

class SocketBarItem(
    val label: String,
    val icon: ImageVector,
    val selectedIcon: ImageVector = icon,
)