Skip to content

Commit 0181f08

Browse files
committed
library: textfield: Add useLabelAsPlaceholder
1 parent 8fc39ae commit 0181f08

File tree

2 files changed

+67
-26
lines changed

2 files changed

+67
-26
lines changed

composeApp/src/commonMain/kotlin/component/OtherComponent.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ fun OtherComponent(padding: PaddingValues) {
4040
val focusManager = LocalFocusManager.current
4141
var text1 by remember { mutableStateOf("") }
4242
var text2 by remember { mutableStateOf(TextFieldValue("")) }
43+
var text3 by remember { mutableStateOf("") }
4344
var progress by remember { mutableStateOf(0.5f) }
4445
val progressDisable by remember { mutableStateOf(0.5f) }
4546
val tabTexts =
@@ -119,6 +120,19 @@ fun OtherComponent(padding: PaddingValues) {
119120
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done)
120121
)
121122

123+
TextField(
124+
value = text3,
125+
onValueChange = { text3 = it },
126+
backgroundColor = MiuixTheme.colorScheme.secondaryContainer,
127+
label = "Use Label As Placeholder",
128+
useLabelAsPlaceholder = true,
129+
modifier = Modifier
130+
.padding(horizontal = 12.dp)
131+
.padding(bottom = 12.dp),
132+
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
133+
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done)
134+
)
135+
122136
SmallTitle(text = "Slider")
123137
Slider(
124138
progress = progress,

miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/basic/TextField.kt

Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ package top.yukonga.miuix.kmp.basic
22

33
import androidx.compose.animation.animateColorAsState
44
import androidx.compose.animation.core.animateDpAsState
5+
import androidx.compose.animation.core.spring
6+
import androidx.compose.animation.fadeIn
7+
import androidx.compose.animation.fadeOut
58
import androidx.compose.foundation.background
69
import androidx.compose.foundation.border
710
import androidx.compose.foundation.interaction.MutableInteractionSource
@@ -48,6 +51,7 @@ import top.yukonga.miuix.kmp.utils.SmoothRoundedCornerShape
4851
* @param cornerRadius The corner radius of the [TextField].
4952
* @param label The label to be displayed when the [TextField] is empty.
5053
* @param labelColor The color of the label.
54+
* @param useLabelAsPlaceholder Whether to use the label as a placeholder.
5155
* @param enabled Whether the [TextField] is enabled.
5256
* @param readOnly Whether the [TextField] is read-only.
5357
* @param textStyle The text style to be applied to the [TextField].
@@ -73,6 +77,7 @@ fun TextField(
7377
cornerRadius: Dp = 18.dp,
7478
label: String = "",
7579
labelColor: Color = MiuixTheme.colorScheme.onSecondaryContainer,
80+
useLabelAsPlaceholder: Boolean = false,
7681
enabled: Boolean = true,
7782
readOnly: Boolean = false,
7883
textStyle: TextStyle = MiuixTheme.textStyles.main,
@@ -98,12 +103,12 @@ fun TextField(
98103
val isFocused by interactionSource.collectIsFocusedAsState()
99104
val borderWidth by animateDpAsState(if (isFocused) 2.dp else 0.dp)
100105
val borderColor by animateColorAsState(if (isFocused) MiuixTheme.colorScheme.primary else backgroundColor)
101-
val labelOffsetY by animateDpAsState(if (value.text.isNotEmpty()) -(insideMargin.height / 2) else 0.dp)
102-
val innerTextOffsetY by animateDpAsState(if (value.text.isNotEmpty()) (insideMargin.height / 2) else 0.dp)
103-
val labelFontSize by animateDpAsState(if (value.text.isNotEmpty()) 10.dp else 16.dp)
106+
val labelOffsetY by animateDpAsState(if (value.text.isNotEmpty() && useLabelAsPlaceholder == false) -(insideMargin.height / 2) else 0.dp)
107+
val innerTextOffsetY by animateDpAsState(if (value.text.isNotEmpty() && useLabelAsPlaceholder == false) (insideMargin.height / 2) else 0.dp)
108+
val labelFontSize by animateDpAsState(if (value.text.isNotEmpty() && useLabelAsPlaceholder == false) 10.dp else 16.dp)
104109
val border = Modifier.border(borderWidth, borderColor, RoundedCornerShape(cornerRadius))
105-
val labelOffset = if (label != "") Modifier.offset(y = labelOffsetY) else Modifier
106-
val innerTextOffset = if (label != "") Modifier.offset(y = innerTextOffsetY) else Modifier
110+
val labelOffset = if (label != "" && useLabelAsPlaceholder == false) Modifier.offset(y = labelOffsetY) else Modifier
111+
val innerTextOffset = if (label != "" && useLabelAsPlaceholder == false) Modifier.offset(y = innerTextOffsetY) else Modifier
107112

108113
BasicTextField(
109114
value = value,
@@ -144,14 +149,24 @@ fun TextField(
144149
.weight(1f)
145150
.then(paddingModifier)
146151
) {
147-
Text(
148-
text = label,
149-
textAlign = TextAlign.Start,
150-
fontWeight = FontWeight.Medium,
151-
fontSize = labelFontSize.value.sp,
152-
modifier = Modifier.then(labelOffset),
153-
color = labelColor
154-
)
152+
androidx.compose.animation.AnimatedVisibility(
153+
visible = if (useLabelAsPlaceholder) value.text.isEmpty() else true,
154+
enter = fadeIn(
155+
spring(stiffness = 2500f)
156+
),
157+
exit = fadeOut(
158+
spring(stiffness = 5000f)
159+
)
160+
) {
161+
Text(
162+
text = label,
163+
textAlign = TextAlign.Start,
164+
fontWeight = FontWeight.Medium,
165+
fontSize = labelFontSize.value.sp,
166+
modifier = Modifier.then(labelOffset),
167+
color = labelColor
168+
)
169+
}
155170
Box(
156171
modifier = Modifier.then(innerTextOffset),
157172
contentAlignment = Alignment.BottomStart
@@ -179,6 +194,7 @@ fun TextField(
179194
* @param cornerRadius The corner radius of the [TextField].
180195
* @param label The label to be displayed when the [TextField] is empty.
181196
* @param labelColor The color of the label.
197+
* @param useLabelAsPlaceholder Whether to use the label as a placeholder.
182198
* @param enabled Whether the [TextField] is enabled.
183199
* @param readOnly Whether the [TextField] is read-only.
184200
* @param textStyle The text style to be applied to the [TextField].
@@ -204,6 +220,7 @@ fun TextField(
204220
cornerRadius: Dp = 16.dp,
205221
label: String = "",
206222
labelColor: Color = MiuixTheme.colorScheme.onSecondaryContainer,
223+
useLabelAsPlaceholder: Boolean = false,
207224
enabled: Boolean = true,
208225
readOnly: Boolean = false,
209226
textStyle: TextStyle = MiuixTheme.textStyles.main,
@@ -229,12 +246,12 @@ fun TextField(
229246
val isFocused by interactionSource.collectIsFocusedAsState()
230247
val borderWidth by animateDpAsState(if (isFocused) 2.0.dp else 0.dp)
231248
val borderColor by animateColorAsState(if (isFocused) MiuixTheme.colorScheme.primary else backgroundColor)
232-
val labelOffsetY by animateDpAsState(if (value.isNotEmpty()) -(insideMargin.height / 2) else 0.dp)
233-
val innerTextOffsetY by animateDpAsState(if (value.isNotEmpty()) (insideMargin.height / 2) else 0.dp)
234-
val labelFontSize by animateDpAsState(if (value.isNotEmpty()) 10.dp else 16.dp)
249+
val labelOffsetY by animateDpAsState(if (value.isNotEmpty() && useLabelAsPlaceholder == false) -(insideMargin.height / 2) else 0.dp)
250+
val innerTextOffsetY by animateDpAsState(if (value.isNotEmpty() && useLabelAsPlaceholder == false) (insideMargin.height / 2) else 0.dp)
251+
val labelFontSize by animateDpAsState(if (value.isNotEmpty() && useLabelAsPlaceholder == false) 10.dp else 16.dp)
235252
val border = Modifier.border(borderWidth, borderColor, RoundedCornerShape(cornerRadius))
236-
val labelOffset = if (label != "") Modifier.offset(y = labelOffsetY) else Modifier
237-
val innerTextOffset = if (label != "") Modifier.offset(y = innerTextOffsetY) else Modifier
253+
val labelOffset = if (label != "" && useLabelAsPlaceholder == false) Modifier.offset(y = labelOffsetY) else Modifier
254+
val innerTextOffset = if (label != "" && useLabelAsPlaceholder == false) Modifier.offset(y = innerTextOffsetY) else Modifier
238255

239256
BasicTextField(
240257
value = value,
@@ -274,14 +291,24 @@ fun TextField(
274291
.weight(1f)
275292
.then(paddingModifier)
276293
) {
277-
Text(
278-
text = label,
279-
textAlign = TextAlign.Start,
280-
fontWeight = FontWeight.Medium,
281-
fontSize = labelFontSize.value.sp,
282-
modifier = Modifier.then(labelOffset),
283-
color = labelColor
284-
)
294+
androidx.compose.animation.AnimatedVisibility(
295+
visible = if (useLabelAsPlaceholder) value.isEmpty() else true,
296+
enter = fadeIn(
297+
spring(stiffness = 2500f)
298+
),
299+
exit = fadeOut(
300+
spring(stiffness = 5000f)
301+
)
302+
) {
303+
Text(
304+
text = label,
305+
textAlign = TextAlign.Start,
306+
fontWeight = FontWeight.Medium,
307+
fontSize = labelFontSize.value.sp,
308+
modifier = Modifier.then(labelOffset),
309+
color = labelColor
310+
)
311+
}
285312
Box(
286313
modifier = Modifier.then(innerTextOffset),
287314
contentAlignment = Alignment.BottomStart

0 commit comments

Comments
 (0)