SegmentedControl
An iOS-style segmented control for Compose Multiplatform — platform-appropriate visuals with
three styles built in, an animated selection indicator, and full keyboard & RTL support.

Why this library
Material 3's SingleChoiceSegmentedButtonRow always looks like Material — which feels out of place
on iOS, where users expect the familiar UISegmentedControl. SegmentedControl gives you a
platform-appropriate look from a single Compose codebase: ship the iOS style on Apple platforms,
Material3 on Android, or Pill everywhere — without forking your UI code.
Platform support
Installation
gradle/libs.versions.toml:
[libraries]
segmented-control = { module = "io.github.nadeemiqbal:segmented-control", version = "0.1.0" }
commonMain dependencies:
kotlin {
sourceSets {
commonMain.dependencies {
implementation(libs.segmented.control)
}
}
}
Quick start
var selected by remember { mutableStateOf(0) }
SegmentedControl(
items = listOf("Day", "Week", "Month"),
selectedIndex = selected,
onSelectionChange = { selected = it },
modifier = Modifier.fillMaxWidth(),
)
API examples
Icon + text segments
SegmentedControl(
items = listOf(
SegmentItem("List", Icons.Default.List),
SegmentItem("Grid", Icons.Default.GridView),
),
selectedIndex = selected,
onSelectionChange = { selected = it },
)
Pick a style
SegmentedControl(
items = items,
selectedIndex = selected,
onSelectionChange = { selected = it },
style = SegmentedControlStyle.iOS,
)
Disabled segments
SegmentedControl(
items = labels.mapIndexed { i, label -> SegmentItem(label, enabled = i != 2) },
selectedIndex = selected,
onSelectionChange = { selected = it },
)
Equal vs content width
SegmentedControl(items, selected, { selected = it }, width = SegmentedControlWidth.Equal, modifier = Modifier.fillMaxWidth())
SegmentedControl(items, selected, { selected = it }, width = SegmentedControlWidth.Content)
Icon-only
SegmentedControl(
items = listOf(
SegmentItem(icon = Icons.Default.FormatAlignLeft),
SegmentItem(icon = Icons.Default.FormatAlignCenter),
SegmentItem(icon = Icons.Default.FormatAlignRight),
),
selectedIndex = selected,
onSelectionChange = { selected = it },
)
Keyboard navigation — on Desktop and Web, focus the control (Tab) and use the Left/Right arrow
keys to move the selection between enabled segments. No extra setup required.
Customization
SegmentedControl(
items = items,
selectedIndex = selected,
onSelectionChange = { selected = it },
style = SegmentedControlStyle.Pill,
colors = SegmentedControlDefaults.colors(SegmentedControlStyle.Pill).copy(
thumbColor = MaterialTheme.colorScheme.tertiary,
selectedContentColor = MaterialTheme.colorScheme.onTertiary,
),
shape = RoundedCornerShape(8.dp),
animationSpec = spring(dampingRatio = Spring.DampingRatioLowBouncy),
)
Comparison with alternatives
Be honest with yourself: if you only ship Android and you're all-in on Material, the built-in M3
control is fine. Reach for this library when you want an iOS-appropriate look, a richer animated
indicator, or keyboard support — without maintaining your own component.
Roadmap
- Scrollable / overflow mode for many segments
- Badge support on segments
- Optional haptic feedback on selection (Android/iOS)
Contributing
See CONTRIBUTING.md. Bug reports and feature requests are welcome via GitHub
Issues.
License
Copyright 2026 Nadeem Iqbal
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http:
See LICENSE for the full text.