Skip to content

Voyager Integration

Thiago Santos edited this page Aug 18, 2024 · 1 revision

Important

This module is a case of studies that shows how you can extend Kotlin Routing to your context.

Voyager is a stack based compose navigation library. It works very well and is too easy having a navigation between compositions using it Screen concept. But Voyager don't have a route system and working on web without WASM or receiving a deep link is not easy.

So this module extend route handle to creating a Voyager Screen routing system.

sourceSets {
    commonMain.dependencies {
        implementation("dev.programadorthi.routing:voyager:$version")
    }
}

Setup the Voyager

import dev.programadorthi.routing.voyager.VoyagerRouting
// ...

val router = routing {
    // ...
}

@Composable
fun App() {
    VoyagerRouting(
        routing = router,
        initialScreen = YourInitialScreen(),
    )
}

Define screen handlers

import dev.programadorthi.routing.voyager.screen
// ...

val router = routing {
    screen(path = "...") {
        YourScreen()
    }
}

screen is a route handler on the hood and you can name it, change the route method, get call infos, and other behaviors as any route handler have.

Checkout Routing for more information.

Pop a screen

There is an extension function that need to be called to pop a screen. It works getting the previous route and invoking it.

Call the pop function

import dev.programadorthi.routing.voyager.pop
// ...

router.pop()

Pop with result

import dev.programadorthi.routing.voyager.pop
import dev.programadorthi.routing.voyager.VoyagerRoutingPopResult
// ...

class YourScreen : VoyagerRoutingPopResult<ResultType> {

    override fun onResult(result: ResultType?) {
        // to get the result
    }

}

val router = routing {
    // ...
}

router.pop(result = ResultTypeInstance)

Pop until some predicate

Voyager has a popUntil function that uses a predicate to determine how many screens should be removed from the stack.

import dev.programadorthi.routing.voyager.popUntil
// ...

router.popUntil(result = ...) { screen -> 
    // ...
}

Type-safe Screen

There is support to use type-safe with Voyager too.

Create a annotated type

@Resource("/articles")
class Articles()

Install Resources

val router = routing {
    install(Resources)
}

Define screen handlers

import dev.programadorthi.routing.voyager.screen
// ...

val router = routing {
    // ...
    screen<Articles> {
        // ...
    }
}

Push a screen

import dev.programadorthi.routing.resources.push
// ...

router.push(resource = Articles())

Replace a screen

import dev.programadorthi.routing.resources.replace
// ...

router.replace(resource = Articles())

Replace all screens

import dev.programadorthi.routing.resources.replaceAll
// ...

router.replaceAll(resource = Articles())

Checkout Type-safe Routing for more information.