Bug: Update BitwardenDatePickerDialog to match current designs (#6943)

This commit is contained in:
David Perez
2026-05-19 11:41:21 -05:00
committed by GitHub
parent 83a9d35e32
commit 6ccb9d9f3e
2 changed files with 87 additions and 48 deletions

View File

@@ -2939,7 +2939,7 @@ class VaultAddEditScreenTest : BitwardenComposeTest() {
.performClick()
composeTestRule
.onNodeWithTag(testTag = "ClearButton")
.onNodeWithText(text = "Clear")
.performClick()
verify {
@@ -2976,7 +2976,7 @@ class VaultAddEditScreenTest : BitwardenComposeTest() {
.performClick()
composeTestRule
.onNodeWithTag(testTag = "ClearButton")
.onNodeWithText(text = "Clear")
.performClick()
verify {
@@ -3014,7 +3014,7 @@ class VaultAddEditScreenTest : BitwardenComposeTest() {
.performClick()
composeTestRule
.onNodeWithTag(testTag = "ClearButton")
.onNodeWithText(text = "Clear")
.performClick()
verify {
@@ -3218,7 +3218,7 @@ class VaultAddEditScreenTest : BitwardenComposeTest() {
.performClick()
composeTestRule
.onNodeWithTag(testTag = "ClearButton")
.onNodeWithText(text = "Clear")
.performClick()
verify {
@@ -3256,7 +3256,7 @@ class VaultAddEditScreenTest : BitwardenComposeTest() {
.performClick()
composeTestRule
.onNodeWithTag(testTag = "ClearButton")
.onNodeWithText(text = "Clear")
.performClick()
verify {
@@ -3294,7 +3294,7 @@ class VaultAddEditScreenTest : BitwardenComposeTest() {
.performClick()
composeTestRule
.onNodeWithTag(testTag = "ClearButton")
.onNodeWithText(text = "Clear")
.performClick()
verify {

View File

@@ -1,8 +1,22 @@
package com.bitwarden.ui.platform.components.dialog
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredWidth
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.BasicAlertDialog
import androidx.compose.material3.DatePicker
import androidx.compose.material3.DatePickerColors
import androidx.compose.material3.DatePickerDialog
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Surface
import androidx.compose.material3.rememberDatePickerState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
@@ -12,6 +26,7 @@ import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTag
import androidx.compose.ui.semantics.testTagsAsResourceId
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.bitwarden.ui.platform.components.button.BitwardenTextButton
import com.bitwarden.ui.platform.components.field.color.bitwardenTextFieldColors
import com.bitwarden.ui.platform.resource.BitwardenString
@@ -27,6 +42,8 @@ import java.time.ZoneOffset
* @param onDateSelect The callback invoked with the selected [LocalDate] when the user confirms.
* @param onDismissRequest The callback invoked when the dialog is dismissed.
*/
@Suppress("LongMethod")
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun BitwardenDatePickerDialog(
initialDate: LocalDate?,
@@ -39,49 +56,71 @@ fun BitwardenDatePickerDialog(
?.toInstant()
?.toEpochMilli(),
)
DatePickerDialog(
BasicAlertDialog(
onDismissRequest = onDismissRequest,
confirmButton = {
BitwardenTextButton(
label = stringResource(id = BitwardenString.okay),
onClick = {
datePickerState
.selectedDateMillis
?.let { millis ->
Instant
.ofEpochMilli(millis)
.atZone(ZoneOffset.UTC)
.toLocalDate()
}
.let(onDateSelect)
},
modifier = Modifier.testTag(tag = "AcceptAlertButton"),
)
},
dismissButton = {
BitwardenTextButton(
label = stringResource(id = BitwardenString.clear),
onClick = { onDateSelect(null) },
contentColor = BitwardenTheme.colorScheme.status.error,
modifier = Modifier.testTag(tag = "ClearButton"),
)
BitwardenTextButton(
label = stringResource(id = BitwardenString.cancel),
onClick = onDismissRequest,
modifier = Modifier.testTag(tag = "DismissAlertButton"),
)
},
shape = BitwardenTheme.shapes.dialog,
colors = bitwardenDatePickerColors(),
modifier = Modifier.semantics {
testTagsAsResourceId = true
testTag = "DatePickerDialog"
},
modifier = Modifier
.semantics {
testTagsAsResourceId = true
testTag = "DatePickerDialog"
}
.wrapContentHeight(),
) {
DatePicker(
state = datePickerState,
colors = bitwardenDatePickerColors(),
)
val colors = bitwardenDatePickerColors()
Surface(
modifier = Modifier
// The Date picker has specific requirements in order to look correct.
// It does not follow the normal dialog size rules.
.requiredWidth(width = 360.dp)
.heightIn(max = 568.0.dp),
shape = BitwardenTheme.shapes.dialog,
color = colors.containerColor,
) {
Column {
// Wrap the content in a Box with a weight of 1f to ensure that any buttons
// are not pushed out of view when running on small screens. Fill is false to
// support collapsing the dialog's height when switching to input mode.
Box(modifier = Modifier.weight(weight = 1f, fill = false)) {
DatePicker(
modifier = Modifier.verticalScroll(state = rememberScrollState()),
state = datePickerState,
colors = colors,
)
}
Row(modifier = Modifier.padding(bottom = 8.dp, start = 12.dp)) {
BitwardenTextButton(
label = stringResource(id = BitwardenString.clear),
onClick = { onDateSelect(null) },
modifier = Modifier.testTag(tag = "ClearAlertButton"),
)
Spacer(modifier = Modifier.weight(weight = 1f))
FlowRow(
horizontalArrangement = Arrangement.End,
modifier = Modifier.padding(horizontal = 8.dp),
) {
BitwardenTextButton(
label = stringResource(id = BitwardenString.cancel),
onClick = onDismissRequest,
modifier = Modifier.testTag(tag = "DismissAlertButton"),
)
BitwardenTextButton(
label = stringResource(id = BitwardenString.okay),
onClick = {
datePickerState
.selectedDateMillis
?.let { millis ->
Instant
.ofEpochMilli(millis)
.atZone(ZoneOffset.UTC)
.toLocalDate()
}
.let(onDateSelect)
},
modifier = Modifier.testTag(tag = "AcceptAlertButton"),
)
}
}
}
}
}
}