Skip to content

Commit 786c2ad

Browse files
committed
design(text field) : allow setting validity (instead of just isError bool)
1 parent 498f63e commit 786c2ad

File tree

6 files changed

+59
-31
lines changed

6 files changed

+59
-31
lines changed

features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight
2929
import io.element.android.libraries.designsystem.theme.components.Button
3030
import io.element.android.libraries.designsystem.theme.components.ModalBottomSheet
3131
import io.element.android.libraries.designsystem.theme.components.TextField
32+
import io.element.android.libraries.designsystem.theme.components.TextFieldValidity
3233
import io.element.android.libraries.ui.strings.CommonStrings
3334

3435
@OptIn(ExperimentalMaterial3Api::class)
@@ -98,7 +99,11 @@ private fun RoomAddressField(
9899
"e.g. #room-name:matrix.org"
99100
}
100101
},
101-
isError = addressState is RoomAddressState.Invalid,
102+
validity = when (addressState) {
103+
RoomAddressState.Unknown -> null
104+
RoomAddressState.Invalid -> TextFieldValidity.Invalid
105+
is RoomAddressState.Valid -> if (addressState.matchingRoomFound) TextFieldValidity.Valid else null
106+
},
102107
onValueChange = onAddressChange,
103108
singleLine = true,
104109
)

features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight
4545
import io.element.android.libraries.designsystem.preview.debugPlaceholderBackground
4646
import io.element.android.libraries.designsystem.theme.components.Button
4747
import io.element.android.libraries.designsystem.theme.components.TextField
48+
import io.element.android.libraries.designsystem.theme.components.TextFieldValidity
4849
import io.element.android.libraries.ui.strings.CommonStrings
4950

5051
@Composable
@@ -90,7 +91,7 @@ fun BugReportView(
9091
keyboardController?.hide()
9192
}),
9293
minLines = 3,
93-
isError = state.isDescriptionInError,
94+
validity = if(state.isDescriptionInError) TextFieldValidity.Invalid else null,
9495
)
9596
}
9697
Spacer(modifier = Modifier.height(16.dp))

features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/reset/password/ResetIdentityPasswordView.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight
3333
import io.element.android.libraries.designsystem.theme.components.Button
3434
import io.element.android.libraries.designsystem.theme.components.Icon
3535
import io.element.android.libraries.designsystem.theme.components.TextField
36+
import io.element.android.libraries.designsystem.theme.components.TextFieldValidity
3637
import io.element.android.libraries.ui.strings.CommonStrings
3738

3839
@Composable
@@ -82,8 +83,8 @@ private fun Content(text: String, onTextChange: (String) -> Unit, hasError: Bool
8283
var showPassword by remember { mutableStateOf(false) }
8384
TextField(
8485
modifier = Modifier
85-
.fillMaxWidth()
86-
.onTabOrEnterKeyFocusNext(LocalFocusManager.current),
86+
.fillMaxWidth()
87+
.onTabOrEnterKeyFocusNext(LocalFocusManager.current),
8788
value = text,
8889
onValueChange = onTextChange,
8990
placeholder = stringResource(CommonStrings.common_password),
@@ -99,7 +100,7 @@ private fun Content(text: String, onTextChange: (String) -> Unit, hasError: Bool
99100
Icon(imageVector = image, description)
100101
}
101102
},
102-
isError = hasError,
103+
validity = if (hasError) TextFieldValidity.Invalid else null,
103104
supportingText = if (hasError) {
104105
stringResource(R.string.screen_reset_encryption_password_error)
105106
} else {

libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/TextField.kt

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ fun TextField(
5858
placeholder: String? = null,
5959
leadingIcon: @Composable (() -> Unit)? = null,
6060
trailingIcon: @Composable (() -> Unit)? = null,
61-
isError: Boolean = false,
61+
validity: TextFieldValidity? = null,
6262
enabled: Boolean = true,
6363
readOnly: Boolean = false,
6464
singleLine: Boolean = false,
@@ -93,7 +93,7 @@ fun TextField(
9393
readOnly = readOnly,
9494
enabled = enabled,
9595
isFocused = isFocused,
96-
isError = isError,
96+
validity = validity,
9797
leadingIcon = leadingIcon,
9898
placeholder = placeholder,
9999
isTextEmpty = value.isEmpty(),
@@ -114,7 +114,7 @@ fun TextField(
114114
placeholder: String? = null,
115115
leadingIcon: @Composable (() -> Unit)? = null,
116116
trailingIcon: @Composable (() -> Unit)? = null,
117-
isError: Boolean = false,
117+
validity: TextFieldValidity? = null,
118118
enabled: Boolean = true,
119119
readOnly: Boolean = false,
120120
singleLine: Boolean = false,
@@ -149,7 +149,7 @@ fun TextField(
149149
readOnly = readOnly,
150150
enabled = enabled,
151151
isFocused = isFocused,
152-
isError = isError,
152+
validity = validity,
153153
leadingIcon = leadingIcon,
154154
placeholder = placeholder,
155155
isTextEmpty = value.text.isEmpty(),
@@ -166,7 +166,7 @@ private fun DecorationBox(
166166
enabled: Boolean,
167167
readOnly: Boolean,
168168
isFocused: Boolean,
169-
isError: Boolean,
169+
validity: TextFieldValidity?,
170170
placeholder: String?,
171171
isTextEmpty: Boolean,
172172
supportingText: String?,
@@ -187,7 +187,7 @@ private fun DecorationBox(
187187
enabled = enabled,
188188
readOnly = readOnly,
189189
isFocused = isFocused,
190-
isError = isError
190+
isError = validity == TextFieldValidity.Invalid
191191
) {
192192
Row(modifier = Modifier.padding(16.dp)) {
193193
if (leadingIcon != null) {
@@ -216,7 +216,7 @@ private fun DecorationBox(
216216
}
217217
if (supportingText != null) {
218218
Spacer(modifier = Modifier.height(4.dp))
219-
SupportingTextLayout(isError, supportingText)
219+
SupportingTextLayout(validity, supportingText)
220220
}
221221
}
222222
}
@@ -254,24 +254,44 @@ private fun TextFieldContainer(
254254
}
255255

256256
@Composable
257-
private fun SupportingTextLayout(isError: Boolean, supportingText: String) {
257+
private fun SupportingTextLayout(validity: TextFieldValidity?, supportingText: String) {
258258
Row(horizontalArrangement = spacedBy(4.dp)) {
259-
if (isError) {
260-
Icon(
261-
imageVector = CompoundIcons.Error(),
262-
contentDescription = null,
263-
modifier = Modifier.size(16.dp),
264-
tint = ElementTheme.colors.iconCriticalPrimary
265-
)
259+
when (validity) {
260+
TextFieldValidity.Invalid -> {
261+
Icon(
262+
imageVector = CompoundIcons.Error(),
263+
contentDescription = null,
264+
modifier = Modifier.size(16.dp),
265+
tint = ElementTheme.colors.iconCriticalPrimary
266+
)
267+
}
268+
TextFieldValidity.Valid -> {
269+
Icon(
270+
imageVector = CompoundIcons.CheckCircleSolid(),
271+
contentDescription = null,
272+
modifier = Modifier.size(16.dp),
273+
tint = ElementTheme.colors.iconSuccessPrimary
274+
)
275+
}
276+
else -> Unit
266277
}
267278
Text(
268279
text = supportingText,
269-
color = if (isError) ElementTheme.colors.textCriticalPrimary else ElementTheme.colors.textSecondary,
280+
color = when (validity) {
281+
TextFieldValidity.Invalid -> ElementTheme.colors.textCriticalPrimary
282+
TextFieldValidity.Valid -> ElementTheme.colors.textSuccessPrimary
283+
else -> ElementTheme.colors.textSecondary
284+
},
270285
style = ElementTheme.typography.fontBodySmRegular,
271286
)
272287
}
273288
}
274289

290+
enum class TextFieldValidity {
291+
Invalid,
292+
Valid
293+
}
294+
275295
@Composable
276296
private fun textFieldStyle(enabled: Boolean): TextStyle {
277297
return ElementTheme.typography.fontBodyLgRegular.copy(
@@ -283,27 +303,27 @@ private fun textFieldStyle(enabled: Boolean): TextStyle {
283303
)
284304
}
285305

286-
@Preview(group = PreviewGroup.TextFields)
306+
@Preview(group = PreviewGroup.TextFields, heightDp = 1000)
287307
@Composable
288308
internal fun TextFieldsLightPreview() = ElementPreviewLight { ContentToPreview() }
289309

290-
@Preview(group = PreviewGroup.TextFields)
310+
@Preview(group = PreviewGroup.TextFields, heightDp = 1000)
291311
@Composable
292312
internal fun TextFieldsDarkPreview() = ElementPreviewDark { ContentToPreview() }
293313

294314
@Composable
295315
@ExcludeFromCoverage
296316
private fun ContentToPreview() {
297317
Column(modifier = Modifier.padding(4.dp)) {
298-
allBooleans.forEach { isError ->
318+
TextFieldValidity.entries.forEach { validity ->
299319
allBooleans.forEach { enabled ->
300320
allBooleans.forEach { readonly ->
301321
TextField(
302322
onValueChange = {},
303323
label = "Label",
304-
value = "Hello er=${isError.asInt()}, en=${enabled.asInt()}, ro=${readonly.asInt()}",
324+
value = "Hello val=${validity}, en=${enabled.asInt()}, ro=${readonly.asInt()}",
305325
supportingText = "Supporting text",
306-
isError = isError,
326+
validity = validity,
307327
enabled = enabled,
308328
readOnly = readonly,
309329
)

libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/address/RoomAddressField.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import io.element.android.libraries.designsystem.preview.ElementPreview
1515
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
1616
import io.element.android.libraries.designsystem.theme.components.Text
1717
import io.element.android.libraries.designsystem.theme.components.TextField
18+
import io.element.android.libraries.designsystem.theme.components.TextFieldValidity
1819
import io.element.android.libraries.testtags.TestTags
1920
import io.element.android.libraries.testtags.testTag
2021
import io.element.android.libraries.ui.strings.CommonStrings
@@ -56,7 +57,10 @@ fun RoomAddressField(
5657
}
5758
else -> supportingText
5859
},
59-
isError = addressValidity.isError(),
60+
validity = when (addressValidity) {
61+
RoomAddressValidity.InvalidSymbols, RoomAddressValidity.NotAvailable -> TextFieldValidity.Invalid
62+
else -> null
63+
},
6064
onValueChange = onAddressChange,
6165
singleLine = true,
6266
)

libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/address/RoomAddressValidity.kt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
package io.element.android.libraries.matrix.ui.room.address
99

1010
import androidx.compose.runtime.Immutable
11+
import io.element.android.libraries.designsystem.theme.components.TextFieldValidity
1112

1213
/**
1314
* Represents the validity state of a room address.
@@ -19,8 +20,4 @@ sealed interface RoomAddressValidity {
1920
data object InvalidSymbols : RoomAddressValidity
2021
data object NotAvailable : RoomAddressValidity
2122
data object Valid : RoomAddressValidity
22-
23-
fun isError(): Boolean {
24-
return this is InvalidSymbols || this is NotAvailable
25-
}
2623
}

0 commit comments

Comments
 (0)