Add Theme2 implementing Material 3
This commit is contained in:
parent
45d79a9a16
commit
237c753b02
21 changed files with 786 additions and 1 deletions
|
@ -790,7 +790,22 @@ style:
|
|||
Compose:
|
||||
CompositionLocalAllowlist:
|
||||
active: true
|
||||
allowedCompositionLocals: [LocalColors, LocalElevations, LocalImages, LocalShapes, LocalSizes, LocalSpacings, LocalActivity]
|
||||
allowedCompositionLocals: [
|
||||
LocalColors,
|
||||
LocalElevations,
|
||||
LocalImages,
|
||||
LocalShapes,
|
||||
LocalSizes,
|
||||
LocalSpacings,
|
||||
LocalActivity,
|
||||
LocalThemeColorScheme,
|
||||
LocalThemeElevations,
|
||||
LocalThemeImages,
|
||||
LocalThemeShapes,
|
||||
LocalThemeSizes,
|
||||
LocalThemeSpacings,
|
||||
LocalThemeTypography
|
||||
]
|
||||
ContentEmitterReturningValues:
|
||||
active: true
|
||||
ModifierComposable:
|
||||
|
|
15
core/ui/compose/theme2/common/README.md
Normal file
15
core/ui/compose/theme2/common/README.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
## Core - UI - Compose - Theme2 - Common
|
||||
|
||||
This provides the common `MainTheme` with dark/light variation support, a wrapper for the Compose Material 3 theme. It supports [CompositionLocal](https://developer.android.com/jetpack/compose/compositionlocal) changes to colors, typography, shapes and adds additionally elevations, sizes, spacings and images.
|
||||
|
||||
To change Material 3 related properties use `MainTheme` instead of `MaterialTheme`:
|
||||
|
||||
- `MainTheme.colors`: Material 3 color scheme
|
||||
- `MainTheme.elevations`: Elevation levels as [defined](https://m3.material.io/styles/elevation/overview) in Material3
|
||||
- `MainTheme.images`: Images used across the theme, e.g. logo
|
||||
- `MainTheme.shapes`: Shapes as [defined](https://m3.material.io/styles/shape/overview) in Material 3
|
||||
- `MainTheme.sizes`: Sizes (smaller, small, medium, large, larger, huge, huger)
|
||||
- `MainTheme.spacings`: Spacings (quarter, half, default, oneHalf, double, triple, quadruple) while default is 8 dp.
|
||||
- `MainTheme.typography`: Material 3 typography
|
||||
|
||||
To use the MainTheme, you need to provide a `ThemeConfig` with your desired colors, typography, shapes, elevations, sizes, spacings and images. The `ThemeConfig` is a data class that holds all the necessary information for the `MainTheme` to work.
|
17
core/ui/compose/theme2/common/build.gradle.kts
Normal file
17
core/ui/compose/theme2/common/build.gradle.kts
Normal file
|
@ -0,0 +1,17 @@
|
|||
plugins {
|
||||
id(ThunderbirdPlugins.Library.androidCompose)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "app.k9mail.core.ui.compose.theme2"
|
||||
resourcePrefix = "core_ui_theme2"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(projects.core.ui.compose.common)
|
||||
|
||||
implementation(libs.androidx.compose.material3)
|
||||
implementation(libs.androidx.compose.material.icons.extended)
|
||||
|
||||
implementation(libs.androidx.activity)
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
package app.k9mail.core.ui.compose.theme2
|
||||
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.material3.ColorScheme
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.ReadOnlyComposable
|
||||
|
||||
@Composable
|
||||
fun MainTheme(
|
||||
themeConfig: ThemeConfig,
|
||||
darkTheme: Boolean = isSystemInDarkTheme(),
|
||||
dynamicColor: Boolean = true,
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
val themeColorScheme = selectThemeColorScheme(
|
||||
themeConfig = themeConfig,
|
||||
darkTheme = darkTheme,
|
||||
dynamicColor = dynamicColor,
|
||||
)
|
||||
val themeImages = selectThemeImages(
|
||||
themeConfig = themeConfig,
|
||||
darkTheme = darkTheme,
|
||||
)
|
||||
|
||||
SystemBar(
|
||||
darkTheme = darkTheme,
|
||||
colorScheme = themeColorScheme,
|
||||
)
|
||||
|
||||
CompositionLocalProvider(
|
||||
LocalThemeColorScheme provides themeColorScheme,
|
||||
LocalThemeElevations provides themeConfig.elevations,
|
||||
LocalThemeImages provides themeImages,
|
||||
LocalThemeShapes provides themeConfig.shapes,
|
||||
LocalThemeSizes provides themeConfig.sizes,
|
||||
LocalThemeSpacings provides themeConfig.spacings,
|
||||
LocalThemeTypography provides themeConfig.typography,
|
||||
) {
|
||||
MaterialTheme(
|
||||
colorScheme = themeColorScheme.toMaterial3ColorScheme(),
|
||||
shapes = themeConfig.shapes.toMaterial3Shapes(),
|
||||
typography = themeConfig.typography.toMaterial3Typography(),
|
||||
content = content,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains functions to access the current theme values provided at the call site's position in
|
||||
* the hierarchy.
|
||||
*/
|
||||
object MainTheme {
|
||||
|
||||
/**
|
||||
* Retrieves the current [ColorScheme] at the call site's position in the hierarchy.
|
||||
*/
|
||||
val colors: ThemeColorScheme
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
get() = LocalThemeColorScheme.current
|
||||
|
||||
/**
|
||||
* Retrieves the current [ThemeElevations] at the call site's position in the hierarchy.
|
||||
*/
|
||||
val elevations: ThemeElevations
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
get() = LocalThemeElevations.current
|
||||
|
||||
/**
|
||||
* Retrieves the current [ThemeImages] at the call site's position in the hierarchy.
|
||||
*/
|
||||
val images: ThemeImages
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
get() = LocalThemeImages.current
|
||||
|
||||
/**
|
||||
* Retrieves the current [ThemeShapes] at the call site's position in the hierarchy.
|
||||
*/
|
||||
val shapes: ThemeShapes
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
get() = LocalThemeShapes.current
|
||||
|
||||
/**
|
||||
* Retrieves the current [ThemeSizes] at the call site's position in the hierarchy.
|
||||
*/
|
||||
val sizes: ThemeSizes
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
get() = LocalThemeSizes.current
|
||||
|
||||
/**
|
||||
* Retrieves the current [ThemeSpacings] at the call site's position in the hierarchy.
|
||||
*/
|
||||
val spacings: ThemeSpacings
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
get() = LocalThemeSpacings.current
|
||||
|
||||
/**
|
||||
* Retrieves the current [ThemeTypography] at the call site's position in the hierarchy.
|
||||
*/
|
||||
val typography: ThemeTypography
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
get() = LocalThemeTypography.current
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package app.k9mail.core.ui.compose.theme2
|
||||
|
||||
import androidx.compose.material3.ColorScheme
|
||||
import androidx.compose.material3.dynamicDarkColorScheme
|
||||
import androidx.compose.material3.dynamicLightColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
|
||||
@Composable
|
||||
internal fun selectThemeColorScheme(
|
||||
themeConfig: ThemeConfig,
|
||||
darkTheme: Boolean,
|
||||
dynamicColor: Boolean,
|
||||
): ThemeColorScheme {
|
||||
return when {
|
||||
dynamicColor && supportsDynamicColor() -> {
|
||||
val context = LocalContext.current
|
||||
val colorScheme = if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
|
||||
colorScheme.toThemeColorScheme()
|
||||
}
|
||||
|
||||
darkTheme -> themeConfig.colors.dark
|
||||
else -> themeConfig.colors.light
|
||||
}
|
||||
}
|
||||
|
||||
// Supported from Android 12+
|
||||
private fun supportsDynamicColor(): Boolean {
|
||||
return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S
|
||||
}
|
||||
|
||||
private fun ColorScheme.toThemeColorScheme() = ThemeColorScheme(
|
||||
primary = primary,
|
||||
onPrimary = onPrimary,
|
||||
primaryContainer = primaryContainer,
|
||||
onPrimaryContainer = onPrimaryContainer,
|
||||
|
||||
secondary = secondary,
|
||||
onSecondary = onSecondary,
|
||||
secondaryContainer = secondaryContainer,
|
||||
onSecondaryContainer = onSecondaryContainer,
|
||||
|
||||
tertiary = tertiary,
|
||||
onTertiary = onTertiary,
|
||||
tertiaryContainer = tertiaryContainer,
|
||||
onTertiaryContainer = onTertiaryContainer,
|
||||
|
||||
error = error,
|
||||
onError = onError,
|
||||
errorContainer = errorContainer,
|
||||
onErrorContainer = onErrorContainer,
|
||||
|
||||
surface = surface,
|
||||
onSurface = onSurface,
|
||||
onSurfaceVariant = onSurfaceVariant,
|
||||
surfaceContainerLowest = surfaceContainerLowest,
|
||||
surfaceContainerLow = surfaceContainerLow,
|
||||
surfaceContainer = surfaceContainer,
|
||||
surfaceContainerHigh = surfaceContainerHigh,
|
||||
surfaceContainerHighest = surfaceContainerHighest,
|
||||
|
||||
inverseSurface = inverseSurface,
|
||||
inverseOnSurface = inverseOnSurface,
|
||||
inversePrimary = inversePrimary,
|
||||
|
||||
outline = outline,
|
||||
outlineVariant = outlineVariant,
|
||||
|
||||
surfaceBright = surfaceBright,
|
||||
surfaceDim = surfaceDim,
|
||||
|
||||
scrim = scrim,
|
||||
)
|
|
@ -0,0 +1,12 @@
|
|||
package app.k9mail.core.ui.compose.theme2
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
|
||||
@Composable
|
||||
internal fun selectThemeImages(
|
||||
themeConfig: ThemeConfig,
|
||||
darkTheme: Boolean,
|
||||
) = when {
|
||||
darkTheme -> themeConfig.images.dark
|
||||
else -> themeConfig.images.light
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package app.k9mail.core.ui.compose.theme2
|
||||
|
||||
import android.app.Activity
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.SideEffect
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
import androidx.core.view.WindowCompat
|
||||
|
||||
@Composable
|
||||
fun SystemBar(
|
||||
darkTheme: Boolean,
|
||||
colorScheme: ThemeColorScheme,
|
||||
) {
|
||||
val view = LocalView.current
|
||||
if (!view.isInEditMode) {
|
||||
SideEffect {
|
||||
val window = (view.context as Activity).window
|
||||
window.statusBarColor = colorScheme.surfaceContainer.toArgb()
|
||||
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !darkTheme
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
package app.k9mail.core.ui.compose.theme2
|
||||
|
||||
import androidx.compose.material3.ColorScheme
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.staticCompositionLocalOf
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
/**
|
||||
* Theme color scheme following Material 3 color roles.
|
||||
*
|
||||
* This supports tone-based Surfaces introduced for Material 3.
|
||||
*
|
||||
* @see: https://m3.material.io/styles/color/roles
|
||||
* @see: https://material.io/blog/tone-based-surface-color-m3
|
||||
*/
|
||||
@Immutable
|
||||
data class ThemeColorScheme(
|
||||
val primary: Color,
|
||||
val onPrimary: Color,
|
||||
val primaryContainer: Color,
|
||||
val onPrimaryContainer: Color,
|
||||
|
||||
val secondary: Color,
|
||||
val onSecondary: Color,
|
||||
val secondaryContainer: Color,
|
||||
val onSecondaryContainer: Color,
|
||||
|
||||
val tertiary: Color,
|
||||
val onTertiary: Color,
|
||||
val tertiaryContainer: Color,
|
||||
val onTertiaryContainer: Color,
|
||||
|
||||
val error: Color,
|
||||
val onError: Color,
|
||||
val errorContainer: Color,
|
||||
val onErrorContainer: Color,
|
||||
|
||||
val surface: Color,
|
||||
val onSurface: Color,
|
||||
val onSurfaceVariant: Color,
|
||||
val surfaceContainerLowest: Color,
|
||||
val surfaceContainerLow: Color,
|
||||
val surfaceContainer: Color,
|
||||
val surfaceContainerHigh: Color,
|
||||
val surfaceContainerHighest: Color,
|
||||
|
||||
val inverseSurface: Color,
|
||||
val inverseOnSurface: Color,
|
||||
val inversePrimary: Color,
|
||||
|
||||
val outline: Color,
|
||||
val outlineVariant: Color,
|
||||
|
||||
val surfaceBright: Color,
|
||||
val surfaceDim: Color,
|
||||
|
||||
val scrim: Color,
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert a [ThemeColorScheme] to a Material 3 [ColorScheme].
|
||||
*
|
||||
* Note: background, onBackground are deprecated and mapped to surface, onSurface.
|
||||
*/
|
||||
internal fun ThemeColorScheme.toMaterial3ColorScheme(): ColorScheme {
|
||||
return ColorScheme(
|
||||
primary = primary,
|
||||
onPrimary = onPrimary,
|
||||
primaryContainer = primaryContainer,
|
||||
onPrimaryContainer = onPrimaryContainer,
|
||||
|
||||
secondary = secondary,
|
||||
onSecondary = onSecondary,
|
||||
secondaryContainer = secondaryContainer,
|
||||
onSecondaryContainer = onSecondaryContainer,
|
||||
|
||||
tertiary = tertiary,
|
||||
onTertiary = onTertiary,
|
||||
tertiaryContainer = tertiaryContainer,
|
||||
onTertiaryContainer = onTertiaryContainer,
|
||||
|
||||
error = error,
|
||||
onError = onError,
|
||||
errorContainer = errorContainer,
|
||||
onErrorContainer = onErrorContainer,
|
||||
|
||||
surface = surface,
|
||||
onSurface = onSurface,
|
||||
onSurfaceVariant = onSurfaceVariant,
|
||||
|
||||
surfaceContainerLowest = surfaceContainerLowest,
|
||||
surfaceContainerLow = surfaceContainerLow,
|
||||
surfaceContainer = surfaceContainer,
|
||||
surfaceContainerHigh = surfaceContainerHigh,
|
||||
surfaceContainerHighest = surfaceContainerHighest,
|
||||
|
||||
inverseSurface = inverseSurface,
|
||||
inverseOnSurface = inverseOnSurface,
|
||||
inversePrimary = inversePrimary,
|
||||
|
||||
outline = outline,
|
||||
outlineVariant = outlineVariant,
|
||||
|
||||
surfaceBright = surfaceBright,
|
||||
surfaceDim = surfaceDim,
|
||||
|
||||
scrim = scrim,
|
||||
|
||||
// Remapping properties due to changes in Material 3 tone based surface colors
|
||||
// https://material.io/blog/tone-based-surface-color-m3
|
||||
background = surface,
|
||||
onBackground = onSurface,
|
||||
surfaceVariant = surfaceContainerHighest,
|
||||
|
||||
surfaceTint = surfaceContainerHighest,
|
||||
)
|
||||
}
|
||||
|
||||
internal val LocalThemeColorScheme = staticCompositionLocalOf<ThemeColorScheme> {
|
||||
error("No ThemeColorScheme provided")
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package app.k9mail.core.ui.compose.theme2
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
|
||||
@Immutable
|
||||
data class ThemeConfig(
|
||||
val colors: ThemeColorSchemeVariants,
|
||||
val elevations: ThemeElevations,
|
||||
val images: ThemeImageVariants,
|
||||
val shapes: ThemeShapes,
|
||||
val sizes: ThemeSizes,
|
||||
val spacings: ThemeSpacings,
|
||||
val typography: ThemeTypography,
|
||||
)
|
||||
|
||||
@Immutable
|
||||
data class ThemeColorSchemeVariants(
|
||||
val dark: ThemeColorScheme,
|
||||
val light: ThemeColorScheme,
|
||||
)
|
||||
|
||||
@Immutable
|
||||
data class ThemeImageVariants(
|
||||
val dark: ThemeImages,
|
||||
val light: ThemeImages,
|
||||
)
|
|
@ -0,0 +1,29 @@
|
|||
package app.k9mail.core.ui.compose.theme2
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.staticCompositionLocalOf
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
/**
|
||||
* Elevation values used in the app.
|
||||
*
|
||||
* Material uses six levels of elevation, each with a corresponding dp value. These values are named for their
|
||||
* relative distance above the UI’s surface: 0, +1, +2, +3, +4, and +5. An element’s resting state can be on
|
||||
* levels 0 to +3, while levels +4 and +5 are reserved for user-interacted states such as hover and dragged.
|
||||
*
|
||||
* @see: https://m3.material.io/styles/elevation/tokens
|
||||
*/
|
||||
@Immutable
|
||||
data class ThemeElevations(
|
||||
val level0: Dp = 0.dp,
|
||||
val level1: Dp = 1.dp,
|
||||
val level2: Dp = 3.dp,
|
||||
val level3: Dp = 6.dp,
|
||||
val level4: Dp = 8.dp,
|
||||
val level5: Dp = 12.dp,
|
||||
)
|
||||
|
||||
internal val LocalThemeElevations = staticCompositionLocalOf<ThemeElevations> {
|
||||
error("No ThemeElevations provided")
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package app.k9mail.core.ui.compose.theme2
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.staticCompositionLocalOf
|
||||
|
||||
@Immutable
|
||||
data class ThemeImages(
|
||||
@DrawableRes val logo: Int,
|
||||
)
|
||||
|
||||
internal val LocalThemeImages = staticCompositionLocalOf<ThemeImages> {
|
||||
error("No ThemeImages provided")
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package app.k9mail.core.ui.compose.theme2
|
||||
|
||||
import androidx.compose.foundation.shape.CornerBasedShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Shapes
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.staticCompositionLocalOf
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
/**
|
||||
* The shapes used in the app.
|
||||
*
|
||||
* The shapes are defined as:
|
||||
*
|
||||
* - None
|
||||
* - ExtraSmall
|
||||
* - Small
|
||||
* - Medium
|
||||
* - Large
|
||||
* - ExtraLarge
|
||||
* - Full
|
||||
*
|
||||
* The default values are based on the Material Design guidelines.
|
||||
*
|
||||
* Shapes None and Full are omitted as None is a RectangleShape and Full is a CircleShape.
|
||||
*
|
||||
* @see: https://m3.material.io/styles/shape/overview
|
||||
*/
|
||||
@Immutable
|
||||
data class ThemeShapes(
|
||||
val extraSmall: CornerBasedShape = RoundedCornerShape(4.dp),
|
||||
val small: CornerBasedShape = RoundedCornerShape(8.dp),
|
||||
val medium: CornerBasedShape = RoundedCornerShape(12.dp),
|
||||
val large: CornerBasedShape = RoundedCornerShape(16.dp),
|
||||
val extraLarge: CornerBasedShape = RoundedCornerShape(28.dp),
|
||||
)
|
||||
|
||||
/**
|
||||
* Converts the [ThemeShapes] to Material 3 [Shapes].
|
||||
*/
|
||||
internal fun ThemeShapes.toMaterial3Shapes() = Shapes(
|
||||
extraSmall = extraSmall,
|
||||
small = small,
|
||||
medium = medium,
|
||||
large = large,
|
||||
extraLarge = extraLarge,
|
||||
)
|
||||
|
||||
internal val LocalThemeShapes = staticCompositionLocalOf<ThemeShapes> {
|
||||
error("No ThemeShapes provided")
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package app.k9mail.core.ui.compose.theme2
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.staticCompositionLocalOf
|
||||
import androidx.compose.ui.unit.Dp
|
||||
|
||||
@Immutable
|
||||
data class ThemeSizes(
|
||||
val smaller: Dp,
|
||||
val small: Dp,
|
||||
val medium: Dp,
|
||||
val large: Dp,
|
||||
val larger: Dp,
|
||||
val huge: Dp,
|
||||
val huger: Dp,
|
||||
|
||||
val icon: Dp,
|
||||
val largeIcon: Dp,
|
||||
|
||||
val topBarHeight: Dp,
|
||||
val bottomBarHeight: Dp,
|
||||
)
|
||||
|
||||
internal val LocalThemeSizes = staticCompositionLocalOf<ThemeSizes> {
|
||||
error("No ThemeSizes provided")
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package app.k9mail.core.ui.compose.theme2
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.staticCompositionLocalOf
|
||||
import androidx.compose.ui.unit.Dp
|
||||
|
||||
@Immutable
|
||||
data class ThemeSpacings(
|
||||
val zero: Dp,
|
||||
val quarter: Dp,
|
||||
val half: Dp,
|
||||
val default: Dp,
|
||||
val oneHalf: Dp,
|
||||
val double: Dp,
|
||||
val triple: Dp,
|
||||
val quadruple: Dp,
|
||||
)
|
||||
|
||||
internal val LocalThemeSpacings = staticCompositionLocalOf<ThemeSpacings> {
|
||||
error("No ThemeSpacings provided")
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package app.k9mail.core.ui.compose.theme2
|
||||
|
||||
import androidx.compose.material3.Typography
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.staticCompositionLocalOf
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
|
||||
@Immutable
|
||||
data class ThemeTypography(
|
||||
val displayLarge: TextStyle,
|
||||
val displayMedium: TextStyle,
|
||||
val displaySmall: TextStyle,
|
||||
val headlineLarge: TextStyle,
|
||||
val headlineMedium: TextStyle,
|
||||
val headlineSmall: TextStyle,
|
||||
val titleLarge: TextStyle,
|
||||
val titleMedium: TextStyle,
|
||||
val titleSmall: TextStyle,
|
||||
val bodyLarge: TextStyle,
|
||||
val bodyMedium: TextStyle,
|
||||
val bodySmall: TextStyle,
|
||||
val labelLarge: TextStyle,
|
||||
val labelMedium: TextStyle,
|
||||
val labelSmall: TextStyle,
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert [ThemeTypography] to Material 3 [Typography]
|
||||
*/
|
||||
internal fun ThemeTypography.toMaterial3Typography() = Typography(
|
||||
displayLarge = displayLarge,
|
||||
displayMedium = displayMedium,
|
||||
displaySmall = displaySmall,
|
||||
headlineLarge = headlineLarge,
|
||||
headlineMedium = headlineMedium,
|
||||
headlineSmall = headlineSmall,
|
||||
titleLarge = titleLarge,
|
||||
titleMedium = titleMedium,
|
||||
titleSmall = titleSmall,
|
||||
bodyLarge = bodyLarge,
|
||||
bodyMedium = bodyMedium,
|
||||
bodySmall = bodySmall,
|
||||
labelLarge = labelLarge,
|
||||
labelMedium = labelMedium,
|
||||
labelSmall = labelSmall,
|
||||
)
|
||||
|
||||
internal val LocalThemeTypography = staticCompositionLocalOf<ThemeTypography> {
|
||||
error("No ThemeTypography provided")
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package app.k9mail.core.ui.compose.theme2.default
|
||||
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.k9mail.core.ui.compose.theme2.ThemeElevations
|
||||
|
||||
/**
|
||||
* Default values for Material elevation taken from https://m3.material.io/styles/elevation/tokens
|
||||
*/
|
||||
val defaultThemeElevations = ThemeElevations(
|
||||
level0 = 0.dp,
|
||||
level1 = 1.dp,
|
||||
level2 = 3.dp,
|
||||
level3 = 6.dp,
|
||||
level4 = 8.dp,
|
||||
level5 = 12.dp,
|
||||
)
|
|
@ -0,0 +1,13 @@
|
|||
package app.k9mail.core.ui.compose.theme2.default
|
||||
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.k9mail.core.ui.compose.theme2.ThemeShapes
|
||||
|
||||
val defaultThemeShapes = ThemeShapes(
|
||||
extraSmall = RoundedCornerShape(4.dp),
|
||||
small = RoundedCornerShape(8.dp),
|
||||
medium = RoundedCornerShape(12.dp),
|
||||
large = RoundedCornerShape(16.dp),
|
||||
extraLarge = RoundedCornerShape(28.dp),
|
||||
)
|
|
@ -0,0 +1,20 @@
|
|||
package app.k9mail.core.ui.compose.theme2.default
|
||||
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.k9mail.core.ui.compose.theme2.ThemeSizes
|
||||
|
||||
val defaultThemeSizes = ThemeSizes(
|
||||
smaller = 8.dp,
|
||||
small = 16.dp,
|
||||
medium = 32.dp,
|
||||
large = 64.dp,
|
||||
larger = 128.dp,
|
||||
huge = 256.dp,
|
||||
huger = 384.dp,
|
||||
|
||||
icon = 24.dp,
|
||||
largeIcon = 32.dp,
|
||||
|
||||
topBarHeight = 56.dp,
|
||||
bottomBarHeight = 56.dp,
|
||||
)
|
|
@ -0,0 +1,15 @@
|
|||
package app.k9mail.core.ui.compose.theme2.default
|
||||
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.k9mail.core.ui.compose.theme2.ThemeSpacings
|
||||
|
||||
val defaultThemeSpacings = ThemeSpacings(
|
||||
zero = 0.dp,
|
||||
quarter = 2.dp,
|
||||
half = 4.dp,
|
||||
default = 8.dp,
|
||||
oneHalf = 12.dp,
|
||||
double = 16.dp,
|
||||
triple = 24.dp,
|
||||
quadruple = 32.dp,
|
||||
)
|
|
@ -0,0 +1,116 @@
|
|||
package app.k9mail.core.ui.compose.theme2.default
|
||||
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.sp
|
||||
import app.k9mail.core.ui.compose.theme2.ThemeTypography
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
val defaultTypography = ThemeTypography(
|
||||
displayLarge = TextStyle(
|
||||
fontFamily = FontFamily.SansSerif,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 57.sp,
|
||||
lineHeight = 64.sp,
|
||||
letterSpacing = (-0.2).sp,
|
||||
),
|
||||
displayMedium = TextStyle(
|
||||
fontFamily = FontFamily.SansSerif,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 45.sp,
|
||||
lineHeight = 52.sp,
|
||||
letterSpacing = 0.sp,
|
||||
),
|
||||
displaySmall = TextStyle(
|
||||
fontFamily = FontFamily.SansSerif,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 36.sp,
|
||||
lineHeight = 44.sp,
|
||||
letterSpacing = 0.sp,
|
||||
),
|
||||
headlineLarge = TextStyle(
|
||||
fontFamily = FontFamily.SansSerif,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 32.sp,
|
||||
lineHeight = 40.sp,
|
||||
letterSpacing = 0.sp,
|
||||
),
|
||||
headlineMedium = TextStyle(
|
||||
fontFamily = FontFamily.SansSerif,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 28.sp,
|
||||
lineHeight = 36.sp,
|
||||
letterSpacing = 0.sp,
|
||||
),
|
||||
headlineSmall = TextStyle(
|
||||
fontFamily = FontFamily.SansSerif,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 24.sp,
|
||||
lineHeight = 32.sp,
|
||||
letterSpacing = 0.sp,
|
||||
),
|
||||
titleLarge = TextStyle(
|
||||
fontFamily = FontFamily.SansSerif,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 22.sp,
|
||||
lineHeight = 28.sp,
|
||||
letterSpacing = 0.sp,
|
||||
),
|
||||
titleMedium = TextStyle(
|
||||
fontFamily = FontFamily.SansSerif,
|
||||
fontWeight = FontWeight.Medium,
|
||||
fontSize = 16.sp,
|
||||
lineHeight = 24.sp,
|
||||
letterSpacing = 0.2.sp,
|
||||
),
|
||||
titleSmall = TextStyle(
|
||||
fontFamily = FontFamily.SansSerif,
|
||||
fontWeight = FontWeight.Medium,
|
||||
fontSize = 14.sp,
|
||||
lineHeight = 20.sp,
|
||||
letterSpacing = 0.1.sp,
|
||||
),
|
||||
bodyLarge = TextStyle(
|
||||
fontFamily = FontFamily.SansSerif,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 16.sp,
|
||||
lineHeight = 24.sp,
|
||||
letterSpacing = 0.5.sp,
|
||||
),
|
||||
bodyMedium = TextStyle(
|
||||
fontFamily = FontFamily.SansSerif,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 14.sp,
|
||||
lineHeight = 20.sp,
|
||||
letterSpacing = 0.2.sp,
|
||||
),
|
||||
bodySmall = TextStyle(
|
||||
fontFamily = FontFamily.SansSerif,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 12.sp,
|
||||
lineHeight = 16.sp,
|
||||
letterSpacing = 0.4.sp,
|
||||
),
|
||||
labelLarge = TextStyle(
|
||||
fontFamily = FontFamily.SansSerif,
|
||||
fontWeight = FontWeight.Medium,
|
||||
fontSize = 14.sp,
|
||||
lineHeight = 20.sp,
|
||||
letterSpacing = 0.1.sp,
|
||||
),
|
||||
labelMedium = TextStyle(
|
||||
fontFamily = FontFamily.SansSerif,
|
||||
fontWeight = FontWeight.Medium,
|
||||
fontSize = 12.sp,
|
||||
lineHeight = 16.sp,
|
||||
letterSpacing = 0.5.sp,
|
||||
),
|
||||
labelSmall = TextStyle(
|
||||
fontFamily = FontFamily.SansSerif,
|
||||
fontWeight = FontWeight.Medium,
|
||||
fontSize = 11.sp,
|
||||
lineHeight = 16.sp,
|
||||
letterSpacing = 0.5.sp,
|
||||
),
|
||||
)
|
|
@ -76,6 +76,7 @@ include(
|
|||
":core:ui:compose:common",
|
||||
":core:ui:compose:designsystem",
|
||||
":core:ui:compose:theme",
|
||||
":core:ui:compose:theme2:common",
|
||||
":core:ui:compose:testing",
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in a new issue