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
+