-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ANDROAPP-5506-mobile-ui-Create-Input-Letter-component (#47)
* Create component and implement functionality * Implement tests for component * Add error example and default values for SupportingText component * ktlint style fix * ktlint
- Loading branch information
1 parent
9fa87fa
commit 782861f
Showing
6 changed files
with
428 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
146 changes: 146 additions & 0 deletions
146
common/src/commonMain/kotlin/org/hisp/dhis/common/screens/InputLetterScreen.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
package org.hisp.dhis.common.screens | ||
|
||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.getValue | ||
import androidx.compose.runtime.mutableStateOf | ||
import androidx.compose.runtime.saveable.rememberSaveable | ||
import androidx.compose.runtime.setValue | ||
import androidx.compose.ui.text.input.ImeAction | ||
import org.hisp.dhis.mobile.ui.designsystem.component.ColumnComponentContainer | ||
import org.hisp.dhis.mobile.ui.designsystem.component.InputLetter | ||
import org.hisp.dhis.mobile.ui.designsystem.component.InputShellState | ||
import org.hisp.dhis.mobile.ui.designsystem.component.LegendData | ||
import org.hisp.dhis.mobile.ui.designsystem.component.SubTitle | ||
import org.hisp.dhis.mobile.ui.designsystem.component.SupportingTextData | ||
import org.hisp.dhis.mobile.ui.designsystem.component.SupportingTextState | ||
import org.hisp.dhis.mobile.ui.designsystem.component.Title | ||
import org.hisp.dhis.mobile.ui.designsystem.theme.SurfaceColor | ||
import org.hisp.dhis.mobile.ui.designsystem.theme.TextColor | ||
|
||
@Composable | ||
fun InputLetterScreen() { | ||
ColumnComponentContainer { | ||
Title("Input Letter component", textColor = TextColor.OnSurfaceVariant) | ||
SubTitle(" Basic Input Letter", textColor = TextColor.OnSurfaceVariant) | ||
var inputValue1 by rememberSaveable { mutableStateOf("") } | ||
|
||
InputLetter( | ||
title = "Label", | ||
inputText = inputValue1, | ||
onValueChanged = { | ||
if (it != null) { | ||
inputValue1 = it | ||
} | ||
}, | ||
) | ||
SubTitle(" Basic Input Letter with erro", textColor = TextColor.OnSurfaceVariant) | ||
var inputValueError by rememberSaveable { mutableStateOf("") } | ||
|
||
InputLetter( | ||
title = "Label", | ||
inputText = inputValueError, | ||
onValueChanged = { | ||
if (it != null) { | ||
inputValueError = it | ||
} | ||
}, | ||
supportingText = listOf(SupportingTextData("Letters only. eg. A, B, C", SupportingTextState.ERROR)), | ||
state = InputShellState.ERROR, | ||
) | ||
var inputValue2 by rememberSaveable { mutableStateOf("") } | ||
SubTitle("Input Letter with legend", textColor = TextColor.OnSurfaceVariant) | ||
InputLetter( | ||
title = "Label", | ||
inputText = inputValue2, | ||
legendData = LegendData(SurfaceColor.CustomGreen, "Legend"), | ||
onValueChanged = { | ||
if (it != null) { | ||
inputValue2 = it | ||
} | ||
}, | ||
) | ||
|
||
var inputValue3 by rememberSaveable { mutableStateOf("") } | ||
|
||
SubTitle("Input Letter with Supporting text", textColor = TextColor.OnSurfaceVariant) | ||
InputLetter( | ||
title = "Label", | ||
inputText = inputValue3, | ||
supportingText = listOf(SupportingTextData("Supporting text", SupportingTextState.DEFAULT)), | ||
onValueChanged = { | ||
if (it != null) { | ||
inputValue3 = it | ||
} | ||
}, | ||
) | ||
|
||
var inputValue4 by rememberSaveable { mutableStateOf("") } | ||
|
||
SubTitle("Input Letter with Supporting text and legend", textColor = TextColor.OnSurfaceVariant) | ||
|
||
InputLetter( | ||
title = "Label", | ||
inputText = inputValue4, | ||
supportingText = listOf( | ||
SupportingTextData( | ||
"Supporting text", | ||
SupportingTextState.DEFAULT, | ||
), | ||
), | ||
legendData = LegendData(SurfaceColor.CustomGreen, "Legend"), | ||
onValueChanged = { | ||
if (it != null) { | ||
inputValue4 = it | ||
} | ||
}, | ||
) | ||
SubTitle("Input Letter with error and warning text and legend", textColor = TextColor.OnSurfaceVariant) | ||
var inputValue5 by rememberSaveable { mutableStateOf("") } | ||
|
||
InputLetter( | ||
title = "Label", | ||
inputText = inputValue5, | ||
supportingText = listOf( | ||
SupportingTextData("Supporting text", SupportingTextState.DEFAULT), | ||
SupportingTextData("Supporting text", SupportingTextState.WARNING), | ||
SupportingTextData("Supporting text", SupportingTextState.ERROR), | ||
|
||
), | ||
legendData = LegendData(SurfaceColor.CustomGreen, "Legend"), | ||
state = InputShellState.ERROR, | ||
imeAction = ImeAction.Done, | ||
onValueChanged = { | ||
if (it != null) { | ||
inputValue5 = it | ||
} | ||
}, | ||
) | ||
var inputValue6 by rememberSaveable { mutableStateOf("") } | ||
|
||
SubTitle("Disabled Input Letter ", textColor = TextColor.OnSurfaceVariant) | ||
InputLetter( | ||
title = "Label", | ||
inputText = inputValue6, | ||
state = InputShellState.DISABLED, | ||
onValueChanged = { | ||
if (it != null) { | ||
inputValue6 = it | ||
} | ||
}, | ||
) | ||
|
||
var inputValue7 by rememberSaveable { mutableStateOf("A") } | ||
|
||
SubTitle("Disabled Input Letter with content ", textColor = TextColor.OnSurfaceVariant) | ||
InputLetter( | ||
title = "Label", | ||
inputText = inputValue7, | ||
state = InputShellState.DISABLED, | ||
onValueChanged = { | ||
if (it != null) { | ||
inputValue7 = it | ||
} | ||
}, | ||
) | ||
} | ||
} |
112 changes: 112 additions & 0 deletions
112
...ystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputLetter.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
package org.hisp.dhis.mobile.ui.designsystem.component | ||
|
||
import androidx.compose.foundation.text.KeyboardOptions | ||
import androidx.compose.material.icons.Icons | ||
import androidx.compose.material.icons.outlined.Cancel | ||
import androidx.compose.material3.Icon | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.getValue | ||
import androidx.compose.runtime.mutableStateOf | ||
import androidx.compose.runtime.remember | ||
import androidx.compose.runtime.setValue | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.focus.FocusDirection | ||
import androidx.compose.ui.platform.LocalFocusManager | ||
import androidx.compose.ui.platform.testTag | ||
import androidx.compose.ui.text.input.ImeAction | ||
import androidx.compose.ui.text.input.KeyboardCapitalization | ||
import java.util.Locale | ||
|
||
/** | ||
* DHIS2 Input Letter. Wraps DHIS · [InputShell]. | ||
* Component that only allows a single character, | ||
* must be a single letter | ||
* @param title controls the text to be shown for the title | ||
* @param state Manages the InputShell state | ||
* @param supportingText is a list of SupportingTextData that | ||
* manages all the messages to be shown | ||
* @param legendData manages the legendComponent | ||
* @param inputText manages the value of the text in the input field | ||
* @param modifier allows a modifier to be passed externally | ||
*/ | ||
@Composable | ||
fun InputLetter( | ||
title: String, | ||
state: InputShellState = InputShellState.UNFOCUSED, | ||
supportingText: List<SupportingTextData>? = null, | ||
legendData: LegendData? = null, | ||
inputText: String? = null, | ||
isRequiredField: Boolean = false, | ||
onNextClicked: (() -> Unit)? = null, | ||
onValueChanged: ((String?) -> Unit)? = null, | ||
imeAction: ImeAction = ImeAction.Next, | ||
modifier: Modifier = Modifier, | ||
) { | ||
val inputValue by remember(inputText) { mutableStateOf(inputText) } | ||
|
||
var deleteButtonIsVisible by remember { mutableStateOf(!inputText.isNullOrEmpty() && state != InputShellState.DISABLED) } | ||
val focusManager = LocalFocusManager.current | ||
val pattern = remember { Regex("^[A-Z]\$") } | ||
val keyboardOptions = KeyboardOptions(imeAction = imeAction, capitalization = KeyboardCapitalization.Characters) | ||
InputShell( | ||
modifier = modifier, | ||
isRequiredField = isRequiredField, | ||
title = title, | ||
primaryButton = { | ||
if (deleteButtonIsVisible) { | ||
IconButton( | ||
modifier = Modifier.testTag("INPUT_LETTER_RESET_BUTTON"), | ||
icon = { | ||
Icon( | ||
imageVector = Icons.Outlined.Cancel, | ||
contentDescription = "Icon Button", | ||
) | ||
}, | ||
onClick = { | ||
onValueChanged?.invoke("") | ||
deleteButtonIsVisible = false | ||
}, | ||
enabled = state != InputShellState.DISABLED, | ||
) | ||
} | ||
}, | ||
state = state, | ||
legend = { | ||
legendData?.let { | ||
Legend(legendData, Modifier.testTag("INPUT_LETTER_LEGEND")) | ||
} | ||
}, | ||
supportingText = { | ||
supportingText?.forEach { | ||
label -> | ||
SupportingText( | ||
label.text, | ||
label.state, | ||
modifier = Modifier.testTag("INPUT_LETTER_SUPPORTING_TEXT"), | ||
) | ||
} | ||
}, | ||
inputField = { | ||
BasicInput( | ||
modifier = Modifier.testTag("INPUT_LETTER_FIELD"), | ||
inputText = inputValue ?: "", | ||
onInputChanged = { | ||
if (it.uppercase(Locale.getDefault()).matches(pattern) || it.isEmpty()) { | ||
onValueChanged?.invoke(it.uppercase(Locale.getDefault())) | ||
} | ||
deleteButtonIsVisible = it.isNotEmpty() | ||
}, | ||
enabled = state != InputShellState.DISABLED, | ||
state = state, | ||
keyboardOptions = keyboardOptions, | ||
onNextClicked = { | ||
if (onNextClicked != null) { | ||
onNextClicked.invoke() | ||
} else { | ||
focusManager.moveFocus(FocusDirection.Down) | ||
} | ||
}, | ||
) | ||
}, | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.