From c7208610ae68df808949d45cb260e126c17ae46f Mon Sep 17 00:00:00 2001 From: Rebecca Franks Date: Fri, 13 Mar 2026 16:28:27 +0000 Subject: [PATCH 01/11] 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 0fca21037b..2d1d6a086d 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 0000000000..df849fbc1c --- /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 794bd3f1d7..8ba8ac1af6 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 8507472164..04d6ecd776 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 089313675a..98c4b1d475 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 30121ea109..ff753cbfd8 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 1a7fba80c4..58c94ef17b 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 39ebb9070e..c65086d21e 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 4952bd2768..f4b21bcee8 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 028ee2b1ce..12dc5e31ec 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 1104c51f1e..1346999427 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 b706ea8bb3..7eba0922c4 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 10e3125ce5..39ccd8e74b 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 28d1f4b927..072b04001f 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 6268546131..5afdf18663 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 05aebc129f..e2a74e017a 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 33e84c51e7..85d95e31ed 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 0000000000..41ecc7863e --- /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 ad0a8e66c1..2ad96a0f0a 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 c51b64c942..c10875b44e 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 02/11] 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 8ba8ac1af6..45c2622aad 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 04d6ecd776..e8f4f2bf35 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 ff753cbfd8..0c88fd7184 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 f4b21bcee8..dc14bcdd69 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 12dc5e31ec..cd3ee0ae8c 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 0000000000..4f3a514699 --- /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 7eba0922c4..f886354763 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 f2c0dcabc4..3b928c01a2 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 072b04001f..4dd136751b 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 799fa28f3e..2c6a524cec 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 5afdf18663..7dc5352871 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 dba32a0023..47dce9c495 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 e2a74e017a..e802d9ec34 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 85d95e31ed..823322656c 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 62b9ff40c1..306a2f29a7 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 32cf6dd0c5..55d33fadec 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 41ecc7863e..741ce488b9 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 +) From f89e3801258dccf2e2559f3a5aeb21b945ba5af8 Mon Sep 17 00:00:00 2001 From: Rebecca Franks Date: Mon, 16 Mar 2026 12:04:43 +0000 Subject: [PATCH 03/11] Refactor Jetsnack theme to use a unified `JetsnackTheme` class and one `CompositionLocal`. - Deleted `CompositionLocals.kt` which used reflection to access internal Material 3 locals. - Introduced `JetsnackTheme` class to encapsulate `JetsnackColors`, `Typography`, `Shapes`, and `AppStyles`. - Replaced individual `LocalJetsnackColors`, `LocalAppStyles`, and Material 3 `LocalTypography`/`LocalShapes` lookups with `JetsnackTheme.colors`, `JetsnackTheme.typography`, etc. - Added a `StyleScope.currentJetsnackTheme` helper to provide easy access to the theme within `Style` blocks. - Moved `JetsnackColors` and color palette definitions to `Color.kt`. - Updated `debugColors` to include newer Material 3 color roles. --- .../compose/material3/CompositionLocals.kt | 41 ---- .../example/jetsnack/ui/components/Divider.kt | 4 +- .../example/jetsnack/ui/components/Filters.kt | 10 +- .../ui/components/QuantitySelector.kt | 11 +- .../example/jetsnack/ui/components/Snacks.kt | 22 +- .../example/jetsnack/ui/components/Text.kt | 4 +- .../jetsnack/ui/home/DestinationBar.kt | 7 +- .../example/jetsnack/ui/home/FilterScreen.kt | 19 +- .../java/com/example/jetsnack/ui/home/Home.kt | 4 +- .../com/example/jetsnack/ui/home/Profile.kt | 6 +- .../com/example/jetsnack/ui/home/cart/Cart.kt | 39 ++-- .../jetsnack/ui/home/search/Categories.kt | 11 +- .../jetsnack/ui/home/search/Results.kt | 23 +- .../example/jetsnack/ui/home/search/Search.kt | 12 +- .../jetsnack/ui/home/search/Suggestions.kt | 9 +- .../jetsnack/ui/snackdetail/SnackDetail.kt | 35 ++-- .../com/example/jetsnack/ui/theme/Color.kt | 146 +++++++++++++ .../com/example/jetsnack/ui/theme/Styles.kt | 47 ++--- .../com/example/jetsnack/ui/theme/Theme.kt | 198 ++++-------------- 19 files changed, 311 insertions(+), 337 deletions(-) delete mode 100644 Jetsnack/app/src/main/java/androidx/compose/material3/CompositionLocals.kt diff --git a/Jetsnack/app/src/main/java/androidx/compose/material3/CompositionLocals.kt b/Jetsnack/app/src/main/java/androidx/compose/material3/CompositionLocals.kt deleted file mode 100644 index df849fbc1c..0000000000 --- a/Jetsnack/app/src/main/java/androidx/compose/material3/CompositionLocals.kt +++ /dev/null @@ -1,41 +0,0 @@ -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/Divider.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Divider.kt index 98c4b1d475..88b35269a4 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 @@ -31,14 +31,14 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.example.jetsnack.ui.theme.JetsnackTheme -import com.example.jetsnack.ui.theme.LocalAppStyles +import com.example.jetsnack.ui.theme.JetsnackTheme.Companion.LocalJetsnackTheme @Composable fun JetsnackDivider( modifier: Modifier = Modifier, style: Style = Style ) { - Box(modifier = modifier.styleable(null, LocalAppStyles.current.dividerStyle, style)) + Box(modifier = modifier.styleable(null, LocalJetsnackTheme.current.appStyles.dividerStyle, style)) } 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 0c88fd7184..92b11cbedd 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 @@ -40,8 +40,6 @@ 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.LocalTypography import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Alignment @@ -57,7 +55,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 +import com.example.jetsnack.ui.theme.currentJetsnackTheme @Composable fun FilterBar( @@ -100,7 +98,7 @@ fun FilterBar( FilterChip( filter = filter, style = Style { - shape(LocalShapes.currentValue.small) + shape(currentJetsnackTheme.shapes.small) }, ) } @@ -141,7 +139,7 @@ fun FilterChip( animate { background( Brush.horizontalGradient( - colors = LocalJetsnackColors.currentValue.interactiveSecondary, + colors = currentJetsnackTheme.colors.interactiveSecondary, startX = 0f, endX = 200f, tileMode = TileMode.Mirror, @@ -157,7 +155,7 @@ fun FilterChip( JetsnackText( text = filter.name, style = { - jetsnackTextStyle(LocalTypography.currentValue.bodySmall) + jetsnackTextStyle(currentJetsnackTheme.typography.bodySmall) }, maxLines = 1, modifier = Modifier.padding( 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 dc14bcdd69..a8e15c37cc 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,7 +24,6 @@ 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.LocalTypography import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Alignment @@ -39,7 +38,7 @@ 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 +import com.example.jetsnack.ui.theme.currentJetsnackTheme @Composable fun QuantitySelector(count: Int, decreaseItemCount: () -> Unit, increaseItemCount: () -> Unit, modifier: Modifier = Modifier) { @@ -47,8 +46,8 @@ fun QuantitySelector(count: Int, decreaseItemCount: () -> Unit, increaseItemCoun JetsnackText( text = stringResource(R.string.quantity), style = { - jetsnackTextStyle(LocalTypography.currentValue.titleMedium) - contentColor(LocalJetsnackColors.currentValue.textSecondary) + jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) + contentColor(currentJetsnackTheme.colors.textSecondary) fontWeight(FontWeight.Normal) }, modifier = Modifier @@ -69,9 +68,9 @@ fun QuantitySelector(count: Int, decreaseItemCount: () -> Unit, increaseItemCoun JetsnackText( text = "$it", style = { - jetsnackTextStyle(LocalTypography.currentValue.titleSmall) + jetsnackTextStyle(currentJetsnackTheme.typography.titleSmall) fontSize(18.sp) - contentColor(LocalJetsnackColors.currentValue.textPrimary) + contentColor(currentJetsnackTheme.colors.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 cd3ee0ae8c..b0423c0fab 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 @@ -53,8 +53,6 @@ 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.LocalTypography import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.getValue @@ -85,7 +83,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 +import com.example.jetsnack.ui.theme.currentJetsnackTheme private val HighlightCardWidth = 170.dp private val HighlightCardPadding = 16.dp @@ -110,8 +108,8 @@ fun SnackCollection( JetsnackText( text = snackCollection.name, style = { - jetsnackTextStyle(LocalTypography.currentValue.titleLarge) - contentColor(LocalJetsnackColors.currentValue.brand) + jetsnackTextStyle(currentJetsnackTheme.typography.titleLarge) + contentColor(currentJetsnackTheme.colors.brand) }, maxLines = 1, overflow = TextOverflow.Ellipsis, @@ -195,7 +193,7 @@ private fun Snacks(snackCollectionId: Long, snacks: List, onSnackClick: ( fun SnackItem(snack: Snack, snackCollectionId: Long, onSnackClick: (Long, String) -> Unit, modifier: Modifier = Modifier) { JetsnackSurface( style = { - shape(LocalShapes.currentValue.medium) + shape(currentJetsnackTheme.shapes.medium) }, modifier = modifier.padding( start = 4.dp, @@ -239,8 +237,8 @@ fun SnackItem(snack: Snack, snackCollectionId: Long, onSnackClick: (Long, String JetsnackText( text = snack.name, style = { - jetsnackTextStyle(LocalTypography.currentValue.titleMedium) - contentColor(LocalJetsnackColors.currentValue.textSecondary) + jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) + contentColor(currentJetsnackTheme.colors.textSecondary) }, modifier = Modifier .padding(top = 8.dp) @@ -400,8 +398,8 @@ private fun HighlightSnackItem( maxLines = 1, overflow = TextOverflow.Ellipsis, style = { - jetsnackTextStyle(LocalTypography.currentValue.titleLarge) - contentColor(LocalJetsnackColors.currentValue.textSecondary) + jetsnackTextStyle(currentJetsnackTheme.typography.titleLarge) + contentColor(currentJetsnackTheme.colors.textSecondary) }, modifier = Modifier .padding(horizontal = 16.dp) @@ -426,8 +424,8 @@ private fun HighlightSnackItem( JetsnackText( text = snack.tagline, style = { - jetsnackTextStyle(LocalTypography.currentValue.bodyLarge) - contentColor(LocalJetsnackColors.currentValue.textHelp) + jetsnackTextStyle(currentJetsnackTheme.typography.bodyLarge) + contentColor(currentJetsnackTheme.colors.textHelp) }, modifier = Modifier .padding(horizontal = 16.dp) 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 index 4f3a514699..2b3a9af21b 100644 --- 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 @@ -11,7 +11,7 @@ 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 +import com.example.jetsnack.ui.theme.JetsnackTheme // Workaround for b/492528450 - setting textStyle currently doesn't set fontFamily. @ExperimentalFoundationStyleApi @@ -35,7 +35,7 @@ fun JetsnackText( ) { BasicText( text = text, - modifier = modifier.styleable(null, LocalAppStyles.current.defaultTextStyle, style), + modifier = modifier.styleable(null, JetsnackTheme.appStyles.defaultTextStyle, style), onTextLayout = onTextLayout, overflow = overflow, softWrap = softWrap, 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 f886354763..a986b7743a 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,7 +29,6 @@ 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.LocalTypography import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable @@ -50,7 +49,7 @@ 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 +import com.example.jetsnack.ui.theme.currentJetsnackTheme @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -76,8 +75,8 @@ fun DestinationBar(modifier: Modifier = Modifier) { JetsnackText( text = "Delivery to 1600 Amphitheater Way", style = { - jetsnackTextStyle(LocalTypography.currentValue.titleMedium) - contentColor(LocalJetsnackColors.currentValue.textSecondary) + jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) + contentColor(currentJetsnackTheme.colors.textSecondary) textAlign(TextAlign.Center) }, maxLines = 1, 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 3b928c01a2..7bd9e102d1 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,7 +46,6 @@ 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 @@ -74,7 +73,7 @@ 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 +import com.example.jetsnack.ui.theme.currentJetsnackTheme @Composable fun FilterScreen(sharedTransitionScope: SharedTransitionScope, animatedVisibilityScope: AnimatedVisibilityScope, onDismiss: () -> Unit) { @@ -144,7 +143,7 @@ fun FilterScreen(sharedTransitionScope: SharedTransitionScope, animatedVisibilit .padding(top = 8.dp, end = 48.dp), style = { textAlign(TextAlign.Center) - jetsnackTextStyle(LocalTypography.currentValue.titleLarge) + jetsnackTextStyle(currentJetsnackTheme.typography.titleLarge) } ) val resetEnabled = sortState != defaultFilter @@ -162,10 +161,10 @@ fun FilterScreen(sharedTransitionScope: SharedTransitionScope, animatedVisibilit JetsnackText( text = stringResource(id = R.string.reset), style = { - jetsnackTextStyle(LocalTypography.currentValue.bodyMedium) + jetsnackTextStyle(currentJetsnackTheme.typography.bodyMedium) fontWeight(fontWeight) contentColor( - LocalJetsnackColors.currentValue.uiBackground + currentJetsnackTheme.colors.uiBackground .copy(alpha = if (!resetEnabled) 0.38f else 1f) ) } @@ -255,8 +254,8 @@ fun MaxCalories(sliderPosition: Float, onValueChanged: (Float) -> Unit) { JetsnackText( text = stringResource(id = R.string.per_serving), style = { - jetsnackTextStyle(LocalTypography.currentValue.bodyMedium) - contentColor(LocalJetsnackColors.currentValue.brand) + jetsnackTextStyle(currentJetsnackTheme.typography.bodyMedium) + contentColor(currentJetsnackTheme.colors.brand) }, modifier = Modifier.padding(top = 5.dp, start = 10.dp), ) @@ -283,8 +282,8 @@ fun FilterTitle(text: String) { JetsnackText( text = text, style = { - jetsnackTextStyle(LocalTypography.currentValue.titleLarge) - contentColor(LocalJetsnackColors.currentValue.brand) + jetsnackTextStyle(currentJetsnackTheme.typography.titleLarge) + contentColor(currentJetsnackTheme.colors.brand) }, modifier = Modifier.padding(bottom = 8.dp), ) @@ -303,7 +302,7 @@ fun SortOption(text: String, @DrawableRes icon: Int?, onClickOption: () -> Unit, JetsnackText( text = text, style = { - jetsnackTextStyle(LocalTypography.currentValue.titleMedium) + jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) }, modifier = Modifier .padding(start = 10.dp) 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 4dd136751b..ada5b2abd0 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,7 +41,6 @@ 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.LocalTypography import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.LaunchedEffect @@ -82,6 +81,7 @@ import com.example.jetsnack.ui.home.search.Search import com.example.jetsnack.ui.snackdetail.nonSpatialExpressiveSpring import com.example.jetsnack.ui.snackdetail.spatialExpressiveSpring import com.example.jetsnack.ui.theme.JetsnackTheme +import com.example.jetsnack.ui.theme.currentJetsnackTheme import java.util.Locale import androidx.compose.ui.platform.LocalLocale @@ -219,7 +219,7 @@ fun JetsnackBottomBar( text = text, style = { contentColor(tint) - jetsnackTextStyle(LocalTypography.currentValue.labelLarge) + jetsnackTextStyle(currentJetsnackTheme.typography.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 2c6a524cec..8510712f33 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,7 +25,6 @@ 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.LocalTypography import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -38,6 +37,7 @@ 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 +import com.example.jetsnack.ui.theme.currentJetsnackTheme @Composable fun Profile(modifier: Modifier = Modifier) { @@ -56,7 +56,7 @@ fun Profile(modifier: Modifier = Modifier) { JetsnackText( text = stringResource(R.string.work_in_progress), style = { - jetsnackTextStyle(LocalTypography.currentValue.titleMedium) + jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) textAlign(TextAlign.Center) }, modifier = Modifier.fillMaxWidth(), @@ -65,7 +65,7 @@ fun Profile(modifier: Modifier = Modifier) { JetsnackText( text = stringResource(R.string.grab_beverage), style = { - jetsnackTextStyle(LocalTypography.currentValue.bodyMedium) + jetsnackTextStyle(currentJetsnackTheme.typography.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 7dc5352871..a638c1b790 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,7 +45,6 @@ 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.runtime.Composable @@ -84,7 +83,7 @@ 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.theme.currentJetsnackTheme import com.example.jetsnack.ui.utils.formatPrice import kotlin.math.roundToInt import androidx.compose.ui.platform.LocalResources @@ -164,8 +163,8 @@ private fun CartContent( JetsnackText( text = stringResource(R.string.cart_order_header, snackCountFormattedString), style = { - jetsnackTextStyle(LocalTypography.currentValue.titleLarge) - contentColor(LocalJetsnackColors.currentValue.brand) + jetsnackTextStyle(currentJetsnackTheme.typography.titleLarge) + contentColor(currentJetsnackTheme.colors.brand) }, maxLines = 1, overflow = TextOverflow.Ellipsis, @@ -278,8 +277,8 @@ private fun SwipeDismissItemBackground(progress: Float) { JetsnackText( text = stringResource(id = R.string.remove_item), style = { - jetsnackTextStyle(LocalTypography.currentValue.titleMedium) - contentColor(LocalJetsnackColors.currentValue.uiBackground) + jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) + contentColor(currentJetsnackTheme.colors.uiBackground) textAlign(TextAlign.Center) }, modifier = Modifier @@ -330,8 +329,8 @@ fun CartItem( JetsnackText( text = snack.name, style = { - jetsnackTextStyle(LocalTypography.currentValue.titleMedium) - contentColor(LocalJetsnackColors.currentValue.textSecondary) + jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) + contentColor(currentJetsnackTheme.colors.textSecondary) }, modifier = Modifier .weight(1f) @@ -351,8 +350,8 @@ fun CartItem( JetsnackText( text = snack.tagline, style = { - jetsnackTextStyle(LocalTypography.currentValue.bodyLarge) - contentColor(LocalJetsnackColors.currentValue.textHelp) + jetsnackTextStyle(currentJetsnackTheme.typography.bodyLarge) + contentColor(currentJetsnackTheme.colors.textHelp) }, modifier = Modifier.padding(end = 16.dp), ) @@ -363,8 +362,8 @@ fun CartItem( JetsnackText( text = formatPrice(snack.price), style = { - jetsnackTextStyle(LocalTypography.currentValue.titleMedium) - contentColor(LocalJetsnackColors.currentValue.textPrimary) + jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) + contentColor(currentJetsnackTheme.colors.textPrimary) }, modifier = Modifier .weight(1f) @@ -390,8 +389,8 @@ fun SummaryItem(subtotal: Long, shippingCosts: Long, modifier: Modifier = Modifi JetsnackText( text = stringResource(R.string.cart_summary_header), style = { - jetsnackTextStyle(LocalTypography.currentValue.titleLarge) - contentColor(LocalJetsnackColors.currentValue.brand) + jetsnackTextStyle(currentJetsnackTheme.typography.titleLarge) + contentColor(currentJetsnackTheme.colors.brand) }, maxLines = 1, overflow = TextOverflow.Ellipsis, @@ -404,7 +403,7 @@ fun SummaryItem(subtotal: Long, shippingCosts: Long, modifier: Modifier = Modifi JetsnackText( text = stringResource(R.string.cart_subtotal_label), style = { - jetsnackTextStyle(LocalTypography.currentValue.bodyLarge) + jetsnackTextStyle(currentJetsnackTheme.typography.bodyLarge) }, modifier = Modifier .weight(1f) @@ -414,7 +413,7 @@ fun SummaryItem(subtotal: Long, shippingCosts: Long, modifier: Modifier = Modifi JetsnackText( text = formatPrice(subtotal), style = { - jetsnackTextStyle(LocalTypography.currentValue.bodyLarge) + jetsnackTextStyle(currentJetsnackTheme.typography.bodyLarge) }, modifier = Modifier.alignBy(LastBaseline), ) @@ -423,7 +422,7 @@ fun SummaryItem(subtotal: Long, shippingCosts: Long, modifier: Modifier = Modifi JetsnackText( text = stringResource(R.string.cart_shipping_label), style = { - jetsnackTextStyle(LocalTypography.currentValue.bodyLarge) + jetsnackTextStyle(currentJetsnackTheme.typography.bodyLarge) }, modifier = Modifier .weight(1f) @@ -433,7 +432,7 @@ fun SummaryItem(subtotal: Long, shippingCosts: Long, modifier: Modifier = Modifi JetsnackText( text = formatPrice(shippingCosts), style = { - jetsnackTextStyle(LocalTypography.currentValue.bodyLarge) + jetsnackTextStyle(currentJetsnackTheme.typography.bodyLarge) }, modifier = Modifier.alignBy(LastBaseline), ) @@ -444,7 +443,7 @@ fun SummaryItem(subtotal: Long, shippingCosts: Long, modifier: Modifier = Modifi JetsnackText( text = stringResource(R.string.cart_total_label), style = { - jetsnackTextStyle(LocalTypography.currentValue.bodyLarge) + jetsnackTextStyle(currentJetsnackTheme.typography.bodyLarge) }, modifier = Modifier .weight(1f) @@ -455,7 +454,7 @@ fun SummaryItem(subtotal: Long, shippingCosts: Long, modifier: Modifier = Modifi JetsnackText( text = formatPrice(subtotal + shippingCosts), style = { - jetsnackTextStyle(LocalTypography.currentValue.titleMedium) + jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) }, modifier = Modifier.alignBy(LastBaseline), ) 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 47dce9c495..b545fc45af 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,7 +30,6 @@ 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.LocalTypography import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -49,7 +48,7 @@ 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 com.example.jetsnack.ui.theme.currentJetsnackTheme import kotlin.math.max @Composable @@ -68,8 +67,8 @@ private fun SearchCategoryCollection(collection: SearchCategoryCollection, index JetsnackText( text = collection.name, style = { - jetsnackTextStyle(LocalTypography.currentValue.titleLarge) - contentColor(LocalJetsnackColors.currentValue.textPrimary) + jetsnackTextStyle(currentJetsnackTheme.typography.titleLarge) + contentColor(currentJetsnackTheme.colors.textPrimary) }, modifier = Modifier .heightIn(min = 56.dp) @@ -110,8 +109,8 @@ private fun SearchCategory(category: SearchCategory, gradient: List, modi JetsnackText( text = category.name, style = { - jetsnackTextStyle(LocalTypography.currentValue.titleMedium) - contentColor(LocalJetsnackColors.currentValue.textSecondary) + jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) + contentColor(currentJetsnackTheme.colors.textSecondary) }, modifier = Modifier .padding(4.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 e802d9ec34..53f810ede7 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,7 +34,6 @@ 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.LocalTypography import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -53,7 +52,7 @@ 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.theme.currentJetsnackTheme import com.example.jetsnack.ui.utils.formatPrice @Composable @@ -62,8 +61,8 @@ fun SearchResults(searchResults: List, onSnackClick: (Long, String) -> Un JetsnackText( text = stringResource(R.string.search_count, searchResults.size), style = { - jetsnackTextStyle(LocalTypography.currentValue.titleLarge) - contentColor(LocalJetsnackColors.currentValue.textPrimary) + jetsnackTextStyle(currentJetsnackTheme.typography.titleLarge) + contentColor(currentJetsnackTheme.colors.textPrimary) }, modifier = Modifier.padding(horizontal = 24.dp, vertical = 4.dp), ) @@ -105,23 +104,23 @@ private fun SearchResult(snack: Snack, onSnackClick: (Long, String) -> Unit, sho JetsnackText( text = snack.name, style = { - jetsnackTextStyle(LocalTypography.currentValue.titleMedium) - contentColor(LocalJetsnackColors.currentValue.textSecondary) + jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) + contentColor(currentJetsnackTheme.colors.textSecondary) }, ) JetsnackText( text = snack.tagline, style = { - jetsnackTextStyle(LocalTypography.currentValue.bodyLarge) - contentColor(LocalJetsnackColors.currentValue.textHelp) + jetsnackTextStyle(currentJetsnackTheme.typography.bodyLarge) + contentColor(currentJetsnackTheme.colors.textHelp) }, ) Spacer(Modifier.height(8.dp)) JetsnackText( text = formatPrice(snack.price), style = { - jetsnackTextStyle(LocalTypography.currentValue.titleMedium) - contentColor(LocalJetsnackColors.currentValue.textPrimary) + jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) + contentColor(currentJetsnackTheme.colors.textPrimary) }, ) } @@ -159,7 +158,7 @@ fun NoResults(query: String, modifier: Modifier = Modifier) { JetsnackText( text = stringResource(R.string.search_no_matches, query), style = { - jetsnackTextStyle(LocalTypography.currentValue.titleMedium) + jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) textAlign(TextAlign.Center) }, modifier = Modifier.fillMaxWidth(), @@ -168,7 +167,7 @@ fun NoResults(query: String, modifier: Modifier = Modifier) { JetsnackText( text = stringResource(R.string.search_no_matches_retry), style = { - jetsnackTextStyle(LocalTypography.currentValue.bodyMedium) + jetsnackTextStyle(currentJetsnackTheme.typography.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 823322656c..768b9da838 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,8 +34,6 @@ 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.LocalTypography import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.Stable @@ -62,7 +60,7 @@ 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 +import com.example.jetsnack.ui.theme.currentJetsnackTheme @Composable fun Search(onSnackClick: (Long, String) -> Unit, modifier: Modifier = Modifier, state: SearchState = rememberSearchState()) { @@ -173,9 +171,9 @@ private fun SearchBar( ) { JetsnackSurface( style = { - background(LocalJetsnackColors.currentValue.uiFloated) - contentColor(LocalJetsnackColors.currentValue.textSecondary) - shape(LocalShapes.currentValue.small) + background(currentJetsnackTheme.colors.uiFloated) + contentColor(currentJetsnackTheme.colors.textSecondary) + shape(currentJetsnackTheme.shapes.small) }, modifier = modifier .fillMaxWidth() @@ -244,7 +242,7 @@ private fun SearchHint() { JetsnackText( text = stringResource(R.string.search_jetsnack), style = { - contentColor(LocalJetsnackColors.currentValue.textHelp) + contentColor(currentJetsnackTheme.colors.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 306a2f29a7..40d122e71a 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,7 +26,6 @@ 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.LocalTypography import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -38,7 +37,7 @@ 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 +import com.example.jetsnack.ui.theme.currentJetsnackTheme @Composable fun SearchSuggestions(suggestions: List, onSuggestionSelect: (String) -> Unit) { @@ -66,8 +65,8 @@ private fun SuggestionHeader(name: String, modifier: Modifier = Modifier) { JetsnackText( text = name, style = { - jetsnackTextStyle(LocalTypography.currentValue.titleLarge) - contentColor(LocalJetsnackColors.currentValue.textPrimary) + jetsnackTextStyle(currentJetsnackTheme.typography.titleLarge) + contentColor(currentJetsnackTheme.colors.textPrimary) }, modifier = modifier .heightIn(min = 56.dp) @@ -81,7 +80,7 @@ private fun Suggestion(suggestion: String, onSuggestionSelect: (String) -> Unit, JetsnackText( text = suggestion, style = { - jetsnackTextStyle(LocalTypography.currentValue.titleMedium) + jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) }, modifier = modifier .heightIn(min = 48.dp) 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 55d33fadec..fedc561b2e 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 @@ -65,7 +65,6 @@ 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.runtime.Composable import androidx.compose.runtime.getValue @@ -114,7 +113,7 @@ 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.currentJetsnackTheme import com.example.jetsnack.ui.theme.Neutral8 import com.example.jetsnack.ui.utils.formatPrice import kotlin.math.max @@ -310,8 +309,8 @@ private fun Body(related: List, scroll: ScrollState) { JetsnackText( text = stringResource(R.string.detail_header), style = { - jetsnackTextStyle(LocalTypography.currentValue.headlineMedium) - contentColor(LocalJetsnackColors.currentValue.textHelp) + jetsnackTextStyle(currentJetsnackTheme.typography.headlineMedium) + contentColor(currentJetsnackTheme.colors.textHelp) contentPaddingHorizontal(24.dp) } ) @@ -321,8 +320,8 @@ private fun Body(related: List, scroll: ScrollState) { JetsnackText( text = stringResource(R.string.detail_placeholder), style = { - jetsnackTextStyle(LocalTypography.currentValue.bodyLarge) - contentColor(LocalJetsnackColors.currentValue.textHelp) + jetsnackTextStyle(currentJetsnackTheme.typography.bodyLarge) + contentColor(currentJetsnackTheme.colors.textHelp) contentPaddingHorizontal(24.dp) }, maxLines = if (seeMore) 5 else Int.MAX_VALUE, @@ -339,8 +338,8 @@ private fun Body(related: List, scroll: ScrollState) { JetsnackText( text = textButton, style = { - jetsnackTextStyle(LocalTypography.currentValue.labelLarge) - contentColor(LocalJetsnackColors.currentValue.textLink) + jetsnackTextStyle(currentJetsnackTheme.typography.labelLarge) + contentColor(currentJetsnackTheme.colors.textLink) textAlign(TextAlign.Center) contentPaddingTop(15.dp) fillWidth() @@ -357,8 +356,8 @@ private fun Body(related: List, scroll: ScrollState) { JetsnackText( text = stringResource(R.string.ingredients), style = { - jetsnackTextStyle(LocalTypography.currentValue.labelSmall) - contentColor(LocalJetsnackColors.currentValue.textHelp) + jetsnackTextStyle(currentJetsnackTheme.typography.labelSmall) + contentColor(currentJetsnackTheme.colors.textHelp) contentPaddingHorizontal(24.dp) } ) @@ -366,8 +365,8 @@ private fun Body(related: List, scroll: ScrollState) { JetsnackText( text = stringResource(R.string.ingredients_list), style = { - jetsnackTextStyle(LocalTypography.currentValue.bodyLarge) - contentColor(LocalJetsnackColors.currentValue.textHelp) + jetsnackTextStyle(currentJetsnackTheme.typography.bodyLarge) + contentColor(currentJetsnackTheme.colors.textHelp) contentPaddingHorizontal(24.dp) } ) @@ -425,8 +424,8 @@ private fun Title(snack: Snack, origin: String, scrollProvider: () -> Int) { JetsnackText( text = snack.name, style = { - jetsnackTextStyle(LocalTypography.currentValue.headlineMedium) - contentColor(LocalJetsnackColors.currentValue.textSecondary) + jetsnackTextStyle(currentJetsnackTheme.typography.headlineMedium) + contentColor(currentJetsnackTheme.colors.textSecondary) fontStyle(FontStyle.Italic) }, modifier = HzPadding @@ -446,9 +445,9 @@ private fun Title(snack: Snack, origin: String, scrollProvider: () -> Int) { JetsnackText( text = snack.tagline, style = { - jetsnackTextStyle(LocalTypography.currentValue.titleSmall) + jetsnackTextStyle(currentJetsnackTheme.typography.titleSmall) fontStyle(FontStyle.Italic) - contentColor(LocalJetsnackColors.currentValue.textHelp) + contentColor(currentJetsnackTheme.colors.textHelp) fontSize(20.sp) }, modifier = HzPadding @@ -470,8 +469,8 @@ private fun Title(snack: Snack, origin: String, scrollProvider: () -> Int) { JetsnackText( text = formatPrice(snack.price), style = { - jetsnackTextStyle(LocalTypography.currentValue.titleLarge) - contentColor(LocalJetsnackColors.currentValue.textPrimary) + jetsnackTextStyle(currentJetsnackTheme.typography.titleLarge) + contentColor(currentJetsnackTheme.colors.textPrimary) }, modifier = HzPadding .animateEnterExit( diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/theme/Color.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/theme/Color.kt index eb99c98163..04237b42c4 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/theme/Color.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/theme/Color.kt @@ -16,8 +16,101 @@ package com.example.jetsnack.ui.theme +import androidx.compose.material3.ColorScheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.MaterialTheme.colorScheme +import androidx.compose.runtime.Immutable import androidx.compose.ui.graphics.Color +/** + * Jetsnack custom Color Palette + */ +@Immutable +data class JetsnackColors( + val gradient6_1: List, + val gradient6_2: List, + val gradient3_1: List, + val gradient3_2: List, + val gradient2_1: List, + val gradient2_2: List, + val gradient2_3: List, + val brand: Color, + val brandSecondary: Color, + val uiBackground: Color, + val uiBorder: Color, + val uiFloated: Color, + val interactivePrimary: List = gradient2_1, + val interactiveSecondary: List = gradient2_2, + val interactiveMask: List = gradient6_1, + val textPrimary: Color = brand, + val textSecondary: Color, + val textHelp: Color, + val textInteractive: Color, + val textLink: Color, + val tornado1: List, + val iconPrimary: Color = brand, + val iconSecondary: Color, + val iconInteractive: Color, + val iconInteractiveInactive: Color, + val error: Color, + val notificationBadge: Color = error, + val isDark: Boolean, +) +/** + * A Material [Colors] implementation which sets all colors to [debugColor] to discourage usage of + * [MaterialTheme.colorScheme] in preference to [JetsnackTheme.colors]. + */ +fun debugColors(darkTheme: Boolean, debugColor: Color = Color.Magenta) = ColorScheme( + primary = debugColor, + onPrimary = debugColor, + primaryContainer = debugColor, + onPrimaryContainer = debugColor, + inversePrimary = debugColor, + secondary = debugColor, + onSecondary = debugColor, + secondaryContainer = debugColor, + onSecondaryContainer = debugColor, + tertiary = debugColor, + onTertiary = debugColor, + tertiaryContainer = debugColor, + onTertiaryContainer = debugColor, + background = debugColor, + onBackground = debugColor, + surface = debugColor, + onSurface = debugColor, + surfaceVariant = debugColor, + onSurfaceVariant = debugColor, + surfaceTint = debugColor, + inverseSurface = debugColor, + inverseOnSurface = debugColor, + error = debugColor, + onError = debugColor, + errorContainer = debugColor, + onErrorContainer = debugColor, + outline = debugColor, + outlineVariant = debugColor, + scrim = debugColor, + surfaceBright = debugColor, + surfaceDim = debugColor, + surfaceContainer = debugColor, + surfaceContainerHigh = debugColor, + surfaceContainerHighest = debugColor, + surfaceContainerLow = debugColor, + surfaceContainerLowest = debugColor, + primaryFixed = debugColor, + primaryFixedDim = debugColor, + onPrimaryFixed = debugColor, + onPrimaryFixedVariant = debugColor, + secondaryFixed = debugColor, + secondaryFixedDim = debugColor, + onSecondaryFixed = debugColor, + onSecondaryFixedVariant = debugColor, + tertiaryFixed = debugColor, + tertiaryFixedDim = debugColor, + onTertiaryFixed = debugColor, + onTertiaryFixedVariant = debugColor +) + val Shadow11 = Color(0xff001787) val Shadow10 = Color(0xff00119e) val Shadow9 = Color(0xff0009b3) @@ -87,3 +180,56 @@ val FunctionalGrey = Color(0xfff6f6f6) val FunctionalDarkGrey = Color(0xff2e2e2e) const val AlphaNearOpaque = 0.95f + + +internal val LightColorPalette = JetsnackColors( + brand = Shadow5, + brandSecondary = Ocean3, + uiBackground = Neutral0, + uiBorder = Neutral4, + uiFloated = FunctionalGrey, + textSecondary = Neutral7, + textHelp = Neutral6, + textInteractive = Neutral0, + textLink = Ocean11, + iconSecondary = Neutral7, + iconInteractive = Neutral0, + iconInteractiveInactive = Neutral1, + error = FunctionalRed, + gradient6_1 = listOf(Shadow4, Ocean3, Shadow2, Ocean3, Shadow4), + gradient6_2 = listOf(Rose4, Lavender3, Rose2, Lavender3, Rose4), + gradient3_1 = listOf(Shadow2, Ocean3, Shadow4), + gradient3_2 = listOf(Rose2, Lavender3, Rose4), + gradient2_1 = listOf(Shadow4, Shadow11), + gradient2_2 = listOf(Ocean3, Shadow3), + gradient2_3 = listOf(Lavender3, Rose2), + tornado1 = listOf(Shadow4, Ocean3), + isDark = false, +) + +internal val DarkColorPalette = JetsnackColors( + brand = Shadow1, + brandSecondary = Ocean2, + uiBackground = Neutral8, + uiBorder = Neutral3, + uiFloated = FunctionalDarkGrey, + textPrimary = Shadow1, + textSecondary = Neutral0, + textHelp = Neutral1, + textInteractive = Neutral7, + textLink = Ocean2, + iconPrimary = Shadow1, + iconSecondary = Neutral0, + iconInteractive = Neutral7, + iconInteractiveInactive = Neutral6, + error = FunctionalRedDark, + gradient6_1 = listOf(Shadow5, Ocean7, Shadow9, Ocean7, Shadow5), + gradient6_2 = listOf(Rose11, Lavender7, Rose8, Lavender7, Rose11), + gradient3_1 = listOf(Shadow9, Ocean7, Shadow5), + gradient3_2 = listOf(Rose8, Lavender7, Rose11), + gradient2_1 = listOf(Ocean3, Shadow3), + gradient2_2 = listOf(Ocean4, Shadow2), + gradient2_3 = listOf(Lavender3, Rose3), + tornado1 = listOf(Shadow4, Ocean3), + isDark = true, +) \ No newline at end of file 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 741ce488b9..67a8ac37c7 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 @@ -6,63 +6,60 @@ 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.StyleScope 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 +import com.example.jetsnack.ui.theme.JetsnackTheme.Companion.LocalJetsnackTheme @Immutable data class AppStyles( val buttonStyle : Style = Style { shape( RoundedCornerShape(percent = 50)) - background(Brush.linearGradient(LocalJetsnackColors.currentValue.interactivePrimary)) - contentColor(LocalJetsnackColors.currentValue.textInteractive) + background(Brush.linearGradient(currentJetsnackTheme.colors.interactivePrimary)) + contentColor(currentJetsnackTheme.colors.textInteractive) contentPadding( ButtonDefaults.ContentPadding.calculateTopPadding()) // todo file issue to support padding values - jetsnackTextStyle(LocalTypography.currentValue.labelLarge) + jetsnackTextStyle(currentJetsnackTheme.typography.labelLarge) disabled { animate { - background(Brush.linearGradient(LocalJetsnackColors.currentValue.interactiveSecondary)) - contentColor(LocalJetsnackColors.currentValue.textHelp) + background(Brush.linearGradient(currentJetsnackTheme.colors.interactiveSecondary)) + contentColor(currentJetsnackTheme.colors.textHelp) } } }, val cardStyle: Style = Style { - shape(LocalShapes.currentValue.medium) - background(LocalJetsnackColors.currentValue.uiBackground) - contentColor(LocalJetsnackColors.currentValue.textPrimary) + shape(currentJetsnackTheme.shapes.medium) + background(currentJetsnackTheme.colors.uiBackground) + contentColor(currentJetsnackTheme.colors.textPrimary) /* todo elevation elevation: Dp = 4.dp,*/ }, val dividerStyle: Style = Style { - background(LocalJetsnackColors.currentValue.uiBorder.copy(alpha = 0.12f)) + background(currentJetsnackTheme.colors.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) + border(2.dp, Brush.linearGradient(currentJetsnackTheme.colors.interactiveSecondary)) + background(currentJetsnackTheme.colors.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, + colors = currentJetsnackTheme.colors.interactiveSecondary, startX = 0f, endX = 200f, tileMode = TileMode.Mirror, @@ -71,14 +68,14 @@ data class AppStyles( } }, val filterChipStyle: Style = Style { - shape(LocalShapes.currentValue.small) - background(LocalJetsnackColors.currentValue.uiBackground) - contentColor(LocalJetsnackColors.currentValue.textSecondary) - border(1.dp, Brush.linearGradient(LocalJetsnackColors.currentValue.interactiveSecondary)) + shape(currentJetsnackTheme.shapes.small) + background(currentJetsnackTheme.colors.uiBackground) + contentColor(currentJetsnackTheme.colors.textSecondary) + border(1.dp, Brush.linearGradient(currentJetsnackTheme.colors.interactiveSecondary)) // todo elevation = 2.dp, selected { animate { - background(LocalJetsnackColors.currentValue.brandSecondary) + background(currentJetsnackTheme.colors.brandSecondary) contentColor(Color.Black) border(1.dp, Color.Transparent) } @@ -89,8 +86,10 @@ data class AppStyles( }, val surfaceStyle: Style = Style { shape(RectangleShape) - background(LocalJetsnackColors.currentValue.uiBackground) - contentColor(LocalJetsnackColors.currentValue.textSecondary) + background(currentJetsnackTheme.colors.uiBackground) + contentColor(currentJetsnackTheme.colors.textSecondary) clip(true) } ) +val StyleScope.currentJetsnackTheme: JetsnackTheme + get() = LocalJetsnackTheme.currentValue \ 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 2ad96a0f0a..008a18b966 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 @@ -20,176 +20,60 @@ 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.material3.Shapes +import androidx.compose.material3.Typography import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.Immutable import androidx.compose.runtime.ProvidableCompositionLocal +import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.staticCompositionLocalOf -import androidx.compose.ui.graphics.Color -private val LightColorPalette = JetsnackColors( - brand = Shadow5, - brandSecondary = Ocean3, - uiBackground = Neutral0, - uiBorder = Neutral4, - uiFloated = FunctionalGrey, - textSecondary = Neutral7, - textHelp = Neutral6, - textInteractive = Neutral0, - textLink = Ocean11, - iconSecondary = Neutral7, - iconInteractive = Neutral0, - iconInteractiveInactive = Neutral1, - error = FunctionalRed, - gradient6_1 = listOf(Shadow4, Ocean3, Shadow2, Ocean3, Shadow4), - gradient6_2 = listOf(Rose4, Lavender3, Rose2, Lavender3, Rose4), - gradient3_1 = listOf(Shadow2, Ocean3, Shadow4), - gradient3_2 = listOf(Rose2, Lavender3, Rose4), - gradient2_1 = listOf(Shadow4, Shadow11), - gradient2_2 = listOf(Ocean3, Shadow3), - gradient2_3 = listOf(Lavender3, Rose2), - tornado1 = listOf(Shadow4, Ocean3), - isDark = false, -) -private val DarkColorPalette = JetsnackColors( - brand = Shadow1, - brandSecondary = Ocean2, - uiBackground = Neutral8, - uiBorder = Neutral3, - uiFloated = FunctionalDarkGrey, - textPrimary = Shadow1, - textSecondary = Neutral0, - textHelp = Neutral1, - textInteractive = Neutral7, - textLink = Ocean2, - iconPrimary = Shadow1, - iconSecondary = Neutral0, - iconInteractive = Neutral7, - iconInteractiveInactive = Neutral6, - error = FunctionalRedDark, - gradient6_1 = listOf(Shadow5, Ocean7, Shadow9, Ocean7, Shadow5), - gradient6_2 = listOf(Rose11, Lavender7, Rose8, Lavender7, Rose11), - gradient3_1 = listOf(Shadow9, Ocean7, Shadow5), - gradient3_2 = listOf(Rose8, Lavender7, Rose11), - gradient2_1 = listOf(Ocean3, Shadow3), - gradient2_2 = listOf(Ocean4, Shadow2), - gradient2_3 = listOf(Lavender3, Rose3), - tornado1 = listOf(Shadow4, Ocean3), - isDark = true, -) +@Immutable +class JetsnackTheme( + val colors: JetsnackColors = LightColorPalette, + val typography: Typography = Typography, + val appStyles: AppStyles = AppStyles(), +) { + val shapes: Shapes = _shapes -@Composable -fun JetsnackTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) { - val colors = if (darkTheme) DarkColorPalette else LightColorPalette - val styles = AppStyles() - ProvideJetsnackColors(colors) { - CompositionLocalProvider(LocalAppStyles provides styles) { - MaterialTheme( - colorScheme = debugColors(darkTheme), - typography = Typography, - shapes = Shapes, - content = content, - ) - } + companion object { + val colors: JetsnackColors + @Composable @ReadOnlyComposable get() = LocalJetsnackTheme.current.colors + + val typography: Typography + @Composable @ReadOnlyComposable get() = LocalJetsnackTheme.current.typography + + val shapes: Shapes + @Composable @ReadOnlyComposable get() = LocalJetsnackTheme.current.shapes + + val appStyles: AppStyles + @Composable @ReadOnlyComposable get() = LocalJetsnackTheme.current.appStyles + + val LocalJetsnackTheme: ProvidableCompositionLocal + get() = LocalJetsnackThemeInstance + + private val _shapes = Shapes } } -//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 -} -/** - * Jetsnack custom Color Palette - */ -@Immutable -data class JetsnackColors( - val gradient6_1: List, - val gradient6_2: List, - val gradient3_1: List, - val gradient3_2: List, - val gradient2_1: List, - val gradient2_2: List, - val gradient2_3: List, - val brand: Color, - val brandSecondary: Color, - val uiBackground: Color, - val uiBorder: Color, - val uiFloated: Color, - val interactivePrimary: List = gradient2_1, - val interactiveSecondary: List = gradient2_2, - val interactiveMask: List = gradient6_1, - val textPrimary: Color = brand, - val textSecondary: Color, - val textHelp: Color, - val textInteractive: Color, - val textLink: Color, - val tornado1: List, - val iconPrimary: Color = brand, - val iconSecondary: Color, - val iconInteractive: Color, - val iconInteractiveInactive: Color, - val error: Color, - val notificationBadge: Color = error, - val isDark: Boolean, -) +internal val LocalJetsnackThemeInstance = staticCompositionLocalOf { JetsnackTheme() } @Composable -fun ProvideJetsnackColors(colors: JetsnackColors, content: @Composable () -> Unit) { - CompositionLocalProvider(LocalJetsnackColors provides colors, content = content) -} +fun JetsnackTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) { + val colors = if (darkTheme) DarkColorPalette else LightColorPalette + val theme = JetsnackTheme(colors = colors, appStyles = AppStyles()) -val LocalJetsnackColors = staticCompositionLocalOf { - error("No JetsnackColorPalette provided") + CompositionLocalProvider( + JetsnackTheme.LocalJetsnackTheme provides theme + ) { + MaterialTheme( + colorScheme = debugColors(darkTheme), + typography = Typography, + shapes = Shapes, + content = content, + ) + } } -val LocalAppStyles = staticCompositionLocalOf { AppStyles() } - -/** - * A Material [Colors] implementation which sets all colors to [debugColor] to discourage usage of - * [MaterialTheme.colorScheme] in preference to [JetsnackTheme.colors]. - */ -fun debugColors(darkTheme: Boolean, debugColor: Color = Color.Magenta) = ColorScheme( - primary = debugColor, - onPrimary = debugColor, - primaryContainer = debugColor, - onPrimaryContainer = debugColor, - inversePrimary = debugColor, - secondary = debugColor, - onSecondary = debugColor, - secondaryContainer = debugColor, - onSecondaryContainer = debugColor, - tertiary = debugColor, - onTertiary = debugColor, - tertiaryContainer = debugColor, - onTertiaryContainer = debugColor, - background = debugColor, - onBackground = debugColor, - surface = debugColor, - onSurface = debugColor, - surfaceVariant = debugColor, - onSurfaceVariant = debugColor, - surfaceTint = debugColor, - inverseSurface = debugColor, - inverseOnSurface = debugColor, - error = debugColor, - onError = debugColor, - errorContainer = debugColor, - onErrorContainer = debugColor, - outline = debugColor, - outlineVariant = debugColor, - scrim = debugColor, - surfaceBright = debugColor, - surfaceDim = debugColor, - surfaceContainer = debugColor, - surfaceContainerHigh = debugColor, - surfaceContainerHighest = debugColor, - surfaceContainerLow = debugColor, - surfaceContainerLowest = debugColor, -) From 6a3885ce20ddc46ce36bacae9e54a38d34cf2d30 Mon Sep 17 00:00:00 2001 From: Rebecca Franks Date: Mon, 16 Mar 2026 13:01:24 +0000 Subject: [PATCH 04/11] Run Spotless --- .../example/jetsnack/ui/components/Button.kt | 2 +- .../example/jetsnack/ui/components/Card.kt | 6 +-- .../example/jetsnack/ui/components/Divider.kt | 6 +-- .../example/jetsnack/ui/components/Filters.kt | 6 +-- .../jetsnack/ui/components/Gradient.kt | 1 - .../example/jetsnack/ui/components/Snacks.kt | 2 +- .../example/jetsnack/ui/components/Surface.kt | 53 ------------------- .../example/jetsnack/ui/components/Text.kt | 20 ++++++- .../example/jetsnack/ui/home/FilterScreen.kt | 6 +-- .../java/com/example/jetsnack/ui/home/Home.kt | 4 +- .../com/example/jetsnack/ui/home/cart/Cart.kt | 4 +- .../jetsnack/ui/home/search/Categories.kt | 2 +- .../jetsnack/ui/home/search/Results.kt | 2 +- .../example/jetsnack/ui/home/search/Search.kt | 2 +- .../jetsnack/ui/snackdetail/SnackDetail.kt | 10 ++-- .../com/example/jetsnack/ui/theme/Color.kt | 5 +- .../com/example/jetsnack/ui/theme/Styles.kt | 42 ++++++++++----- .../com/example/jetsnack/ui/theme/Theme.kt | 15 +++--- 18 files changed, 79 insertions(+), 109 deletions(-) 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 45c2622aad..4a4a97c33c 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 @@ -43,7 +43,7 @@ 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 +// todo think about the text style here @Composable fun JetsnackButton( onClick: () -> Unit, 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 e8f4f2bf35..cbe20f493e 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 @@ -30,11 +30,7 @@ import androidx.compose.ui.unit.dp import com.example.jetsnack.ui.theme.JetsnackTheme @Composable -fun JetsnackCard( - modifier: Modifier = Modifier, - style: Style = Style, - content: @Composable () -> Unit, -) { +fun JetsnackCard(modifier: Modifier = Modifier, style: Style = Style, content: @Composable () -> Unit) { JetsnackSurface( modifier = modifier, style = JetsnackTheme.appStyles.cardStyle then style, 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 88b35269a4..8a14dcb806 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 @@ -34,14 +34,10 @@ import com.example.jetsnack.ui.theme.JetsnackTheme import com.example.jetsnack.ui.theme.JetsnackTheme.Companion.LocalJetsnackTheme @Composable -fun JetsnackDivider( - modifier: Modifier = Modifier, - style: Style = Style -) { +fun JetsnackDivider(modifier: Modifier = Modifier, style: Style = Style) { Box(modifier = modifier.styleable(null, LocalJetsnackTheme.current.appStyles.dividerStyle, style)) } - @Preview("default", showBackground = true) @Preview("dark theme", uiMode = Configuration.UI_MODE_NIGHT_YES, showBackground = true) @Composable 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 92b11cbedd..09087a7e5f 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 @@ -107,11 +107,7 @@ fun FilterBar( } @Composable -fun FilterChip( - filter: Filter, - modifier: Modifier = Modifier, - style: Style = Style, -) { +fun FilterChip(filter: Filter, modifier: Modifier = Modifier, style: Style = Style) { val (selected, setSelected) = filter.enabled val interactionSource = remember { MutableInteractionSource() } 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 58c94ef17b..5709b8cecd 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 @@ -55,4 +55,3 @@ fun Modifier.diagonalGradientBorder(colors: List, borderSize: Dp = 2.dp, brush = Brush.linearGradient(colors), shape = shape, ) - 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 b0423c0fab..fa56c5be65 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 @@ -288,7 +288,7 @@ private fun HighlightSnackItem( } JetsnackCard( style = Style { - shape( RoundedCornerShape(roundedCornerAnimation)) + shape(RoundedCornerShape(roundedCornerAnimation)) }, modifier = modifier .padding(bottom = 16.dp) 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 1346999427..46aa30409a 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 @@ -18,30 +18,15 @@ 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 import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.draw.shadow -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.RectangleShape -import androidx.compose.ui.graphics.Shape -import androidx.compose.ui.graphics.compositeOver -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import androidx.compose.ui.zIndex import com.example.jetsnack.ui.theme.JetsnackTheme -import kotlin.math.ln /** * An alternative to [androidx.compose.material3.Surface] utilizing @@ -63,41 +48,3 @@ fun JetsnackSurface( 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 - // JetsnackTheme.colors.isDark //&& - // color == JetsnackTheme.colors.uiBackground - ) { - color.withElevation(elevation) - } else { - 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/components/Text.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Text.kt index 2b3a9af21b..37e68dd3af 100644 --- 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 @@ -1,3 +1,19 @@ +/* + * Copyright 2026 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.example.jetsnack.ui.components import androidx.compose.foundation.style.ExperimentalFoundationStyleApi @@ -8,8 +24,8 @@ 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.TextStyle import androidx.compose.ui.text.style.TextOverflow import com.example.jetsnack.ui.theme.JetsnackTheme @@ -32,7 +48,7 @@ fun JetsnackText( maxLines: Int = Int.MAX_VALUE, minLines: Int = 1, autoSize: TextAutoSize? = null, - ) { +) { BasicText( text = text, modifier = modifier.styleable(null, JetsnackTheme.appStyles.defaultTextStyle, style), 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 7bd9e102d1..0126912b91 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 @@ -144,7 +144,7 @@ fun FilterScreen(sharedTransitionScope: SharedTransitionScope, animatedVisibilit style = { textAlign(TextAlign.Center) jetsnackTextStyle(currentJetsnackTheme.typography.titleLarge) - } + }, ) val resetEnabled = sortState != defaultFilter @@ -165,9 +165,9 @@ fun FilterScreen(sharedTransitionScope: SharedTransitionScope, animatedVisibilit fontWeight(fontWeight) contentColor( currentJetsnackTheme.colors.uiBackground - .copy(alpha = if (!resetEnabled) 0.38f else 1f) + .copy(alpha = if (!resetEnabled) 0.38f else 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 ada5b2abd0..59d3f26019 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 @@ -58,6 +58,7 @@ import androidx.compose.ui.layout.MeasureScope import androidx.compose.ui.layout.Placeable import androidx.compose.ui.layout.layoutId import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.platform.LocalLocale import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview @@ -83,7 +84,6 @@ import com.example.jetsnack.ui.snackdetail.spatialExpressiveSpring import com.example.jetsnack.ui.theme.JetsnackTheme import com.example.jetsnack.ui.theme.currentJetsnackTheme import java.util.Locale -import androidx.compose.ui.platform.LocalLocale fun NavGraphBuilder.composableWithCompositionLocal( route: String, @@ -179,7 +179,7 @@ fun JetsnackBottomBar( style = { background(color) contentColor(contentColor) - } + }, ) { val springSpec = spatialExpressiveSpring() JetsnackBottomNavLayout( 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 a638c1b790..66df1f0820 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 @@ -56,6 +56,7 @@ import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.layout.LastBaseline import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalResources import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign @@ -74,10 +75,10 @@ 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 +import com.example.jetsnack.ui.components.jetsnackTextStyle import com.example.jetsnack.ui.home.DestinationBar import com.example.jetsnack.ui.snackdetail.nonSpatialExpressiveSpring import com.example.jetsnack.ui.snackdetail.spatialExpressiveSpring @@ -86,7 +87,6 @@ import com.example.jetsnack.ui.theme.JetsnackTheme import com.example.jetsnack.ui.theme.currentJetsnackTheme import com.example.jetsnack.ui.utils.formatPrice import kotlin.math.roundToInt -import androidx.compose.ui.platform.LocalResources @Composable fun Cart( 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 b545fc45af..5238998a94 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 @@ -44,9 +44,9 @@ 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.components.jetsnackTextStyle import com.example.jetsnack.ui.theme.JetsnackTheme import com.example.jetsnack.ui.theme.currentJetsnackTheme import kotlin.math.max 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 53f810ede7..852655b670 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 @@ -49,8 +49,8 @@ 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.components.jetsnackTextStyle import com.example.jetsnack.ui.theme.JetsnackTheme import com.example.jetsnack.ui.theme.currentJetsnackTheme import com.example.jetsnack.ui.utils.formatPrice 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 768b9da838..ff24a92711 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 @@ -243,7 +243,7 @@ private fun SearchHint() { text = stringResource(R.string.search_jetsnack), style = { contentColor(currentJetsnackTheme.colors.textHelp) - } + }, ) } } 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 fedc561b2e..a6c35c6f65 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 @@ -108,13 +108,13 @@ 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.components.jetsnackTextStyle import com.example.jetsnack.ui.theme.JetsnackTheme -import com.example.jetsnack.ui.theme.currentJetsnackTheme import com.example.jetsnack.ui.theme.Neutral8 +import com.example.jetsnack.ui.theme.currentJetsnackTheme import com.example.jetsnack.ui.utils.formatPrice import kotlin.math.max import kotlin.math.min @@ -312,7 +312,7 @@ private fun Body(related: List, scroll: ScrollState) { jetsnackTextStyle(currentJetsnackTheme.typography.headlineMedium) contentColor(currentJetsnackTheme.colors.textHelp) contentPaddingHorizontal(24.dp) - } + }, ) Spacer(Modifier.height(16.dp)) var seeMore by remember { mutableStateOf(true) } @@ -359,7 +359,7 @@ private fun Body(related: List, scroll: ScrollState) { jetsnackTextStyle(currentJetsnackTheme.typography.labelSmall) contentColor(currentJetsnackTheme.colors.textHelp) contentPaddingHorizontal(24.dp) - } + }, ) Spacer(Modifier.height(4.dp)) JetsnackText( @@ -368,7 +368,7 @@ private fun Body(related: List, scroll: ScrollState) { jetsnackTextStyle(currentJetsnackTheme.typography.bodyLarge) contentColor(currentJetsnackTheme.colors.textHelp) contentPaddingHorizontal(24.dp) - } + }, ) Spacer(Modifier.height(16.dp)) diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/theme/Color.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/theme/Color.kt index 04237b42c4..918312fb87 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/theme/Color.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/theme/Color.kt @@ -108,7 +108,7 @@ fun debugColors(darkTheme: Boolean, debugColor: Color = Color.Magenta) = ColorSc tertiaryFixed = debugColor, tertiaryFixedDim = debugColor, onTertiaryFixed = debugColor, - onTertiaryFixedVariant = debugColor + onTertiaryFixedVariant = debugColor, ) val Shadow11 = Color(0xff001787) @@ -181,7 +181,6 @@ val FunctionalDarkGrey = Color(0xff2e2e2e) const val AlphaNearOpaque = 0.95f - internal val LightColorPalette = JetsnackColors( brand = Shadow5, brandSecondary = Ocean3, @@ -232,4 +231,4 @@ internal val DarkColorPalette = JetsnackColors( gradient2_3 = listOf(Lavender3, Rose3), tornado1 = listOf(Shadow4, Ocean3), isDark = true, -) \ No newline at end of file +) 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 67a8ac37c7..9b6012b704 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 @@ -1,3 +1,19 @@ +/* + * Copyright 2026 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + @file:OptIn(ExperimentalFoundationStyleApi::class) package com.example.jetsnack.ui.theme @@ -24,11 +40,11 @@ import com.example.jetsnack.ui.theme.JetsnackTheme.Companion.LocalJetsnackTheme @Immutable data class AppStyles( - val buttonStyle : Style = Style { - shape( RoundedCornerShape(percent = 50)) + val buttonStyle: Style = Style { + shape(RoundedCornerShape(percent = 50)) background(Brush.linearGradient(currentJetsnackTheme.colors.interactivePrimary)) contentColor(currentJetsnackTheme.colors.textInteractive) - contentPadding( ButtonDefaults.ContentPadding.calculateTopPadding()) // todo file issue to support padding values + contentPadding(ButtonDefaults.ContentPadding.calculateTopPadding()) // todo file issue to support padding values jetsnackTextStyle(currentJetsnackTheme.typography.labelLarge) disabled { animate { @@ -57,13 +73,15 @@ data class AppStyles( background(currentJetsnackTheme.colors.uiBackground) pressed { animate { - background(Brush.horizontalGradient( - // this was a parameter input into the function? might want to make helper function for it - colors = currentJetsnackTheme.colors.interactiveSecondary, - startX = 0f, - endX = 200f, - tileMode = TileMode.Mirror, - )) + background( + Brush.horizontalGradient( + // this was a parameter input into the function? might want to make helper function for it + colors = currentJetsnackTheme.colors.interactiveSecondary, + startX = 0f, + endX = 200f, + tileMode = TileMode.Mirror, + ), + ) } } }, @@ -89,7 +107,7 @@ data class AppStyles( background(currentJetsnackTheme.colors.uiBackground) contentColor(currentJetsnackTheme.colors.textSecondary) clip(true) - } + }, ) val StyleScope.currentJetsnackTheme: JetsnackTheme - get() = LocalJetsnackTheme.currentValue \ No newline at end of file + get() = LocalJetsnackTheme.currentValue 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 008a18b966..4b19ef0080 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 @@ -30,7 +30,6 @@ import androidx.compose.runtime.ProvidableCompositionLocal import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.staticCompositionLocalOf - @Immutable class JetsnackTheme( val colors: JetsnackColors = LightColorPalette, @@ -41,16 +40,20 @@ class JetsnackTheme( companion object { val colors: JetsnackColors - @Composable @ReadOnlyComposable get() = LocalJetsnackTheme.current.colors + @Composable @ReadOnlyComposable + get() = LocalJetsnackTheme.current.colors val typography: Typography - @Composable @ReadOnlyComposable get() = LocalJetsnackTheme.current.typography + @Composable @ReadOnlyComposable + get() = LocalJetsnackTheme.current.typography val shapes: Shapes - @Composable @ReadOnlyComposable get() = LocalJetsnackTheme.current.shapes + @Composable @ReadOnlyComposable + get() = LocalJetsnackTheme.current.shapes val appStyles: AppStyles - @Composable @ReadOnlyComposable get() = LocalJetsnackTheme.current.appStyles + @Composable @ReadOnlyComposable + get() = LocalJetsnackTheme.current.appStyles val LocalJetsnackTheme: ProvidableCompositionLocal get() = LocalJetsnackThemeInstance @@ -67,7 +70,7 @@ fun JetsnackTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composab val theme = JetsnackTheme(colors = colors, appStyles = AppStyles()) CompositionLocalProvider( - JetsnackTheme.LocalJetsnackTheme provides theme + JetsnackTheme.LocalJetsnackTheme provides theme, ) { MaterialTheme( colorScheme = debugColors(darkTheme), From 169312e0c1b385017983cd841c9332c162a033ea Mon Sep 17 00:00:00 2001 From: Rebecca Franks Date: Mon, 16 Mar 2026 18:07:29 +0000 Subject: [PATCH 05/11] Rename and refactor UI components and theme accessors. - Rename `JetsnackButton`, `JetsnackSurface`, and `JetsnackText` to `Button`, `Surface`, and `Text`. - Rename `jetsnackTextStyle` to `textStyleWithFontFamilyFix`. - Replace `currentJetsnackTheme` with direct `colors`, `typography`, and `shapes` accessors within `StyleScope`. - Update `AppStyles` to use the new theme accessors and refined padding properties. - Add a ripple indication to the base `Button` component. --- .../example/jetsnack/ui/components/Button.kt | 43 ++++------ .../example/jetsnack/ui/components/Card.kt | 4 +- .../example/jetsnack/ui/components/Filters.kt | 14 ++-- .../ui/components/GradientTintedIconButton.kt | 10 ++- .../ui/components/QuantitySelector.kt | 19 ++--- .../example/jetsnack/ui/components/Snacks.kt | 34 ++++---- .../example/jetsnack/ui/components/Surface.kt | 2 +- .../example/jetsnack/ui/components/Text.kt | 4 +- .../jetsnack/ui/home/DestinationBar.kt | 13 +-- .../java/com/example/jetsnack/ui/home/Feed.kt | 4 +- .../example/jetsnack/ui/home/FilterScreen.kt | 33 ++++---- .../java/com/example/jetsnack/ui/home/Home.kt | 14 ++-- .../com/example/jetsnack/ui/home/Profile.kt | 16 ++-- .../com/example/jetsnack/ui/home/cart/Cart.kt | 80 +++++++++---------- .../jetsnack/ui/home/search/Categories.kt | 19 ++--- .../jetsnack/ui/home/search/Results.kt | 48 +++++------ .../example/jetsnack/ui/home/search/Search.kt | 23 +++--- .../jetsnack/ui/home/search/Suggestions.kt | 21 ++--- .../jetsnack/ui/snackdetail/SnackDetail.kt | 68 ++++++++-------- .../com/example/jetsnack/ui/theme/Styles.kt | 50 ++++++------ .../com/example/jetsnack/ui/theme/Theme.kt | 15 +++- 21 files changed, 271 insertions(+), 263 deletions(-) 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 4a4a97c33c..b5fc023b37 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 @@ -20,7 +20,6 @@ package com.example.jetsnack.ui.components import android.content.res.Configuration.UI_MODE_NIGHT_YES 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.Row @@ -31,8 +30,6 @@ 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 import androidx.compose.material3.ripple import androidx.compose.runtime.Composable import androidx.compose.runtime.remember @@ -43,9 +40,8 @@ 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( +fun Button( onClick: () -> Unit, modifier: Modifier = Modifier, style: Style = Style, @@ -56,7 +52,7 @@ fun JetsnackButton( val styleState = rememberUpdatedStyleState(interactionSource, { it.isEnabled = enabled }) - JetsnackSurface( + Surface( style = JetsnackTheme.appStyles.buttonStyle then style, styleState = styleState, modifier = modifier @@ -65,24 +61,19 @@ fun JetsnackButton( enabled = enabled, role = Role.Button, interactionSource = interactionSource, - indication = null, + indication = ripple() //TODO This ripple doesn't know the shape of the button. ), ) { - ProvideTextStyle( - value = MaterialTheme.typography.labelLarge, - ) { - Row( - Modifier - .defaultMinSize( - minWidth = ButtonDefaults.MinWidth, - minHeight = ButtonDefaults.MinHeight, - ) - .indication(interactionSource, ripple()), - horizontalArrangement = Arrangement.Center, - verticalAlignment = Alignment.CenterVertically, - content = content, - ) - } + Row( + Modifier + .defaultMinSize( + minWidth = ButtonDefaults.MinWidth, + minHeight = ButtonDefaults.MinHeight, + ), + horizontalArrangement = Arrangement.Center, + verticalAlignment = Alignment.CenterVertically, + content = content, + ) } } @@ -92,8 +83,8 @@ fun JetsnackButton( @Composable private fun ButtonPreview() { JetsnackTheme { - JetsnackButton(onClick = {}) { - JetsnackText(text = "Demo") + Button(onClick = {}) { + Text(text = "Demo") } } } @@ -104,12 +95,12 @@ private fun ButtonPreview() { @Composable private fun RectangleButtonPreview() { JetsnackTheme { - JetsnackButton( + Button( onClick = {}, style = { shape(RectangleShape) }, ) { - JetsnackText(text = "Demo") + 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 cbe20f493e..dc8c4041e4 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 @@ -31,7 +31,7 @@ import com.example.jetsnack.ui.theme.JetsnackTheme @Composable fun JetsnackCard(modifier: Modifier = Modifier, style: Style = Style, content: @Composable () -> Unit) { - JetsnackSurface( + Surface( modifier = modifier, style = JetsnackTheme.appStyles.cardStyle then style, content = content, @@ -45,7 +45,7 @@ fun JetsnackCard(modifier: Modifier = Modifier, style: Style = Style, content: @ private fun CardPreview() { JetsnackTheme { JetsnackCard { - JetsnackText(text = "Demo", modifier = Modifier.padding(16.dp)) + Text(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 09087a7e5f..58dc08f5a8 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 @@ -55,7 +55,9 @@ 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.currentJetsnackTheme +import com.example.jetsnack.ui.theme.colors +import com.example.jetsnack.ui.theme.shapes +import com.example.jetsnack.ui.theme.typography @Composable fun FilterBar( @@ -98,7 +100,7 @@ fun FilterBar( FilterChip( filter = filter, style = Style { - shape(currentJetsnackTheme.shapes.small) + shape(shapes.small) }, ) } @@ -118,7 +120,7 @@ fun FilterChip(filter: Filter, modifier: Modifier = Modifier, style: Style = Sty }, ) - JetsnackSurface( + Surface( modifier = modifier .toggleable( value = selected, @@ -135,7 +137,7 @@ fun FilterChip(filter: Filter, modifier: Modifier = Modifier, style: Style = Sty animate { background( Brush.horizontalGradient( - colors = currentJetsnackTheme.colors.interactiveSecondary, + colors = colors.interactiveSecondary, startX = 0f, endX = 200f, tileMode = TileMode.Mirror, @@ -148,10 +150,10 @@ fun FilterChip(filter: Filter, modifier: Modifier = Modifier, style: Style = Sty modifier = Modifier .styleable(styleState, innerBackgroundStyle), ) { - JetsnackText( + Text( text = filter.name, style = { - jetsnackTextStyle(currentJetsnackTheme.typography.bodySmall) + textStyleWithFontFamilyFix(typography.bodySmall) }, maxLines = 1, modifier = Modifier.padding( 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 c65086d21e..0b73d55bde 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 @@ -23,15 +23,19 @@ import androidx.annotation.DrawableRes import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.collectIsPressedAsState +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.padding 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.material3.Icon import androidx.compose.material3.Surface +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.BlendMode import androidx.compose.ui.graphics.Color @@ -72,8 +76,8 @@ fun JetsnackGradientTintedIconButton( val modifierColor = if (pressed) { Modifier.contentTintDiagonalGradient( colors = listOf( - JetsnackTheme.colors.textSecondary, - JetsnackTheme.colors.textSecondary, + JetsnackTheme.colors.textPrimary, + JetsnackTheme.colors.textPrimary, ), blendMode = blendMode, ) @@ -103,4 +107,4 @@ private fun GradientTintedIconButtonPreview() { modifier = Modifier.padding(4.dp), ) } -} +} \ No newline at end of file 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 a8e15c37cc..6940051e9b 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 @@ -38,16 +38,17 @@ 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.currentJetsnackTheme +import com.example.jetsnack.ui.theme.colors +import com.example.jetsnack.ui.theme.typography @Composable fun QuantitySelector(count: Int, decreaseItemCount: () -> Unit, increaseItemCount: () -> Unit, modifier: Modifier = Modifier) { Row(modifier = modifier) { - JetsnackText( + Text( text = stringResource(R.string.quantity), style = { - jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) - contentColor(currentJetsnackTheme.colors.textSecondary) + textStyleWithFontFamilyFix(typography.titleMedium) + contentColor(colors.textSecondary) fontWeight(FontWeight.Normal) }, modifier = Modifier @@ -65,12 +66,12 @@ fun QuantitySelector(count: Int, decreaseItemCount: () -> Unit, increaseItemCoun modifier = Modifier .align(Alignment.CenterVertically), ) { - JetsnackText( + Text( text = "$it", style = { - jetsnackTextStyle(currentJetsnackTheme.typography.titleSmall) + textStyleWithFontFamilyFix(typography.titleSmall) fontSize(18.sp) - contentColor(currentJetsnackTheme.colors.textPrimary) + contentColor(colors.textPrimary) textAlign(TextAlign.Center) }, modifier = Modifier.widthIn(min = 24.dp), @@ -91,7 +92,7 @@ fun QuantitySelector(count: Int, decreaseItemCount: () -> Unit, increaseItemCoun @Composable fun QuantitySelectorPreview() { JetsnackTheme { - JetsnackSurface { + Surface { QuantitySelector(1, {}, {}) } } @@ -101,7 +102,7 @@ fun QuantitySelectorPreview() { @Composable fun QuantitySelectorPreviewRtl() { JetsnackTheme { - JetsnackSurface { + Surface { CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) { QuantitySelector(1, {}, {}) } 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 fa56c5be65..b77f6935fb 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 @@ -83,7 +83,9 @@ 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.currentJetsnackTheme +import com.example.jetsnack.ui.theme.colors +import com.example.jetsnack.ui.theme.shapes +import com.example.jetsnack.ui.theme.typography private val HighlightCardWidth = 170.dp private val HighlightCardPadding = 16.dp @@ -105,11 +107,11 @@ fun SnackCollection( .heightIn(min = 56.dp) .padding(start = 24.dp), ) { - JetsnackText( + Text( text = snackCollection.name, style = { - jetsnackTextStyle(currentJetsnackTheme.typography.titleLarge) - contentColor(currentJetsnackTheme.colors.brand) + textStyleWithFontFamilyFix(typography.titleLarge) + contentColor(colors.brand) }, maxLines = 1, overflow = TextOverflow.Ellipsis, @@ -191,9 +193,9 @@ private fun Snacks(snackCollectionId: Long, snacks: List, onSnackClick: ( @Composable fun SnackItem(snack: Snack, snackCollectionId: Long, onSnackClick: (Long, String) -> Unit, modifier: Modifier = Modifier) { - JetsnackSurface( + Surface( style = { - shape(currentJetsnackTheme.shapes.medium) + shape(shapes.medium) }, modifier = modifier.padding( start = 4.dp, @@ -234,11 +236,11 @@ fun SnackItem(snack: Snack, snackCollectionId: Long, onSnackClick: (Long, String boundsTransform = snackDetailBoundsTransform, ), ) - JetsnackText( + Text( text = snack.name, style = { - jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) - contentColor(currentJetsnackTheme.colors.textSecondary) + textStyleWithFontFamilyFix(typography.titleMedium) + contentColor(colors.textSecondary) }, modifier = Modifier .padding(top = 8.dp) @@ -393,13 +395,13 @@ private fun HighlightSnackItem( } Spacer(modifier = Modifier.height(8.dp)) - JetsnackText( + Text( text = snack.name, maxLines = 1, overflow = TextOverflow.Ellipsis, style = { - jetsnackTextStyle(currentJetsnackTheme.typography.titleLarge) - contentColor(currentJetsnackTheme.colors.textSecondary) + textStyleWithFontFamilyFix(typography.titleLarge) + contentColor(colors.textSecondary) }, modifier = Modifier .padding(horizontal = 16.dp) @@ -421,11 +423,11 @@ private fun HighlightSnackItem( ) Spacer(modifier = Modifier.height(4.dp)) - JetsnackText( + Text( text = snack.tagline, style = { - jetsnackTextStyle(currentJetsnackTheme.typography.bodyLarge) - contentColor(currentJetsnackTheme.colors.textHelp) + textStyleWithFontFamilyFix(typography.bodyLarge) + contentColor(colors.textHelp) }, modifier = Modifier .padding(horizontal = 16.dp) @@ -465,7 +467,7 @@ fun SnackImage( modifier: Modifier = Modifier, elevation: Dp = 0.dp, ) { - JetsnackSurface( + Surface( style = { shape(CircleShape) // todo elevation 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 46aa30409a..fbbfd30f71 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 @@ -33,7 +33,7 @@ import com.example.jetsnack.ui.theme.JetsnackTheme * [com.example.jetsnack.ui.theme.JetsnackColors] */ @Composable -fun JetsnackSurface( +fun Surface( modifier: Modifier = Modifier, style: Style = Style, // todo confirm patten is acceptable 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 index 37e68dd3af..f0e374b16e 100644 --- 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 @@ -31,14 +31,14 @@ import com.example.jetsnack.ui.theme.JetsnackTheme // Workaround for b/492528450 - setting textStyle currently doesn't set fontFamily. @ExperimentalFoundationStyleApi -fun StyleScope.jetsnackTextStyle(value: TextStyle) { +fun StyleScope.textStyleWithFontFamilyFix(value: TextStyle) { textStyle(value) value.fontFamily?.let { fontFamily(it) } } @ExperimentalFoundationStyleApi @Composable -fun JetsnackText( +fun Text( text: String, modifier: Modifier = Modifier, style: Style = Style, 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 a986b7743a..b5c85d0df9 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 @@ -44,12 +44,13 @@ 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.components.Text +import com.example.jetsnack.ui.components.textStyleWithFontFamilyFix 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.currentJetsnackTheme +import com.example.jetsnack.ui.theme.colors +import com.example.jetsnack.ui.theme.typography @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -72,11 +73,11 @@ fun DestinationBar(modifier: Modifier = Modifier) { windowInsets = WindowInsets(0, 0, 0, 0), title = { Row { - JetsnackText( + Text( text = "Delivery to 1600 Amphitheater Way", style = { - jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) - contentColor(currentJetsnackTheme.colors.textSecondary) + textStyleWithFontFamilyFix(typography.titleMedium) + contentColor(colors.textSecondary) textAlign(TextAlign.Center) }, maxLines = 1, 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 39ccd8e74b..4c9b29cc22 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 @@ -47,7 +47,7 @@ import com.example.jetsnack.model.SnackCollection import com.example.jetsnack.model.SnackRepo import com.example.jetsnack.ui.components.FilterBar import com.example.jetsnack.ui.components.JetsnackDivider -import com.example.jetsnack.ui.components.JetsnackSurface +import com.example.jetsnack.ui.components.Surface import com.example.jetsnack.ui.components.SnackCollection import com.example.jetsnack.ui.theme.JetsnackTheme @@ -70,7 +70,7 @@ private fun Feed( onSnackClick: (Long, String) -> Unit, modifier: Modifier = Modifier, ) { - JetsnackSurface(modifier = modifier.fillMaxSize()) { + Surface(modifier = modifier.fillMaxSize()) { var filtersVisible by remember { mutableStateOf(false) } 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 0126912b91..0bf868481c 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 @@ -70,10 +70,11 @@ 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.components.Text +import com.example.jetsnack.ui.components.textStyleWithFontFamilyFix import com.example.jetsnack.ui.theme.JetsnackTheme -import com.example.jetsnack.ui.theme.currentJetsnackTheme +import com.example.jetsnack.ui.theme.colors +import com.example.jetsnack.ui.theme.typography @Composable fun FilterScreen(sharedTransitionScope: SharedTransitionScope, animatedVisibilityScope: AnimatedVisibilityScope, onDismiss: () -> Unit) { @@ -135,7 +136,7 @@ fun FilterScreen(sharedTransitionScope: SharedTransitionScope, animatedVisibilit contentDescription = stringResource(id = R.string.close), ) } - JetsnackText( + Text( text = stringResource(id = R.string.label_filters), modifier = Modifier .fillMaxWidth() @@ -143,7 +144,7 @@ fun FilterScreen(sharedTransitionScope: SharedTransitionScope, animatedVisibilit .padding(top = 8.dp, end = 48.dp), style = { textAlign(TextAlign.Center) - jetsnackTextStyle(currentJetsnackTheme.typography.titleLarge) + textStyleWithFontFamilyFix(typography.titleLarge) }, ) val resetEnabled = sortState != defaultFilter @@ -158,13 +159,13 @@ fun FilterScreen(sharedTransitionScope: SharedTransitionScope, animatedVisibilit FontWeight.Normal } - JetsnackText( + Text( text = stringResource(id = R.string.reset), style = { - jetsnackTextStyle(currentJetsnackTheme.typography.bodyMedium) + textStyleWithFontFamilyFix(typography.bodyMedium) fontWeight(fontWeight) contentColor( - currentJetsnackTheme.colors.uiBackground + colors.uiBackground .copy(alpha = if (!resetEnabled) 0.38f else 1f), ) }, @@ -251,11 +252,11 @@ fun SortFilters(sortFilters: List = SnackRepo.getSortFilters(), sortStat fun MaxCalories(sliderPosition: Float, onValueChanged: (Float) -> Unit) { FlowRow { FilterTitle(text = stringResource(id = R.string.max_calories)) - JetsnackText( + Text( text = stringResource(id = R.string.per_serving), style = { - jetsnackTextStyle(currentJetsnackTheme.typography.bodyMedium) - contentColor(currentJetsnackTheme.colors.brand) + textStyleWithFontFamilyFix(typography.bodyMedium) + contentColor(colors.brand) }, modifier = Modifier.padding(top = 5.dp, start = 10.dp), ) @@ -279,11 +280,11 @@ fun MaxCalories(sliderPosition: Float, onValueChanged: (Float) -> Unit) { @Composable fun FilterTitle(text: String) { - JetsnackText( + Text( text = text, style = { - jetsnackTextStyle(currentJetsnackTheme.typography.titleLarge) - contentColor(currentJetsnackTheme.colors.brand) + textStyleWithFontFamilyFix(typography.titleLarge) + contentColor(colors.brand) }, modifier = Modifier.padding(bottom = 8.dp), ) @@ -299,10 +300,10 @@ fun SortOption(text: String, @DrawableRes icon: Int?, onClickOption: () -> Unit, if (icon != null) { Icon(painter = painterResource(id = icon), contentDescription = null) } - JetsnackText( + Text( text = text, style = { - jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) + textStyleWithFontFamilyFix(typography.titleMedium) }, modifier = Modifier .padding(start = 10.dp) 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 59d3f26019..d2265268ba 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 @@ -74,15 +74,15 @@ import androidx.navigation.compose.composable 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.components.Surface +import com.example.jetsnack.ui.components.Text +import com.example.jetsnack.ui.components.textStyleWithFontFamilyFix import com.example.jetsnack.ui.home.cart.Cart import com.example.jetsnack.ui.home.search.Search import com.example.jetsnack.ui.snackdetail.nonSpatialExpressiveSpring import com.example.jetsnack.ui.snackdetail.spatialExpressiveSpring import com.example.jetsnack.ui.theme.JetsnackTheme -import com.example.jetsnack.ui.theme.currentJetsnackTheme +import com.example.jetsnack.ui.theme.typography import java.util.Locale fun NavGraphBuilder.composableWithCompositionLocal( @@ -174,7 +174,7 @@ fun JetsnackBottomBar( val routes = remember { tabs.map { it.route } } val currentSection = tabs.first { it.route == currentRoute } - JetsnackSurface( + Surface( modifier = modifier, style = { background(color) @@ -215,11 +215,11 @@ fun JetsnackBottomBar( ) }, text = { - JetsnackText( + Text( text = text, style = { contentColor(tint) - jetsnackTextStyle(currentJetsnackTheme.typography.labelLarge) + textStyleWithFontFamilyFix(typography.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 8510712f33..33e5d8ca83 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 @@ -34,10 +34,12 @@ 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.components.Text +import com.example.jetsnack.ui.components.textStyleWithFontFamilyFix import com.example.jetsnack.ui.theme.JetsnackTheme -import com.example.jetsnack.ui.theme.currentJetsnackTheme +import com.example.jetsnack.ui.theme.colors +import com.example.jetsnack.ui.theme.shapes +import com.example.jetsnack.ui.theme.typography @Composable fun Profile(modifier: Modifier = Modifier) { @@ -53,19 +55,19 @@ fun Profile(modifier: Modifier = Modifier) { contentDescription = null, ) Spacer(Modifier.height(24.dp)) - JetsnackText( + Text( text = stringResource(R.string.work_in_progress), style = { - jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) + textStyleWithFontFamilyFix(typography.titleMedium) textAlign(TextAlign.Center) }, modifier = Modifier.fillMaxWidth(), ) Spacer(Modifier.height(16.dp)) - JetsnackText( + Text( text = stringResource(R.string.grab_beverage), style = { - jetsnackTextStyle(currentJetsnackTheme.typography.bodyMedium) + textStyleWithFontFamilyFix(typography.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 66df1f0820..5576b38f06 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,7 +45,6 @@ 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.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -55,7 +54,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.layout.LastBaseline -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalResources import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -71,20 +69,20 @@ import com.example.jetsnack.R import com.example.jetsnack.model.OrderLine import com.example.jetsnack.model.SnackCollection import com.example.jetsnack.model.SnackRepo -import com.example.jetsnack.ui.components.JetsnackButton +import com.example.jetsnack.ui.components.Button 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.Text 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.components.jetsnackTextStyle +import com.example.jetsnack.ui.components.textStyleWithFontFamilyFix import com.example.jetsnack.ui.home.DestinationBar 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.currentJetsnackTheme +import com.example.jetsnack.ui.theme.colors +import com.example.jetsnack.ui.theme.typography import com.example.jetsnack.ui.utils.formatPrice import kotlin.math.roundToInt @@ -117,7 +115,7 @@ fun Cart( onSnackClick: (Long, String) -> Unit, modifier: Modifier = Modifier, ) { - JetsnackSurface(modifier = modifier.fillMaxSize()) { + com.example.jetsnack.ui.components.Surface(modifier = modifier.fillMaxSize()) { Box(modifier = Modifier.fillMaxSize()) { CartContent( orderLines = orderLines, @@ -160,11 +158,11 @@ private fun CartContent( WindowInsets.statusBars.add(WindowInsets(top = 56.dp)), ), ) - JetsnackText( + Text( text = stringResource(R.string.cart_order_header, snackCountFormattedString), style = { - jetsnackTextStyle(currentJetsnackTheme.typography.titleLarge) - contentColor(currentJetsnackTheme.colors.brand) + textStyleWithFontFamilyFix(typography.titleLarge) + contentColor(colors.brand) }, maxLines = 1, overflow = TextOverflow.Ellipsis, @@ -269,16 +267,16 @@ private fun SwipeDismissItemBackground(progress: Float) { ) } /*Text opacity increases as the text is supposed to appear in - the screen*/ + the screen*/ val textAlpha by animateFloatAsState( if (progress > 0.5f) 1f else 0.5f, label = "text alpha", ) if (progress > 0.5f) { - JetsnackText( + Text( text = stringResource(id = R.string.remove_item), style = { - jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) - contentColor(currentJetsnackTheme.colors.uiBackground) + textStyleWithFontFamilyFix(typography.titleMedium) + contentColor(colors.uiBackground) textAlign(TextAlign.Center) }, modifier = Modifier @@ -326,11 +324,11 @@ fun CartItem( .padding(start = 16.dp), ) { Row(modifier = Modifier.fillMaxWidth()) { - JetsnackText( + Text( text = snack.name, style = { - jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) - contentColor(currentJetsnackTheme.colors.textSecondary) + textStyleWithFontFamilyFix(typography.titleMedium) + contentColor(colors.textSecondary) }, modifier = Modifier .weight(1f) @@ -347,11 +345,11 @@ fun CartItem( ) } } - JetsnackText( + Text( text = snack.tagline, style = { - jetsnackTextStyle(currentJetsnackTheme.typography.bodyLarge) - contentColor(currentJetsnackTheme.colors.textHelp) + textStyleWithFontFamilyFix(typography.bodyLarge) + contentColor(colors.textHelp) }, modifier = Modifier.padding(end = 16.dp), ) @@ -359,11 +357,11 @@ fun CartItem( Row( modifier = Modifier.fillMaxWidth(), ) { - JetsnackText( + Text( text = formatPrice(snack.price), style = { - jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) - contentColor(currentJetsnackTheme.colors.textPrimary) + textStyleWithFontFamilyFix(typography.titleMedium) + contentColor(colors.textPrimary) }, modifier = Modifier .weight(1f) @@ -386,11 +384,11 @@ fun CartItem( @Composable fun SummaryItem(subtotal: Long, shippingCosts: Long, modifier: Modifier = Modifier) { Column(modifier) { - JetsnackText( + Text( text = stringResource(R.string.cart_summary_header), style = { - jetsnackTextStyle(currentJetsnackTheme.typography.titleLarge) - contentColor(currentJetsnackTheme.colors.brand) + textStyleWithFontFamilyFix(typography.titleLarge) + contentColor(colors.brand) }, maxLines = 1, overflow = TextOverflow.Ellipsis, @@ -400,39 +398,39 @@ fun SummaryItem(subtotal: Long, shippingCosts: Long, modifier: Modifier = Modifi .wrapContentHeight(), ) Row(modifier = Modifier.padding(horizontal = 24.dp)) { - JetsnackText( + Text( text = stringResource(R.string.cart_subtotal_label), style = { - jetsnackTextStyle(currentJetsnackTheme.typography.bodyLarge) + textStyleWithFontFamilyFix(typography.bodyLarge) }, modifier = Modifier .weight(1f) .wrapContentWidth(Alignment.Start) .alignBy(LastBaseline), ) - JetsnackText( + Text( text = formatPrice(subtotal), style = { - jetsnackTextStyle(currentJetsnackTheme.typography.bodyLarge) + textStyleWithFontFamilyFix(typography.bodyLarge) }, modifier = Modifier.alignBy(LastBaseline), ) } Row(modifier = Modifier.padding(horizontal = 24.dp, vertical = 8.dp)) { - JetsnackText( + Text( text = stringResource(R.string.cart_shipping_label), style = { - jetsnackTextStyle(currentJetsnackTheme.typography.bodyLarge) + textStyleWithFontFamilyFix(typography.bodyLarge) }, modifier = Modifier .weight(1f) .wrapContentWidth(Alignment.Start) .alignBy(LastBaseline), ) - JetsnackText( + Text( text = formatPrice(shippingCosts), style = { - jetsnackTextStyle(currentJetsnackTheme.typography.bodyLarge) + textStyleWithFontFamilyFix(typography.bodyLarge) }, modifier = Modifier.alignBy(LastBaseline), ) @@ -440,10 +438,10 @@ fun SummaryItem(subtotal: Long, shippingCosts: Long, modifier: Modifier = Modifi Spacer(modifier = Modifier.height(8.dp)) JetsnackDivider() Row(modifier = Modifier.padding(horizontal = 24.dp, vertical = 8.dp)) { - JetsnackText( + Text( text = stringResource(R.string.cart_total_label), style = { - jetsnackTextStyle(currentJetsnackTheme.typography.bodyLarge) + textStyleWithFontFamilyFix(typography.bodyLarge) }, modifier = Modifier .weight(1f) @@ -451,10 +449,10 @@ fun SummaryItem(subtotal: Long, shippingCosts: Long, modifier: Modifier = Modifi .wrapContentWidth(Alignment.End) .alignBy(LastBaseline), ) - JetsnackText( + Text( text = formatPrice(subtotal + shippingCosts), style = { - jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) + textStyleWithFontFamilyFix(typography.titleMedium) }, modifier = Modifier.alignBy(LastBaseline), ) @@ -474,7 +472,7 @@ private fun CheckoutBar(modifier: Modifier = Modifier) { JetsnackDivider() Row { Spacer(Modifier.weight(1f)) - JetsnackButton( + Button( onClick = { /* todo */ }, style = { shape(RectangleShape) @@ -483,7 +481,7 @@ private fun CheckoutBar(modifier: Modifier = Modifier) { .padding(horizontal = 12.dp, vertical = 8.dp) .weight(1f), ) { - JetsnackText( + Text( text = stringResource(id = R.string.cart_checkout), modifier = Modifier.fillMaxWidth(), style = { 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 5238998a94..f17b2eaeed 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 @@ -43,12 +43,13 @@ 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.Text import com.example.jetsnack.ui.components.SnackImage import com.example.jetsnack.ui.components.VerticalGrid -import com.example.jetsnack.ui.components.jetsnackTextStyle +import com.example.jetsnack.ui.components.textStyleWithFontFamilyFix import com.example.jetsnack.ui.theme.JetsnackTheme -import com.example.jetsnack.ui.theme.currentJetsnackTheme +import com.example.jetsnack.ui.theme.colors +import com.example.jetsnack.ui.theme.typography import kotlin.math.max @Composable @@ -64,11 +65,11 @@ fun SearchCategories(categories: List) { @Composable private fun SearchCategoryCollection(collection: SearchCategoryCollection, index: Int, modifier: Modifier = Modifier) { Column(modifier) { - JetsnackText( + Text( text = collection.name, style = { - jetsnackTextStyle(currentJetsnackTheme.typography.titleLarge) - contentColor(currentJetsnackTheme.colors.textPrimary) + textStyleWithFontFamilyFix(typography.titleLarge) + contentColor(colors.textPrimary) }, modifier = Modifier .heightIn(min = 56.dp) @@ -106,11 +107,11 @@ private fun SearchCategory(category: SearchCategory, gradient: List, modi .background(Brush.horizontalGradient(gradient)) .clickable { /* todo */ }, content = { - JetsnackText( + Text( text = category.name, style = { - jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) - contentColor(currentJetsnackTheme.colors.textSecondary) + textStyleWithFontFamilyFix(typography.titleMedium) + contentColor(colors.textSecondary) }, modifier = Modifier .padding(4.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 852655b670..14057014f9 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 @@ -21,7 +21,6 @@ import androidx.compose.foundation.Image import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize @@ -45,24 +44,25 @@ import androidx.compose.ui.unit.dp import com.example.jetsnack.R import com.example.jetsnack.model.Snack import com.example.jetsnack.model.snacks -import com.example.jetsnack.ui.components.JetsnackButton +import com.example.jetsnack.ui.components.Button 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.Surface +import com.example.jetsnack.ui.components.Text import com.example.jetsnack.ui.components.SnackImage -import com.example.jetsnack.ui.components.jetsnackTextStyle +import com.example.jetsnack.ui.components.textStyleWithFontFamilyFix import com.example.jetsnack.ui.theme.JetsnackTheme -import com.example.jetsnack.ui.theme.currentJetsnackTheme +import com.example.jetsnack.ui.theme.colors +import com.example.jetsnack.ui.theme.typography import com.example.jetsnack.ui.utils.formatPrice @Composable fun SearchResults(searchResults: List, onSnackClick: (Long, String) -> Unit) { Column { - JetsnackText( + Text( text = stringResource(R.string.search_count, searchResults.size), style = { - jetsnackTextStyle(currentJetsnackTheme.typography.titleLarge) - contentColor(currentJetsnackTheme.colors.textPrimary) + textStyleWithFontFamilyFix(typography.titleLarge) + contentColor(colors.textPrimary) }, modifier = Modifier.padding(horizontal = 24.dp, vertical = 4.dp), ) @@ -101,30 +101,30 @@ private fun SearchResult(snack: Snack, onSnackClick: (Long, String) -> Unit, sho .weight(1f) .padding(start = 16.dp, end = 16.dp), ) { - JetsnackText( + Text( text = snack.name, style = { - jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) - contentColor(currentJetsnackTheme.colors.textSecondary) + textStyleWithFontFamilyFix(typography.titleMedium) + contentColor(colors.textSecondary) }, ) - JetsnackText( + Text( text = snack.tagline, style = { - jetsnackTextStyle(currentJetsnackTheme.typography.bodyLarge) - contentColor(currentJetsnackTheme.colors.textHelp) + textStyleWithFontFamilyFix(typography.bodyLarge) + contentColor(colors.textHelp) }, ) Spacer(Modifier.height(8.dp)) - JetsnackText( + Text( text = formatPrice(snack.price), style = { - jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) - contentColor(currentJetsnackTheme.colors.textPrimary) + textStyleWithFontFamilyFix(typography.titleMedium) + contentColor(colors.textPrimary) }, ) } - JetsnackButton( + Button( onClick = { /* todo */ }, style = { shape(CircleShape) @@ -155,19 +155,19 @@ fun NoResults(query: String, modifier: Modifier = Modifier) { contentDescription = null, ) Spacer(Modifier.height(24.dp)) - JetsnackText( + Text( text = stringResource(R.string.search_no_matches, query), style = { - jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) + textStyleWithFontFamilyFix(typography.titleMedium) textAlign(TextAlign.Center) }, modifier = Modifier.fillMaxWidth(), ) Spacer(Modifier.height(16.dp)) - JetsnackText( + Text( text = stringResource(R.string.search_no_matches_retry), style = { - jetsnackTextStyle(currentJetsnackTheme.typography.bodyMedium) + textStyleWithFontFamilyFix(typography.bodyMedium) textAlign(TextAlign.Center) }, modifier = Modifier.fillMaxWidth(), @@ -181,7 +181,7 @@ fun NoResults(query: String, modifier: Modifier = Modifier) { @Composable private fun SearchResultPreview() { JetsnackTheme { - JetsnackSurface { + Surface { SearchResult( snack = snacks[0], onSnackClick = { _, _ -> }, 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 ff24a92711..e284e7951b 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 @@ -57,14 +57,15 @@ import com.example.jetsnack.model.SearchSuggestionGroup 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.components.Surface +import com.example.jetsnack.ui.components.Text import com.example.jetsnack.ui.theme.JetsnackTheme -import com.example.jetsnack.ui.theme.currentJetsnackTheme +import com.example.jetsnack.ui.theme.colors +import com.example.jetsnack.ui.theme.shapes @Composable fun Search(onSnackClick: (Long, String) -> Unit, modifier: Modifier = Modifier, state: SearchState = rememberSearchState()) { - JetsnackSurface(modifier = modifier.fillMaxSize()) { + Surface(modifier = modifier.fillMaxSize()) { Column { Spacer(modifier = Modifier.statusBarsPadding()) SearchBar( @@ -169,11 +170,11 @@ private fun SearchBar( searching: Boolean, modifier: Modifier = Modifier, ) { - JetsnackSurface( + Surface( style = { - background(currentJetsnackTheme.colors.uiFloated) - contentColor(currentJetsnackTheme.colors.textSecondary) - shape(currentJetsnackTheme.shapes.small) + background(colors.uiFloated) + contentColor(colors.textSecondary) + shape(shapes.small) }, modifier = modifier .fillMaxWidth() @@ -239,10 +240,10 @@ private fun SearchHint() { contentDescription = stringResource(R.string.label_search), ) Spacer(Modifier.width(8.dp)) - JetsnackText( + Text( text = stringResource(R.string.search_jetsnack), style = { - contentColor(currentJetsnackTheme.colors.textHelp) + contentColor(colors.textHelp) }, ) } @@ -254,7 +255,7 @@ private fun SearchHint() { @Composable private fun SearchBarPreview() { JetsnackTheme { - JetsnackSurface { + Surface { SearchBar( query = TextFieldValue(""), onQueryChange = { }, 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 40d122e71a..8ebe6ba34b 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 @@ -33,11 +33,12 @@ import androidx.compose.ui.tooling.preview.Preview 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.components.Surface +import com.example.jetsnack.ui.components.Text +import com.example.jetsnack.ui.components.textStyleWithFontFamilyFix import com.example.jetsnack.ui.theme.JetsnackTheme -import com.example.jetsnack.ui.theme.currentJetsnackTheme +import com.example.jetsnack.ui.theme.colors +import com.example.jetsnack.ui.theme.typography @Composable fun SearchSuggestions(suggestions: List, onSuggestionSelect: (String) -> Unit) { @@ -62,11 +63,11 @@ fun SearchSuggestions(suggestions: List, onSuggestionSele @Composable private fun SuggestionHeader(name: String, modifier: Modifier = Modifier) { - JetsnackText( + Text( text = name, style = { - jetsnackTextStyle(currentJetsnackTheme.typography.titleLarge) - contentColor(currentJetsnackTheme.colors.textPrimary) + textStyleWithFontFamilyFix(typography.titleLarge) + contentColor(colors.textPrimary) }, modifier = modifier .heightIn(min = 56.dp) @@ -77,10 +78,10 @@ private fun SuggestionHeader(name: String, modifier: Modifier = Modifier) { @Composable private fun Suggestion(suggestion: String, onSuggestionSelect: (String) -> Unit, modifier: Modifier = Modifier) { - JetsnackText( + Text( text = suggestion, style = { - jetsnackTextStyle(currentJetsnackTheme.typography.titleMedium) + textStyleWithFontFamilyFix(typography.titleMedium) }, modifier = modifier .heightIn(min = 48.dp) @@ -96,7 +97,7 @@ private fun Suggestion(suggestion: String, onSuggestionSelect: (String) -> Unit, @Composable fun PreviewSuggestions() { JetsnackTheme { - JetsnackSurface { + Surface { SearchSuggestions( suggestions = SearchRepo.getSuggestions(), onSuggestionSelect = { }, 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 a6c35c6f65..ec555a7ab7 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 @@ -65,7 +65,6 @@ 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.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.key @@ -103,18 +102,19 @@ import com.example.jetsnack.ui.LocalNavAnimatedVisibilityScope import com.example.jetsnack.ui.LocalSharedTransitionScope import com.example.jetsnack.ui.SnackSharedElementKey import com.example.jetsnack.ui.SnackSharedElementType -import com.example.jetsnack.ui.components.JetsnackButton +import com.example.jetsnack.ui.components.Button 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.Surface +import com.example.jetsnack.ui.components.Text 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.components.jetsnackTextStyle +import com.example.jetsnack.ui.components.textStyleWithFontFamilyFix import com.example.jetsnack.ui.theme.JetsnackTheme import com.example.jetsnack.ui.theme.Neutral8 -import com.example.jetsnack.ui.theme.currentJetsnackTheme +import com.example.jetsnack.ui.theme.colors +import com.example.jetsnack.ui.theme.typography import com.example.jetsnack.ui.utils.formatPrice import kotlin.math.max import kotlin.math.min @@ -299,29 +299,29 @@ private fun Body(related: List, scroll: ScrollState) { ) { Spacer(Modifier.height(GradientScroll)) Spacer(Modifier.height(ImageOverlap)) - JetsnackSurface( + Surface( Modifier .fillMaxWidth() .padding(top = 16.dp), ) { Column { Spacer(Modifier.height(TitleHeight)) - JetsnackText( + Text( text = stringResource(R.string.detail_header), style = { - jetsnackTextStyle(currentJetsnackTheme.typography.headlineMedium) - contentColor(currentJetsnackTheme.colors.textHelp) + textStyleWithFontFamilyFix(typography.headlineMedium) + contentColor(colors.textHelp) contentPaddingHorizontal(24.dp) }, ) Spacer(Modifier.height(16.dp)) var seeMore by remember { mutableStateOf(true) } with(sharedTransitionScope) { - JetsnackText( + Text( text = stringResource(R.string.detail_placeholder), style = { - jetsnackTextStyle(currentJetsnackTheme.typography.bodyLarge) - contentColor(currentJetsnackTheme.colors.textHelp) + textStyleWithFontFamilyFix(typography.bodyLarge) + contentColor(colors.textHelp) contentPaddingHorizontal(24.dp) }, maxLines = if (seeMore) 5 else Int.MAX_VALUE, @@ -335,11 +335,11 @@ private fun Body(related: List, scroll: ScrollState) { stringResource(id = R.string.see_less) } - JetsnackText( + Text( text = textButton, style = { - jetsnackTextStyle(currentJetsnackTheme.typography.labelLarge) - contentColor(currentJetsnackTheme.colors.textLink) + textStyleWithFontFamilyFix(typography.labelLarge) + contentColor(colors.textLink) textAlign(TextAlign.Center) contentPaddingTop(15.dp) fillWidth() @@ -353,20 +353,20 @@ private fun Body(related: List, scroll: ScrollState) { ) Spacer(Modifier.height(40.dp)) - JetsnackText( + Text( text = stringResource(R.string.ingredients), style = { - jetsnackTextStyle(currentJetsnackTheme.typography.labelSmall) - contentColor(currentJetsnackTheme.colors.textHelp) + textStyleWithFontFamilyFix(typography.labelSmall) + contentColor(colors.textHelp) contentPaddingHorizontal(24.dp) }, ) Spacer(Modifier.height(4.dp)) - JetsnackText( + Text( text = stringResource(R.string.ingredients_list), style = { - jetsnackTextStyle(currentJetsnackTheme.typography.bodyLarge) - contentColor(currentJetsnackTheme.colors.textHelp) + textStyleWithFontFamilyFix(typography.bodyLarge) + contentColor(colors.textHelp) contentPaddingHorizontal(24.dp) }, ) @@ -421,11 +421,11 @@ private fun Title(snack: Snack, origin: String, scrollProvider: () -> Int) { .background(JetsnackTheme.colors.uiBackground), ) { Spacer(Modifier.height(16.dp)) - JetsnackText( + Text( text = snack.name, style = { - jetsnackTextStyle(currentJetsnackTheme.typography.headlineMedium) - contentColor(currentJetsnackTheme.colors.textSecondary) + textStyleWithFontFamilyFix(typography.headlineMedium) + contentColor(colors.textSecondary) fontStyle(FontStyle.Italic) }, modifier = HzPadding @@ -442,12 +442,12 @@ private fun Title(snack: Snack, origin: String, scrollProvider: () -> Int) { ) .wrapContentWidth(), ) - JetsnackText( + Text( text = snack.tagline, style = { - jetsnackTextStyle(currentJetsnackTheme.typography.titleSmall) + textStyleWithFontFamilyFix(typography.titleSmall) fontStyle(FontStyle.Italic) - contentColor(currentJetsnackTheme.colors.textHelp) + contentColor(colors.textHelp) fontSize(20.sp) }, modifier = HzPadding @@ -466,11 +466,11 @@ private fun Title(snack: Snack, origin: String, scrollProvider: () -> Int) { ) Spacer(Modifier.height(4.dp)) with(animatedVisibilityScope) { - JetsnackText( + Text( text = formatPrice(snack.price), style = { - jetsnackTextStyle(currentJetsnackTheme.typography.titleLarge) - contentColor(currentJetsnackTheme.colors.textPrimary) + textStyleWithFontFamilyFix(typography.titleLarge) + contentColor(colors.textPrimary) }, modifier = HzPadding .animateEnterExit( @@ -572,7 +572,7 @@ private fun CartBottomBar(modifier: Modifier = Modifier) { LocalNavAnimatedVisibilityScope.current ?: throw IllegalStateException("No Shared scope") with(sharedTransitionScope) { with(animatedVisibilityScope) { - JetsnackSurface( + Surface( modifier = modifier .renderInSharedTransitionScopeOverlay(zIndexInOverlay = 4f) .animateEnterExit( @@ -601,11 +601,11 @@ private fun CartBottomBar(modifier: Modifier = Modifier) { increaseItemCount = { updateCount(count + 1) }, ) Spacer(Modifier.width(16.dp)) - JetsnackButton( + Button( onClick = { /* todo */ }, modifier = Modifier.weight(1f), ) { - JetsnackText( + Text( text = stringResource(R.string.add_to_cart), modifier = Modifier.fillMaxWidth(), style = { 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 9b6012b704..acc31f6237 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 @@ -22,12 +22,10 @@ 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.StyleScope 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.LocalTextStyle import androidx.compose.runtime.Immutable import androidx.compose.ui.graphics.Brush @@ -35,48 +33,48 @@ 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 -import com.example.jetsnack.ui.theme.JetsnackTheme.Companion.LocalJetsnackTheme +import com.example.jetsnack.ui.components.textStyleWithFontFamilyFix @Immutable data class AppStyles( val buttonStyle: Style = Style { shape(RoundedCornerShape(percent = 50)) - background(Brush.linearGradient(currentJetsnackTheme.colors.interactivePrimary)) - contentColor(currentJetsnackTheme.colors.textInteractive) - contentPadding(ButtonDefaults.ContentPadding.calculateTopPadding()) // todo file issue to support padding values - jetsnackTextStyle(currentJetsnackTheme.typography.labelLarge) + background(Brush.linearGradient(colors.interactivePrimary)) + contentColor(colors.textInteractive) + contentPaddingVertical(8.dp) + contentPaddingHorizontal(24.dp) + textStyleWithFontFamilyFix(typography.labelLarge) disabled { animate { - background(Brush.linearGradient(currentJetsnackTheme.colors.interactiveSecondary)) - contentColor(currentJetsnackTheme.colors.textHelp) + background(Brush.linearGradient(colors.interactiveSecondary)) + contentColor(colors.textHelp) } } }, val cardStyle: Style = Style { - shape(currentJetsnackTheme.shapes.medium) - background(currentJetsnackTheme.colors.uiBackground) - contentColor(currentJetsnackTheme.colors.textPrimary) + shape(shapes.medium) + background(colors.uiBackground) + contentColor(colors.textPrimary) /* todo elevation elevation: Dp = 4.dp,*/ }, val dividerStyle: Style = Style { - background(currentJetsnackTheme.colors.uiBorder.copy(alpha = 0.12f)) + background(colors.uiBorder.copy(alpha = 0.12f)) height(1.dp) fillWidth() }, val gradientIconButtonStyle: Style = Style { shape(CircleShape) clip(true) - border(2.dp, Brush.linearGradient(currentJetsnackTheme.colors.interactiveSecondary)) - background(currentJetsnackTheme.colors.uiBackground) + border(2.dp, Brush.linearGradient(colors.interactiveSecondary)) + background(colors.uiBackground) pressed { animate { background( Brush.horizontalGradient( // this was a parameter input into the function? might want to make helper function for it - colors = currentJetsnackTheme.colors.interactiveSecondary, + colors = colors.interactiveSecondary, startX = 0f, endX = 200f, tileMode = TileMode.Mirror, @@ -86,28 +84,26 @@ data class AppStyles( } }, val filterChipStyle: Style = Style { - shape(currentJetsnackTheme.shapes.small) - background(currentJetsnackTheme.colors.uiBackground) - contentColor(currentJetsnackTheme.colors.textSecondary) - border(1.dp, Brush.linearGradient(currentJetsnackTheme.colors.interactiveSecondary)) + shape(shapes.small) + background(colors.uiBackground) + contentColor(colors.textSecondary) + border(1.dp, Brush.linearGradient(colors.interactiveSecondary)) // todo elevation = 2.dp, selected { animate { - background(currentJetsnackTheme.colors.brandSecondary) + background(colors.brandSecondary) contentColor(Color.Black) border(1.dp, Color.Transparent) } } }, val defaultTextStyle: Style = Style { - jetsnackTextStyle(LocalTextStyle.currentValue) + textStyleWithFontFamilyFix(LocalTextStyle.currentValue) }, val surfaceStyle: Style = Style { shape(RectangleShape) - background(currentJetsnackTheme.colors.uiBackground) - contentColor(currentJetsnackTheme.colors.textSecondary) + background(colors.uiBackground) + contentColor(colors.textSecondary) clip(true) }, ) -val StyleScope.currentJetsnackTheme: JetsnackTheme - get() = LocalJetsnackTheme.currentValue 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 4b19ef0080..16af20c9a1 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 @@ -20,6 +20,7 @@ package com.example.jetsnack.ui.theme import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.style.ExperimentalFoundationStyleApi +import androidx.compose.foundation.style.StyleScope import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Shapes import androidx.compose.material3.Typography @@ -34,10 +35,9 @@ import androidx.compose.runtime.staticCompositionLocalOf class JetsnackTheme( val colors: JetsnackColors = LightColorPalette, val typography: Typography = Typography, + val shapes: Shapes = Shapes, val appStyles: AppStyles = AppStyles(), ) { - val shapes: Shapes = _shapes - companion object { val colors: JetsnackColors @Composable @ReadOnlyComposable @@ -57,11 +57,18 @@ class JetsnackTheme( val LocalJetsnackTheme: ProvidableCompositionLocal get() = LocalJetsnackThemeInstance - - private val _shapes = Shapes } } +val StyleScope.colors: JetsnackColors + get() = JetsnackTheme.LocalJetsnackTheme.currentValue.colors + +val StyleScope.typography: Typography + get() = JetsnackTheme.LocalJetsnackTheme.currentValue.typography + +val StyleScope.shapes: Shapes + get() = JetsnackTheme.LocalJetsnackTheme.currentValue.shapes + internal val LocalJetsnackThemeInstance = staticCompositionLocalOf { JetsnackTheme() } @Composable From 2e57f912919f3c14205ab4849881f08362d06f4c Mon Sep 17 00:00:00 2001 From: Rebecca Franks Date: Mon, 16 Mar 2026 20:59:16 +0000 Subject: [PATCH 06/11] Rename `AppStyles` to `Styles` and refactor styling in components - Rename `AppStyles` data class to `Styles` and update all references in `JetsnackTheme`. - Update `JetsnackCard`, `JetsnackDivider`, `JetsnackButton`, and other components to use the renamed `styles` property. - Move border and size styling from `Modifier` to `Style` in `SnackHighlight` cards. - Remove unused `HorizontalDivider` import and clean up styling logic in `Text.kt`. --- .../com/example/jetsnack/ui/components/Button.kt | 2 +- .../java/com/example/jetsnack/ui/components/Card.kt | 2 +- .../com/example/jetsnack/ui/components/Divider.kt | 3 +-- .../com/example/jetsnack/ui/components/Filters.kt | 2 +- .../ui/components/GradientTintedIconButton.kt | 6 +----- .../com/example/jetsnack/ui/components/Snacks.kt | 12 +++--------- .../com/example/jetsnack/ui/components/Surface.kt | 2 +- .../java/com/example/jetsnack/ui/components/Text.kt | 4 ++-- .../java/com/example/jetsnack/ui/theme/Styles.kt | 2 +- .../main/java/com/example/jetsnack/ui/theme/Theme.kt | 8 ++++---- 10 files changed, 16 insertions(+), 27 deletions(-) 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 b5fc023b37..6c25594383 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 @@ -53,7 +53,7 @@ fun Button( it.isEnabled = enabled }) Surface( - style = JetsnackTheme.appStyles.buttonStyle then style, + style = JetsnackTheme.styles.buttonStyle then style, styleState = styleState, modifier = modifier .clickable( 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 dc8c4041e4..5cc626f2ba 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 @@ -33,7 +33,7 @@ import com.example.jetsnack.ui.theme.JetsnackTheme fun JetsnackCard(modifier: Modifier = Modifier, style: Style = Style, content: @Composable () -> Unit) { Surface( modifier = modifier, - style = JetsnackTheme.appStyles.cardStyle then style, + style = JetsnackTheme.styles.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 8a14dcb806..a135fa9740 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 @@ -24,7 +24,6 @@ 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 @@ -35,7 +34,7 @@ import com.example.jetsnack.ui.theme.JetsnackTheme.Companion.LocalJetsnackTheme @Composable fun JetsnackDivider(modifier: Modifier = Modifier, style: Style = Style) { - Box(modifier = modifier.styleable(null, LocalJetsnackTheme.current.appStyles.dividerStyle, style)) + Box(modifier = modifier.styleable(null, LocalJetsnackTheme.current.styles.dividerStyle, style)) } @Preview("default", 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 58dc08f5a8..64ad722db6 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 @@ -128,7 +128,7 @@ fun FilterChip(filter: Filter, modifier: Modifier = Modifier, style: Style = Sty interactionSource = interactionSource, indication = null, ), - style = JetsnackTheme.appStyles.filterChipStyle then style, + style = JetsnackTheme.styles.filterChipStyle then style, styleState = styleState, ) { val innerBackgroundStyle = Style { 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 0b73d55bde..5b958a60f4 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 @@ -23,19 +23,15 @@ import androidx.annotation.DrawableRes import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.collectIsPressedAsState -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.padding 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.material3.Icon import androidx.compose.material3.Surface -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.BlendMode import androidx.compose.ui.graphics.Color @@ -66,7 +62,7 @@ fun JetsnackGradientTintedIconButton( interactionSource = interactionSource, indication = null, ) - .styleable(styleState, JetsnackTheme.appStyles.gradientIconButtonStyle, style), + .styleable(styleState, JetsnackTheme.styles.gradientIconButtonStyle, style), color = Color.Transparent, ) { val blendMode = if (JetsnackTheme.colors.isDark) BlendMode.Darken else BlendMode.Plus 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 b77f6935fb..29671c719c 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 @@ -291,6 +291,8 @@ private fun HighlightSnackItem( JetsnackCard( style = Style { shape(RoundedCornerShape(roundedCornerAnimation)) + border(1.dp, colors.uiBorder.copy(alpha = 0.12f)) + size(width = HighlightCardWidth, height = 250.dp) }, modifier = modifier .padding(bottom = 16.dp) @@ -311,15 +313,6 @@ private fun HighlightSnackItem( ), enter = fadeIn(), exit = fadeOut(), - ) - .size( - width = HighlightCardWidth, - height = 250.dp, - ) - .border( - 1.dp, - JetsnackTheme.colors.uiBorder.copy(alpha = 0.12f), - RoundedCornerShape(roundedCornerAnimation), ), ) { @@ -395,6 +388,7 @@ private fun HighlightSnackItem( } Spacer(modifier = Modifier.height(8.dp)) + Text( text = snack.name, maxLines = 1, 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 fbbfd30f71..6f24605445 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 @@ -42,7 +42,7 @@ fun Surface( ) { Box( modifier = modifier - .styleable(styleState, JetsnackTheme.appStyles.surfaceStyle, style) + .styleable(styleState, JetsnackTheme.styles.surfaceStyle, style) ) { //todo double check CompositionLocalProvider(LocalContentColor provides contentColor, content = content) content() 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 index f0e374b16e..cf1b88e949 100644 --- 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 @@ -33,7 +33,7 @@ import com.example.jetsnack.ui.theme.JetsnackTheme @ExperimentalFoundationStyleApi fun StyleScope.textStyleWithFontFamilyFix(value: TextStyle) { textStyle(value) - value.fontFamily?.let { fontFamily(it) } + //value.fontFamily?.let { fontFamily(it) } } @ExperimentalFoundationStyleApi @@ -51,7 +51,7 @@ fun Text( ) { BasicText( text = text, - modifier = modifier.styleable(null, JetsnackTheme.appStyles.defaultTextStyle, style), + modifier = modifier.styleable(null, JetsnackTheme.styles.defaultTextStyle, style), onTextLayout = onTextLayout, overflow = overflow, softWrap = softWrap, 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 acc31f6237..f9db5ad8ee 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 @@ -36,7 +36,7 @@ import androidx.compose.ui.unit.dp import com.example.jetsnack.ui.components.textStyleWithFontFamilyFix @Immutable -data class AppStyles( +data class Styles( val buttonStyle: Style = Style { shape(RoundedCornerShape(percent = 50)) background(Brush.linearGradient(colors.interactivePrimary)) 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 16af20c9a1..bbf60c7c56 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 @@ -36,7 +36,7 @@ class JetsnackTheme( val colors: JetsnackColors = LightColorPalette, val typography: Typography = Typography, val shapes: Shapes = Shapes, - val appStyles: AppStyles = AppStyles(), + val styles: Styles = Styles(), ) { companion object { val colors: JetsnackColors @@ -51,9 +51,9 @@ class JetsnackTheme( @Composable @ReadOnlyComposable get() = LocalJetsnackTheme.current.shapes - val appStyles: AppStyles + val styles: Styles @Composable @ReadOnlyComposable - get() = LocalJetsnackTheme.current.appStyles + get() = LocalJetsnackTheme.current.styles val LocalJetsnackTheme: ProvidableCompositionLocal get() = LocalJetsnackThemeInstance @@ -74,7 +74,7 @@ internal val LocalJetsnackThemeInstance = staticCompositionLocalOf { JetsnackThe @Composable fun JetsnackTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) { val colors = if (darkTheme) DarkColorPalette else LightColorPalette - val theme = JetsnackTheme(colors = colors, appStyles = AppStyles()) + val theme = JetsnackTheme(colors = colors, styles = Styles()) CompositionLocalProvider( JetsnackTheme.LocalJetsnackTheme provides theme, From b733ea8cd4b3f5233ab2fbe2cdd85180400e94f4 Mon Sep 17 00:00:00 2001 From: Rebecca Franks Date: Tue, 17 Mar 2026 13:07:07 +0000 Subject: [PATCH 07/11] Update snack components and detail view to use Compose Foundation styling APIs. --- .../example/jetsnack/ui/components/Snacks.kt | 43 ++++++++++--------- .../jetsnack/ui/snackdetail/SnackDetail.kt | 3 ++ .../com/example/jetsnack/ui/theme/Styles.kt | 2 +- 3 files changed, 27 insertions(+), 21 deletions(-) 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 29671c719c..2cd70db035 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 @@ -51,6 +51,7 @@ 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.styleable import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.runtime.Composable @@ -58,7 +59,10 @@ import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.getValue 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.TileMode import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalDensity @@ -220,7 +224,6 @@ fun SnackItem(snack: Snack, snackCollectionId: Long, onSnackClick: (Long, String ) { SnackImage( imageRes = snack.imageRes, - elevation = 1.dp, contentDescription = null, modifier = Modifier .size(120.dp) @@ -291,7 +294,8 @@ private fun HighlightSnackItem( JetsnackCard( style = Style { shape(RoundedCornerShape(roundedCornerAnimation)) - border(1.dp, colors.uiBorder.copy(alpha = 0.12f)) + clip(true) + border(1.dp, colors.uiBorder) size(width = HighlightCardWidth, height = 250.dp) }, modifier = modifier @@ -313,8 +317,7 @@ private fun HighlightSnackItem( ), enter = fadeIn(), exit = fadeOut(), - ), - + ) ) { Column( modifier = Modifier @@ -332,6 +335,20 @@ private fun HighlightSnackItem( .height(160.dp) .fillMaxWidth(), ) { + // todo investigate this is not clipping properly to the container + val spannedBackgroundGradient = Style { + val left = index * cardWidthWithPaddingPx + val gradientOffset = left - (scrollProvider() / 3f) + + val brush = + Brush.horizontalGradient( + colors = gradient, + startX = -gradientOffset, + endX = (6 * cardWidthWithPaddingPx) - gradientOffset, + tileMode = TileMode.Mirror, + ) + background(brush) + } Box( modifier = Modifier .sharedBounds( @@ -348,21 +365,9 @@ private fun HighlightSnackItem( exit = fadeOut(nonSpatialExpressiveSpring()), resizeMode = SharedTransitionScope.ResizeMode.scaleToBounds(), ) + .styleable(null, spannedBackgroundGradient) .height(100.dp) .fillMaxWidth() - .offsetGradientBackground( - colors = gradient, - width = { - // The Cards show a gradient which spans 6 cards and - // scrolls with parallax. - 6 * cardWidthWithPaddingPx - }, - offset = { - val left = index * cardWidthWithPaddingPx - val gradientOffset = left - (scrollProvider() / 3f) - gradientOffset - }, - ), ) SnackImage( @@ -458,13 +463,11 @@ fun SnackImage( @DrawableRes imageRes: Int, contentDescription: String?, - modifier: Modifier = Modifier, - elevation: Dp = 0.dp, + modifier: Modifier = Modifier ) { Surface( style = { shape(CircleShape) - // todo elevation }, modifier = modifier, ) { 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 ec555a7ab7..7ae75aa3e7 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 @@ -604,6 +604,9 @@ private fun CartBottomBar(modifier: Modifier = Modifier) { Button( onClick = { /* todo */ }, modifier = Modifier.weight(1f), + style = { + externalPadding(4.dp) + } ) { Text( text = stringResource(R.string.add_to_cart), 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 f9db5ad8ee..5fa46b83ea 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 @@ -38,7 +38,7 @@ import com.example.jetsnack.ui.components.textStyleWithFontFamilyFix @Immutable data class Styles( val buttonStyle: Style = Style { - shape(RoundedCornerShape(percent = 50)) + shape(shapes.small) background(Brush.linearGradient(colors.interactivePrimary)) contentColor(colors.textInteractive) contentPaddingVertical(8.dp) From d116df3b4d1bf89b0adcc319e1a15d1cdb80e1d3 Mon Sep 17 00:00:00 2001 From: Rebecca Franks Date: Tue, 17 Mar 2026 13:09:21 +0000 Subject: [PATCH 08/11] Enable font family application in textStyleWithFontFamilyFix --- .../src/main/java/com/example/jetsnack/ui/components/Text.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index cf1b88e949..b37c4208d0 100644 --- 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 @@ -33,7 +33,7 @@ import com.example.jetsnack.ui.theme.JetsnackTheme @ExperimentalFoundationStyleApi fun StyleScope.textStyleWithFontFamilyFix(value: TextStyle) { textStyle(value) - //value.fontFamily?.let { fontFamily(it) } + value.fontFamily?.let { fontFamily(it) } } @ExperimentalFoundationStyleApi From 252b8f7a24922badaa8b3bc93c022e52abc342ee Mon Sep 17 00:00:00 2001 From: Rebecca Franks Date: Wed, 18 Mar 2026 13:17:39 +0000 Subject: [PATCH 09/11] Simplify button definition. --- .../example/jetsnack/ui/components/Button.kt | 38 +++++++++---------- 1 file changed, 17 insertions(+), 21 deletions(-) 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 6c25594383..97910aa870 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 @@ -22,12 +22,14 @@ import android.content.res.Configuration.UI_MODE_NIGHT_YES import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.defaultMinSize 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.foundation.style.then import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ripple @@ -37,6 +39,8 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.semantics.Role +import androidx.compose.ui.semantics.role +import androidx.compose.ui.semantics.semantics import androidx.compose.ui.tooling.preview.Preview import com.example.jetsnack.ui.theme.JetsnackTheme @@ -49,32 +53,24 @@ fun Button( interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, content: @Composable RowScope.() -> Unit, ) { - val styleState = rememberUpdatedStyleState(interactionSource, { + val styleState = rememberUpdatedStyleState(interactionSource) { it.isEnabled = enabled - }) - Surface( - style = JetsnackTheme.styles.buttonStyle then style, - styleState = styleState, + } + Row( modifier = modifier + .semantics(properties = { + role = Role.Button + }) .clickable( - onClick = onClick, enabled = enabled, - role = Role.Button, + onClick = onClick, interactionSource = interactionSource, - indication = ripple() //TODO This ripple doesn't know the shape of the button. - ), - ) { - Row( - Modifier - .defaultMinSize( - minWidth = ButtonDefaults.MinWidth, - minHeight = ButtonDefaults.MinHeight, - ), - horizontalArrangement = Arrangement.Center, - verticalAlignment = Alignment.CenterVertically, - content = content, - ) - } + indication = null, + ) + .styleable(styleState, JetsnackTheme.styles.buttonStyle, style), + content = content, + verticalAlignment = Alignment.CenterVertically + ) } @Preview("default", "round") From 8ca8c344cb5df22fce7a36438c1e6107efc7f339 Mon Sep 17 00:00:00 2001 From: Rebecca Franks Date: Wed, 18 Mar 2026 13:20:20 +0000 Subject: [PATCH 10/11] Simplify button definition. --- .../example/jetsnack/ui/components/Button.kt | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) 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 97910aa870..2c42a1f9bb 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 @@ -21,18 +21,12 @@ package com.example.jetsnack.ui.components import android.content.res.Configuration.UI_MODE_NIGHT_YES import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.RowScope -import androidx.compose.foundation.layout.defaultMinSize 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.foundation.style.then -import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.ripple import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Alignment @@ -58,9 +52,11 @@ fun Button( } Row( modifier = modifier - .semantics(properties = { - role = Role.Button - }) + .semantics( + properties = { + role = Role.Button + }, + ) .clickable( enabled = enabled, onClick = onClick, @@ -69,7 +65,7 @@ fun Button( ) .styleable(styleState, JetsnackTheme.styles.buttonStyle, style), content = content, - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) } @@ -92,7 +88,8 @@ private fun ButtonPreview() { private fun RectangleButtonPreview() { JetsnackTheme { Button( - onClick = {}, style = { + onClick = {}, + style = { shape(RectangleShape) }, ) { From bf00df62c535cede46153564d4d1a7505e33e4b3 Mon Sep 17 00:00:00 2001 From: Rebecca Franks Date: Wed, 18 Mar 2026 17:43:56 +0000 Subject: [PATCH 11/11] Add minSize to the Button --- .../example/jetsnack/ui/components/Button.kt | 3 +- .../com/example/jetsnack/ui/theme/Styles.kt | 31 ++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) 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 2c42a1f9bb..ce8a9a0e55 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 @@ -27,6 +27,7 @@ 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.ripple import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Alignment @@ -61,7 +62,7 @@ fun Button( enabled = enabled, onClick = onClick, interactionSource = interactionSource, - indication = null, + indication = ripple(), ) .styleable(styleState, JetsnackTheme.styles.buttonStyle, style), content = content, 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 5fa46b83ea..04d3c190dc 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 @@ -14,7 +14,7 @@ * limitations under the License. */ -@file:OptIn(ExperimentalFoundationStyleApi::class) +@file:OptIn(ExperimentalFoundationStyleApi::class, ExperimentalMediaQueryApi::class) package com.example.jetsnack.ui.theme @@ -22,19 +22,47 @@ 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.StyleScope 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.LocalTextStyle import androidx.compose.runtime.Immutable +import androidx.compose.ui.ExperimentalMediaQueryApi +import androidx.compose.ui.LocalUiMediaScope +import androidx.compose.ui.UiMediaScope +import androidx.compose.ui.UiMediaScope.ViewingDistance 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.mediaQuery +import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp import com.example.jetsnack.ui.components.textStyleWithFontFamilyFix +fun StyleScope.adaptiveFontSize(fontSize: TextUnit) { + var scaleFactor = when (LocalUiMediaScope.currentValue.viewingDistance) { + ViewingDistance.Near -> 1f + ViewingDistance.Medium -> 1.72f + ViewingDistance.Far -> 1.5f + else -> 1f + } + scaleFactor = when (LocalUiMediaScope.currentValue.pointerPrecision) { + UiMediaScope.PointerPrecision.Coarse -> scaleFactor * 1f + UiMediaScope.PointerPrecision.Blunt -> scaleFactor * 0.66f + UiMediaScope.PointerPrecision.Fine -> scaleFactor * 1f + UiMediaScope.PointerPrecision.None -> scaleFactor + else -> { + scaleFactor + } + } + fontSize(fontSize * scaleFactor) +} + @Immutable data class Styles( val buttonStyle: Style = Style { @@ -43,6 +71,7 @@ data class Styles( contentColor(colors.textInteractive) contentPaddingVertical(8.dp) contentPaddingHorizontal(24.dp) + minSize(58.dp, 48.dp) textStyleWithFontFamilyFix(typography.labelLarge) disabled { animate {