Navigation item
Updated: Aug 29, 2026
Navigation items represent destinations in a vertical side rail, along the left or right edge of a primary content area. The Meta VR UI Set SDK provides SideNavItem, a single row that adapts between an expanded rail and an icon-only rail.
- Layout:
collapsed renders the icon alone, centered in a square row. The expanded row shows the icon, the primary label, and an optional secondary label. - Density:
dense uses the 40 dp row height and the button shape. The standard row is 56 dp and uses the menu shape. - Selection:
selected marks the current destination and switches the row to the selected colors. - Icon control:
showExpandedIcon drops the icon from an expanded row, which leaves a text-only destination. - Theming: Colors come from
SideNavItemDefaults, and row heights, icon size, padding, and spacing come from UiSetTheme.dimensions.navigation. - Accessibility: A collapsed row stays at least a 48 dp target, matching the Android design requirements.
Place items in a Column and hold the current destination in your own state. The row is stateless, so selected reflects your state and onClick updates it.
import androidx.compose.foundation.layout.Column
import metavrx.uiset.compose.Icon
import metavrx.uiset.compose.navigation.SideNavItem
import metavrx.uiset.compose.theme.icons.Icons
val destinations = listOf(
"Home" to Icons.Regular.Home,
"Library" to Icons.Regular.Library,
"Store" to Icons.Regular.Store,
"Settings" to Icons.Regular.Settings,
)
var selectedIndex by remember { mutableIntStateOf(0) }
Column {
destinations.forEachIndexed { index, (label, icon) ->
SideNavItem(
icon = { Icon(icon, contentDescription = null) },
onClick = { selectedIndex = index },
primaryLabel = label,
selected = index == selectedIndex,
)
}
}
collapsed is a value you own. Drive it from your own state to switch the rail between icon-only and expanded rows.
SideNavItem(
icon = { Icon(Icons.Regular.Library, contentDescription = "Library") },
onClick = { /* ... */ },
primaryLabel = "Library",
collapsed = true,
dense = true,
)
The primary label wraps to two lines in a standard row and to one line in a dense row, and the secondary label always renders on one line. A collapsed row hides both labels, so give the icon a contentDescription when the label is the only other name for the destination.
icon: @Composable () -> Unit: The destination icon, and the only content of a collapsed row.onClick: () -> Unit: Invoked when the destination is chosen.primaryLabel: String: The destination name.secondaryLabel: String? = null: Supporting text below the primary label.collapsed: Boolean = false: Renders the icon-only form.dense: Boolean = false: Uses the shorter row height and the button shape.showExpandedIcon: Boolean = true: Set to false for a text-only expanded row.selected: Boolean = false: Marks the current destination.enabled: Boolean = true: Controls interactivity.colors: SideNavItemColors: Selected, unselected, and disabled colors. Defaults come from SideNavItemDefaults.dimensions: NavigationDimensions: Row heights, icon size, padding, and spacing.modifier: Modifier = Modifier: Applied to the full interaction target.
Keep the labels short enough to read at a glance, and mark exactly one item as selected.