Overview
A Compose-multiplatform navigation library that leverage Decompose to create an API inspired by Conductor
Features
🚏 A
Router
that manages a stack, pages or slot for your screen configurations📦
rememberOnRoute()
lets you retain your state holders across configuration changes and gets cleared when the user leaves the screen🚉 Multiplatform! Supports Android, WearOS, Desktop, iOS and Web
At a glance
// Declare your screen configurations for type-safety
@Serializable
sealed class Screen: Parcelable {
object List : Screen()
data class Details(val detail: String) : Screen()
}
@Composable
fun ListDetailScreen() {
// Create a router with a stack of screen configurations 🚏
val router: Router<Screen> = rememberRouter { listOf(List) }
// Hoist your screens for each configuration 🏗️
RoutedContent(router = router) { screen ->
when (screen) {
List -> ListScreen(
// Navigate by pushing new configurations on the router 🧭
onSelectItem = { detail -> router.push(detail) }
)
is Details -> DetailsScreen(screen.detail)
}
}
}
@Composable
fun DetailsScreen(detail: String) {
// 📦 Scope an instance (a view model, a state-holder or whatever) to a route with [rememberOnRoute]
// This makes your instances survive configuration changes (on android) 🔁
// And holds-on the instance as long as it is in the backstack 🔗
// Pass in key if you want to reissue a new instance when key changes 🔑 (optional)
val instance: DetailInstance = rememberOnRoute(key = detail) { context -> DetailInstance(context, detail) }
val state: DetailState by instance.states.collectAsState()
Text(text = state.detail)
}
// If you want your state to survive process death ☠️ derive your initial state from [SavedStateHandle]
class DetailInstance(context: RouterContext, detail: String) : InstanceKeeper.Instance {
private val initialState: DetailState = context.state(DetailState(detail)) { states.value }
private val stateFlow = MutableStateFlow(initialState)
val states: StateFlow<DetailState> = stateFlow
}
Last modified: 25 November 2024