diff --git a/common/src/commonMain/kotlin/org/hisp/dhis/common/App.kt b/common/src/commonMain/kotlin/org/hisp/dhis/common/App.kt index 185a0a097..fcd607b4d 100644 --- a/common/src/commonMain/kotlin/org/hisp/dhis/common/App.kt +++ b/common/src/commonMain/kotlin/org/hisp/dhis/common/App.kt @@ -82,6 +82,7 @@ import org.hisp.dhis.common.screens.SectionScreen import org.hisp.dhis.common.screens.SupportingTextScreen import org.hisp.dhis.common.screens.SwitchScreen import org.hisp.dhis.common.screens.TagsScreen +import org.hisp.dhis.common.screens.parameter.ParameterSelectorScreen import org.hisp.dhis.mobile.ui.designsystem.theme.DHIS2Theme import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing @@ -94,8 +95,7 @@ fun App() { @Composable fun Main() { - val currentScreen = remember { mutableStateOf(Components.LIST_CARD) } - + val currentScreen = remember { mutableStateOf(Components.PARAMETER_SELECTOR) } var expanded by remember { mutableStateOf(false) } Column( @@ -202,6 +202,7 @@ fun Main() { Components.FULL_SCREEN_IMAGE -> FullScreenImageScreen() Components.ORG_TREE_BOTTOM_SHEET -> OrgTreeBottomSheetScreen() Components.INDICATOR_INPUT -> IndicatorInputScreen() + Components.PARAMETER_SELECTOR -> ParameterSelectorScreen() } } } diff --git a/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/Components.kt b/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/Components.kt index 947314413..a34820327 100644 --- a/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/Components.kt +++ b/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/Components.kt @@ -61,4 +61,5 @@ enum class Components(val label: String) { FULL_SCREEN_IMAGE("Full Screen Image"), ORG_TREE_BOTTOM_SHEET("Org Tree Bottom Sheet"), INDICATOR_INPUT("Indicator Input"), + PARAMETER_SELECTOR("Parameter selector"), } diff --git a/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/FormsComponentsScreen.kt b/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/FormsComponentsScreen.kt index 75d01bd9f..6b6db7d01 100644 --- a/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/FormsComponentsScreen.kt +++ b/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/FormsComponentsScreen.kt @@ -12,6 +12,7 @@ import androidx.compose.ui.text.input.TextFieldValue import org.hisp.dhis.common.screens.previews.InputShellPreview import org.hisp.dhis.mobile.ui.designsystem.component.BasicTextField import org.hisp.dhis.mobile.ui.designsystem.component.ColumnComponentContainer +import org.hisp.dhis.mobile.ui.designsystem.component.HelperStyle import org.hisp.dhis.mobile.ui.designsystem.component.InputShellState import org.hisp.dhis.mobile.ui.designsystem.component.InputStyle import org.hisp.dhis.mobile.ui.designsystem.component.SubTitle @@ -21,7 +22,7 @@ import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing fun FormsComponentsScreen() { ColumnComponentContainer("Input Shell") { SubTitle("Sample functional Input Shell ") - InputShellPreview("Label", inputField = { BasicTextField("Helper", true, helperStyle = InputStyle.WITH_HELPER_BEFORE, onInputChanged = {}) }) + InputShellPreview("Label", inputField = { BasicTextField("Helper", true, helperStyle = HelperStyle.WITH_HELPER_BEFORE, onInputChanged = {}) }) Spacer(Modifier.size(Spacing.Spacing18)) SubTitle("Unfocused Input shell ") InputShellPreview("Label") @@ -40,7 +41,7 @@ fun FormsComponentsScreen() { InputShellPreview( title = "Label", state = InputShellState.UNFOCUSED, - hasTransparentBackground = true, + inputStyle = InputStyle.ParameterInputStyle(), onInputClear = { inputField = "" }, @@ -49,7 +50,7 @@ fun FormsComponentsScreen() { helper = "Helper", inputTextValue = TextFieldValue(inputField), enabled = true, - helperStyle = InputStyle.WITH_HELPER_BEFORE, + helperStyle = HelperStyle.WITH_HELPER_BEFORE, onInputChanged = { inputField = it.text }, diff --git a/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/InputScreen.kt b/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/InputScreen.kt index 9f1e4ecbb..617874984 100644 --- a/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/InputScreen.kt +++ b/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/InputScreen.kt @@ -11,7 +11,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.text.input.TextFieldValue import org.hisp.dhis.mobile.ui.designsystem.component.BasicTextField import org.hisp.dhis.mobile.ui.designsystem.component.ColumnComponentContainer -import org.hisp.dhis.mobile.ui.designsystem.component.InputStyle +import org.hisp.dhis.mobile.ui.designsystem.component.HelperStyle import org.hisp.dhis.mobile.ui.designsystem.component.SubTitle import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing @@ -26,11 +26,11 @@ fun InputScreen() { title = "Input", content = { SubTitle("With helper before") - BasicTextField("Helper", helperStyle = InputStyle.WITH_HELPER_BEFORE, inputTextValue = TextFieldValue(inputValue1), onInputChanged = { inputValue1 = it.text }) + BasicTextField("Helper", helperStyle = HelperStyle.WITH_HELPER_BEFORE, inputTextValue = TextFieldValue(inputValue1), onInputChanged = { inputValue1 = it.text }) Spacer(Modifier.size(Spacing.Spacing18)) SubTitle("With helper after") - BasicTextField("Helper", helperStyle = InputStyle.WITH_HELPER_AFTER, inputTextValue = TextFieldValue(inputValue2), onInputChanged = { inputValue2 = it.text }) + BasicTextField("Helper", helperStyle = HelperStyle.WITH_HELPER_AFTER, inputTextValue = TextFieldValue(inputValue2), onInputChanged = { inputValue2 = it.text }) Spacer(Modifier.size(Spacing.Spacing18)) SubTitle("No helper") BasicTextField(inputTextValue = TextFieldValue(inputValue3), onInputChanged = { diff --git a/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/parameter/ParameterSelectorScreen.kt b/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/parameter/ParameterSelectorScreen.kt new file mode 100644 index 000000000..18c9a1e3f --- /dev/null +++ b/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/parameter/ParameterSelectorScreen.kt @@ -0,0 +1,434 @@ +package org.hisp.dhis.common.screens.parameter + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.QrCode2 +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 androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.input.TextFieldValue +import org.hisp.dhis.mobile.ui.designsystem.component.AgeInputType +import org.hisp.dhis.mobile.ui.designsystem.component.CheckBoxData +import org.hisp.dhis.mobile.ui.designsystem.component.DropdownItem +import org.hisp.dhis.mobile.ui.designsystem.component.InputAge +import org.hisp.dhis.mobile.ui.designsystem.component.InputBarCode +import org.hisp.dhis.mobile.ui.designsystem.component.InputCheckBox +import org.hisp.dhis.mobile.ui.designsystem.component.InputDateTime +import org.hisp.dhis.mobile.ui.designsystem.component.InputDropDown +import org.hisp.dhis.mobile.ui.designsystem.component.InputEmail +import org.hisp.dhis.mobile.ui.designsystem.component.InputInteger +import org.hisp.dhis.mobile.ui.designsystem.component.InputLink +import org.hisp.dhis.mobile.ui.designsystem.component.InputLongText +import org.hisp.dhis.mobile.ui.designsystem.component.InputMatrix +import org.hisp.dhis.mobile.ui.designsystem.component.InputNotSupported +import org.hisp.dhis.mobile.ui.designsystem.component.InputOrgUnit +import org.hisp.dhis.mobile.ui.designsystem.component.InputPhoneNumber +import org.hisp.dhis.mobile.ui.designsystem.component.InputQRCode +import org.hisp.dhis.mobile.ui.designsystem.component.InputRadioButton +import org.hisp.dhis.mobile.ui.designsystem.component.InputSequential +import org.hisp.dhis.mobile.ui.designsystem.component.InputShellState +import org.hisp.dhis.mobile.ui.designsystem.component.InputStyle +import org.hisp.dhis.mobile.ui.designsystem.component.InputText +import org.hisp.dhis.mobile.ui.designsystem.component.InputYesNoField +import org.hisp.dhis.mobile.ui.designsystem.component.InputYesOnlyCheckBox +import org.hisp.dhis.mobile.ui.designsystem.component.InputYesOnlySwitch +import org.hisp.dhis.mobile.ui.designsystem.component.RadioButtonData +import org.hisp.dhis.mobile.ui.designsystem.component.internal.IconCardData +import org.hisp.dhis.mobile.ui.designsystem.component.parameter.ParameterSelectorItem +import org.hisp.dhis.mobile.ui.designsystem.component.parameter.model.ParameterSelectorItemModel +import org.hisp.dhis.mobile.ui.designsystem.component.parameter.model.ParameterSelectorItemModel.Status.CLOSED +import org.hisp.dhis.mobile.ui.designsystem.component.parameter.model.ParameterSelectorItemModel.Status.OPENED + +@Composable +fun ParameterSelectorScreen() { + var inputTextValue by rememberSaveable(stateSaver = TextFieldValue.Saver) { + mutableStateOf(TextFieldValue("")) + } + var ageInputType by remember { + mutableStateOf(AgeInputType.None) + } + var inputBarcodeValue by rememberSaveable(stateSaver = TextFieldValue.Saver) { + mutableStateOf( + TextFieldValue("889026a1-d01e-4d34-8209-81e8ed5c614b"), + ) + } + var inputQRCodeValue by rememberSaveable(stateSaver = TextFieldValue.Saver) { + mutableStateOf( + TextFieldValue("889026a1-d01e-4d34-8209-81e8ed5c614b"), + ) + } + var checkBoxSelected: Boolean by remember { mutableStateOf(false) } + + val items = listOf( + ParameterSelectorItemModel( + icon = Icons.Outlined.QrCode2, + label = "QRCode parameter", + helper = "Optional", + inputField = { + InputQRCode( + title = "QRCode parameter", + state = InputShellState.UNFOCUSED, + inputTextFieldValue = inputQRCodeValue, + inputStyle = InputStyle.ParameterInputStyle(), + onQRButtonClicked = {}, + onValueChanged = { + inputQRCodeValue = it ?: TextFieldValue() + }, + ) + }, + status = if (inputQRCodeValue.text.isEmpty()) { + CLOSED + } else { + OPENED + }, + ), + ParameterSelectorItemModel( + label = "Text parameter", + helper = "Optional", + inputField = { + InputText( + title = "Text parameter", + state = InputShellState.UNFOCUSED, + inputTextFieldValue = inputTextValue, + inputStyle = InputStyle.ParameterInputStyle(), + onValueChanged = { + inputTextValue = it ?: TextFieldValue() + }, + ) + }, + status = if (inputTextValue.text.isEmpty()) { + CLOSED + } else { + OPENED + }, + ), + ParameterSelectorItemModel( + label = "Age parameter", + helper = "Optional", + inputField = { + InputAge( + title = "Age parameter", + inputType = ageInputType, + inputStyle = InputStyle.ParameterInputStyle(), + onCalendarActionClicked = {}, + onValueChanged = { + ageInputType = it + }, + ) + }, + status = when (ageInputType) { + AgeInputType.None -> CLOSED + else -> OPENED + }, + ), + ParameterSelectorItemModel( + label = "Barcode parameter", + helper = "Optional", + inputField = { + InputBarCode( + title = "Barcode parameter", + inputTextFieldValue = inputBarcodeValue, + inputStyle = InputStyle.ParameterInputStyle(), + onActionButtonClicked = {}, + onValueChanged = { + inputBarcodeValue = it ?: TextFieldValue() + }, + ) + }, + status = if (inputBarcodeValue.text.isEmpty()) { + CLOSED + } else { + OPENED + }, + ), + ParameterSelectorItemModel( + label = "CheckBox parameter", + helper = "Optional", + inputField = { + InputCheckBox( + title = "CheckBox parameter", + state = InputShellState.UNFOCUSED, + inputStyle = InputStyle.ParameterInputStyle(), + checkBoxData = listOf( + CheckBoxData( + uid = "uid1", + checked = true, + enabled = true, + textInput = "option 1", + ), + CheckBoxData( + uid = "uid1", + checked = false, + enabled = true, + textInput = "option 2", + ), + ), + onClearSelection = { + checkBoxSelected = false + }, + onItemChange = { + checkBoxSelected = true + }, + ) + }, + status = if (checkBoxSelected) { + OPENED + } else { + CLOSED + }, + ), + ParameterSelectorItemModel( + label = "DateTime parameter", + helper = "Optional", + inputField = { + InputDateTime( + title = "DateTime parameter", + inputStyle = InputStyle.ParameterInputStyle(), + inputTextFieldValue = TextFieldValue(), + onActionClicked = {}, + onValueChanged = {}, + ) + }, + ), + ParameterSelectorItemModel( + label = "DropDown parameter", + helper = "Optional", + inputField = { + InputDropDown( + title = "DropDown parameter", + state = InputShellState.UNFOCUSED, + inputStyle = InputStyle.ParameterInputStyle(), + dropdownItems = listOf( + DropdownItem("Item 1"), + DropdownItem("Item 2"), + ), + onItemSelected = {}, + onResetButtonClicked = {}, + ) + }, + ), + ParameterSelectorItemModel( + label = "Email parameter", + helper = "Optional", + inputField = { + InputEmail( + title = "Email parameter", + state = InputShellState.UNFOCUSED, + inputTextFieldValue = TextFieldValue("android@dhis2.org"), + inputStyle = InputStyle.ParameterInputStyle(), + onEmailActionCLicked = {}, + ) + }, + ), + ParameterSelectorItemModel( + label = "Link parameter", + helper = "Optional", + inputField = { + InputLink( + title = "Link parameter", + state = InputShellState.UNFOCUSED, + inputTextFieldValue = TextFieldValue("http://dhis2.org"), + inputStyle = InputStyle.ParameterInputStyle(), + onLinkActionCLicked = {}, + ) + }, + ), + ParameterSelectorItemModel( + label = "Integer parameter", + helper = "Optional", + inputField = { + InputInteger( + title = "Integer parameter", + state = InputShellState.UNFOCUSED, + inputTextFieldValue = TextFieldValue("123456"), + inputStyle = InputStyle.ParameterInputStyle(), + ) + }, + ), + ParameterSelectorItemModel( + label = "Long text parameter", + helper = "Optional", + inputField = { + InputLongText( + title = "Long text parameter", + state = InputShellState.UNFOCUSED, + inputTextFieldValue = TextFieldValue("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."), + inputStyle = InputStyle.ParameterInputStyle(), + ) + }, + ), + ParameterSelectorItemModel( + label = "Matrix parameter", + helper = "Optional", + inputField = { + InputMatrix( + title = "Matrix parameter", + state = InputShellState.UNFOCUSED, + inputStyle = InputStyle.ParameterInputStyle(), + data = listOf( + IconCardData( + uid = "7e0cb105-c276-4f12-9f56-a26af8314121", + label = "Stethoscope", + iconRes = "dhis2_stethoscope_positive", + iconTint = Color(0xFFFF8400), + ), + IconCardData( + uid = "72269f6b-6b99-4d2e-a667-09f20c2097e0", + label = "Medicines", + iconRes = "dhis2_medicines_positive", + iconTint = Color(0xFFEB0085), + ), + ), + onSelectionChanged = {}, + ) + }, + ), + ParameterSelectorItemModel( + label = "Not supported parameter", + helper = "Optional", + inputField = { + InputNotSupported( + title = "Not supported parameter", + notSupportedString = "Not supported", + inputStyle = InputStyle.ParameterInputStyle(), + ) + }, + ), + ParameterSelectorItemModel( + label = "Org unit parameter", + helper = "Optional", + inputField = { + InputOrgUnit( + title = "Org unit parameter", + inputStyle = InputStyle.ParameterInputStyle(), + onOrgUnitActionCLicked = {}, + ) + }, + ), + ParameterSelectorItemModel( + label = "Phone number parameter", + helper = "Optional", + inputField = { + InputPhoneNumber( + title = "Phone number parameter", + state = InputShellState.UNFOCUSED, + inputTextFieldValue = TextFieldValue("999 666 888"), + inputStyle = InputStyle.ParameterInputStyle(), + onCallActionClicked = {}, + ) + }, + ), + ParameterSelectorItemModel( + label = "Radio button parameter", + helper = "Optional", + inputField = { + InputRadioButton( + title = "Radio button parameter", + state = InputShellState.UNFOCUSED, + inputStyle = InputStyle.ParameterInputStyle(), + radioButtonData = listOf( + RadioButtonData( + uid = "uid1", + selected = false, + enabled = true, + textInput = "option1", + ), + RadioButtonData( + uid = "uid2", + selected = true, + enabled = true, + textInput = "option2", + ), + ), + onItemChange = {}, + ) + }, + ), + ParameterSelectorItemModel( + label = "Sequential parameter", + helper = "Optional", + inputField = { + InputSequential( + title = "Sequential parameter", + state = InputShellState.UNFOCUSED, + inputStyle = InputStyle.ParameterInputStyle(), + data = listOf( + IconCardData( + uid = "7e0cb105-c276-4f12-9f56-a26af8314121", + label = "Stethoscope", + iconRes = "dhis2_stethoscope_positive", + iconTint = Color(0xFFFF8400), + ), + IconCardData( + uid = "72269f6b-6b99-4d2e-a667-09f20c2097e0", + label = "Medicines", + iconRes = "dhis2_medicines_positive", + iconTint = Color(0xFFEB0085), + ), + ), + onSelectionChanged = {}, + ) + }, + ), + ParameterSelectorItemModel( + label = "Yes No parameter", + helper = "Optional", + inputField = { + InputYesNoField( + title = "Yes No parameter", + state = InputShellState.UNFOCUSED, + inputStyle = InputStyle.ParameterInputStyle(), + onItemChange = {}, + ) + }, + ), + ParameterSelectorItemModel( + label = "Yes only check box parameter", + helper = "Optional", + inputField = { + InputYesOnlyCheckBox( + state = InputShellState.UNFOCUSED, + inputStyle = InputStyle.ParameterInputStyle(), + checkBoxData = CheckBoxData( + uid = "uid1", + checked = true, + enabled = true, + textInput = "option 1", + ), + onClick = {}, + ) + }, + ), + ParameterSelectorItemModel( + label = "Yes only switch parameter", + helper = "Optional", + inputField = { + InputYesOnlySwitch( + title = "Yes only switch parameter", + state = InputShellState.UNFOCUSED, + inputStyle = InputStyle.ParameterInputStyle(), + isChecked = true, + onClick = {}, + ) + }, + ), + ) + + Column( + modifier = Modifier + .verticalScroll(rememberScrollState()), + ) { + items.forEach { + ParameterSelectorItem( + model = it, + ) + } + } +} diff --git a/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/previews/FormsComponentsPreview.kt b/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/previews/FormsComponentsPreview.kt index 0e5c03f4d..8bdf592a8 100644 --- a/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/previews/FormsComponentsPreview.kt +++ b/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/previews/FormsComponentsPreview.kt @@ -14,6 +14,7 @@ import org.hisp.dhis.mobile.ui.designsystem.component.EmptyInput import org.hisp.dhis.mobile.ui.designsystem.component.IconButton import org.hisp.dhis.mobile.ui.designsystem.component.InputShell import org.hisp.dhis.mobile.ui.designsystem.component.InputShellState +import org.hisp.dhis.mobile.ui.designsystem.component.InputStyle import org.hisp.dhis.mobile.ui.designsystem.component.SquareIconButton import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing import org.hisp.dhis.mobile.ui.designsystem.theme.TextColor @@ -23,7 +24,7 @@ internal fun InputShellPreview( title: String, state: InputShellState = InputShellState.UNFOCUSED, inputField: @Composable (() -> Unit)? = null, - hasTransparentBackground: Boolean = false, + inputStyle: InputStyle = InputStyle.DataInputStyle(), onInputClear: () -> Unit = { }, ) { InputShell( @@ -67,6 +68,6 @@ internal fun InputShellPreview( ) }, state = state, - hasTransparentBackground = hasTransparentBackground, + inputStyle = inputStyle, ) } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/BasicInputImage.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/BasicInputImage.kt index 465900770..49bec55c6 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/BasicInputImage.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/BasicInputImage.kt @@ -48,6 +48,7 @@ import org.hisp.dhis.mobile.ui.designsystem.theme.TextColor internal fun BasicInputImage( title: String, state: InputShellState = InputShellState.UNFOCUSED, + inputStyle: InputStyle = InputStyle.DataInputStyle(), supportingText: List? = null, legendData: LegendData? = null, uploadState: UploadState = UploadState.ADD, @@ -174,6 +175,7 @@ internal fun BasicInputImage( } else { null }, + inputStyle = inputStyle, ) } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/BasicTextInput.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/BasicTextInput.kt index 6a1739ff3..4a2999089 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/BasicTextInput.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/BasicTextInput.kt @@ -69,11 +69,12 @@ internal fun BasicTextInput( keyboardOptions: KeyboardOptions, allowedCharacters: Regex? = null, helper: String? = null, - helperStyle: InputStyle = InputStyle.NONE, + helperStyle: HelperStyle = HelperStyle.NONE, testTag: String = "", isSingleLine: Boolean = true, actionButton: @Composable (() -> Unit)? = null, modifier: Modifier = Modifier, + inputStyle: InputStyle, ) { var inputValue by remember(inputTextFieldValue) { mutableStateOf(inputTextFieldValue) } @@ -214,6 +215,7 @@ internal fun BasicTextInput( } }, onFocusChanged = onFocusChanged, + inputStyle = inputStyle, ) } } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputAge.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputAge.kt index cbb1e1b1f..7ca1fcd6f 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputAge.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputAge.kt @@ -50,6 +50,7 @@ import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing fun InputAge( title: String, inputType: AgeInputType = None, + inputStyle: InputStyle = InputStyle.DataInputStyle(), onCalendarActionClicked: () -> Unit, modifier: Modifier = Modifier, state: InputShellState = InputShellState.UNFOCUSED, @@ -74,9 +75,9 @@ fun InputAge( } val helperStyle = remember(inputType) { when (inputType) { - None -> InputStyle.NONE - is DateOfBirth -> InputStyle.WITH_DATE_OF_BIRTH_HELPER - is Age -> InputStyle.WITH_HELPER_AFTER + None -> HelperStyle.NONE + is DateOfBirth -> HelperStyle.WITH_DATE_OF_BIRTH_HELPER + is Age -> HelperStyle.WITH_HELPER_AFTER } } @@ -229,6 +230,7 @@ fun InputAge( Legend(legendData, Modifier.testTag("INPUT_AGE_LEGEND")) } }, + inputStyle = inputStyle, ) } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputBarCode.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputBarCode.kt index 4f34fb537..d5f7ee911 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputBarCode.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputBarCode.kt @@ -43,8 +43,10 @@ fun InputBarCode( onFocusChanged: ((Boolean) -> Unit)? = null, imeAction: ImeAction = ImeAction.Next, modifier: Modifier = Modifier, + inputStyle: InputStyle = InputStyle.DataInputStyle(), ) { - val actionButtonIconVector = mutableStateOf(if (inputTextFieldValue?.text.isNullOrEmpty()) "material_barcode_scanner" else "material_barcode") + val actionButtonIconVector = + mutableStateOf(if (inputTextFieldValue?.text.isNullOrEmpty()) "material_barcode_scanner" else "material_barcode") BasicTextInput( title = title, state = state, @@ -61,7 +63,7 @@ fun InputBarCode( actionButton = { SquareIconButton( modifier = Modifier.testTag("INPUT_BAR_CODE_BUTTON"), - enabled = (state == InputShellState.DISABLED && !inputTextFieldValue?.text.isNullOrEmpty()) || state != InputShellState.DISABLED, + enabled = isButtonEnabled(inputStyle, state, inputTextFieldValue?.text), icon = { Icon( painter = provideDHIS2Icon(actionButtonIconVector.value), @@ -73,5 +75,16 @@ fun InputBarCode( }, autoCompleteList = autoCompleteList, autoCompleteItemSelected = autoCompleteItemSelected, + inputStyle = inputStyle, ) } + +private fun isButtonEnabled(inputStyle: InputStyle, state: InputShellState, inputText: String?) = + when (inputStyle) { + is InputStyle.DataInputStyle -> { + (state == InputShellState.DISABLED && !inputText.isNullOrEmpty()) || + state != InputShellState.DISABLED + } + + is InputStyle.ParameterInputStyle -> inputText.isNullOrEmpty() + } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputCheckBox.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputCheckBox.kt index c6e5fdada..dd653ef05 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputCheckBox.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputCheckBox.kt @@ -38,6 +38,7 @@ fun InputCheckBox( supportingText: List? = null, legendData: LegendData? = null, isRequired: Boolean = false, + inputStyle: InputStyle = InputStyle.DataInputStyle(), onItemChange: (CheckBoxData) -> Unit, onClearSelection: () -> Unit, ) { @@ -91,5 +92,6 @@ fun InputCheckBox( Spacer(modifier = Modifier.width(Spacing.Spacing48)) } }, + inputStyle = inputStyle, ) } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputCoordinate.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputCoordinate.kt index f93799c8e..45c86d0e1 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputCoordinate.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputCoordinate.kt @@ -47,6 +47,7 @@ import org.hisp.dhis.mobile.ui.designsystem.theme.TextColor fun InputCoordinate( title: String, state: InputShellState = InputShellState.UNFOCUSED, + inputStyle: InputStyle = InputStyle.DataInputStyle(), supportingText: List? = null, legendData: LegendData? = null, coordinates: Coordinates? = null, @@ -162,6 +163,7 @@ fun InputCoordinate( } else { null }, + inputStyle = inputStyle, ) } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputDateTime.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputDateTime.kt index 58785112a..455df51db 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputDateTime.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputDateTime.kt @@ -55,6 +55,7 @@ fun InputDateTime( onActionClicked: () -> Unit, modifier: Modifier = Modifier, state: InputShellState = InputShellState.UNFOCUSED, + inputStyle: InputStyle = InputStyle.DataInputStyle(), legendData: LegendData? = null, supportingText: List? = null, onNextClicked: (() -> Unit)? = null, @@ -187,6 +188,7 @@ fun InputDateTime( Legend(legendData, Modifier.testTag("INPUT_DATE_TIME_LEGEND")) } }, + inputStyle = inputStyle, ) } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputDropDown.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputDropDown.kt index cff6fbeea..da4cf4ea1 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputDropDown.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputDropDown.kt @@ -62,6 +62,7 @@ private const val MAX_DROPDOWN_ITEMS = 6 fun InputDropDown( title: String, state: InputShellState, + inputStyle: InputStyle = InputStyle.DataInputStyle(), dropdownItems: List, selectedItem: DropdownItem? = null, supportingTextData: List? = null, @@ -83,6 +84,7 @@ fun InputDropDown( focusRequester = focusRequester, title = title, state = state, + inputStyle = inputStyle, isRequiredField = isRequiredField, expanded = showDropdown, onFocusChanged = onFocusChanged, @@ -203,6 +205,7 @@ fun InputDropDown( private fun DropdownInputField( title: String, state: InputShellState, + inputStyle: InputStyle = InputStyle.DataInputStyle(), isRequiredField: Boolean, expanded: Boolean, focusRequester: FocusRequester, @@ -299,6 +302,7 @@ private fun DropdownInputField( } else { null }, + inputStyle = inputStyle, ) } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputEmail.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputEmail.kt index e27ab730b..5c99fd79d 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputEmail.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputEmail.kt @@ -46,6 +46,7 @@ fun InputEmail( imeAction: ImeAction = ImeAction.Next, modifier: Modifier = Modifier, onEmailActionCLicked: () -> Unit, + inputStyle: InputStyle = InputStyle.DataInputStyle(), ) { val isValidEmailAddress = RegExValidations.EMAIL.regex.matches(inputTextFieldValue?.text.orEmpty()) BasicTextInput( @@ -67,7 +68,7 @@ fun InputEmail( actionButton = { SquareIconButton( modifier = Modifier.testTag("EMAIL_BUTTON"), - enabled = isValidEmailAddress, + enabled = isButtonEnabled(inputStyle, isValidEmailAddress), icon = { Icon( imageVector = Icons.Outlined.Email, @@ -79,5 +80,12 @@ fun InputEmail( }, autoCompleteList = autoCompleteList, autoCompleteItemSelected = autoCompleteItemSelected, + inputStyle = inputStyle, ) } + +private fun isButtonEnabled(inputStyle: InputStyle, isValidEmailAddress: Boolean) = + when (inputStyle) { + is InputStyle.DataInputStyle -> isValidEmailAddress + is InputStyle.ParameterInputStyle -> false + } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputField.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputField.kt index 6fe4d9e59..c497a9138 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputField.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputField.kt @@ -69,7 +69,7 @@ fun EmptyInput( * clickable and will appear disabled to accessibility services. * @param isSingleLine manages the number of lines to be allowed in the input field * @param helperStyle manages the helper text style, NONE by default - * @param inputText manages the value of the input field text + * @param inputTextValue manages the value of the input field text * @param onInputChanged gives access to the onTextChangedEvent * @param modifier to pass a modifier if necessary * @param state manages the color of cursor depending on the state of parent component @@ -85,7 +85,7 @@ fun BasicTextField( helper: String? = null, enabled: Boolean = true, isSingleLine: Boolean = true, - helperStyle: InputStyle = InputStyle.NONE, + helperStyle: HelperStyle = HelperStyle.NONE, inputTextValue: TextFieldValue? = null, onInputChanged: (TextFieldValue) -> Unit, modifier: Modifier = Modifier, @@ -97,12 +97,12 @@ fun BasicTextField( val keyboardController = LocalSoftwareKeyboardController.current var textFieldVisualTransformation = VisualTransformation.None - if (helperStyle != InputStyle.NONE) { + if (helperStyle != HelperStyle.NONE) { when (helperStyle) { - InputStyle.WITH_HELPER_BEFORE -> { + HelperStyle.WITH_HELPER_BEFORE -> { helper?.let { textFieldVisualTransformation = PrefixTransformation(it, enabled) } } - InputStyle.WITH_DATE_OF_BIRTH_HELPER -> { + HelperStyle.WITH_DATE_OF_BIRTH_HELPER -> { textFieldVisualTransformation = DateTransformation() } else -> { @@ -168,7 +168,7 @@ fun BasicTextField( } } -enum class InputStyle { +enum class HelperStyle { WITH_HELPER_AFTER, WITH_HELPER_BEFORE, WITH_DATE_OF_BIRTH_HELPER, diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputFileResource.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputFileResource.kt index 44947a9c4..814de297b 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputFileResource.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputFileResource.kt @@ -45,6 +45,7 @@ fun InputFileResource( onClear: () -> Unit = {}, uploadFileState: UploadFileState = ADD, inputShellState: InputShellState = InputShellState.UNFOCUSED, + inputStyle: InputStyle = InputStyle.DataInputStyle(), supportingText: List? = null, legendData: LegendData? = null, isRequired: Boolean = false, @@ -180,6 +181,7 @@ fun InputFileResource( secondaryButton = secondaryButton, isRequiredField = isRequired, modifier = modifier.focusRequester(focusRequester), + inputStyle = inputStyle, ) } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputImage.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputImage.kt index 24e4aeb6c..86d1d3421 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputImage.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputImage.kt @@ -31,6 +31,7 @@ import org.hisp.dhis.mobile.ui.designsystem.resource.provideStringResource fun InputImage( title: String, state: InputShellState = InputShellState.UNFOCUSED, + inputStyle: InputStyle = InputStyle.DataInputStyle(), supportingText: List? = null, legendData: LegendData? = null, uploadState: UploadState = UploadState.ADD, @@ -48,6 +49,7 @@ fun InputImage( BasicInputImage( title = title, state = state, + inputStyle = inputStyle, supportingText = supportingText, legendData = legendData, addButtonText = addImageBtnText, diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputInteger.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputInteger.kt index 5b7ab2af5..81a6578bf 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputInteger.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputInteger.kt @@ -30,6 +30,7 @@ import org.hisp.dhis.mobile.ui.designsystem.component.internal.RegExValidations fun InputInteger( title: String, state: InputShellState, + inputStyle: InputStyle = InputStyle.DataInputStyle(), supportingText: List? = null, legendData: LegendData? = null, inputTextFieldValue: TextFieldValue? = null, @@ -58,5 +59,6 @@ fun InputInteger( onFocusChanged = onFocusChanged, autoCompleteList = autoCompleteList, autoCompleteItemSelected = autoCompleteItemSelected, + inputStyle = inputStyle, ) } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputLetter.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputLetter.kt index 0427204cc..b78c7452f 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputLetter.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputLetter.kt @@ -32,6 +32,7 @@ import org.hisp.dhis.mobile.ui.designsystem.component.internal.RegExValidations fun InputLetter( title: String, state: InputShellState, + inputStyle: InputStyle = InputStyle.DataInputStyle(), supportingText: List? = null, legendData: LegendData? = null, inputTextFieldValue: TextFieldValue? = null, @@ -47,6 +48,7 @@ fun InputLetter( BasicTextInput( title = title, state = state, + inputStyle = inputStyle, supportingText = supportingText, legendData = legendData, inputTextFieldValue = inputTextFieldValue, diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputLink.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputLink.kt index 182160888..e0fbe8c7b 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputLink.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputLink.kt @@ -34,6 +34,7 @@ import org.hisp.dhis.mobile.ui.designsystem.component.internal.RegExValidations fun InputLink( title: String, state: InputShellState, + inputStyle: InputStyle = InputStyle.DataInputStyle(), supportingText: List? = null, legendData: LegendData? = null, inputTextFieldValue: TextFieldValue? = null, @@ -51,6 +52,7 @@ fun InputLink( BasicTextInput( title = title, state = state, + inputStyle = inputStyle, supportingText = supportingText, legendData = legendData, inputTextFieldValue = inputTextFieldValue, @@ -67,7 +69,7 @@ fun InputLink( actionButton = { SquareIconButton( modifier = Modifier.testTag("LINK_BUTTON"), - enabled = isValidUrl && state != InputShellState.DISABLED, + enabled = isButtonEnabled(inputStyle, isValidUrl, state), icon = { Icon( imageVector = Icons.Outlined.Link, @@ -81,3 +83,9 @@ fun InputLink( autoCompleteItemSelected = autoCompleteItemSelected, ) } + +private fun isButtonEnabled(inputStyle: InputStyle, isValidUrl: Boolean, state: InputShellState) = + when (inputStyle) { + is InputStyle.DataInputStyle -> isValidUrl && state != InputShellState.DISABLED + is InputStyle.ParameterInputStyle -> false + } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputLongText.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputLongText.kt index 922192f1b..56f6d9321 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputLongText.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputLongText.kt @@ -27,6 +27,7 @@ import androidx.compose.ui.text.input.TextFieldValue fun InputLongText( title: String, state: InputShellState, + inputStyle: InputStyle = InputStyle.DataInputStyle(), supportingText: List? = null, legendData: LegendData? = null, inputTextFieldValue: TextFieldValue? = null, @@ -42,6 +43,7 @@ fun InputLongText( BasicTextInput( title = title, state = state, + inputStyle = inputStyle, supportingText = supportingText, legendData = legendData, inputTextFieldValue = inputTextFieldValue, diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputMatrix.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputMatrix.kt index dfe7af4a2..a8137c84c 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputMatrix.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputMatrix.kt @@ -42,6 +42,7 @@ fun InputMatrix( selectedData: IconCardData? = null, modifier: Modifier = Modifier, state: InputShellState, + inputStyle: InputStyle = InputStyle.DataInputStyle(), supportingText: List? = null, legendData: LegendData? = null, isRequired: Boolean = false, @@ -96,6 +97,7 @@ fun InputMatrix( Legend(legendData, Modifier.testTag("ICON_CARDS_INPUT_" + testTag + "_LEGEND")) } }, + inputStyle = inputStyle, ) } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputNegativeInteger.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputNegativeInteger.kt index 5d88ea0a8..5af9fdea8 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputNegativeInteger.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputNegativeInteger.kt @@ -35,6 +35,7 @@ import org.hisp.dhis.mobile.ui.designsystem.component.internal.RegExValidations fun InputNegativeInteger( title: String, state: InputShellState, + inputStyle: InputStyle = InputStyle.DataInputStyle(), supportingText: List? = null, legendData: LegendData? = null, inputTextFieldValue: TextFieldValue? = null, @@ -52,6 +53,7 @@ fun InputNegativeInteger( BasicTextInput( title = title, state = state, + inputStyle = inputStyle, supportingText = supportingText, legendData = legendData, inputTextFieldValue = inputValue, @@ -61,7 +63,7 @@ fun InputNegativeInteger( onValueChanged?.invoke(TextFieldValue(if (it.text.startsWith("-") || it.text.isEmpty()) it.text else "-${it.text}")) inputValue = TextFieldValue(if (it.text.startsWith("-")) inputValue.text.replaceFirst("-", "") else it.text) }, - helperStyle = InputStyle.WITH_HELPER_BEFORE, + helperStyle = HelperStyle.WITH_HELPER_BEFORE, helper = "-", keyboardOptions = KeyboardOptions(imeAction = imeAction, keyboardType = KeyboardType.Number), allowedCharacters = RegExValidations.NEGATIVE_INTEGERS.regex, diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputNotSupported.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputNotSupported.kt index 08ace6c06..a6107679a 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputNotSupported.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputNotSupported.kt @@ -17,6 +17,7 @@ fun InputNotSupported( title: String, modifier: Modifier = Modifier, notSupportedString: String = provideStringResource("not_supported"), + inputStyle: InputStyle = InputStyle.DataInputStyle(), ) { InputShell( modifier = modifier, @@ -29,5 +30,6 @@ fun InputNotSupported( style = MaterialTheme.typography.bodyLarge, ) }, + inputStyle = inputStyle, ) } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputNumber.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputNumber.kt index f974f0bd4..f33d698dd 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputNumber.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputNumber.kt @@ -32,6 +32,7 @@ import org.hisp.dhis.mobile.ui.designsystem.component.internal.RegExValidations fun InputNumber( title: String, state: InputShellState, + inputStyle: InputStyle = InputStyle.DataInputStyle(), supportingText: List? = null, legendData: LegendData? = null, inputTextFieldValue: TextFieldValue? = null, @@ -48,6 +49,7 @@ fun InputNumber( BasicTextInput( title = title, state = state, + inputStyle = inputStyle, supportingText = supportingText, legendData = legendData, inputTextFieldValue = inputTextFieldValue, diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputOrgUnit.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputOrgUnit.kt index 7f3927c37..cd8231a8e 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputOrgUnit.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputOrgUnit.kt @@ -30,7 +30,7 @@ import org.hisp.dhis.mobile.ui.designsystem.theme.TextColor import org.hisp.dhis.mobile.ui.designsystem.theme.textFieldHoverPointerIcon /** - * DHIS2 Input org unit. Wraps DHIS · [BasicTextInput]. + * DHIS2 Input org unit. * @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 @@ -48,6 +48,7 @@ import org.hisp.dhis.mobile.ui.designsystem.theme.textFieldHoverPointerIcon fun InputOrgUnit( title: String, state: InputShellState = InputShellState.UNFOCUSED, + inputStyle: InputStyle = InputStyle.DataInputStyle(), supportingText: List? = null, legendData: LegendData? = null, inputText: String? = null, @@ -185,5 +186,6 @@ fun InputOrgUnit( } }, onFocusChanged = onFocusChanged, + inputStyle = inputStyle, ) } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputPercentage.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputPercentage.kt index e8d340968..c366dfe7f 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputPercentage.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputPercentage.kt @@ -30,6 +30,7 @@ import org.hisp.dhis.mobile.ui.designsystem.component.internal.RegExValidations fun InputPercentage( title: String, state: InputShellState, + inputStyle: InputStyle = InputStyle.DataInputStyle(), supportingText: List? = null, legendData: LegendData? = null, inputTextFieldValue: TextFieldValue? = null, @@ -45,13 +46,14 @@ fun InputPercentage( BasicTextInput( title = title, state = state, + inputStyle = inputStyle, supportingText = supportingText, legendData = legendData, inputTextFieldValue = inputTextFieldValue, isRequiredField = isRequiredField, onNextClicked = onNextClicked, onValueChanged = onValueChanged, - helperStyle = InputStyle.WITH_HELPER_AFTER, + helperStyle = HelperStyle.WITH_HELPER_AFTER, helper = "%", keyboardOptions = KeyboardOptions(imeAction = imeAction, keyboardType = KeyboardType.Number), allowedCharacters = RegExValidations.PERCENTAGE.regex, diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputPhoneNumber.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputPhoneNumber.kt index 8c2c2e0f7..f27a743f0 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputPhoneNumber.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputPhoneNumber.kt @@ -13,7 +13,7 @@ import androidx.compose.ui.text.input.TextFieldValue import org.hisp.dhis.mobile.ui.designsystem.component.internal.RegExValidations /** - * DHIS2 Input Phone Number + * DHIS2 Input Phone Number. Wraps DHIS · [BasicTextInput]. * Input that allows only numeric values for entering phone number. * * @param title controls the text to be shown for the title @@ -37,6 +37,7 @@ fun InputPhoneNumber( modifier: Modifier = Modifier, maxLength: Int = 12, state: InputShellState, + inputStyle: InputStyle = InputStyle.DataInputStyle(), legendData: LegendData? = null, inputTextFieldValue: TextFieldValue? = null, isRequiredField: Boolean = false, @@ -53,6 +54,7 @@ fun InputPhoneNumber( BasicTextInput( title = title, state = state, + inputStyle = inputStyle, supportingText = supportingText, legendData = legendData, inputTextFieldValue = inputTextFieldValue, @@ -65,14 +67,17 @@ fun InputPhoneNumber( // no-op } }, - keyboardOptions = KeyboardOptions(imeAction = imeAction, keyboardType = KeyboardType.Number), + keyboardOptions = KeyboardOptions( + imeAction = imeAction, + keyboardType = KeyboardType.Number, + ), allowedCharacters = allowedCharacters.regex, modifier = modifier, testTag = "PHONE_NUMBER", actionButton = { SquareIconButton( modifier = Modifier.testTag("CALL_PHONE_NUMBER_BUTTON"), - enabled = hasMinimumPhoneNumberInput, + enabled = isButtonEnabled(inputStyle, hasMinimumPhoneNumberInput), icon = { Icon( imageVector = Icons.Filled.Phone, @@ -89,3 +94,9 @@ fun InputPhoneNumber( autoCompleteItemSelected = autoCompleteItemSelected, ) } + +private fun isButtonEnabled(inputStyle: InputStyle, hasMinimumPhoneNumberInput: Boolean) = + when (inputStyle) { + is InputStyle.DataInputStyle -> hasMinimumPhoneNumberInput + is InputStyle.ParameterInputStyle -> false + } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputPolygon.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputPolygon.kt index 3adf995bb..f45bc7702 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputPolygon.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputPolygon.kt @@ -36,6 +36,7 @@ import org.hisp.dhis.mobile.ui.designsystem.theme.TextColor fun InputPolygon( title: String, state: InputShellState = InputShellState.UNFOCUSED, + inputStyle: InputStyle = InputStyle.DataInputStyle(), supportingText: List? = null, legendData: LegendData? = null, polygonText: String? = provideStringResource("polygon_captured"), @@ -132,5 +133,6 @@ fun InputPolygon( } else { null }, + inputStyle = inputStyle, ) } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputPositiveInteger.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputPositiveInteger.kt index 53f4aef08..e7367bdf8 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputPositiveInteger.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputPositiveInteger.kt @@ -30,6 +30,7 @@ import org.hisp.dhis.mobile.ui.designsystem.component.internal.RegExValidations fun InputPositiveInteger( title: String, state: InputShellState, + inputStyle: InputStyle = InputStyle.DataInputStyle(), supportingText: List? = null, legendData: LegendData? = null, inputTextFieldValue: TextFieldValue? = null, @@ -45,6 +46,7 @@ fun InputPositiveInteger( BasicTextInput( title = title, state = state, + inputStyle = inputStyle, supportingText = supportingText, legendData = legendData, inputTextFieldValue = inputTextFieldValue, diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputPositiveIntegerOrZero.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputPositiveIntegerOrZero.kt index e2edff7b3..13e02c94a 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputPositiveIntegerOrZero.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputPositiveIntegerOrZero.kt @@ -30,6 +30,7 @@ import org.hisp.dhis.mobile.ui.designsystem.component.internal.RegExValidations fun InputPositiveIntegerOrZero( title: String, state: InputShellState, + inputStyle: InputStyle = InputStyle.DataInputStyle(), supportingText: List? = null, legendData: LegendData? = null, inputTextFieldValue: TextFieldValue? = null, @@ -45,6 +46,7 @@ fun InputPositiveIntegerOrZero( BasicTextInput( title = title, state = state, + inputStyle = inputStyle, supportingText = supportingText, legendData = legendData, inputTextFieldValue = inputTextFieldValue, diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputQRCode.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputQRCode.kt index 0b2c462d3..f49550791 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputQRCode.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputQRCode.kt @@ -34,6 +34,7 @@ import androidx.compose.ui.text.input.TextFieldValue fun InputQRCode( title: String, state: InputShellState, + inputStyle: InputStyle = InputStyle.DataInputStyle(), onQRButtonClicked: () -> Unit, supportingText: List? = null, legendData: LegendData? = null, @@ -47,10 +48,12 @@ fun InputQRCode( imeAction: ImeAction = ImeAction.Next, modifier: Modifier = Modifier, ) { - val actionButtonIconVector = mutableStateOf(if (!inputTextFieldValue?.text.isNullOrEmpty()) Icons.Outlined.QrCode2 else Icons.Outlined.QrCodeScanner) + val actionButtonIconVector = + mutableStateOf(if (!inputTextFieldValue?.text.isNullOrEmpty()) Icons.Outlined.QrCode2 else Icons.Outlined.QrCodeScanner) BasicTextInput( title = title, state = state, + inputStyle = inputStyle, supportingText = supportingText, legendData = legendData, inputTextFieldValue = inputTextFieldValue, @@ -64,7 +67,7 @@ fun InputQRCode( actionButton = { SquareIconButton( modifier = Modifier.testTag("INPUT_QR_CODE_BUTTON"), - enabled = state != InputShellState.DISABLED, + enabled = isButtonEnabled(inputStyle, state, inputTextFieldValue?.text), icon = { Icon( imageVector = actionButtonIconVector.value, @@ -78,3 +81,9 @@ fun InputQRCode( autoCompleteItemSelected = autoCompleteItemSelected, ) } + +private fun isButtonEnabled(inputStyle: InputStyle, state: InputShellState, inputText: String?) = + when (inputStyle) { + is InputStyle.DataInputStyle -> state != InputShellState.DISABLED + is InputStyle.ParameterInputStyle -> inputText.isNullOrEmpty() + } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputRadioButton.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputRadioButton.kt index d8423e09f..8bf41afb8 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputRadioButton.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputRadioButton.kt @@ -38,6 +38,7 @@ fun InputRadioButton( modifier: Modifier = Modifier, orientation: Orientation = VERTICAL, state: InputShellState, + inputStyle: InputStyle = InputStyle.DataInputStyle(), supportingText: List? = null, legendData: LegendData? = null, isRequired: Boolean = false, @@ -95,5 +96,6 @@ fun InputRadioButton( Spacer(modifier = Modifier.width(Spacing.Spacing48)) } }, + inputStyle = inputStyle, ) } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputSequential.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputSequential.kt index a70047663..ad7830a57 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputSequential.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputSequential.kt @@ -41,6 +41,7 @@ fun InputSequential( selectedData: IconCardData? = null, modifier: Modifier = Modifier, state: InputShellState, + inputStyle: InputStyle = InputStyle.DataInputStyle(), supportingText: List? = null, legendData: LegendData? = null, isRequired: Boolean = false, @@ -93,6 +94,7 @@ fun InputSequential( Legend(legendData, Modifier.testTag("ICON_CARDS_INPUT_" + testTag + "_LEGEND")) } }, + inputStyle = inputStyle, ) } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputShell.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputShell.kt index f9ca1aab4..b58c107b1 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputShell.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputShell.kt @@ -62,8 +62,7 @@ fun InputShell( onFocusChanged: ((Boolean) -> Unit)? = null, isRequiredField: Boolean = false, modifier: Modifier = Modifier, - hasTransparentBackground: Boolean = false, - startIndent: Dp = if (hasTransparentBackground) Spacing.Spacing40 else Spacing.Spacing0, + inputStyle: InputStyle, ) { Column( modifier = modifier @@ -75,9 +74,8 @@ fun InputShell( var indicatorColor by remember(state) { mutableStateOf(state.color) } var indicatorThickness by remember { mutableStateOf(Border.Thin) } val backgroundColor = when { - hasTransparentBackground -> Color.Transparent - state != InputShellState.DISABLED -> SurfaceColor.Surface - else -> SurfaceColor.DisabledSurface + state != InputShellState.DISABLED -> inputStyle.backGroundColor + else -> inputStyle.disabledBackGroundColor } val focusRequester = remember { FocusRequester() } @@ -99,9 +97,15 @@ fun InputShell( } indicatorColor = when { - state == InputShellState.DISABLED -> InputShellState.DISABLED.color + state == InputShellState.DISABLED -> + inputStyle.disabledIndicatorColor + ?: InputShellState.DISABLED.color + it.isFocused && state != InputShellState.ERROR && state != InputShellState.WARNING -> InputShellState.FOCUSED.color - hasTransparentBackground && state == InputShellState.UNFOCUSED -> Outline.Light + state == InputShellState.UNFOCUSED -> + inputStyle.unfocusedIndicatorColor + ?: state.color + else -> state.color } indicatorThickness = when { @@ -110,7 +114,7 @@ fun InputShell( else -> Border.Thin } onFocusChanged?.invoke(it.isFocused) - }.padding(start = startIndent), + }.padding(start = inputStyle.startIndent), backgroundColor = backgroundColor, ) { Column( @@ -156,7 +160,12 @@ fun InputShell( legend?.invoke(this) if (state != InputShellState.DISABLED) supportingText?.invoke() - if (isRequiredField && state == InputShellState.ERROR && supportingText == null) SupportingText("Required", state = SupportingTextState.ERROR) + if (isRequiredField && state == InputShellState.ERROR && supportingText == null) { + SupportingText( + "Required", + state = SupportingTextState.ERROR, + ) + } } } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputSignature.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputSignature.kt index 4f20d2ecb..f01e81261 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputSignature.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputSignature.kt @@ -36,6 +36,7 @@ import org.hisp.dhis.mobile.ui.designsystem.resource.provideStringResource fun InputSignature( title: String, state: InputShellState = InputShellState.UNFOCUSED, + inputStyle: InputStyle = InputStyle.DataInputStyle(), supportingText: List? = null, legendData: LegendData? = null, addSignatureBtnText: String = provideStringResource("add_signature"), @@ -54,6 +55,7 @@ fun InputSignature( BasicInputImage( title = title, state = state, + inputStyle = inputStyle, supportingText = supportingText, legendData = legendData, addButtonText = addSignatureBtnText, diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputStyle.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputStyle.kt new file mode 100644 index 000000000..204dd74b0 --- /dev/null +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputStyle.kt @@ -0,0 +1,31 @@ +package org.hisp.dhis.mobile.ui.designsystem.component + +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.Dp +import org.hisp.dhis.mobile.ui.designsystem.theme.Outline +import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing +import org.hisp.dhis.mobile.ui.designsystem.theme.SurfaceColor + +sealed class InputStyle( + val startIndent: Dp, + val backGroundColor: Color, + val disabledBackGroundColor: Color, + val unfocusedIndicatorColor: Color?, + val disabledIndicatorColor: Color?, +) { + class DataInputStyle : InputStyle( + startIndent = Spacing.Spacing0, + backGroundColor = SurfaceColor.Surface, + disabledBackGroundColor = SurfaceColor.DisabledSurface, + unfocusedIndicatorColor = null, + disabledIndicatorColor = null, + ) + + class ParameterInputStyle : InputStyle( + startIndent = Spacing.Spacing40, + backGroundColor = Color.Transparent, + disabledBackGroundColor = Color.Transparent, + unfocusedIndicatorColor = Outline.Light, + disabledIndicatorColor = Outline.Light, + ) +} diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputText.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputText.kt index 90d792804..74840f8b8 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputText.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputText.kt @@ -37,6 +37,7 @@ fun InputText( onAutoCompleteItemSelected: ((String?) -> Unit)? = null, imeAction: ImeAction = ImeAction.Next, modifier: Modifier = Modifier, + inputStyle: InputStyle = InputStyle.DataInputStyle(), ) { BasicTextInput( title = title, @@ -53,5 +54,6 @@ fun InputText( testTag = "TEXT", onFocusChanged = onFocusChanged, autoCompleteItemSelected = onAutoCompleteItemSelected, + inputStyle = inputStyle, ) } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputUnitInterval.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputUnitInterval.kt index fcf92b0be..5347c7251 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputUnitInterval.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputUnitInterval.kt @@ -12,6 +12,7 @@ import org.hisp.dhis.mobile.ui.designsystem.component.internal.RegExValidations fun InputUnitInterval( title: String, state: InputShellState, + inputStyle: InputStyle = InputStyle.DataInputStyle(), supportingText: List? = null, legendData: LegendData? = null, inputTextFieldValue: TextFieldValue? = null, @@ -24,6 +25,7 @@ fun InputUnitInterval( BasicTextInput( title = title, state = state, + inputStyle = inputStyle, supportingText = supportingText, legendData = legendData, inputTextFieldValue = inputTextFieldValue, diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputYesNoField.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputYesNoField.kt index 46e7ff045..775fb68a0 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputYesNoField.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputYesNoField.kt @@ -29,6 +29,7 @@ fun InputYesNoField( title: String, modifier: Modifier = Modifier, state: InputShellState, + inputStyle: InputStyle = InputStyle.DataInputStyle(), supportingText: List? = null, legendData: LegendData? = null, isRequired: Boolean = false, @@ -55,7 +56,7 @@ fun InputYesNoField( } }, inputField = { - val options = InputYesNoFieldValues.values().map { + val options = InputYesNoFieldValues.entries.map { RadioButtonData( it.value, itemSelected == it, @@ -70,7 +71,7 @@ fun InputYesNoField( Modifier.offset(x = -Spacing.Spacing8), ) { radioButtonData -> onItemChange.invoke( - InputYesNoFieldValues.values().firstOrNull { it.name.equals(radioButtonData.uid, true) }, + InputYesNoFieldValues.entries.firstOrNull { it.name.equals(radioButtonData.uid, true) }, ) } }, @@ -91,6 +92,7 @@ fun InputYesNoField( ) } }, + inputStyle = inputStyle, ) } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputYesOnlyCheckBox.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputYesOnlyCheckBox.kt index 6ddab7d71..d8a207f51 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputYesOnlyCheckBox.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputYesOnlyCheckBox.kt @@ -16,6 +16,7 @@ fun InputYesOnlyCheckBox( checkBoxData: CheckBoxData, modifier: Modifier = Modifier, state: InputShellState, + inputStyle: InputStyle = InputStyle.DataInputStyle(), supportingText: List? = null, legendData: LegendData? = null, isRequired: Boolean = false, @@ -60,5 +61,6 @@ fun InputYesOnlyCheckBox( onClick.invoke(it) } }, + inputStyle = inputStyle, ) } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputYesOnlySwitch.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputYesOnlySwitch.kt index e561852c9..c08c6394c 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputYesOnlySwitch.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputYesOnlySwitch.kt @@ -20,6 +20,7 @@ fun InputYesOnlySwitch( title: String, modifier: Modifier = Modifier, state: InputShellState, + inputStyle: InputStyle = InputStyle.DataInputStyle(), supportingText: List? = null, legendData: LegendData? = null, isRequired: Boolean = false, @@ -71,5 +72,6 @@ fun InputYesOnlySwitch( } } }, + inputStyle = inputStyle, ) } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/parameter/ParameterSelector.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/parameter/ParameterSelector.kt new file mode 100644 index 000000000..f478f205e --- /dev/null +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/parameter/ParameterSelector.kt @@ -0,0 +1,136 @@ +package org.hisp.dhis.mobile.ui.designsystem.component.parameter + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.expandVertically +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.shrinkVertically +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentWidth +import androidx.compose.material.ripple.rememberRipple +import androidx.compose.material3.Divider +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +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.graphics.Color +import androidx.compose.ui.semantics.Role +import org.hisp.dhis.mobile.ui.designsystem.component.IconButton +import org.hisp.dhis.mobile.ui.designsystem.component.parameter.model.ParameterSelectorItemModel +import org.hisp.dhis.mobile.ui.designsystem.component.parameter.model.ParameterSelectorItemModel.Status.CLOSED +import org.hisp.dhis.mobile.ui.designsystem.component.parameter.model.ParameterSelectorItemModel.Status.OPENED +import org.hisp.dhis.mobile.ui.designsystem.theme.Border +import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing +import org.hisp.dhis.mobile.ui.designsystem.theme.SurfaceColor +import org.hisp.dhis.mobile.ui.designsystem.theme.TextColor +import org.hisp.dhis.mobile.ui.designsystem.theme.hoverPointerIcon + +@Composable +fun ParameterSelectorItem( + model: ParameterSelectorItemModel, +) { + var status by remember(model.status) { mutableStateOf(model.status) } + + AnimatedVisibility( + visible = status == CLOSED, + enter = fadeIn() + expandVertically(), + exit = shrinkVertically() + fadeOut(), + ) { + EmptyParameterField( + model = model, + ) { + status = OPENED + } + } + + AnimatedVisibility( + visible = status == OPENED, + enter = fadeIn() + expandVertically(), + exit = shrinkVertically() + fadeOut(), + ) { + model.inputField.invoke() + } +} + +@Composable +private fun EmptyParameterField( + model: ParameterSelectorItemModel, + onClick: () -> Unit, +) { + val interactionSource = remember { MutableInteractionSource() } + Column( + modifier = Modifier + .background(color = Color.Transparent) + .fillMaxWidth() + .clickable( + role = Role.Button, + interactionSource = interactionSource, + indication = rememberRipple( + color = SurfaceColor.Primary, + ), + onClick = onClick, + ) + .hoverPointerIcon(true), + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .fillMaxWidth() + .padding( + start = Spacing.Spacing8, + top = Spacing.Spacing8, + end = Spacing.Spacing16, + bottom = Spacing.Spacing8, + ), + ) { + IconButton( + modifier = Modifier + .padding(Spacing.Spacing8) + .wrapContentWidth(), + icon = { + Icon( + imageVector = model.icon, + contentDescription = "Icon Button", + tint = SurfaceColor.Primary, + ) + }, + onClick = onClick, + ) + Text( + modifier = Modifier + .weight(1f), + text = model.label, + color = SurfaceColor.Primary, + ) + + Text( + modifier = Modifier + .wrapContentWidth(), + text = model.helper, + color = TextColor.OnDisabledSurface, + style = MaterialTheme.typography.bodySmall, + ) + } + Box(Modifier.height(Spacing.Spacing2)) { + Divider( + modifier = Modifier.align(Alignment.BottomStart), + color = SurfaceColor.DisabledSurface, + thickness = Border.Thin, + ) + } + } +} diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/parameter/model/ParameterSelectorItemModel.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/parameter/model/ParameterSelectorItemModel.kt new file mode 100644 index 000000000..9ba9e7f0a --- /dev/null +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/parameter/model/ParameterSelectorItemModel.kt @@ -0,0 +1,19 @@ +package org.hisp.dhis.mobile.ui.designsystem.component.parameter.model + +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.AddCircleOutline +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.vector.ImageVector + +data class ParameterSelectorItemModel( + val icon: ImageVector = Icons.Outlined.AddCircleOutline, + val label: String, + val helper: String, + val inputField: @Composable () -> Unit, + val status: Status = Status.CLOSED, +) { + enum class Status { + OPENED, + CLOSED, + } +} diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/theme/Shape.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/theme/Shape.kt index bc3a5ca02..013a68a21 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/theme/Shape.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/theme/Shape.kt @@ -30,6 +30,12 @@ object Shape { ) val Medium = RoundedCornerShape(Radius.M) val Large = RoundedCornerShape(Radius.L) + val LargeTop = RoundedCornerShape( + topStart = CornerSize(Radius.L), + topEnd = CornerSize(Radius.L), + bottomEnd = CornerSize(Radius.NoRounding), + bottomStart = CornerSize(Radius.NoRounding), + ) val ExtraLargeTop = RoundedCornerShape( topStart = CornerSize(Radius.XL), diff --git a/gradle.properties b/gradle.properties index e80150033..211a6361a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -21,6 +21,6 @@ android.targetSdk=34 android.minSdk=21 #Versions -kotlin.version=1.9.21 -agp.version=8.2.0 -compose.version=1.5.11 \ No newline at end of file +kotlin.version=1.9.22 +agp.version=8.2.2 +compose.version=1.5.12 \ No newline at end of file