From b8102171cb1fb1883fd06eb985b283c53be9317b Mon Sep 17 00:00:00 2001 From: DavidAparicioAlbaAsenjo <137989685+DavidAparicioAlbaAsenjo@users.noreply.github.com> Date: Wed, 10 Jan 2024 13:37:08 +0100 Subject: [PATCH] =?UTF-8?q?update:=20[ANDROAPP-5751]=20component=20updated?= =?UTF-8?q?,=20using=20BasicTextField=20for=20f=E2=80=A6=20(#165)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * update: [ANDROAPP-5751] component updated, using BasicTextField for fixing a padding, ripple effect added * add: [ANDROAPP-5751] content description added, string resource extracted * add:[ANDROAPP-5751] focus added * update: [ANDROAPP-5751] typography modified, padding added * update: [ANDROAPP-5751] padding modified * update: [ANDROAPP-5751] padding and caret color modified --- .../ui/designsystem/component/SearchBar.kt | 175 +++++++++++++----- .../resources/values/strings_en.xml | 2 + 2 files changed, 131 insertions(+), 46 deletions(-) diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/SearchBar.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/SearchBar.kt index d64034c3e..8483ac11f 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/SearchBar.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/SearchBar.kt @@ -1,21 +1,49 @@ package org.hisp.dhis.mobile.ui.designsystem.component +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.collectIsPressedAsState +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Cancel import androidx.compose.material.icons.outlined.Search +import androidx.compose.material.ripple.rememberRipple import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon -import androidx.compose.material3.SearchBar +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.SearchBarDefaults import androidx.compose.material3.Text +import androidx.compose.material3.TextFieldDefaults 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 androidx.compose.ui.draw.clip +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.focus.onFocusChanged +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.input.key.Key +import androidx.compose.ui.input.key.KeyEventType +import androidx.compose.ui.input.key.key +import androidx.compose.ui.input.key.onKeyEvent +import androidx.compose.ui.input.key.type import androidx.compose.ui.platform.testTag +import androidx.compose.ui.semantics.Role +import androidx.compose.ui.semantics.contentDescription +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.VisualTransformation +import org.hisp.dhis.mobile.ui.designsystem.resource.provideStringResource +import org.hisp.dhis.mobile.ui.designsystem.theme.Shape +import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing import org.hisp.dhis.mobile.ui.designsystem.theme.SurfaceColor import org.hisp.dhis.mobile.ui.designsystem.theme.TextColor @@ -23,61 +51,116 @@ import org.hisp.dhis.mobile.ui.designsystem.theme.TextColor @Composable fun SearchBar( text: String = "", - placeHolderText: String = "Search", + placeHolderText: String = provideStringResource("search"), onActiveChange: (Boolean) -> Unit = {}, onSearch: (String) -> Unit = {}, onQueryChange: (String) -> Unit = {}, + state: InputShellState = InputShellState.FOCUSED, modifier: Modifier = Modifier, ) { val interactionSource = remember { MutableInteractionSource() } val isPressed by interactionSource.collectIsPressedAsState() - - SearchBar( - modifier = modifier.testTag("SEARCH_INPUT"), - query = text, - onQueryChange = onQueryChange, - onSearch = onSearch, - active = false, - onActiveChange = onActiveChange, - colors = if (!isPressed) { - SearchBarDefaults.colors(containerColor = SurfaceColor.ContainerLow) + val focusRequester = remember { FocusRequester() } + val containerColor = if (!isPressed) { + SurfaceColor.ContainerLow + } else { + SurfaceColor.Container + } + val cursorColor by remember { + if (state == InputShellState.UNFOCUSED || state == InputShellState.FOCUSED) { + mutableStateOf(InputShellState.FOCUSED.color) } else { - SearchBarDefaults.colors(containerColor = SurfaceColor.Container) - }, - placeholder = { - Text( - text = placeHolderText, - color = TextColor.OnDisabledSurface, + mutableStateOf(state.color) + } + } + BasicTextField( + value = text, + onValueChange = onQueryChange, + modifier = modifier + .testTag("SEARCH_INPUT") + .height(SearchBarDefaults.InputFieldHeight) + .fillMaxWidth() + .background(containerColor, Shape.Full) + .clip(Shape.Full) + .focusRequester(focusRequester) + .clickable( + onClick = {}, + role = Role.Button, + interactionSource = interactionSource, + indication = rememberRipple( + true, + color = SurfaceColor.Primary, + ), ) - }, - trailingIcon = { - if (text != "") { - IconButton( - modifier = Modifier.testTag("CANCEL_BUTTON"), - icon = { - Icon( - imageVector = Icons.Outlined.Cancel, - contentDescription = "cancel button", + .onFocusChanged { if (it.isFocused) onActiveChange(true) } + .onKeyEvent { + if (it.key == Key.Escape && it.type == KeyEventType.KeyDown) { + onActiveChange(false) + true + } else { + false + } + } + .padding(end = Spacing.Spacing4) + .semantics { + contentDescription = "Search" + }, + enabled = true, + singleLine = true, + keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search), + keyboardActions = KeyboardActions(onSearch = { onSearch(text) }), + interactionSource = interactionSource, + textStyle = MaterialTheme.typography.bodyLarge, + decorationBox = @Composable { innerTextField -> + TextFieldDefaults.DecorationBox( + value = text, + innerTextField = innerTextField, + enabled = true, + singleLine = true, + visualTransformation = VisualTransformation.None, + interactionSource = interactionSource, + placeholder = { + Text( + text = placeHolderText, + color = TextColor.OnDisabledSurface, + ) + }, + trailingIcon = { + if (text != "") { + IconButton( + modifier = Modifier + .testTag("CANCEL_BUTTON"), + icon = { + Icon( + imageVector = Icons.Outlined.Cancel, + contentDescription = "Cancel Icon", + ) + }, + onClick = { + onQueryChange.invoke("") + }, ) - }, - onClick = { - onQueryChange.invoke("") - }, - ) - } else { - IconButton( - modifier = Modifier.testTag("SEARCH_BUTTON"), - icon = { - Icon( - imageVector = Icons.Outlined.Search, - contentDescription = "search button", + } else { + IconButton( + modifier = Modifier + .testTag("SEARCH_BUTTON"), + icon = { + Icon( + imageVector = Icons.Outlined.Search, + contentDescription = "Search Icon", + ) + }, + onClick = { + focusRequester.requestFocus() + }, ) - }, - onClick = {}, - ) - } + } + }, + shape = SearchBarDefaults.inputFieldShape, + contentPadding = TextFieldDefaults.contentPaddingWithoutLabel(), + container = {}, + ) }, - interactionSource = interactionSource, - content = {}, + cursorBrush = SolidColor(cursorColor), ) } diff --git a/designsystem/src/commonMain/resources/values/strings_en.xml b/designsystem/src/commonMain/resources/values/strings_en.xml index 2c0c3c2fb..2cfcb1241 100644 --- a/designsystem/src/commonMain/resources/values/strings_en.xml +++ b/designsystem/src/commonMain/resources/values/strings_en.xml @@ -29,4 +29,6 @@ Add signature Add image Not supported + Search +