-
Notifications
You must be signed in to change notification settings - Fork 127
[Multiple Choice Task] Fix UI bugs in multiple choice selectors #2899
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
dd84cf5
0520536
0ac386d
06c0569
6776f5a
f3163ca
0b2efd0
459bee0
256a339
b256930
b898bcb
86213bf
15dd5cc
06ca789
528e31d
90fafc1
4044daf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
/* | ||
* Copyright 2024 Google LLC | ||
* | ||
* 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 | ||
* | ||
* https://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.google.android.ground.ui.datacollection.tasks.multiplechoice | ||
|
||
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.text.ClickableText | ||
import androidx.compose.material3.Checkbox | ||
import androidx.compose.material3.HorizontalDivider | ||
import androidx.compose.material3.MaterialTheme | ||
import androidx.compose.material3.RadioButton | ||
import androidx.compose.material3.TextField | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.ui.Alignment | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.platform.testTag | ||
import androidx.compose.ui.res.stringResource | ||
import androidx.compose.ui.text.AnnotatedString | ||
import androidx.compose.ui.tooling.preview.Preview | ||
import androidx.compose.ui.unit.dp | ||
import com.google.android.ground.ExcludeFromJacocoGeneratedReport | ||
import com.google.android.ground.R | ||
import com.google.android.ground.model.task.MultipleChoice | ||
import com.google.android.ground.model.task.Option | ||
import com.google.android.ground.ui.theme.AppTheme | ||
|
||
const val MULTIPLE_CHOICE_ITEM_TEST_TAG = "multiple choice item test tag" | ||
const val OTHER_INPUT_TEXT_TEST_TAG = "other input test tag" | ||
const val SELECT_MULTIPLE_RADIO_TEST_TAG = "select multiple radio test tag" | ||
|
||
/** | ||
* A composable function that displays a single item in a multiple-choice list. | ||
* | ||
* This composable provides a visually consistent and interactive way to present an option within a | ||
* list of choices where the user can select one or more items. It typically includes a text label | ||
* and a selectable indicator (e.g., a checkbox). | ||
*/ | ||
@Composable | ||
fun MultipleChoiceItemView( | ||
item: MultipleChoiceItem, | ||
modifier: Modifier = Modifier, | ||
isLastIndex: Boolean = false, | ||
toggleItem: (item: MultipleChoiceItem) -> Unit = {}, | ||
otherValueChanged: (text: String) -> Unit = {}, | ||
) { | ||
Column(modifier = Modifier.testTag(MULTIPLE_CHOICE_ITEM_TEST_TAG)) { | ||
Row(modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) { | ||
when (item.cardinality) { | ||
MultipleChoice.Cardinality.SELECT_ONE -> { | ||
RadioButton( | ||
modifier = Modifier.testTag(SELECT_MULTIPLE_RADIO_TEST_TAG), | ||
selected = item.isSelected, | ||
onClick = { toggleItem(item) }, | ||
anandwana001 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
) | ||
} | ||
|
||
MultipleChoice.Cardinality.SELECT_MULTIPLE -> { | ||
Checkbox(checked = item.isSelected, onCheckedChange = { toggleItem(item) }) | ||
} | ||
} | ||
|
||
ClickableText( | ||
text = item.toTextLabel(), | ||
modifier = modifier, | ||
style = MaterialTheme.typography.bodyLarge, | ||
onClick = { toggleItem(item) }, | ||
) | ||
} | ||
|
||
if (item.isOtherOption) { | ||
Row(modifier = modifier.padding(horizontal = 48.dp)) { | ||
TextField( | ||
value = item.otherText, | ||
textStyle = MaterialTheme.typography.bodyLarge, | ||
onValueChange = { otherValueChanged(it) }, | ||
modifier = Modifier.testTag(OTHER_INPUT_TEXT_TEST_TAG), | ||
) | ||
} | ||
} | ||
|
||
if (!isLastIndex) { | ||
HorizontalDivider(color = MaterialTheme.colorScheme.outlineVariant) | ||
} | ||
} | ||
} | ||
|
||
@Composable | ||
private fun MultipleChoiceItem.toTextLabel() = | ||
AnnotatedString(if (isOtherOption) stringResource(id = R.string.other) else option.label) | ||
|
||
@Preview(backgroundColor = 0xFFFFFFFF, showBackground = true) | ||
@Composable | ||
@ExcludeFromJacocoGeneratedReport | ||
fun SelectOneListItemPreview() { | ||
AppTheme { | ||
Check warning on line 110 in ground/src/main/java/com/google/android/ground/ui/datacollection/tasks/multiplechoice/MultipleChoiceItemView.kt
|
||
MultipleChoiceItemView( | ||
item = | ||
MultipleChoiceItem( | ||
Option(id = "id", code = "code", label = "Option 1"), | ||
cardinality = MultipleChoice.Cardinality.SELECT_ONE, | ||
isSelected = false, | ||
Check warning on line 116 in ground/src/main/java/com/google/android/ground/ui/datacollection/tasks/multiplechoice/MultipleChoiceItemView.kt
|
||
) | ||
) | ||
} | ||
Check warning on line 119 in ground/src/main/java/com/google/android/ground/ui/datacollection/tasks/multiplechoice/MultipleChoiceItemView.kt
|
||
} | ||
|
||
@Preview(backgroundColor = 0xFFFFFFFF, showBackground = true) | ||
@Composable | ||
@ExcludeFromJacocoGeneratedReport | ||
fun SelectMultipleListItemPreview() { | ||
AppTheme { | ||
Check warning on line 126 in ground/src/main/java/com/google/android/ground/ui/datacollection/tasks/multiplechoice/MultipleChoiceItemView.kt
|
||
MultipleChoiceItemView( | ||
item = | ||
MultipleChoiceItem( | ||
Option(id = "id", code = "code", label = "Option 2"), | ||
cardinality = MultipleChoice.Cardinality.SELECT_MULTIPLE, | ||
isSelected = false, | ||
Check warning on line 132 in ground/src/main/java/com/google/android/ground/ui/datacollection/tasks/multiplechoice/MultipleChoiceItemView.kt
|
||
) | ||
) | ||
} | ||
Check warning on line 135 in ground/src/main/java/com/google/android/ground/ui/datacollection/tasks/multiplechoice/MultipleChoiceItemView.kt
|
||
} | ||
|
||
@Preview(backgroundColor = 0xFFFFFFFF, showBackground = true) | ||
@Composable | ||
@ExcludeFromJacocoGeneratedReport | ||
fun SelectOneOtherListItemPreview() { | ||
AppTheme { | ||
Check warning on line 142 in ground/src/main/java/com/google/android/ground/ui/datacollection/tasks/multiplechoice/MultipleChoiceItemView.kt
|
||
MultipleChoiceItemView( | ||
item = | ||
MultipleChoiceItem( | ||
Option(id = "id", code = "code", label = "Option 3"), | ||
cardinality = MultipleChoice.Cardinality.SELECT_ONE, | ||
isSelected = true, | ||
isOtherOption = true, | ||
otherText = "Other text", | ||
Check warning on line 150 in ground/src/main/java/com/google/android/ground/ui/datacollection/tasks/multiplechoice/MultipleChoiceItemView.kt
|
||
) | ||
) | ||
} | ||
Check warning on line 153 in ground/src/main/java/com/google/android/ground/ui/datacollection/tasks/multiplechoice/MultipleChoiceItemView.kt
|
||
} | ||
|
||
@Preview(backgroundColor = 0xFFFFFFFF, showBackground = true) | ||
@Composable | ||
@ExcludeFromJacocoGeneratedReport | ||
fun SelectMultipleOtherListItemPreview() { | ||
AppTheme { | ||
Check warning on line 160 in ground/src/main/java/com/google/android/ground/ui/datacollection/tasks/multiplechoice/MultipleChoiceItemView.kt
|
||
MultipleChoiceItemView( | ||
item = | ||
MultipleChoiceItem( | ||
Option(id = "id", code = "code", label = "Option 4"), | ||
cardinality = MultipleChoice.Cardinality.SELECT_MULTIPLE, | ||
isSelected = true, | ||
isOtherOption = true, | ||
otherText = "Other text", | ||
Check warning on line 168 in ground/src/main/java/com/google/android/ground/ui/datacollection/tasks/multiplechoice/MultipleChoiceItemView.kt
|
||
) | ||
) | ||
} | ||
Check warning on line 171 in ground/src/main/java/com/google/android/ground/ui/datacollection/tasks/multiplechoice/MultipleChoiceItemView.kt
|
||
} |
Uh oh!
There was an error while loading. Please reload this page.