diff --git a/catalog/src/main/kotlin/com/adevinta/spark/catalog/configurator/ComponentsScreen.kt b/catalog/src/main/kotlin/com/adevinta/spark/catalog/configurator/ComponentsScreen.kt index 3895672c0..eeaa469d3 100644 --- a/catalog/src/main/kotlin/com/adevinta/spark/catalog/configurator/ComponentsScreen.kt +++ b/catalog/src/main/kotlin/com/adevinta/spark/catalog/configurator/ComponentsScreen.kt @@ -45,7 +45,7 @@ import androidx.navigation.compose.NavHost import androidx.navigation.compose.rememberNavController import com.adevinta.spark.SparkTheme import com.adevinta.spark.catalog.R -import com.adevinta.spark.catalog.configurator.component.ConfiguratorComponentComponentItem +import com.adevinta.spark.catalog.examples.component.ComponentItem import com.adevinta.spark.catalog.model.Component import com.adevinta.spark.components.text.Text import com.adevinta.spark.tokens.Layout @@ -126,11 +126,15 @@ internal fun ComponentsListScreen( span = { GridItemSpan(1) }, contentType = { ComponentsItemType.Component }, itemContent = { component -> - ConfiguratorComponentComponentItem(component = component) { - val componentId = component.id - val route = "$ConfiguratorRoute/$componentId" - navController.navigate(route) - } + ComponentItem( + component = component, + showExampleCount = false, + onClick = { + val componentId = component.id + val route = "$ConfiguratorRoute/$componentId" + navController.navigate(route) + }, + ) }, ) } diff --git a/catalog/src/main/kotlin/com/adevinta/spark/catalog/configurator/Navigation.kt b/catalog/src/main/kotlin/com/adevinta/spark/catalog/configurator/Navigation.kt index 44a04da0e..91e553e4f 100644 --- a/catalog/src/main/kotlin/com/adevinta/spark/catalog/configurator/Navigation.kt +++ b/catalog/src/main/kotlin/com/adevinta/spark/catalog/configurator/Navigation.kt @@ -28,7 +28,6 @@ import androidx.navigation.NavType import androidx.navigation.compose.composable import androidx.navigation.navArgument import com.adevinta.spark.catalog.configurator.component.ConfiguratorComponentScreen -import com.adevinta.spark.catalog.examples.component.Component import com.adevinta.spark.catalog.model.Component internal fun NavGraphBuilder.navGraph( 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 55e0e8744..28e057312 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 @@ -159,6 +159,6 @@ private fun ConfiguratorComponentMenuPreview() { .fillMaxSize() .wrapContentSize(Alignment.Center), ) { - ConfiguratorComponentMenu(Components.first(), true, {}) + ConfiguratorComponentMenu(Components.first(), true) {} } } diff --git a/catalog/src/main/kotlin/com/adevinta/spark/catalog/configurator/component/ComponentItem.kt b/catalog/src/main/kotlin/com/adevinta/spark/catalog/configurator/component/ComponentItem.kt deleted file mode 100644 index 5aa0d6320..000000000 --- a/catalog/src/main/kotlin/com/adevinta/spark/catalog/configurator/component/ComponentItem.kt +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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.component - -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.OutlinedCard -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import com.adevinta.spark.catalog.model.Component - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -public fun ConfiguratorComponentComponentItem( - component: Component, - onClick: (component: Component) -> Unit, -) { - OutlinedCard( - onClick = { onClick(component) }, - modifier = Modifier - .height(ComponentItemHeight) - .padding(ComponentItemOuterPadding), - ) { - Box( - modifier = Modifier - .fillMaxSize() - .padding(ComponentItemInnerPadding), - ) { - Text( - text = component.name, - modifier = Modifier.align(Alignment.BottomStart), - style = MaterialTheme.typography.bodySmall, - ) - } - } -} - -private val ComponentItemHeight = 180.dp -private val ComponentItemOuterPadding = 4.dp -private val ComponentItemInnerPadding = 16.dp diff --git a/catalog/src/main/kotlin/com/adevinta/spark/catalog/configurator/samples/buttons/IconToggleButtonsConfigurator.kt b/catalog/src/main/kotlin/com/adevinta/spark/catalog/configurator/samples/buttons/IconToggleButtonsConfigurator.kt index 791eac94a..a7a596a8a 100644 --- a/catalog/src/main/kotlin/com/adevinta/spark/catalog/configurator/samples/buttons/IconToggleButtonsConfigurator.kt +++ b/catalog/src/main/kotlin/com/adevinta/spark/catalog/configurator/samples/buttons/IconToggleButtonsConfigurator.kt @@ -83,7 +83,7 @@ private fun IconToggleButtonSample() { var shape by remember { mutableStateOf(IconButtonShape.Large) } var size by remember { mutableStateOf(IconButtonSize.Medium) } var intent by remember { mutableStateOf(IconButtonIntent.Main) } - var icons by remember { mutableStateOf(IconToggleButtonIcons(SparkIcons.CarOutline, SparkIcons.CarFill)) } + val icons by remember { mutableStateOf(IconToggleButtonIcons(SparkIcons.CarOutline, SparkIcons.CarFill)) } var contentDescription by remember { mutableStateOf("Content Description") } ConfigedIconToggleButton( diff --git a/catalog/src/main/kotlin/com/adevinta/spark/catalog/configurator/samples/textfields/TextFieldsConfigurator.kt b/catalog/src/main/kotlin/com/adevinta/spark/catalog/configurator/samples/textfields/TextFieldsConfigurator.kt index 7b8ae7878..562464717 100644 --- a/catalog/src/main/kotlin/com/adevinta/spark/catalog/configurator/samples/textfields/TextFieldsConfigurator.kt +++ b/catalog/src/main/kotlin/com/adevinta/spark/catalog/configurator/samples/textfields/TextFieldsConfigurator.kt @@ -210,7 +210,7 @@ private fun TextFieldSample() { modifier = Modifier.fillMaxWidth(), value = addonText ?: "", onValueChange = { - addonText = if (it.isBlank()) null else it + addonText = it.ifBlank { null } }, label = "Prefix", placeholder = "State message of the TextField", diff --git a/catalog/src/main/kotlin/com/adevinta/spark/catalog/examples/ComponentsScreen.kt b/catalog/src/main/kotlin/com/adevinta/spark/catalog/examples/ComponentsScreen.kt index 68f40e3e8..400846f0c 100644 --- a/catalog/src/main/kotlin/com/adevinta/spark/catalog/examples/ComponentsScreen.kt +++ b/catalog/src/main/kotlin/com/adevinta/spark/catalog/examples/ComponentsScreen.kt @@ -126,11 +126,14 @@ internal fun ComponentsListScreen( span = { GridItemSpan(1) }, contentType = { ComponentsItemType.Component }, itemContent = { component -> - ComponentItem(component = component) { - val componentId = component.id - val route = "$ComponentRoute/$componentId" - navController.navigate(route) - } + ComponentItem( + component = component, + onClick = { + val componentId = component.id + val route = "$ComponentRoute/$componentId" + navController.navigate(route) + }, + ) }, ) } diff --git a/catalog/src/main/kotlin/com/adevinta/spark/catalog/examples/component/ComponentItem.kt b/catalog/src/main/kotlin/com/adevinta/spark/catalog/examples/component/ComponentItem.kt index 7e98b8cd5..b1a333d56 100644 --- a/catalog/src/main/kotlin/com/adevinta/spark/catalog/examples/component/ComponentItem.kt +++ b/catalog/src/main/kotlin/com/adevinta/spark/catalog/examples/component/ComponentItem.kt @@ -26,20 +26,31 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.LocalContentColor import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedCard import androidx.compose.material3.Text +import androidx.compose.material3.surfaceColorAtElevation import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import com.adevinta.spark.catalog.R import com.adevinta.spark.catalog.model.Component +import com.adevinta.spark.catalog.model.Configurator +import com.adevinta.spark.catalog.util.PreviewTheme +import com.adevinta.spark.catalog.util.drawForegroundGradientScrim +import com.adevinta.spark.components.image.Illustration +import com.adevinta.spark.components.tags.TagTinted @OptIn(ExperimentalMaterial3Api::class) @Composable public fun ComponentItem( component: Component, onClick: (component: Component) -> Unit, + showExampleCount: Boolean = true, ) { OutlinedCard( onClick = { onClick(component) }, @@ -48,15 +59,34 @@ public fun ComponentItem( .padding(ComponentItemOuterPadding), ) { Box( - modifier = Modifier - .fillMaxSize() - .padding(ComponentItemInnerPadding), + modifier = Modifier.fillMaxSize(), ) { + val tint = ColorFilter.tint(LocalContentColor.current).takeIf { component.tintIcon } + Illustration( + modifier = Modifier + .fillMaxSize() + .drawForegroundGradientScrim( + color = MaterialTheme.colorScheme.surfaceColorAtElevation(1.dp), + ), + drawableRes = component.illustration, + contentDescription = null, + colorFilter = tint, + ) Text( text = component.name, - modifier = Modifier.align(Alignment.BottomStart), + modifier = Modifier + .align(Alignment.BottomStart) + .padding(ComponentItemInnerPadding), style = MaterialTheme.typography.bodySmall, ) + if (showExampleCount) { + TagTinted( + modifier = Modifier + .align(Alignment.BottomEnd) + .padding(ComponentItemInnerPadding), + text = component.examples.count().toString(), + ) + } } } } @@ -64,3 +94,48 @@ public fun ComponentItem( private val ComponentItemHeight = 180.dp private val ComponentItemOuterPadding = 4.dp private val ComponentItemInnerPadding = 16.dp + +@Preview +@Composable +private fun ComponentItemPreview() { + PreviewTheme { + ComponentItem( + component = Component( + 0, + name = "Tokens", + description = R.string.component_tokens_description, + guidelinesUrl = "https://www.google.com/#q=constituto", + docsUrl = "https://www.google.com/#q=dictas", + sourceUrl = "http://www.bing.com/search?q=inani", + examples = listOf(), + configurator = Configurator( + name = "Ronny Bowman", + description = "singulis", + sourceUrl = "https://www.google.com/#q=tempor", + content = {}, + ), + ), + onClick = {}, + ) + ComponentItem( + component = Component( + 0, + name = "Tokens", + description = R.string.component_tokens_description, + illustration = R.drawable.illu_component_tokens, + tintIcon = false, + guidelinesUrl = "https://www.google.com/#q=constituto", + docsUrl = "https://www.google.com/#q=dictas", + sourceUrl = "http://www.bing.com/search?q=inani", + examples = listOf(), + configurator = Configurator( + name = "Ronny Bowman", + description = "singulis", + sourceUrl = "https://www.google.com/#q=tempor", + content = {}, + ), + ), + onClick = {}, + ) + } +} 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 index 540a34b98..97f4c6c56 100644 --- 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 @@ -145,7 +145,7 @@ private fun IconButtonSample( ) { val icon = SparkIcons.LikeFill val contentDescription = "Localized Content Description" - var isLoading by remember { mutableStateOf(false) } + val isLoading by remember { mutableStateOf(false) } button( /* onClick = */ { }, /* enabled = */ true, diff --git a/catalog/src/main/kotlin/com/adevinta/spark/catalog/examples/samples/toggles/SwitchExamples.kt b/catalog/src/main/kotlin/com/adevinta/spark/catalog/examples/samples/toggles/SwitchExamples.kt index df1ea2897..179e46a44 100644 --- a/catalog/src/main/kotlin/com/adevinta/spark/catalog/examples/samples/toggles/SwitchExamples.kt +++ b/catalog/src/main/kotlin/com/adevinta/spark/catalog/examples/samples/toggles/SwitchExamples.kt @@ -22,7 +22,6 @@ package com.adevinta.spark.catalog.examples.samples.toggles import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -120,7 +119,7 @@ private fun LabeledSwitchGroupExample( } @Composable -private fun ColumnScope.SwitchPair( +private fun SwitchPair( checked: Boolean, icons: SwitchIcons? = null, onCheckedChange: (Boolean) -> Unit, 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 a2ed06f00..eb89fe807 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 @@ -21,6 +21,7 @@ */ package com.adevinta.spark.catalog.model +import androidx.annotation.DrawableRes import androidx.annotation.StringRes import com.adevinta.spark.catalog.R import com.adevinta.spark.catalog.configurator.samples.buttons.ButtonsConfigurator @@ -47,6 +48,8 @@ public data class Component( @StringRes val description: Int, val tintIcon: Boolean = true, + @DrawableRes + val illustration: Int = R.drawable.illu_component_placeholder, val guidelinesUrl: String, val docsUrl: String, val sourceUrl: String, @@ -60,6 +63,8 @@ private fun nextId(): Int = nextId.also { nextId += 1 } private val Buttons = Component( id = nextId(), name = "Buttons", + illustration = R.drawable.illu_component_button, + tintIcon = false, description = R.string.component_button_description, guidelinesUrl = "$ComponentGuidelinesUrl/p/34b742-button/b/32e1a2", docsUrl = "$PackageSummaryUrl/com.adevinta.spark.components.buttons/index.html", @@ -71,6 +76,8 @@ private val Buttons = Component( private val Checkboxes = Component( id = nextId(), name = "Checkboxes", + illustration = R.drawable.illu_component_checkbox, + tintIcon = false, description = R.string.component_checkbox_description, guidelinesUrl = "$ComponentGuidelinesUrl/p/76f5a8-checkbox/b/98915d", docsUrl = "$PackageSummaryUrl/com.adevinta.spark.components.toggles/index.html", @@ -82,6 +89,8 @@ private val Checkboxes = Component( private val IconButtons = Component( id = nextId(), name = "IconButtons", + illustration = R.drawable.illu_component_iconbutton, + tintIcon = false, description = R.string.component_iconbutton_description, guidelinesUrl = "$ComponentGuidelinesUrl/p/2352e9-icon-button/b/32e1a2", docsUrl = "$PackageSummaryUrl/com.adevinta.spark.components.iconbuttons/index.html", @@ -94,7 +103,8 @@ private val IconToggleButtons = Component( id = nextId(), name = "IconToggleButtons", description = R.string.component_icontogglebutton_description, - // No buttons icon + illustration = R.drawable.illu_component_icontogglebutton, + tintIcon = false, guidelinesUrl = "$ComponentGuidelinesUrl/p/2352e9-icon-button/b/32e1a2", docsUrl = "$PackageSummaryUrl/com.adevinta.spark.components.iconbuttons/index.html", sourceUrl = "$SparkSourceUrl/kotlin/com/adevinta/components/iconTogglebuttons/IconToggleButton.kt", @@ -105,6 +115,8 @@ private val IconToggleButtons = Component( private val RadioButtons = Component( id = nextId(), name = "Radio buttons", + illustration = R.drawable.illu_component_radiobutton, + tintIcon = false, description = R.string.component_radiobutton_description, guidelinesUrl = "$ComponentGuidelinesUrl/p/98058f-radio-button/b/700a17", docsUrl = "$PackageSummaryUrl/com.adevinta.spark.components.toggles/index.html", @@ -116,6 +128,8 @@ private val RadioButtons = Component( private val Switches = Component( id = nextId(), name = "Switches", + illustration = R.drawable.illu_component_switch, + tintIcon = false, description = R.string.component_switch_description, guidelinesUrl = "$ComponentGuidelinesUrl/p/58a2c6-switch/b/700a17", docsUrl = "$PackageSummaryUrl/com.adevinta.spark.components.toggles/index.html", @@ -138,6 +152,8 @@ private val TextFields = Component( private val Tokens = Component( id = nextId(), name = "Tokens", + illustration = R.drawable.illu_component_tokens, + tintIcon = false, description = R.string.component_tokens_description, guidelinesUrl = "$ComponentGuidelinesUrl/p/3075e9-foundations", docsUrl = "$PackageSummaryUrl/com.adevinta.spark.tokens/index.html", diff --git a/catalog/src/main/kotlin/com/adevinta/spark/catalog/showkase/ComponentDetailScreen.kt b/catalog/src/main/kotlin/com/adevinta/spark/catalog/showkase/ComponentDetailScreen.kt index f7fd1e1de..7be3cbacb 100644 --- a/catalog/src/main/kotlin/com/adevinta/spark/catalog/showkase/ComponentDetailScreen.kt +++ b/catalog/src/main/kotlin/com/adevinta/spark/catalog/showkase/ComponentDetailScreen.kt @@ -157,7 +157,7 @@ private fun getCollabsableTextAndIcon(showDocumentation: Boolean) = if (showDocu stringResource(R.string.showkase_browser_show_documentation) to SparkIcons.ArrowHorizontalDown } -internal fun Modifier.generateComposableModifier(metadata: ShowkaseBrowserComponent) = composed { +internal fun Modifier.generateComposableModifier(metadata: ShowkaseBrowserComponent) = this then composed { val baseModifier = sizeIn(maxHeight = Dp(LocalConfiguration.current.screenHeightDp.toFloat())) when { metadata.heightDp != null && metadata.widthDp != null -> baseModifier.size( diff --git a/catalog/src/main/kotlin/com/adevinta/spark/catalog/showkase/CurrentScreen.kt b/catalog/src/main/kotlin/com/adevinta/spark/catalog/showkase/CurrentScreen.kt index 0ee529d2e..f4b20e76b 100644 --- a/catalog/src/main/kotlin/com/adevinta/spark/catalog/showkase/CurrentScreen.kt +++ b/catalog/src/main/kotlin/com/adevinta/spark/catalog/showkase/CurrentScreen.kt @@ -33,8 +33,6 @@ internal enum class CurrentScreen { CATEGORIES, } -internal fun String?.insideGroup() = this == CurrentScreen.COMPONENTS_IN_A_GROUP.name - @Parcelize internal data class ShowkaseBrowserScreenMetadata( val currentGroup: String? = null, diff --git a/catalog/src/main/kotlin/com/adevinta/spark/catalog/themes/SegmentedButton.kt b/catalog/src/main/kotlin/com/adevinta/spark/catalog/themes/SegmentedButton.kt index ea703c6de..30546bfdb 100644 --- a/catalog/src/main/kotlin/com/adevinta/spark/catalog/themes/SegmentedButton.kt +++ b/catalog/src/main/kotlin/com/adevinta/spark/catalog/themes/SegmentedButton.kt @@ -39,6 +39,7 @@ import androidx.compose.material3.LocalContentColor import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue @@ -73,7 +74,7 @@ internal fun SegmentedButton( require(options.size <= 5) { "This composable requires at most 5 options" } require(options.contains(selectedOption)) { "Invalid selected option [$selectedOption]" } - val selectedIndex by remember(options, selectedOption) { mutableStateOf(options.indexOf(selectedOption)) } + val selectedIndex by remember(options, selectedOption) { mutableIntStateOf(options.indexOf(selectedOption)) } val backgroundProgress by animateFloatAsState( label = "Background Position Progress", diff --git a/catalog/src/main/kotlin/com/adevinta/spark/catalog/themes/ThemePicker.kt b/catalog/src/main/kotlin/com/adevinta/spark/catalog/themes/ThemePicker.kt index 29f91ebf0..25378fd3f 100644 --- a/catalog/src/main/kotlin/com/adevinta/spark/catalog/themes/ThemePicker.kt +++ b/catalog/src/main/kotlin/com/adevinta/spark/catalog/themes/ThemePicker.kt @@ -38,6 +38,7 @@ import androidx.compose.foundation.layout.safeDrawing import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue @@ -207,7 +208,7 @@ public fun ThemePicker( .height(48.dp), ) } - var fontScale by remember { mutableStateOf(theme.fontScale) } + var fontScale by remember { mutableFloatStateOf(theme.fontScale) } AnimatedVisibility(visible = theme.fontScaleMode == FontScaleMode.Custom) { FontScaleItem( modifier = Modifier diff --git a/catalog/src/main/kotlin/com/adevinta/spark/catalog/util/GradientScrim.kt b/catalog/src/main/kotlin/com/adevinta/spark/catalog/util/GradientScrim.kt new file mode 100644 index 000000000..f78ebc21f --- /dev/null +++ b/catalog/src/main/kotlin/com/adevinta/spark/catalog/util/GradientScrim.kt @@ -0,0 +1,93 @@ +/* + * 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.util + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.size +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.composed +import androidx.compose.ui.draw.drawWithContent +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.adevinta.spark.SparkTheme +import kotlin.math.pow + +/** + * Draws a vertical gradient scrim in the foreground. + * + * @param color The color of the gradient scrim. + * @param decay The exponential decay to apply to the gradient. Defaults to `3.0f` which is + * a cubic decay. + * @param numStops The number of color stops to draw in the gradient. Higher numbers result in + * the higher visual quality at the cost of draw performance. Defaults to `16`. + */ +public fun Modifier.drawForegroundGradientScrim( + color: Color, + decay: Float = 3f, + numStops: Int = 16, + startY: Float = 0f, + endY: Float = 1f, +): Modifier = composed { + val colors = remember(color, numStops) { + val baseAlpha = color.alpha + List(numStops) { i -> + val x = i * 1f / (numStops - 1) + val opacity = x.pow(decay) + color.copy(alpha = baseAlpha * opacity) + } + } + + drawWithContent { + drawContent() + drawRect( + topLeft = Offset(x = 0f, y = startY * size.height), + size = size.copy(height = (endY - startY) * size.height), + brush = Brush.verticalGradient(colors = colors), + ) + } +} + +@Preview +@Composable +private fun GradientScrimPreview() { + PreviewTheme { + Box( + modifier = Modifier.size(100.dp) + .background(SparkTheme.colors.surfaceInverse) + .drawForegroundGradientScrim(SparkTheme.colors.surface), + ) + Box( + modifier = Modifier.size(100.dp) + .background(SparkTheme.colors.surfaceInverse) + .drawForegroundGradientScrim( + color = SparkTheme.colors.surface, + decay = 1.5f, + ), + ) + } +} diff --git a/catalog/src/main/res/drawable-hdpi/illu_component_button.webp b/catalog/src/main/res/drawable-hdpi/illu_component_button.webp new file mode 100644 index 000000000..e56cdf4e8 Binary files /dev/null and b/catalog/src/main/res/drawable-hdpi/illu_component_button.webp differ diff --git a/catalog/src/main/res/drawable-hdpi/illu_component_checkbox.webp b/catalog/src/main/res/drawable-hdpi/illu_component_checkbox.webp new file mode 100644 index 000000000..a2d34e96d Binary files /dev/null and b/catalog/src/main/res/drawable-hdpi/illu_component_checkbox.webp differ diff --git a/catalog/src/main/res/drawable-hdpi/illu_component_iconbutton.webp b/catalog/src/main/res/drawable-hdpi/illu_component_iconbutton.webp new file mode 100644 index 000000000..5c0aa2cc1 Binary files /dev/null and b/catalog/src/main/res/drawable-hdpi/illu_component_iconbutton.webp differ diff --git a/catalog/src/main/res/drawable-hdpi/illu_component_icontogglebutton.webp b/catalog/src/main/res/drawable-hdpi/illu_component_icontogglebutton.webp new file mode 100644 index 000000000..86adc18f0 Binary files /dev/null and b/catalog/src/main/res/drawable-hdpi/illu_component_icontogglebutton.webp differ diff --git a/catalog/src/main/res/drawable-hdpi/illu_component_radiobutton.webp b/catalog/src/main/res/drawable-hdpi/illu_component_radiobutton.webp new file mode 100644 index 000000000..875dd437a Binary files /dev/null and b/catalog/src/main/res/drawable-hdpi/illu_component_radiobutton.webp differ diff --git a/catalog/src/main/res/drawable-hdpi/illu_component_switch.webp b/catalog/src/main/res/drawable-hdpi/illu_component_switch.webp new file mode 100644 index 000000000..7e72cd564 Binary files /dev/null and b/catalog/src/main/res/drawable-hdpi/illu_component_switch.webp differ diff --git a/catalog/src/main/res/drawable-hdpi/illu_component_tokens.webp b/catalog/src/main/res/drawable-hdpi/illu_component_tokens.webp new file mode 100644 index 000000000..cd4d0a724 Binary files /dev/null and b/catalog/src/main/res/drawable-hdpi/illu_component_tokens.webp differ diff --git a/catalog/src/main/res/drawable-mdpi/illu_component_button.webp b/catalog/src/main/res/drawable-mdpi/illu_component_button.webp new file mode 100644 index 000000000..9bdc403be Binary files /dev/null and b/catalog/src/main/res/drawable-mdpi/illu_component_button.webp differ diff --git a/catalog/src/main/res/drawable-mdpi/illu_component_checkbox.webp b/catalog/src/main/res/drawable-mdpi/illu_component_checkbox.webp new file mode 100644 index 000000000..8d3795f3f Binary files /dev/null and b/catalog/src/main/res/drawable-mdpi/illu_component_checkbox.webp differ diff --git a/catalog/src/main/res/drawable-mdpi/illu_component_iconbutton.webp b/catalog/src/main/res/drawable-mdpi/illu_component_iconbutton.webp new file mode 100644 index 000000000..eb7360961 Binary files /dev/null and b/catalog/src/main/res/drawable-mdpi/illu_component_iconbutton.webp differ diff --git a/catalog/src/main/res/drawable-mdpi/illu_component_icontogglebutton.webp b/catalog/src/main/res/drawable-mdpi/illu_component_icontogglebutton.webp new file mode 100644 index 000000000..c9ca94e34 Binary files /dev/null and b/catalog/src/main/res/drawable-mdpi/illu_component_icontogglebutton.webp differ diff --git a/catalog/src/main/res/drawable-mdpi/illu_component_radiobutton.webp b/catalog/src/main/res/drawable-mdpi/illu_component_radiobutton.webp new file mode 100644 index 000000000..4d9cd2178 Binary files /dev/null and b/catalog/src/main/res/drawable-mdpi/illu_component_radiobutton.webp differ diff --git a/catalog/src/main/res/drawable-mdpi/illu_component_switch.webp b/catalog/src/main/res/drawable-mdpi/illu_component_switch.webp new file mode 100644 index 000000000..077fa47ad Binary files /dev/null and b/catalog/src/main/res/drawable-mdpi/illu_component_switch.webp differ diff --git a/catalog/src/main/res/drawable-mdpi/illu_component_tokens.webp b/catalog/src/main/res/drawable-mdpi/illu_component_tokens.webp new file mode 100644 index 000000000..3571765ba Binary files /dev/null and b/catalog/src/main/res/drawable-mdpi/illu_component_tokens.webp differ diff --git a/catalog/src/main/res/drawable-xhdpi/illu_component_button.webp b/catalog/src/main/res/drawable-xhdpi/illu_component_button.webp new file mode 100644 index 000000000..4a56e993b Binary files /dev/null and b/catalog/src/main/res/drawable-xhdpi/illu_component_button.webp differ diff --git a/catalog/src/main/res/drawable-xhdpi/illu_component_checkbox.webp b/catalog/src/main/res/drawable-xhdpi/illu_component_checkbox.webp new file mode 100644 index 000000000..76cb00da3 Binary files /dev/null and b/catalog/src/main/res/drawable-xhdpi/illu_component_checkbox.webp differ diff --git a/catalog/src/main/res/drawable-xhdpi/illu_component_iconbutton.webp b/catalog/src/main/res/drawable-xhdpi/illu_component_iconbutton.webp new file mode 100644 index 000000000..73ec5e1ee Binary files /dev/null and b/catalog/src/main/res/drawable-xhdpi/illu_component_iconbutton.webp differ diff --git a/catalog/src/main/res/drawable-xhdpi/illu_component_icontogglebutton.webp b/catalog/src/main/res/drawable-xhdpi/illu_component_icontogglebutton.webp new file mode 100644 index 000000000..aa57b18b9 Binary files /dev/null and b/catalog/src/main/res/drawable-xhdpi/illu_component_icontogglebutton.webp differ diff --git a/catalog/src/main/res/drawable-xhdpi/illu_component_radiobutton.webp b/catalog/src/main/res/drawable-xhdpi/illu_component_radiobutton.webp new file mode 100644 index 000000000..cd3b25aeb Binary files /dev/null and b/catalog/src/main/res/drawable-xhdpi/illu_component_radiobutton.webp differ diff --git a/catalog/src/main/res/drawable-xhdpi/illu_component_switch.webp b/catalog/src/main/res/drawable-xhdpi/illu_component_switch.webp new file mode 100644 index 000000000..6c442976e Binary files /dev/null and b/catalog/src/main/res/drawable-xhdpi/illu_component_switch.webp differ diff --git a/catalog/src/main/res/drawable-xhdpi/illu_component_tokens.webp b/catalog/src/main/res/drawable-xhdpi/illu_component_tokens.webp new file mode 100644 index 000000000..4f4f460eb Binary files /dev/null and b/catalog/src/main/res/drawable-xhdpi/illu_component_tokens.webp differ diff --git a/catalog/src/main/res/drawable-xxhdpi/illu_component_button.webp b/catalog/src/main/res/drawable-xxhdpi/illu_component_button.webp new file mode 100644 index 000000000..359f8a7dd Binary files /dev/null and b/catalog/src/main/res/drawable-xxhdpi/illu_component_button.webp differ diff --git a/catalog/src/main/res/drawable-xxhdpi/illu_component_checkbox.webp b/catalog/src/main/res/drawable-xxhdpi/illu_component_checkbox.webp new file mode 100644 index 000000000..8573293f0 Binary files /dev/null and b/catalog/src/main/res/drawable-xxhdpi/illu_component_checkbox.webp differ diff --git a/catalog/src/main/res/drawable-xxhdpi/illu_component_iconbutton.webp b/catalog/src/main/res/drawable-xxhdpi/illu_component_iconbutton.webp new file mode 100644 index 000000000..c44303ad3 Binary files /dev/null and b/catalog/src/main/res/drawable-xxhdpi/illu_component_iconbutton.webp differ diff --git a/catalog/src/main/res/drawable-xxhdpi/illu_component_icontogglebutton.webp b/catalog/src/main/res/drawable-xxhdpi/illu_component_icontogglebutton.webp new file mode 100644 index 000000000..248471efd Binary files /dev/null and b/catalog/src/main/res/drawable-xxhdpi/illu_component_icontogglebutton.webp differ diff --git a/catalog/src/main/res/drawable-xxhdpi/illu_component_radiobutton.webp b/catalog/src/main/res/drawable-xxhdpi/illu_component_radiobutton.webp new file mode 100644 index 000000000..3092fd452 Binary files /dev/null and b/catalog/src/main/res/drawable-xxhdpi/illu_component_radiobutton.webp differ diff --git a/catalog/src/main/res/drawable-xxhdpi/illu_component_switch.webp b/catalog/src/main/res/drawable-xxhdpi/illu_component_switch.webp new file mode 100644 index 000000000..52b386068 Binary files /dev/null and b/catalog/src/main/res/drawable-xxhdpi/illu_component_switch.webp differ diff --git a/catalog/src/main/res/drawable-xxhdpi/illu_component_tokens.webp b/catalog/src/main/res/drawable-xxhdpi/illu_component_tokens.webp new file mode 100644 index 000000000..3796e7779 Binary files /dev/null and b/catalog/src/main/res/drawable-xxhdpi/illu_component_tokens.webp differ diff --git a/catalog/src/main/res/drawable-xxxhdpi/illu_component_button.webp b/catalog/src/main/res/drawable-xxxhdpi/illu_component_button.webp new file mode 100644 index 000000000..4cdc16847 Binary files /dev/null and b/catalog/src/main/res/drawable-xxxhdpi/illu_component_button.webp differ diff --git a/catalog/src/main/res/drawable-xxxhdpi/illu_component_checkbox.webp b/catalog/src/main/res/drawable-xxxhdpi/illu_component_checkbox.webp new file mode 100644 index 000000000..d45603df3 Binary files /dev/null and b/catalog/src/main/res/drawable-xxxhdpi/illu_component_checkbox.webp differ diff --git a/catalog/src/main/res/drawable-xxxhdpi/illu_component_iconbutton.webp b/catalog/src/main/res/drawable-xxxhdpi/illu_component_iconbutton.webp new file mode 100644 index 000000000..4aaeb1523 Binary files /dev/null and b/catalog/src/main/res/drawable-xxxhdpi/illu_component_iconbutton.webp differ diff --git a/catalog/src/main/res/drawable-xxxhdpi/illu_component_icontogglebutton.webp b/catalog/src/main/res/drawable-xxxhdpi/illu_component_icontogglebutton.webp new file mode 100644 index 000000000..136debba8 Binary files /dev/null and b/catalog/src/main/res/drawable-xxxhdpi/illu_component_icontogglebutton.webp differ diff --git a/catalog/src/main/res/drawable-xxxhdpi/illu_component_radiobutton.webp b/catalog/src/main/res/drawable-xxxhdpi/illu_component_radiobutton.webp new file mode 100644 index 000000000..138141f98 Binary files /dev/null and b/catalog/src/main/res/drawable-xxxhdpi/illu_component_radiobutton.webp differ diff --git a/catalog/src/main/res/drawable-xxxhdpi/illu_component_switch.webp b/catalog/src/main/res/drawable-xxxhdpi/illu_component_switch.webp new file mode 100644 index 000000000..bf157aeaf Binary files /dev/null and b/catalog/src/main/res/drawable-xxxhdpi/illu_component_switch.webp differ diff --git a/catalog/src/main/res/drawable-xxxhdpi/illu_component_tokens.webp b/catalog/src/main/res/drawable-xxxhdpi/illu_component_tokens.webp new file mode 100644 index 000000000..2c85136f4 Binary files /dev/null and b/catalog/src/main/res/drawable-xxxhdpi/illu_component_tokens.webp differ diff --git a/catalog/src/main/res/drawable/ic_launcher_background.xml b/catalog/src/main/res/drawable/ic_launcher_background.xml index 3bce40025..42ebe15a1 100644 --- a/catalog/src/main/res/drawable/ic_launcher_background.xml +++ b/catalog/src/main/res/drawable/ic_launcher_background.xml @@ -20,7 +20,6 @@ SOFTWARE. --> + + + diff --git a/catalog/src/main/res/raw/catalog_keep.xml b/catalog/src/main/res/raw/catalog_keep.xml new file mode 100644 index 000000000..924c37142 --- /dev/null +++ b/catalog/src/main/res/raw/catalog_keep.xml @@ -0,0 +1,26 @@ + + + + + \ No newline at end of file