Skip to content

Commit

Permalink
Add further test cases for responsive dialogs (#2010)
Browse files Browse the repository at this point in the history
* Add further test cases for responsive dialogs, update AlertDialog variations to handle more cases.

---------

Co-authored-by: stevebower <[email protected]>
Co-authored-by: BowerSteve <[email protected]>
  • Loading branch information
3 people authored Jan 26, 2024
1 parent 9661276 commit a060669
Show file tree
Hide file tree
Showing 50 changed files with 421 additions and 15 deletions.
6 changes: 4 additions & 2 deletions compose-material/api/current.api
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
package com.google.android.horologist.compose.material {

public final class AlertDialogKt {
method @androidx.compose.runtime.Composable @com.google.android.horologist.annotations.ExperimentalHorologistApi public static void AlertContent(String message, kotlin.jvm.functions.Function0<kotlin.Unit>? onCancelButtonClick, kotlin.jvm.functions.Function0<kotlin.Unit>? onOKButtonClick, optional String? title, optional String okButtonContentDescription, optional String cancelButtonContentDescription, optional com.google.android.horologist.compose.layout.ScalingLazyColumnState columnState, optional boolean showPositionIndicator);
method @androidx.compose.runtime.Composable @com.google.android.horologist.annotations.ExperimentalHorologistApi public static void AlertDialog(String message, kotlin.jvm.functions.Function0<kotlin.Unit> onCancelButtonClick, kotlin.jvm.functions.Function0<kotlin.Unit> onOKButtonClick, boolean showDialog, optional androidx.compose.ui.Modifier modifier, optional String? title, optional String okButtonContentDescription, optional String cancelButtonContentDescription, optional com.google.android.horologist.compose.layout.ScalingLazyColumnState columnState);
method @androidx.compose.runtime.Composable @com.google.android.horologist.annotations.ExperimentalHorologistApi public static void AlertContent(kotlin.jvm.functions.Function0<kotlin.Unit>? onCancelButtonClick, kotlin.jvm.functions.Function0<kotlin.Unit>? onOKButtonClick, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional String? title, optional String? message, optional String okButtonContentDescription, optional String cancelButtonContentDescription, optional com.google.android.horologist.compose.layout.ScalingLazyColumnState columnState, optional boolean showPositionIndicator);
method @androidx.compose.runtime.Composable @com.google.android.horologist.annotations.ExperimentalHorologistApi public static void AlertDialog(kotlin.jvm.functions.Function0<kotlin.Unit> onCancelButtonClick, kotlin.jvm.functions.Function0<kotlin.Unit> onOKButtonClick, boolean showDialog, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional String? title, optional String? message, optional String okButtonContentDescription, optional String cancelButtonContentDescription, optional com.google.android.horologist.compose.layout.ScalingLazyColumnState columnState);
}

public final class ButtonKt {
Expand Down Expand Up @@ -59,7 +59,9 @@ package com.google.android.horologist.compose.material {
}

public final class ConfirmationKt {
method @androidx.compose.runtime.Composable @com.google.android.horologist.annotations.ExperimentalHorologistApi public static void Confirmation(boolean showDialog, kotlin.jvm.functions.Function0<kotlin.Unit> onTimeout, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional String? title, optional long durationMillis, optional com.google.android.horologist.compose.layout.ScalingLazyColumnState columnState);
method @androidx.compose.runtime.Composable @com.google.android.horologist.annotations.ExperimentalHorologistApi public static void Confirmation(kotlin.jvm.functions.Function0<kotlin.Unit> onTimeout, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? icon, optional androidx.wear.compose.foundation.lazy.ScalingLazyListState scrollState, optional long durationMillis, optional long backgroundColor, optional long contentColor, optional long iconColor, optional androidx.compose.foundation.layout.Arrangement.Vertical verticalArrangement, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
method @androidx.compose.runtime.Composable @com.google.android.horologist.annotations.ExperimentalHorologistApi public static void ConfirmationContent(optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional String? title, optional com.google.android.horologist.compose.layout.ScalingLazyColumnState columnState, optional boolean showPositionIndicator);
}

public final class IconKt {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.wear.compose.material.MaterialTheme
import androidx.wear.compose.material.Text
import androidx.wear.compose.material.dialog.Dialog
Expand All @@ -37,12 +38,13 @@ import com.google.android.horologist.compose.layout.rememberColumnState
@ExperimentalHorologistApi
@Composable
public fun AlertDialog(
message: String,
onCancelButtonClick: () -> Unit,
onOKButtonClick: () -> Unit,
showDialog: Boolean,
modifier: Modifier = Modifier,
icon: @Composable (() -> Unit)? = null,
title: String? = null,
message: String? = null,
okButtonContentDescription: String = stringResource(android.R.string.ok),
cancelButtonContentDescription: String = stringResource(android.R.string.cancel),
columnState: ScalingLazyColumnState = rememberColumnState(
Expand All @@ -56,6 +58,7 @@ public fun AlertDialog(
scrollState = columnState.state,
) {
AlertContent(
icon = icon,
title = title,
message = message,
onCancelButtonClick = onCancelButtonClick,
Expand All @@ -71,10 +74,11 @@ public fun AlertDialog(
@ExperimentalHorologistApi
@Composable
public fun AlertContent(
message: String,
onCancelButtonClick: (() -> Unit)?,
onOKButtonClick: (() -> Unit)?,
icon: @Composable (() -> Unit)? = null,
title: String? = null,
message: String? = null,
okButtonContentDescription: String = stringResource(android.R.string.ok),
cancelButtonContentDescription: String = stringResource(android.R.string.cancel),
columnState: ScalingLazyColumnState = rememberColumnState(
Expand All @@ -83,23 +87,27 @@ public fun AlertContent(
showPositionIndicator: Boolean = true,
) {
ResponsiveDialogContent(
icon = icon,
title = title?.let {
{
Text(
text = it,
color = MaterialTheme.colors.onBackground,
textAlign = TextAlign.Center,
maxLines = 3,
maxLines = if (icon == null) 3 else 2,
overflow = TextOverflow.Ellipsis,
)
}
},
message = {
Text(
text = message,
color = MaterialTheme.colors.onBackground,
textAlign = TextAlign.Center,
maxLines = 3,
)
message = message?.let {
{
Text(
text = it,
color = MaterialTheme.colors.onBackground,
textAlign = TextAlign.Center,
maxLines = 3,
)
}
},
onOkButtonClick = onOKButtonClick,
onCancelButtonClick = onCancelButtonClick,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,106 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalAccessibilityManager
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.wear.compose.foundation.lazy.ScalingLazyListState
import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
import androidx.wear.compose.material.MaterialTheme
import androidx.wear.compose.material.Text
import androidx.wear.compose.material.contentColorFor
import androidx.wear.compose.material.dialog.Confirmation
import androidx.wear.compose.material.dialog.Dialog
import androidx.wear.compose.material.dialog.DialogDefaults
import com.google.android.horologist.annotations.ExperimentalHorologistApi
import com.google.android.horologist.compose.layout.ScalingLazyColumnDefaults
import com.google.android.horologist.compose.layout.ScalingLazyColumnState
import com.google.android.horologist.compose.layout.rememberColumnState
import kotlinx.coroutines.delay

/**
* This component is an alternative to [ConfirmationContent], providing the following:
* - a convenient way of passing a title and an icon;
* - duration;
* - wrapped in a [Dialog];
*/
@ExperimentalHorologistApi
@Composable
public fun Confirmation(
showDialog: Boolean,
onTimeout: () -> Unit,
modifier: Modifier = Modifier,
icon: @Composable (() -> Unit)? = null,
title: String? = null,
durationMillis: Long = DialogDefaults.ShortDurationMillis,
columnState: ScalingLazyColumnState = rememberColumnState(
ScalingLazyColumnDefaults.responsive(),
),
) {
// Always refer to the latest inputs with which Confirmation was recomposed.
val currentOnDismissed by rememberUpdatedState(onTimeout)

val a11yDurationMillis = LocalAccessibilityManager.current?.calculateRecommendedTimeoutMillis(
originalTimeoutMillis = durationMillis,
containsIcons = icon != null,
containsText = title != null,
containsControls = false,
) ?: durationMillis

LaunchedEffect(showDialog, a11yDurationMillis) {
if (showDialog == true) {
delay(a11yDurationMillis)
currentOnDismissed()
}
}

Dialog(
showDialog = showDialog,
onDismissRequest = currentOnDismissed,
modifier = modifier,
scrollState = columnState.state,
) {
ConfirmationContent(
icon = icon,
title = title,
columnState = columnState,
showPositionIndicator = false,
)
}
}

@ExperimentalHorologistApi
@Composable
public fun ConfirmationContent(
icon: @Composable (() -> Unit)? = null,
title: String? = null,
columnState: ScalingLazyColumnState = rememberColumnState(
ScalingLazyColumnDefaults.responsive(),
),
showPositionIndicator: Boolean = true,
) {
ResponsiveDialogContent(
icon = icon,
title = title?.let {
{
Text(
text = it,
color = MaterialTheme.colors.onBackground,
textAlign = TextAlign.Center,
maxLines = if (icon == null) 3 else 2,
overflow = TextOverflow.Ellipsis,
)
}
},
state = columnState,
showPositionIndicator = showPositionIndicator,
)
}

/**
* A wrapper for [Confirmation] component, that calculates the value passed to [durationMillis] for
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ public fun ResponsiveDialogContent(
onCancelButtonClick: (() -> Unit)? = null,
okButtonContentDescription: String = stringResource(R.string.ok),
cancelButtonContentDescription: String = stringResource(R.string.cancel),
state: ScalingLazyColumnState = rememberColumnState(responsive(firstItemIsFullWidth = icon == null)),
state: ScalingLazyColumnState =
rememberColumnState(responsive(firstItemIsFullWidth = icon == null)),
showPositionIndicator: Boolean = true,
content: (ScalingLazyListScope.() -> Unit)? = null,
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,24 @@

package com.google.android.horologist.materialcomponents

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Check
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.unit.dp
import androidx.wear.compose.material.Chip
import androidx.wear.compose.material.ChipDefaults
import androidx.wear.compose.material.Icon
import androidx.wear.compose.material.Text
import com.google.android.horologist.compose.material.Confirmation

Expand All @@ -34,6 +49,34 @@ internal fun SampleConfirmationScreen(
}
}

@Composable
internal fun SampleConfirmationLauncher() {
var showDialog by remember { mutableStateOf(false) }
Column(
modifier = Modifier.fillMaxSize().padding(horizontal = 20.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Chip(
onClick = { showDialog = true },
label = { Text("Show dialog") },
colors = ChipDefaults.secondaryChipColors(),
)
}
Confirmation(
showDialog = showDialog,
onTimeout = { showDialog = false },
icon = {
Icon(
imageVector = Icons.Filled.Check,
contentDescription = "Completed",
tint = Color.Green,
)
},
title = "Alarm in 23 hr 59 min",
)
}

@Composable
private fun ConfirmationContent() {
Text(text = "Confirmation Content")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,18 @@ fun MenuScreen(
}
item {
Chip(
label = stringResource(id = R.string.sample_material_confirmation_dialog),
label = stringResource(id = R.string.sample_material_confirmation_screen),
modifier = modifier.fillMaxWidth(),
onClick = { navigateToRoute(Screen.MaterialConfirmationScreen.route) },
)
}
item {
Chip(
label = stringResource(id = R.string.sample_material_confirmation_launcher),
modifier = modifier.fillMaxWidth(),
onClick = { navigateToRoute(Screen.MaterialConfirmationLauncher.route) },
)
}
item {
Chip(
label = stringResource(id = R.string.sample_material_icon),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import com.google.android.horologist.materialcomponents.SampleButtonScreen
import com.google.android.horologist.materialcomponents.SampleChipIconWithProgressScreen
import com.google.android.horologist.materialcomponents.SampleChipScreen
import com.google.android.horologist.materialcomponents.SampleCompactChipScreen
import com.google.android.horologist.materialcomponents.SampleConfirmationLauncher
import com.google.android.horologist.materialcomponents.SampleConfirmationScreen
import com.google.android.horologist.materialcomponents.SampleIconScreen
import com.google.android.horologist.materialcomponents.SampleOutlinedChipScreen
Expand Down Expand Up @@ -222,6 +223,13 @@ fun SampleWearApp() {
SampleConfirmationScreen()
}
}
composable(
route = Screen.MaterialConfirmationLauncher.route,
) {
ScreenScaffold(timeText = {}) {
SampleConfirmationLauncher()
}
}
composable(
route = Screen.MaterialIconScreen.route,
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ sealed class Screen(
object MaterialChipIconWithProgressScreen : Screen("materialChipIconWithProgressScreen")
object MaterialCompactChipsScreen : Screen("materialCompactChips")
object MaterialConfirmationScreen : Screen("materialConfirmationScreen")
object MaterialConfirmationLauncher : Screen("materialConfirmationLauncher")
object MaterialIconScreen : Screen("materialIconScreen")
object MaterialOutlinedChipScreen : Screen("materialOutlinedChipScreen")
object MaterialOutlinedCompactChipScreen : Screen("materialOutlinedCompactChipScreen")
Expand Down
3 changes: 2 additions & 1 deletion sample/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
<string name="sample_material_chips">Material Chips Sample</string>
<string name="sample_material_chip_icon_with_progress">Material Chip Icon With Progress</string>
<string name="sample_material_compact_chip">Material Compact Chips</string>
<string name="sample_material_confirmation_dialog">Material Confirmation Dialog</string>
<string name="sample_material_confirmation_screen">Material Confirmation Screen</string>
<string name="sample_material_confirmation_launcher">Material Confirmation Launcher</string>
<string name="sample_material_icon">Material Icon</string>
<string name="sample_material_outlined_chips">Material Outlined Chips</string>
<string name="sample_material_outlined_compact_chips">Material Outlined Compact Chips</string>
Expand Down
Loading

0 comments on commit a060669

Please sign in to comment.