Skip to content

Commit

Permalink
feat: expand sms text field (closes #327)
Browse files Browse the repository at this point in the history
  • Loading branch information
Bnyro committed Dec 12, 2023
1 parent 391a212 commit 8425a18
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 110 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import com.bnyro.contacts.R
import com.bnyro.contacts.obj.ContactData
import com.bnyro.contacts.obj.FilterOptions
import com.bnyro.contacts.ui.components.base.ClickableIcon
import com.bnyro.contacts.ui.components.base.ElevatedTextInputField
import com.bnyro.contacts.ui.components.base.FullScreenDialog
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
Expand Down Expand Up @@ -74,31 +75,17 @@ fun ContactSearchScreen(
}

Column(Modifier.fillMaxSize()) {
TextField(
ElevatedTextInputField(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 8.dp)
.padding(top = 8.dp)
.focusRequester(focusRequester),
value = searchQuery,
onValueChange = { searchQuery = it },
placeholder = { Text(stringResource(id = R.string.search)) },
leadingIcon = {
Icon(imageVector = Icons.Default.Search, contentDescription = null)
},
trailingIcon = {
if (searchQuery.isNotEmpty()) {
ClickableIcon(icon = Icons.Default.Close) {
searchQuery = ""
}
}
},
shape = RoundedCornerShape(50),
colors = TextFieldDefaults.colors(
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent
),
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done)
.padding(top = 8.dp),
query = searchQuery,
onQueryChange = { searchQuery = it },
leadingIcon = Icons.Default.Search,
placeholder = stringResource(id = R.string.search),
imeAction = ImeAction.Done,
focusRequester = focusRequester
)
ContactsList(
contacts = visibleContacts,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,106 +1,57 @@
package com.bnyro.contacts.ui.components.base

import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SearchBarDefaults
import androidx.compose.material3.Surface
import androidx.compose.material3.TextFieldColors
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.material3.contentColorFor
import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.semantics.onClick
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.zIndex

private val SearchBarIconOffsetX: Dp = 4.dp
private val TonalElevation = 10.dp

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ElevatedTextInputField(
modifier: Modifier = Modifier,
query: String,
onQueryChange: (String) -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
placeholder: @Composable (() -> Unit)? = null,
leadingIcon: @Composable (() -> Unit)? = null,
trailingIcon: @Composable (() -> Unit)? = null,
colors: TextFieldColors = SearchBarDefaults.inputFieldColors(),
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
placeholder: String? = null,
leadingIcon: ImageVector? = null,
imeAction: ImeAction = ImeAction.Default,
focusRequester: FocusRequester = remember { FocusRequester() }
) {
val focusRequester = remember { FocusRequester() }

val elevationColor = MaterialTheme.colorScheme.surfaceColorAtElevation(TonalElevation)
Surface(
shape = RoundedCornerShape(36.dp),
color = elevationColor,
contentColor = contentColorFor(elevationColor),
tonalElevation = TonalElevation,
TextField(
modifier = modifier
.zIndex(1f)
) {
BasicTextField(
value = query,
onValueChange = onQueryChange,
modifier = modifier
.height(SearchBarDefaults.InputFieldHeight)
.fillMaxWidth()
.focusRequester(focusRequester)
.semantics {
onClick {
focusRequester.requestFocus()
true
}
},
enabled = enabled,
textStyle = LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.onBackground),
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Default),
cursorBrush = SolidColor(MaterialTheme.colorScheme.onBackground),
interactionSource = interactionSource,
decorationBox = @Composable { innerTextField ->
TextFieldDefaults.DecorationBox(
value = query,
innerTextField = innerTextField,
enabled = enabled,
singleLine = true,
visualTransformation = VisualTransformation.None,
interactionSource = interactionSource,
placeholder = placeholder,
leadingIcon = leadingIcon?.let { leading ->
{
Box(Modifier.offset(x = SearchBarIconOffsetX)) { leading() }
}
},
trailingIcon = trailingIcon?.let { trailing ->
{
Box(Modifier.offset(x = -SearchBarIconOffsetX)) { trailing() }
}
},
shape = SearchBarDefaults.inputFieldShape,
colors = colors,
contentPadding = TextFieldDefaults.contentPaddingWithoutLabel(),
container = {}
)
.focusRequester(focusRequester),
value = query,
onValueChange = onQueryChange,
placeholder = { placeholder?.let { Text(it) } },
leadingIcon = {
leadingIcon?.let { Icon(imageVector = it, contentDescription = null) }
},
trailingIcon = {
if (query.isNotEmpty()) {
ClickableIcon(icon = Icons.Default.Close) {
onQueryChange("")
}
}
)
}
},
shape = RoundedCornerShape(50),
colors = TextFieldDefaults.colors(
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent
),
keyboardOptions = KeyboardOptions(imeAction = imeAction)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,10 @@ fun SmsThreadScreen(
}

ElevatedTextInputField(
modifier = Modifier
.weight(1f),
modifier = Modifier.weight(1f),
query = text,
onQueryChange = { text = it },
placeholder = {
Text(stringResource(R.string.send))
}
placeholder = stringResource(R.string.send)
)

Spacer(modifier = Modifier.width(8.dp))
Expand Down

0 comments on commit 8425a18

Please sign in to comment.