-
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-5500-mobile-ui-Create-Input-Long-Text (#45)
* add InputLongText component, add documentation * implement tests for new component * ktlint
- Loading branch information
1 parent
557cb35
commit 9fa87fa
Showing
9 changed files
with
455 additions
and
5 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
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
173 changes: 173 additions & 0 deletions
173
common/src/commonMain/kotlin/org/hisp/dhis/common/screens/InputLongTextScreen.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,173 @@ | ||
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.InputLongText | ||
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 InputLongTextScreen() { | ||
ColumnComponentContainer { | ||
Title("Input Long Text component", textColor = TextColor.OnSurfaceVariant) | ||
SubTitle(" Basic Input Long Text", textColor = TextColor.OnSurfaceVariant) | ||
var inputValue1 by rememberSaveable { | ||
mutableStateOf( | ||
"Lorem ipsum dolor sit amet," + | ||
" consectetur adipiscing elit. " + | ||
"Maecenas dolor lacus, aliquam.", | ||
) | ||
} | ||
|
||
InputLongText( | ||
title = "Label", | ||
inputText = inputValue1, | ||
onValueChanged = { | ||
if (it != null) { | ||
inputValue1 = it | ||
} | ||
}, | ||
) | ||
SubTitle(" Basic Input Long Text with error message", textColor = TextColor.OnSurfaceVariant) | ||
var inputValueError by rememberSaveable { | ||
mutableStateOf( | ||
"Lorem ipsum dolor sit amet," + | ||
" consectetur adipiscing elit. " + | ||
"Maecenas dolor lacus, aliquam." + | ||
"Lorem ipsum dolor sit amet," + | ||
" consectetur adipiscing elit. " + | ||
"Maecenas dolor lacus, aliquam." + | ||
"Lorem ipsum dolor sit amet," + | ||
" consectetur adipiscing elit. " + | ||
"Maecenas dolor lacus, aliquam." + | ||
"Lorem ipsum dolor sit amet," + | ||
" consectetur adipiscing elit. " + | ||
"Maecenas dolor lacus, aliquam.", | ||
) | ||
} | ||
|
||
InputLongText( | ||
title = "Label", | ||
inputText = inputValueError, | ||
onValueChanged = { | ||
if (it != null) { | ||
inputValueError = it | ||
} | ||
}, | ||
supportingText = listOf( | ||
SupportingTextData( | ||
"100000/1000000 characters used", | ||
state = SupportingTextState.ERROR, | ||
), | ||
), | ||
state = InputShellState.ERROR, | ||
) | ||
|
||
var inputValue2 by rememberSaveable { mutableStateOf("") } | ||
SubTitle("Input long text with legend", textColor = TextColor.OnSurfaceVariant) | ||
InputLongText( | ||
title = "Label", | ||
inputText = inputValue2, | ||
legendData = LegendData(SurfaceColor.CustomGreen, "Legend"), | ||
onValueChanged = { | ||
if (it != null) { | ||
inputValue2 = it | ||
} | ||
}, | ||
) | ||
|
||
var inputValue3 by rememberSaveable { mutableStateOf("") } | ||
|
||
SubTitle("Input Long text with Supporting text", textColor = TextColor.OnSurfaceVariant) | ||
InputLongText( | ||
title = "Label", | ||
inputText = inputValue3, | ||
supportingText = listOf(SupportingTextData("Supporting text", SupportingTextState.DEFAULT)), | ||
onValueChanged = { | ||
if (it != null) { | ||
inputValue3 = it | ||
} | ||
}, | ||
) | ||
|
||
var inputValue4 by rememberSaveable { mutableStateOf("") } | ||
|
||
SubTitle("Input Long Text with Supporting text and legend", textColor = TextColor.OnSurfaceVariant) | ||
|
||
InputLongText( | ||
title = "Label", | ||
inputText = inputValue4, | ||
supportingText = listOf( | ||
SupportingTextData( | ||
"Supporting text", | ||
SupportingTextState.DEFAULT, | ||
), | ||
), | ||
legendData = LegendData(SurfaceColor.CustomGreen, "Legend"), | ||
onValueChanged = { | ||
if (it != null) { | ||
inputValue4 = it | ||
} | ||
}, | ||
) | ||
SubTitle("Input Long text with error and warning text and legend", textColor = TextColor.OnSurfaceVariant) | ||
var inputValue5 by rememberSaveable { mutableStateOf("") } | ||
|
||
InputLongText( | ||
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 Long Text ", textColor = TextColor.OnSurfaceVariant) | ||
InputLongText( | ||
title = "Label", | ||
inputText = inputValue6, | ||
state = InputShellState.DISABLED, | ||
onValueChanged = { | ||
if (it != null) { | ||
inputValue6 = it | ||
} | ||
}, | ||
) | ||
|
||
var inputValue7 by rememberSaveable { mutableStateOf("Content") } | ||
|
||
SubTitle("Disabled Input text with content ", textColor = TextColor.OnSurfaceVariant) | ||
InputLongText( | ||
title = "Label", | ||
inputText = inputValue7, | ||
state = InputShellState.DISABLED, | ||
onValueChanged = { | ||
if (it != null) { | ||
inputValue7 = it | ||
} | ||
}, | ||
) | ||
} | ||
} |
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
122 changes: 122 additions & 0 deletions
122
...tem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputLongText.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,122 @@ | ||
package org.hisp.dhis.mobile.ui.designsystem.component | ||
|
||
import androidx.compose.foundation.gestures.Orientation | ||
import androidx.compose.foundation.gestures.scrollable | ||
import androidx.compose.foundation.layout.heightIn | ||
import androidx.compose.foundation.rememberScrollState | ||
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 org.hisp.dhis.mobile.ui.designsystem.theme.InternalSizeValues | ||
import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing | ||
|
||
/** | ||
* DHIS2 Input Long Text. Wraps DHIS · [InputShell]. | ||
* @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 isRequiredField manages whether the field is mandatory or not | ||
* @param onNextClicked gives access to the ImeAction event | ||
* @param onValueChanged gives access to the onValueChanged event | ||
* @param imeAction controls the ImeAction to show in the keyboard | ||
* @param modifier allows a modifier to be passed externally | ||
*/ | ||
@Composable | ||
fun InputLongText( | ||
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 keyboardOptions = KeyboardOptions(imeAction = imeAction) | ||
InputShell( | ||
modifier = modifier, | ||
isRequiredField = isRequiredField, | ||
title = title, | ||
primaryButton = { | ||
if (deleteButtonIsVisible) { | ||
IconButton( | ||
modifier = Modifier.testTag("INPUT_LONG_TEXT_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_LONG_TEXT_LEGEND")) | ||
} | ||
}, | ||
supportingText = { | ||
supportingText?.forEach { | ||
label -> | ||
SupportingText( | ||
label.text, | ||
label.state, | ||
modifier = Modifier.testTag("INPUT_LONG_TEXT_SUPPORTING_TEXT"), | ||
) | ||
} | ||
}, | ||
inputField = { | ||
BasicInput( | ||
modifier = Modifier.testTag("INPUT_LONG_TEXT_FIELD") | ||
.scrollable( | ||
orientation = Orientation.Vertical, | ||
state = rememberScrollState(), | ||
).heightIn(Spacing.Spacing0, InternalSizeValues.Size300), | ||
isSingleLine = false, | ||
inputText = inputValue, | ||
onInputChanged = { | ||
onValueChanged?.invoke(it) | ||
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.