From 9b291975b78540b06914e4123484bc65f23ba25c Mon Sep 17 00:00:00 2001 From: Kaushik Meesala Date: Wed, 11 Oct 2023 16:14:55 -0700 Subject: [PATCH 01/11] init radiobutton field type impl --- .../toolkit/featureforms/FeatureForm.kt | 10 ++ .../featureforms/components/FormElements.kt | 7 + .../components/radio/RadioButtonField.kt | 160 ++++++++++++++++++ .../components/radio/RadioButtonFieldState.kt | 134 +++++++++++++++ 4 files changed, 311 insertions(+) create mode 100644 toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonField.kt create mode 100644 toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonFieldState.kt diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/FeatureForm.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/FeatureForm.kt index 92caeaeb2..49d524ae2 100644 --- a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/FeatureForm.kt +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/FeatureForm.kt @@ -33,12 +33,14 @@ import com.arcgismaps.mapping.featureforms.ComboBoxFormInput import com.arcgismaps.mapping.featureforms.DateTimePickerFormInput import com.arcgismaps.mapping.featureforms.FeatureForm import com.arcgismaps.mapping.featureforms.FieldFormElement +import com.arcgismaps.mapping.featureforms.RadioButtonsFormInput import com.arcgismaps.mapping.featureforms.TextAreaFormInput import com.arcgismaps.mapping.featureforms.TextBoxFormInput import com.arcgismaps.toolkit.featureforms.components.FieldElement import com.arcgismaps.toolkit.featureforms.components.base.BaseFieldState import com.arcgismaps.toolkit.featureforms.components.combo.rememberComboBoxFieldState import com.arcgismaps.toolkit.featureforms.components.datetime.rememberDateTimeFieldState +import com.arcgismaps.toolkit.featureforms.components.radio.rememberRadioButtonFieldState import com.arcgismaps.toolkit.featureforms.components.text.rememberFormTextFieldState import kotlinx.coroutines.CoroutineScope import java.util.Objects @@ -194,6 +196,14 @@ private fun rememberFieldStates( ) } + is RadioButtonsFormInput -> { + rememberRadioButtonFieldState( + field = fieldElement, + form = form, + scope = scope + ) + } + else -> { null } diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/FormElements.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/FormElements.kt index f4fb2fa67..12cf7e183 100644 --- a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/FormElements.kt +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/FormElements.kt @@ -8,6 +8,7 @@ import com.arcgismaps.mapping.featureforms.DateTimePickerFormInput import com.arcgismaps.mapping.featureforms.FeatureForm import com.arcgismaps.mapping.featureforms.FieldFormElement import com.arcgismaps.mapping.featureforms.GroupFormElement +import com.arcgismaps.mapping.featureforms.RadioButtonsFormInput import com.arcgismaps.mapping.featureforms.TextAreaFormInput import com.arcgismaps.mapping.featureforms.TextBoxFormInput import com.arcgismaps.toolkit.featureforms.components.base.BaseFieldState @@ -15,6 +16,8 @@ import com.arcgismaps.toolkit.featureforms.components.combo.ComboBoxField import com.arcgismaps.toolkit.featureforms.components.combo.ComboBoxFieldState import com.arcgismaps.toolkit.featureforms.components.datetime.DateTimeField import com.arcgismaps.toolkit.featureforms.components.datetime.DateTimeFieldState +import com.arcgismaps.toolkit.featureforms.components.radio.RadioButtonField +import com.arcgismaps.toolkit.featureforms.components.radio.RadioButtonFieldState import com.arcgismaps.toolkit.featureforms.components.text.FormTextField import com.arcgismaps.toolkit.featureforms.components.text.FormTextFieldState @@ -35,6 +38,10 @@ internal fun FieldElement(field: FieldFormElement, state: BaseFieldState) { ComboBoxField(state = state as ComboBoxFieldState) } + is RadioButtonsFormInput -> { + RadioButtonField(state = state as RadioButtonFieldState) + } + else -> { /* TO-DO: add support for other input types */ } } diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonField.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonField.kt new file mode 100644 index 000000000..c85308471 --- /dev/null +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonField.kt @@ -0,0 +1,160 @@ +/* + * Copyright 2023 Esri + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.arcgismaps.toolkit.featureforms.components.radio + +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.selection.selectable +import androidx.compose.foundation.selection.selectableGroup +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.RadioButton +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.semantics.Role +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.arcgismaps.mapping.featureforms.FormInputNoValueOption +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow + +@Composable +internal fun RadioButtonField(state: RadioButtonFieldState, modifier: Modifier = Modifier) { + val value by state.value.collectAsState() + val editable by state.isEditable.collectAsState() + val required by state.isRequired.collectAsState() + + val label = remember(required) { + if (required) { + "${state.label} *" + } else { + state.label + } + } + + Column( + modifier = modifier + .fillMaxWidth() + .padding(start = 15.dp, end = 15.dp, top = 10.dp, bottom = 10.dp), + verticalArrangement = Arrangement.spacedBy(10.dp), + horizontalAlignment = Alignment.Start + ) { + Text( + text = label, + style = MaterialTheme.typography.bodyLarge, + color = if (editable) { + MaterialTheme.colorScheme.onSurfaceVariant + } else { + MaterialTheme.colorScheme.onSurface.copy( + alpha = 0.38f + ) + } + ) + Column( + modifier = Modifier + .selectableGroup() + .border( + width = 1.dp, + color = MaterialTheme.colorScheme.primaryContainer, + shape = RoundedCornerShape(5.dp) + ) + ) { + state.codedValues.forEach { code -> + RadioButtonRow( + value = code, + selected = (code == value), + onClick = { state.onValueChanged(code) } + ) + } + } + if (state.description.isNotEmpty()) { + Text( + text = state.description, + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + } + +} + +@Composable +private fun RadioButtonRow( + value: String, + selected: Boolean, + onClick: () -> Unit, + modifier: Modifier = Modifier, +) { + Row( + modifier = modifier + .fillMaxWidth() + .selectable( + selected = selected, + onClick = onClick, + role = Role.RadioButton + ) + .padding(15.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(15.dp) + ) { + RadioButton(selected = selected, onClick = null) + Text(text = value, style = MaterialTheme.typography.bodyLarge) + } +} + +internal class RadioButtonFieldColors ( + val labelColor : Color, + val focusedLabelColor : Color, + val disabledLabelColor : Color, + val supportingTextColor : Color, + val containerColor : Color, + val containerBorderColor : Color +) + +@Preview(showBackground = true, backgroundColor = 0xFFFFFFFF, showSystemUi = true) +@Composable +private fun RadioButtonFieldPreview() { + MaterialTheme { + val state = RadioButtonFieldState( + properties = RadioButtonFieldProperties( + label = "Label", + placeholder = "Placeholder", + description = "Description", + value = MutableStateFlow(""), + editable = MutableStateFlow(true), + required = MutableStateFlow(true), + codedValues = listOf("One", "Two", "Three"), + showNoValueOption = FormInputNoValueOption.Show, + noValueLabel = "No Value" + ), + scope = CoroutineScope(Dispatchers.IO), + onEditValue = {} + ) + RadioButtonField(state = state) + } +} diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonFieldState.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonFieldState.kt new file mode 100644 index 000000000..0c973d0e5 --- /dev/null +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonFieldState.kt @@ -0,0 +1,134 @@ +/* + * Copyright 2023 Esri + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.arcgismaps.toolkit.featureforms.components.radio + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.saveable.Saver +import androidx.compose.runtime.saveable.listSaver +import androidx.compose.runtime.saveable.rememberSaveable +import com.arcgismaps.mapping.featureforms.FeatureForm +import com.arcgismaps.mapping.featureforms.FieldFormElement +import com.arcgismaps.mapping.featureforms.FormInputNoValueOption +import com.arcgismaps.mapping.featureforms.RadioButtonsFormInput +import com.arcgismaps.toolkit.featureforms.components.base.BaseFieldState +import com.arcgismaps.toolkit.featureforms.components.base.FieldProperties +import com.arcgismaps.toolkit.featureforms.components.combo.ComboBoxFieldState +import com.arcgismaps.toolkit.featureforms.utils.editValue +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch + +internal class RadioButtonFieldProperties( + label: String, + placeholder: String, + description: String, + value: StateFlow, + required: StateFlow, + editable: StateFlow, + val codedValues: List, + val showNoValueOption: FormInputNoValueOption, + val noValueLabel: String +) : FieldProperties(label, placeholder, description, value, required, editable) + +internal class RadioButtonFieldState( + properties: RadioButtonFieldProperties, + initialValue: String = properties.value.value, + scope: CoroutineScope, + onEditValue: ((Any?) -> Unit) +) : BaseFieldState(properties, initialValue, scope, onEditValue) { + + /** + * The list of coded values associated with this field. + */ + val codedValues: List = properties.codedValues + + /** + * This property defines whether to display a special "no value" option if this field is + * optional. + */ + val showNoValueOption: FormInputNoValueOption = properties.showNoValueOption + + /** + * The custom label to use if [showNoValueOption] is enabled. + */ + val noValueLabel: String = properties.noValueLabel + + companion object { + fun Saver( + formElement: FieldFormElement, + form: FeatureForm, + scope: CoroutineScope + ): Saver = listSaver( + save = { + listOf( + it.value.value + ) + }, + restore = { list -> + val input = formElement.input as RadioButtonsFormInput + RadioButtonFieldState( + properties = RadioButtonFieldProperties( + label = formElement.label, + placeholder = formElement.hint, + description = formElement.description, + value = formElement.value, + editable = formElement.isEditable, + required = formElement.isRequired, + codedValues = input.codedValues.map { it.code.toString() }, + showNoValueOption = input.noValueOption, + noValueLabel = input.noValueLabel + ), + initialValue = list[0], + scope = scope, + onEditValue = { newValue -> + form.editValue(formElement, newValue) + scope.launch { form.evaluateExpressions() } + } + ) + } + ) + } +} + +@Composable +internal fun rememberRadioButtonFieldState( + field: FieldFormElement, + form: FeatureForm, + scope: CoroutineScope +): RadioButtonFieldState = rememberSaveable( + saver = RadioButtonFieldState.Saver(field, form, scope) +) { + val input = field.input as RadioButtonsFormInput + RadioButtonFieldState( + properties = RadioButtonFieldProperties( + label = field.label, + placeholder = field.hint, + description = field.description, + value = field.value, + editable = field.isEditable, + required = field.isRequired, + codedValues = input.codedValues.map { it.code.toString() }, + showNoValueOption = input.noValueOption, + noValueLabel = input.noValueLabel + ), + scope = scope, + onEditValue = { + form.editValue(field, it) + scope.launch { form.evaluateExpressions() } + } + ) +} From b4dffe452ded9702803705e086804c097a6e7367 Mon Sep 17 00:00:00 2001 From: Kaushik Meesala Date: Wed, 11 Oct 2023 16:51:42 -0700 Subject: [PATCH 02/11] added no value row handing --- .../components/radio/RadioButtonField.kt | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonField.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonField.kt index c85308471..947f3492f 100644 --- a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonField.kt +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonField.kt @@ -35,10 +35,13 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.Role import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.arcgismaps.mapping.featureforms.FormInputNoValueOption +import com.arcgismaps.toolkit.featureforms.R import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow @@ -48,6 +51,12 @@ internal fun RadioButtonField(state: RadioButtonFieldState, modifier: Modifier = val value by state.value.collectAsState() val editable by state.isEditable.collectAsState() val required by state.isRequired.collectAsState() + val noValueLabel = state.noValueLabel.ifEmpty { stringResource(R.string.no_value) } + val options = if (!required) { + if (state.showNoValueOption == FormInputNoValueOption.Show) { + listOf(noValueLabel) + state.codedValues + } else state.codedValues + } else state.codedValues val label = remember(required) { if (required) { @@ -84,10 +93,10 @@ internal fun RadioButtonField(state: RadioButtonFieldState, modifier: Modifier = shape = RoundedCornerShape(5.dp) ) ) { - state.codedValues.forEach { code -> + options.forEach { code -> RadioButtonRow( value = code, - selected = (code == value), + selected = (code == value) || (code == noValueLabel && value.isEmpty()), onClick = { state.onValueChanged(code) } ) } @@ -127,13 +136,13 @@ private fun RadioButtonRow( } } -internal class RadioButtonFieldColors ( - val labelColor : Color, - val focusedLabelColor : Color, - val disabledLabelColor : Color, - val supportingTextColor : Color, - val containerColor : Color, - val containerBorderColor : Color +internal class RadioButtonFieldColors( + val labelColor: Color, + val focusedLabelColor: Color, + val disabledLabelColor: Color, + val supportingTextColor: Color, + val containerColor: Color, + val containerBorderColor: Color ) @Preview(showBackground = true, backgroundColor = 0xFFFFFFFF, showSystemUi = true) @@ -147,7 +156,7 @@ private fun RadioButtonFieldPreview() { description = "Description", value = MutableStateFlow(""), editable = MutableStateFlow(true), - required = MutableStateFlow(true), + required = MutableStateFlow(false), codedValues = listOf("One", "Two", "Three"), showNoValueOption = FormInputNoValueOption.Show, noValueLabel = "No Value" From 5465ae2d315fc88a94ac1832c80ede0e75e69501 Mon Sep 17 00:00:00 2001 From: Kaushik Meesala Date: Thu, 12 Oct 2023 11:35:03 -0700 Subject: [PATCH 03/11] added default color support for radio button --- .../components/radio/RadioButtonField.kt | 70 ++++++----- .../radio/RadioButtonFieldDefaults.kt | 115 ++++++++++++++++++ 2 files changed, 152 insertions(+), 33 deletions(-) create mode 100644 toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonFieldDefaults.kt diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonField.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonField.kt index 947f3492f..2efdbd53e 100644 --- a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonField.kt +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonField.kt @@ -25,17 +25,17 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.selection.selectable import androidx.compose.foundation.selection.selectableGroup import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.LocalContentColor import androidx.compose.material3.MaterialTheme import androidx.compose.material3.RadioButton import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.Role import androidx.compose.ui.tooling.preview.Preview @@ -47,7 +47,11 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow @Composable -internal fun RadioButtonField(state: RadioButtonFieldState, modifier: Modifier = Modifier) { +internal fun RadioButtonField( + state: RadioButtonFieldState, + modifier: Modifier = Modifier, + colors: RadioButtonFieldColors = RadioButtonFieldDefaults.colors() +) { val value by state.value.collectAsState() val editable by state.isEditable.collectAsState() val required by state.isRequired.collectAsState() @@ -75,37 +79,36 @@ internal fun RadioButtonField(state: RadioButtonFieldState, modifier: Modifier = ) { Text( text = label, - style = MaterialTheme.typography.bodyLarge, - color = if (editable) { - MaterialTheme.colorScheme.onSurfaceVariant - } else { - MaterialTheme.colorScheme.onSurface.copy( - alpha = 0.38f - ) - } + style = MaterialTheme.typography.bodyMedium, + color = colors.labelColor(enabled = editable) ) Column( modifier = Modifier .selectableGroup() .border( width = 1.dp, - color = MaterialTheme.colorScheme.primaryContainer, + color = colors.containerBorderColor(enabled = editable), shape = RoundedCornerShape(5.dp) ) ) { - options.forEach { code -> - RadioButtonRow( - value = code, - selected = (code == value) || (code == noValueLabel && value.isEmpty()), - onClick = { state.onValueChanged(code) } - ) + CompositionLocalProvider( + LocalContentColor provides colors.textColor(enabled = editable) + ) { + options.forEach { code -> + RadioButtonRow( + value = code, + selected = (code == value) || (code == noValueLabel && value.isEmpty()), + enabled = editable, + onClick = { state.onValueChanged(code) } + ) + } } } if (state.description.isNotEmpty()) { Text( text = state.description, style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant + color = colors.supportingTextColor(enabled = editable) ) } } @@ -116,6 +119,7 @@ internal fun RadioButtonField(state: RadioButtonFieldState, modifier: Modifier = private fun RadioButtonRow( value: String, selected: Boolean, + enabled: Boolean, onClick: () -> Unit, modifier: Modifier = Modifier, ) { @@ -124,26 +128,26 @@ private fun RadioButtonRow( .fillMaxWidth() .selectable( selected = selected, + enabled = enabled, + role = Role.RadioButton, onClick = onClick, - role = Role.RadioButton ) - .padding(15.dp), + .padding(10.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(15.dp) + horizontalArrangement = Arrangement.spacedBy(10.dp) ) { - RadioButton(selected = selected, onClick = null) - Text(text = value, style = MaterialTheme.typography.bodyLarge) + RadioButton( + selected = selected, + onClick = null, + enabled = enabled + ) + Text( + text = value, + style = MaterialTheme.typography.bodyMedium + ) } } -internal class RadioButtonFieldColors( - val labelColor: Color, - val focusedLabelColor: Color, - val disabledLabelColor: Color, - val supportingTextColor: Color, - val containerColor: Color, - val containerBorderColor: Color -) @Preview(showBackground = true, backgroundColor = 0xFFFFFFFF, showSystemUi = true) @Composable @@ -151,7 +155,7 @@ private fun RadioButtonFieldPreview() { MaterialTheme { val state = RadioButtonFieldState( properties = RadioButtonFieldProperties( - label = "Label", + label = "A list of values", placeholder = "Placeholder", description = "Description", value = MutableStateFlow(""), diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonFieldDefaults.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonFieldDefaults.kt new file mode 100644 index 000000000..5e35f18fd --- /dev/null +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonFieldDefaults.kt @@ -0,0 +1,115 @@ +/* + * Copyright 2023 Esri + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.arcgismaps.toolkit.featureforms.components.radio + +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color + +internal object RadioButtonFieldDefaults { + + private const val textDisabledAlpha = 0.38f + private const val containerDisabledAlpha = 0.12f + + @Composable + fun colors(): RadioButtonFieldColors = RadioButtonFieldColors( + defaultLabelColor = MaterialTheme.colorScheme.onSurfaceVariant, + disabledLabelColor = MaterialTheme.colorScheme.onSurface.copy( + alpha = textDisabledAlpha + ), + defaultSupportingTextColor = MaterialTheme.colorScheme.onSurfaceVariant, + supportingTextDisabledColor = MaterialTheme.colorScheme.onSurfaceVariant.copy( + alpha = textDisabledAlpha + ), + errorColor = MaterialTheme.colorScheme.error, + defaultContainerBorderColor = MaterialTheme.colorScheme.outline, + containerBorderDisabledColor = MaterialTheme.colorScheme.outline.copy( + alpha = containerDisabledAlpha + ), + defaultTextColor = LocalContentColor.current, + disabledTextColor = LocalContentColor.current.copy(alpha = textDisabledAlpha) + ) +} + +internal data class RadioButtonFieldColors( + val defaultLabelColor: Color, + val disabledLabelColor: Color, + val defaultSupportingTextColor: Color, + val supportingTextDisabledColor: Color, + val errorColor: Color, + val defaultContainerBorderColor: Color, + val containerBorderDisabledColor: Color, + val defaultTextColor: Color, + val disabledTextColor: Color +) { + /** + * Represents the color used for the label of this radio button field. + * + * @param enabled whether the field is enabled + */ + @Composable + fun labelColor(enabled: Boolean): Color { + return if (enabled) { + defaultLabelColor + } else { + disabledLabelColor + } + } + + /** + * Represents the color used for the supporting text of this radio button field. + * + * @param enabled whether the field is enabled + */ + @Composable + fun supportingTextColor(enabled: Boolean): Color { + return if (enabled) { + defaultSupportingTextColor + } else { + supportingTextDisabledColor + } + } + + /** + * Represents the color used for the container border of this radio button field. + * + * @param enabled whether the field is enabled + */ + @Composable + fun containerBorderColor(enabled: Boolean): Color { + return if (enabled) { + defaultContainerBorderColor + } else { + containerBorderDisabledColor + } + } + + /** + * Represents the color used for the text of this radio button field options. + * + * @param enabled whether the field is enabled + */ + @Composable + fun textColor(enabled: Boolean): Color { + return if (enabled) { + defaultTextColor + } else { + disabledTextColor + } + } +} From 18bed2a4174c3d93aa6126b011da534e5255241d Mon Sep 17 00:00:00 2001 From: Kaushik Meesala Date: Thu, 12 Oct 2023 15:57:22 -0700 Subject: [PATCH 04/11] refactor comboboxfieldstate into codedvaluefieldstate --- .../toolkit/featureforms/FeatureForm.kt | 5 +- .../featureforms/components/FormElements.kt | 6 +- .../CodedValueFieldState.kt} | 56 +++++++++---------- .../{combo => codedvalue}/ComboBoxField.kt | 11 +++- 4 files changed, 39 insertions(+), 39 deletions(-) rename toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/{combo/ComboBoxFieldState.kt => codedvalue/CodedValueFieldState.kt} (78%) rename toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/{combo => codedvalue}/ComboBoxField.kt (96%) diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/FeatureForm.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/FeatureForm.kt index 92caeaeb2..151ce417e 100644 --- a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/FeatureForm.kt +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/FeatureForm.kt @@ -37,7 +37,7 @@ import com.arcgismaps.mapping.featureforms.TextAreaFormInput import com.arcgismaps.mapping.featureforms.TextBoxFormInput import com.arcgismaps.toolkit.featureforms.components.FieldElement import com.arcgismaps.toolkit.featureforms.components.base.BaseFieldState -import com.arcgismaps.toolkit.featureforms.components.combo.rememberComboBoxFieldState +import com.arcgismaps.toolkit.featureforms.components.codedvalue.rememberCodedValueFieldState import com.arcgismaps.toolkit.featureforms.components.datetime.rememberDateTimeFieldState import com.arcgismaps.toolkit.featureforms.components.text.rememberFormTextFieldState import kotlinx.coroutines.CoroutineScope @@ -186,10 +186,9 @@ private fun rememberFieldStates( } is ComboBoxFormInput -> { - rememberComboBoxFieldState( + rememberCodedValueFieldState( field = fieldElement, form = form, - context = context, scope = scope ) } diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/FormElements.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/FormElements.kt index f4fb2fa67..1d7a38991 100644 --- a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/FormElements.kt +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/FormElements.kt @@ -11,8 +11,8 @@ import com.arcgismaps.mapping.featureforms.GroupFormElement import com.arcgismaps.mapping.featureforms.TextAreaFormInput import com.arcgismaps.mapping.featureforms.TextBoxFormInput import com.arcgismaps.toolkit.featureforms.components.base.BaseFieldState -import com.arcgismaps.toolkit.featureforms.components.combo.ComboBoxField -import com.arcgismaps.toolkit.featureforms.components.combo.ComboBoxFieldState +import com.arcgismaps.toolkit.featureforms.components.codedvalue.ComboBoxField +import com.arcgismaps.toolkit.featureforms.components.codedvalue.CodedValueFieldState import com.arcgismaps.toolkit.featureforms.components.datetime.DateTimeField import com.arcgismaps.toolkit.featureforms.components.datetime.DateTimeFieldState import com.arcgismaps.toolkit.featureforms.components.text.FormTextField @@ -32,7 +32,7 @@ internal fun FieldElement(field: FieldFormElement, state: BaseFieldState) { } is ComboBoxFormInput -> { - ComboBoxField(state = state as ComboBoxFieldState) + ComboBoxField(state = state as CodedValueFieldState) } else -> { /* TO-DO: add support for other input types */ diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/combo/ComboBoxFieldState.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/CodedValueFieldState.kt similarity index 78% rename from toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/combo/ComboBoxFieldState.kt rename to toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/CodedValueFieldState.kt index 6778a8431..2ac876805 100644 --- a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/combo/ComboBoxFieldState.kt +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/CodedValueFieldState.kt @@ -14,9 +14,8 @@ * limitations under the License. */ -package com.arcgismaps.toolkit.featureforms.components.combo +package com.arcgismaps.toolkit.featureforms.components.codedvalue -import android.content.Context import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import androidx.compose.runtime.saveable.Saver @@ -27,8 +26,6 @@ import com.arcgismaps.mapping.featureforms.ComboBoxFormInput import com.arcgismaps.mapping.featureforms.FeatureForm import com.arcgismaps.mapping.featureforms.FieldFormElement import com.arcgismaps.mapping.featureforms.FormInputNoValueOption -import com.arcgismaps.toolkit.featureforms.R -import com.arcgismaps.toolkit.featureforms.components.FieldElement import com.arcgismaps.toolkit.featureforms.components.base.BaseFieldState import com.arcgismaps.toolkit.featureforms.components.base.FieldProperties import com.arcgismaps.toolkit.featureforms.components.text.TextFieldProperties @@ -37,7 +34,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch -internal class ComboBoxFieldProperties( +internal open class CodedValueFieldProperties( label: String, placeholder: String, description: String, @@ -50,23 +47,21 @@ internal class ComboBoxFieldProperties( ) : FieldProperties(label, placeholder, description, value, required, editable) /** - * A class to handle the state of a [ComboBoxField]. Essential properties are inherited from the - * [BaseFieldState]. + * A class to handle the state of a [ComboBoxField]. Essential properties are inherited + * from the [BaseFieldState]. * - * @param properties the [ComboBoxFieldProperties] associated with this state. + * @param properties the [CodedValueFieldProperties] associated with this state. * @param initialValue optional initial value to set for this field. It is set to the value of * [TextFieldProperties.value] by default. * @param scope a [CoroutineScope] to start [StateFlow] collectors on. - * @param context a Context scoped to the lifetime of a call to the [FieldElement] composable function. * @param onEditValue a callback to invoke when the user edits result in a change of value. This - * is called on [ComboBoxFieldState.onValueChanged]. + * is called on [CodedValueFieldState.onValueChanged]. */ @Stable -internal class ComboBoxFieldState( - properties: ComboBoxFieldProperties, +internal open class CodedValueFieldState( + properties: CodedValueFieldProperties, initialValue: String = properties.value.value, scope: CoroutineScope, - context: Context, onEditValue: ((Any?) -> Unit) ) : BaseFieldState( properties = properties, @@ -90,19 +85,23 @@ internal class ComboBoxFieldState( */ val noValueLabel: String = properties.noValueLabel - override val placeholder = if (isRequired.value) { - context.getString(R.string.enter_value) - } else if (showNoValueOption == FormInputNoValueOption.Show) { - noValueLabel.ifEmpty { context.getString(R.string.no_value) } - } else "" +// override val placeholder = if (isRequired.value) { +// context.getString(R.string.enter_value) +// } else if (showNoValueOption == FormInputNoValueOption.Show) { +// noValueLabel.ifEmpty { context.getString(R.string.no_value) } +// } else "" companion object { + + /** + * The default saver for a [CodedValueFieldState] implemented for a [ComboBoxFormInput] type. + * Hence for [formElement] the [FieldFormElement.input] type must be a [ComboBoxFormInput]. + */ fun Saver( formElement: FieldFormElement, form: FeatureForm, - context: Context, scope: CoroutineScope - ): Saver = listSaver( + ): Saver = listSaver( save = { listOf( it.value.value @@ -110,8 +109,8 @@ internal class ComboBoxFieldState( }, restore = { list -> val input = formElement.input as ComboBoxFormInput - ComboBoxFieldState( - properties = ComboBoxFieldProperties( + CodedValueFieldState( + properties = CodedValueFieldProperties( label = formElement.label, placeholder = formElement.hint, description = formElement.description, @@ -123,7 +122,6 @@ internal class ComboBoxFieldState( noValueLabel = input.noValueLabel ), initialValue = list[0], - context = context, scope = scope, onEditValue = { newValue -> form.editValue(formElement, newValue) @@ -136,17 +134,16 @@ internal class ComboBoxFieldState( } @Composable -internal fun rememberComboBoxFieldState( +internal fun rememberCodedValueFieldState( field: FieldFormElement, form: FeatureForm, - context: Context, scope: CoroutineScope -): ComboBoxFieldState = rememberSaveable( - saver = ComboBoxFieldState.Saver(field, form, context, scope) +): CodedValueFieldState = rememberSaveable( + saver = CodedValueFieldState.Saver(field, form, scope) ) { val input = field.input as ComboBoxFormInput - ComboBoxFieldState( - properties = ComboBoxFieldProperties( + CodedValueFieldState( + properties = CodedValueFieldProperties( label = field.label, placeholder = field.hint, description = field.description, @@ -157,7 +154,6 @@ internal fun rememberComboBoxFieldState( showNoValueOption = input.noValueOption, noValueLabel = input.noValueLabel ), - context = context, scope = scope, onEditValue = { form.editValue(field, it) diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/combo/ComboBoxField.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/ComboBoxField.kt similarity index 96% rename from toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/combo/ComboBoxField.kt rename to toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/ComboBoxField.kt index 771fa7a9e..8436199e7 100644 --- a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/combo/ComboBoxField.kt +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/ComboBoxField.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.arcgismaps.toolkit.featureforms.components.combo +package com.arcgismaps.toolkit.featureforms.components.codedvalue import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource @@ -72,7 +72,7 @@ import com.arcgismaps.toolkit.featureforms.R import com.arcgismaps.toolkit.featureforms.components.base.BaseTextField @Composable -internal fun ComboBoxField(state: ComboBoxFieldState, modifier: Modifier = Modifier) { +internal fun ComboBoxField(state: CodedValueFieldState, modifier: Modifier = Modifier) { val value by state.value.collectAsState() val isEditable by state.isEditable.collectAsState() val isRequired by state.isRequired.collectAsState() @@ -87,6 +87,11 @@ internal fun ComboBoxField(state: ComboBoxFieldState, modifier: Modifier = Modif state.label } } + val placeholder = if (isRequired) { + stringResource(R.string.enter_value) + } else if (state.showNoValueOption == FormInputNoValueOption.Show) { + state.noValueLabel.ifEmpty { stringResource(R.string.no_value) } + } else "" BaseTextField( text = value, @@ -100,7 +105,7 @@ internal fun ComboBoxField(state: ComboBoxFieldState, modifier: Modifier = Modif readOnly = true, isEditable = isEditable, label = label, - placeholder = state.placeholder, + placeholder = placeholder, singleLine = true, trailingIcon = Icons.Outlined.List, supportingText = { From feff2ffd722112e792873e00cd5279d17d23017b Mon Sep 17 00:00:00 2001 From: Kaushik Meesala Date: Thu, 12 Oct 2023 16:11:27 -0700 Subject: [PATCH 05/11] Update CodedValueFieldState.kt --- .../components/codedvalue/CodedValueFieldState.kt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/CodedValueFieldState.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/CodedValueFieldState.kt index 2ac876805..2ec11d98a 100644 --- a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/CodedValueFieldState.kt +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/CodedValueFieldState.kt @@ -85,12 +85,6 @@ internal open class CodedValueFieldState( */ val noValueLabel: String = properties.noValueLabel -// override val placeholder = if (isRequired.value) { -// context.getString(R.string.enter_value) -// } else if (showNoValueOption == FormInputNoValueOption.Show) { -// noValueLabel.ifEmpty { context.getString(R.string.no_value) } -// } else "" - companion object { /** From 82077f112b163dad44a7c1e3e17792907032d6da Mon Sep 17 00:00:00 2001 From: Kaushik Meesala Date: Thu, 12 Oct 2023 16:18:15 -0700 Subject: [PATCH 06/11] refactored list of codedvalues to be list of strings --- .../components/codedvalue/CodedValueFieldState.kt | 8 ++++---- .../featureforms/components/codedvalue/ComboBoxField.kt | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/CodedValueFieldState.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/CodedValueFieldState.kt index 2ec11d98a..b6f3ccea6 100644 --- a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/CodedValueFieldState.kt +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/CodedValueFieldState.kt @@ -41,7 +41,7 @@ internal open class CodedValueFieldProperties( value: StateFlow, required: StateFlow, editable: StateFlow, - val codedValues: List, + val codedValues: List, val showNoValueOption: FormInputNoValueOption, val noValueLabel: String ) : FieldProperties(label, placeholder, description, value, required, editable) @@ -72,7 +72,7 @@ internal open class CodedValueFieldState( /** * The list of coded values associated with this field. */ - val codedValues: List = properties.codedValues + val codedValues: List = properties.codedValues /** * This property defines whether to display a special "no value" option if this field is @@ -111,7 +111,7 @@ internal open class CodedValueFieldState( value = formElement.value, editable = formElement.isEditable, required = formElement.isRequired, - codedValues = input.codedValues, + codedValues = input.codedValues.map { it.code.toString() }, showNoValueOption = input.noValueOption, noValueLabel = input.noValueLabel ), @@ -144,7 +144,7 @@ internal fun rememberCodedValueFieldState( value = field.value, editable = field.isEditable, required = field.isRequired, - codedValues = input.codedValues, + codedValues = input.codedValues.map { it.code.toString() }, showNoValueOption = input.noValueOption, noValueLabel = input.noValueLabel ), diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/ComboBoxField.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/ComboBoxField.kt index 8436199e7..e4bfcdb98 100644 --- a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/ComboBoxField.kt +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/ComboBoxField.kt @@ -128,7 +128,7 @@ internal fun ComboBoxField(state: CodedValueFieldState, modifier: Modifier = Mod if (showDialog) { ComboBoxDialog( initialValue = value, - values = state.codedValues.map { it.code.toString() }, + values = state.codedValues, label = state.label, description = state.description, isRequired = isRequired, From 981c9468c20dad0f72beb631889d91dda1ba26bb Mon Sep 17 00:00:00 2001 From: Kaushik Meesala Date: Thu, 12 Oct 2023 16:23:30 -0700 Subject: [PATCH 07/11] radiobuttonfieldstate subclasses codedvaluefieldstate --- .../toolkit/featureforms/FeatureForm.kt | 2 +- .../featureforms/components/FormElements.kt | 16 +++++-- .../{radio => codedvalue}/RadioButtonField.kt | 3 +- .../RadioButtonFieldDefaults.kt | 2 +- .../RadioButtonFieldState.kt | 42 ++++--------------- 5 files changed, 25 insertions(+), 40 deletions(-) rename toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/{radio => codedvalue}/RadioButtonField.kt (98%) rename toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/{radio => codedvalue}/RadioButtonFieldDefaults.kt (98%) rename toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/{radio => codedvalue}/RadioButtonFieldState.kt (73%) diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/FeatureForm.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/FeatureForm.kt index b14d5c280..cb054650d 100644 --- a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/FeatureForm.kt +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/FeatureForm.kt @@ -40,7 +40,7 @@ import com.arcgismaps.toolkit.featureforms.components.FieldElement import com.arcgismaps.toolkit.featureforms.components.base.BaseFieldState import com.arcgismaps.toolkit.featureforms.components.codedvalue.rememberCodedValueFieldState import com.arcgismaps.toolkit.featureforms.components.datetime.rememberDateTimeFieldState -import com.arcgismaps.toolkit.featureforms.components.radio.rememberRadioButtonFieldState +import com.arcgismaps.toolkit.featureforms.components.codedvalue.rememberRadioButtonFieldState import com.arcgismaps.toolkit.featureforms.components.text.rememberFormTextFieldState import kotlinx.coroutines.CoroutineScope import java.util.Objects diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/FormElements.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/FormElements.kt index 309102f14..4abe658b1 100644 --- a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/FormElements.kt +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/FormElements.kt @@ -7,6 +7,7 @@ import com.arcgismaps.mapping.featureforms.ComboBoxFormInput import com.arcgismaps.mapping.featureforms.DateTimePickerFormInput import com.arcgismaps.mapping.featureforms.FeatureForm import com.arcgismaps.mapping.featureforms.FieldFormElement +import com.arcgismaps.mapping.featureforms.FormInputNoValueOption import com.arcgismaps.mapping.featureforms.GroupFormElement import com.arcgismaps.mapping.featureforms.RadioButtonsFormInput import com.arcgismaps.mapping.featureforms.TextAreaFormInput @@ -16,8 +17,8 @@ import com.arcgismaps.toolkit.featureforms.components.codedvalue.ComboBoxField import com.arcgismaps.toolkit.featureforms.components.codedvalue.CodedValueFieldState import com.arcgismaps.toolkit.featureforms.components.datetime.DateTimeField import com.arcgismaps.toolkit.featureforms.components.datetime.DateTimeFieldState -import com.arcgismaps.toolkit.featureforms.components.radio.RadioButtonField -import com.arcgismaps.toolkit.featureforms.components.radio.RadioButtonFieldState +import com.arcgismaps.toolkit.featureforms.components.codedvalue.RadioButtonField +import com.arcgismaps.toolkit.featureforms.components.codedvalue.RadioButtonFieldState import com.arcgismaps.toolkit.featureforms.components.text.FormTextField import com.arcgismaps.toolkit.featureforms.components.text.FormTextFieldState @@ -39,7 +40,16 @@ internal fun FieldElement(field: FieldFormElement, state: BaseFieldState) { } is RadioButtonsFormInput -> { - RadioButtonField(state = state as RadioButtonFieldState) + val value by state.value.collectAsState() + val codedValues = (field.input as RadioButtonsFormInput).codedValues.map { + it.code.toString() + } + val fallback = (value !in codedValues) && (field.input as RadioButtonsFormInput).noValueOption == FormInputNoValueOption.Show + if (fallback) { + ComboBoxField(state = state as CodedValueFieldState) + } else { + RadioButtonField(state = state as RadioButtonFieldState) + } } else -> { /* TO-DO: add support for other input types */ diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonField.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/RadioButtonField.kt similarity index 98% rename from toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonField.kt rename to toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/RadioButtonField.kt index 2efdbd53e..f1ddedfd6 100644 --- a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonField.kt +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/RadioButtonField.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.arcgismaps.toolkit.featureforms.components.radio +package com.arcgismaps.toolkit.featureforms.components.codedvalue import androidx.compose.foundation.border import androidx.compose.foundation.layout.Arrangement @@ -36,6 +36,7 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.Role import androidx.compose.ui.tooling.preview.Preview diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonFieldDefaults.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/RadioButtonFieldDefaults.kt similarity index 98% rename from toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonFieldDefaults.kt rename to toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/RadioButtonFieldDefaults.kt index 5e35f18fd..9ee100ecc 100644 --- a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonFieldDefaults.kt +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/RadioButtonFieldDefaults.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.arcgismaps.toolkit.featureforms.components.radio +package com.arcgismaps.toolkit.featureforms.components.codedvalue import androidx.compose.material3.LocalContentColor import androidx.compose.material3.MaterialTheme diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonFieldState.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/RadioButtonFieldState.kt similarity index 73% rename from toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonFieldState.kt rename to toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/RadioButtonFieldState.kt index 0c973d0e5..1d64d9799 100644 --- a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/radio/RadioButtonFieldState.kt +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/RadioButtonFieldState.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.arcgismaps.toolkit.featureforms.components.radio +package com.arcgismaps.toolkit.featureforms.components.codedvalue import androidx.compose.runtime.Composable import androidx.compose.runtime.saveable.Saver @@ -22,50 +22,24 @@ import androidx.compose.runtime.saveable.listSaver import androidx.compose.runtime.saveable.rememberSaveable import com.arcgismaps.mapping.featureforms.FeatureForm import com.arcgismaps.mapping.featureforms.FieldFormElement -import com.arcgismaps.mapping.featureforms.FormInputNoValueOption import com.arcgismaps.mapping.featureforms.RadioButtonsFormInput -import com.arcgismaps.toolkit.featureforms.components.base.BaseFieldState -import com.arcgismaps.toolkit.featureforms.components.base.FieldProperties -import com.arcgismaps.toolkit.featureforms.components.combo.ComboBoxFieldState import com.arcgismaps.toolkit.featureforms.utils.editValue import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch -internal class RadioButtonFieldProperties( - label: String, - placeholder: String, - description: String, - value: StateFlow, - required: StateFlow, - editable: StateFlow, - val codedValues: List, - val showNoValueOption: FormInputNoValueOption, - val noValueLabel: String -) : FieldProperties(label, placeholder, description, value, required, editable) +internal typealias RadioButtonFieldProperties = CodedValueFieldProperties internal class RadioButtonFieldState( properties: RadioButtonFieldProperties, initialValue: String = properties.value.value, scope: CoroutineScope, onEditValue: ((Any?) -> Unit) -) : BaseFieldState(properties, initialValue, scope, onEditValue) { - - /** - * The list of coded values associated with this field. - */ - val codedValues: List = properties.codedValues - - /** - * This property defines whether to display a special "no value" option if this field is - * optional. - */ - val showNoValueOption: FormInputNoValueOption = properties.showNoValueOption - - /** - * The custom label to use if [showNoValueOption] is enabled. - */ - val noValueLabel: String = properties.noValueLabel +) : CodedValueFieldState( + properties = properties, + initialValue = initialValue, + scope = scope, + onEditValue = onEditValue +) { companion object { fun Saver( From 25d197d0ae46e47692d790758268cb74cfefb041 Mon Sep 17 00:00:00 2001 From: Kaushik Meesala Date: Fri, 13 Oct 2023 15:14:09 -0700 Subject: [PATCH 08/11] updated merge conflicts --- .../components/codedvalue/CodedValueFieldState.kt | 8 ++++---- .../featureforms/components/codedvalue/ComboBoxField.kt | 3 --- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/CodedValueFieldState.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/CodedValueFieldState.kt index b6f3ccea6..2ec11d98a 100644 --- a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/CodedValueFieldState.kt +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/CodedValueFieldState.kt @@ -41,7 +41,7 @@ internal open class CodedValueFieldProperties( value: StateFlow, required: StateFlow, editable: StateFlow, - val codedValues: List, + val codedValues: List, val showNoValueOption: FormInputNoValueOption, val noValueLabel: String ) : FieldProperties(label, placeholder, description, value, required, editable) @@ -72,7 +72,7 @@ internal open class CodedValueFieldState( /** * The list of coded values associated with this field. */ - val codedValues: List = properties.codedValues + val codedValues: List = properties.codedValues /** * This property defines whether to display a special "no value" option if this field is @@ -111,7 +111,7 @@ internal open class CodedValueFieldState( value = formElement.value, editable = formElement.isEditable, required = formElement.isRequired, - codedValues = input.codedValues.map { it.code.toString() }, + codedValues = input.codedValues, showNoValueOption = input.noValueOption, noValueLabel = input.noValueLabel ), @@ -144,7 +144,7 @@ internal fun rememberCodedValueFieldState( value = field.value, editable = field.isEditable, required = field.isRequired, - codedValues = input.codedValues.map { it.code.toString() }, + codedValues = input.codedValues, showNoValueOption = input.noValueOption, noValueLabel = input.noValueLabel ), diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/ComboBoxField.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/ComboBoxField.kt index ee5c80d09..b116c3a3b 100644 --- a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/ComboBoxField.kt +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/ComboBoxField.kt @@ -27,7 +27,6 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.icons.Icons @@ -71,9 +70,7 @@ import androidx.compose.ui.window.DialogProperties import com.arcgismaps.mapping.featureforms.FormInputNoValueOption import com.arcgismaps.toolkit.featureforms.R import com.arcgismaps.toolkit.featureforms.components.base.BaseTextField -import com.arcgismaps.toolkit.featureforms.utils.editValue import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.launch @Composable internal fun ComboBoxField(state: CodedValueFieldState, modifier: Modifier = Modifier) { From 071f5541091927b4196e1a9db9a903405eaee7d4 Mon Sep 17 00:00:00 2001 From: Kaushik Meesala Date: Fri, 13 Oct 2023 15:43:30 -0700 Subject: [PATCH 09/11] fixed fallback behavior --- .../featureforms/components/FormElements.kt | 9 +-- .../components/codedvalue/RadioButtonField.kt | 60 ++++++++++--------- .../codedvalue/RadioButtonFieldState.kt | 22 ++++++- 3 files changed, 53 insertions(+), 38 deletions(-) diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/FormElements.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/FormElements.kt index 4abe658b1..bfe05f758 100644 --- a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/FormElements.kt +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/FormElements.kt @@ -40,15 +40,10 @@ internal fun FieldElement(field: FieldFormElement, state: BaseFieldState) { } is RadioButtonsFormInput -> { - val value by state.value.collectAsState() - val codedValues = (field.input as RadioButtonsFormInput).codedValues.map { - it.code.toString() - } - val fallback = (value !in codedValues) && (field.input as RadioButtonsFormInput).noValueOption == FormInputNoValueOption.Show - if (fallback) { + if ((state as RadioButtonFieldState).shouldFallback()) { ComboBoxField(state = state as CodedValueFieldState) } else { - RadioButtonField(state = state as RadioButtonFieldState) + RadioButtonField(state = state) } } diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/RadioButtonField.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/RadioButtonField.kt index f1ddedfd6..10f33e8de 100644 --- a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/RadioButtonField.kt +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/RadioButtonField.kt @@ -41,6 +41,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.Role import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import com.arcgismaps.data.CodedValue import com.arcgismaps.mapping.featureforms.FormInputNoValueOption import com.arcgismaps.toolkit.featureforms.R import kotlinx.coroutines.CoroutineScope @@ -59,9 +60,9 @@ internal fun RadioButtonField( val noValueLabel = state.noValueLabel.ifEmpty { stringResource(R.string.no_value) } val options = if (!required) { if (state.showNoValueOption == FormInputNoValueOption.Show) { - listOf(noValueLabel) + state.codedValues - } else state.codedValues - } else state.codedValues + mapOf("" to noValueLabel) + state.codedValues.associateBy({ it.code }, { it.name }) + } else state.codedValues.associateBy({ it.code }, { it.name }) + } else state.codedValues.associateBy({ it.code }, { it.name }) val label = remember(required) { if (required) { @@ -95,12 +96,13 @@ internal fun RadioButtonField( CompositionLocalProvider( LocalContentColor provides colors.textColor(enabled = editable) ) { - options.forEach { code -> + options.forEach { (code, name) -> RadioButtonRow( - value = code, - selected = (code == value) || (code == noValueLabel && value.isEmpty()), + value = name, + selected = (code?.toString() + ?: "") == value || (name == noValueLabel && value.isEmpty()), enabled = editable, - onClick = { state.onValueChanged(code) } + onClick = { state.onValueChanged(code?.toString() ?: "") } ) } } @@ -150,25 +152,25 @@ private fun RadioButtonRow( } -@Preview(showBackground = true, backgroundColor = 0xFFFFFFFF, showSystemUi = true) -@Composable -private fun RadioButtonFieldPreview() { - MaterialTheme { - val state = RadioButtonFieldState( - properties = RadioButtonFieldProperties( - label = "A list of values", - placeholder = "Placeholder", - description = "Description", - value = MutableStateFlow(""), - editable = MutableStateFlow(true), - required = MutableStateFlow(false), - codedValues = listOf("One", "Two", "Three"), - showNoValueOption = FormInputNoValueOption.Show, - noValueLabel = "No Value" - ), - scope = CoroutineScope(Dispatchers.IO), - onEditValue = {} - ) - RadioButtonField(state = state) - } -} +//@Preview(showBackground = true, backgroundColor = 0xFFFFFFFF, showSystemUi = true) +//@Composable +//private fun RadioButtonFieldPreview() { +// MaterialTheme { +// val state = RadioButtonFieldState( +// properties = RadioButtonFieldProperties( +// label = "A list of values", +// placeholder = "Placeholder", +// description = "Description", +// value = MutableStateFlow(""), +// editable = MutableStateFlow(true), +// required = MutableStateFlow(false), +// codedValues = listOf("One", "Two", "Three"), +// showNoValueOption = FormInputNoValueOption.Show, +// noValueLabel = "No Value" +// ), +// scope = CoroutineScope(Dispatchers.IO), +// onEditValue = {} +// ) +// RadioButtonField(state = state) +// } +//} diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/RadioButtonFieldState.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/RadioButtonFieldState.kt index 1d64d9799..d13738c0c 100644 --- a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/RadioButtonFieldState.kt +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/RadioButtonFieldState.kt @@ -41,7 +41,25 @@ internal class RadioButtonFieldState( onEditValue = onEditValue ) { + /** + * Returns true if the current value of [value] is not in the [codedValues]. This should + * trigger a fallback to a ComboBox. If the [value] is empty then this returns false. + */ + fun shouldFallback(): Boolean { + return if (value.value.isEmpty()) { + false + } else { + !codedValues.any { + it.code.toString() == value.value + } + } + } + companion object { + + /** + * Default saver for the [RadioButtonFieldState]. + */ fun Saver( formElement: FieldFormElement, form: FeatureForm, @@ -62,7 +80,7 @@ internal class RadioButtonFieldState( value = formElement.value, editable = formElement.isEditable, required = formElement.isRequired, - codedValues = input.codedValues.map { it.code.toString() }, + codedValues = input.codedValues, showNoValueOption = input.noValueOption, noValueLabel = input.noValueLabel ), @@ -95,7 +113,7 @@ internal fun rememberRadioButtonFieldState( value = field.value, editable = field.isEditable, required = field.isRequired, - codedValues = input.codedValues.map { it.code.toString() }, + codedValues = input.codedValues, showNoValueOption = input.noValueOption, noValueLabel = input.noValueLabel ), From ad134e6b68cbba336ff757d3e00c3564eeb0ae3b Mon Sep 17 00:00:00 2001 From: Kaushik Meesala Date: Fri, 13 Oct 2023 17:20:13 -0700 Subject: [PATCH 10/11] extracted params from RadioButtonField to support preview --- .../components/codedvalue/RadioButtonField.kt | 107 ++++++++++-------- .../codedvalue/RadioButtonFieldDefaults.kt | 12 +- 2 files changed, 68 insertions(+), 51 deletions(-) diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/RadioButtonField.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/RadioButtonField.kt index 10f33e8de..a98991b9a 100644 --- a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/RadioButtonField.kt +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/RadioButtonField.kt @@ -33,20 +33,14 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue -import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.Role import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.arcgismaps.data.CodedValue import com.arcgismaps.mapping.featureforms.FormInputNoValueOption import com.arcgismaps.toolkit.featureforms.R -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.MutableStateFlow @Composable internal fun RadioButtonField( @@ -58,19 +52,41 @@ internal fun RadioButtonField( val editable by state.isEditable.collectAsState() val required by state.isRequired.collectAsState() val noValueLabel = state.noValueLabel.ifEmpty { stringResource(R.string.no_value) } - val options = if (!required) { - if (state.showNoValueOption == FormInputNoValueOption.Show) { - mapOf("" to noValueLabel) + state.codedValues.associateBy({ it.code }, { it.name }) - } else state.codedValues.associateBy({ it.code }, { it.name }) - } else state.codedValues.associateBy({ it.code }, { it.name }) - - val label = remember(required) { - if (required) { - "${state.label} *" - } else { - state.label - } + RadioButtonField( + label = state.label, + description = state.description, + value = value, + editable = editable, + required = required, + codedValues = state.codedValues.associateBy({ it.code }, { it.name }), + showNoValueOption = state.showNoValueOption, + noValueLabel = noValueLabel, + modifier = modifier, + colors = colors + ) { + state.onValueChanged(it) } +} + +@Composable +private fun RadioButtonField( + label: String, + description: String, + value: String, + editable: Boolean, + required: Boolean, + codedValues: Map, + showNoValueOption: FormInputNoValueOption, + noValueLabel: String, + modifier: Modifier = Modifier, + colors: RadioButtonFieldColors = RadioButtonFieldDefaults.colors(), + onValueChanged: (String) -> Unit = {} +) { + val options = if (!required) { + if (showNoValueOption == FormInputNoValueOption.Show) { + mapOf("" to noValueLabel) + codedValues + } else codedValues + } else codedValues Column( modifier = modifier @@ -80,7 +96,11 @@ internal fun RadioButtonField( horizontalAlignment = Alignment.Start ) { Text( - text = label, + text = if (required) { + "$label *" + } else { + label + }, style = MaterialTheme.typography.bodyMedium, color = colors.labelColor(enabled = editable) ) @@ -102,14 +122,14 @@ internal fun RadioButtonField( selected = (code?.toString() ?: "") == value || (name == noValueLabel && value.isEmpty()), enabled = editable, - onClick = { state.onValueChanged(code?.toString() ?: "") } + onClick = { onValueChanged(code?.toString() ?: "") } ) } } } - if (state.description.isNotEmpty()) { + if (description.isNotEmpty()) { Text( - text = state.description, + text = description, style = MaterialTheme.typography.bodySmall, color = colors.supportingTextColor(enabled = editable) ) @@ -151,26 +171,23 @@ private fun RadioButtonRow( } } - -//@Preview(showBackground = true, backgroundColor = 0xFFFFFFFF, showSystemUi = true) -//@Composable -//private fun RadioButtonFieldPreview() { -// MaterialTheme { -// val state = RadioButtonFieldState( -// properties = RadioButtonFieldProperties( -// label = "A list of values", -// placeholder = "Placeholder", -// description = "Description", -// value = MutableStateFlow(""), -// editable = MutableStateFlow(true), -// required = MutableStateFlow(false), -// codedValues = listOf("One", "Two", "Three"), -// showNoValueOption = FormInputNoValueOption.Show, -// noValueLabel = "No Value" -// ), -// scope = CoroutineScope(Dispatchers.IO), -// onEditValue = {} -// ) -// RadioButtonField(state = state) -// } -//} +@Preview(showBackground = true, backgroundColor = 0xFFFFFFFF, showSystemUi = true) +@Composable +private fun RadioButtonFieldPreview() { + MaterialTheme { + RadioButtonField( + label = "A list of values", + description = "Description", + value = "", + editable = true, + required = true, + codedValues = mapOf( + "One" to "One", + "Two" to "Two", + "Three" to "Three" + ), + showNoValueOption = FormInputNoValueOption.Show, + noValueLabel = "No Value", + ) { } + } +} diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/RadioButtonFieldDefaults.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/RadioButtonFieldDefaults.kt index 9ee100ecc..26c9ed1ae 100644 --- a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/RadioButtonFieldDefaults.kt +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/codedvalue/RadioButtonFieldDefaults.kt @@ -33,12 +33,12 @@ internal object RadioButtonFieldDefaults { alpha = textDisabledAlpha ), defaultSupportingTextColor = MaterialTheme.colorScheme.onSurfaceVariant, - supportingTextDisabledColor = MaterialTheme.colorScheme.onSurfaceVariant.copy( + disabledSupportingTextColor = MaterialTheme.colorScheme.onSurfaceVariant.copy( alpha = textDisabledAlpha ), errorColor = MaterialTheme.colorScheme.error, defaultContainerBorderColor = MaterialTheme.colorScheme.outline, - containerBorderDisabledColor = MaterialTheme.colorScheme.outline.copy( + disabledContainerBorderColor = MaterialTheme.colorScheme.outline.copy( alpha = containerDisabledAlpha ), defaultTextColor = LocalContentColor.current, @@ -50,10 +50,10 @@ internal data class RadioButtonFieldColors( val defaultLabelColor: Color, val disabledLabelColor: Color, val defaultSupportingTextColor: Color, - val supportingTextDisabledColor: Color, + val disabledSupportingTextColor: Color, val errorColor: Color, val defaultContainerBorderColor: Color, - val containerBorderDisabledColor: Color, + val disabledContainerBorderColor: Color, val defaultTextColor: Color, val disabledTextColor: Color ) { @@ -81,7 +81,7 @@ internal data class RadioButtonFieldColors( return if (enabled) { defaultSupportingTextColor } else { - supportingTextDisabledColor + disabledSupportingTextColor } } @@ -95,7 +95,7 @@ internal data class RadioButtonFieldColors( return if (enabled) { defaultContainerBorderColor } else { - containerBorderDisabledColor + disabledContainerBorderColor } } From a00cfe7798c01bbf817b93fce10ff80186ee1dfd Mon Sep 17 00:00:00 2001 From: Kaushik Meesala Date: Mon, 16 Oct 2023 14:40:13 -0700 Subject: [PATCH 11/11] PR feedback --- .../arcgismaps/toolkit/featureforms/components/FormElements.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/FormElements.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/FormElements.kt index bfe05f758..cd0f41507 100644 --- a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/FormElements.kt +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/components/FormElements.kt @@ -41,7 +41,7 @@ internal fun FieldElement(field: FieldFormElement, state: BaseFieldState) { is RadioButtonsFormInput -> { if ((state as RadioButtonFieldState).shouldFallback()) { - ComboBoxField(state = state as CodedValueFieldState) + ComboBoxField(state = state) } else { RadioButtonField(state = state) }