Skip to content

Commit

Permalink
ANDROAPP-5470-mobile-ui-Create-text-input (#33)
Browse files Browse the repository at this point in the history
* reset button functionality and padding corrections

* add documentation, remove unnecessary mutable values , add disabled examples

* small correction after rebase
  • Loading branch information
xavimolloy authored Aug 29, 2023
1 parent 950b4c8 commit 58f161a
Show file tree
Hide file tree
Showing 10 changed files with 203 additions and 25 deletions.
5 changes: 3 additions & 2 deletions common/src/commonMain/kotlin/org/hisp/dhis/common/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import org.hisp.dhis.common.screens.Components
import org.hisp.dhis.common.screens.FormsComponentsScreen
import org.hisp.dhis.common.screens.IconButtonScreen
import org.hisp.dhis.common.screens.InputScreen
import org.hisp.dhis.common.screens.InputTextScreen
import org.hisp.dhis.common.screens.LegendDescriptionScreen
import org.hisp.dhis.common.screens.LegendScreen
import org.hisp.dhis.common.screens.NotImplementedScreen
Expand All @@ -45,7 +46,7 @@ fun App() {
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Main() {
val currentScreen = remember { mutableStateOf(Components.LEGEND_DESCRIPTION) }
val currentScreen = remember { mutableStateOf(Components.INPUT_TEXT) }
var expanded by remember { mutableStateOf(false) }

Column(modifier = Modifier.padding(Spacing.Spacing16)) {
Expand Down Expand Up @@ -98,8 +99,8 @@ fun Main() {
Components.LEGEND -> LegendScreen()
Components.INPUT -> InputScreen()
Components.SUPPORTING_TEXT -> SupportingTextScreen()
Components.INPUT_TEXT -> InputTextScreen()
Components.LEGEND_DESCRIPTION -> LegendDescriptionScreen()

else -> NotImplementedScreen()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ enum class Components(val label: String) {
SUPPORTING_TEXT("Supporting Text"),
LEGEND("Legend"),
INPUT("Input"),
LEGEND_DESCRIPTION("Legend description")
LEGEND_DESCRIPTION("Legend description"),
INPUT_TEXT("Input Text")
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing
fun FormsComponentsScreen() {
ColumnComponentContainer("Input Shell") {
Text("Sample functional Input Shell ", style = MaterialTheme.typography.titleSmall)
InputShellPreview("Label", inputField = { BasicInput("Helper", true, InputStyle.WITH_HELPER_BEFORE) })
InputShellPreview("Label", inputField = { BasicInput("Helper", true, InputStyle.WITH_HELPER_BEFORE) {} })
Text("Unfocused Input shell ", style = MaterialTheme.typography.titleSmall)
InputShellPreview("Label")
Text("Focused ", style = MaterialTheme.typography.titleSmall)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ fun InputScreen() {
ColumnComponentContainer(
content = {
Text("With helper before")
BasicInput("Helper", helperStyle = InputStyle.WITH_HELPER_BEFORE, inputText = "Input")
BasicInput("Helper", helperStyle = InputStyle.WITH_HELPER_BEFORE, inputText = "Input") {}
Text("With helper after")
BasicInput("Helper", helperStyle = InputStyle.WITH_HELPER_AFTER, inputText = "Input")
BasicInput("Helper", helperStyle = InputStyle.WITH_HELPER_AFTER, inputText = "Input") {}
Text("No helper")
BasicInput(inputText = "Input")
BasicInput(inputText = "Input") {}
Text("Disabled")
BasicInput(enabled = false, inputText = "Input")
BasicInput(enabled = false, inputText = "Input") {}
}
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.hisp.dhis.common.screens

import androidx.compose.runtime.Composable
import org.hisp.dhis.mobile.ui.designsystem.component.ColumnComponentContainer
import org.hisp.dhis.mobile.ui.designsystem.component.InputShellState
import org.hisp.dhis.mobile.ui.designsystem.component.InputText
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.TextColor

@Composable
fun InputTextScreen() {
ColumnComponentContainer {
Title("Input text component", textColor = TextColor.OnSurfaceVariant)
SubTitle(" Basic Input text", textColor = TextColor.OnSurfaceVariant)
InputText(title = "Label", inputText = "")

SubTitle("Input text with legend", textColor = TextColor.OnSurfaceVariant)
InputText(title = "Label", inputText = "", legendText = "Legend")

SubTitle("Input text with Supporting text", textColor = TextColor.OnSurfaceVariant)
InputText(title = "Label", inputText = "", supportingText = listOf(SupportingTextData("Supporting text", SupportingTextState.DEFAULT)))

SubTitle("Input text with Supporting text and legend", textColor = TextColor.OnSurfaceVariant)
InputText(title = "Label", inputText = "", supportingText = listOf(SupportingTextData("Supporting text", SupportingTextState.DEFAULT)), legendText = "Legend")

SubTitle("Input text with error and warning text and legend", textColor = TextColor.OnSurfaceVariant)
InputText(
title = "Label",
inputText = "",
supportingText = listOf(
SupportingTextData("Supporting text", SupportingTextState.DEFAULT),
SupportingTextData("Supporting text", SupportingTextState.WARNING),
SupportingTextData("Supporting text", SupportingTextState.ERROR)

),
legendText = "Legend",
state = InputShellState.ERROR
)

SubTitle("Disabled Input text ", textColor = TextColor.OnSurfaceVariant)
InputText(title = "Label", inputText = "", state = InputShellState.DISABLED)

SubTitle("Disabled Input text with content ", textColor = TextColor.OnSurfaceVariant)
InputText(title = "Label", inputText = "Content", state = InputShellState.DISABLED)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package org.hisp.dhis.mobile.ui.designsystem.component

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.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import org.hisp.dhis.mobile.ui.designsystem.theme.SurfaceColor

/**
* DHIS2 Input 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 legendText manages the text to be shown with the legend component
* @param inputText manages the value of the text in the input field
* @param modifier allows a modifier to be passed externally
*/
@Composable
fun InputText(
title: String,
state: InputShellState = InputShellState.UNFOCUSED,
supportingText: List<SupportingTextData>? = null,
legendText: String? = null,
inputText: String = "",
modifier: Modifier = Modifier
) {
var inputValue by rememberSaveable { mutableStateOf(inputText) }
var deleteButtonIsVisible by remember { mutableStateOf(false) }
InputShell(
modifier = modifier,
title = title,
primaryButton = {
if (deleteButtonIsVisible) {
IconButton(
icon = {
Icon(
imageVector = Icons.Outlined.Cancel,
contentDescription = "Icon Button"
)
},
onClick = {
inputValue = ""
deleteButtonIsVisible = false
},
enabled = state != InputShellState.DISABLED
)
}
},
state = state,
legend = {
legendText?.let {
Legend(SurfaceColor.CustomGreen, legendText) {}
}
},
supportingText = {
supportingText?.forEach { label -> SupportingText(label.text, label.state) }
},
inputField = {
BasicInput(
inputText = inputValue,
onInputChanged = {
inputValue = it
deleteButtonIsVisible = inputValue.isNotEmpty()
},
enabled = state != InputShellState.DISABLED
)
}
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.material3.MaterialTheme
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.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.CornerRadius
Expand Down Expand Up @@ -50,20 +46,21 @@ fun EmptyInput(

/**
* DHIS2 Basic Input. Wraps Material· [BasicTextField].
* @param helper Manages the helper text to be shown
* @param enabled Controls the enabled state of the component. When `false`, this component will not be
* clickable and will appear disabled to accessibility services.
* @param helper Manages the helper text to be shown
* @param helperStyle manages the helper text style, NONE by default
* @param inputText manages the value of the input field text
* @param onInputChanged gives access to the onTextChangedEvent
*/
@Composable
fun BasicInput(
helper: String? = null,
enabled: Boolean = true,
helperStyle: InputStyle = InputStyle.NONE,
inputText: String = ""
inputText: String = "",
onInputChanged: (String) -> Unit
) {
var text by remember { mutableStateOf(inputText) }

var visualTransformation = VisualTransformation.None

if (helperStyle != InputStyle.NONE) {
Expand All @@ -81,10 +78,8 @@ fun BasicInput(
Color.Transparent
)
.fillMaxWidth(),
value = text,
onValueChange = {
text = it
},
value = inputText,
onValueChange = onInputChanged,
enabled = enabled,
textStyle = MaterialTheme.typography.bodyLarge.copy(color = if (enabled) TextColor.OnSurface else TextColor.OnDisabledSurface),
singleLine = true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package org.hisp.dhis.mobile.ui.designsystem.component

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Divider
Expand Down Expand Up @@ -45,9 +47,10 @@ fun InputShell(
secondaryButton: @Composable (() -> Unit)? = null,
inputField: @Composable (() -> Unit)? = null,
supportingText: @Composable (() -> Unit)? = null,
legend: @Composable (() -> Unit)? = null
legend: @Composable (() -> Unit)? = null,
modifier: Modifier = Modifier
) {
Column(modifier = Modifier.fillMaxWidth().clip(shape = RoundedCornerShape(Radius.XS, Radius.XS))) {
Column(modifier = modifier.fillMaxWidth().clip(shape = RoundedCornerShape(Radius.XS, Radius.XS))) {
var indicatorColor by remember { mutableStateOf(InputShellState.UNFOCUSED.color) }
val backgroundColor = if (state != InputShellState.DISABLED) SurfaceColor.Surface else SurfaceColor.DisabledSurface
InputShellRow(
Expand All @@ -68,13 +71,20 @@ fun InputShell(
Row(
verticalAlignment = Alignment.CenterVertically
) {
primaryButton?.invoke()
primaryButton?.let {
Box(Modifier.size(Spacing.Spacing48)) {
it.invoke()
}
}
if (primaryButton != null && secondaryButton != null) {
InputShellButtonSeparator()
Spacer(modifier = Modifier.width(Spacing.Spacing4))
}
secondaryButton?.invoke()
Spacer(modifier = Modifier.width(Spacing.Spacing4))
secondaryButton?.let {
Box(Modifier.size(Spacing.Spacing48)) {
it.invoke()
}
}
}
}
InputShellIndicator(color = indicatorColor)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,5 @@ enum class SupportingTextState(val color: Color) {
WARNING(TextColor.OnWarning),
ERROR(SurfaceColor.Error)
}

data class SupportingTextData(val text: String, val state: SupportingTextState)
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,47 @@ internal fun LegendDescriptionRangeText(
textAlign = TextAlign.Start
)
}

@Composable
fun Title(
text: String,
textColor: Color,
modifier: Modifier = Modifier
) {
Text(
text,
modifier = modifier,
color = textColor,
style = MaterialTheme.typography.titleMedium,
textAlign = TextAlign.Start
)
}

@Composable fun SubTitle(
text: String,
textColor: Color,
modifier: Modifier = Modifier
) {
Text(
text,
modifier = modifier,
color = textColor,
style = MaterialTheme.typography.titleSmall,
textAlign = TextAlign.Start
)
}

@Composable
internal fun Description(
text: String,
textColor: Color,
modifier: Modifier = Modifier
) {
Text(
text,
modifier = modifier,
color = textColor,
style = MaterialTheme.typography.bodyMedium,
textAlign = TextAlign.Start
)
}

0 comments on commit 58f161a

Please sign in to comment.