Compose Multiplatform Navigation - Pragmatic, type safety navigation for Compose Multiplatform. Based on Freeletics Navigation.
- 
Integrate with Jetpack ComposeandCompose Multiplatformseamlessly.
- 
Integrate with kmp-viewmodel library seamlessly - Stack entry scoped ViewModel, exists as long as the stack entry is on the navigation stack, including the configuration changes onAndroid.
- Supports SavedStateHandle, used to save and restore data over configuration changes or process death onAndroid.
 
- Stack entry scoped 
- 
Type safety navigation, easy to pass data between destinations. 
- 
Supports Multi-Backstacks, this is most commonly used in apps that use bottom navigation to separate the back stack of each tab. See Freeletics Navigation - Multiple back stacks. 
- 
Supports Lifecycleevents, similar toAndroidX Lifecyclelibrary.
- 
Most of code in solivagant-khonshu-navigation-coreandsolivagant-navigationlibraries is taken from Freeletics Navigation, and ported toKotlin MultiplatformandCompose Multiplatform.
- 
The solivagant-lifecyclelibrary is inspired by Essenty Lifecycle, and AndroidX Lifecycle.
Author: Petrus Nguyễn Thái Học
Liked some of my work? Buy me a coffee (or more likely a beer)
0.x release docs: https://hoc081098.github.io/solivagant/docs/0.x
Snapshot docs: https://hoc081098.github.io/solivagant/docs/latest
allprojects {
  repositories {
    [...]
    mavenCentral()
  }
}implementation("io.github.hoc081098:solivagant-navigation:0.0.1-alpha01")- The concept is similar to Freeletics Navigationlibrary, so you can read the Freeletics Navigation to understand the concept.
@Immutable
@Parcelize
data object StartScreenRoute : NavRoute, NavRoot
@Immutable
@Parcelize
data object SearchProductScreenRoute : NavRoute@JvmField
val StartScreenDestination: NavDestination =
  ScreenDestination<StartScreenRoute> { StartScreen() }
@Composable
internal fun StartScreen(
  modifier: Modifier = Modifier,
  viewModel: StartViewModel = koinKmpViewModel(),
) {
  // UI Composable
}
class StartViewModel(
  // used to trigger navigation actions from outside the view layer (e.g. from a ViewModel).
  // Usually, it is singleton object, or the host Activity retained scope.
  private val navigator: NavEventNavigator,
) : ViewModel() {
  internal fun navigateToProductsScreen() = navigator.navigateTo(ProductsScreenRoute)
  internal fun navigateToSearchProductScreen() = navigator.navigateTo(SearchProductScreenRoute)
}@JvmField
val SearchProductScreenDestination: NavDestination =
  ScreenDestination<SearchProductScreenRoute> { SearchProductsScreen() }
@Composable
fun SearchProductsScreen(
  modifier: Modifier = Modifier,
  viewModel: SearchProductsViewModel = koinKmpViewModel<SearchProductsViewModel>(),
) {
  // UI Composable
}
class SearchProductsViewModel(
  private val searchProducts: SearchProducts,
  private val savedStateHandle: SavedStateHandle,
  // used to trigger navigation actions from outside the view layer (e.g. from a ViewModel).
  // Usually, it is singleton object, or the host Activity retained scope.
  private val navigator: NavEventNavigator,
) : ViewModel() {
  fun navigateToProductDetail(id: Int) {
    navigator.navigateTo(ProductDetailScreenRoute(id))
  }
}@Stable
private val AllDestinations: ImmutableSet<NavDestination> = persistentSetOf(
  StartScreenDestination,
  SearchProductScreenDestination,
  // and more ...
)
@Composable
fun MyAwesomeApp(
  // used to trigger navigation actions from outside the view layer (e.g. from a ViewModel).
  // Usually, it is singleton object, or the host Activity retained scope.
  navigator: NavEventNavigator,
  modifier: Modifier = Modifier,
) {
  var currentRoute: BaseRoute? by remember { mutableStateOf(null) }
  NavHost(
    modifier = modifier,
    // route to the screen that should be shown initially
    startRoute = StartScreenRoute,
    // should contain all destinations that can be navigated to
    destinations = AllDestinations,
    navEventNavigator = navigator,
    destinationChangedCallback = { currentRoute = it },
  )
}class MainActivity : ComponentActivity() {
  override fun onCreate(savedInstanceState: Bundle) {
    super.onCreate()
    // navigator can be retrieved from the DI container, such as Koin, Dagger Hilt, etc.
    setContent {
      MyAwesomeApp(
        navigator = navigator
      )
    }
  }
}// navigate to the destination that the given route leads to
navigator.navigateTo(DetailScreenRoute("some-id"))
// navigate up in the hierarchy
navigator.navigateUp()
// navigate to the previous destination in the backstack
navigator.navigateBack()
// navigate back to the destination belonging to the referenced route and remove all destinations
// in between from the back stack, depending on inclusive the destination
navigator.navigateBackTo<MainScreenRoute>(inclusive = false)- Samples sample: a complete sample using Compose Multiplatform (Android, Desktop, iOS)- solivagant-navigationfor navigation in Compose Multiplatform.
- kmp-viewmodelto share- ViewModeland- SavedStateHandle.
- Koin DI.
 
- Add more tests
- Support transition when navigating
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

