Removed now outdated AutocompleteTextField

This commit is contained in:
dankito 2024-09-05 00:14:42 +02:00
parent 40ae222dfc
commit cd1465f144
3 changed files with 15 additions and 144 deletions

View File

@ -1,140 +0,0 @@
package net.codinux.banking.ui.forms
import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.Divider
import androidx.compose.material.Icon
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.runtime.Composable
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.*
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.toSize
import kotlinx.coroutines.launch
import net.codinux.banking.ui.config.Colors
@Composable
fun <T> AutocompleteTextField(
onValueChange: (T?) -> Unit,
modifier: Modifier = Modifier.fillMaxWidth(),
label: @Composable () -> Unit = { Text("Search") },
showDividersBetweenItems: Boolean = true,
getItemTitle: ((T) -> String)? = null,
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
fetchSuggestions: suspend (query: String) -> List<T> = { emptyList() },
suggestionContent: @Composable (T) -> Unit
) {
var searchQuery by remember { mutableStateOf("") }
var isLoading by remember { mutableStateOf(false) }
var suggestions by remember { mutableStateOf<List<T>>(emptyList()) }
var textFieldSize by remember { mutableStateOf(Size.Zero) }
var expanded by remember { mutableStateOf(false) }
val textFieldFocus = remember { FocusRequester() }
val focusManager = LocalFocusManager.current
val coroutineScope = rememberCoroutineScope()
Box(Modifier.fillMaxWidth()) {
OutlinedTextField(
value = searchQuery,
onValueChange = { query ->
searchQuery = query
onValueChange(null)
if (query.length >= 1) {
isLoading = true
coroutineScope.launch {
suggestions = fetchSuggestions(query)
isLoading = false
expanded = true
}
} else {
suggestions = emptyList()
expanded = false
}
},
label = label,
modifier = modifier
.focusRequester(textFieldFocus)
.onGloballyPositioned {
textFieldSize = it.size.toSize()
},
keyboardOptions = keyboardOptions,
trailingIcon = {
if (isLoading) {
CircularProgressIndicator(
modifier = Modifier.size(24.dp),
strokeWidth = 2.dp
)
} else if (searchQuery.isNotEmpty()) {
Icon(
imageVector = Icons.Default.Close,
contentDescription = "Clear",
modifier = Modifier.clickable {
searchQuery = ""
suggestions = emptyList()
expanded = false
onValueChange(null)
textFieldFocus.requestFocus()
}.focusProperties { canFocus = false }
)
}
},
// isError = selectedItem == null && searchQuery.isNotEmpty()
)
if (expanded) {
RoundedCornersCard(
Modifier.width(textFieldSize.width.dp)
.heightIn(max = 400.dp)
.padding(top = with(LocalDensity.current) { (textFieldSize.height + 2).toDp() })
,
cornerSize = 4.dp,
shadowElevation = 4.dp
) {
Column(Modifier.verticalScroll(ScrollState(0), enabled = true)) {
suggestions.forEachIndexed { index, item ->
Column(
Modifier.fillMaxWidth().padding(8.dp).clickable {
onValueChange(item)
getItemTitle?.let {
searchQuery = it.invoke(item)
}
expanded = false
textFieldFocus.freeFocus()
focusManager.moveFocus(FocusDirection.Down)
}
) {
suggestionContent(item)
}
if (showDividersBetweenItems && index < suggestions.size - 1) {
Divider(color = Colors.Zinc200, thickness = 1.dp)
}
}
}
}
}
}
LaunchedEffect(textFieldFocus) {
textFieldFocus.requestFocus()
}
}

View File

@ -6,8 +6,7 @@ import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.LocalTextStyle
import androidx.compose.material.MaterialTheme
import androidx.compose.material.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.*
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Shape
@ -15,7 +14,11 @@ import androidx.compose.ui.input.key.*
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.VisualTransformation
import kotlinx.coroutines.Job
import net.codinux.banking.ui.config.Colors
import net.codinux.banking.ui.config.DI
private val uiService = DI.uiService
@OptIn(ExperimentalComposeUiApi::class)
@Composable
@ -47,12 +50,20 @@ fun OutlinedTextField(
focusedLabelColor = Colors.CodinuxSecondaryColor // does not work
)
var debounceJob by remember { mutableStateOf<Job?>(null) }
val coroutineScope = rememberCoroutineScope()
androidx.compose.material.OutlinedTextField(
value = value,
onValueChange = onValueChange,
modifier = modifier.onKeyEvent { event -> // onKeyEvent only handle input on hardware keyboards
if (onEnterPressed != null && event.type == KeyEventType.KeyUp && (event.key == Key.Enter || event.key == Key.NumPadEnter)) {
onEnterPressed()
debounceJob?.cancel()
debounceJob = uiService.debounce(coroutineScope) {
onEnterPressed()
}
true
} else {
false

View File

@ -17,7 +17,7 @@ import bankmeister.composeapp.generated.resources.visibility
import bankmeister.composeapp.generated.resources.visibility_off
import org.jetbrains.compose.resources.imageResource
@Composable
@Composable // try BasicSecureTextField
fun PasswordTextField(password: String = "", label: String = "Passwort", forceHidePassword: Boolean? = null, onEnterPressed: (() -> Unit)? = null, onChange: (String) -> Unit) {
var passwordVisible by remember { mutableStateOf(false) }