-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #30 from soil-kt/jb-navigation
Supported androidx.Navigation Library for Compose Multiplatform
- Loading branch information
Showing
18 changed files
with
432 additions
and
235 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
internal/playground/src/commonMain/kotlin/soil/playground/router/NavLink.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package soil.playground.router | ||
|
||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.remember | ||
|
||
@Composable | ||
inline fun NavLink( | ||
to: String, | ||
router: NavRouter = LocalNavRouter.current, | ||
content: @Composable (NavLinkHandle) -> Unit | ||
) { | ||
val handle: NavLinkHandle = remember(to) { { router.push(to) } } | ||
content(handle) | ||
} | ||
|
||
@Composable | ||
inline fun <T : NavRoute> NavLink( | ||
to: T, | ||
router: NavRouter = LocalNavRouter.current, | ||
content: @Composable (NavLinkHandle) -> Unit | ||
) { | ||
val handle: NavLinkHandle = remember(to) { { router.push<T>(to) } } | ||
content(handle) | ||
} | ||
|
||
typealias NavLinkHandle = () -> Unit |
28 changes: 28 additions & 0 deletions
28
internal/playground/src/commonMain/kotlin/soil/playground/router/NavRouter.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package soil.playground.router | ||
|
||
import androidx.compose.runtime.Stable | ||
import androidx.compose.runtime.staticCompositionLocalOf | ||
|
||
@Stable | ||
interface NavRouter { | ||
fun push(route: String) | ||
|
||
fun <T : NavRoute> push(route: T) | ||
|
||
fun back(): Boolean | ||
|
||
fun canBack(): Boolean | ||
} | ||
|
||
interface NavRoute | ||
|
||
private val noRouter = object : NavRouter { | ||
override fun push(route: String) = Unit | ||
override fun <T : NavRoute> push(route: T) = Unit | ||
override fun back() = false | ||
override fun canBack() = false | ||
} | ||
|
||
val LocalNavRouter = staticCompositionLocalOf<NavRouter> { | ||
noRouter | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 0 additions & 11 deletions
11
sample/composeApp/src/androidMain/kotlin/soil/kmp/integration/voyager/ScreenExt.android.kt
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.CompositionLocalProvider | ||
import androidx.compose.runtime.Stable | ||
import androidx.compose.runtime.remember | ||
import androidx.compose.ui.Modifier | ||
import androidx.navigation.NamedNavArgument | ||
import androidx.navigation.NavHostController | ||
import androidx.navigation.NavType | ||
import androidx.navigation.compose.NavHost | ||
import androidx.navigation.compose.composable | ||
import androidx.navigation.navArgument | ||
import soil.kmp.screen.HelloFormScreen | ||
import soil.kmp.screen.HelloQueryDetailScreen | ||
import soil.kmp.screen.HelloQueryScreen | ||
import soil.kmp.screen.HelloSpaceScreen | ||
import soil.kmp.screen.HomeScreen | ||
import soil.kmp.screen.NavScreen | ||
import soil.playground.router.LocalNavRouter | ||
import soil.playground.router.NavRoute | ||
import soil.playground.router.NavRouter | ||
import soil.space.compose.rememberViewModelStore | ||
|
||
@Stable | ||
class Navigator( | ||
val navController: NavHostController | ||
) : NavRouter { | ||
override fun push(route: String) { | ||
navController.navigate(route) | ||
} | ||
|
||
override fun <T : NavRoute> push(route: T) { | ||
when (val screen = route as NavScreen) { | ||
is NavScreen.Home -> push(NavScreenDestination.Home()) | ||
is NavScreen.HelloQuery -> push(NavScreenDestination.HelloQuery()) | ||
is NavScreen.HelloQueryDetail -> push(NavScreenDestination.HelloQueryDetail(screen.postId)) | ||
is NavScreen.HelloForm -> push(NavScreenDestination.HelloForm()) | ||
is NavScreen.HelloSpace -> push(NavScreenDestination.HelloSpace()) | ||
} | ||
} | ||
|
||
override fun back(): Boolean { | ||
return navController.popBackStack() | ||
} | ||
|
||
override fun canBack(): Boolean { | ||
return navController.previousBackStackEntry != null | ||
} | ||
} | ||
|
||
@Composable | ||
fun NavRouterHost( | ||
navigator: Navigator, | ||
modifier: Modifier | ||
) { | ||
val startDestination = remember(NavScreen.root) { NavScreen.root.destination.route } | ||
CompositionLocalProvider(LocalNavRouter provides navigator) { | ||
NavHost( | ||
navController = navigator.navController, | ||
startDestination = startDestination, | ||
modifier = modifier | ||
) { | ||
composable( | ||
route = NavScreenDestination.Home.route | ||
) { | ||
HomeScreen() | ||
} | ||
composable( | ||
route = NavScreenDestination.HelloQuery.route | ||
) { | ||
HelloQueryScreen() | ||
} | ||
composable( | ||
route = NavScreenDestination.HelloQueryDetail.route, | ||
arguments = NavScreenDestination.HelloQueryDetail.arguments | ||
) { | ||
val id = checkNotNull(it.arguments?.getInt(NavScreenDestination.HelloQueryDetail.id.name)) | ||
HelloQueryDetailScreen(postId = id) | ||
} | ||
composable( | ||
route = NavScreenDestination.HelloForm.route | ||
) { | ||
HelloFormScreen() | ||
} | ||
composable( | ||
route = NavScreenDestination.HelloSpace.route | ||
) { | ||
val rootEntry = navigator.navController.getBackStackEntry(startDestination) | ||
HelloSpaceScreen( | ||
navStore = rememberViewModelStore(rootEntry) | ||
) | ||
} | ||
} | ||
} | ||
} | ||
|
||
private sealed class NavScreenDestination( | ||
val route: String | ||
) { | ||
data object Home : NavScreenDestination("/home") { | ||
operator fun invoke() = route | ||
} | ||
|
||
data object HelloQuery : NavScreenDestination("/helloQuery") { | ||
operator fun invoke() = route | ||
} | ||
|
||
data object HelloQueryDetail : NavScreenDestination("/helloQuery/{id}") { | ||
val arguments get() = listOf(id) | ||
val id: NamedNavArgument | ||
get() = navArgument("id") { | ||
type = NavType.IntType | ||
} | ||
|
||
operator fun invoke(postId: Int) = "/helloQuery/$postId" | ||
} | ||
|
||
data object HelloForm : NavScreenDestination("/helloForm") { | ||
operator fun invoke() = route | ||
} | ||
|
||
data object HelloSpace : NavScreenDestination("/helloSpace") { | ||
operator fun invoke() = route | ||
} | ||
} | ||
|
||
private val NavScreen.destination: NavScreenDestination | ||
get() = when (this) { | ||
is NavScreen.Home -> NavScreenDestination.Home | ||
is NavScreen.HelloQuery -> NavScreenDestination.HelloQuery | ||
is NavScreen.HelloQueryDetail -> NavScreenDestination.HelloQueryDetail | ||
is NavScreen.HelloForm -> NavScreenDestination.HelloForm | ||
is NavScreen.HelloSpace -> NavScreenDestination.HelloSpace | ||
} |
9 changes: 0 additions & 9 deletions
9
sample/composeApp/src/commonMain/kotlin/soil/kmp/integration/voyager/AtomScreenModel.kt
This file was deleted.
Oops, something went wrong.
19 changes: 0 additions & 19 deletions
19
sample/composeApp/src/commonMain/kotlin/soil/kmp/integration/voyager/ScreenExt.kt
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.