diff --git a/catalog/src/main/kotlin/com/adevinta/spark/catalog/configurator/component/Component.kt b/catalog/src/main/kotlin/com/adevinta/spark/catalog/configurator/component/Component.kt index ebe4c35cc..55e0e8744 100644 --- a/catalog/src/main/kotlin/com/adevinta/spark/catalog/configurator/component/Component.kt +++ b/catalog/src/main/kotlin/com/adevinta/spark/catalog/configurator/component/Component.kt @@ -34,9 +34,6 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.rounded.BugReport import androidx.compose.material.icons.rounded.Code import androidx.compose.material.icons.rounded.Palette -import androidx.compose.material.icons.twotone.BugReport -import androidx.compose.material.icons.twotone.Code -import androidx.compose.material.icons.twotone.Palette import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -54,8 +51,8 @@ import com.adevinta.spark.catalog.model.Configurator import com.adevinta.spark.catalog.util.IssueUrl import com.adevinta.spark.catalog.util.openUrl import com.adevinta.spark.components.divider.Divider +import com.adevinta.spark.components.iconbuttons.IconButtonGhost import com.adevinta.spark.components.icons.Icon -import com.adevinta.spark.components.icons.IconButton import com.adevinta.spark.components.menu.DropdownMenu import com.adevinta.spark.components.menu.DropdownMenuItem import com.adevinta.spark.components.text.Text @@ -81,11 +78,11 @@ public fun ConfiguratorComponentScreen( modifier = Modifier.align(Alignment.End), ) { var expanded by remember { mutableStateOf(false) } - IconButton( + IconButtonGhost( + icon = SparkIcons.Link, onClick = { expanded = true }, - ) { - Icon(SparkIcons.Link, contentDescription = "Localized description") - } + contentDescription = "Localized description", + ) ConfiguratorComponentMenu( component = component, diff --git a/catalog/src/main/kotlin/com/adevinta/spark/catalog/configurator/samples/buttons/IconButtonsConfigurator.kt b/catalog/src/main/kotlin/com/adevinta/spark/catalog/configurator/samples/buttons/IconButtonsConfigurator.kt new file mode 100644 index 000000000..2371165e5 --- /dev/null +++ b/catalog/src/main/kotlin/com/adevinta/spark/catalog/configurator/samples/buttons/IconButtonsConfigurator.kt @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2023 Adevinta + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.adevinta.spark.catalog.configurator.samples.buttons + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +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.Modifier +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.adevinta.spark.SparkTheme +import com.adevinta.spark.catalog.model.Configurator +import com.adevinta.spark.catalog.themes.SegmentedButton +import com.adevinta.spark.catalog.util.SampleSourceUrl +import com.adevinta.spark.components.iconbuttons.IconButtonContrast +import com.adevinta.spark.components.iconbuttons.IconButtonFilled +import com.adevinta.spark.components.iconbuttons.IconButtonGhost +import com.adevinta.spark.components.iconbuttons.IconButtonIntent +import com.adevinta.spark.components.iconbuttons.IconButtonOutlined +import com.adevinta.spark.components.iconbuttons.IconButtonShape +import com.adevinta.spark.components.iconbuttons.IconButtonSize +import com.adevinta.spark.components.iconbuttons.IconButtonTinted +import com.adevinta.spark.components.menu.DropdownMenuItem +import com.adevinta.spark.components.text.Text +import com.adevinta.spark.components.textfields.SelectTextField +import com.adevinta.spark.components.textfields.TextField +import com.adevinta.spark.components.toggles.SwitchLabelled +import com.adevinta.spark.icons.LikeFill +import com.adevinta.spark.icons.SparkIcon +import com.adevinta.spark.icons.SparkIcons + +public val IconButtonsConfigurator: Configurator = Configurator( + name = "IconButton", + description = "IconButton configuration", + sourceUrl = "$SampleSourceUrl/IconButtonSamples.kt", +) { + IconButtonSample() +} + +@Preview( + showBackground = true, +) +@Composable +private fun IconButtonSample() { + val scrollState = rememberScrollState() + Column( + verticalArrangement = Arrangement.spacedBy(16.dp), + modifier = Modifier.verticalScroll(scrollState), + ) { + var style by remember { mutableStateOf(IconButtonStyle.Filled) } + var icon: SparkIcon by remember { mutableStateOf(SparkIcons.LikeFill) } + var isEnabled by remember { mutableStateOf(true) } + var shape by remember { mutableStateOf(IconButtonShape.Large) } + var size by remember { mutableStateOf(IconButtonSize.Medium) } + var intent by remember { mutableStateOf(IconButtonIntent.Main) } + var contentDescription by remember { mutableStateOf("Content Description") } + + ConfigedIconButton( + style = style, + shape = shape, + contentDescription = contentDescription, + onClick = { }, + size = size, + intent = intent, + isEnabled = isEnabled, + icon = icon, + ) + + SwitchLabelled( + checked = isEnabled, + onCheckedChange = { isEnabled = it }, + ) { + Text( + text = "Enabled", + modifier = Modifier.fillMaxWidth(), + ) + } + + Column { + Text( + text = "Style", + modifier = Modifier.padding(bottom = 8.dp), + style = SparkTheme.typography.body2.copy(fontWeight = FontWeight.Bold), + ) + val buttonStyles = IconButtonStyle.values() + val buttonStylesLabel = buttonStyles.map { it.name } + SegmentedButton( + options = buttonStylesLabel, + selectedOption = style.name, + onOptionSelect = { style = IconButtonStyle.valueOf(it) }, + modifier = Modifier + .fillMaxWidth() + .height(48.dp), + ) + } + + val intents = IconButtonIntent.values() + var expanded by remember { mutableStateOf(false) } + SelectTextField( + modifier = Modifier.fillMaxWidth(), + value = intent.name, + onValueChange = {}, + readOnly = true, + label = "Intent", + expanded = expanded, + onExpandedChange = { + expanded = !expanded + }, + onDismissRequest = { + expanded = false + }, + dropdownContent = { + intents.forEach { + DropdownMenuItem( + text = { Text(it.name) }, + onClick = { + intent = it + expanded = false + }, + ) + } + }, + ) + + Column { + Text( + text = "Shape", + modifier = Modifier.padding(bottom = 8.dp), + style = SparkTheme.typography.body2.copy(fontWeight = FontWeight.Bold), + ) + val buttonShapes = IconButtonShape.values() + val buttonShapesLabel = buttonShapes.map { it.name } + SegmentedButton( + options = buttonShapesLabel, + selectedOption = shape.name, + onOptionSelect = { shape = IconButtonShape.valueOf(it) }, + modifier = Modifier + .fillMaxWidth() + .height(48.dp), + ) + } + Column { + Text( + text = "Size", + modifier = Modifier.padding(bottom = 8.dp), + style = SparkTheme.typography.body2.copy(fontWeight = FontWeight.Bold), + ) + val buttonSizes = IconButtonSize.values() + val buttonSizesLabel = buttonSizes.map { it.name } + SegmentedButton( + options = buttonSizesLabel, + selectedOption = size.name, + onOptionSelect = { size = IconButtonSize.valueOf(it) }, + modifier = Modifier + .fillMaxWidth() + .height(48.dp), + ) + } + + TextField( + modifier = Modifier.fillMaxWidth(), + value = contentDescription, + onValueChange = { + contentDescription = it + }, + label = "Content Description", + placeholder = "Content Description", + ) + } +} + +@Composable +private fun ConfigedIconButton( + modifier: Modifier = Modifier, + style: IconButtonStyle, + shape: IconButtonShape, + contentDescription: String?, + onClick: () -> Unit = {}, + size: IconButtonSize, + intent: IconButtonIntent, + isEnabled: Boolean, + icon: SparkIcon, +) { + when (style) { + IconButtonStyle.Filled -> IconButtonFilled( + modifier = modifier, + contentDescription = contentDescription, + onClick = onClick, + size = size, + shape = shape, + intent = intent, + enabled = isEnabled, + icon = icon, + ) + + IconButtonStyle.Outlined -> IconButtonOutlined( + modifier = modifier, + contentDescription = contentDescription, + onClick = onClick, + size = size, + shape = shape, + intent = intent, + enabled = isEnabled, + icon = icon, + ) + + IconButtonStyle.Tinted -> IconButtonTinted( + modifier = modifier, + contentDescription = contentDescription, + onClick = onClick, + size = size, + shape = shape, + intent = intent, + enabled = isEnabled, + icon = icon, + ) + + IconButtonStyle.Ghost -> IconButtonGhost( + modifier = modifier, + contentDescription = contentDescription, + onClick = onClick, + size = size, + shape = shape, + intent = intent, + enabled = isEnabled, + icon = icon, + ) + + IconButtonStyle.Contrast -> IconButtonContrast( + modifier = modifier, + contentDescription = contentDescription, + onClick = onClick, + size = size, + shape = shape, + intent = intent, + enabled = isEnabled, + icon = icon, + ) + } +} + +private enum class IconButtonStyle { + Filled, + Outlined, + Tinted, + Contrast, + Ghost, +} diff --git a/catalog/src/main/kotlin/com/adevinta/spark/catalog/examples/samples/buttons/IconButtonsExamples.kt b/catalog/src/main/kotlin/com/adevinta/spark/catalog/examples/samples/buttons/IconButtonsExamples.kt new file mode 100644 index 000000000..a414c7796 --- /dev/null +++ b/catalog/src/main/kotlin/com/adevinta/spark/catalog/examples/samples/buttons/IconButtonsExamples.kt @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2023 Adevinta + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.adevinta.spark.catalog.examples.samples.buttons + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.runtime.Composable +import androidx.compose.ui.unit.dp +import com.adevinta.spark.catalog.model.Example +import com.adevinta.spark.catalog.util.SampleSourceUrl +import com.adevinta.spark.components.iconbuttons.IconButtonContrast +import com.adevinta.spark.components.iconbuttons.IconButtonFilled +import com.adevinta.spark.components.iconbuttons.IconButtonGhost +import com.adevinta.spark.components.iconbuttons.IconButtonOutlined +import com.adevinta.spark.components.iconbuttons.IconButtonTinted +import com.adevinta.spark.icons.LikeFill +import com.adevinta.spark.icons.SparkIcon +import com.adevinta.spark.icons.SparkIcons + +private const val IconButtonsExampleDescription = "Icon Button examples" +private const val IconButtonsExampleSourceUrl = "$SampleSourceUrl/IconButtonSamples.kt" +public val IconButtonsExamples: List = listOf( + Example( + name = "Filled Icon Button", + description = IconButtonsExampleDescription, + sourceUrl = IconButtonsExampleSourceUrl, + ) { + IconButtonSample( + button = { onClick, enabled, icon, contentDescription -> + IconButtonFilled( + onClick = onClick, + enabled = enabled, + icon = icon, + contentDescription = contentDescription, + ) + }, + ) + }, + Example( + name = "Tinted Icon Button", + description = IconButtonsExampleDescription, + sourceUrl = IconButtonsExampleSourceUrl, + ) { + IconButtonSample( + button = { onClick, enabled, icon, contentDescription -> + IconButtonTinted( + onClick = onClick, + enabled = enabled, + icon = icon, + contentDescription = contentDescription, + ) + }, + ) + }, + Example( + name = "Outlined Icon Button", + description = IconButtonsExampleDescription, + sourceUrl = IconButtonsExampleSourceUrl, + ) { + IconButtonSample( + button = { onClick, enabled, icon, contentDescription -> + IconButtonOutlined( + onClick = onClick, + enabled = enabled, + icon = icon, + contentDescription = contentDescription, + ) + }, + ) + }, + Example( + name = "Ghost Icon Button", + description = IconButtonsExampleDescription, + sourceUrl = IconButtonsExampleSourceUrl, + ) { + IconButtonSample( + button = { onClick, enabled, icon, contentDescription -> + IconButtonGhost( + onClick = onClick, + enabled = enabled, + icon = icon, + contentDescription = contentDescription, + ) + }, + ) + }, + Example( + name = "Contrast Icon Button", + description = IconButtonsExampleDescription, + sourceUrl = IconButtonsExampleSourceUrl, + ) { + IconButtonSample( + button = { onClick, enabled, icon, contentDescription -> + IconButtonContrast( + onClick = onClick, + enabled = enabled, + icon = icon, + contentDescription = contentDescription, + ) + }, + ) + }, +) + +@Composable +private fun IconButtonSample( + button: @Composable ( + onClick: () -> Unit, + enabled: Boolean, + icon: SparkIcon, + contentDescription: String?, + ) -> Unit, +) { + Column( + verticalArrangement = Arrangement.spacedBy(16.dp), + ) { + val icon = SparkIcons.LikeFill + val contentDescription = "Localized Content Description" + button( + onClick = { }, + enabled = true, + icon = icon, + contentDescription = contentDescription, + ) + button( + onClick = { }, + enabled = false, + icon = icon, + contentDescription = contentDescription, + ) + } +} diff --git a/catalog/src/main/kotlin/com/adevinta/spark/catalog/model/Components.kt b/catalog/src/main/kotlin/com/adevinta/spark/catalog/model/Components.kt index a08559958..f20a2a55c 100644 --- a/catalog/src/main/kotlin/com/adevinta/spark/catalog/model/Components.kt +++ b/catalog/src/main/kotlin/com/adevinta/spark/catalog/model/Components.kt @@ -24,11 +24,13 @@ package com.adevinta.spark.catalog.model import androidx.annotation.StringRes import com.adevinta.spark.catalog.R import com.adevinta.spark.catalog.configurator.samples.buttons.ButtonsConfigurator +import com.adevinta.spark.catalog.configurator.samples.buttons.IconButtonsConfigurator import com.adevinta.spark.catalog.configurator.samples.textfields.TextFieldsConfigurator import com.adevinta.spark.catalog.configurator.samples.toggles.CheckboxConfigurator import com.adevinta.spark.catalog.configurator.samples.toggles.RadioButtonConfigurator import com.adevinta.spark.catalog.configurator.samples.toggles.SwitchConfigurator import com.adevinta.spark.catalog.examples.samples.buttons.ButtonsExamples +import com.adevinta.spark.catalog.examples.samples.buttons.IconButtonsExamples import com.adevinta.spark.catalog.examples.samples.toggles.CheckboxExamples import com.adevinta.spark.catalog.examples.samples.toggles.RadioButtonExamples import com.adevinta.spark.catalog.examples.samples.toggles.SwitchExamples @@ -76,6 +78,18 @@ private val Checkboxes = Component( configurator = CheckboxConfigurator, ) +private val IconButtons = Component( + id = nextId(), + name = "IconButtons", + description = R.string.component_iconbutton_description, + // No buttons icon + guidelinesUrl = "$ComponentGuidelinesUrl/p/2352e9-icon-button/b/32e1a2", + docsUrl = "$PackageSummaryUrl/com.adevinta.spark.components.iconbuttons/index.html", + sourceUrl = "$SparkSourceUrl/kotlin/com/adevinta/components/iconbuttons/IconButton.kt", + examples = IconButtonsExamples, + configurator = IconButtonsConfigurator, +) + private val RadioButtons = Component( id = nextId(), name = "Radio buttons", @@ -116,6 +130,7 @@ private val TextFields = Component( public val Components: List = listOf( Buttons, Checkboxes, + IconButtons, RadioButtons, Switches, TextFields, diff --git a/catalog/src/main/res/values/strings.xml b/catalog/src/main/res/values/strings.xml index 94d60404d..c1311b8a7 100644 --- a/catalog/src/main/res/values/strings.xml +++ b/catalog/src/main/res/values/strings.xml @@ -54,6 +54,8 @@ The input / text-field component allows users to write in the space provided for the content. ⚠️ Theming don’t work on these! These are the previews that the developers have when working on components. They are not exhaustive and are only meant to give you a quick idea of what the component looks like. + + Icon buttons help people take supplementary actions with a single tap. They’re used when a compact button is required, such as in a toolbar or image list. Component used when only one choice may be selected in a series of options. @@ -73,4 +75,4 @@ View developer docs View source code Report an issue - \ No newline at end of file + \ No newline at end of file diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipsdashed_dark.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipsdashed_dark.png index 32eb874d5..691e25570 100644 --- a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipsdashed_dark.png +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipsdashed_dark.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c5096de5824a4aedf4e40eca0e2bc61e5262ad687bee4fd17d9f05e5e0fc29a2 -size 104849 +oid sha256:b5d2dc48ed571956777795e1b60546428a920da32f017d7a4a72fc4299bfb7c6 +size 104952 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipsdashed_light.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipsdashed_light.png index 3c08cef9b..ad7d8f533 100644 --- a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipsdashed_light.png +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipsdashed_light.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e963fc0e8a6392d730f0c90f194ed80792673c8d9cd4fcf5ec0caa275aa30108 -size 100383 +oid sha256:fe7b62638b602b09bd5cd058e59a4af4dde0130f71e8c31c44bbd769904d8267 +size 100515 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipsfilled_dark.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipsfilled_dark.png index 384d27028..edf111267 100644 --- a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipsfilled_dark.png +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipsfilled_dark.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ebc3d99536a0966f039f465fb7af21a1af9603d635724a710f3eb1e7a90e2a4e -size 88399 +oid sha256:68b66c68c0ed66160c8029bedad628ef4577ed01b59d53118c7b2ae7edec3f2a +size 88359 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipsfilled_light.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipsfilled_light.png index 89e81bc52..c4bb65167 100644 --- a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipsfilled_light.png +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipsfilled_light.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b729adbd3bc5860b9980f24be0620772d531699443fc80fa7ee6dc88467205cc -size 90193 +oid sha256:7a3316dbd5a2e2abef843f3cdc4837a5b15c44ccc3787921353af600f7f5855a +size 90151 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipsoutlined_dark.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipsoutlined_dark.png index 5594b2436..fa3406bef 100644 --- a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipsoutlined_dark.png +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipsoutlined_dark.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:119379d412fa6c0fa99cc950016c2a072cd55e6d0eb75b93d41fe652a71b0a71 -size 97720 +oid sha256:be8789abfacdb70480273ad1949d8d1061b8d09fc8ac1a4abbc197dd6052e425 +size 97751 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipsoutlined_light.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipsoutlined_light.png index 47fb6fb7e..9308a37e5 100644 --- a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipsoutlined_light.png +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipsoutlined_light.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:125c586a2f1cac68ea166fde7aa2dea630e5cb296912e41421942983b1bf5103 -size 94153 +oid sha256:11a487e2a34d48504d8b0a68a307a3e1d1b87c39768becc64556a9b79446496c +size 94202 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipstinted_dark.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipstinted_dark.png index be1a0aa09..7474bbe9b 100644 --- a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipstinted_dark.png +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipstinted_dark.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8e081fb3c34f7f9eaaab7fc084cb127afd73ffed0a31747b98229093955ca729 -size 90504 +oid sha256:ce189640f51f452d8c62eb15f592e78e991890c9e566ae0c383cef85bf70a8f8 +size 90484 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipstinted_light.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipstinted_light.png index b1f85b633..6970a1d8b 100644 --- a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipstinted_light.png +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_chips_chipstinted_light.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:11afbff7e06c67abffc93bd4ca01d2ae74eafde28b563d5be035cb99a5164793 -size 85448 +oid sha256:9fca919204b44e50f54fa8f670d00d221b679333334a9527e7a71f2f2a9e74dc +size 85438 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttoncontrastlarge_dark.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttoncontrastlarge_dark.png new file mode 100644 index 000000000..c82c58be8 --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttoncontrastlarge_dark.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74bf3704781def2234ad36e55cc90e2bf585c6a012361ed76007d9695e88ad3e +size 59049 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttoncontrastlarge_light.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttoncontrastlarge_light.png new file mode 100644 index 000000000..eb92b14fa --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttoncontrastlarge_light.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4762f411c3658aa5110aa75be3ae7ca03033bbf70b172e56384411ef8693cf28 +size 57796 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttoncontrastmedium_dark.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttoncontrastmedium_dark.png new file mode 100644 index 000000000..c4831540f --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttoncontrastmedium_dark.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3fbcabf7bb2e243052b63ff6a7da382f5c4c6c4d02909bb923d2cbe56d2cddb9 +size 38678 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttoncontrastmedium_light.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttoncontrastmedium_light.png new file mode 100644 index 000000000..2c7738ae8 --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttoncontrastmedium_light.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:892eda1889a1cac3f5f10be46657317b2dc808b7ee1fafe717bacf7b70f232ff +size 37665 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttoncontrastsmall_dark.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttoncontrastsmall_dark.png new file mode 100644 index 000000000..38ba70f6d --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttoncontrastsmall_dark.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e33eed4d87d7b99a4c659a21de3ded3ed265691ad22eaacf9ef32b45bf81745d +size 38370 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttoncontrastsmall_light.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttoncontrastsmall_light.png new file mode 100644 index 000000000..3964e1247 --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttoncontrastsmall_light.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba5621905b72704d43fee2f73e79be03a7b7b7ee6d3061f445a572dee1f62e5d +size 37294 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonfilledlarge_dark.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonfilledlarge_dark.png new file mode 100644 index 000000000..ece9ce4e6 --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonfilledlarge_dark.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dbf9610e99842732c4fbc16ad63808c912478412bf75c302668669170c919598 +size 98761 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonfilledlarge_light.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonfilledlarge_light.png new file mode 100644 index 000000000..ba31213aa --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonfilledlarge_light.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa4931d5e4cf81ccd05e28964a5f13b8d1933699bbcda7d38b08938ccd534381 +size 99456 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonfilledmedium_dark.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonfilledmedium_dark.png new file mode 100644 index 000000000..5a992f968 --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonfilledmedium_dark.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:554fb5d063a9d413a4c90acf2b2650b2be1983f45f625b784ef17b417d687251 +size 91834 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonfilledmedium_light.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonfilledmedium_light.png new file mode 100644 index 000000000..1609a65f1 --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonfilledmedium_light.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:292aefae7e5bed5627eeef76eba2f3e7e44df2a6ceeec3875a569a207d0dafe3 +size 90548 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonfilledsmall_dark.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonfilledsmall_dark.png new file mode 100644 index 000000000..ffc31f9f8 --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonfilledsmall_dark.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb5ee3afa7166f8354411df04adc933fea3b243b9d728557cc5e6f3e43f9dd6b +size 80174 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonfilledsmall_light.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonfilledsmall_light.png new file mode 100644 index 000000000..1b909e9ca --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonfilledsmall_light.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0abc1c9a86db57dc2cb33041b6cbf007e93ad54b48a8a65266f3f4a38556b32f +size 79907 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonghostlarge_dark.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonghostlarge_dark.png new file mode 100644 index 000000000..7476b7e4f --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonghostlarge_dark.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:17efa594df454cb3de9172b2375d120ff34227355af04c48cff12d0bcf7e3c34 +size 53880 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonghostlarge_light.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonghostlarge_light.png new file mode 100644 index 000000000..c956d30b9 --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonghostlarge_light.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e36730b0964e91d8e1d58741e18d0e935ddbfcad79b73c85ce1ba0900b13274d +size 52819 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonghostmedium_dark.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonghostmedium_dark.png new file mode 100644 index 000000000..27cd98957 --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonghostmedium_dark.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b559aec6a50dc2b84154d09260c86cc9cf385c3cdddaa046eaa89a94d4b4134a +size 33724 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonghostmedium_light.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonghostmedium_light.png new file mode 100644 index 000000000..2b4567019 --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonghostmedium_light.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:19d956594befd633e0ca04b5c499665a0ede38b45d0dbe8ab33065853066cc58 +size 32809 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonghostsmall_dark.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonghostsmall_dark.png new file mode 100644 index 000000000..3c400c9ca --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonghostsmall_dark.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:62287dcc6af84872f5a17a0ac19a618fc687d677df4e4a9e707e214c9e882408 +size 34139 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonghostsmall_light.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonghostsmall_light.png new file mode 100644 index 000000000..e9860e982 --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonghostsmall_light.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a0419d39cd532638ad9fc6d60e694f3c1df6239cabc35d263c453afe7a9c1080 +size 33149 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonoutlinedlarge_dark.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonoutlinedlarge_dark.png new file mode 100644 index 000000000..dd2351563 --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonoutlinedlarge_dark.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ac7370145e9faebd68fcf082d2bb38ca0cec9fab1b1c2cd67620414c4838812a +size 116583 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonoutlinedlarge_light.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonoutlinedlarge_light.png new file mode 100644 index 000000000..32b5ecfa1 --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonoutlinedlarge_light.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:578ec8d1fe1933e8f0b3c44b5948a73b0c3b9833bde62521d1608ca5fa6aa876 +size 113609 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonoutlinedmedium_dark.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonoutlinedmedium_dark.png new file mode 100644 index 000000000..a8f2bb93d --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonoutlinedmedium_dark.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6817fa1e92278779e5e7a9272fdc0b8e2f18809a90e72ddaf64bbd160e0baa7c +size 96867 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonoutlinedmedium_light.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonoutlinedmedium_light.png new file mode 100644 index 000000000..3beffd50b --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonoutlinedmedium_light.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b92ae29aa085c65bd07d52a319101fc758601a836f29cd8c4dafb3d12ee2e047 +size 93387 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonoutlinedsmall_dark.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonoutlinedsmall_dark.png new file mode 100644 index 000000000..5816cc2d4 --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonoutlinedsmall_dark.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:347bef25f87fea53b7def0410596957495775ce5bf2e3b1949c7a83d748a94a9 +size 79878 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonoutlinedsmall_light.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonoutlinedsmall_light.png new file mode 100644 index 000000000..b2d36df77 --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonoutlinedsmall_light.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:de092e590366c9678179ba26c3e2ee304d80229528e757223e368e9e1937a396 +size 77415 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttons_dark.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttons_dark.png new file mode 100644 index 000000000..c24c94bad --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttons_dark.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ac4ab33c332d723386e6051868aed828f4acfc699107915fa46b36e2221b8793 +size 33232 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttons_light.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttons_light.png new file mode 100644 index 000000000..219a1537f --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttons_light.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d6531f0086120c9895a67d12424dbe4841143450aef095b2c4b5d7d2c1f18e9 +size 33548 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttontintedlarge_dark.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttontintedlarge_dark.png new file mode 100644 index 000000000..594032675 --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttontintedlarge_dark.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a1cdd6f1b1108c01482918255ae7746803048752cb0a77d422972b9b2f522a08 +size 96566 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttontintedlarge_light.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttontintedlarge_light.png new file mode 100644 index 000000000..4adbafe62 --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttontintedlarge_light.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:39f4f89445282377a33984611d25a63c05daf330e14413608d8670d6665dc021 +size 91615 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttontintedmedium_dark.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttontintedmedium_dark.png new file mode 100644 index 000000000..5aaa877fd --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttontintedmedium_dark.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fc0253bca24f500757773df65fa1dd4b215c8aaa00c66790a94f7c0d7a3ddd57 +size 76253 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttontintedmedium_light.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttontintedmedium_light.png new file mode 100644 index 000000000..75e365d12 --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttontintedmedium_light.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f0a9e7674cc64242b30fd8eaee85461ca6b3cdf803cd8927789422dfe9d8d244 +size 68960 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttontintedsmall_dark.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttontintedsmall_dark.png new file mode 100644 index 000000000..ffc31f9f8 --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttontintedsmall_dark.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb5ee3afa7166f8354411df04adc933fea3b243b9d728557cc5e6f3e43f9dd6b +size 80174 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttontintedsmall_light.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttontintedsmall_light.png new file mode 100644 index 000000000..1b909e9ca --- /dev/null +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttontintedsmall_light.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0abc1c9a86db57dc2cb33041b6cbf007e93ad54b48a8a65266f3f4a38556b32f +size 79907 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_checkboxlabelled_dark.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_checkboxlabelled_dark.png index 2e88d64d5..4a7654afa 100644 --- a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_checkboxlabelled_dark.png +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_checkboxlabelled_dark.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:031ae17cf1a8d7596175d9c46ac4a2d1d92a2e49bf0fe588d9a089377728da7b -size 59692 +oid sha256:a7ebfd4276848f221bf948a60c107ab5bf1ba765b99d0222bdf16c16d75ae232 +size 65346 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_checkboxlabelled_light.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_checkboxlabelled_light.png index 678ea41a9..140dd0a2e 100644 --- a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_checkboxlabelled_light.png +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_checkboxlabelled_light.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:079abb7e1ce190e9ec488d97f9496c1a656435770eea27d64aaf479d8eabc8cb -size 59164 +oid sha256:f9b37d7b62a312ea4b6385ce4b6a55c7cb60158a7bb2f0710574afe7db84d722 +size 64825 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_labelledslot.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_labelledslot.png index 8893ea8d0..a4b7b8910 100644 --- a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_labelledslot.png +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_labelledslot.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:99e76b3a02257f826db25d0a060f99c1f682ef45e9c1b9a4da8459d9564e9951 -size 7553 +oid sha256:92a63574a589ce42574b0be22542c99434f58e2853139b28fce33a4add52e1d9 +size 7331 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_radiobuttonlabelled_dark.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_radiobuttonlabelled_dark.png index 940685584..fa13cfe25 100644 --- a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_radiobuttonlabelled_dark.png +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_radiobuttonlabelled_dark.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c8ebe352cd736b15f7db8e192204dedf9142dc61f913977dda6264087657775e -size 26947 +oid sha256:74f002a378c3d2ca1bd7fca3bb14afa0e76701426f7945af9f961313f3d2598c +size 26650 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_radiobuttonlabelled_light.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_radiobuttonlabelled_light.png index e7f6b30a7..53cee865e 100644 --- a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_radiobuttonlabelled_light.png +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_radiobuttonlabelled_light.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:94068acf6ce60419f2aa19dcd9db91e38faa1a7ce352dc3336160c0779fd27de -size 26471 +oid sha256:fe3d146fb1d1f7b4385df15763f16a6d8500333af1b6464268c2587ac84977c7 +size 26148 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_switchlabelled_dark.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_switchlabelled_dark.png index 62a20d4a2..9773e3a3b 100644 --- a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_switchlabelled_dark.png +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_switchlabelled_dark.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1ef6743c9a3aa75bd7fcbf9b8d0e7ab62539080a4385d284fb36caf573574cd6 -size 111450 +oid sha256:5de81a2204f1644e58fa1408ea16b5b6dbbc51ad25860215cec487ff0b5337b5 +size 109520 diff --git a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_switchlabelled_light.png b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_switchlabelled_light.png index ba11e4723..fec2f0d39 100644 --- a/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_switchlabelled_light.png +++ b/spark-screenshot-testing/src/test/snapshots/images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_toggles_switchlabelled_light.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f729621b17625b917e3da9eab0a65940773e09545af2c0b8691dd4dede280fe9 -size 109739 +oid sha256:8e41d126c9b9c573b13a2b73a901a69fb13fac8f293c9f9d15524e166e1ddc31 +size 108045 diff --git a/spark/src/main/kotlin/com/adevinta/spark/components/appbar/BottomAppBar.kt b/spark/src/main/kotlin/com/adevinta/spark/components/appbar/BottomAppBar.kt index c9e1e2da5..7e4e4c3bc 100644 --- a/spark/src/main/kotlin/com/adevinta/spark/components/appbar/BottomAppBar.kt +++ b/spark/src/main/kotlin/com/adevinta/spark/components/appbar/BottomAppBar.kt @@ -19,6 +19,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ +@file:Suppress("DEPRECATION") + package com.adevinta.spark.components.appbar import androidx.compose.foundation.layout.PaddingValues diff --git a/spark/src/main/kotlin/com/adevinta/spark/components/dialog/ModalFullScreenScaffold.kt b/spark/src/main/kotlin/com/adevinta/spark/components/dialog/ModalFullScreenScaffold.kt index 3c09a9542..e6964fc76 100644 --- a/spark/src/main/kotlin/com/adevinta/spark/components/dialog/ModalFullScreenScaffold.kt +++ b/spark/src/main/kotlin/com/adevinta/spark/components/dialog/ModalFullScreenScaffold.kt @@ -41,6 +41,7 @@ import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.res.stringResource @@ -55,8 +56,8 @@ import com.adevinta.spark.SparkTheme import com.adevinta.spark.components.appbar.TopAppBar import com.adevinta.spark.components.buttons.ButtonFilled import com.adevinta.spark.components.buttons.ButtonOutlined -import com.adevinta.spark.components.icons.Icon -import com.adevinta.spark.components.icons.IconButton +import com.adevinta.spark.components.iconbuttons.IconButtonColors +import com.adevinta.spark.components.iconbuttons.SparkIconButton import com.adevinta.spark.components.image.Illustration import com.adevinta.spark.components.scaffold.Scaffold import com.adevinta.spark.components.text.Text @@ -66,6 +67,7 @@ import com.adevinta.spark.icons.SparkIcons import com.adevinta.spark.tokens.Layout import com.adevinta.spark.tokens.bodyWidth import com.adevinta.spark.tokens.dim2 +import com.adevinta.spark.tokens.disabled import com.adevinta.spark.tools.preview.DevicePreviews /** @@ -218,13 +220,7 @@ private fun PhonePortraitModalScaffold( topBar = { TopAppBar( navigationIcon = { - IconButton(onClick = onClose) { - Icon( - sparkIcon = SparkIcons.Close, - tint = SparkTheme.colors.onSurface.dim2, - contentDescription = stringResource(id = R.string.spark_a11y_modal_fullscreen_close), - ) - } + CloseIconButton(onClose = onClose) }, title = { }, ) @@ -306,13 +302,7 @@ private fun PhoneLandscapeModalScaffold( topBar = { TopAppBar( navigationIcon = { - IconButton(onClick = onClose) { - Icon( - sparkIcon = SparkIcons.Close, - tint = SparkTheme.colors.onSurface.dim2, - contentDescription = stringResource(id = R.string.spark_a11y_modal_fullscreen_close), - ) - } + CloseIconButton(onClose = onClose) }, title = { }, ) @@ -363,6 +353,27 @@ private fun PhoneLandscapeModalScaffold( } } +@Composable +private fun CloseIconButton( + onClose: () -> Unit, +) { + val contentColor = SparkTheme.colors.onSurface.dim2 + val colors = IconButtonColors( + containerColor = Color.Transparent, + contentColor = contentColor, + disabledContainerColor = Color.Transparent, + disabledContentColor = contentColor.disabled, + ) + SparkIconButton( + icon = SparkIcons.Close, + onClick = onClose, + contentDescription = stringResource( + id = R.string.spark_a11y_modal_fullscreen_close, + ), + colors = colors, + ) +} + private val MinWidth = 280.dp private val MaxWidth = 560.dp @@ -393,6 +404,7 @@ private fun ModalPreview() { ButtonOutlined(modifier = it, onClick = { /*TODO*/ }, text = "Alternative Action") }, reverseButtonOrder = true, + illustrationContentScale = ContentScale.FillWidth, ) { innerPadding -> Text( modifier = Modifier diff --git a/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButton.kt b/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButton.kt new file mode 100644 index 000000000..c119e41ce --- /dev/null +++ b/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButton.kt @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2023 Adevinta + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.adevinta.spark.components.iconbuttons + +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.background +import androidx.compose.foundation.interaction.Interaction +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.size +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.PlainTooltipBox +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.unit.dp +import com.adevinta.spark.InternalSparkApi +import com.adevinta.spark.PreviewTheme +import com.adevinta.spark.SparkTheme +import com.adevinta.spark.components.icons.Icon +import com.adevinta.spark.components.text.Text +import com.adevinta.spark.icons.SparkIcon +import com.adevinta.spark.tools.modifiers.ifTrue +import com.adevinta.spark.tools.modifiers.minimumTouchTargetSize +import com.adevinta.spark.tools.modifiers.sparkUsageOverlay +import com.adevinta.spark.tools.preview.ThemeProvider +import com.adevinta.spark.tools.preview.ThemeVariant + +/** + * Icon buttons help people take supplementary actions with a single tap. They’re used when a + * compact button is required, such as in a toolbar or image list. + * + * @param icon a content to be drawn inside the IconButton + * @param colors [IconButtonColors] that will be used to resolve the colors used for this icon + * button in different states. + * @param onClick called when this icon button is clicked + * @param modifier the [Modifier] to be applied to this icon button + * @param enabled controls the enabled state of this icon button. When `false`, this component will + * not respond to user input, and it will appear visually disabled and disabled to accessibility + * services. + * @param shape to be applied to the IconButton background. It should be one of [IconButtonShape] values + * @param size one of the [IconButtonSize] values that sets width and height of the IconButton + * @param border an optional [BorderStroke] to be applied to the IconButton + * @param contentDescription text used by accessibility services to describe what this icon button + * represents. This text should be localized, such as by using [androidx.compose.ui.res.stringResource] or similar + * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s + * for this icon button. You can create and pass in your own `remember`ed instance to observe + * [Interaction]s and customize the appearance / behavior of this icon button in different states. + */ +@OptIn(ExperimentalMaterial3Api::class) +@InternalSparkApi +@Composable +internal fun SparkIconButton( + icon: SparkIcon, + colors: IconButtonColors, + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + shape: IconButtonShape = IconButtonDefaults.DefaultShape, + size: IconButtonSize = IconButtonDefaults.DefaultSize, + border: BorderStroke? = null, + contentDescription: String? = null, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, +) { + val content: @Composable () -> Unit = { + Icon( + sparkIcon = icon, + contentDescription = contentDescription, + size = size.iconSize, + ) + } + PlainTooltipBox( + tooltip = { Text(contentDescription.orEmpty()) }, + shape = IconButtonDefaults.TooltipContainerShape, + containerColor = IconButtonDefaults.TooltipContainerColor, + contentColor = IconButtonDefaults.TooltipContentColor, + ) { + Surface( + onClick = onClick, + modifier = modifier + .minimumTouchTargetSize() + .tooltipAnchor() + .sparkUsageOverlay(), + enabled = enabled, + shape = shape.shape, + color = colors.containerColor(enabled = enabled).value, + contentColor = colors.contentColor(enabled).value, + border = border, + interactionSource = interactionSource, + ) { + Box( + modifier = Modifier.size(size.height), + contentAlignment = Alignment.Center, + ) { + content() + } + } + } +} + +@Preview( + group = "IconButtons", + name = "IconButtons", +) +@Composable +internal fun IconButtonPreview( + @PreviewParameter(ThemeProvider::class) theme: ThemeVariant, +) { + PreviewTheme(theme) { + val intent = IconButtonIntent.Basic + IconButtonSize.values().forEach { size -> + IconButtonShape.values().forEach { shape -> + IconButtonFilledPair( + intent = intent, + size = size, + shape = shape, + ) + } + } + } +} + +@Composable +internal fun IconButtonPreview( + content: @Composable ( + intent: IconButtonIntent, + shape: IconButtonShape, + ) -> Unit, +) { + IconButtonIntent.values().forEach { intent -> + Row( + modifier = Modifier.ifTrue(intent == IconButtonIntent.Surface) { + background(SparkTheme.colors.neutralContainer) + }, + horizontalArrangement = Arrangement.spacedBy(8.dp), + ) { + IconButtonShape.values().forEach { shape -> + content(intent = intent, shape = shape) + } + } + } +} diff --git a/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonContrast.kt b/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonContrast.kt new file mode 100644 index 000000000..0bc1abe63 --- /dev/null +++ b/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonContrast.kt @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2023 Adevinta + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.adevinta.spark.components.iconbuttons + +import androidx.compose.foundation.interaction.Interaction +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Row +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import com.adevinta.spark.PreviewTheme +import com.adevinta.spark.icons.SparkIcon +import com.adevinta.spark.icons.SparkIcons +import com.adevinta.spark.icons.WheelOutline +import com.adevinta.spark.tools.preview.ThemeProvider +import com.adevinta.spark.tools.preview.ThemeVariant + +/** + * Icon buttons help people take supplementary actions with a single tap. They’re used when a + * compact button is required, such as in a toolbar or image list. + * + * @param icon a content to be drawn inside the IconButton + * @param onClick called when this icon button is clicked + * @param modifier the [Modifier] to be applied to this icon button + * @param intent one of [IconButtonIntent] values that will be used to determine [IconButtonColors] to be applied + * @param enabled controls the enabled state of this icon button. When `false`, this component will + * not respond to user input, and it will appear visually disabled and disabled to accessibility + * services. + * @param shape to be applied to the IconButton background. It should be one of [IconButtonShape] values + * @param size one of the [IconButtonSize] values that sets width and height of the IconButton + * @param contentDescription text used by accessibility services to describe what this icon button + * represents. This text should be localized, such as by using [androidx.compose.ui.res.stringResource] or similar + * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s + * for this icon button. You can create and pass in your own `remember`ed instance to observe + * [Interaction]s and customize the appearance / behavior of this icon button in different states. + */ +@Composable +public fun IconButtonContrast( + icon: SparkIcon, + onClick: () -> Unit, + modifier: Modifier = Modifier, + intent: IconButtonIntent = IconButtonDefaults.DefaultIntent, + enabled: Boolean = true, + shape: IconButtonShape = IconButtonDefaults.DefaultShape, + size: IconButtonSize = IconButtonDefaults.DefaultSize, + contentDescription: String? = null, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, +) { + val colors = IconButtonDefaults.contrastIconButtonColors(intent.colors()) + SparkIconButton( + icon = icon, + onClick = onClick, + modifier = modifier, + colors = colors, + enabled = enabled, + shape = shape, + size = size, + contentDescription = contentDescription, + interactionSource = interactionSource, + ) +} + +@Preview( + group = "IconButtons", + name = "IconButton Contrast Small", +) +@Composable +internal fun IconButtonContrastSmallPreview( + @PreviewParameter(ThemeProvider::class) theme: ThemeVariant, +) { + PreviewTheme(theme) { + IconButtonPreview { intent, shape -> + IconButtonContrastPair( + intent = intent, + size = IconButtonSize.Small, + shape = shape, + ) + } + } +} + +@Preview( + group = "IconButtons", + name = "IconButton Contrast Medium", +) +@Composable +internal fun IconButtonContrastMediumPreview( + @PreviewParameter(ThemeProvider::class) theme: ThemeVariant, +) { + PreviewTheme(theme) { + IconButtonPreview { intent, shape -> + IconButtonContrastPair( + intent = intent, + size = IconButtonSize.Medium, + shape = shape, + ) + } + } +} + +@Preview( + group = "IconButtons", + name = "IconButton Contrast Large", +) +@Composable +internal fun IconButtonContrastLargePreview( + @PreviewParameter(ThemeProvider::class) theme: ThemeVariant, +) { + PreviewTheme(theme) { + IconButtonPreview { intent, shape -> + IconButtonContrastPair( + intent = intent, + size = IconButtonSize.Large, + shape = shape, + ) + } + } +} + +@Composable +internal fun IconButtonContrastPair( + intent: IconButtonIntent, + size: IconButtonSize, + shape: IconButtonShape, +) { + val icon = SparkIcons.WheelOutline + val contentDescription = "Localized description" + Row { + listOf(true, false).forEach { enabled -> + IconButtonContrast( + icon = icon, + onClick = {}, + intent = intent, + enabled = enabled, + contentDescription = contentDescription, + size = size, + shape = shape, + ) + } + } +} diff --git a/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonDefaults.kt b/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonDefaults.kt new file mode 100644 index 000000000..af6b9b8f0 --- /dev/null +++ b/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonDefaults.kt @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2023 Adevinta + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.adevinta.spark.components.iconbuttons + +import androidx.compose.material3.IconButtonDefaults +import androidx.compose.material3.OutlinedIconButton +import androidx.compose.material3.PlainTooltipBox +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable +import androidx.compose.runtime.State +import androidx.compose.runtime.rememberUpdatedState +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.unit.dp +import com.adevinta.spark.SparkTheme +import com.adevinta.spark.components.IntentColor +import com.adevinta.spark.tokens.disabled + +internal object IconButtonDefaults { + + /** + * The outlined icon button's border size + */ + internal val OutlinedBorderSize = 1.dp + + /** + * The default intent of IconButton + */ + internal val DefaultIntent = IconButtonIntent.Main + + /** + * The default size of IconButton + */ + internal val DefaultSize = IconButtonSize.Medium + + /** + * The default shape of IconButton + */ + internal val DefaultShape = IconButtonShape.Large + + /** + * The [Color] for a PlainTooltipBox's container. + */ + internal val TooltipContainerColor @Composable get() = SparkTheme.colors.surfaceInverse + + /** + * The [Color] for the content within the PlainTooltipBox. + */ + internal val TooltipContentColor @Composable get() = SparkTheme.colors.onSurfaceInverse + + /** + * The [Shape] for a [PlainTooltipBox]'s container. + */ + val TooltipContainerShape: Shape + @Composable get() = SparkTheme.shapes.large + + @Composable + fun filledIconButtonColors( + intent: IntentColor, + containerColor: Color = intent.color, + contentColor: Color = intent.onColor, + disabledContainerColor: Color = containerColor.disabled, + disabledContentColor: Color = contentColor.disabled, + ): IconButtonColors = + IconButtonColors( + containerColor = containerColor, + contentColor = contentColor, + disabledContainerColor = disabledContainerColor, + disabledContentColor = disabledContentColor, + ) + + @Composable + fun outlinedIconButtonColors( + intent: IntentColor, + containerColor: Color = Color.Transparent, + contentColor: Color = intent.color, + disabledContainerColor: Color = Color.Transparent, + disabledContentColor: Color = contentColor.disabled, + ): IconButtonColors = + IconButtonColors( + containerColor = containerColor, + contentColor = contentColor, + disabledContainerColor = disabledContainerColor, + disabledContentColor = disabledContentColor, + ) + + @Composable + fun tintedIconButtonColors( + intent: IntentColor, + containerColor: Color = intent.containerColor, + contentColor: Color = intent.onContainerColor, + disabledContainerColor: Color = containerColor.disabled, + disabledContentColor: Color = contentColor.disabled, + ): IconButtonColors = + IconButtonColors( + containerColor = containerColor, + contentColor = contentColor, + disabledContainerColor = disabledContainerColor, + disabledContentColor = disabledContentColor, + ) + + @Composable + fun ghostIconButtonColors( + intent: IntentColor, + containerColor: Color = Color.Transparent, + contentColor: Color = intent.color, + disabledContainerColor: Color = Color.Transparent, + disabledContentColor: Color = contentColor.disabled, + ): IconButtonColors = + IconButtonColors( + containerColor = containerColor, + contentColor = contentColor, + disabledContainerColor = disabledContainerColor, + disabledContentColor = disabledContentColor, + ) + + @Composable + fun contrastIconButtonColors( + intent: IntentColor, + containerColor: Color = SparkTheme.colors.surface, + contentColor: Color = intent.color, + disabledContainerColor: Color = containerColor.disabled, + ): IconButtonColors = with(if (containerColor != contentColor) contentColor else SparkTheme.colors.onSurface) { + IconButtonColors( + containerColor = containerColor, + contentColor = this, + disabledContainerColor = disabledContainerColor, + disabledContentColor = this.disabled, + ) + } +} + +/** + * Represents the container and content colors used in an icon button in different states. + * + * - See [IconButtonDefaults.filledIconButtonColors] and + * [IconButtonDefaults.filledTonalIconButtonColors] for the default colors used in a + * [IconButtonFilled]. + * - See [IconButtonDefaults.outlinedIconButtonColors] for the default colors used in an + * [OutlinedIconButton]. + */ +@Immutable +// FIXME: Copy from MD. Remove once MD version is updated and constructor is no longer internal +internal class IconButtonColors( + private val containerColor: Color, + private val contentColor: Color, + private val disabledContainerColor: Color, + private val disabledContentColor: Color, +) { + /** + * Represents the container color for this icon button, depending on [enabled]. + * + * @param enabled whether the icon button is enabled + */ + @Composable + internal fun containerColor(enabled: Boolean): State { + return rememberUpdatedState(if (enabled) containerColor else disabledContainerColor) + } + + /** + * Represents the content color for this icon button, depending on [enabled]. + * + * @param enabled whether the icon button is enabled + */ + @Composable + internal fun contentColor(enabled: Boolean): State { + return rememberUpdatedState(if (enabled) contentColor else disabledContentColor) + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || other !is IconButtonColors) return false + + if (containerColor != other.containerColor) return false + if (contentColor != other.contentColor) return false + if (disabledContainerColor != other.disabledContainerColor) return false + if (disabledContentColor != other.disabledContentColor) return false + + return true + } + + override fun hashCode(): Int { + var result = containerColor.hashCode() + result = 31 * result + contentColor.hashCode() + result = 31 * result + disabledContainerColor.hashCode() + result = 31 * result + disabledContentColor.hashCode() + + return result + } +} diff --git a/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonFilled.kt b/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonFilled.kt new file mode 100644 index 000000000..78a5286b2 --- /dev/null +++ b/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonFilled.kt @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2023 Adevinta + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.adevinta.spark.components.iconbuttons + +import androidx.compose.foundation.interaction.Interaction +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.unit.dp +import com.adevinta.spark.PreviewTheme +import com.adevinta.spark.icons.SparkIcon +import com.adevinta.spark.icons.SparkIcons +import com.adevinta.spark.icons.WheelOutline +import com.adevinta.spark.tools.preview.ThemeProvider +import com.adevinta.spark.tools.preview.ThemeVariant + +/** + * Icon buttons help people take supplementary actions with a single tap. They’re used when a + * compact button is required, such as in a toolbar or image list. + * + * @param icon a content to be drawn inside the IconButton + * @param onClick called when this icon button is clicked + * @param modifier the [Modifier] to be applied to this icon button + * @param intent one of [IconButtonIntent] values that will be used to determine [IconButtonColors] to be applied + * @param enabled controls the enabled state of this icon button. When `false`, this component will + * not respond to user input, and it will appear visually disabled and disabled to accessibility + * services. + * @param shape to be applied to the IconButton background. It should be one of [IconButtonShape] values + * @param size one of the [IconButtonSize] values that sets width and height of the IconButton + * @param contentDescription text used by accessibility services to describe what this icon button + * represents. This text should be localized, such as by using [androidx.compose.ui.res.stringResource] or similar + * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s + * for this icon button. You can create and pass in your own `remember`ed instance to observe + * [Interaction]s and customize the appearance / behavior of this icon button in different states. + */ +@Composable +public fun IconButtonFilled( + icon: SparkIcon, + onClick: () -> Unit, + modifier: Modifier = Modifier, + intent: IconButtonIntent = IconButtonDefaults.DefaultIntent, + enabled: Boolean = true, + shape: IconButtonShape = IconButtonDefaults.DefaultShape, + size: IconButtonSize = IconButtonDefaults.DefaultSize, + contentDescription: String? = null, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, +) { + val colors = IconButtonDefaults.filledIconButtonColors(intent.colors()) + SparkIconButton( + icon = icon, + onClick = onClick, + modifier = modifier, + colors = colors, + enabled = enabled, + shape = shape, + size = size, + contentDescription = contentDescription, + interactionSource = interactionSource, + ) +} + +@Preview( + group = "IconButtons", + name = "IconButton Filled Small", +) +@Composable +internal fun IconButtonFilledSmallPreview( + @PreviewParameter(ThemeProvider::class) theme: ThemeVariant, +) { + PreviewTheme(theme) { + IconButtonPreview { intent, shape -> + IconButtonFilledPair( + intent = intent, + size = IconButtonSize.Small, + shape = shape, + ) + } + } +} + +@Preview( + group = "IconButtons", + name = "IconButton Filled Medium", +) +@Composable +internal fun IconButtonFilledMediumPreview( + @PreviewParameter(ThemeProvider::class) theme: ThemeVariant, +) { + PreviewTheme(theme) { + IconButtonPreview { intent, shape -> + IconButtonFilledPair( + intent = intent, + size = IconButtonSize.Medium, + shape = shape, + ) + } + } +} + +@Preview( + group = "IconButtons", + name = "IconButton Filled Large", +) +@Composable +internal fun IconButtonFilledLargePreview( + @PreviewParameter(ThemeProvider::class) theme: ThemeVariant, +) { + PreviewTheme(theme) { + IconButtonPreview { intent, shape -> + IconButtonFilledPair( + intent = intent, + size = IconButtonSize.Large, + shape = shape, + ) + } + } +} + +@Composable +internal fun IconButtonFilledPair( + intent: IconButtonIntent, + size: IconButtonSize, + shape: IconButtonShape, +) { + val icon = SparkIcons.WheelOutline + val contentDescription = "Localized description" + Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { + listOf(true, false).forEach { enabled -> + IconButtonFilled( + icon = icon, + onClick = {}, + intent = intent, + enabled = enabled, + contentDescription = contentDescription, + size = size, + shape = shape, + ) + } + } +} diff --git a/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonGhost.kt b/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonGhost.kt new file mode 100644 index 000000000..4e907be7a --- /dev/null +++ b/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonGhost.kt @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2023 Adevinta + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.adevinta.spark.components.iconbuttons + +import androidx.compose.foundation.interaction.Interaction +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Row +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import com.adevinta.spark.PreviewTheme +import com.adevinta.spark.icons.SparkIcon +import com.adevinta.spark.icons.SparkIcons +import com.adevinta.spark.icons.WheelOutline +import com.adevinta.spark.tools.preview.ThemeProvider +import com.adevinta.spark.tools.preview.ThemeVariant + +/** + * Icon buttons help people take supplementary actions with a single tap. They’re used when a + * compact button is required, such as in a toolbar or image list. + * + * @param icon a content to be drawn inside the IconButton + * @param onClick called when this icon button is clicked + * @param modifier the [Modifier] to be applied to this icon button + * @param intent one of [IconButtonIntent] values that will be used to determine [IconButtonColors] to be applied + * @param enabled controls the enabled state of this icon button. When `false`, this component will + * not respond to user input, and it will appear visually disabled and disabled to accessibility + * services. + * @param shape to be applied to the IconButton background. It should be one of [IconButtonShape] values + * @param size one of the [IconButtonSize] values that sets width and height of the IconButton + * @param contentDescription text used by accessibility services to describe what this icon button + * represents. This text should be localized, such as by using [androidx.compose.ui.res.stringResource] or similar + * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s + * for this icon button. You can create and pass in your own `remember`ed instance to observe + * [Interaction]s and customize the appearance / behavior of this icon button in different states. + */ +@Composable +public fun IconButtonGhost( + icon: SparkIcon, + onClick: () -> Unit, + modifier: Modifier = Modifier, + intent: IconButtonIntent = IconButtonDefaults.DefaultIntent, + enabled: Boolean = true, + shape: IconButtonShape = IconButtonDefaults.DefaultShape, + size: IconButtonSize = IconButtonDefaults.DefaultSize, + contentDescription: String? = null, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, +) { + val colors = IconButtonDefaults.ghostIconButtonColors(intent.colors()) + SparkIconButton( + icon = icon, + onClick = onClick, + modifier = modifier, + colors = colors, + enabled = enabled, + shape = shape, + size = size, + contentDescription = contentDescription, + interactionSource = interactionSource, + ) +} + +@Preview( + group = "IconButtons", + name = "IconButton Ghost Small", +) +@Composable +internal fun IconButtonGhostSmallPreview( + @PreviewParameter(ThemeProvider::class) theme: ThemeVariant, +) { + PreviewTheme(theme) { + IconButtonPreview { intent, shape -> + IconButtonGhostPair( + intent = intent, + size = IconButtonSize.Small, + shape = shape, + ) + } + } +} + +@Preview( + group = "IconButtons", + name = "IconButton Ghost Medium", +) +@Composable +internal fun IconButtonGhostMediumPreview( + @PreviewParameter(ThemeProvider::class) theme: ThemeVariant, +) { + PreviewTheme(theme) { + IconButtonPreview { intent, shape -> + IconButtonGhostPair( + intent = intent, + size = IconButtonSize.Medium, + shape = shape, + ) + } + } +} + +@Preview( + group = "IconButtons", + name = "IconButton Ghost Large", +) +@Composable +internal fun IconButtonGhostLargePreview( + @PreviewParameter(ThemeProvider::class) theme: ThemeVariant, +) { + PreviewTheme(theme) { + IconButtonPreview { intent, shape -> + IconButtonGhostPair( + intent = intent, + size = IconButtonSize.Large, + shape = shape, + ) + } + } +} + +@Composable +internal fun IconButtonGhostPair( + intent: IconButtonIntent, + size: IconButtonSize, + shape: IconButtonShape, +) { + val icon = SparkIcons.WheelOutline + val contentDescription = "Localized description" + Row { + listOf(true, false).forEach { enabled -> + IconButtonGhost( + icon = icon, + onClick = {}, + intent = intent, + enabled = enabled, + contentDescription = contentDescription, + size = size, + shape = shape, + ) + } + } +} diff --git a/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonIntent.kt b/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonIntent.kt new file mode 100644 index 000000000..53bb7d9bc --- /dev/null +++ b/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonIntent.kt @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2023 Adevinta + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.adevinta.spark.components.iconbuttons + +import androidx.compose.runtime.Composable +import com.adevinta.spark.components.IntentColor +import com.adevinta.spark.components.IntentColors + +/** + * IconButtonIntent is used to define the intent of the icon buttons. + */ +public enum class IconButtonIntent { + /** + * Used to match default color of such UI controls as toggles, Slider, etc. + */ + Basic { + @Composable + override fun colors(): IntentColor = IntentColors.Basic.colors() + }, + + /** + * Used to make button visually accentuated. + */ + Accent { + @Composable + override fun colors(): IntentColor = IntentColors.Accent.colors() + }, + + /** + * Main buttons are used for the most important actions. + */ + Main { + @Composable + override fun colors(): IntentColor = IntentColors.Main.colors() + }, + + /** + * Support buttons are used to highlight/accentuate actions. + */ + Support { + @Composable + override fun colors(): IntentColor = IntentColors.Support.colors() + }, + + /** + * Actions on a color / image panel without on intent color. + */ + Surface { + @Composable + override fun colors(): IntentColor = IntentColors.Surface.colors() + }, + + /** + * Used for confirmation actions. + */ + Success { + @Composable + override fun colors(): IntentColor = IntentColors.Success.colors() + }, + + /** + * Used for warning actions. + */ + Alert { + @Composable + override fun colors(): IntentColor = IntentColors.Alert.colors() + }, + + /** + * Used for risky actions. + */ + Danger { + @Composable + override fun colors(): IntentColor = IntentColors.Danger.colors() + }, + + /** + * Used for low or irrelevant actions. + */ + Neutral { + @Composable + override fun colors(): IntentColor = IntentColors.Neutral.colors() + }, + ; + + @Composable + internal abstract fun colors(): IntentColor +} diff --git a/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonOutlined.kt b/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonOutlined.kt new file mode 100644 index 000000000..4546ce3ef --- /dev/null +++ b/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonOutlined.kt @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2023 Adevinta + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.adevinta.spark.components.iconbuttons + +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.interaction.Interaction +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Row +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import com.adevinta.spark.PreviewTheme +import com.adevinta.spark.icons.SparkIcon +import com.adevinta.spark.icons.SparkIcons +import com.adevinta.spark.icons.WheelOutline +import com.adevinta.spark.tools.preview.ThemeProvider +import com.adevinta.spark.tools.preview.ThemeVariant + +/** + * Icon buttons help people take supplementary actions with a single tap. They’re used when a + * compact button is required, such as in a toolbar or image list. + * + * @param icon a content to be drawn inside the IconButton + * @param onClick called when this icon button is clicked + * @param modifier the [Modifier] to be applied to this icon button + * @param intent one of [IconButtonIntent] values that will be used to determine [IconButtonColors] to be applied + * @param enabled controls the enabled state of this icon button. When `false`, this component will + * not respond to user input, and it will appear visually disabled and disabled to accessibility + * services. + * @param shape to be applied to the IconButton background. It should be one of [IconButtonShape] values + * @param size one of the [IconButtonSize] values that sets width and height of the IconButton + * @param contentDescription text used by accessibility services to describe what this icon button + * represents. This text should be localized, such as by using [androidx.compose.ui.res.stringResource] or similar + * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s + * for this icon button. You can create and pass in your own `remember`ed instance to observe + * [Interaction]s and customize the appearance / behavior of this icon button in different states. + */ +@Composable +public fun IconButtonOutlined( + icon: SparkIcon, + onClick: () -> Unit, + modifier: Modifier = Modifier, + intent: IconButtonIntent = IconButtonDefaults.DefaultIntent, + enabled: Boolean = true, + shape: IconButtonShape = IconButtonDefaults.DefaultShape, + size: IconButtonSize = IconButtonDefaults.DefaultSize, + contentDescription: String? = null, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, +) { + val colors = IconButtonDefaults.outlinedIconButtonColors(intent = intent.colors()) + SparkIconButton( + icon = icon, + onClick = onClick, + modifier = modifier, + colors = colors, + enabled = enabled, + shape = shape, + size = size, + border = BorderStroke( + width = IconButtonDefaults.OutlinedBorderSize, + color = colors.contentColor(enabled = enabled).value, + ), + contentDescription = contentDescription, + interactionSource = interactionSource, + ) +} + +@Preview( + group = "IconButtons", + name = "IconButton Outlined Small", +) +@Composable +internal fun IconButtonOutlinedSmallPreview( + @PreviewParameter(ThemeProvider::class) theme: ThemeVariant, +) { + PreviewTheme(theme) { + IconButtonPreview { intent, shape -> + IconButtonOutlinedPair( + intent = intent, + size = IconButtonSize.Small, + shape = shape, + ) + } + } +} + +@Preview( + group = "IconButtons", + name = "IconButton Outlined Medium", +) +@Composable +internal fun IconButtonOutlinedMediumPreview( + @PreviewParameter(ThemeProvider::class) theme: ThemeVariant, +) { + PreviewTheme(theme) { + IconButtonPreview { intent, shape -> + IconButtonOutlinedPair( + intent = intent, + size = IconButtonSize.Medium, + shape = shape, + ) + } + } +} + +@Preview( + group = "IconButtons", + name = "IconButton Outlined Large", +) +@Composable +internal fun IconButtonOutlinedLargePreview( + @PreviewParameter(ThemeProvider::class) theme: ThemeVariant, +) { + PreviewTheme(theme) { + IconButtonPreview { intent, shape -> + IconButtonOutlinedPair( + intent = intent, + size = IconButtonSize.Large, + shape = shape, + ) + } + } +} + +@Composable +internal fun IconButtonOutlinedPair( + intent: IconButtonIntent, + size: IconButtonSize, + shape: IconButtonShape, +) { + val icon = SparkIcons.WheelOutline + val contentDescription = "Localized description" + Row { + listOf(true, false).forEach { enabled -> + IconButtonOutlined( + icon = icon, + onClick = {}, + intent = intent, + enabled = enabled, + contentDescription = contentDescription, + size = size, + shape = shape, + ) + } + } +} diff --git a/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonShape.kt b/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonShape.kt new file mode 100644 index 000000000..0de35d34d --- /dev/null +++ b/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonShape.kt @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2023 Adevinta + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.adevinta.spark.components.iconbuttons + +import androidx.compose.foundation.shape.CornerBasedShape +import androidx.compose.runtime.Composable +import com.adevinta.spark.SparkTheme + +public enum class IconButtonShape { + /** + * Small button with min touch size still applied + */ + None { + override val shape: CornerBasedShape + @Composable + get() = SparkTheme.shapes.none + }, + + /** + * Medium button is the default button size (recommended). + */ + Full { + override val shape: CornerBasedShape + @Composable + get() = SparkTheme.shapes.full + }, + + /** + * Alternative large icon button size to give more emphasis to the action + */ + Large { + override val shape: CornerBasedShape + @Composable + get() = SparkTheme.shapes.large + }, + ; + + internal abstract val shape: CornerBasedShape + @Composable get +} diff --git a/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonSize.kt b/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonSize.kt new file mode 100644 index 000000000..d873f7356 --- /dev/null +++ b/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonSize.kt @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2023 Adevinta + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.adevinta.spark.components.iconbuttons + +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.adevinta.spark.components.icons.IconSize + +public enum class IconButtonSize { + /** + * Small button with min touch size still applied + */ + Small { + override val height: Dp = 32.dp + override val iconSize: IconSize = IconSize.Small + }, + + /** + * Medium button is the default button size (recommended). + */ + Medium { + override val height: Dp = 44.dp + override val iconSize: IconSize = IconSize.Small + }, + + /** + * Alternative large icon button size to give more emphasis to the action + */ + Large { + override val height: Dp = 56.dp + override val iconSize: IconSize = IconSize.Medium + }, + ; + + internal abstract val height: Dp + internal abstract val iconSize: IconSize +} diff --git a/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonTinted.kt b/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonTinted.kt new file mode 100644 index 000000000..547257918 --- /dev/null +++ b/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtonTinted.kt @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2023 Adevinta + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.adevinta.spark.components.iconbuttons + +import androidx.compose.foundation.interaction.Interaction +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Row +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import com.adevinta.spark.PreviewTheme +import com.adevinta.spark.icons.SparkIcon +import com.adevinta.spark.icons.SparkIcons +import com.adevinta.spark.icons.WheelOutline +import com.adevinta.spark.tools.preview.ThemeProvider +import com.adevinta.spark.tools.preview.ThemeVariant + +/** + * Icon buttons help people take supplementary actions with a single tap. They’re used when a + * compact button is required, such as in a toolbar or image list. + * + * @param icon a content to be drawn inside the IconButton + * @param onClick called when this icon button is clicked + * @param modifier the [Modifier] to be applied to this icon button + * @param intent one of [IconButtonIntent] values that will be used to determine [IconButtonColors] to be applied + * @param enabled controls the enabled state of this icon button. When `false`, this component will + * not respond to user input, and it will appear visually disabled and disabled to accessibility + * services. + * @param shape to be applied to the IconButton background. It should be one of [IconButtonShape] values + * @param size one of the [IconButtonSize] values that sets width and height of the IconButton + * @param contentDescription text used by accessibility services to describe what this icon button + * represents. This text should be localized, such as by using [androidx.compose.ui.res.stringResource] or similar + * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s + * for this icon button. You can create and pass in your own `remember`ed instance to observe + * [Interaction]s and customize the appearance / behavior of this icon button in different states. + */ +@Composable +public fun IconButtonTinted( + icon: SparkIcon, + onClick: () -> Unit, + modifier: Modifier = Modifier, + intent: IconButtonIntent = IconButtonDefaults.DefaultIntent, + enabled: Boolean = true, + shape: IconButtonShape = IconButtonDefaults.DefaultShape, + size: IconButtonSize = IconButtonDefaults.DefaultSize, + contentDescription: String? = null, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, +) { + val colors = IconButtonDefaults.tintedIconButtonColors(intent.colors()) + SparkIconButton( + icon = icon, + onClick = onClick, + modifier = modifier, + colors = colors, + enabled = enabled, + shape = shape, + size = size, + contentDescription = contentDescription, + interactionSource = interactionSource, + ) +} + +@Preview( + group = "IconButtons", + name = "IconButton Tinted Small", +) +@Composable +internal fun IconButtonTintedSmallPreview( + @PreviewParameter(ThemeProvider::class) theme: ThemeVariant, +) { + PreviewTheme(theme) { + IconButtonPreview { intent, shape -> + IconButtonFilledPair( + intent = intent, + size = IconButtonSize.Small, + shape = shape, + ) + } + } +} + +@Preview( + group = "IconButtons", + name = "IconButton Tinted Medium", +) +@Composable +internal fun IconButtonTintedMediumPreview( + @PreviewParameter(ThemeProvider::class) theme: ThemeVariant, +) { + PreviewTheme(theme) { + IconButtonPreview { intent, shape -> + IconButtonTintedPair( + intent = intent, + size = IconButtonSize.Medium, + shape = shape, + ) + } + } +} + +@Preview( + group = "IconButtons", + name = "IconButton Tinted Large", +) +@Composable +internal fun IconButtonTintedLargePreview( + @PreviewParameter(ThemeProvider::class) theme: ThemeVariant, +) { + PreviewTheme(theme) { + IconButtonPreview { intent, shape -> + IconButtonTintedPair( + intent = intent, + size = IconButtonSize.Large, + shape = shape, + ) + } + } +} + +@Composable +internal fun IconButtonTintedPair( + intent: IconButtonIntent, + size: IconButtonSize, + shape: IconButtonShape, +) { + val icon = SparkIcons.WheelOutline + val contentDescription = "Localized description" + Row { + listOf(true, false).forEach { enabled -> + IconButtonTinted( + icon = icon, + onClick = {}, + intent = intent, + enabled = enabled, + contentDescription = contentDescription, + size = size, + shape = shape, + ) + } + } +} diff --git a/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtons.md b/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtons.md new file mode 100644 index 000000000..5e988d8be --- /dev/null +++ b/spark/src/main/kotlin/com/adevinta/spark/components/iconbuttons/IconButtons.md @@ -0,0 +1,143 @@ +# Package com.adevinta.spark.components.buttons + +[IconButtons](https://spark.adevinta.com/1186e1705/p/2352e9-icon-button/b/32e1a2) take supplementary +actions with a single tap. They’re used when a compact button is required, such as in a toolbar or +image list. + +### Styles + +Icon buttons come in various styles: + +- Filled +- Tinted +- Outlined +- Contrast +- Ghost + +| | Filled | Outlined | Tinted | Ghost | Contrast | +|-------|------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------| +| Light | ![](../../images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonfilledmedium_light.png) | ![](../../images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonoutlinedmedium_light.png) | ![](../../images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttontintedmedium_light.png) | ![](../../images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonghostmedium_light.png) | ![](../../images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttoncontrastmedium_light.png) | +| Dark | ![](../../images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonfilledmedium_dark.png) | ![](../../images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonoutlinedmedium_dark.png) | ![](../../images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttontintedmedium_dark.png) | ![](../../images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonghostmedium_dark.png) | ![](../../images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttoncontrastmedium_dark.png) | + +### Sizes + +Icon buttons come in 3 sizes [IconButtonSize](IconButtonSize.kt): + +- small - 32.dp (however, the minimum touch size is applied and is 44.dp) +- medium - 44.dp (default) +- large - 56.dp + +The content icon is 16.dp for `IconButtonSize.Small` and `IconButtonSize.Medium`, and 24.dp +for `IconButtonSize.Large` +![](../../images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttons_light.png) + +### Shapes +Icon buttons come in 3 shapes [IconButtonShape](IconButtonShape.kt) : +- None +- Full (default) +- Large + +The buttons have an loading state that can be used to indicate that the button is loading some +data and show/hide an indeterminate circular progress indicator on the start of the button. + +![](../../images/loading-button.gif) + +### Intents + +Icon Buttons support all intents: +- Basic (default) +- Accent +- Main +- Support +- Success +- Alert +- Danger +- Info +- Neutral +- Surface + +#### IconButtonFilled + +Filled icon buttons are the standard for most use cases. The filled styling places the most +emphasis and should be used for important actions. + +```kotlin +fun IconButtonFilled( + icon: SparkIcon, + onClick: () -> Unit, +) +``` + +| Light | Dark | +|------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------| +| ![](../../images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonfilledmedium_light.png) | ![](../../images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonfilledmedium_dark.png) | + +#### IconButtonOutlined + +Outlined icon buttons are used for support actions. The outlined styling places less emphasis on these +actions that are important but not the main ones. + +Be aware that it's not advised to use it on top of images since it will be hard to see. + +```kotlin +fun IconButtonOutlined( + icon: SparkIcon, + onClick: () -> Unit, +) +``` + +| Light | Dark | +|--------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------| +| ![](../../images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonoutlinedmedium_light.png) | ![](../../images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonoutlinedmedium_dark.png) | + +#### IconButtonTinted + +Tinted icon buttons are medium-emphasis buttons that is an alternative middle ground between +default filled icon buttons and outlined icon buttons. They can be used in contexts where lower-priority +icon button requires slightly more emphasis than an outline would give. + +```kotlin +fun IconButtonTinted( + icon: SparkIcon, + onClick: () -> Unit, +) +``` + +| Light | Dark | +|------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------| +| ![](../../images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttontintedmedium_light.png) | ![](../../images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttontintedmedium_dark.png) | + +#### IconButtonGhost + +Ghost icon buttons are used for the lowest priority actions, especially when presenting multiple options. + +Ghost icon buttons can be placed on a variety of backgrounds. Until the button is interacted with, its +container isn’t visible. +This button style is often used inside other components like snackbars, dialogs, and cards. + +```kotlin +fun IconButtonGhost( + icon: SparkIcon, + onClick: () -> Unit, +) +``` + +| Light | Dark | +|-----------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------| +| ![](../../images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonghostmedium_light.png) | ![](../../images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttonghostmedium_dark.png) | + +#### IconButtonContrast + +Contrast icon buttons are used for the high to mid priority actions when the background is dark like on +an image or a video. + +```kotlin +fun IconButtonContrast( + icon: SparkIcon, + onClick: () -> Unit, +) +``` + +| Light | Dark | +|--------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------| +| ![](../../images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttoncontrastmedium_light.png) | ![](../../images/com.adevinta.spark_PreviewScreenshotTests_preview_tests_iconbuttons_iconbuttoncontrastmedium_dark.png) | diff --git a/spark/src/main/kotlin/com/adevinta/spark/components/icons/IconButton.kt b/spark/src/main/kotlin/com/adevinta/spark/components/icons/IconButton.kt index 2a098fb2e..4cc417061 100644 --- a/spark/src/main/kotlin/com/adevinta/spark/components/icons/IconButton.kt +++ b/spark/src/main/kotlin/com/adevinta/spark/components/icons/IconButton.kt @@ -29,20 +29,12 @@ import androidx.compose.material3.Icon import androidx.compose.material3.IconButtonColors import androidx.compose.material3.IconButtonDefaults import androidx.compose.material3.OutlinedIconButton -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Shape -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.tooling.preview.PreviewParameter import com.adevinta.spark.ExperimentalSparkApi -import com.adevinta.spark.PreviewTheme import com.adevinta.spark.SparkTheme -import com.adevinta.spark.icons.SparkIcons -import com.adevinta.spark.icons.WheelOutline -import com.adevinta.spark.tools.preview.ThemeProvider -import com.adevinta.spark.tools.preview.ThemeVariant import androidx.compose.material3.FilledIconButton as MaterialFilledIconButton import androidx.compose.material3.FilledTonalIconButton as MaterialFilledTonalIconButton import androidx.compose.material3.IconButton as MaterialIconButton @@ -74,6 +66,13 @@ import androidx.compose.material3.OutlinedIconButton as MaterialOutlinedIconButt * @param content the content of this icon button, typically an [Icon] */ @Composable +@Deprecated( + "Use styled icon button like from iconbuttons package", + replaceWith = ReplaceWith( + "IconButtonGhost(icon = icon, onClick = onClick, contentDescription = contentDescription)", + imports = arrayOf("com.adevinta.spark.components.iconbuttons.IconButtonGhost"), + ), +) public fun IconButton( onClick: () -> Unit, modifier: Modifier = Modifier, @@ -118,6 +117,13 @@ public fun IconButton( * [Interaction]s and customize the appearance / behavior of this icon button in different states. * @param content the content of this icon button, typically an [Icon] */ +@Deprecated( + "Use styled icon button like from iconbuttons package", + replaceWith = ReplaceWith( + "IconButtonFilled(icon = icon, onClick = onClick)", + imports = arrayOf("com.adevinta.spark.components.iconbuttons.IconButtonFilled"), + ), +) @ExperimentalSparkApi @Composable public fun FilledIconButton( @@ -171,6 +177,13 @@ public fun FilledIconButton( * [Interaction]s and customize the appearance / behavior of this icon button in different states. * @param content the content of this icon button, typically an [Icon] */ +@Deprecated( + "Use styled icon button from iconbuttons package", + replaceWith = ReplaceWith( + "IconButtonTinted(icon = icon, onClick = onClick)", + imports = arrayOf("com.adevinta.spark.components.iconbuttons.IconButtonTinted"), + ), +) @ExperimentalSparkApi @Composable public fun FilledTonalIconButton( @@ -230,6 +243,13 @@ public fun FilledTonalIconButton( * [Interaction]s and customize the appearance / behavior of this icon button in different states. * @param content the content of this icon button, typically an [Icon] */ +@Deprecated( + "Use styled icon button from iconbuttons package", + replaceWith = ReplaceWith( + "IconButtonOutlined(icon = icon, onClick = onClick)", + imports = arrayOf("com.adevinta.spark.components.iconbuttons.IconButtonOutlined"), + ), +) @ExperimentalSparkApi @Composable public fun OutlinedIconButton( @@ -253,37 +273,3 @@ public fun OutlinedIconButton( content = content, ) } - -@Preview( - group = "Icons", - name = "IconButtons", -) -@Composable -internal fun IconButtonPreview( - @PreviewParameter(ThemeProvider::class) theme: ThemeVariant, -) { - PreviewTheme(theme) { - val icon = SparkIcons.WheelOutline - val contentDescription = "Localized description" - - Text("IconButton") - IconButton(onClick = { /* doSomething() */ }) { - Icon(icon, contentDescription = contentDescription) - } - - Text("FilledIconButton") - FilledIconButton(onClick = { /* doSomething() */ }) { - Icon(icon, contentDescription = contentDescription) - } - - Text("FilledTonalIconButton") - FilledTonalIconButton(onClick = { /* doSomething() */ }) { - Icon(icon, contentDescription = contentDescription) - } - - Text("OutlinedIconButton") - OutlinedIconButton(onClick = { /* doSomething() */ }) { - Icon(icon, contentDescription = contentDescription) - } - } -} diff --git a/spark/src/main/kotlin/com/adevinta/spark/components/menu/DropdownMenu.kt b/spark/src/main/kotlin/com/adevinta/spark/components/menu/DropdownMenu.kt index d060e4096..63f5b0a79 100644 --- a/spark/src/main/kotlin/com/adevinta/spark/components/menu/DropdownMenu.kt +++ b/spark/src/main/kotlin/com/adevinta/spark/components/menu/DropdownMenu.kt @@ -19,6 +19,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ +@file:Suppress("DEPRECATION") + package com.adevinta.spark.components.menu import androidx.compose.foundation.interaction.Interaction diff --git a/spark/src/main/kotlin/com/adevinta/spark/components/scaffold/Scaffold.kt b/spark/src/main/kotlin/com/adevinta/spark/components/scaffold/Scaffold.kt index a2ff180b1..2b5181954 100644 --- a/spark/src/main/kotlin/com/adevinta/spark/components/scaffold/Scaffold.kt +++ b/spark/src/main/kotlin/com/adevinta/spark/components/scaffold/Scaffold.kt @@ -20,6 +20,7 @@ * SOFTWARE. */ @file:OptIn(ExperimentalMaterial3Api::class) +@file:Suppress("DEPRECATION") package com.adevinta.spark.components.scaffold diff --git a/spark/src/main/kotlin/com/adevinta/spark/components/textfields/SelectTextField.kt b/spark/src/main/kotlin/com/adevinta/spark/components/textfields/SelectTextField.kt index 0c2354928..307a25cfe 100644 --- a/spark/src/main/kotlin/com/adevinta/spark/components/textfields/SelectTextField.kt +++ b/spark/src/main/kotlin/com/adevinta/spark/components/textfields/SelectTextField.kt @@ -19,6 +19,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ +@file:Suppress("DEPRECATION") + package com.adevinta.spark.components.textfields import androidx.compose.foundation.interaction.FocusInteraction diff --git a/spark/src/main/kotlin/com/adevinta/spark/tools/modifiers/TouchTarget.kt b/spark/src/main/kotlin/com/adevinta/spark/tools/modifiers/TouchTarget.kt index 4dc5f61c1..7abac1d08 100644 --- a/spark/src/main/kotlin/com/adevinta/spark/tools/modifiers/TouchTarget.kt +++ b/spark/src/main/kotlin/com/adevinta/spark/tools/modifiers/TouchTarget.kt @@ -61,7 +61,7 @@ private class MinimumTouchTargetModifier : ModifierNodeElement