Add asterisk as required indicator to TextField atoms

This commit is contained in:
Wolf-Martell Montwé 2023-05-12 12:17:12 +02:00
parent 8f02a9e279
commit 9ea4d8045a
No known key found for this signature in database
GPG key ID: 6D45B21512ACBF72
6 changed files with 189 additions and 13 deletions

View file

@ -44,6 +44,27 @@ private fun LazyGridScope.textFieldOutlinedItems() {
)
}
}
item {
WithRememberedState(input = "Input text required") { state ->
TextFieldOutlined(
value = state.value,
label = "Label",
onValueChange = { state.value = it },
isRequired = true,
)
}
}
item {
WithRememberedState(input = "Input text required with error") { state ->
TextFieldOutlined(
value = state.value,
label = "Label",
onValueChange = { state.value = it },
isRequired = true,
isError = true,
)
}
}
}
private fun LazyGridScope.passwordTextFieldOutlinedItems() {
@ -68,15 +89,36 @@ private fun LazyGridScope.passwordTextFieldOutlinedItems() {
}
}
item {
WithRememberedState(input = "Password disabled") { state ->
WithRememberedState(input = "Password") { state ->
TextFieldOutlinedPassword(
value = state.value,
label = "Password",
label = "Password disabled",
onValueChange = { state.value = it },
enabled = false,
)
}
}
item {
WithRememberedState(input = "Password") { state ->
TextFieldOutlinedPassword(
value = state.value,
label = "Password required",
onValueChange = { state.value = it },
isRequired = true,
)
}
}
item {
WithRememberedState(input = "Password") { state ->
TextFieldOutlinedPassword(
value = state.value,
label = "Password required with error",
onValueChange = { state.value = it },
isRequired = true,
isError = true,
)
}
}
}
private fun LazyGridScope.emailTextFieldOutlinedItems() {
@ -101,13 +143,34 @@ private fun LazyGridScope.emailTextFieldOutlinedItems() {
}
}
item {
WithRememberedState(input = "email@example.com disabled") { state ->
WithRememberedState(input = "email@example.com") { state ->
TextFieldOutlinedEmailAddress(
value = state.value,
label = "Email address",
label = "Email address disabled",
onValueChange = { state.value = it },
enabled = false,
)
}
}
item {
WithRememberedState(input = "email@example.com") { state ->
TextFieldOutlinedEmailAddress(
value = state.value,
label = "Email address required",
onValueChange = { state.value = it },
isRequired = true,
)
}
}
item {
WithRememberedState(input = "email@example.com") { state ->
TextFieldOutlinedEmailAddress(
value = state.value,
label = "Email address required with error",
onValueChange = { state.value = it },
isRequired = true,
isError = true,
)
}
}
}

View file

@ -2,13 +2,67 @@ package app.k9mail.core.ui.compose.designsystem.atom.textfield
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.theme.PreviewWithThemes
internal fun selectLabel(label: String?): @Composable (() -> Unit)? {
return if (label != null) {
internal fun selectLabel(
label: String?,
isRequired: Boolean,
): @Composable (() -> Unit)? {
return if (label != null || isRequired) {
{
Text(text = label)
TextFieldLabel(label.orEmpty(), isRequired)
}
} else {
null
}
}
@Composable
internal fun TextFieldLabel(
label: String,
isRequired: Boolean,
) {
Text(
text = if (isRequired) {
"$label$ASTERISK"
} else {
label
},
)
}
private const val ASTERISK = "*"
@Preview(showBackground = true)
@Composable
fun TextFieldLabelPreview() {
PreviewWithThemes {
TextFieldLabel(
label = "Label",
isRequired = false,
)
}
}
@Preview(showBackground = true)
@Composable
fun TextFieldLabelRequiredPreview() {
PreviewWithThemes {
TextFieldLabel(
label = "Label",
isRequired = true,
)
}
}
@Preview(showBackground = true)
@Composable
fun TextFieldLabelRequiredEmptyLabelPreview() {
PreviewWithThemes {
TextFieldLabel(
label = "",
isRequired = true,
)
}
}

View file

@ -13,6 +13,7 @@ fun TextFieldOutlined(
modifier: Modifier = Modifier,
enabled: Boolean = true,
label: String? = null,
isRequired: Boolean = false,
isError: Boolean = false,
) {
MaterialOutlinedTextField(
@ -20,7 +21,7 @@ fun TextFieldOutlined(
onValueChange = onValueChange,
modifier = modifier,
enabled = enabled,
label = selectLabel(label),
label = selectLabel(label, isRequired),
isError = isError,
)
}
@ -71,3 +72,16 @@ internal fun TextFieldOutlinedErrorPreview() {
)
}
}
@Preview(showBackground = true)
@Composable
internal fun TextFieldOutlinedRequiredPreview() {
PreviewWithThemes {
TextFieldOutlined(
value = "",
onValueChange = {},
label = "Label",
isRequired = true,
)
}
}

View file

@ -15,6 +15,7 @@ fun TextFieldOutlinedEmailAddress(
modifier: Modifier = Modifier,
enabled: Boolean = true,
label: String? = null,
isRequired: Boolean = false,
isError: Boolean = false,
) {
MaterialOutlinedTextField(
@ -22,7 +23,7 @@ fun TextFieldOutlinedEmailAddress(
onValueChange = onValueChange,
modifier = modifier,
enabled = enabled,
label = selectLabel(label),
label = selectLabel(label, isRequired),
isError = isError,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Email,

View file

@ -26,6 +26,7 @@ fun TextFieldOutlinedPassword(
modifier: Modifier = Modifier,
enabled: Boolean = true,
label: String? = null,
isRequired: Boolean = false,
isError: Boolean = false,
) {
var passwordVisibilityState by rememberSaveable { mutableStateOf(false) }
@ -35,7 +36,7 @@ fun TextFieldOutlinedPassword(
onValueChange = onValueChange,
modifier = modifier,
enabled = enabled,
label = selectLabel(label),
label = selectLabel(label, isRequired),
trailingIcon = selectTrailingIcon(
isEnabled = enabled,
isPasswordVisible = passwordVisibilityState,

View file

@ -28,6 +28,7 @@ data class TextFieldTestData(
modifier: Modifier,
enabled: Boolean?,
label: String?,
isRequired: Boolean,
) -> Unit,
)
@ -49,6 +50,7 @@ class TextFieldKtTest(
modifier = Modifier.testTag(testSubjectName),
enabled = null,
label = null,
isRequired = false,
)
}
@ -67,6 +69,7 @@ class TextFieldKtTest(
modifier = Modifier.testTag(testSubjectName),
enabled = null,
label = null,
isRequired = false,
)
}
@ -82,6 +85,7 @@ class TextFieldKtTest(
modifier = Modifier.testTag(testSubjectName),
enabled = false,
label = null,
isRequired = false,
)
}
@ -97,12 +101,45 @@ class TextFieldKtTest(
modifier = Modifier.testTag(testSubjectName),
enabled = null,
label = LABEL,
isRequired = false,
)
}
onNodeWithText(LABEL).assertIsDisplayed()
}
@Test
fun `should show asterisk when isRequired is true`() = runComposeTest {
setContent {
testSubject(
value = VALUE,
onValueChange = {},
modifier = Modifier.testTag(testSubjectName),
enabled = null,
label = LABEL,
isRequired = true,
)
}
onNodeWithText("$LABEL*").assertIsDisplayed()
}
@Test
fun `should not show asterisk when isRequired is false`() = runComposeTest {
setContent {
testSubject(
value = VALUE,
onValueChange = {},
modifier = Modifier.testTag(testSubjectName),
enabled = null,
label = LABEL,
isRequired = false,
)
}
onNodeWithText("$LABEL*").assertDoesNotExist()
}
companion object {
@JvmStatic
@ParameterizedRobolectricTestRunner.Parameters(name = "{0}")
@ -110,7 +147,7 @@ class TextFieldKtTest(
fun data(): List<TextFieldTestData> = listOf(
TextFieldTestData(
name = "TextFieldOutlined",
content = { value, onValueChange, modifier, enabled, label ->
content = { value, onValueChange, modifier, enabled, label, isRequired ->
if (enabled != null) {
TextFieldOutlined(
value = value,
@ -118,6 +155,7 @@ class TextFieldKtTest(
modifier = modifier,
enabled = enabled,
label = label,
isRequired = isRequired,
)
} else {
TextFieldOutlined(
@ -125,13 +163,14 @@ class TextFieldKtTest(
onValueChange = onValueChange,
modifier = modifier,
label = label,
isRequired = isRequired,
)
}
},
),
TextFieldTestData(
name = "TextFieldOutlinedPassword",
content = { value, onValueChange, modifier, enabled, label ->
content = { value, onValueChange, modifier, enabled, label, isRequired ->
if (enabled != null) {
TextFieldOutlinedPassword(
value = value,
@ -139,6 +178,7 @@ class TextFieldKtTest(
modifier = modifier,
enabled = enabled,
label = label,
isRequired = isRequired,
)
} else {
TextFieldOutlinedPassword(
@ -146,13 +186,14 @@ class TextFieldKtTest(
onValueChange = onValueChange,
modifier = modifier,
label = label,
isRequired = isRequired,
)
}
},
),
TextFieldTestData(
name = "TextFieldOutlinedEmail",
content = { value, onValueChange, modifier, enabled, label ->
content = { value, onValueChange, modifier, enabled, label, isRequired ->
if (enabled != null) {
TextFieldOutlinedEmailAddress(
value = value,
@ -160,6 +201,7 @@ class TextFieldKtTest(
modifier = modifier,
enabled = enabled,
label = label,
isRequired = isRequired,
)
} else {
TextFieldOutlinedEmailAddress(
@ -167,6 +209,7 @@ class TextFieldKtTest(
onValueChange = onValueChange,
modifier = modifier,
label = label,
isRequired = isRequired,
)
}
},