From 3a4f3e3a64cbca514a7d3b62cb1eb1c04649deba Mon Sep 17 00:00:00 2001 From: Gustavo Pagani Date: Fri, 7 Jul 2023 15:13:07 +0100 Subject: [PATCH] Implement ToggleButton (#1476) --- compose-material/api/current.api | 10 + .../compose/material/ToggleButtonPreview.kt | 172 ++++++++++ .../compose/material/SplitToggleChip.kt | 4 +- .../compose/material/ToggleButton.kt | 158 ++++++++++ .../horologist/compose/material/ToggleChip.kt | 4 +- .../src/main/res/values/strings.xml | 10 +- .../compose/material/ToggleButtonA11yTest.kt | 125 ++++++++ .../compose/material/ToggleButtonTest.kt | 296 ++++++++++++++++++ ....material_ToggleButtonA11yTest_default.png | 3 + ...material_ToggleButtonA11yTest_disabled.png | 3 + ...material_ToggleButtonA11yTest_iconOnly.png | 3 + ...terial_ToggleButtonA11yTest_notChecked.png | 3 + ...oggleButtonA11yTest_notCheckedDisabled.png | 3 + ...ose.material_ToggleButtonA11yTest_text.png | 3 + ...pose.material_ToggleButtonTest_default.png | 3 + ...ose.material_ToggleButtonTest_disabled.png | 3 + ...ose.material_ToggleButtonTest_mirrored.png | 3 + ....material_ToggleButtonTest_mirroredRtl.png | 3 + ...e.material_ToggleButtonTest_notChecked.png | 3 + ...al_ToggleButtonTest_notCheckedDisabled.png | 3 + ....compose.material_ToggleButtonTest_rtl.png | 3 + ...ompose.material_ToggleButtonTest_small.png | 3 + ...aterial_ToggleButtonTest_smallDisabled.png | 3 + ...erial_ToggleButtonTest_smallNotChecked.png | 3 + ...compose.material_ToggleButtonTest_text.png | 3 + ...material_ToggleButtonTest_textDisabled.png | 3 + ...terial_ToggleButtonTest_textNotChecked.png | 3 + ...oggleButtonTest_textNotCheckedDisabled.png | 3 + ...gleButtonTest_textWithLargestFontScale.png | 3 + 29 files changed, 834 insertions(+), 8 deletions(-) create mode 100644 compose-material/src/debug/java/com/google/android/horologist/compose/material/ToggleButtonPreview.kt create mode 100644 compose-material/src/main/java/com/google/android/horologist/compose/material/ToggleButton.kt create mode 100644 compose-material/src/test/java/com/google/android/horologist/compose/material/ToggleButtonA11yTest.kt create mode 100644 compose-material/src/test/java/com/google/android/horologist/compose/material/ToggleButtonTest.kt create mode 100644 compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonA11yTest_default.png create mode 100644 compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonA11yTest_disabled.png create mode 100644 compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonA11yTest_iconOnly.png create mode 100644 compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonA11yTest_notChecked.png create mode 100644 compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonA11yTest_notCheckedDisabled.png create mode 100644 compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonA11yTest_text.png create mode 100644 compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_default.png create mode 100644 compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_disabled.png create mode 100644 compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_mirrored.png create mode 100644 compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_mirroredRtl.png create mode 100644 compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_notChecked.png create mode 100644 compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_notCheckedDisabled.png create mode 100644 compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_rtl.png create mode 100644 compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_small.png create mode 100644 compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_smallDisabled.png create mode 100644 compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_smallNotChecked.png create mode 100644 compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_text.png create mode 100644 compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_textDisabled.png create mode 100644 compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_textNotChecked.png create mode 100644 compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_textNotCheckedDisabled.png create mode 100644 compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_textWithLargestFontScale.png diff --git a/compose-material/api/current.api b/compose-material/api/current.api index 38bc994dd9..368bba84d7 100644 --- a/compose-material/api/current.api +++ b/compose-material/api/current.api @@ -65,6 +65,16 @@ package com.google.android.horologist.compose.material { method @androidx.compose.runtime.Composable @com.google.android.horologist.annotations.ExperimentalHorologistApi public static void Title(String text, optional androidx.compose.ui.Modifier modifier); } + public final class ToggleButtonDefaults { + method @androidx.compose.runtime.Composable public androidx.wear.compose.material.ToggleButtonColors iconOnlyColors(); + field public static final com.google.android.horologist.compose.material.ToggleButtonDefaults INSTANCE; + } + + public final class ToggleButtonKt { + method @androidx.compose.runtime.Composable public static void ToggleButton(String text, kotlin.jvm.functions.Function1 onCheckedChanged, optional androidx.compose.ui.Modifier modifier, optional boolean checked, optional boolean enabled, optional androidx.wear.compose.material.ToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional int role, optional boolean smallSize); + method @androidx.compose.runtime.Composable public static void ToggleButton(Object checkedIcon, Object notCheckedIcon, String contentDescription, kotlin.jvm.functions.Function1 onCheckedChanged, optional androidx.compose.ui.Modifier modifier, optional boolean checked, optional boolean enabled, optional androidx.wear.compose.material.ToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional int role, optional com.google.android.horologist.compose.material.IconRtlMode iconRtlMode, optional boolean smallSize); + } + public final class ToggleChipKt { method @androidx.compose.runtime.Composable @com.google.android.horologist.annotations.ExperimentalHorologistApi public static void ToggleChip(boolean checked, kotlin.jvm.functions.Function1 onCheckedChanged, String label, com.google.android.horologist.compose.material.ToggleChipToggleControl toggleControl, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.vector.ImageVector? icon, optional com.google.android.horologist.compose.material.IconRtlMode iconRtlMode, optional String? secondaryLabel, optional androidx.wear.compose.material.ToggleChipColors colors, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource); } diff --git a/compose-material/src/debug/java/com/google/android/horologist/compose/material/ToggleButtonPreview.kt b/compose-material/src/debug/java/com/google/android/horologist/compose/material/ToggleButtonPreview.kt new file mode 100644 index 0000000000..ea78667449 --- /dev/null +++ b/compose-material/src/debug/java/com/google/android/horologist/compose/material/ToggleButtonPreview.kt @@ -0,0 +1,172 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * 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.horologist.compose.material + +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.AirplanemodeActive +import androidx.compose.material.icons.filled.AirplanemodeInactive +import androidx.compose.runtime.Composable +import androidx.compose.ui.tooling.preview.Preview + +@Preview( + backgroundColor = 0xff000000, + showBackground = true +) +@Composable +fun ToggleButtonPreview() { + ToggleButton( + checkedIcon = Icons.Filled.AirplanemodeActive, + notCheckedIcon = Icons.Filled.AirplanemodeInactive, + contentDescription = "contentDescription", + onCheckedChanged = {} + ) +} + +@Preview( + backgroundColor = 0xff000000, + showBackground = true +) +@Composable +fun ToggleButtonPreviewNotChecked() { + ToggleButton( + checkedIcon = Icons.Filled.AirplanemodeActive, + notCheckedIcon = Icons.Filled.AirplanemodeInactive, + contentDescription = "contentDescription", + onCheckedChanged = {}, + checked = false + ) +} + +@Preview( + backgroundColor = 0xff000000, + showBackground = true +) +@Composable +fun ToggleButtonPreviewDisabled() { + ToggleButton( + checkedIcon = Icons.Filled.AirplanemodeActive, + notCheckedIcon = Icons.Filled.AirplanemodeInactive, + contentDescription = "contentDescription", + onCheckedChanged = {}, + enabled = false + ) +} + +@Preview( + backgroundColor = 0xff000000, + showBackground = true +) +@Composable +fun ToggleButtonPreviewNotCheckedDisabled() { + ToggleButton( + checkedIcon = Icons.Filled.AirplanemodeActive, + notCheckedIcon = Icons.Filled.AirplanemodeInactive, + contentDescription = "contentDescription", + onCheckedChanged = {}, + checked = false, + enabled = false + ) +} + +@Preview( + backgroundColor = 0xff000000, + showBackground = true +) +@Composable +fun ToggleButtonPreviewText() { + ToggleButton( + text = "Monday", + onCheckedChanged = {} + ) +} + +@Preview( + backgroundColor = 0xff000000, + showBackground = true +) +@Composable +fun ToggleButtonPreviewTextNotChecked() { + ToggleButton( + text = "Monday", + onCheckedChanged = {}, + checked = false + ) +} + +@Preview( + backgroundColor = 0xff000000, + showBackground = true +) +@Composable +fun ToggleButtonPreviewSmall() { + ToggleButton( + checkedIcon = Icons.Filled.AirplanemodeActive, + notCheckedIcon = Icons.Filled.AirplanemodeInactive, + contentDescription = "contentDescription", + onCheckedChanged = {}, + smallSize = true + ) +} + +@Preview( + backgroundColor = 0xff000000, + showBackground = true +) +@Composable +fun ToggleButtonPreviewSmallNotChecked() { + ToggleButton( + checkedIcon = Icons.Filled.AirplanemodeActive, + notCheckedIcon = Icons.Filled.AirplanemodeInactive, + contentDescription = "contentDescription", + onCheckedChanged = {}, + checked = false, + smallSize = true + ) +} + +@Preview( + backgroundColor = 0xff000000, + showBackground = true +) +@Composable +fun ToggleButtonPreviewIconOnly() { + ToggleButton( + checkedIcon = Icons.Filled.AirplanemodeActive, + notCheckedIcon = Icons.Filled.AirplanemodeInactive, + contentDescription = "contentDescription", + onCheckedChanged = {}, + colors = ToggleButtonDefaults.iconOnlyColors(), + smallSize = true + ) +} + +@Preview( + backgroundColor = 0xff000000, + showBackground = true +) +@Composable +fun ToggleButtonPreviewIconOnlyNotChecked() { + ToggleButton( + checkedIcon = Icons.Filled.AirplanemodeActive, + notCheckedIcon = Icons.Filled.AirplanemodeInactive, + contentDescription = "contentDescription", + onCheckedChanged = {}, + checked = false, + colors = ToggleButtonDefaults.iconOnlyColors(), + smallSize = true + ) +} diff --git a/compose-material/src/main/java/com/google/android/horologist/compose/material/SplitToggleChip.kt b/compose-material/src/main/java/com/google/android/horologist/compose/material/SplitToggleChip.kt index 6d7827b6e9..93a1b26ea2 100644 --- a/compose-material/src/main/java/com/google/android/horologist/compose/material/SplitToggleChip.kt +++ b/compose-material/src/main/java/com/google/android/horologist/compose/material/SplitToggleChip.kt @@ -87,9 +87,9 @@ public fun SplitToggleChip( val toggleControlParam: (@Composable BoxScope.() -> Unit) = { val stateDescriptionSemantics = stringResource( if (checked) { - R.string.horologist_split_toggle_chip_on_content_description + R.string.horologist_split_toggle_chip_on_state_description } else { - R.string.horologist_split_toggle_chip_off_content_description + R.string.horologist_split_toggle_chip_off_state_description } ) Icon( diff --git a/compose-material/src/main/java/com/google/android/horologist/compose/material/ToggleButton.kt b/compose-material/src/main/java/com/google/android/horologist/compose/material/ToggleButton.kt new file mode 100644 index 0000000000..ca1b6a01a8 --- /dev/null +++ b/compose-material/src/main/java/com/google/android/horologist/compose/material/ToggleButton.kt @@ -0,0 +1,158 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * 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.horologist.compose.material + +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.Role +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.semantics.stateDescription +import androidx.wear.compose.material.ContentAlpha +import androidx.wear.compose.material.MaterialTheme +import androidx.wear.compose.material.Text +import androidx.wear.compose.material.ToggleButton +import androidx.wear.compose.material.ToggleButtonColors +import androidx.wear.compose.material.ToggleButtonDefaults +import androidx.wear.compose.material.contentColorFor + +/** + * This component is an alternative to [ToggleButton], providing the following: + * - a convenient way of providing text; + */ +@Composable +public fun ToggleButton( + text: String, + onCheckedChanged: (Boolean) -> Unit, + modifier: Modifier = Modifier, + checked: Boolean = true, + enabled: Boolean = true, + colors: ToggleButtonColors = ToggleButtonDefaults.toggleButtonColors(), + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, + shape: Shape = CircleShape, + role: Role = ToggleButtonDefaults.DefaultRole, + smallSize: Boolean = false +) { + val stateDescriptionSemantics = stringResource( + if (checked) { + R.string.horologist_toggle_button_on_state_description + } else { + R.string.horologist_toggle_button_off_state_description + } + ) + + val newModifier = if (smallSize) { + modifier.size(ToggleButtonDefaults.SmallToggleButtonSize) + } else { + modifier + }.semantics { stateDescription = stateDescriptionSemantics } + + ToggleButton( + checked = checked, + onCheckedChange = onCheckedChanged, + modifier = newModifier, + enabled = enabled, + colors = colors, + interactionSource = interactionSource, + shape = shape, + role = role + ) { + Text(text = text.take(3)) + } +} + +/**ยง + * This component is an alternative to [ToggleButton], providing the following: + * - a convenient way of providing a icons for the checked and not checked states; + */ +@Composable +public fun ToggleButton( + checkedIcon: Any, + notCheckedIcon: Any, + contentDescription: String, + onCheckedChanged: (Boolean) -> Unit, + modifier: Modifier = Modifier, + checked: Boolean = true, + enabled: Boolean = true, + colors: ToggleButtonColors = ToggleButtonDefaults.toggleButtonColors(), + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, + shape: Shape = CircleShape, + role: Role = ToggleButtonDefaults.DefaultRole, + iconRtlMode: IconRtlMode = IconRtlMode.Default, + smallSize: Boolean = false +) { + val stateDescriptionSemantics = stringResource( + if (checked) { + R.string.horologist_toggle_button_on_state_description + } else { + R.string.horologist_toggle_button_off_state_description + } + ) + + val newModifier = if (smallSize) { + modifier.size(ToggleButtonDefaults.SmallToggleButtonSize) + } else { + modifier + }.semantics { stateDescription = stateDescriptionSemantics } + + ToggleButton( + checked = checked, + onCheckedChange = onCheckedChanged, + modifier = newModifier, + enabled = enabled, + colors = colors, + interactionSource = interactionSource, + shape = shape, + role = role + ) { + Icon( + icon = if (checked) { + checkedIcon + } else { + notCheckedIcon + }, + modifier = modifier, + contentDescription = contentDescription, + rtlMode = iconRtlMode + ) + } +} + +/** + * Contains the default values used by [ToggleButton]. + */ +public object ToggleButtonDefaults { + + /** + * Creates a [ToggleButtonColors] that represents the content colors for an icon-only + * [ToggleButton]. + */ + @Composable + public fun iconOnlyColors(): ToggleButtonColors { + return ToggleButtonDefaults.toggleButtonColors( + checkedBackgroundColor = Color.Transparent, + uncheckedBackgroundColor = Color.Transparent, + disabledCheckedContentColor = contentColorFor(MaterialTheme.colors.surface).copy(alpha = ContentAlpha.disabled) + ) + } +} diff --git a/compose-material/src/main/java/com/google/android/horologist/compose/material/ToggleChip.kt b/compose-material/src/main/java/com/google/android/horologist/compose/material/ToggleChip.kt index 5c3e1f7239..3da5f11304 100644 --- a/compose-material/src/main/java/com/google/android/horologist/compose/material/ToggleChip.kt +++ b/compose-material/src/main/java/com/google/android/horologist/compose/material/ToggleChip.kt @@ -123,9 +123,9 @@ public fun ToggleChip( val stateDescriptionSemantics = stringResource( if (checked) { - R.string.horologist_toggle_chip_on_content_description + R.string.horologist_toggle_chip_on_state_description } else { - R.string.horologist_toggle_chip_off_content_description + R.string.horologist_toggle_chip_off_state_description } ) ToggleChip( diff --git a/compose-material/src/main/res/values/strings.xml b/compose-material/src/main/res/values/strings.xml index 3c98b72355..d044b546a2 100644 --- a/compose-material/src/main/res/values/strings.xml +++ b/compose-material/src/main/res/values/strings.xml @@ -15,8 +15,10 @@ --> - On - Off - On - Off + On + Off + On + Off + On + Off diff --git a/compose-material/src/test/java/com/google/android/horologist/compose/material/ToggleButtonA11yTest.kt b/compose-material/src/test/java/com/google/android/horologist/compose/material/ToggleButtonA11yTest.kt new file mode 100644 index 0000000000..c77b113f97 --- /dev/null +++ b/compose-material/src/test/java/com/google/android/horologist/compose/material/ToggleButtonA11yTest.kt @@ -0,0 +1,125 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * 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.horologist.compose.material + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.AirplanemodeActive +import androidx.compose.material.icons.filled.AirplanemodeInactive +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import com.google.android.horologist.screenshots.ScreenshotBaseTest +import com.google.android.horologist.screenshots.ScreenshotTestRule +import org.junit.Test + +class ToggleButtonA11yTest : + ScreenshotBaseTest( + ScreenshotTestRule.screenshotTestRuleParams { + enableA11y = true + screenTimeText = {} + } + ) { + + @Test + fun default() { + screenshotTestRule.setContent(takeScreenshot = true) { + Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize()) { + ToggleButton( + checkedIcon = Icons.Filled.AirplanemodeActive, + notCheckedIcon = Icons.Filled.AirplanemodeInactive, + contentDescription = "contentDescription", + onCheckedChanged = {} + ) + } + } + } + + @Test + fun notChecked() { + screenshotTestRule.setContent(takeScreenshot = true) { + Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize()) { + ToggleButton( + checkedIcon = Icons.Filled.AirplanemodeActive, + notCheckedIcon = Icons.Filled.AirplanemodeInactive, + contentDescription = "contentDescription", + onCheckedChanged = {}, + checked = false + ) + } + } + } + + @Test + fun disabled() { + screenshotTestRule.setContent(takeScreenshot = true) { + Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize()) { + ToggleButton( + checkedIcon = Icons.Filled.AirplanemodeActive, + notCheckedIcon = Icons.Filled.AirplanemodeInactive, + contentDescription = "contentDescription", + onCheckedChanged = {}, + enabled = false + ) + } + } + } + + @Test + fun notCheckedDisabled() { + screenshotTestRule.setContent(takeScreenshot = true) { + Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize()) { + ToggleButton( + checkedIcon = Icons.Filled.AirplanemodeActive, + notCheckedIcon = Icons.Filled.AirplanemodeInactive, + contentDescription = "contentDescription", + onCheckedChanged = {}, + checked = false, + enabled = false + ) + } + } + } + + @Test + fun text() { + screenshotTestRule.setContent(takeScreenshot = true) { + Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize()) { + ToggleButton( + text = "Monday", + onCheckedChanged = {} + ) + } + } + } + + @Test + fun iconOnly() { + screenshotTestRule.setContent(takeScreenshot = true) { + Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize()) { + ToggleButton( + checkedIcon = Icons.Filled.AirplanemodeActive, + notCheckedIcon = Icons.Filled.AirplanemodeInactive, + contentDescription = "contentDescription", + onCheckedChanged = {}, + colors = ToggleButtonDefaults.iconOnlyColors(), + smallSize = true + ) + } + } + } +} diff --git a/compose-material/src/test/java/com/google/android/horologist/compose/material/ToggleButtonTest.kt b/compose-material/src/test/java/com/google/android/horologist/compose/material/ToggleButtonTest.kt new file mode 100644 index 0000000000..09b06d6f4e --- /dev/null +++ b/compose-material/src/test/java/com/google/android/horologist/compose/material/ToggleButtonTest.kt @@ -0,0 +1,296 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * 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.horologist.compose.material + +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.AirplanemodeActive +import androidx.compose.material.icons.filled.AirplanemodeInactive +import androidx.compose.material.icons.filled.VolumeOff +import androidx.compose.material.icons.filled.VolumeUp +import androidx.compose.ui.unit.LayoutDirection +import com.google.accompanist.testharness.TestHarness +import com.google.android.horologist.screenshots.ScreenshotBaseTest +import org.junit.Test + +class ToggleButtonTest : ScreenshotBaseTest() { + + @Test + fun default() { + screenshotTestRule.setContent(isComponent = true, takeScreenshot = true) { + ToggleButton( + checkedIcon = Icons.Filled.AirplanemodeActive, + notCheckedIcon = Icons.Filled.AirplanemodeInactive, + contentDescription = "contentDescription", + onCheckedChanged = {} + ) + } + } + + @Test + fun notChecked() { + screenshotTestRule.setContent(isComponent = true, takeScreenshot = true) { + ToggleButton( + checkedIcon = Icons.Filled.AirplanemodeActive, + notCheckedIcon = Icons.Filled.AirplanemodeInactive, + contentDescription = "contentDescription", + onCheckedChanged = {}, + checked = false + ) + } + } + + @Test + fun disabled() { + screenshotTestRule.setContent(isComponent = true, takeScreenshot = true) { + ToggleButton( + checkedIcon = Icons.Filled.AirplanemodeActive, + notCheckedIcon = Icons.Filled.AirplanemodeInactive, + contentDescription = "contentDescription", + onCheckedChanged = {}, + enabled = false + ) + } + } + + @Test + fun notCheckedDisabled() { + screenshotTestRule.setContent(isComponent = true, takeScreenshot = true) { + ToggleButton( + checkedIcon = Icons.Filled.AirplanemodeActive, + notCheckedIcon = Icons.Filled.AirplanemodeInactive, + contentDescription = "contentDescription", + onCheckedChanged = {}, + checked = false, + enabled = false + ) + } + } + + @Test + fun text() { + screenshotTestRule.setContent(isComponent = true, takeScreenshot = true) { + ToggleButton( + text = "Monday", + onCheckedChanged = {} + ) + } + } + + @Test + fun textNotChecked() { + screenshotTestRule.setContent(isComponent = true, takeScreenshot = true) { + ToggleButton( + text = "Monday", + onCheckedChanged = {}, + checked = false + ) + } + } + + @Test + fun textDisabled() { + screenshotTestRule.setContent(isComponent = true, takeScreenshot = true) { + ToggleButton( + text = "Monday", + onCheckedChanged = {}, + enabled = false + ) + } + } + + @Test + fun textNotCheckedDisabled() { + screenshotTestRule.setContent(isComponent = true, takeScreenshot = true) { + ToggleButton( + text = "Monday", + onCheckedChanged = {}, + checked = false, + enabled = false + ) + } + } + + @Test + fun small() { + screenshotTestRule.setContent(isComponent = true, takeScreenshot = true) { + ToggleButton( + checkedIcon = Icons.Filled.AirplanemodeActive, + notCheckedIcon = Icons.Filled.AirplanemodeInactive, + contentDescription = "contentDescription", + onCheckedChanged = {}, + smallSize = true + ) + } + } + + @Test + fun smallNotChecked() { + screenshotTestRule.setContent(isComponent = true, takeScreenshot = true) { + ToggleButton( + checkedIcon = Icons.Filled.AirplanemodeActive, + notCheckedIcon = Icons.Filled.AirplanemodeInactive, + contentDescription = "contentDescription", + onCheckedChanged = {}, + checked = false, + smallSize = true + ) + } + } + + @Test + fun smallDisabled() { + screenshotTestRule.setContent(isComponent = true, takeScreenshot = true) { + ToggleButton( + checkedIcon = Icons.Filled.AirplanemodeActive, + notCheckedIcon = Icons.Filled.AirplanemodeInactive, + contentDescription = "contentDescription", + onCheckedChanged = {}, + enabled = false, + smallSize = true + ) + } + } + + fun smallNotCheckedDisabled() { + screenshotTestRule.setContent(isComponent = true, takeScreenshot = true) { + ToggleButton( + checkedIcon = Icons.Filled.AirplanemodeActive, + notCheckedIcon = Icons.Filled.AirplanemodeInactive, + contentDescription = "contentDescription", + onCheckedChanged = {}, + checked = false, + enabled = false, + smallSize = true + ) + } + } + + fun iconOnly() { + screenshotTestRule.setContent(isComponent = true, takeScreenshot = true) { + ToggleButton( + checkedIcon = Icons.Filled.AirplanemodeActive, + notCheckedIcon = Icons.Filled.AirplanemodeInactive, + contentDescription = "contentDescription", + onCheckedChanged = {}, + colors = ToggleButtonDefaults.iconOnlyColors(), + smallSize = true + ) + } + } + + fun iconOnlyNotChecked() { + screenshotTestRule.setContent(isComponent = true, takeScreenshot = true) { + ToggleButton( + checkedIcon = Icons.Filled.AirplanemodeActive, + notCheckedIcon = Icons.Filled.AirplanemodeInactive, + contentDescription = "contentDescription", + onCheckedChanged = {}, + checked = false, + colors = ToggleButtonDefaults.iconOnlyColors(), + smallSize = true + ) + } + } + + fun iconOnlyDisabled() { + screenshotTestRule.setContent(isComponent = true, takeScreenshot = true) { + ToggleButton( + checkedIcon = Icons.Filled.AirplanemodeActive, + notCheckedIcon = Icons.Filled.AirplanemodeInactive, + contentDescription = "contentDescription", + onCheckedChanged = {}, + enabled = false, + colors = ToggleButtonDefaults.iconOnlyColors(), + smallSize = true + ) + } + } + + fun iconOnlyNotCheckedDisabled() { + screenshotTestRule.setContent(isComponent = true, takeScreenshot = true) { + ToggleButton( + checkedIcon = Icons.Filled.AirplanemodeActive, + notCheckedIcon = Icons.Filled.AirplanemodeInactive, + contentDescription = "contentDescription", + onCheckedChanged = {}, + checked = false, + enabled = false, + colors = ToggleButtonDefaults.iconOnlyColors(), + smallSize = true + ) + } + } + + @Test + fun rtl() { + screenshotTestRule.setContent(isComponent = true, takeScreenshot = true) { + TestHarness(layoutDirection = LayoutDirection.Rtl) { + ToggleButton( + checkedIcon = Icons.Filled.VolumeUp, + notCheckedIcon = Icons.Filled.VolumeOff, + contentDescription = "contentDescription", + onCheckedChanged = {} + ) + } + } + } + + @Test + fun mirrored() { + screenshotTestRule.setContent(isComponent = true, takeScreenshot = true) { + ToggleButton( + checkedIcon = Icons.Filled.VolumeUp, + notCheckedIcon = Icons.Filled.VolumeOff, + contentDescription = "contentDescription", + onCheckedChanged = {}, + iconRtlMode = IconRtlMode.Mirrored + ) + } + } + + @Test + fun mirroredRtl() { + screenshotTestRule.setContent(isComponent = true, takeScreenshot = true) { + TestHarness(layoutDirection = LayoutDirection.Rtl) { + ToggleButton( + checkedIcon = Icons.Filled.VolumeUp, + notCheckedIcon = Icons.Filled.VolumeOff, + contentDescription = "contentDescription", + onCheckedChanged = {}, + iconRtlMode = IconRtlMode.Mirrored + ) + } + } + } + + @Test + fun textWithLargestFontScale() { + screenshotTestRule.setContent(isComponent = true, takeScreenshot = true) { + TestHarness(fontScale = largestFontScale) { + ToggleButton( + text = "Monday", + onCheckedChanged = {} + ) + } + } + } + + companion object { + + private const val largestFontScale = 1.18f + } +} diff --git a/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonA11yTest_default.png b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonA11yTest_default.png new file mode 100644 index 0000000000..8f96dc2cba --- /dev/null +++ b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonA11yTest_default.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0204976731ca4df8179c0593dd27b15e1a2e1b17e84bb83619edcfc8d59bcaa6 +size 14682 diff --git a/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonA11yTest_disabled.png b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonA11yTest_disabled.png new file mode 100644 index 0000000000..5d7c37a912 --- /dev/null +++ b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonA11yTest_disabled.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1c70afb42d13edcabb6de6bcf2c0bed793799bd6cde263f42a479216edfef4f3 +size 14503 diff --git a/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonA11yTest_iconOnly.png b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonA11yTest_iconOnly.png new file mode 100644 index 0000000000..fe90dff858 --- /dev/null +++ b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonA11yTest_iconOnly.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:62f1171232cbfaf6d60358f0bc465c557ec1f5391f9f81114a26f330d4e06dd7 +size 12194 diff --git a/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonA11yTest_notChecked.png b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonA11yTest_notChecked.png new file mode 100644 index 0000000000..9c3270edf8 --- /dev/null +++ b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonA11yTest_notChecked.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a8d801416ec0da5aab10eb76d2482d80009534375517ea8e408d2fe5c6cb3dd2 +size 14770 diff --git a/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonA11yTest_notCheckedDisabled.png b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonA11yTest_notCheckedDisabled.png new file mode 100644 index 0000000000..b4b69d7bb0 --- /dev/null +++ b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonA11yTest_notCheckedDisabled.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0c19dcad3946308d29ce3072fe863367ca8774538d1145ffe88641facb44f627 +size 14289 diff --git a/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonA11yTest_text.png b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonA11yTest_text.png new file mode 100644 index 0000000000..f75440e129 --- /dev/null +++ b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonA11yTest_text.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:882d7c62ece903dbfae0002bb379522659a1e7fd832d8ba0e893eb0bbd0ae3e6 +size 14846 diff --git a/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_default.png b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_default.png new file mode 100644 index 0000000000..15123c7f8e --- /dev/null +++ b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_default.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:663c5f57e311c7e0faf9bd8840a6a64eceb919399d34ddcff9014edad41e983b +size 3566 diff --git a/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_disabled.png b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_disabled.png new file mode 100644 index 0000000000..4c22ec133b --- /dev/null +++ b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_disabled.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:121f7c9d2d76983acac9df889a16fc6dc81fec061b356fdec9bc6d6f4399cab7 +size 3537 diff --git a/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_mirrored.png b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_mirrored.png new file mode 100644 index 0000000000..06fc0b1725 --- /dev/null +++ b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_mirrored.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cbf95f96e8944d2188224f5ecad34743f9495a0802dd12006a5d8658fd58fcad +size 3571 diff --git a/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_mirroredRtl.png b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_mirroredRtl.png new file mode 100644 index 0000000000..ed321162df --- /dev/null +++ b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_mirroredRtl.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b168fc58dabbaefcfcc1703d5a6e600591b96a4b50c2943ef84539a2f7aff4b6 +size 3591 diff --git a/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_notChecked.png b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_notChecked.png new file mode 100644 index 0000000000..455b11dce4 --- /dev/null +++ b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_notChecked.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:93b2f16b4f9eac3471494f5ddda5096580751248440c3d31aa5d914c1a9b7f6a +size 3700 diff --git a/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_notCheckedDisabled.png b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_notCheckedDisabled.png new file mode 100644 index 0000000000..138492f60e --- /dev/null +++ b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_notCheckedDisabled.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:013d2e10757b5bf2f22178b2ced4d5cff6493e184800ae3dadc2d253123f48f3 +size 3684 diff --git a/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_rtl.png b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_rtl.png new file mode 100644 index 0000000000..06fc0b1725 --- /dev/null +++ b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_rtl.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cbf95f96e8944d2188224f5ecad34743f9495a0802dd12006a5d8658fd58fcad +size 3571 diff --git a/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_small.png b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_small.png new file mode 100644 index 0000000000..2fc38e4c94 --- /dev/null +++ b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_small.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a06f107efbfdf76c5192fec55bc7a6a84b815a6390c91b5ea83560960827b88b +size 3383 diff --git a/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_smallDisabled.png b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_smallDisabled.png new file mode 100644 index 0000000000..11cb3cfec1 --- /dev/null +++ b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_smallDisabled.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aebba39fbbb8eef9f51d0b545babeecb0762257a90c451730204b5e9df56da50 +size 3378 diff --git a/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_smallNotChecked.png b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_smallNotChecked.png new file mode 100644 index 0000000000..4a29acd34b --- /dev/null +++ b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_smallNotChecked.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b23ac8c8714198e0f02b2a5fcd1655c0be8fdf0d7252dd755b5b7a1a69ddbb2f +size 3552 diff --git a/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_text.png b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_text.png new file mode 100644 index 0000000000..919c864ed5 --- /dev/null +++ b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_text.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b1a742d6cd2d422064d13b90b77776d9a65e6aec23faaef2bb4b95bab87bba40 +size 4105 diff --git a/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_textDisabled.png b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_textDisabled.png new file mode 100644 index 0000000000..7fc7e9f49a --- /dev/null +++ b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_textDisabled.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:76fa6bdf65a310eb709cb616a69fddb4a3f8cb449d28a2f686e6968fd29cc796 +size 4083 diff --git a/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_textNotChecked.png b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_textNotChecked.png new file mode 100644 index 0000000000..de4ad3f4d8 --- /dev/null +++ b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_textNotChecked.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e7b1d3a3835ec4b6aa637657276b150fad837d8aacea6b7a1c365e36d1a63693 +size 3908 diff --git a/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_textNotCheckedDisabled.png b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_textNotCheckedDisabled.png new file mode 100644 index 0000000000..cc64628550 --- /dev/null +++ b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_textNotCheckedDisabled.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1d016b2fbf4df3b75f9174bf9be9b2a640f24f093e1dc3e89c41fb170bed514c +size 3623 diff --git a/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_textWithLargestFontScale.png b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_textWithLargestFontScale.png new file mode 100644 index 0000000000..07f6560e44 --- /dev/null +++ b/compose-material/src/test/snapshots/images/com.google.android.horologist.compose.material_ToggleButtonTest_textWithLargestFontScale.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ad33882f3b596458379ff1bf7797c10cd2dbdcb316594ba7ac0c272b96a93653 +size 4299