diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts index 98f509a..7127661 100644 --- a/composeApp/build.gradle.kts +++ b/composeApp/build.gradle.kts @@ -16,7 +16,7 @@ kotlin { jvmTarget.set(JvmTarget.JVM_11) } } - + listOf( iosX64(), iosArm64(), @@ -27,9 +27,9 @@ kotlin { isStatic = true } } - + sourceSets { - + androidMain.dependencies { implementation(compose.preview) implementation(libs.androidx.activity.compose) @@ -38,6 +38,7 @@ kotlin { implementation(compose.runtime) implementation(compose.foundation) implementation(compose.material) + implementation(compose.material3) implementation(compose.ui) implementation(compose.components.resources) implementation(compose.components.uiToolingPreview) diff --git a/composeApp/src/androidMain/kotlin/io/anthonyberg/veganenumbers/MainActivity.kt b/composeApp/src/androidMain/kotlin/io/anthonyberg/veganenumbers/MainActivity.kt index 29189b4..527a5cc 100644 --- a/composeApp/src/androidMain/kotlin/io/anthonyberg/veganenumbers/MainActivity.kt +++ b/composeApp/src/androidMain/kotlin/io/anthonyberg/veganenumbers/MainActivity.kt @@ -6,13 +6,16 @@ import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.runtime.Composable import androidx.compose.ui.tooling.preview.Preview +import io.anthonyberg.veganenumbers.ui.theme.AppTheme class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { - App() + AppTheme { + App() + } } } } @@ -21,4 +24,4 @@ class MainActivity : ComponentActivity() { @Composable fun AppAndroidPreview() { App() -} \ No newline at end of file +} diff --git a/composeApp/src/androidMain/kotlin/io/anthonyberg/veganenumbers/ui/theme/Color.kt b/composeApp/src/androidMain/kotlin/io/anthonyberg/veganenumbers/ui/theme/Color.kt new file mode 100644 index 0000000..6eb3c1c --- /dev/null +++ b/composeApp/src/androidMain/kotlin/io/anthonyberg/veganenumbers/ui/theme/Color.kt @@ -0,0 +1,225 @@ +package io.anthonyberg.veganenumbers.ui.theme +import androidx.compose.ui.graphics.Color + +val primaryLight = Color(0xFF4C662B) +val onPrimaryLight = Color(0xFFFFFFFF) +val primaryContainerLight = Color(0xFFCDEDA3) +val onPrimaryContainerLight = Color(0xFF102000) +val secondaryLight = Color(0xFF586249) +val onSecondaryLight = Color(0xFFFFFFFF) +val secondaryContainerLight = Color(0xFFDCE7C8) +val onSecondaryContainerLight = Color(0xFF151E0B) +val tertiaryLight = Color(0xFF386663) +val onTertiaryLight = Color(0xFFFFFFFF) +val tertiaryContainerLight = Color(0xFFBCECE7) +val onTertiaryContainerLight = Color(0xFF00201E) +val errorLight = Color(0xFFBA1A1A) +val onErrorLight = Color(0xFFFFFFFF) +val errorContainerLight = Color(0xFFFFDAD6) +val onErrorContainerLight = Color(0xFF410002) +val backgroundLight = Color(0xFFF9FAEF) +val onBackgroundLight = Color(0xFF1A1C16) +val surfaceLight = Color(0xFFF9FAEF) +val onSurfaceLight = Color(0xFF1A1C16) +val surfaceVariantLight = Color(0xFFE1E4D5) +val onSurfaceVariantLight = Color(0xFF44483D) +val outlineLight = Color(0xFF75796C) +val outlineVariantLight = Color(0xFFC5C8BA) +val scrimLight = Color(0xFF000000) +val inverseSurfaceLight = Color(0xFF2F312A) +val inverseOnSurfaceLight = Color(0xFFF1F2E6) +val inversePrimaryLight = Color(0xFFB1D18A) +val surfaceDimLight = Color(0xFFDADBD0) +val surfaceBrightLight = Color(0xFFF9FAEF) +val surfaceContainerLowestLight = Color(0xFFFFFFFF) +val surfaceContainerLowLight = Color(0xFFF3F4E9) +val surfaceContainerLight = Color(0xFFEEEFE3) +val surfaceContainerHighLight = Color(0xFFE8E9DE) +val surfaceContainerHighestLight = Color(0xFFE2E3D8) + +val primaryLightMediumContrast = Color(0xFF314A12) +val onPrimaryLightMediumContrast = Color(0xFFFFFFFF) +val primaryContainerLightMediumContrast = Color(0xFF617D3F) +val onPrimaryContainerLightMediumContrast = Color(0xFFFFFFFF) +val secondaryLightMediumContrast = Color(0xFF3C462F) +val onSecondaryLightMediumContrast = Color(0xFFFFFFFF) +val secondaryContainerLightMediumContrast = Color(0xFF6E785E) +val onSecondaryContainerLightMediumContrast = Color(0xFFFFFFFF) +val tertiaryLightMediumContrast = Color(0xFF1A4A47) +val onTertiaryLightMediumContrast = Color(0xFFFFFFFF) +val tertiaryContainerLightMediumContrast = Color(0xFF4F7D79) +val onTertiaryContainerLightMediumContrast = Color(0xFFFFFFFF) +val errorLightMediumContrast = Color(0xFF8C0009) +val onErrorLightMediumContrast = Color(0xFFFFFFFF) +val errorContainerLightMediumContrast = Color(0xFFDA342E) +val onErrorContainerLightMediumContrast = Color(0xFFFFFFFF) +val backgroundLightMediumContrast = Color(0xFFF9FAEF) +val onBackgroundLightMediumContrast = Color(0xFF1A1C16) +val surfaceLightMediumContrast = Color(0xFFF9FAEF) +val onSurfaceLightMediumContrast = Color(0xFF1A1C16) +val surfaceVariantLightMediumContrast = Color(0xFFE1E4D5) +val onSurfaceVariantLightMediumContrast = Color(0xFF404439) +val outlineLightMediumContrast = Color(0xFF5D6155) +val outlineVariantLightMediumContrast = Color(0xFF787C70) +val scrimLightMediumContrast = Color(0xFF000000) +val inverseSurfaceLightMediumContrast = Color(0xFF2F312A) +val inverseOnSurfaceLightMediumContrast = Color(0xFFF1F2E6) +val inversePrimaryLightMediumContrast = Color(0xFFB1D18A) +val surfaceDimLightMediumContrast = Color(0xFFDADBD0) +val surfaceBrightLightMediumContrast = Color(0xFFF9FAEF) +val surfaceContainerLowestLightMediumContrast = Color(0xFFFFFFFF) +val surfaceContainerLowLightMediumContrast = Color(0xFFF3F4E9) +val surfaceContainerLightMediumContrast = Color(0xFFEEEFE3) +val surfaceContainerHighLightMediumContrast = Color(0xFFE8E9DE) +val surfaceContainerHighestLightMediumContrast = Color(0xFFE2E3D8) + +val primaryLightHighContrast = Color(0xFF142700) +val onPrimaryLightHighContrast = Color(0xFFFFFFFF) +val primaryContainerLightHighContrast = Color(0xFF314A12) +val onPrimaryContainerLightHighContrast = Color(0xFFFFFFFF) +val secondaryLightHighContrast = Color(0xFF1C2511) +val onSecondaryLightHighContrast = Color(0xFFFFFFFF) +val secondaryContainerLightHighContrast = Color(0xFF3C462F) +val onSecondaryContainerLightHighContrast = Color(0xFFFFFFFF) +val tertiaryLightHighContrast = Color(0xFF002725) +val onTertiaryLightHighContrast = Color(0xFFFFFFFF) +val tertiaryContainerLightHighContrast = Color(0xFF1A4A47) +val onTertiaryContainerLightHighContrast = Color(0xFFFFFFFF) +val errorLightHighContrast = Color(0xFF4E0002) +val onErrorLightHighContrast = Color(0xFFFFFFFF) +val errorContainerLightHighContrast = Color(0xFF8C0009) +val onErrorContainerLightHighContrast = Color(0xFFFFFFFF) +val backgroundLightHighContrast = Color(0xFFF9FAEF) +val onBackgroundLightHighContrast = Color(0xFF1A1C16) +val surfaceLightHighContrast = Color(0xFFF9FAEF) +val onSurfaceLightHighContrast = Color(0xFF000000) +val surfaceVariantLightHighContrast = Color(0xFFE1E4D5) +val onSurfaceVariantLightHighContrast = Color(0xFF21251C) +val outlineLightHighContrast = Color(0xFF404439) +val outlineVariantLightHighContrast = Color(0xFF404439) +val scrimLightHighContrast = Color(0xFF000000) +val inverseSurfaceLightHighContrast = Color(0xFF2F312A) +val inverseOnSurfaceLightHighContrast = Color(0xFFFFFFFF) +val inversePrimaryLightHighContrast = Color(0xFFD6F7AC) +val surfaceDimLightHighContrast = Color(0xFFDADBD0) +val surfaceBrightLightHighContrast = Color(0xFFF9FAEF) +val surfaceContainerLowestLightHighContrast = Color(0xFFFFFFFF) +val surfaceContainerLowLightHighContrast = Color(0xFFF3F4E9) +val surfaceContainerLightHighContrast = Color(0xFFEEEFE3) +val surfaceContainerHighLightHighContrast = Color(0xFFE8E9DE) +val surfaceContainerHighestLightHighContrast = Color(0xFFE2E3D8) + +val primaryDark = Color(0xFFB1D18A) +val onPrimaryDark = Color(0xFF1F3701) +val primaryContainerDark = Color(0xFF354E16) +val onPrimaryContainerDark = Color(0xFFCDEDA3) +val secondaryDark = Color(0xFFBFCBAD) +val onSecondaryDark = Color(0xFF2A331E) +val secondaryContainerDark = Color(0xFF404A33) +val onSecondaryContainerDark = Color(0xFFDCE7C8) +val tertiaryDark = Color(0xFFA0D0CB) +val onTertiaryDark = Color(0xFF003735) +val tertiaryContainerDark = Color(0xFF1F4E4B) +val onTertiaryContainerDark = Color(0xFFBCECE7) +val errorDark = Color(0xFFFFB4AB) +val onErrorDark = Color(0xFF690005) +val errorContainerDark = Color(0xFF93000A) +val onErrorContainerDark = Color(0xFFFFDAD6) +val backgroundDark = Color(0xFF12140E) +val onBackgroundDark = Color(0xFFE2E3D8) +val surfaceDark = Color(0xFF12140E) +val onSurfaceDark = Color(0xFFE2E3D8) +val surfaceVariantDark = Color(0xFF44483D) +val onSurfaceVariantDark = Color(0xFFC5C8BA) +val outlineDark = Color(0xFF8F9285) +val outlineVariantDark = Color(0xFF44483D) +val scrimDark = Color(0xFF000000) +val inverseSurfaceDark = Color(0xFFE2E3D8) +val inverseOnSurfaceDark = Color(0xFF2F312A) +val inversePrimaryDark = Color(0xFF4C662B) +val surfaceDimDark = Color(0xFF12140E) +val surfaceBrightDark = Color(0xFF383A32) +val surfaceContainerLowestDark = Color(0xFF0C0F09) +val surfaceContainerLowDark = Color(0xFF1A1C16) +val surfaceContainerDark = Color(0xFF1E201A) +val surfaceContainerHighDark = Color(0xFF282B24) +val surfaceContainerHighestDark = Color(0xFF33362E) + +val primaryDarkMediumContrast = Color(0xFFB5D58E) +val onPrimaryDarkMediumContrast = Color(0xFF0C1A00) +val primaryContainerDarkMediumContrast = Color(0xFF7D9A59) +val onPrimaryContainerDarkMediumContrast = Color(0xFF000000) +val secondaryDarkMediumContrast = Color(0xFFC4CFB1) +val onSecondaryDarkMediumContrast = Color(0xFF101907) +val secondaryContainerDarkMediumContrast = Color(0xFF8A9579) +val onSecondaryContainerDarkMediumContrast = Color(0xFF000000) +val tertiaryDarkMediumContrast = Color(0xFFA4D4D0) +val onTertiaryDarkMediumContrast = Color(0xFF001A19) +val tertiaryContainerDarkMediumContrast = Color(0xFF6B9995) +val onTertiaryContainerDarkMediumContrast = Color(0xFF000000) +val errorDarkMediumContrast = Color(0xFFFFBAB1) +val onErrorDarkMediumContrast = Color(0xFF370001) +val errorContainerDarkMediumContrast = Color(0xFFFF5449) +val onErrorContainerDarkMediumContrast = Color(0xFF000000) +val backgroundDarkMediumContrast = Color(0xFF12140E) +val onBackgroundDarkMediumContrast = Color(0xFFE2E3D8) +val surfaceDarkMediumContrast = Color(0xFF12140E) +val onSurfaceDarkMediumContrast = Color(0xFFFBFCF0) +val surfaceVariantDarkMediumContrast = Color(0xFF44483D) +val onSurfaceVariantDarkMediumContrast = Color(0xFFC9CCBE) +val outlineDarkMediumContrast = Color(0xFFA1A497) +val outlineVariantDarkMediumContrast = Color(0xFF818578) +val scrimDarkMediumContrast = Color(0xFF000000) +val inverseSurfaceDarkMediumContrast = Color(0xFFE2E3D8) +val inverseOnSurfaceDarkMediumContrast = Color(0xFF282B24) +val inversePrimaryDarkMediumContrast = Color(0xFF364F17) +val surfaceDimDarkMediumContrast = Color(0xFF12140E) +val surfaceBrightDarkMediumContrast = Color(0xFF383A32) +val surfaceContainerLowestDarkMediumContrast = Color(0xFF0C0F09) +val surfaceContainerLowDarkMediumContrast = Color(0xFF1A1C16) +val surfaceContainerDarkMediumContrast = Color(0xFF1E201A) +val surfaceContainerHighDarkMediumContrast = Color(0xFF282B24) +val surfaceContainerHighestDarkMediumContrast = Color(0xFF33362E) + +val primaryDarkHighContrast = Color(0xFFF4FFDF) +val onPrimaryDarkHighContrast = Color(0xFF000000) +val primaryContainerDarkHighContrast = Color(0xFFB5D58E) +val onPrimaryContainerDarkHighContrast = Color(0xFF000000) +val secondaryDarkHighContrast = Color(0xFFF4FFDF) +val onSecondaryDarkHighContrast = Color(0xFF000000) +val secondaryContainerDarkHighContrast = Color(0xFFC4CFB1) +val onSecondaryContainerDarkHighContrast = Color(0xFF000000) +val tertiaryDarkHighContrast = Color(0xFFEAFFFC) +val onTertiaryDarkHighContrast = Color(0xFF000000) +val tertiaryContainerDarkHighContrast = Color(0xFFA4D4D0) +val onTertiaryContainerDarkHighContrast = Color(0xFF000000) +val errorDarkHighContrast = Color(0xFFFFF9F9) +val onErrorDarkHighContrast = Color(0xFF000000) +val errorContainerDarkHighContrast = Color(0xFFFFBAB1) +val onErrorContainerDarkHighContrast = Color(0xFF000000) +val backgroundDarkHighContrast = Color(0xFF12140E) +val onBackgroundDarkHighContrast = Color(0xFFE2E3D8) +val surfaceDarkHighContrast = Color(0xFF12140E) +val onSurfaceDarkHighContrast = Color(0xFFFFFFFF) +val surfaceVariantDarkHighContrast = Color(0xFF44483D) +val onSurfaceVariantDarkHighContrast = Color(0xFFF9FCED) +val outlineDarkHighContrast = Color(0xFFC9CCBE) +val outlineVariantDarkHighContrast = Color(0xFFC9CCBE) +val scrimDarkHighContrast = Color(0xFF000000) +val inverseSurfaceDarkHighContrast = Color(0xFFE2E3D8) +val inverseOnSurfaceDarkHighContrast = Color(0xFF000000) +val inversePrimaryDarkHighContrast = Color(0xFF1A3000) +val surfaceDimDarkHighContrast = Color(0xFF12140E) +val surfaceBrightDarkHighContrast = Color(0xFF383A32) +val surfaceContainerLowestDarkHighContrast = Color(0xFF0C0F09) +val surfaceContainerLowDarkHighContrast = Color(0xFF1A1C16) +val surfaceContainerDarkHighContrast = Color(0xFF1E201A) +val surfaceContainerHighDarkHighContrast = Color(0xFF282B24) +val surfaceContainerHighestDarkHighContrast = Color(0xFF33362E) + + + + + + + diff --git a/composeApp/src/androidMain/kotlin/io/anthonyberg/veganenumbers/ui/theme/Theme.kt b/composeApp/src/androidMain/kotlin/io/anthonyberg/veganenumbers/ui/theme/Theme.kt new file mode 100644 index 0000000..0b176df --- /dev/null +++ b/composeApp/src/androidMain/kotlin/io/anthonyberg/veganenumbers/ui/theme/Theme.kt @@ -0,0 +1,290 @@ +package io.anthonyberg.veganenumbers.ui.theme +import android.app.Activity +import android.os.Build +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable +import androidx.compose.runtime.SideEffect +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalView +import androidx.core.view.WindowCompat + +private val lightScheme = lightColorScheme( + primary = primaryLight, + onPrimary = onPrimaryLight, + primaryContainer = primaryContainerLight, + onPrimaryContainer = onPrimaryContainerLight, + secondary = secondaryLight, + onSecondary = onSecondaryLight, + secondaryContainer = secondaryContainerLight, + onSecondaryContainer = onSecondaryContainerLight, + tertiary = tertiaryLight, + onTertiary = onTertiaryLight, + tertiaryContainer = tertiaryContainerLight, + onTertiaryContainer = onTertiaryContainerLight, + error = errorLight, + onError = onErrorLight, + errorContainer = errorContainerLight, + onErrorContainer = onErrorContainerLight, + background = backgroundLight, + onBackground = onBackgroundLight, + surface = surfaceLight, + onSurface = onSurfaceLight, + surfaceVariant = surfaceVariantLight, + onSurfaceVariant = onSurfaceVariantLight, + outline = outlineLight, + outlineVariant = outlineVariantLight, + scrim = scrimLight, + inverseSurface = inverseSurfaceLight, + inverseOnSurface = inverseOnSurfaceLight, + inversePrimary = inversePrimaryLight, + surfaceDim = surfaceDimLight, + surfaceBright = surfaceBrightLight, + surfaceContainerLowest = surfaceContainerLowestLight, + surfaceContainerLow = surfaceContainerLowLight, + surfaceContainer = surfaceContainerLight, + surfaceContainerHigh = surfaceContainerHighLight, + surfaceContainerHighest = surfaceContainerHighestLight, +) + +private val darkScheme = darkColorScheme( + primary = primaryDark, + onPrimary = onPrimaryDark, + primaryContainer = primaryContainerDark, + onPrimaryContainer = onPrimaryContainerDark, + secondary = secondaryDark, + onSecondary = onSecondaryDark, + secondaryContainer = secondaryContainerDark, + onSecondaryContainer = onSecondaryContainerDark, + tertiary = tertiaryDark, + onTertiary = onTertiaryDark, + tertiaryContainer = tertiaryContainerDark, + onTertiaryContainer = onTertiaryContainerDark, + error = errorDark, + onError = onErrorDark, + errorContainer = errorContainerDark, + onErrorContainer = onErrorContainerDark, + background = backgroundDark, + onBackground = onBackgroundDark, + surface = surfaceDark, + onSurface = onSurfaceDark, + surfaceVariant = surfaceVariantDark, + onSurfaceVariant = onSurfaceVariantDark, + outline = outlineDark, + outlineVariant = outlineVariantDark, + scrim = scrimDark, + inverseSurface = inverseSurfaceDark, + inverseOnSurface = inverseOnSurfaceDark, + inversePrimary = inversePrimaryDark, + surfaceDim = surfaceDimDark, + surfaceBright = surfaceBrightDark, + surfaceContainerLowest = surfaceContainerLowestDark, + surfaceContainerLow = surfaceContainerLowDark, + surfaceContainer = surfaceContainerDark, + surfaceContainerHigh = surfaceContainerHighDark, + surfaceContainerHighest = surfaceContainerHighestDark, +) + +private val mediumContrastLightColorScheme = lightColorScheme( + primary = primaryLightMediumContrast, + onPrimary = onPrimaryLightMediumContrast, + primaryContainer = primaryContainerLightMediumContrast, + onPrimaryContainer = onPrimaryContainerLightMediumContrast, + secondary = secondaryLightMediumContrast, + onSecondary = onSecondaryLightMediumContrast, + secondaryContainer = secondaryContainerLightMediumContrast, + onSecondaryContainer = onSecondaryContainerLightMediumContrast, + tertiary = tertiaryLightMediumContrast, + onTertiary = onTertiaryLightMediumContrast, + tertiaryContainer = tertiaryContainerLightMediumContrast, + onTertiaryContainer = onTertiaryContainerLightMediumContrast, + error = errorLightMediumContrast, + onError = onErrorLightMediumContrast, + errorContainer = errorContainerLightMediumContrast, + onErrorContainer = onErrorContainerLightMediumContrast, + background = backgroundLightMediumContrast, + onBackground = onBackgroundLightMediumContrast, + surface = surfaceLightMediumContrast, + onSurface = onSurfaceLightMediumContrast, + surfaceVariant = surfaceVariantLightMediumContrast, + onSurfaceVariant = onSurfaceVariantLightMediumContrast, + outline = outlineLightMediumContrast, + outlineVariant = outlineVariantLightMediumContrast, + scrim = scrimLightMediumContrast, + inverseSurface = inverseSurfaceLightMediumContrast, + inverseOnSurface = inverseOnSurfaceLightMediumContrast, + inversePrimary = inversePrimaryLightMediumContrast, + surfaceDim = surfaceDimLightMediumContrast, + surfaceBright = surfaceBrightLightMediumContrast, + surfaceContainerLowest = surfaceContainerLowestLightMediumContrast, + surfaceContainerLow = surfaceContainerLowLightMediumContrast, + surfaceContainer = surfaceContainerLightMediumContrast, + surfaceContainerHigh = surfaceContainerHighLightMediumContrast, + surfaceContainerHighest = surfaceContainerHighestLightMediumContrast, +) + +private val highContrastLightColorScheme = lightColorScheme( + primary = primaryLightHighContrast, + onPrimary = onPrimaryLightHighContrast, + primaryContainer = primaryContainerLightHighContrast, + onPrimaryContainer = onPrimaryContainerLightHighContrast, + secondary = secondaryLightHighContrast, + onSecondary = onSecondaryLightHighContrast, + secondaryContainer = secondaryContainerLightHighContrast, + onSecondaryContainer = onSecondaryContainerLightHighContrast, + tertiary = tertiaryLightHighContrast, + onTertiary = onTertiaryLightHighContrast, + tertiaryContainer = tertiaryContainerLightHighContrast, + onTertiaryContainer = onTertiaryContainerLightHighContrast, + error = errorLightHighContrast, + onError = onErrorLightHighContrast, + errorContainer = errorContainerLightHighContrast, + onErrorContainer = onErrorContainerLightHighContrast, + background = backgroundLightHighContrast, + onBackground = onBackgroundLightHighContrast, + surface = surfaceLightHighContrast, + onSurface = onSurfaceLightHighContrast, + surfaceVariant = surfaceVariantLightHighContrast, + onSurfaceVariant = onSurfaceVariantLightHighContrast, + outline = outlineLightHighContrast, + outlineVariant = outlineVariantLightHighContrast, + scrim = scrimLightHighContrast, + inverseSurface = inverseSurfaceLightHighContrast, + inverseOnSurface = inverseOnSurfaceLightHighContrast, + inversePrimary = inversePrimaryLightHighContrast, + surfaceDim = surfaceDimLightHighContrast, + surfaceBright = surfaceBrightLightHighContrast, + surfaceContainerLowest = surfaceContainerLowestLightHighContrast, + surfaceContainerLow = surfaceContainerLowLightHighContrast, + surfaceContainer = surfaceContainerLightHighContrast, + surfaceContainerHigh = surfaceContainerHighLightHighContrast, + surfaceContainerHighest = surfaceContainerHighestLightHighContrast, +) + +private val mediumContrastDarkColorScheme = darkColorScheme( + primary = primaryDarkMediumContrast, + onPrimary = onPrimaryDarkMediumContrast, + primaryContainer = primaryContainerDarkMediumContrast, + onPrimaryContainer = onPrimaryContainerDarkMediumContrast, + secondary = secondaryDarkMediumContrast, + onSecondary = onSecondaryDarkMediumContrast, + secondaryContainer = secondaryContainerDarkMediumContrast, + onSecondaryContainer = onSecondaryContainerDarkMediumContrast, + tertiary = tertiaryDarkMediumContrast, + onTertiary = onTertiaryDarkMediumContrast, + tertiaryContainer = tertiaryContainerDarkMediumContrast, + onTertiaryContainer = onTertiaryContainerDarkMediumContrast, + error = errorDarkMediumContrast, + onError = onErrorDarkMediumContrast, + errorContainer = errorContainerDarkMediumContrast, + onErrorContainer = onErrorContainerDarkMediumContrast, + background = backgroundDarkMediumContrast, + onBackground = onBackgroundDarkMediumContrast, + surface = surfaceDarkMediumContrast, + onSurface = onSurfaceDarkMediumContrast, + surfaceVariant = surfaceVariantDarkMediumContrast, + onSurfaceVariant = onSurfaceVariantDarkMediumContrast, + outline = outlineDarkMediumContrast, + outlineVariant = outlineVariantDarkMediumContrast, + scrim = scrimDarkMediumContrast, + inverseSurface = inverseSurfaceDarkMediumContrast, + inverseOnSurface = inverseOnSurfaceDarkMediumContrast, + inversePrimary = inversePrimaryDarkMediumContrast, + surfaceDim = surfaceDimDarkMediumContrast, + surfaceBright = surfaceBrightDarkMediumContrast, + surfaceContainerLowest = surfaceContainerLowestDarkMediumContrast, + surfaceContainerLow = surfaceContainerLowDarkMediumContrast, + surfaceContainer = surfaceContainerDarkMediumContrast, + surfaceContainerHigh = surfaceContainerHighDarkMediumContrast, + surfaceContainerHighest = surfaceContainerHighestDarkMediumContrast, +) + +private val highContrastDarkColorScheme = darkColorScheme( + primary = primaryDarkHighContrast, + onPrimary = onPrimaryDarkHighContrast, + primaryContainer = primaryContainerDarkHighContrast, + onPrimaryContainer = onPrimaryContainerDarkHighContrast, + secondary = secondaryDarkHighContrast, + onSecondary = onSecondaryDarkHighContrast, + secondaryContainer = secondaryContainerDarkHighContrast, + onSecondaryContainer = onSecondaryContainerDarkHighContrast, + tertiary = tertiaryDarkHighContrast, + onTertiary = onTertiaryDarkHighContrast, + tertiaryContainer = tertiaryContainerDarkHighContrast, + onTertiaryContainer = onTertiaryContainerDarkHighContrast, + error = errorDarkHighContrast, + onError = onErrorDarkHighContrast, + errorContainer = errorContainerDarkHighContrast, + onErrorContainer = onErrorContainerDarkHighContrast, + background = backgroundDarkHighContrast, + onBackground = onBackgroundDarkHighContrast, + surface = surfaceDarkHighContrast, + onSurface = onSurfaceDarkHighContrast, + surfaceVariant = surfaceVariantDarkHighContrast, + onSurfaceVariant = onSurfaceVariantDarkHighContrast, + outline = outlineDarkHighContrast, + outlineVariant = outlineVariantDarkHighContrast, + scrim = scrimDarkHighContrast, + inverseSurface = inverseSurfaceDarkHighContrast, + inverseOnSurface = inverseOnSurfaceDarkHighContrast, + inversePrimary = inversePrimaryDarkHighContrast, + surfaceDim = surfaceDimDarkHighContrast, + surfaceBright = surfaceBrightDarkHighContrast, + surfaceContainerLowest = surfaceContainerLowestDarkHighContrast, + surfaceContainerLow = surfaceContainerLowDarkHighContrast, + surfaceContainer = surfaceContainerDarkHighContrast, + surfaceContainerHigh = surfaceContainerHighDarkHighContrast, + surfaceContainerHighest = surfaceContainerHighestDarkHighContrast, +) + +@Immutable +data class ColorFamily( + val color: Color, + val onColor: Color, + val colorContainer: Color, + val onColorContainer: Color +) + +val unspecified_scheme = ColorFamily( + Color.Unspecified, Color.Unspecified, Color.Unspecified, Color.Unspecified +) + +@Composable +fun AppTheme( + darkTheme: Boolean = isSystemInDarkTheme(), + // Dynamic color is available on Android 12+ + dynamicColor: Boolean = true, + content: @Composable() () -> Unit +) { + val colorScheme = when { + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + val context = LocalContext.current + if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) + } + + darkTheme -> darkScheme + else -> lightScheme + } + val view = LocalView.current + if (!view.isInEditMode) { + SideEffect { + val window = (view.context as Activity).window + window.statusBarColor = colorScheme.primary.toArgb() + WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme + } + } + + MaterialTheme( + colorScheme = colorScheme, + typography = AppTypography, + content = content + ) +} + diff --git a/composeApp/src/androidMain/kotlin/io/anthonyberg/veganenumbers/ui/theme/Type.kt b/composeApp/src/androidMain/kotlin/io/anthonyberg/veganenumbers/ui/theme/Type.kt new file mode 100644 index 0000000..8901f0e --- /dev/null +++ b/composeApp/src/androidMain/kotlin/io/anthonyberg/veganenumbers/ui/theme/Type.kt @@ -0,0 +1,5 @@ +package io.anthonyberg.veganenumbers.ui.theme + +import androidx.compose.material3.Typography + +val AppTypography = Typography() diff --git a/composeApp/src/commonMain/kotlin/App.kt b/composeApp/src/commonMain/kotlin/App.kt index 1c092ee..c1765be 100644 --- a/composeApp/src/commonMain/kotlin/App.kt +++ b/composeApp/src/commonMain/kotlin/App.kt @@ -2,12 +2,16 @@ import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.material.Button -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text +import androidx.compose.foundation.layout.padding +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Menu +import androidx.compose.material.icons.filled.Search +import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.input.nestedscroll.nestedScroll +import androidx.compose.ui.text.style.TextOverflow import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.ui.tooling.preview.Preview @@ -18,18 +22,80 @@ import veganenumbers.composeapp.generated.resources.compose_multiplatform @Preview fun App() { MaterialTheme { - var showContent by remember { mutableStateOf(false) } - Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { - Button(onClick = { showContent = !showContent }) { - Text("Click me!") + AppScaffold() + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun AppScaffold() { + val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState()) + + Scaffold( + modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), + topBar = { + TopBar(scrollBehavior) + } + ) { innerPadding -> + Column( + modifier = Modifier.padding(innerPadding) + ) { + TempContent() + } + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun TopBar( + scrollBehavior: TopAppBarScrollBehavior +) { + + CenterAlignedTopAppBar( + title = { + Text( + text = "Vegan E Numbers", + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + }, + navigationIcon = { + IconButton( + onClick = {/* TODO Implement Navigation Drawer */} + ) { + Icon( + imageVector = Icons.Filled.Menu, + contentDescription = "Navigation Menu", + ) } - AnimatedVisibility(showContent) { - val greeting = remember { Greeting().greet() } - Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { - Image(painterResource(Res.drawable.compose_multiplatform), null) - Text("Compose: $greeting") - } + }, + actions = { + IconButton( + onClick = {/* TODO Implement Search Function */} + ) { + Icon( + imageVector = Icons.Filled.Search, + contentDescription = "Search for E Number", + ) + } + }, + scrollBehavior = scrollBehavior, + ) +} + +@Composable +fun TempContent() { + var showContent by remember { mutableStateOf(false) } + Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { + Button(onClick = { showContent = !showContent }) { + Text("Click me!") + } + AnimatedVisibility(showContent) { + val greeting = remember { Greeting().greet() } + Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { + Image(painterResource(Res.drawable.compose_multiplatform), null) + Text("Compose: $greeting") } } } -} \ No newline at end of file +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 20905d0..7b83ab0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,15 +4,17 @@ android-compileSdk = "34" android-minSdk = "24" android-targetSdk = "34" androidx-activityCompose = "1.9.0" -androidx-appcompat = "1.6.1" +androidx-appcompat = "1.7.0" androidx-constraintlayout = "2.1.4" androidx-core-ktx = "1.13.1" androidx-espresso-core = "3.5.1" androidx-material = "1.12.0" +androidx-material3 = "1.6.11" androidx-test-junit = "1.1.5" compose-plugin = "1.6.10" junit = "4.13.2" kotlin = "2.0.0" +material3Android = "1.2.1" [libraries] kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } @@ -23,12 +25,14 @@ androidx-test-junit = { group = "androidx.test.ext", name = "junit", version.ref androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "androidx-espresso-core" } androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "androidx-appcompat" } androidx-material = { group = "com.google.android.material", name = "material", version.ref = "androidx-material" } +androidx-material3 = { group = "org.jetbrains.compose.material3", name = "material3", version.ref = "androidx-material3" } androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "androidx-constraintlayout" } androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activityCompose" } +androidx-material3-android = { group = "androidx.compose.material3", name = "material3-android", version.ref = "material3Android" } [plugins] androidApplication = { id = "com.android.application", version.ref = "agp" } androidLibrary = { id = "com.android.library", version.ref = "agp" } jetbrainsCompose = { id = "org.jetbrains.compose", version.ref = "compose-plugin" } compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } -kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } \ No newline at end of file +kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }