Skip to content

add onWasmReady #445

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 93 additions & 37 deletions topics/compose/compose-navigation-routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ Users can use the **Back** and **Forward** buttons in the browser to move betwee
as well as use the address bar to understand where they are and get to a destination directly.

To bind the web app to the navigation graph defined in your common code,
call the `window.bindToNavigation()` method in your Kotlin/Wasm or Kotlin/JS code:
you can use the `window.bindToNavigation()` method in your Kotlin/Wasm code. For Kotlin/JS, ensure this code runs within
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expand a tiny bit here: something like "you can use the same method in Kotlin/JS, but make sure to wrap the code..."

the `onWasmReady {}` block. Here is an example of how to set this up:

```kotlin
//commonMain source set
Expand All @@ -80,7 +81,7 @@ fun App(
}
}

//wasmJsMain or jsMain source set
//wasmJsMain source set
@OptIn(ExperimentalComposeUiApi::class)
@ExperimentalBrowserHistoryApi
fun main() {
Expand All @@ -91,6 +92,20 @@ fun main() {
)
}
}

//jsMain source set
@OptIn(ExperimentalComposeUiApi::class)
@ExperimentalBrowserHistoryApi
fun main() {
onWasmReady {
val body = document.body ?: return@onWasmReady
ComposeViewport(body) {
App(
onNavHostReady = { window.bindToNavigation(it) }
)
}
}
}
```

After a `window.bindToNavigation(navController)` call:
Expand Down Expand Up @@ -202,7 +217,7 @@ fun main() {
route.startsWith(Id.serializer().descriptor.serialName) -> {
// Accesses the route arguments
val args = entry.toRoute<Id>()

// Sets the corresponding URL fragment to "#find_id_222"
// instead of "#org.example.app.ID%2F222"
"#find_id_${args.id}"
Expand Down Expand Up @@ -236,40 +251,81 @@ to match manually entered URLs to destination routes.
The code that does the matching needs to run before the `window.bindToNavigation()` call binds
`window.location` to the navigation graph:

```kotlin
@OptIn(
ExperimentalComposeUiApi::class,
ExperimentalBrowserHistoryApi::class,
ExperimentalSerializationApi::class
)
fun main() {
val body = document.body ?: return
ComposeViewport(body) {
App(
onNavHostReady = { navController ->
// Accesses the fragment substring of the current URL
val initRoute = window.location.hash.substringAfter('#', "")
when {
// Identifies the corresponding route and navigates to it
initRoute.startsWith("start") -> {
navController.navigate(StartScreen)
}
initRoute.startsWith("find_id") -> {
// Parses the string to extract route parameters before navigating to it
val id = initRoute.substringAfter("find_id_").toLong()
navController.navigate(Id(id))
}
initRoute.startsWith("patient") -> {
val name = initRoute.substringAfter("patient_").substringBefore("_")
val id = initRoute.substringAfter("patient_").substringAfter("_").toLong()
navController.navigate(Patient(name, id))
<tabs>
<tab title="Kotlin/Wasm">
<code-block lang="Kotlin">
@OptIn(
ExperimentalComposeUiApi::class,
ExperimentalBrowserHistoryApi::class,
ExperimentalSerializationApi::class
)
fun main() {
val body = document.body ?: return
ComposeViewport(body) {
App(
onNavHostReady = { navController ->
// Accesses the fragment substring of the current URL
val initRoute = window.location.hash.substringAfter('#', "")
when {
// Identifies the corresponding route and navigates to it
initRoute.startsWith("start") -> {
navController.navigate(StartScreen)
}
initRoute.startsWith("find_id") -> {
// Parses the string to extract route parameters before navigating to it
val id = initRoute.substringAfter("find_id_").toLong()
navController.navigate(Id(id))
}
initRoute.startsWith("patient") -> {
val name = initRoute.substringAfter("patient_").substringBefore("_")
val id = initRoute.substringAfter("patient_").substringAfter("_").toLong()
navController.navigate(Patient(name, id))
}
}
window.bindToNavigation(navController) { ... }
}
}

window.bindToNavigation(navController) { ... }
)
}
}
</code-block>
</tab>
<tab title="Kotlin/JS">
<code-block lang="kotlin">
@OptIn(
ExperimentalComposeUiApi::class,
ExperimentalBrowserHistoryApi::class,
ExperimentalSerializationApi::class
)
}
}
```
<!--{default-state="collapsed" collapsible="true" collapsed-title="val initRoute = window.location.hash.substringAfter( ..."}-->
fun main() {
onWasmReady {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would still be great to comment on what this actually does — here, or at the top, where we mention it for the first time. Or both :)

val body = document.body ?: return@onWasmReady
ComposeViewport(body) {
App(
onNavHostReady = { navController ->
// Accesses the fragment substring of the current URL
val initRoute = window.location.hash.substringAfter('#', "")
when {
// Identifies the corresponding route and navigates to it
initRoute.startsWith("start") -> {
navController.navigate(StartScreen)
}
initRoute.startsWith("find_id") -> {
// Parses the string to extract route parameters before navigating to it
val id = initRoute.substringAfter("find_id_").toLong()
navController.navigate(Id(id))
}
initRoute.startsWith("patient") -> {
val name = initRoute.substringAfter("patient_").substringBefore("_")
val id = initRoute.substringAfter("patient_").substringAfter("_").toLong()
navController.navigate(Patient(name, id))
}
}
window.bindToNavigation(navController) { ... }
}
)
}
}
}
</code-block>
</tab>
</tabs>