@Composable
fun CustomTextFieldWithFloatingLabel(
label: String,
modifier: Modifier = Modifier,
isAlphanumericOnly: Boolean = false,
height: Dp = 60.dp,
maxLength: Int = 25,
textColor: Color = colorResource(id = R.color.content_default),
labelColor: Color = colorResource(id = R.color.content_light),
emptyBorderColor: Color = colorResource(id = R.color.border_default),
filledBorderColor: Color = colorResource(id = R.color.border_default),
cornerRadius: Dp = 12.dp,
borderWidth: Dp = 1.dp,
keyboardType: KeyboardType = KeyboardType.Text,
imeAction: ImeAction = ImeAction.Next,
focusedLabelFontSize: TextUnit = 12.sp,
unfocusedLabelFontSize: TextUnit = 16.sp,
textFontSize: TextUnit = 16.sp,
isSingleLine: Boolean = true,
@DrawableRes trailingIcon: Int? = null,
trailingIconText: String? = null,
text: String,
isEnabled: Boolean = true,
isReadOnly: Boolean = false,
isAllCaps: Boolean = false,
onTextChange: (String) -> Unit,
onClick: (() -> Unit)? = null // Make onClick optional
) {
var isFocused by remember { mutableStateOf(false) }
val interactionSource = remember { MutableInteractionSource() }
TextField(
value = if (isAllCaps) text.trimStart().uppercase() else text.trimStart(),
onValueChange = { newText ->
val filteredText =
if (isAlphanumericOnly) newText.filter { it.isLetterOrDigit() } else newText
if (newText.length <= maxLength) {
onTextChange(filteredText)
}
},
singleLine = isSingleLine,
enabled = isEnabled,
readOnly = isReadOnly,
keyboardOptions = KeyboardOptions(
keyboardType = keyboardType,
imeAction = imeAction
),
modifier = modifier
.fillMaxWidth()
.height(height)
.onFocusChanged { focusState ->
isFocused = focusState.isFocused
}
.border(
width = borderWidth,
color = if (text.isNotEmpty()) filledBorderColor else emptyBorderColor,
shape = RoundedCornerShape(cornerRadius)
)
.then(if (onClick != null) Modifier.clickable(interactionSource = interactionSource) { onClick() } else Modifier), // Conditionally add clickable
label = {
Text(
text = label,
color = labelColor,
fontSize = if (isFocused || text.isNotEmpty()) focusedLabelFontSize else unfocusedLabelFontSize,
)
},
textStyle = TextStyle(fontSize = textFontSize),
trailingIcon = {
Row(
verticalAlignment = Alignment.CenterVertically
) {
if (trailingIcon != null) {
Icon(
painter = painterResource(id = trailingIcon),
tint = Color.Unspecified,
contentDescription = null
)
}
if (!trailingIconText.isNullOrEmpty()) {
Spacer(modifier = Modifier.width(4.dp))
Text(
text = trailingIconText,
color = textColor,
fontSize = textFontSize
)
Spacer(modifier = Modifier.width(16.dp))
}
}
},
colors = TextFieldDefaults.colors(
focusedContainerColor = Color.Transparent,
unfocusedContainerColor = Color.Transparent,
disabledContainerColor = Color.Transparent,
cursorColor = textColor,
focusedTextColor = textColor,
unfocusedTextColor = textColor,
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent,
disabledIndicatorColor = Color.Transparent,
)
)
// Handle the click interaction
LaunchedEffect(interactionSource) {
interactionSource.interactions.collect {
if (it is PressInteraction.Release) {
onClick?.invoke() // Only trigger if onClick is provided
}
}
}
}