From ad50e700d42acfe8b7d2f43ad8ed70e15bac67ef Mon Sep 17 00:00:00 2001 From: LavaDesu Date: Mon, 14 Apr 2025 13:35:26 +1000 Subject: [PATCH] feat: port skeleton search bar --- .../commonMain/kotlin/moe/lava/banksia/App.kt | 30 +++-- .../kotlin/moe/lava/banksia/ui/Searcher.kt | 105 ++++++++++++++++++ 2 files changed, 123 insertions(+), 12 deletions(-) create mode 100644 composeApp/src/commonMain/kotlin/moe/lava/banksia/ui/Searcher.kt diff --git a/composeApp/src/commonMain/kotlin/moe/lava/banksia/App.kt b/composeApp/src/commonMain/kotlin/moe/lava/banksia/App.kt index f1fdc17..abb300e 100644 --- a/composeApp/src/commonMain/kotlin/moe/lava/banksia/App.kt +++ b/composeApp/src/commonMain/kotlin/moe/lava/banksia/App.kt @@ -1,26 +1,22 @@ package moe.lava.banksia -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material3.BottomSheetScaffold -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.SheetValue import androidx.compose.material3.rememberBottomSheetScaffoldState import androidx.compose.material3.rememberStandardBottomSheetState -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment +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.Modifier -import org.jetbrains.compose.resources.painterResource -import org.jetbrains.compose.ui.tooling.preview.Preview - -import banksia.composeapp.generated.resources.Res -import banksia.composeapp.generated.resources.compose_multiplatform import moe.lava.banksia.native.maps.Maps +import moe.lava.banksia.ui.Searcher +import org.jetbrains.compose.ui.tooling.preview.Preview @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -32,6 +28,10 @@ fun App() { skipHiddenState = false ) ) + + var searchTextState by remember { mutableStateOf("") } + var searchExpandedState by remember { mutableStateOf(false) } + MaterialTheme { BottomSheetScaffold( scaffoldState = scaffoldState, @@ -41,6 +41,12 @@ fun App() { modifier = Modifier.fillMaxSize(), sheetState = scaffoldState.bottomSheetState, ) + Searcher( + expanded = searchExpandedState, + onExpandedChange = { searchExpandedState = it }, + text = searchTextState, + onTextChange = { searchTextState = it }, + ) } } } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/moe/lava/banksia/ui/Searcher.kt b/composeApp/src/commonMain/kotlin/moe/lava/banksia/ui/Searcher.kt new file mode 100644 index 0000000..71afe3d --- /dev/null +++ b/composeApp/src/commonMain/kotlin/moe/lava/banksia/ui/Searcher.kt @@ -0,0 +1,105 @@ +package moe.lava.banksia.ui + +import androidx.compose.animation.core.animateDpAsState +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Clear +import androidx.compose.material.icons.filled.Search +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.SearchBar +import androidx.compose.material3.SearchBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp + + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun Searcher( + expanded: Boolean, + onExpandedChange: (Boolean) -> Unit, + text: String, + onTextChange: (String) -> Unit, +) { + val animatedPadding by animateDpAsState( + if (expanded) { + 0.dp + } else { + 20.dp + }, + label = "padding" + ) + Box(modifier = Modifier.fillMaxSize()) { + LaunchedEffect(Unit) { + /*cache.routes()*/ + } + SearchBar( + colors = SearchBarDefaults.colors(containerColor = MaterialTheme.colorScheme.surfaceContainer), + modifier = Modifier + .align(Alignment.TopCenter) + .fillMaxWidth() + .padding(horizontal = animatedPadding), + inputField = { + SearchBarDefaults.InputField( + query = text, + onQueryChange = onTextChange, + onSearch = {}, + expanded = expanded, + onExpandedChange = onExpandedChange, + leadingIcon = { Icon(Icons.Default.Search, null) }, + trailingIcon = { + if (expanded && text.isNotEmpty()) + Icon( + imageVector = Icons.Default.Clear, + contentDescription = null, + modifier = Modifier.clickable { onTextChange("") } + ) + } + ) + }, + expanded = expanded, + onExpandedChange = onExpandedChange, + ) { + LazyColumn(modifier = Modifier.fillMaxWidth()) { + /*val r = cache.sortedRoutes() + for ((_, route) in r) { + if (!route.route_number.contains(text) && + !route.route_name.lowercase().contains(text.lowercase())) + continue + item { + ListItem( + headlineContent = { Text(route.route_number.ifEmpty { route.route_name }) }, + supportingContent = { + if (route.route_number.isNotEmpty()) { + Text(route.route_name) + } + }, + leadingContent = { route.route_type.ComposableIcon() }, + colors = ListItemDefaults.colors(containerColor = Color.Transparent), + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 4.dp) + .clickable { + text = "${route.route_number} - ${route.route_name}" + + onRouteChanged(route) + expanded = false + } + ) + } + }*/ + } + } + } + +} \ No newline at end of file