├── .github └── FUNDING.yml ├── .gitignore ├── KColor ├── build.gradle.kts └── src │ └── main │ ├── kotlin │ └── com │ │ └── mohitsoni │ │ └── kcolor │ │ ├── KColorExtension.kt │ │ └── KColorPlugin.kt │ └── resources │ └── META-INF │ └── services │ └── com.google.devtools.ksp.processing.SymbolProcessorProvider ├── LICENSE ├── README.md ├── androidApp ├── build.gradle.kts └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── mohitsoni │ │ └── kcolorsample │ │ └── android │ │ ├── MainActivity.kt │ │ └── MyApplicationTheme.kt │ └── res │ └── values │ └── styles.xml ├── build.gradle.kts ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── iosApp ├── iosApp.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── iosApp │ ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json │ ├── Colors.xcassets │ ├── Contents.json │ ├── primary.colorset │ │ └── Contents.json │ ├── primaryFour.colorset │ │ └── Contents.json │ ├── primaryThree.colorset │ │ └── Contents.json │ └── primaryTwo.colorset │ │ └── Contents.json │ ├── ContentView.swift │ ├── Info.plist │ ├── Preview Content │ └── Preview Assets.xcassets │ │ └── Contents.json │ └── iOSApp.swift ├── settings.gradle.kts └── shared ├── build.gradle.kts └── src ├── androidMain └── kotlin │ └── com │ └── mohitsoni │ └── kcolorsample │ └── Platform.android.kt ├── commonMain ├── composeResources │ └── values │ │ └── strings.xml ├── kotlin │ └── com │ │ └── mohitsoni │ │ └── kcolorsample │ │ ├── Greeting.kt │ │ └── Platform.kt └── resources │ └── colors │ └── colors.xml └── iosMain └── kotlin └── com └── mohitsoni └── kcolorsample └── Platform.ios.kt /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: mohitsoni # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 12 | polar: # Replace with a single Polar username 13 | buy_me_a_coffee: # Replace with a single Buy Me a Coffee username 14 | thanks_dev: # Replace with a single thanks.dev username 15 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | .idea 4 | .DS_Store 5 | build 6 | captures 7 | .externalNativeBuild 8 | .cxx 9 | local.properties 10 | xcuserdata 11 | /gradle.properties 12 | .kotlin -------------------------------------------------------------------------------- /KColor/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.vanniktech.maven.publish.SonatypeHost 2 | 3 | plugins { 4 | id("com.vanniktech.maven.publish") version "0.29.0" 5 | `kotlin-dsl` 6 | `java-gradle-plugin` 7 | } 8 | 9 | gradlePlugin { 10 | plugins { 11 | create("kColorPlugin") { 12 | id = "io.github.mohitsoni48.KColor" 13 | implementationClass = "com.mohitsoni.kcolor.KColorPlugin" 14 | } 15 | } 16 | } 17 | 18 | mavenPublishing { 19 | // Define coordinates for the published artifact 20 | 21 | coordinates( 22 | groupId = "io.github.mohitsoni48", 23 | artifactId = "KColor", 24 | version = "1.0.3" 25 | ) 26 | 27 | // Configure POM metadata for the published artifact 28 | pom { 29 | name.set("KColor") 30 | description.set("A library to share color between commonMain and ios swift") 31 | inceptionYear.set("2024") 32 | url.set("https://github.com/mohitsoni48/KColor") 33 | 34 | licenses { 35 | license { 36 | name.set("MIT") 37 | url.set("https://opensource.org/licenses/MIT") 38 | } 39 | } 40 | 41 | // Specify developers information 42 | developers { 43 | developer { 44 | id.set("mohitsoni48") 45 | name.set("Mohit Soni") 46 | email.set("mohitsoni48@gmail.com") 47 | } 48 | } 49 | 50 | // Specify SCM information 51 | scm { 52 | url.set("https://github.com/mohitsoni48/KColor") 53 | developerConnection.set("scm:git:ssh://github.com/mohitsoni48/KColor.git") 54 | connection.set("scm:git:git://github.com/mohitsoni48/KColor.git") 55 | } 56 | } 57 | 58 | // Configure publishing to Maven Central 59 | publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL) 60 | 61 | // Enable GPG signing for all publications 62 | signAllPublications() 63 | } -------------------------------------------------------------------------------- /KColor/src/main/kotlin/com/mohitsoni/kcolor/KColorExtension.kt: -------------------------------------------------------------------------------- 1 | package com.mohitsoni.kcolor 2 | 3 | open class KColorExtension { 4 | var packageName: String? = null 5 | var sharedModule: String? = null 6 | var iosAppName: String? = null 7 | } 8 | -------------------------------------------------------------------------------- /KColor/src/main/kotlin/com/mohitsoni/kcolor/KColorPlugin.kt: -------------------------------------------------------------------------------- 1 | package com.mohitsoni.kcolor 2 | 3 | import org.gradle.api.Plugin 4 | import org.gradle.api.Project 5 | import org.gradle.api.tasks.Input 6 | import org.gradle.api.tasks.TaskAction 7 | import java.io.File 8 | import javax.xml.parsers.DocumentBuilderFactory 9 | 10 | class KColorPlugin : Plugin { 11 | 12 | override fun apply(project: Project) { 13 | val extension = project.extensions.create("kColor", KColorExtension::class.java) 14 | 15 | project.afterEvaluate { 16 | project.tasks.register("generateColors", GenerateColorsTask::class.java).configure { 17 | packageName.set(extension.packageName ?: throw NotImplementedError("KColor plugin not set")) 18 | sharedModule.set(extension.sharedModule ?: "shared") 19 | iosAppName.set(extension.iosAppName ?: "iosApp") 20 | projectRoot.set(project.rootDir.absolutePath.split("/$sharedModule").first()) 21 | } 22 | 23 | val generateColors = project.tasks.findByName("generateColors") 24 | if (generateColors != null) { 25 | project.tasks.named("preBuild").configure { 26 | dependsOn(generateColors) 27 | } 28 | project.tasks.named("embedAndSignAppleFrameworkForXcode").configure { 29 | dependsOn(generateColors) 30 | } 31 | } else { 32 | project.logger.warn("generateColors task not found.") 33 | } 34 | } 35 | } 36 | } 37 | 38 | abstract class GenerateColorsTask : org.gradle.api.DefaultTask() { 39 | 40 | @Input 41 | val packageName = project.objects.property(String::class.java) 42 | 43 | @Input 44 | val sharedModule = project.objects.property(String::class.java) 45 | 46 | @Input 47 | val iosAppName = project.objects.property(String::class.java) 48 | 49 | @Input 50 | val projectRoot = project.objects.property(String::class.java) 51 | 52 | 53 | @TaskAction 54 | fun generate() { 55 | println("Color Generation Started") 56 | 57 | // Retrieve values 58 | val pkgName = packageName.get() 59 | val sharedMod = sharedModule.get() 60 | val iosApp = iosAppName.get() 61 | 62 | // Construct the path to colors.xml 63 | val xmlFilePath = "${projectRoot.get()}/$sharedMod/src/commonMain/resources/colors/colors.xml" 64 | val xmlFile = File(xmlFilePath) 65 | 66 | // Check if colors.xml exists 67 | if (!xmlFile.exists()) { 68 | throw IllegalStateException("colors.xml not found at $xmlFilePath") 69 | } 70 | 71 | // Parse the colors.xml file 72 | val docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder() 73 | val doc = docBuilder.parse(xmlFile) 74 | val resources = doc.documentElement 75 | val colorNodes = resources.getElementsByTagName("color") 76 | 77 | // Generate the Android and iOS color files 78 | generateAndroidColors(pkgName, colorNodes, projectRoot.get(), sharedMod) 79 | generateIosColors(pkgName, iosApp, colorNodes, projectRoot.get(), sharedMod) 80 | } 81 | 82 | private fun generateAndroidColors( 83 | packageName: String, 84 | colorNodes: org.w3c.dom.NodeList, 85 | projectRoot: String, 86 | sharedModule: String 87 | ) { 88 | val colorDeclarations = mutableListOf() 89 | val colorIds = mutableListOf() 90 | 91 | for (i in 0 until colorNodes.length) { 92 | val node = colorNodes.item(i) 93 | val name = node.attributes.getNamedItem("name").nodeValue 94 | val value = node.textContent.trim().replace("#", "").let { hex -> 95 | when (hex.length) { 96 | 3 -> "0xFF" + hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2] 97 | 6 -> "0xFF$hex" 98 | 8 -> "0x$hex" 99 | else -> throw IllegalArgumentException("Invalid color format") 100 | } 101 | } 102 | 103 | val variableName = name.toCamelCase() 104 | 105 | colorDeclarations.add("val $variableName = Color($value)") 106 | colorIds.add("data object ${variableName}: KColorRes(\"${node.textContent.trim()}\")") 107 | } 108 | 109 | val generatedContent = """ 110 | |package $packageName 111 | | 112 | |import androidx.compose.ui.graphics.Color 113 | | 114 | |object KColor { 115 | | ${colorDeclarations.joinToString("\n ")} 116 | |} 117 | |""".trimMargin() 118 | 119 | val outputFilePath = "$projectRoot/$sharedModule/build/generated/colors/KColor.kt" 120 | val outputFile = File(outputFilePath) 121 | outputFile.parentFile.mkdirs() 122 | outputFile.writeText(generatedContent) 123 | 124 | val generatedIds = """ 125 | |package $packageName 126 | | 127 | |sealed class KColorRes(val hex: String) { 128 | | ${colorIds.joinToString("\n ")} 129 | |} 130 | |""".trimMargin() 131 | 132 | val idFilePath = "$projectRoot/$sharedModule/build/generated/colors/KColorRes.kt" 133 | val idFile = File(idFilePath) 134 | idFile.parentFile.mkdirs() 135 | idFile.writeText(generatedIds) 136 | 137 | val androidGetColor = """ 138 | |package $packageName 139 | | 140 | |import androidx.compose.ui.graphics.Color 141 | |fun getColor(kColorRes: KColorRes): Color { 142 | | return Color(android.graphics.Color.parseColor(kColorRes.hex)) 143 | |} 144 | |""".trimMargin() 145 | val androidFilePath = "$projectRoot/$sharedModule/build/generated/android/kcolors/GetColor.kt" 146 | val androidFile = File(androidFilePath) 147 | androidFile.parentFile.mkdirs() 148 | androidFile.writeText(androidGetColor) 149 | } 150 | 151 | private fun generateIosColors( 152 | packageName: String, 153 | iosApp: String, 154 | colorNodes: org.w3c.dom.NodeList, 155 | projectRoot: String, 156 | sharedModule: String 157 | ) { 158 | val outputAsset = "$projectRoot/$iosApp/$iosApp/Colors.xcassets" 159 | 160 | for (i in 0 until colorNodes.length) { 161 | val node = colorNodes.item(i) 162 | val name = node.attributes.getNamedItem("name").nodeValue 163 | val colorFolder = name.toCamelCase() + ".colorset/Contents.json" 164 | val outputFile = File("$outputAsset/$colorFolder") 165 | outputFile.parentFile.mkdirs() 166 | outputFile.writeText(hexToJson(node.textContent.trim())) 167 | } 168 | 169 | val iosGetColor = """ 170 | |package $packageName 171 | | 172 | |import platform.UIKit.UIColor 173 | | 174 | |fun getColor(kColorRes: KColorRes): UIColor { 175 | | val normalizedHex = when { 176 | | kColorRes.hex.length == 7 && kColorRes.hex[0] == '#' -> kColorRes.hex 177 | | kColorRes.hex.length == 9 && kColorRes.hex[0] == '#' -> kColorRes.hex 178 | | kColorRes.hex.length == 4 && kColorRes.hex[0] == '#' -> { 179 | | "#@{kColorRes.hex[1]}@{kColorRes.hex[1]}@{kColorRes.hex[2]}@{kColorRes.hex[2]}@{kColorRes.hex[3]}@{kColorRes.hex[3]}" 180 | | } 181 | | kColorRes.hex.length == 5 && kColorRes.hex[0] == '#' -> { 182 | | "#@{kColorRes.hex[1]}@{kColorRes.hex[1]}@{kColorRes.hex[2]}@{kColorRes.hex[2]}@{kColorRes.hex[3]}@{kColorRes.hex[3]}" 183 | | } 184 | | else -> "#FFFFFF" 185 | | } 186 | | 187 | | val alpha = if (normalizedHex.length == 9) { 188 | | normalizedHex.substring(1, 3).toInt(16) / 255.0 189 | | } else { 190 | | 1.0 191 | | } 192 | | val red = normalizedHex.substring(normalizedHex.length - 6, normalizedHex.length - 4).toInt(16) / 255.0 193 | | val green = normalizedHex.substring(normalizedHex.length - 4, normalizedHex.length - 2).toInt(16) / 255.0 194 | | val blue = normalizedHex.substring(normalizedHex.length - 2).toInt(16) / 255.0 195 | | 196 | | return UIColor(red = red, green = green, blue = blue, alpha = alpha) 197 | |} 198 | """.trimMargin().replace("@", "$") 199 | val iosFilePath = "$projectRoot/$sharedModule/build/generated/ios/kcolors/GetColor.kt" 200 | val iosFile = File(iosFilePath) 201 | iosFile.parentFile.mkdirs() 202 | iosFile.writeText(iosGetColor) 203 | 204 | } 205 | 206 | private fun hexToJson(hex: String): String { 207 | val cleanedHex = hex.removePrefix("#") 208 | val alpha = if (cleanedHex.length == 8) cleanedHex.substring(0, 2) else "FF" 209 | val red = cleanedHex.substring(cleanedHex.length - 6, cleanedHex.length - 4) 210 | val green = cleanedHex.substring(cleanedHex.length - 4, cleanedHex.length - 2) 211 | val blue = cleanedHex.substring(cleanedHex.length - 2) 212 | 213 | val alphaDecimal = (alpha.toInt(16) / 255.0).toString() 214 | val redDecimal = red.toInt(16).toString() 215 | val greenDecimal = green.toInt(16).toString() 216 | val blueDecimal = blue.toInt(16).toString() 217 | 218 | return """ 219 | { 220 | "colors": [ 221 | { 222 | "color": { 223 | "color-space": "srgb", 224 | "components": { 225 | "alpha": "$alphaDecimal", 226 | "blue": "$blueDecimal", 227 | "green": "$greenDecimal", 228 | "red": "$redDecimal" 229 | } 230 | }, 231 | "idiom": "universal" 232 | }, 233 | { 234 | "appearances": [ 235 | { 236 | "appearance": "luminosity", 237 | "value": "dark" 238 | } 239 | ], 240 | "color": { 241 | "color-space": "srgb", 242 | "components": { 243 | "alpha": "$alphaDecimal", 244 | "blue": "$blueDecimal", 245 | "green": "$greenDecimal", 246 | "red": "$redDecimal" 247 | } 248 | }, 249 | "idiom": "universal" 250 | } 251 | ], 252 | "info": { 253 | "author": "xcode", 254 | "version": 1 255 | } 256 | } 257 | """.trimIndent() 258 | } 259 | 260 | private fun String.toCamelCase(): String { 261 | return split('_').joinToString("") { it.capitalize() }.decapitalize() 262 | } 263 | } 264 | 265 | -------------------------------------------------------------------------------- /KColor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider: -------------------------------------------------------------------------------- 1 | KColorProcessorProvider 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 mohitsoni48 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KColor 2 | 3 | ![Maven Central](https://img.shields.io/badge/Maven_Central-1.0.3-blue) 4 | 5 | This is a Kotlin multiplatform library for sharing color between android and iOS. 6 | 7 | ## How to Install 8 | 9 | In project level build.gradle 10 | 11 | ``` groovy 12 | plugins { 13 | //other plugins 14 | id("io.github.mohitsoni48.KColor") version "" apply false 15 | } 16 | ``` 17 | 18 | In shared module build.gradle 19 | 20 | ``` groovy 21 | plugins { 22 | //other plugins 23 | id("io.github.mohitsoni48.KColor") 24 | } 25 | 26 | kotlin { 27 | 28 | sourceSets.commonMain { 29 | kotlin.srcDir("build/generated/colors") 30 | } 31 | 32 | sourceSets { 33 | commonMain.dependencies { 34 | //... 35 | } 36 | } 37 | } 38 | 39 | kColor { 40 | packageName = "com.mohitsoni.kcolorsample" 41 | sharedModule = "shared" //optional, default is shared 42 | iosAppName = "iosApp" //optional, default is iosApp 43 | } 44 | ``` 45 | 46 | ## Add Colors 47 | In your shared module: shared>src>commonMain>resources>colors add “colors.xml” 48 | ``` xml 49 | 50 | #FF9900 51 | #AAFF9900 52 | #FFF00000 53 | 54 | ``` 55 | 56 | ## How to use in Android 57 | After adding color you can run your android app or run 58 | ```./gradlew build``` 59 | Verify generated colors file at shared>build>generated>colors>KColor.kt 60 | You can then simply use this color in your composable like this 61 | 62 | ``` kotlin 63 | @Composable 64 | fun GreetingView(text: String) { 65 | Text(text = text, color = KColor.primaryThree) 66 | } 67 | ``` 68 | 69 | ## How to use in iOS 70 | 71 | Once you have already run your Android app, open iosApp.xcodeproj. On your “iosApp”, right click and click on “Add Files to “iosApp” and add “Colors.xcassets”. You should already start seeing your colors in XCode. 72 | 73 | ## Enable Asset Symbol Extensions 74 | 75 | select iosApp Target> Build Setting, Change the value of “Generate Swift Asset Symbol Extensions” to “yes” 76 | And use it in your swift 77 | 78 | ``` swift 79 | struct ContentView: View { 80 | let greet = Greeting().greet() 81 | 82 | var body: some View { 83 | Text(greet) 84 | .foregroundColor(.primaryThree) 85 | } 86 | } 87 | ``` 88 | 89 | All set 90 | 91 | If you want to set color from your ViewModels you can use generated KColorRes to set colors like this 92 | 93 | In shared module build.gradle 94 | 95 | ``` groovy 96 | plugins { 97 | //other plugins 98 | id("io.github.mohitsoni48.KColor") 99 | } 100 | 101 | kotlin { 102 | 103 | sourceSets.commonMain { 104 | kotlin.srcDir("build/generated/colors") 105 | } 106 | sourceSets.androidMain { 107 | kotlin.srcDir("build/generated/android/kcolors") 108 | } 109 | sourceSets.iosMain { 110 | kotlin.srcDir("build/generated/ios/kcolors") 111 | } 112 | 113 | sourceSets { 114 | commonMain.dependencies { 115 | //... 116 | } 117 | } 118 | } 119 | 120 | kColor { 121 | packageName = "com.mohitsoni.kcolorsample" 122 | sharedModule = "shared" //optional, default is shared 123 | iosAppName = "iosApp" //optional, default is iosApp 124 | } 125 | ``` 126 | 127 | In shared ViewModel 128 | 129 | ``` kotlin 130 | class ColorStateViewModel: ViewModel() { 131 | val colorState: MutableStateFlow = MutableStateFlow(KColorRes.primary) 132 | //..... 133 | fun setColor() { 134 | colorState.value = KColorRes.primaryTwo 135 | } 136 | } 137 | ``` 138 | 139 | and to use in Android and iOS you can use ```getColor()``` method which return ```Color``` from Jertpack compose in AndroidMain and ```UIColor``` in iOSMain 140 | 141 | ### In Android 142 | ``` kotlin 143 | Text(text = text, color = getColor(colorState.value)) 144 | ``` 145 | 146 | ### In iOS 147 | Since in iOS kotlin has interop with Objective-C and not Swift, we get UIColor which you have to convert to ```Color``` in swift so you can create an extention func in swift 148 | 149 | ``` swift 150 | func getColor(kColorRes: KColorRes) -> Color { 151 | return Color(GetColorKt.getColor(kColorRes: kColorRes)) 152 | } 153 | ``` 154 | 155 | and use it like 156 | ``` swift 157 | Text(greet) 158 | .foregroundColor(getColor(kColorRes: colorState.value)) 159 | ``` 160 | 161 | See full instruction with illustrations here: https://medium.com/@mohitsoni48/kcolor-a-library-to-share-color-between-android-and-ios-in-kmm-aca162411dc2 162 | 163 | 164 | ## To support this library 165 | 166 | [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/L3L612MBTA) 167 | -------------------------------------------------------------------------------- /androidApp/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libs.plugins.androidApplication) 3 | alias(libs.plugins.kotlinAndroid) 4 | alias(libs.plugins.compose.compiler) 5 | alias(libs.plugins.google.devtools.ksp) 6 | } 7 | 8 | android { 9 | namespace = "com.mohitsoni.kcolorsample.android" 10 | compileSdk = 34 11 | defaultConfig { 12 | applicationId = "com.mohitsoni.kcolorsample.android" 13 | minSdk = 28 14 | targetSdk = 34 15 | versionCode = 1 16 | versionName = "1.0" 17 | } 18 | buildFeatures { 19 | compose = true 20 | } 21 | packaging { 22 | resources { 23 | excludes += "/META-INF/{AL2.0,LGPL2.1}" 24 | } 25 | } 26 | buildTypes { 27 | getByName("release") { 28 | isMinifyEnabled = false 29 | } 30 | } 31 | compileOptions { 32 | sourceCompatibility = JavaVersion.VERSION_1_8 33 | targetCompatibility = JavaVersion.VERSION_1_8 34 | } 35 | kotlinOptions { 36 | jvmTarget = "1.8" 37 | } 38 | } 39 | 40 | dependencies { 41 | implementation(projects.shared) 42 | implementation(libs.compose.ui) 43 | implementation(libs.compose.ui.tooling.preview) 44 | implementation(libs.compose.material3) 45 | implementation(libs.androidx.activity.compose) 46 | debugImplementation(libs.compose.ui.tooling) 47 | implementation(project(":shared")) 48 | } -------------------------------------------------------------------------------- /androidApp/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /androidApp/src/main/java/com/mohitsoni/kcolorsample/android/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.mohitsoni.kcolorsample.android 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.compose.foundation.layout.Column 7 | import androidx.compose.foundation.layout.fillMaxSize 8 | import androidx.compose.material3.MaterialTheme 9 | import androidx.compose.material3.Surface 10 | import androidx.compose.material3.Text 11 | import androidx.compose.runtime.Composable 12 | import androidx.compose.ui.Modifier 13 | import androidx.compose.ui.tooling.preview.Preview 14 | import com.mohitsoni.kcolorsample.Greeting 15 | import com.mohitsoni.kcolorsample.KColor 16 | import com.mohitsoni.kcolorsample.KColorRes 17 | import com.mohitsoni.kcolorsample.getColor 18 | 19 | class MainActivity : ComponentActivity() { 20 | override fun onCreate(savedInstanceState: Bundle?) { 21 | super.onCreate(savedInstanceState) 22 | setContent { 23 | MyApplicationTheme { 24 | Surface( 25 | modifier = Modifier.fillMaxSize(), 26 | color = MaterialTheme.colorScheme.background 27 | ) { 28 | GreetingView(Greeting().greet()) 29 | } 30 | } 31 | } 32 | } 33 | } 34 | 35 | @Composable 36 | fun GreetingView(text: String) { 37 | Column { 38 | Text(text = text, color = getColor(KColorRes.primary)) 39 | Text(text = text, color = KColor.primary) 40 | Text(text = text, color = KColor.primaryThree) 41 | } 42 | } 43 | 44 | @Preview 45 | @Composable 46 | fun DefaultPreview() { 47 | MyApplicationTheme { 48 | GreetingView("Hello, Android!") 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /androidApp/src/main/java/com/mohitsoni/kcolorsample/android/MyApplicationTheme.kt: -------------------------------------------------------------------------------- 1 | package com.mohitsoni.kcolorsample.android 2 | 3 | import androidx.compose.foundation.isSystemInDarkTheme 4 | import androidx.compose.foundation.shape.RoundedCornerShape 5 | import androidx.compose.material3.MaterialTheme 6 | import androidx.compose.material3.Shapes 7 | import androidx.compose.material3.Typography 8 | import androidx.compose.material3.darkColorScheme 9 | import androidx.compose.material3.lightColorScheme 10 | import androidx.compose.runtime.Composable 11 | import androidx.compose.ui.graphics.Color 12 | import androidx.compose.ui.text.TextStyle 13 | import androidx.compose.ui.text.font.FontFamily 14 | import androidx.compose.ui.text.font.FontWeight 15 | import androidx.compose.ui.unit.dp 16 | import androidx.compose.ui.unit.sp 17 | 18 | @Composable 19 | fun MyApplicationTheme( 20 | darkTheme: Boolean = isSystemInDarkTheme(), 21 | content: @Composable () -> Unit 22 | ) { 23 | val colors = if (darkTheme) { 24 | darkColorScheme( 25 | primary = Color(0xFFBB86FC), 26 | secondary = Color(0xFF03DAC5), 27 | tertiary = Color(0xFF3700B3) 28 | ) 29 | } else { 30 | lightColorScheme( 31 | primary = Color(0xFF6200EE), 32 | secondary = Color(0xFF03DAC5), 33 | tertiary = Color(0xFF3700B3) 34 | ) 35 | } 36 | val typography = Typography( 37 | bodyMedium = TextStyle( 38 | fontFamily = FontFamily.Default, 39 | fontWeight = FontWeight.Normal, 40 | fontSize = 16.sp 41 | ) 42 | ) 43 | val shapes = Shapes( 44 | small = RoundedCornerShape(4.dp), 45 | medium = RoundedCornerShape(4.dp), 46 | large = RoundedCornerShape(0.dp) 47 | ) 48 | 49 | MaterialTheme( 50 | colorScheme = colors, 51 | typography = typography, 52 | shapes = shapes, 53 | content = content 54 | ) 55 | } 56 | -------------------------------------------------------------------------------- /androidApp/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 |