feat: basic nav3
This commit is contained in:
parent
2cb53ee962
commit
1b3b465112
8 changed files with 152 additions and 42 deletions
|
|
@ -7,5 +7,6 @@ plugins {
|
|||
alias(libs.plugins.composeMultiplatform) apply false
|
||||
alias(libs.plugins.composeCompiler) apply false
|
||||
alias(libs.plugins.kotlinMultiplatform) apply false
|
||||
alias(libs.plugins.kotlinSerialization) apply false
|
||||
alias(libs.plugins.metro) apply false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
|||
|
||||
plugins {
|
||||
alias(libs.plugins.kotlinMultiplatform)
|
||||
alias(libs.plugins.kotlinSerialization)
|
||||
alias(libs.plugins.androidApplication)
|
||||
alias(libs.plugins.composeMultiplatform)
|
||||
alias(libs.plugins.composeCompiler)
|
||||
|
|
@ -34,6 +35,11 @@ kotlin {
|
|||
implementation(libs.compose.uiToolingPreview)
|
||||
implementation(libs.androidx.lifecycle.viewmodelCompose)
|
||||
implementation(libs.androidx.lifecycle.runtimeCompose)
|
||||
|
||||
implementation(libs.androidx.lifecycle.viewmodel.nav3)
|
||||
implementation(libs.androidx.nav3.ui)
|
||||
implementation(libs.compose.material3.adaptive)
|
||||
implementation(libs.compose.material3.adaptive.nav3)
|
||||
}
|
||||
commonTest.dependencies {
|
||||
implementation(libs.kotlin.test)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import androidx.activity.compose.setContent
|
|||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.navigation3.ui.defaultPredictivePopTransitionSpec
|
||||
import moe.lava.neon.ui.App
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
|
|
|
|||
|
|
@ -1,48 +1,54 @@
|
|||
package moe.lava.neon.ui
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.safeContentPadding
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import moe.lava.neon.resources.Res
|
||||
import moe.lava.neon.resources.compose_multiplatform
|
||||
import org.jetbrains.compose.resources.painterResource
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.navigation3.runtime.NavKey
|
||||
import androidx.navigation3.runtime.entryProvider
|
||||
import androidx.navigation3.runtime.rememberNavBackStack
|
||||
import androidx.navigation3.ui.NavDisplay
|
||||
import androidx.savedstate.serialization.SavedStateConfiguration
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.modules.SerializersModule
|
||||
import kotlinx.serialization.modules.polymorphic
|
||||
import moe.lava.neon.ui.screens.Login
|
||||
import moe.lava.neon.ui.screens.Sample
|
||||
|
||||
@Composable
|
||||
@Preview
|
||||
fun App() {
|
||||
MaterialTheme {
|
||||
var showContent by remember { mutableStateOf(false) }
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.background(MaterialTheme.colorScheme.primaryContainer)
|
||||
.safeContentPadding()
|
||||
.fillMaxSize(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Button(onClick = { showContent = !showContent }) {
|
||||
Text("Click me!")
|
||||
}
|
||||
AnimatedVisibility(showContent) {
|
||||
val greeting = remember { Greeting().greet() }
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Image(painterResource(Res.drawable.compose_multiplatform), null)
|
||||
Text("Compose: $greeting")
|
||||
}
|
||||
}
|
||||
private object Route {
|
||||
@Serializable
|
||||
data object Login : NavKey
|
||||
|
||||
@Serializable
|
||||
data class Sample(val token: String) : NavKey
|
||||
}
|
||||
|
||||
private val config = SavedStateConfiguration {
|
||||
serializersModule = SerializersModule {
|
||||
polymorphic(NavKey::class) {
|
||||
subclass(Route.Login::class, Route.Login.serializer())
|
||||
subclass(Route.Sample::class, Route.Sample.serializer())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun App() {
|
||||
MaterialTheme {
|
||||
val backStack = rememberNavBackStack(config, Route.Login)
|
||||
NavDisplay(
|
||||
backStack = backStack,
|
||||
onBack = { backStack.removeLastOrNull() },
|
||||
entryProvider = entryProvider {
|
||||
entry<Route.Login> {
|
||||
Login(
|
||||
onSuccess = { token ->
|
||||
backStack.add(Route.Sample(token))
|
||||
}
|
||||
)
|
||||
}
|
||||
entry<Route.Sample> { key ->
|
||||
Sample(key.token)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
package moe.lava.neon.ui.screens
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.safeContentPadding
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
|
||||
@Composable
|
||||
fun Login(
|
||||
onSuccess: (token: String) -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
// .background(MaterialTheme.colorScheme.primaryContainer)
|
||||
.safeContentPadding()
|
||||
.fillMaxSize()
|
||||
) {
|
||||
Text("Login!")
|
||||
|
||||
var token by rememberSaveable { mutableStateOf("") }
|
||||
OutlinedTextField(
|
||||
value = token,
|
||||
onValueChange = { token = it },
|
||||
label = { Text("Enter token") },
|
||||
)
|
||||
Button(onClick = { onSuccess(token) }) {
|
||||
Text("Submit")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package moe.lava.neon.ui.screens
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.safeContentPadding
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import moe.lava.neon.resources.Res
|
||||
import moe.lava.neon.resources.compose_multiplatform
|
||||
import moe.lava.neon.ui.Greeting
|
||||
import org.jetbrains.compose.resources.painterResource
|
||||
|
||||
@Composable
|
||||
fun Sample(token: String) {
|
||||
var showContent by remember { mutableStateOf(false) }
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.background(MaterialTheme.colorScheme.primaryContainer)
|
||||
.safeContentPadding()
|
||||
.fillMaxSize(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Button(onClick = { showContent = !showContent }) {
|
||||
Text("Click me!")
|
||||
}
|
||||
AnimatedVisibility(showContent) {
|
||||
val greeting = remember { Greeting().greet() }
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Image(painterResource(Res.drawable.compose_multiplatform), null)
|
||||
Text("Compose: $greeting")
|
||||
Text("Passed token: $token")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
|||
plugins {
|
||||
alias(libs.plugins.androidLibrary)
|
||||
alias(libs.plugins.kotlinMultiplatform)
|
||||
alias(libs.plugins.kotlinSerialization)
|
||||
alias(libs.plugins.metro)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ androidx-activity = "1.12.2"
|
|||
androidx-appcompat = "1.7.1"
|
||||
androidx-core = "1.17.0"
|
||||
androidx-espresso = "3.7.0"
|
||||
androidx-lifecycle = "2.9.6"
|
||||
androidx-lifecycle = "2.10.0-alpha07"
|
||||
androidx-nav3 = "1.0.0-alpha06"
|
||||
androidx-testExt = "1.3.0"
|
||||
composeHotReload = "1.0.0"
|
||||
composeMultiplatform = "1.10.0"
|
||||
|
|
@ -16,6 +17,7 @@ junit = "4.13.2"
|
|||
kotlin = "2.3.0"
|
||||
kotlinx-coroutines = "1.10.2"
|
||||
material3 = "1.10.0-alpha05"
|
||||
material3-adaptive = "1.3.0-alpha03"
|
||||
metro = "0.10.0"
|
||||
|
||||
[libraries]
|
||||
|
|
@ -30,9 +32,13 @@ androidx-activity-compose = { module = "androidx.activity:activity-compose", ver
|
|||
compose-uiTooling = { module = "org.jetbrains.compose.ui:ui-tooling", version.ref = "composeMultiplatform" }
|
||||
androidx-lifecycle-viewmodelCompose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "androidx-lifecycle" }
|
||||
androidx-lifecycle-runtimeCompose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-runtime-compose", version.ref = "androidx-lifecycle" }
|
||||
androidx-lifecycle-viewmodel-nav3 = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-navigation3", version.ref = "androidx-lifecycle" }
|
||||
androidx-nav3-ui = { module = "org.jetbrains.androidx.navigation3:navigation3-ui", version.ref = "androidx-nav3" }
|
||||
compose-runtime = { module = "org.jetbrains.compose.runtime:runtime", version.ref = "composeMultiplatform" }
|
||||
compose-foundation = { module = "org.jetbrains.compose.foundation:foundation", version.ref = "composeMultiplatform" }
|
||||
compose-material3 = { module = "org.jetbrains.compose.material3:material3", version.ref = "material3" }
|
||||
compose-material3-adaptive = { module = "org.jetbrains.compose.material3.adaptive:adaptive", version.ref = "material3-adaptive" }
|
||||
compose-material3-adaptive-nav3 = { module = "org.jetbrains.compose.material3.adaptive:adaptive-navigation3", version.ref = "material3-adaptive" }
|
||||
compose-ui = { module = "org.jetbrains.compose.ui:ui", version.ref = "composeMultiplatform" }
|
||||
compose-components-resources = { module = "org.jetbrains.compose.components:components-resources", version.ref = "composeMultiplatform" }
|
||||
compose-uiToolingPreview = { module = "org.jetbrains.compose.ui:ui-tooling-preview", version.ref = "composeMultiplatform" }
|
||||
|
|
@ -45,4 +51,5 @@ composeHotReload = { id = "org.jetbrains.compose.hot-reload", version.ref = "com
|
|||
composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "composeMultiplatform" }
|
||||
composeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
|
||||
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
|
||||
kotlinSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
|
||||
metro = { id = "dev.zacsweers.metro", version.ref = "metro" }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue