From c7208610ae68df808949d45cb260e126c17ae46f Mon Sep 17 00:00:00 2001 From: Rebecca Franks Date: Fri, 13 Mar 2026 16:28:27 +0000 Subject: [PATCH 1/2] Migrate JetSnack to use Styles --- Jetsnack/app/build.gradle.kts | 1 + .../compose/material3/CompositionLocals.kt | 41 ++++++++ .../example/jetsnack/ui/components/Button.kt | 39 ++++---- .../example/jetsnack/ui/components/Card.kt | 17 ++-- .../example/jetsnack/ui/components/Divider.kt | 18 ++-- .../example/jetsnack/ui/components/Filters.kt | 98 ++++++++++--------- .../jetsnack/ui/components/Gradient.kt | 27 +---- .../ui/components/GradientTintedIconButton.kt | 63 ++++++------ .../ui/components/QuantitySelector.kt | 3 + .../example/jetsnack/ui/components/Snacks.kt | 21 ++-- .../example/jetsnack/ui/components/Surface.kt | 37 ++++--- .../jetsnack/ui/home/DestinationBar.kt | 3 +- .../java/com/example/jetsnack/ui/home/Feed.kt | 4 +- .../java/com/example/jetsnack/ui/home/Home.kt | 9 +- .../com/example/jetsnack/ui/home/cart/Cart.kt | 4 +- .../jetsnack/ui/home/search/Results.kt | 6 +- .../example/jetsnack/ui/home/search/Search.kt | 10 +- .../com/example/jetsnack/ui/theme/Styles.kt | 91 +++++++++++++++++ .../com/example/jetsnack/ui/theme/Theme.kt | 28 ++++-- Jetsnack/gradle/libs.versions.toml | 2 +- 20 files changed, 331 insertions(+), 191 deletions(-) create mode 100644 Jetsnack/app/src/main/java/androidx/compose/material3/CompositionLocals.kt create mode 100644 Jetsnack/app/src/main/java/com/example/jetsnack/ui/theme/Styles.kt diff --git a/Jetsnack/app/build.gradle.kts b/Jetsnack/app/build.gradle.kts index 0fca21037..2d1d6a086 100644 --- a/Jetsnack/app/build.gradle.kts +++ b/Jetsnack/app/build.gradle.kts @@ -86,6 +86,7 @@ android { kotlin { compilerOptions { jvmTarget = JvmTarget.fromTarget("17") + freeCompilerArgs.add("-opt-in=androidx.compose.foundation.style.ExperimentalFoundationStyleApi") } } compileOptions { diff --git a/Jetsnack/app/src/main/java/androidx/compose/material3/CompositionLocals.kt b/Jetsnack/app/src/main/java/androidx/compose/material3/CompositionLocals.kt new file mode 100644 index 000000000..df849fbc1 --- /dev/null +++ b/Jetsnack/app/src/main/java/androidx/compose/material3/CompositionLocals.kt @@ -0,0 +1,41 @@ +package androidx.compose.material3 + +import androidx.compose.runtime.ProvidableCompositionLocal +import java.lang.reflect.Method + +// This file is only because we don't have this yet implemented in Material 3 theming. + +// This will not be how it's done when its released :) + +val LocalShapes: ProvidableCompositionLocal + get() = getInternalLocal( + className = "androidx.compose.material3.ShapesKt", + methodName = "getLocalShapes", + readableName = "LocalShapes" + ) + +val LocalColorScheme: ProvidableCompositionLocal + get() = getInternalLocal( + className = "androidx.compose.material3.ColorSchemeKt", + methodName = "getLocalColorScheme", + readableName = "LocalColorScheme" + ) + +val LocalTypography: ProvidableCompositionLocal + get() = getInternalLocal( + className = "androidx.compose.material3.TypographyKt", + methodName = "getLocalTypography", + readableName = "LocalTypography" + ) + +private fun getInternalLocal(className: String, methodName: String, readableName: String): ProvidableCompositionLocal { + try { + val clazz = Class.forName(className) + val method: Method = clazz.getDeclaredMethod(methodName) + method.isAccessible = true + @Suppress("UNCHECKED_CAST") + return method.invoke(null) as ProvidableCompositionLocal + } catch (e: Exception) { + throw RuntimeException("Failed to access internal $readableName via reflection", e) + } +} \ No newline at end of file diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Button.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Button.kt index 794bd3f1d..8ba8ac1af 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Button.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Button.kt @@ -14,6 +14,8 @@ * limitations under the License. */ +@file:OptIn(ExperimentalFoundationStyleApi::class) + package com.example.jetsnack.ui.components import android.content.res.Configuration.UI_MODE_NIGHT_YES @@ -29,6 +31,10 @@ import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.style.ExperimentalFoundationStyleApi +import androidx.compose.foundation.style.Style +import androidx.compose.foundation.style.rememberUpdatedStyleState +import androidx.compose.foundation.style.then import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ProvideTextStyle @@ -47,33 +53,23 @@ import androidx.compose.ui.semantics.Role import androidx.compose.ui.tooling.preview.Preview import com.example.jetsnack.ui.theme.JetsnackTheme +//todo think about the text style here @Composable fun JetsnackButton( onClick: () -> Unit, modifier: Modifier = Modifier, + style: Style = Style, enabled: Boolean = true, interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, - shape: Shape = ButtonShape, - border: BorderStroke? = null, - backgroundGradient: List = JetsnackTheme.colors.interactivePrimary, - disabledBackgroundGradient: List = JetsnackTheme.colors.interactiveSecondary, - contentColor: Color = JetsnackTheme.colors.textInteractive, - disabledContentColor: Color = JetsnackTheme.colors.textHelp, - contentPadding: PaddingValues = ButtonDefaults.ContentPadding, content: @Composable RowScope.() -> Unit, ) { + val styleState = rememberUpdatedStyleState(interactionSource, { + it.isEnabled = enabled + }) JetsnackSurface( - shape = shape, - color = Color.Transparent, - contentColor = if (enabled) contentColor else disabledContentColor, - border = border, + style = JetsnackTheme.appStyles.buttonStyle then style, + styleState = styleState, modifier = modifier - .clip(shape) - .background( - Brush.horizontalGradient( - colors = if (enabled) backgroundGradient else disabledBackgroundGradient, - ), - ) .clickable( onClick = onClick, enabled = enabled, @@ -91,8 +87,7 @@ fun JetsnackButton( minWidth = ButtonDefaults.MinWidth, minHeight = ButtonDefaults.MinHeight, ) - .indication(interactionSource, ripple()) - .padding(contentPadding), + .indication(interactionSource, ripple()), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically, content = content, @@ -101,8 +96,6 @@ fun JetsnackButton( } } -private val ButtonShape = RoundedCornerShape(percent = 50) - @Preview("default", "round") @Preview("dark theme", "round", uiMode = UI_MODE_NIGHT_YES) @Preview("large font", "round", fontScale = 2f) @@ -122,7 +115,9 @@ private fun ButtonPreview() { private fun RectangleButtonPreview() { JetsnackTheme { JetsnackButton( - onClick = {}, shape = RectangleShape, + onClick = {}, style = { + shape(RectangleShape) + }, ) { Text(text = "Demo") } diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Card.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Card.kt index 850747216..04d6ecd77 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Card.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Card.kt @@ -14,11 +14,16 @@ * limitations under the License. */ +@file:OptIn(ExperimentalFoundationStyleApi::class) + package com.example.jetsnack.ui.components import android.content.res.Configuration import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.style.ExperimentalFoundationStyleApi +import androidx.compose.foundation.style.Style +import androidx.compose.foundation.style.then import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -33,20 +38,12 @@ import com.example.jetsnack.ui.theme.JetsnackTheme @Composable fun JetsnackCard( modifier: Modifier = Modifier, - shape: Shape = MaterialTheme.shapes.medium, - color: Color = JetsnackTheme.colors.uiBackground, - contentColor: Color = JetsnackTheme.colors.textPrimary, - border: BorderStroke? = null, - elevation: Dp = 4.dp, + style: Style = Style, content: @Composable () -> Unit, ) { JetsnackSurface( modifier = modifier, - shape = shape, - color = color, - contentColor = contentColor, - elevation = elevation, - border = border, + style = JetsnackTheme.appStyles.cardStyle then style, content = content, ) } diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Divider.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Divider.kt index 089313675..98c4b1d47 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Divider.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Divider.kt @@ -14,35 +14,33 @@ * limitations under the License. */ +@file:OptIn(ExperimentalFoundationStyleApi::class) + package com.example.jetsnack.ui.components import android.content.res.Configuration import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.size +import androidx.compose.foundation.style.ExperimentalFoundationStyleApi +import androidx.compose.foundation.style.Style +import androidx.compose.foundation.style.styleable import androidx.compose.material3.HorizontalDivider 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.tooling.preview.Preview -import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.example.jetsnack.ui.theme.JetsnackTheme +import com.example.jetsnack.ui.theme.LocalAppStyles @Composable fun JetsnackDivider( modifier: Modifier = Modifier, - color: Color = JetsnackTheme.colors.uiBorder.copy(alpha = DividerAlpha), - thickness: Dp = 1.dp, + style: Style = Style ) { - HorizontalDivider( - modifier = modifier, - color = color, - thickness = thickness, - ) + Box(modifier = modifier.styleable(null, LocalAppStyles.current.dividerStyle, style)) } -private const val DividerAlpha = 0.12f @Preview("default", showBackground = true) @Preview("dark theme", uiMode = Configuration.UI_MODE_NIGHT_YES, showBackground = true) diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Filters.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Filters.kt index 30121ea10..ff753cbfd 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Filters.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Filters.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -@file:OptIn(ExperimentalSharedTransitionApi::class) +@file:OptIn(ExperimentalSharedTransitionApi::class, ExperimentalFoundationStyleApi::class) package com.example.jetsnack.ui.components @@ -22,10 +22,7 @@ import android.content.res.Configuration import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.ExperimentalSharedTransitionApi import androidx.compose.animation.SharedTransitionScope -import androidx.compose.animation.animateColorAsState -import androidx.compose.foundation.background import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.interaction.collectIsPressedAsState import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.PaddingValues @@ -35,17 +32,24 @@ import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items import androidx.compose.foundation.selection.toggleable import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.style.ExperimentalFoundationStyleApi +import androidx.compose.foundation.style.Style +import androidx.compose.foundation.style.pressed +import androidx.compose.foundation.style.rememberUpdatedStyleState +import androidx.compose.foundation.style.styleable +import androidx.compose.foundation.style.then import androidx.compose.material3.Icon import androidx.compose.material3.IconButton +import androidx.compose.material3.LocalShapes import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.graphics.TileMode import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview @@ -54,6 +58,7 @@ import com.example.jetsnack.R import com.example.jetsnack.model.Filter import com.example.jetsnack.ui.FilterSharedElementKey import com.example.jetsnack.ui.theme.JetsnackTheme +import com.example.jetsnack.ui.theme.LocalJetsnackColors @Composable fun FilterBar( @@ -93,59 +98,62 @@ fun FilterBar( } } items(filters) { filter -> - FilterChip(filter = filter, shape = MaterialTheme.shapes.small) + FilterChip( + filter = filter, + style = Style { + shape(LocalShapes.currentValue.small) + }, + ) } } } } @Composable -fun FilterChip(filter: Filter, modifier: Modifier = Modifier, shape: Shape = MaterialTheme.shapes.small) { +fun FilterChip( + filter: Filter, + modifier: Modifier = Modifier, + style: Style = Style, +) { + val (selected, setSelected) = filter.enabled - val backgroundColor by animateColorAsState( - if (selected) JetsnackTheme.colors.brandSecondary else JetsnackTheme.colors.uiBackground, - label = "background color", - ) - val border = Modifier.fadeInDiagonalGradientBorder( - showBorder = !selected, - colors = JetsnackTheme.colors.interactiveSecondary, - shape = shape, - ) - val textColor by animateColorAsState( - if (selected) Color.Black else JetsnackTheme.colors.textSecondary, - label = "text color", + val interactionSource = remember { MutableInteractionSource() } + val styleState = rememberUpdatedStyleState( + interactionSource, + { + it.isSelected = selected + }, ) JetsnackSurface( - modifier = modifier, - color = backgroundColor, - contentColor = textColor, - shape = shape, - elevation = 2.dp, + modifier = modifier + .toggleable( + value = selected, + onValueChange = setSelected, + interactionSource = interactionSource, + indication = null, + ), + style = JetsnackTheme.appStyles.filterChipStyle then style, + styleState = styleState, ) { - val interactionSource = remember { MutableInteractionSource() } - - val pressed by interactionSource.collectIsPressedAsState() - val backgroundPressed = - if (pressed) { - Modifier.offsetGradientBackground( - JetsnackTheme.colors.interactiveSecondary, - 200f, - 0f, - ) - } else { - Modifier.background(Color.Transparent) + val innerBackgroundStyle = Style { + background(Color.Transparent) + pressed { + animate { + background( + Brush.horizontalGradient( + colors = LocalJetsnackColors.currentValue.interactiveSecondary, + startX = 0f, + endX = 200f, + tileMode = TileMode.Mirror, + ), + ) + } } + } Box( modifier = Modifier - .toggleable( - value = selected, - onValueChange = setSelected, - interactionSource = interactionSource, - indication = null, - ) - .then(backgroundPressed) - .then(border), + .styleable(styleState, innerBackgroundStyle), ) { Text( text = filter.name, diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Gradient.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Gradient.kt index 1a7fba80c..58c94ef17 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Gradient.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Gradient.kt @@ -16,11 +16,8 @@ package com.example.jetsnack.ui.components -import androidx.compose.animation.animateColorAsState -import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.ui.Modifier -import androidx.compose.ui.composed import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.draw.drawWithContent import androidx.compose.ui.graphics.BlendMode @@ -32,7 +29,7 @@ import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -fun Modifier.diagonalGradientTint(colors: List, blendMode: BlendMode) = drawWithContent { +fun Modifier.contentTintDiagonalGradient(colors: List, blendMode: BlendMode) = drawWithContent { drawContent() drawRect( brush = Brush.linearGradient(colors), @@ -40,15 +37,6 @@ fun Modifier.diagonalGradientTint(colors: List, blendMode: BlendMode) = d ) } -fun Modifier.offsetGradientBackground(colors: List, width: Float, offset: Float = 0f) = background( - Brush.horizontalGradient( - colors = colors, - startX = -offset, - endX = width - offset, - tileMode = TileMode.Mirror, - ), -) - fun Modifier.offsetGradientBackground(colors: List, width: Density.() -> Float, offset: Density.() -> Float = { 0f }) = drawBehind { val actualOffset = offset() @@ -68,16 +56,3 @@ fun Modifier.diagonalGradientBorder(colors: List, borderSize: Dp = 2.dp, shape = shape, ) -fun Modifier.fadeInDiagonalGradientBorder(showBorder: Boolean, colors: List, borderSize: Dp = 2.dp, shape: Shape) = composed { - val animatedColors = List(colors.size) { i -> - animateColorAsState( - if (showBorder) colors[i] else colors[i].copy(alpha = 0f), - label = "animated color", - ).value - } - diagonalGradientBorder( - colors = animatedColors, - borderSize = borderSize, - shape = shape, - ) -} diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/GradientTintedIconButton.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/GradientTintedIconButton.kt index 39ebb9070..c65086d21 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/GradientTintedIconButton.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/GradientTintedIconButton.kt @@ -14,23 +14,25 @@ * limitations under the License. */ +@file:OptIn(ExperimentalFoundationStyleApi::class) + package com.example.jetsnack.ui.components import android.content.res.Configuration import androidx.annotation.DrawableRes -import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.collectIsPressedAsState import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.style.ExperimentalFoundationStyleApi +import androidx.compose.foundation.style.Style +import androidx.compose.foundation.style.rememberUpdatedStyleState +import androidx.compose.foundation.style.styleable import androidx.compose.material3.Icon import androidx.compose.material3.Surface import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.BlendMode import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource @@ -39,43 +41,20 @@ import androidx.compose.ui.unit.dp import com.example.jetsnack.R import com.example.jetsnack.ui.theme.JetsnackTheme +// todo introduce lint check for when style is provided but not used ? @Composable fun JetsnackGradientTintedIconButton( @DrawableRes iconResourceId: Int, onClick: () -> Unit, contentDescription: String?, modifier: Modifier = Modifier, + style: Style = Style, + // TODO we cannot migrate this out yet!! colors: List = JetsnackTheme.colors.interactiveSecondary, ) { val interactionSource = remember { MutableInteractionSource() } - // This should use a layer + srcIn but needs investigation - val border = Modifier.fadeInDiagonalGradientBorder( - showBorder = true, - colors = JetsnackTheme.colors.interactiveSecondary, - shape = CircleShape, - ) - val pressed by interactionSource.collectIsPressedAsState() - val background = if (pressed) { - Modifier.offsetGradientBackground(colors, 200f, 0f) - } else { - Modifier.background(JetsnackTheme.colors.uiBackground) - } - val blendMode = if (JetsnackTheme.colors.isDark) BlendMode.Darken else BlendMode.Plus - val modifierColor = if (pressed) { - Modifier.diagonalGradientTint( - colors = listOf( - JetsnackTheme.colors.textSecondary, - JetsnackTheme.colors.textSecondary, - ), - blendMode = blendMode, - ) - } else { - Modifier.diagonalGradientTint( - colors = colors, - blendMode = blendMode, - ) - } + val styleState = rememberUpdatedStyleState(interactionSource) Surface( modifier = modifier .clickable( @@ -83,11 +62,27 @@ fun JetsnackGradientTintedIconButton( interactionSource = interactionSource, indication = null, ) - .clip(CircleShape) - .then(border) - .then(background), + .styleable(styleState, JetsnackTheme.appStyles.gradientIconButtonStyle, style), color = Color.Transparent, ) { + val blendMode = if (JetsnackTheme.colors.isDark) BlendMode.Darken else BlendMode.Plus + // todo this cant be migrated yet due to no support for blendMode and drawWithContent in Styles + // This should use a layer + srcIn but needs investigation + val pressed = interactionSource.collectIsPressedAsState().value + val modifierColor = if (pressed) { + Modifier.contentTintDiagonalGradient( + colors = listOf( + JetsnackTheme.colors.textSecondary, + JetsnackTheme.colors.textSecondary, + ), + blendMode = blendMode, + ) + } else { + Modifier.contentTintDiagonalGradient( + colors = colors, + blendMode = blendMode, + ) + } Icon( painter = painterResource(id = iconResourceId), contentDescription = contentDescription, diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/QuantitySelector.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/QuantitySelector.kt index 4952bd276..f4b21bcee 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/QuantitySelector.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/QuantitySelector.kt @@ -14,6 +14,8 @@ * limitations under the License. */ +@file:OptIn(ExperimentalFoundationStyleApi::class) + package com.example.jetsnack.ui.components import android.content.res.Configuration.UI_MODE_NIGHT_YES @@ -21,6 +23,7 @@ import androidx.compose.animation.Crossfade import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.style.ExperimentalFoundationStyleApi import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Snacks.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Snacks.kt index 028ee2b1c..12dc5e31e 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Snacks.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Snacks.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -@file:OptIn(ExperimentalSharedTransitionApi::class) +@file:OptIn(ExperimentalSharedTransitionApi::class, ExperimentalFoundationStyleApi::class) package com.example.jetsnack.ui.components @@ -49,8 +49,11 @@ import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.style.ExperimentalFoundationStyleApi +import androidx.compose.foundation.style.Style import androidx.compose.material3.Icon import androidx.compose.material3.IconButton +import androidx.compose.material3.LocalShapes import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -189,7 +192,9 @@ private fun Snacks(snackCollectionId: Long, snacks: List, onSnackClick: ( @Composable fun SnackItem(snack: Snack, snackCollectionId: Long, onSnackClick: (Long, String) -> Unit, modifier: Modifier = Modifier) { JetsnackSurface( - shape = MaterialTheme.shapes.medium, + style = { + shape(LocalShapes.currentValue.medium) + }, modifier = modifier.padding( start = 4.dp, end = 4.dp, @@ -280,8 +285,9 @@ private fun HighlightSnackItem( } } JetsnackCard( - elevation = 0.dp, - shape = RoundedCornerShape(roundedCornerAnimation), + style = Style { + shape( RoundedCornerShape(roundedCornerAnimation)) + }, modifier = modifier .padding(bottom = 16.dp) .sharedBounds( @@ -454,11 +460,12 @@ fun SnackImage( elevation: Dp = 0.dp, ) { JetsnackSurface( - elevation = elevation, - shape = CircleShape, + style = { + shape(CircleShape) + // todo elevation + }, modifier = modifier, ) { - AsyncImage( model = ImageRequest.Builder(LocalContext.current) .data(imageRes) diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Surface.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Surface.kt index 1104c51f1..134699942 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Surface.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Surface.kt @@ -14,12 +14,19 @@ * limitations under the License. */ +@file:OptIn(ExperimentalFoundationStyleApi::class) + package com.example.jetsnack.ui.components import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.style.ExperimentalFoundationStyleApi +import androidx.compose.foundation.style.Style +import androidx.compose.foundation.style.StyleState +import androidx.compose.foundation.style.rememberUpdatedStyleState +import androidx.compose.foundation.style.styleable import androidx.compose.material3.LocalContentColor import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider @@ -43,28 +50,21 @@ import kotlin.math.ln @Composable fun JetsnackSurface( modifier: Modifier = Modifier, - shape: Shape = RectangleShape, - color: Color = JetsnackTheme.colors.uiBackground, - contentColor: Color = JetsnackTheme.colors.textSecondary, - border: BorderStroke? = null, - elevation: Dp = 0.dp, + style: Style = Style, + // todo confirm patten is acceptable + styleState: StyleState = rememberUpdatedStyleState(null), content: @Composable () -> Unit, ) { Box( modifier = modifier - .shadow(elevation = elevation, shape = shape, clip = false) - .zIndex(elevation.value) - .then(if (border != null) Modifier.border(border, shape) else Modifier) - .background( - color = getBackgroundColorForElevation(color, elevation), - shape = shape, - ) - .clip(shape), + .styleable(styleState, JetsnackTheme.appStyles.surfaceStyle, style) ) { - CompositionLocalProvider(LocalContentColor provides contentColor, content = content) + //todo double check CompositionLocalProvider(LocalContentColor provides contentColor, content = content) + content() } } +/* TODO Migrate computed property @Composable private fun getBackgroundColorForElevation(color: Color, elevation: Dp): Color { return if (elevation > 0.dp // && https://issuetracker.google.com/issues/161429530 @@ -76,23 +76,28 @@ private fun getBackgroundColorForElevation(color: Color, elevation: Dp): Color { color } } +*/ /** * Applies a [Color.White] overlay to this color based on the [elevation]. This increases visibility * of elevation for surfaces in a dark theme. * * TODO: Remove when public https://issuetracker.google.com/155181601 - */ + *//* + private fun Color.withElevation(elevation: Dp): Color { val foreground = calculateForeground(elevation) return foreground.compositeOver(this) } +*/ /** * @return the alpha-modified [Color.White] to overlay on top of the surface color to produce * the resultant color. - */ + *//* + private fun calculateForeground(elevation: Dp): Color { val alpha = ((4.5f * ln(elevation.value + 1)) + 2f) / 100f return Color.White.copy(alpha = alpha) } +*/ diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/DestinationBar.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/DestinationBar.kt index b706ea8bb..7eba0922c 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/DestinationBar.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/DestinationBar.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -@file:OptIn(ExperimentalSharedTransitionApi::class) +@file:OptIn(ExperimentalSharedTransitionApi::class, ExperimentalFoundationStyleApi::class) package com.example.jetsnack.ui.home @@ -25,6 +25,7 @@ import androidx.compose.animation.slideOutVertically import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.style.ExperimentalFoundationStyleApi import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/Feed.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/Feed.kt index 10e3125ce..39ccd8e74 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/Feed.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/Feed.kt @@ -124,7 +124,9 @@ private fun SnackCollectionList( } itemsIndexed(snackCollections) { index, snackCollection -> if (index > 0) { - JetsnackDivider(thickness = 2.dp) + JetsnackDivider(style = { + height(2.dp) + }) } SnackCollection( diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/Home.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/Home.kt index 28d1f4b92..072b04001 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/Home.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/Home.kt @@ -82,6 +82,7 @@ import com.example.jetsnack.ui.snackdetail.nonSpatialExpressiveSpring import com.example.jetsnack.ui.snackdetail.spatialExpressiveSpring import com.example.jetsnack.ui.theme.JetsnackTheme import java.util.Locale +import androidx.compose.ui.platform.LocalLocale fun NavGraphBuilder.composableWithCompositionLocal( route: String, @@ -174,8 +175,10 @@ fun JetsnackBottomBar( JetsnackSurface( modifier = modifier, - color = color, - contentColor = contentColor, + style = { + background(color) + contentColor(contentColor) + } ) { val springSpec = spatialExpressiveSpring() JetsnackBottomNavLayout( @@ -187,7 +190,7 @@ fun JetsnackBottomBar( ) { val configuration = LocalConfiguration.current val currentLocale: Locale = - ConfigurationCompat.getLocales(configuration).get(0) ?: Locale.getDefault() + ConfigurationCompat.getLocales(configuration).get(0) ?: LocalLocale.current.platformLocale tabs.forEach { section -> val selected = section == currentSection diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/cart/Cart.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/cart/Cart.kt index 626854613..5afdf1866 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/cart/Cart.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/cart/Cart.kt @@ -449,7 +449,9 @@ private fun CheckoutBar(modifier: Modifier = Modifier) { Spacer(Modifier.weight(1f)) JetsnackButton( onClick = { /* todo */ }, - shape = RectangleShape, + style = { + shape(RectangleShape) + }, modifier = Modifier .padding(horizontal = 12.dp, vertical = 8.dp) .weight(1f), diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Results.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Results.kt index 05aebc129..e2a74e017 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Results.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Results.kt @@ -117,8 +117,10 @@ private fun SearchResult(snack: Snack, onSnackClick: (Long, String) -> Unit, sho } JetsnackButton( onClick = { /* todo */ }, - shape = CircleShape, - contentPadding = PaddingValues(0.dp), + style = { + shape(CircleShape) + contentPadding(0.dp) + }, modifier = Modifier.size(36.dp), ) { Icon( diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Search.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Search.kt index 33e84c51e..85d95e31e 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Search.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Search.kt @@ -34,6 +34,7 @@ import androidx.compose.foundation.text.BasicTextField import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Icon import androidx.compose.material3.IconButton +import androidx.compose.material3.LocalShapes import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -61,6 +62,7 @@ import com.example.jetsnack.model.SnackRepo import com.example.jetsnack.ui.components.JetsnackDivider import com.example.jetsnack.ui.components.JetsnackSurface import com.example.jetsnack.ui.theme.JetsnackTheme +import com.example.jetsnack.ui.theme.LocalJetsnackColors @Composable fun Search(onSnackClick: (Long, String) -> Unit, modifier: Modifier = Modifier, state: SearchState = rememberSearchState()) { @@ -170,9 +172,11 @@ private fun SearchBar( modifier: Modifier = Modifier, ) { JetsnackSurface( - color = JetsnackTheme.colors.uiFloated, - contentColor = JetsnackTheme.colors.textSecondary, - shape = MaterialTheme.shapes.small, + style = { + background(LocalJetsnackColors.currentValue.uiFloated) + contentColor(LocalJetsnackColors.currentValue.textSecondary) + shape(LocalShapes.currentValue.small) + }, modifier = modifier .fillMaxWidth() .height(56.dp) diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/theme/Styles.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/theme/Styles.kt new file mode 100644 index 000000000..41ecc7863 --- /dev/null +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/theme/Styles.kt @@ -0,0 +1,91 @@ +@file:OptIn(ExperimentalFoundationStyleApi::class) + +package com.example.jetsnack.ui.theme + +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.style.ExperimentalFoundationStyleApi +import androidx.compose.foundation.style.Style +import androidx.compose.foundation.style.disabled +import androidx.compose.foundation.style.fillWidth +import androidx.compose.foundation.style.pressed +import androidx.compose.foundation.style.selected +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.LocalShapes +import androidx.compose.material3.LocalTypography +import androidx.compose.runtime.Immutable +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.RectangleShape +import androidx.compose.ui.graphics.TileMode +import androidx.compose.ui.unit.dp + +@Immutable +data class AppStyles( + val buttonStyle : Style = Style { + shape( RoundedCornerShape(percent = 50)) + background(Brush.linearGradient(LocalJetsnackColors.currentValue.interactivePrimary)) + contentColor(LocalJetsnackColors.currentValue.textInteractive) + contentPadding( ButtonDefaults.ContentPadding.calculateTopPadding()) // todo file issue to support padding values + textStyle(LocalTypography.currentValue.labelLarge) + disabled { + animate { + background(Brush.linearGradient(LocalJetsnackColors.currentValue.interactiveSecondary)) + contentColor(LocalJetsnackColors.currentValue.textHelp) + } + } + }, + val cardStyle: Style = Style { + shape(LocalShapes.currentValue.medium) + background(LocalJetsnackColors.currentValue.uiBackground) + contentColor(LocalJetsnackColors.currentValue.textPrimary) + /* + todo elevation + elevation: Dp = 4.dp,*/ + }, + val dividerStyle: Style = Style { + background(LocalJetsnackColors.currentValue.uiBorder.copy(alpha = 0.12f)) + height(1.dp) + fillWidth() + }, + val gradientIconButtonStyle: Style = Style { + shape(CircleShape) + clip(true) + border(2.dp, Brush.linearGradient(LocalJetsnackColors.currentValue.interactiveSecondary)) + background(LocalJetsnackColors.currentValue.uiBackground) + pressed { + animate { + background(Brush.horizontalGradient( + // this was a parameter input into the function? might want to make helper function for it + colors = LocalJetsnackColors.currentValue.interactiveSecondary, + startX = 0f, + endX = 200f, // todo double check px/dp + tileMode = TileMode.Mirror, + )) + } + } + }, + val filterChipStyle: Style = Style { + shape(LocalShapes.currentValue.small) + background(LocalJetsnackColors.currentValue.uiBackground) + contentColor(LocalJetsnackColors.currentValue.textSecondary) + border(1.dp, Brush.linearGradient(LocalJetsnackColors.currentValue.interactiveSecondary)) + // todo elevation = 2.dp, + selected { + animate { + background(LocalJetsnackColors.currentValue.brandSecondary) + contentColor(Color.Black) + border(1.dp, Color.Transparent) + } + } + }, + val scaffoldStyle: Style = Style { + + }, + val surfaceStyle: Style = Style { + shape(RectangleShape) + background(LocalJetsnackColors.currentValue.uiBackground) + contentColor(LocalJetsnackColors.currentValue.textSecondary) + clip(true) + } +) \ No newline at end of file diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/theme/Theme.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/theme/Theme.kt index ad0a8e66c..2ad96a0f0 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/theme/Theme.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/theme/Theme.kt @@ -14,14 +14,18 @@ * limitations under the License. */ +@file:OptIn(ExperimentalFoundationStyleApi::class) + package com.example.jetsnack.ui.theme import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.style.ExperimentalFoundationStyleApi import androidx.compose.material3.ColorScheme import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.Immutable +import androidx.compose.runtime.ProvidableCompositionLocal import androidx.compose.runtime.staticCompositionLocalOf import androidx.compose.ui.graphics.Color @@ -80,21 +84,26 @@ private val DarkColorPalette = JetsnackColors( @Composable fun JetsnackTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) { val colors = if (darkTheme) DarkColorPalette else LightColorPalette - + val styles = AppStyles() ProvideJetsnackColors(colors) { - MaterialTheme( - colorScheme = debugColors(darkTheme), - typography = Typography, - shapes = Shapes, - content = content, - ) + CompositionLocalProvider(LocalAppStyles provides styles) { + MaterialTheme( + colorScheme = debugColors(darkTheme), + typography = Typography, + shapes = Shapes, + content = content, + ) + } } } - +//todo discuss best practise for exposing composition locals with @Composable, vs ProvideCompositionLocal object JetsnackTheme { val colors: JetsnackColors @Composable get() = LocalJetsnackColors.current + val appStyles : AppStyles + @Composable + get() = LocalAppStyles.current } /** @@ -137,9 +146,10 @@ fun ProvideJetsnackColors(colors: JetsnackColors, content: @Composable () -> Uni CompositionLocalProvider(LocalJetsnackColors provides colors, content = content) } -private val LocalJetsnackColors = staticCompositionLocalOf { +val LocalJetsnackColors = staticCompositionLocalOf { error("No JetsnackColorPalette provided") } +val LocalAppStyles = staticCompositionLocalOf { AppStyles() } /** * A Material [Colors] implementation which sets all colors to [debugColor] to discourage usage of diff --git a/Jetsnack/gradle/libs.versions.toml b/Jetsnack/gradle/libs.versions.toml index c51b64c94..c10875b44 100644 --- a/Jetsnack/gradle/libs.versions.toml +++ b/Jetsnack/gradle/libs.versions.toml @@ -63,7 +63,7 @@ androidx-activity-ktx = { module = "androidx.activity:activity-ktx", version.ref androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" } androidx-compose-animation = { module = "androidx.compose.animation:animation" } androidx-compose-bom = { module = "androidx.compose:compose-bom", version.ref = "androidx-compose-bom" } -androidx-compose-foundation = { module = "androidx.compose.foundation:foundation" } +androidx-compose-foundation = { module = "androidx.compose.foundation:foundation", version = "1.11.0-beta01" } androidx-compose-foundation-layout = { module = "androidx.compose.foundation:foundation-layout" } androidx-compose-material3 = { module = "androidx.compose.material3:material3" } androidx-compose-material3-adaptive = { module = "androidx.compose.material3.adaptive:adaptive" } From 5a6bcb89bad29e2d5bbc82a02036755efcca185d Mon Sep 17 00:00:00 2001 From: Rebecca Franks Date: Fri, 13 Mar 2026 18:18:59 +0000 Subject: [PATCH 2/2] Migrate Text() to a new JetsnackText() composable instead, to be able to use Styles API. --- .../example/jetsnack/ui/components/Button.kt | 14 +-- .../example/jetsnack/ui/components/Card.kt | 8 +- .../example/jetsnack/ui/components/Filters.kt | 9 +- .../ui/components/QuantitySelector.kt | 26 +++-- .../example/jetsnack/ui/components/Snacks.kt | 36 ++++--- .../example/jetsnack/ui/components/Text.kt | 46 ++++++++ .../jetsnack/ui/home/DestinationBar.kt | 16 +-- .../example/jetsnack/ui/home/FilterScreen.kt | 49 ++++++--- .../java/com/example/jetsnack/ui/home/Home.kt | 13 ++- .../com/example/jetsnack/ui/home/Profile.kt | 21 ++-- .../com/example/jetsnack/ui/home/cart/Cart.kt | 100 ++++++++++++------ .../jetsnack/ui/home/search/Categories.kt | 22 ++-- .../jetsnack/ui/home/search/Results.kt | 54 ++++++---- .../example/jetsnack/ui/home/search/Search.kt | 10 +- .../jetsnack/ui/home/search/Suggestions.kt | 20 ++-- .../jetsnack/ui/snackdetail/SnackDetail.kt | 98 ++++++++++------- .../com/example/jetsnack/ui/theme/Styles.kt | 15 ++- 17 files changed, 356 insertions(+), 201 deletions(-) create mode 100644 Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Text.kt diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Button.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Button.kt index 8ba8ac1af..45c2622aa 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Button.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Button.kt @@ -19,18 +19,13 @@ package com.example.jetsnack.ui.components import android.content.res.Configuration.UI_MODE_NIGHT_YES -import androidx.compose.foundation.BorderStroke -import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.indication import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.defaultMinSize -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.style.ExperimentalFoundationStyleApi import androidx.compose.foundation.style.Style import androidx.compose.foundation.style.rememberUpdatedStyleState @@ -38,17 +33,12 @@ import androidx.compose.foundation.style.then import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ProvideTextStyle -import androidx.compose.material3.Text import androidx.compose.material3.ripple import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Brush -import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.RectangleShape -import androidx.compose.ui.graphics.Shape import androidx.compose.ui.semantics.Role import androidx.compose.ui.tooling.preview.Preview import com.example.jetsnack.ui.theme.JetsnackTheme @@ -103,7 +93,7 @@ fun JetsnackButton( private fun ButtonPreview() { JetsnackTheme { JetsnackButton(onClick = {}) { - Text(text = "Demo") + JetsnackText(text = "Demo") } } } @@ -119,7 +109,7 @@ private fun RectangleButtonPreview() { shape(RectangleShape) }, ) { - Text(text = "Demo") + JetsnackText(text = "Demo") } } } diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Card.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Card.kt index 04d6ecd77..e8f4f2bf3 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Card.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Card.kt @@ -19,19 +19,13 @@ package com.example.jetsnack.ui.components import android.content.res.Configuration -import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.layout.padding import androidx.compose.foundation.style.ExperimentalFoundationStyleApi import androidx.compose.foundation.style.Style import androidx.compose.foundation.style.then -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.Shape import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.example.jetsnack.ui.theme.JetsnackTheme @@ -55,7 +49,7 @@ fun JetsnackCard( private fun CardPreview() { JetsnackTheme { JetsnackCard { - Text(text = "Demo", modifier = Modifier.padding(16.dp)) + JetsnackText(text = "Demo", modifier = Modifier.padding(16.dp)) } } } diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Filters.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Filters.kt index ff753cbfd..0c88fd718 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Filters.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Filters.kt @@ -41,8 +41,7 @@ import androidx.compose.foundation.style.then import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.LocalShapes -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text +import androidx.compose.material3.LocalTypography import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Alignment @@ -155,9 +154,11 @@ fun FilterChip( modifier = Modifier .styleable(styleState, innerBackgroundStyle), ) { - Text( + JetsnackText( text = filter.name, - style = MaterialTheme.typography.bodySmall, + style = { + jetsnackTextStyle(LocalTypography.currentValue.bodySmall) + }, maxLines = 1, modifier = Modifier.padding( horizontal = 20.dp, diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/QuantitySelector.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/QuantitySelector.kt index f4b21bcee..dc14bcdd6 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/QuantitySelector.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/QuantitySelector.kt @@ -24,8 +24,7 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.style.ExperimentalFoundationStyleApi -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text +import androidx.compose.material3.LocalTypography import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Alignment @@ -40,15 +39,18 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.example.jetsnack.R import com.example.jetsnack.ui.theme.JetsnackTheme +import com.example.jetsnack.ui.theme.LocalJetsnackColors @Composable fun QuantitySelector(count: Int, decreaseItemCount: () -> Unit, increaseItemCount: () -> Unit, modifier: Modifier = Modifier) { Row(modifier = modifier) { - Text( + JetsnackText( text = stringResource(R.string.quantity), - style = MaterialTheme.typography.titleMedium, - color = JetsnackTheme.colors.textSecondary, - fontWeight = FontWeight.Normal, + style = { + jetsnackTextStyle(LocalTypography.currentValue.titleMedium) + contentColor(LocalJetsnackColors.currentValue.textSecondary) + fontWeight(FontWeight.Normal) + }, modifier = Modifier .padding(end = 18.dp) .align(Alignment.CenterVertically), @@ -64,12 +66,14 @@ fun QuantitySelector(count: Int, decreaseItemCount: () -> Unit, increaseItemCoun modifier = Modifier .align(Alignment.CenterVertically), ) { - Text( + JetsnackText( text = "$it", - style = MaterialTheme.typography.titleSmall, - fontSize = 18.sp, - color = JetsnackTheme.colors.textPrimary, - textAlign = TextAlign.Center, + style = { + jetsnackTextStyle(LocalTypography.currentValue.titleSmall) + fontSize(18.sp) + contentColor(LocalJetsnackColors.currentValue.textPrimary) + textAlign(TextAlign.Center) + }, modifier = Modifier.widthIn(min = 24.dp), ) } diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Snacks.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Snacks.kt index 12dc5e31e..cd3ee0ae8 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Snacks.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Snacks.kt @@ -54,8 +54,7 @@ import androidx.compose.foundation.style.Style import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.LocalShapes -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text +import androidx.compose.material3.LocalTypography import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.getValue @@ -86,6 +85,7 @@ import com.example.jetsnack.ui.SnackSharedElementType import com.example.jetsnack.ui.snackdetail.nonSpatialExpressiveSpring import com.example.jetsnack.ui.snackdetail.snackDetailBoundsTransform import com.example.jetsnack.ui.theme.JetsnackTheme +import com.example.jetsnack.ui.theme.LocalJetsnackColors private val HighlightCardWidth = 170.dp private val HighlightCardPadding = 16.dp @@ -107,10 +107,12 @@ fun SnackCollection( .heightIn(min = 56.dp) .padding(start = 24.dp), ) { - Text( + JetsnackText( text = snackCollection.name, - style = MaterialTheme.typography.titleLarge, - color = JetsnackTheme.colors.brand, + style = { + jetsnackTextStyle(LocalTypography.currentValue.titleLarge) + contentColor(LocalJetsnackColors.currentValue.brand) + }, maxLines = 1, overflow = TextOverflow.Ellipsis, modifier = Modifier @@ -234,10 +236,12 @@ fun SnackItem(snack: Snack, snackCollectionId: Long, onSnackClick: (Long, String boundsTransform = snackDetailBoundsTransform, ), ) - Text( + JetsnackText( text = snack.name, - style = MaterialTheme.typography.titleMedium, - color = JetsnackTheme.colors.textSecondary, + style = { + jetsnackTextStyle(LocalTypography.currentValue.titleMedium) + contentColor(LocalJetsnackColors.currentValue.textSecondary) + }, modifier = Modifier .padding(top = 8.dp) .wrapContentWidth() @@ -391,12 +395,14 @@ private fun HighlightSnackItem( } Spacer(modifier = Modifier.height(8.dp)) - Text( + JetsnackText( text = snack.name, maxLines = 1, overflow = TextOverflow.Ellipsis, - style = MaterialTheme.typography.titleLarge, - color = JetsnackTheme.colors.textSecondary, + style = { + jetsnackTextStyle(LocalTypography.currentValue.titleLarge) + contentColor(LocalJetsnackColors.currentValue.textSecondary) + }, modifier = Modifier .padding(horizontal = 16.dp) .sharedBounds( @@ -417,10 +423,12 @@ private fun HighlightSnackItem( ) Spacer(modifier = Modifier.height(4.dp)) - Text( + JetsnackText( text = snack.tagline, - style = MaterialTheme.typography.bodyLarge, - color = JetsnackTheme.colors.textHelp, + style = { + jetsnackTextStyle(LocalTypography.currentValue.bodyLarge) + contentColor(LocalJetsnackColors.currentValue.textHelp) + }, modifier = Modifier .padding(horizontal = 16.dp) .sharedBounds( diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Text.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Text.kt new file mode 100644 index 000000000..4f3a51469 --- /dev/null +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Text.kt @@ -0,0 +1,46 @@ +package com.example.jetsnack.ui.components + +import androidx.compose.foundation.style.ExperimentalFoundationStyleApi +import androidx.compose.foundation.style.Style +import androidx.compose.foundation.style.StyleScope +import androidx.compose.foundation.style.styleable +import androidx.compose.foundation.text.BasicText +import androidx.compose.foundation.text.TextAutoSize +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.TextLayoutResult +import androidx.compose.ui.text.style.TextOverflow +import com.example.jetsnack.ui.theme.LocalAppStyles + +// Workaround for b/492528450 - setting textStyle currently doesn't set fontFamily. +@ExperimentalFoundationStyleApi +fun StyleScope.jetsnackTextStyle(value: TextStyle) { + textStyle(value) + value.fontFamily?.let { fontFamily(it) } +} + +@ExperimentalFoundationStyleApi +@Composable +fun JetsnackText( + text: String, + modifier: Modifier = Modifier, + style: Style = Style, + onTextLayout: ((TextLayoutResult) -> Unit)? = null, + overflow: TextOverflow = TextOverflow.Clip, + softWrap: Boolean = true, + maxLines: Int = Int.MAX_VALUE, + minLines: Int = 1, + autoSize: TextAutoSize? = null, + ) { + BasicText( + text = text, + modifier = modifier.styleable(null, LocalAppStyles.current.defaultTextStyle, style), + onTextLayout = onTextLayout, + overflow = overflow, + softWrap = softWrap, + maxLines = maxLines, + minLines = minLines, + autoSize = autoSize, + ) +} diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/DestinationBar.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/DestinationBar.kt index 7eba0922c..f88635476 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/DestinationBar.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/DestinationBar.kt @@ -29,8 +29,7 @@ import androidx.compose.foundation.style.ExperimentalFoundationStyleApi import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text +import androidx.compose.material3.LocalTypography import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable @@ -46,9 +45,12 @@ import com.example.jetsnack.ui.LocalNavAnimatedVisibilityScope import com.example.jetsnack.ui.LocalSharedTransitionScope import com.example.jetsnack.ui.components.JetsnackDivider import com.example.jetsnack.ui.components.JetsnackPreviewWrapper +import com.example.jetsnack.ui.components.JetsnackText +import com.example.jetsnack.ui.components.jetsnackTextStyle import com.example.jetsnack.ui.snackdetail.spatialExpressiveSpring import com.example.jetsnack.ui.theme.AlphaNearOpaque import com.example.jetsnack.ui.theme.JetsnackTheme +import com.example.jetsnack.ui.theme.LocalJetsnackColors @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -71,11 +73,13 @@ fun DestinationBar(modifier: Modifier = Modifier) { windowInsets = WindowInsets(0, 0, 0, 0), title = { Row { - Text( + JetsnackText( text = "Delivery to 1600 Amphitheater Way", - style = MaterialTheme.typography.titleMedium, - color = JetsnackTheme.colors.textSecondary, - textAlign = TextAlign.Center, + style = { + jetsnackTextStyle(LocalTypography.currentValue.titleMedium) + contentColor(LocalJetsnackColors.currentValue.textSecondary) + textAlign(TextAlign.Center) + }, maxLines = 1, overflow = TextOverflow.Ellipsis, modifier = Modifier diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/FilterScreen.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/FilterScreen.kt index f2c0dcabc..3b928c01a 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/FilterScreen.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/FilterScreen.kt @@ -46,10 +46,10 @@ import androidx.compose.foundation.selection.selectable import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Icon import androidx.compose.material3.IconButton +import androidx.compose.material3.LocalTypography import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Slider import androidx.compose.material3.SliderDefaults -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableFloatStateOf @@ -71,7 +71,10 @@ import com.example.jetsnack.model.Filter import com.example.jetsnack.model.SnackRepo import com.example.jetsnack.ui.FilterSharedElementKey import com.example.jetsnack.ui.components.FilterChip +import com.example.jetsnack.ui.components.JetsnackText +import com.example.jetsnack.ui.components.jetsnackTextStyle import com.example.jetsnack.ui.theme.JetsnackTheme +import com.example.jetsnack.ui.theme.LocalJetsnackColors @Composable fun FilterScreen(sharedTransitionScope: SharedTransitionScope, animatedVisibilityScope: AnimatedVisibilityScope, onDismiss: () -> Unit) { @@ -133,14 +136,16 @@ fun FilterScreen(sharedTransitionScope: SharedTransitionScope, animatedVisibilit contentDescription = stringResource(id = R.string.close), ) } - Text( + JetsnackText( text = stringResource(id = R.string.label_filters), modifier = Modifier .fillMaxWidth() .fillMaxHeight() .padding(top = 8.dp, end = 48.dp), - textAlign = TextAlign.Center, - style = MaterialTheme.typography.titleLarge, + style = { + textAlign(TextAlign.Center) + jetsnackTextStyle(LocalTypography.currentValue.titleLarge) + } ) val resetEnabled = sortState != defaultFilter @@ -154,12 +159,16 @@ fun FilterScreen(sharedTransitionScope: SharedTransitionScope, animatedVisibilit FontWeight.Normal } - Text( + JetsnackText( text = stringResource(id = R.string.reset), - style = MaterialTheme.typography.bodyMedium, - fontWeight = fontWeight, - color = JetsnackTheme.colors.uiBackground - .copy(alpha = if (!resetEnabled) 0.38f else 1f), + style = { + jetsnackTextStyle(LocalTypography.currentValue.bodyMedium) + fontWeight(fontWeight) + contentColor( + LocalJetsnackColors.currentValue.uiBackground + .copy(alpha = if (!resetEnabled) 0.38f else 1f) + ) + } ) } } @@ -243,10 +252,12 @@ fun SortFilters(sortFilters: List = SnackRepo.getSortFilters(), sortStat fun MaxCalories(sliderPosition: Float, onValueChanged: (Float) -> Unit) { FlowRow { FilterTitle(text = stringResource(id = R.string.max_calories)) - Text( + JetsnackText( text = stringResource(id = R.string.per_serving), - style = MaterialTheme.typography.bodyMedium, - color = JetsnackTheme.colors.brand, + style = { + jetsnackTextStyle(LocalTypography.currentValue.bodyMedium) + contentColor(LocalJetsnackColors.currentValue.brand) + }, modifier = Modifier.padding(top = 5.dp, start = 10.dp), ) } @@ -269,10 +280,12 @@ fun MaxCalories(sliderPosition: Float, onValueChanged: (Float) -> Unit) { @Composable fun FilterTitle(text: String) { - Text( + JetsnackText( text = text, - style = MaterialTheme.typography.titleLarge, - color = JetsnackTheme.colors.brand, + style = { + jetsnackTextStyle(LocalTypography.currentValue.titleLarge) + contentColor(LocalJetsnackColors.currentValue.brand) + }, modifier = Modifier.padding(bottom = 8.dp), ) } @@ -287,9 +300,11 @@ fun SortOption(text: String, @DrawableRes icon: Int?, onClickOption: () -> Unit, if (icon != null) { Icon(painter = painterResource(id = icon), contentDescription = null) } - Text( + JetsnackText( text = text, - style = MaterialTheme.typography.titleMedium, + style = { + jetsnackTextStyle(LocalTypography.currentValue.titleMedium) + }, modifier = Modifier .padding(start = 10.dp) .weight(1f), diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/Home.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/Home.kt index 072b04001..4dd136751 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/Home.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/Home.kt @@ -41,8 +41,7 @@ import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.selection.selectable import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text +import androidx.compose.material3.LocalTypography import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.LaunchedEffect @@ -76,6 +75,8 @@ import androidx.navigation.navDeepLink import com.example.jetsnack.R import com.example.jetsnack.ui.LocalNavAnimatedVisibilityScope import com.example.jetsnack.ui.components.JetsnackSurface +import com.example.jetsnack.ui.components.JetsnackText +import com.example.jetsnack.ui.components.jetsnackTextStyle import com.example.jetsnack.ui.home.cart.Cart import com.example.jetsnack.ui.home.search.Search import com.example.jetsnack.ui.snackdetail.nonSpatialExpressiveSpring @@ -214,10 +215,12 @@ fun JetsnackBottomBar( ) }, text = { - Text( + JetsnackText( text = text, - color = tint, - style = MaterialTheme.typography.labelLarge, + style = { + contentColor(tint) + jetsnackTextStyle(LocalTypography.currentValue.labelLarge) + }, maxLines = 1, ) }, diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/Profile.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/Profile.kt index 799fa28f3..2c6a524ce 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/Profile.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/Profile.kt @@ -25,8 +25,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.wrapContentSize -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text +import androidx.compose.material3.LocalTypography import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -36,6 +35,8 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.example.jetsnack.R +import com.example.jetsnack.ui.components.JetsnackText +import com.example.jetsnack.ui.components.jetsnackTextStyle import com.example.jetsnack.ui.theme.JetsnackTheme @Composable @@ -52,17 +53,21 @@ fun Profile(modifier: Modifier = Modifier) { contentDescription = null, ) Spacer(Modifier.height(24.dp)) - Text( + JetsnackText( text = stringResource(R.string.work_in_progress), - style = MaterialTheme.typography.titleMedium, - textAlign = TextAlign.Center, + style = { + jetsnackTextStyle(LocalTypography.currentValue.titleMedium) + textAlign(TextAlign.Center) + }, modifier = Modifier.fillMaxWidth(), ) Spacer(Modifier.height(16.dp)) - Text( + JetsnackText( text = stringResource(R.string.grab_beverage), - style = MaterialTheme.typography.bodyMedium, - textAlign = TextAlign.Center, + style = { + jetsnackTextStyle(LocalTypography.currentValue.bodyMedium) + textAlign(TextAlign.Center) + }, modifier = Modifier.fillMaxWidth(), ) } diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/cart/Cart.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/cart/Cart.kt index 5afdf1866..7dc535287 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/cart/Cart.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/cart/Cart.kt @@ -45,9 +45,9 @@ import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Icon import androidx.compose.material3.IconButton +import androidx.compose.material3.LocalTypography import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.remember @@ -74,6 +74,8 @@ import com.example.jetsnack.model.SnackRepo import com.example.jetsnack.ui.components.JetsnackButton import com.example.jetsnack.ui.components.JetsnackDivider import com.example.jetsnack.ui.components.JetsnackSurface +import com.example.jetsnack.ui.components.JetsnackText +import com.example.jetsnack.ui.components.jetsnackTextStyle import com.example.jetsnack.ui.components.QuantitySelector import com.example.jetsnack.ui.components.SnackCollection import com.example.jetsnack.ui.components.SnackImage @@ -82,8 +84,10 @@ import com.example.jetsnack.ui.snackdetail.nonSpatialExpressiveSpring import com.example.jetsnack.ui.snackdetail.spatialExpressiveSpring import com.example.jetsnack.ui.theme.AlphaNearOpaque import com.example.jetsnack.ui.theme.JetsnackTheme +import com.example.jetsnack.ui.theme.LocalJetsnackColors import com.example.jetsnack.ui.utils.formatPrice import kotlin.math.roundToInt +import androidx.compose.ui.platform.LocalResources @Composable fun Cart( @@ -141,7 +145,7 @@ private fun CartContent( onSnackClick: (Long, String) -> Unit, modifier: Modifier = Modifier, ) { - val resources = LocalContext.current.resources + val resources = LocalResources.current val snackCountFormattedString = remember(orderLines.size, resources) { resources.getQuantityString( R.plurals.cart_order_count, @@ -157,10 +161,12 @@ private fun CartContent( WindowInsets.statusBars.add(WindowInsets(top = 56.dp)), ), ) - Text( + JetsnackText( text = stringResource(R.string.cart_order_header, snackCountFormattedString), - style = MaterialTheme.typography.titleLarge, - color = JetsnackTheme.colors.brand, + style = { + jetsnackTextStyle(LocalTypography.currentValue.titleLarge) + contentColor(LocalJetsnackColors.currentValue.brand) + }, maxLines = 1, overflow = TextOverflow.Ellipsis, modifier = Modifier @@ -269,11 +275,13 @@ private fun SwipeDismissItemBackground(progress: Float) { if (progress > 0.5f) 1f else 0.5f, label = "text alpha", ) if (progress > 0.5f) { - Text( + JetsnackText( text = stringResource(id = R.string.remove_item), - style = MaterialTheme.typography.titleMedium, - color = JetsnackTheme.colors.uiBackground, - textAlign = TextAlign.Center, + style = { + jetsnackTextStyle(LocalTypography.currentValue.titleMedium) + contentColor(LocalJetsnackColors.currentValue.uiBackground) + textAlign(TextAlign.Center) + }, modifier = Modifier .graphicsLayer( alpha = textAlpha, @@ -319,10 +327,12 @@ fun CartItem( .padding(start = 16.dp), ) { Row(modifier = Modifier.fillMaxWidth()) { - Text( + JetsnackText( text = snack.name, - style = MaterialTheme.typography.titleMedium, - color = JetsnackTheme.colors.textSecondary, + style = { + jetsnackTextStyle(LocalTypography.currentValue.titleMedium) + contentColor(LocalJetsnackColors.currentValue.textSecondary) + }, modifier = Modifier .weight(1f) .padding(top = 16.dp, end = 16.dp), @@ -338,20 +348,24 @@ fun CartItem( ) } } - Text( + JetsnackText( text = snack.tagline, - style = MaterialTheme.typography.bodyLarge, - color = JetsnackTheme.colors.textHelp, + style = { + jetsnackTextStyle(LocalTypography.currentValue.bodyLarge) + contentColor(LocalJetsnackColors.currentValue.textHelp) + }, modifier = Modifier.padding(end = 16.dp), ) Spacer(Modifier.height(8.dp)) Row( modifier = Modifier.fillMaxWidth(), ) { - Text( + JetsnackText( text = formatPrice(snack.price), - style = MaterialTheme.typography.titleMedium, - color = JetsnackTheme.colors.textPrimary, + style = { + jetsnackTextStyle(LocalTypography.currentValue.titleMedium) + contentColor(LocalJetsnackColors.currentValue.textPrimary) + }, modifier = Modifier .weight(1f) .padding(end = 16.dp) @@ -373,10 +387,12 @@ fun CartItem( @Composable fun SummaryItem(subtotal: Long, shippingCosts: Long, modifier: Modifier = Modifier) { Column(modifier) { - Text( + JetsnackText( text = stringResource(R.string.cart_summary_header), - style = MaterialTheme.typography.titleLarge, - color = JetsnackTheme.colors.brand, + style = { + jetsnackTextStyle(LocalTypography.currentValue.titleLarge) + contentColor(LocalJetsnackColors.currentValue.brand) + }, maxLines = 1, overflow = TextOverflow.Ellipsis, modifier = Modifier @@ -385,50 +401,62 @@ fun SummaryItem(subtotal: Long, shippingCosts: Long, modifier: Modifier = Modifi .wrapContentHeight(), ) Row(modifier = Modifier.padding(horizontal = 24.dp)) { - Text( + JetsnackText( text = stringResource(R.string.cart_subtotal_label), - style = MaterialTheme.typography.bodyLarge, + style = { + jetsnackTextStyle(LocalTypography.currentValue.bodyLarge) + }, modifier = Modifier .weight(1f) .wrapContentWidth(Alignment.Start) .alignBy(LastBaseline), ) - Text( + JetsnackText( text = formatPrice(subtotal), - style = MaterialTheme.typography.bodyLarge, + style = { + jetsnackTextStyle(LocalTypography.currentValue.bodyLarge) + }, modifier = Modifier.alignBy(LastBaseline), ) } Row(modifier = Modifier.padding(horizontal = 24.dp, vertical = 8.dp)) { - Text( + JetsnackText( text = stringResource(R.string.cart_shipping_label), - style = MaterialTheme.typography.bodyLarge, + style = { + jetsnackTextStyle(LocalTypography.currentValue.bodyLarge) + }, modifier = Modifier .weight(1f) .wrapContentWidth(Alignment.Start) .alignBy(LastBaseline), ) - Text( + JetsnackText( text = formatPrice(shippingCosts), - style = MaterialTheme.typography.bodyLarge, + style = { + jetsnackTextStyle(LocalTypography.currentValue.bodyLarge) + }, modifier = Modifier.alignBy(LastBaseline), ) } Spacer(modifier = Modifier.height(8.dp)) JetsnackDivider() Row(modifier = Modifier.padding(horizontal = 24.dp, vertical = 8.dp)) { - Text( + JetsnackText( text = stringResource(R.string.cart_total_label), - style = MaterialTheme.typography.bodyLarge, + style = { + jetsnackTextStyle(LocalTypography.currentValue.bodyLarge) + }, modifier = Modifier .weight(1f) .padding(end = 16.dp) .wrapContentWidth(Alignment.End) .alignBy(LastBaseline), ) - Text( + JetsnackText( text = formatPrice(subtotal + shippingCosts), - style = MaterialTheme.typography.titleMedium, + style = { + jetsnackTextStyle(LocalTypography.currentValue.titleMedium) + }, modifier = Modifier.alignBy(LastBaseline), ) } @@ -456,10 +484,12 @@ private fun CheckoutBar(modifier: Modifier = Modifier) { .padding(horizontal = 12.dp, vertical = 8.dp) .weight(1f), ) { - Text( + JetsnackText( text = stringResource(id = R.string.cart_checkout), modifier = Modifier.fillMaxWidth(), - textAlign = TextAlign.Left, + style = { + textAlign(TextAlign.Left) + }, maxLines = 1, ) } diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Categories.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Categories.kt index dba32a002..47dce9c49 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Categories.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Categories.kt @@ -30,8 +30,7 @@ import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text +import androidx.compose.material3.LocalTypography import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -45,9 +44,12 @@ import androidx.compose.ui.unit.dp import com.example.jetsnack.R import com.example.jetsnack.model.SearchCategory import com.example.jetsnack.model.SearchCategoryCollection +import com.example.jetsnack.ui.components.JetsnackText +import com.example.jetsnack.ui.components.jetsnackTextStyle import com.example.jetsnack.ui.components.SnackImage import com.example.jetsnack.ui.components.VerticalGrid import com.example.jetsnack.ui.theme.JetsnackTheme +import com.example.jetsnack.ui.theme.LocalJetsnackColors import kotlin.math.max @Composable @@ -63,10 +65,12 @@ fun SearchCategories(categories: List) { @Composable private fun SearchCategoryCollection(collection: SearchCategoryCollection, index: Int, modifier: Modifier = Modifier) { Column(modifier) { - Text( + JetsnackText( text = collection.name, - style = MaterialTheme.typography.titleLarge, - color = JetsnackTheme.colors.textPrimary, + style = { + jetsnackTextStyle(LocalTypography.currentValue.titleLarge) + contentColor(LocalJetsnackColors.currentValue.textPrimary) + }, modifier = Modifier .heightIn(min = 56.dp) .padding(horizontal = 24.dp, vertical = 4.dp) @@ -103,10 +107,12 @@ private fun SearchCategory(category: SearchCategory, gradient: List, modi .background(Brush.horizontalGradient(gradient)) .clickable { /* todo */ }, content = { - Text( + JetsnackText( text = category.name, - style = MaterialTheme.typography.titleMedium, - color = JetsnackTheme.colors.textSecondary, + style = { + jetsnackTextStyle(LocalTypography.currentValue.titleMedium) + contentColor(LocalJetsnackColors.currentValue.textSecondary) + }, modifier = Modifier .padding(4.dp) .padding(start = 8.dp), diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Results.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Results.kt index e2a74e017..e802d9ec3 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Results.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Results.kt @@ -34,8 +34,7 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text +import androidx.compose.material3.LocalTypography import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -50,17 +49,22 @@ import com.example.jetsnack.model.snacks import com.example.jetsnack.ui.components.JetsnackButton import com.example.jetsnack.ui.components.JetsnackDivider import com.example.jetsnack.ui.components.JetsnackSurface +import com.example.jetsnack.ui.components.JetsnackText +import com.example.jetsnack.ui.components.jetsnackTextStyle import com.example.jetsnack.ui.components.SnackImage import com.example.jetsnack.ui.theme.JetsnackTheme +import com.example.jetsnack.ui.theme.LocalJetsnackColors import com.example.jetsnack.ui.utils.formatPrice @Composable fun SearchResults(searchResults: List, onSnackClick: (Long, String) -> Unit) { Column { - Text( + JetsnackText( text = stringResource(R.string.search_count, searchResults.size), - style = MaterialTheme.typography.titleLarge, - color = JetsnackTheme.colors.textPrimary, + style = { + jetsnackTextStyle(LocalTypography.currentValue.titleLarge) + contentColor(LocalJetsnackColors.currentValue.textPrimary) + }, modifier = Modifier.padding(horizontal = 24.dp, vertical = 4.dp), ) LazyColumn { @@ -98,21 +102,27 @@ private fun SearchResult(snack: Snack, onSnackClick: (Long, String) -> Unit, sho .weight(1f) .padding(start = 16.dp, end = 16.dp), ) { - Text( + JetsnackText( text = snack.name, - style = MaterialTheme.typography.titleMedium, - color = JetsnackTheme.colors.textSecondary, + style = { + jetsnackTextStyle(LocalTypography.currentValue.titleMedium) + contentColor(LocalJetsnackColors.currentValue.textSecondary) + }, ) - Text( + JetsnackText( text = snack.tagline, - style = MaterialTheme.typography.bodyLarge, - color = JetsnackTheme.colors.textHelp, + style = { + jetsnackTextStyle(LocalTypography.currentValue.bodyLarge) + contentColor(LocalJetsnackColors.currentValue.textHelp) + }, ) Spacer(Modifier.height(8.dp)) - Text( + JetsnackText( text = formatPrice(snack.price), - style = MaterialTheme.typography.titleMedium, - color = JetsnackTheme.colors.textPrimary, + style = { + jetsnackTextStyle(LocalTypography.currentValue.titleMedium) + contentColor(LocalJetsnackColors.currentValue.textPrimary) + }, ) } JetsnackButton( @@ -146,17 +156,21 @@ fun NoResults(query: String, modifier: Modifier = Modifier) { contentDescription = null, ) Spacer(Modifier.height(24.dp)) - Text( + JetsnackText( text = stringResource(R.string.search_no_matches, query), - style = MaterialTheme.typography.titleMedium, - textAlign = TextAlign.Center, + style = { + jetsnackTextStyle(LocalTypography.currentValue.titleMedium) + textAlign(TextAlign.Center) + }, modifier = Modifier.fillMaxWidth(), ) Spacer(Modifier.height(16.dp)) - Text( + JetsnackText( text = stringResource(R.string.search_no_matches_retry), - style = MaterialTheme.typography.bodyMedium, - textAlign = TextAlign.Center, + style = { + jetsnackTextStyle(LocalTypography.currentValue.bodyMedium) + textAlign(TextAlign.Center) + }, modifier = Modifier.fillMaxWidth(), ) } diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Search.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Search.kt index 85d95e31e..823322656 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Search.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Search.kt @@ -35,8 +35,7 @@ import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.LocalShapes -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text +import androidx.compose.material3.LocalTypography import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.Stable @@ -61,6 +60,7 @@ import com.example.jetsnack.model.Snack import com.example.jetsnack.model.SnackRepo import com.example.jetsnack.ui.components.JetsnackDivider import com.example.jetsnack.ui.components.JetsnackSurface +import com.example.jetsnack.ui.components.JetsnackText import com.example.jetsnack.ui.theme.JetsnackTheme import com.example.jetsnack.ui.theme.LocalJetsnackColors @@ -241,9 +241,11 @@ private fun SearchHint() { contentDescription = stringResource(R.string.label_search), ) Spacer(Modifier.width(8.dp)) - Text( + JetsnackText( text = stringResource(R.string.search_jetsnack), - color = JetsnackTheme.colors.textHelp, + style = { + contentColor(LocalJetsnackColors.currentValue.textHelp) + } ) } } diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Suggestions.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Suggestions.kt index 62b9ff40c..306a2f29a 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Suggestions.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Suggestions.kt @@ -26,8 +26,7 @@ import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text +import androidx.compose.material3.LocalTypography import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -36,7 +35,10 @@ import androidx.compose.ui.unit.dp import com.example.jetsnack.model.SearchRepo import com.example.jetsnack.model.SearchSuggestionGroup import com.example.jetsnack.ui.components.JetsnackSurface +import com.example.jetsnack.ui.components.JetsnackText +import com.example.jetsnack.ui.components.jetsnackTextStyle import com.example.jetsnack.ui.theme.JetsnackTheme +import com.example.jetsnack.ui.theme.LocalJetsnackColors @Composable fun SearchSuggestions(suggestions: List, onSuggestionSelect: (String) -> Unit) { @@ -61,10 +63,12 @@ fun SearchSuggestions(suggestions: List, onSuggestionSele @Composable private fun SuggestionHeader(name: String, modifier: Modifier = Modifier) { - Text( + JetsnackText( text = name, - style = MaterialTheme.typography.titleLarge, - color = JetsnackTheme.colors.textPrimary, + style = { + jetsnackTextStyle(LocalTypography.currentValue.titleLarge) + contentColor(LocalJetsnackColors.currentValue.textPrimary) + }, modifier = modifier .heightIn(min = 56.dp) .padding(horizontal = 24.dp, vertical = 4.dp) @@ -74,9 +78,11 @@ private fun SuggestionHeader(name: String, modifier: Modifier = Modifier) { @Composable private fun Suggestion(suggestion: String, onSuggestionSelect: (String) -> Unit, modifier: Modifier = Modifier) { - Text( + JetsnackText( text = suggestion, - style = MaterialTheme.typography.titleMedium, + style = { + jetsnackTextStyle(LocalTypography.currentValue.titleMedium) + }, modifier = modifier .heightIn(min = 48.dp) .clickable { onSuggestionSelect(suggestion) } diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/snackdetail/SnackDetail.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/snackdetail/SnackDetail.kt index 32cf6dd0c..55d33fade 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/snackdetail/SnackDetail.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/snackdetail/SnackDetail.kt @@ -61,11 +61,12 @@ import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.style.fillWidth import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Icon import androidx.compose.material3.IconButton +import androidx.compose.material3.LocalTypography import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.key @@ -107,10 +108,13 @@ import com.example.jetsnack.ui.components.JetsnackButton import com.example.jetsnack.ui.components.JetsnackDivider import com.example.jetsnack.ui.components.JetsnackPreviewWrapper import com.example.jetsnack.ui.components.JetsnackSurface +import com.example.jetsnack.ui.components.JetsnackText +import com.example.jetsnack.ui.components.jetsnackTextStyle import com.example.jetsnack.ui.components.QuantitySelector import com.example.jetsnack.ui.components.SnackCollection import com.example.jetsnack.ui.components.SnackImage import com.example.jetsnack.ui.theme.JetsnackTheme +import com.example.jetsnack.ui.theme.LocalJetsnackColors import com.example.jetsnack.ui.theme.Neutral8 import com.example.jetsnack.ui.utils.formatPrice import kotlin.math.max @@ -303,23 +307,27 @@ private fun Body(related: List, scroll: ScrollState) { ) { Column { Spacer(Modifier.height(TitleHeight)) - Text( + JetsnackText( text = stringResource(R.string.detail_header), - style = MaterialTheme.typography.labelSmall, - color = JetsnackTheme.colors.textHelp, - modifier = HzPadding, + style = { + jetsnackTextStyle(LocalTypography.currentValue.headlineMedium) + contentColor(LocalJetsnackColors.currentValue.textHelp) + contentPaddingHorizontal(24.dp) + } ) Spacer(Modifier.height(16.dp)) var seeMore by remember { mutableStateOf(true) } with(sharedTransitionScope) { - Text( + JetsnackText( text = stringResource(R.string.detail_placeholder), - style = MaterialTheme.typography.bodyLarge, - color = JetsnackTheme.colors.textHelp, + style = { + jetsnackTextStyle(LocalTypography.currentValue.bodyLarge) + contentColor(LocalJetsnackColors.currentValue.textHelp) + contentPaddingHorizontal(24.dp) + }, maxLines = if (seeMore) 5 else Int.MAX_VALUE, overflow = TextOverflow.Ellipsis, - modifier = HzPadding.skipToLookaheadSize(), - + modifier = Modifier.skipToLookaheadSize(), ) } val textButton = if (seeMore) { @@ -328,15 +336,17 @@ private fun Body(related: List, scroll: ScrollState) { stringResource(id = R.string.see_less) } - Text( + JetsnackText( text = textButton, - style = MaterialTheme.typography.labelLarge, - textAlign = TextAlign.Center, - color = JetsnackTheme.colors.textLink, + style = { + jetsnackTextStyle(LocalTypography.currentValue.labelLarge) + contentColor(LocalJetsnackColors.currentValue.textLink) + textAlign(TextAlign.Center) + contentPaddingTop(15.dp) + fillWidth() + }, modifier = Modifier .heightIn(20.dp) - .fillMaxWidth() - .padding(top = 15.dp) .clickable { seeMore = !seeMore } @@ -344,18 +354,22 @@ private fun Body(related: List, scroll: ScrollState) { ) Spacer(Modifier.height(40.dp)) - Text( + JetsnackText( text = stringResource(R.string.ingredients), - style = MaterialTheme.typography.labelSmall, - color = JetsnackTheme.colors.textHelp, - modifier = HzPadding, + style = { + jetsnackTextStyle(LocalTypography.currentValue.labelSmall) + contentColor(LocalJetsnackColors.currentValue.textHelp) + contentPaddingHorizontal(24.dp) + } ) Spacer(Modifier.height(4.dp)) - Text( + JetsnackText( text = stringResource(R.string.ingredients_list), - style = MaterialTheme.typography.bodyLarge, - color = JetsnackTheme.colors.textHelp, - modifier = HzPadding, + style = { + jetsnackTextStyle(LocalTypography.currentValue.bodyLarge) + contentColor(LocalJetsnackColors.currentValue.textHelp) + contentPaddingHorizontal(24.dp) + } ) Spacer(Modifier.height(16.dp)) @@ -408,11 +422,13 @@ private fun Title(snack: Snack, origin: String, scrollProvider: () -> Int) { .background(JetsnackTheme.colors.uiBackground), ) { Spacer(Modifier.height(16.dp)) - Text( + JetsnackText( text = snack.name, - fontStyle = FontStyle.Italic, - style = MaterialTheme.typography.headlineMedium, - color = JetsnackTheme.colors.textSecondary, + style = { + jetsnackTextStyle(LocalTypography.currentValue.headlineMedium) + contentColor(LocalJetsnackColors.currentValue.textSecondary) + fontStyle(FontStyle.Italic) + }, modifier = HzPadding .sharedBounds( rememberSharedContentState( @@ -427,12 +443,14 @@ private fun Title(snack: Snack, origin: String, scrollProvider: () -> Int) { ) .wrapContentWidth(), ) - Text( + JetsnackText( text = snack.tagline, - fontStyle = FontStyle.Italic, - style = MaterialTheme.typography.titleSmall, - fontSize = 20.sp, - color = JetsnackTheme.colors.textHelp, + style = { + jetsnackTextStyle(LocalTypography.currentValue.titleSmall) + fontStyle(FontStyle.Italic) + contentColor(LocalJetsnackColors.currentValue.textHelp) + fontSize(20.sp) + }, modifier = HzPadding .sharedBounds( rememberSharedContentState( @@ -449,10 +467,12 @@ private fun Title(snack: Snack, origin: String, scrollProvider: () -> Int) { ) Spacer(Modifier.height(4.dp)) with(animatedVisibilityScope) { - Text( + JetsnackText( text = formatPrice(snack.price), - style = MaterialTheme.typography.titleLarge, - color = JetsnackTheme.colors.textPrimary, + style = { + jetsnackTextStyle(LocalTypography.currentValue.titleLarge) + contentColor(LocalJetsnackColors.currentValue.textPrimary) + }, modifier = HzPadding .animateEnterExit( enter = fadeIn() + slideInVertically { -it / 3 }, @@ -586,10 +606,12 @@ private fun CartBottomBar(modifier: Modifier = Modifier) { onClick = { /* todo */ }, modifier = Modifier.weight(1f), ) { - Text( + JetsnackText( text = stringResource(R.string.add_to_cart), modifier = Modifier.fillMaxWidth(), - textAlign = TextAlign.Center, + style = { + textAlign(TextAlign.Center) + }, maxLines = 1, ) } diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/theme/Styles.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/theme/Styles.kt index 41ecc7863..741ce488b 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/theme/Styles.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/theme/Styles.kt @@ -8,17 +8,22 @@ import androidx.compose.foundation.style.ExperimentalFoundationStyleApi import androidx.compose.foundation.style.Style import androidx.compose.foundation.style.disabled import androidx.compose.foundation.style.fillWidth +import androidx.compose.foundation.style.hovered import androidx.compose.foundation.style.pressed import androidx.compose.foundation.style.selected import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.LocalShapes +import androidx.compose.material3.LocalTextStyle import androidx.compose.material3.LocalTypography +import androidx.compose.material3.Typography import androidx.compose.runtime.Immutable +import androidx.compose.runtime.ProvidableCompositionLocal import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.graphics.TileMode import androidx.compose.ui.unit.dp +import com.example.jetsnack.ui.components.jetsnackTextStyle @Immutable data class AppStyles( @@ -27,7 +32,7 @@ data class AppStyles( background(Brush.linearGradient(LocalJetsnackColors.currentValue.interactivePrimary)) contentColor(LocalJetsnackColors.currentValue.textInteractive) contentPadding( ButtonDefaults.ContentPadding.calculateTopPadding()) // todo file issue to support padding values - textStyle(LocalTypography.currentValue.labelLarge) + jetsnackTextStyle(LocalTypography.currentValue.labelLarge) disabled { animate { background(Brush.linearGradient(LocalJetsnackColors.currentValue.interactiveSecondary)) @@ -59,7 +64,7 @@ data class AppStyles( // this was a parameter input into the function? might want to make helper function for it colors = LocalJetsnackColors.currentValue.interactiveSecondary, startX = 0f, - endX = 200f, // todo double check px/dp + endX = 200f, tileMode = TileMode.Mirror, )) } @@ -79,8 +84,8 @@ data class AppStyles( } } }, - val scaffoldStyle: Style = Style { - + val defaultTextStyle: Style = Style { + jetsnackTextStyle(LocalTextStyle.currentValue) }, val surfaceStyle: Style = Style { shape(RectangleShape) @@ -88,4 +93,4 @@ data class AppStyles( contentColor(LocalJetsnackColors.currentValue.textSecondary) clip(true) } -) \ No newline at end of file +)