Skip to content

Instantly share code, notes, and snippets.

@ch8n
Created October 10, 2021 08:20
Show Gist options
  • Save ch8n/ad2f3ff524c67bb9218efb1ce18c93bc to your computer and use it in GitHub Desktop.
Save ch8n/ad2f3ff524c67bb9218efb1ce18c93bc to your computer and use it in GitHub Desktop.
package com.proptiger.ui.components.edittext
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.material.Divider
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.CheckCircle
import androidx.compose.material.icons.filled.Error
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusState
import androidx.compose.ui.focus.onFocusEvent
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.proptiger.R
import com.proptiger.ui.components.utils.Preview
import com.proptiger.ui.theme.textStyle18spSemibold
data class EditTextState(
val hint: String,
val isError: Boolean,
val maxLines: Int = 1,
val tailingResId: Int,
val errorResId: Int,
val errorMessage: String = "Something Went Wrong!",
val isValid: Boolean = false
)
@ExperimentalAnimationApi
@Composable
fun PTEditText(
state: State<EditTextState>,
onTextChanged: (String) -> Unit = {},
onFocusChanged: (isFocused: Boolean) -> Unit = {},
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(start = 16.dp, end = 16.dp)
.height(75.dp)
) {
var editTextValue by remember { mutableStateOf(TextFieldValue("")) }
var isHintVisible by remember { mutableStateOf(false) }
var isEditTextFocused by remember { mutableStateOf(false) }
if (isHintVisible) {
Text(
text = state.value.hint,
style = MaterialTheme.typography.body2,
color = if (state.value.isError) {
Color.Red
} else {
Color.Unspecified
}
)
Spacer(modifier = Modifier.height(5.dp))
} else {
Spacer(
modifier = Modifier
.width(200.dp)
.height(19.dp)
)
}
Box(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight(),
contentAlignment = Alignment.Center
) {
BasicTextField(
value = editTextValue,
onValueChange = {
editTextValue = it
onTextChanged.invoke(it.text)
},
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.onFocusEvent { ft: FocusState ->
if (ft.isFocused) {
isHintVisible = true
}
isEditTextFocused = ft.isFocused
onFocusChanged.invoke(ft.isFocused)
},
singleLine = state.value.maxLines == 1,
maxLines = state.value.maxLines,
decorationBox = { innerTextField ->
Row(
verticalAlignment = Alignment.CenterVertically
) {
if (editTextValue.text.isEmpty()) {
isHintVisible = false
if (!isEditTextFocused) {
Text(
text = state.value.hint,
style = MaterialTheme.typography.body2,
color = if (state.value.isError) {
Color.Red
} else {
Color.Unspecified
},
)
}
}
innerTextField() //<-- Add this
}
},
textStyle = textStyle18spSemibold
)
if (state.value.isValid) {
Box(
modifier = Modifier
.fillMaxWidth()
.padding(end = 8.dp)
.wrapContentHeight(),
contentAlignment = Alignment.CenterEnd
) {
Icon(
contentDescription = "",
modifier = Modifier.size(16.dp),
imageVector = Icons.Filled.CheckCircle,
tint = Color.Green
)
}
}
}
Spacer(modifier = Modifier.height(6.dp))
Box(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight(),
contentAlignment = Alignment.Center
) {
Divider(
color = if (state.value.isError) {
Color.Red
} else {
Color.LightGray
},
)
}
if (state.value.isError) {
Spacer(modifier = Modifier.height(3.dp))
Column(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight(),
horizontalAlignment = Alignment.End
) {
Row {
Icon(
contentDescription = "",
modifier = Modifier.size(16.dp),
imageVector = Icons.Filled.Error,
tint = Color.Red
)
Spacer(modifier = Modifier.width(14.dp))
Text(
state.value.errorMessage,
color = Color.Red,
maxLines = 1
)
}
}
}
}
}
@ExperimentalAnimationApi
@Preview
@Composable
fun PTEditTextPreview() {
Preview {
val state = EditTextState(
hint = "Name",
isError = false,
errorMessage = "are you sure this is valid name?",
tailingResId = R.drawable.ic_launcher_foreground,
errorResId = R.drawable.ic_launcher_foreground,
isValid = true
)
Column {
PTEditText(
state = remember { mutableStateOf(state.copy(isError = true, isValid = false)) },
onTextChanged = {
// value should be collected from here
},
onFocusChanged = {
// should do validation and error state step up here
}
)
PTEditText(
state = remember { mutableStateOf(state) },
onTextChanged = {
// value should be collected from here
},
onFocusChanged = {
// should do validation and error state step up here
}
)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment