Skip to content

Commit 9b5a5d3

Browse files
committed
Included M3/M2 theme wrapper as module.
1 parent a5f7bec commit 9b5a5d3

File tree

12 files changed

+1190
-2
lines changed

12 files changed

+1190
-2
lines changed

README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,18 @@ Utilities for theming Compose UI.
2828
- Extended default component colors including secondary (de-emphasised) button colors.
2929
- Drop-in status bar color component to set light or dark status bar icons.
3030

31-
**Module:** `theme` (Material 2) or `theme-m3` (Material 3)
31+
**Module:** `theme` (Material 2) or `theme-m3` (Material 3)
32+
33+
### Theme Wrapper for Compose Material 3
34+
Provides wrappers to apply Material 3 (M3) themes to Material 2 (M2) components and vice-versa.
35+
- Provides wrapper composables that take the color, typography and shape values from the applied M2/M3 theme and maps them onto a M3/M2 theme.
36+
- Use existing Compose components and libraries built with M2 in your M3 project, and your theme will be applied.
37+
- Use new M3 components in your existing M2 project.
38+
- Migrate parts of your UI or migrate your theme without worrying about compatibility with old or new Compose libraries and components.
39+
40+
See the [documentation](/theme-wrapper/README.md) for more info and usage instructions.
41+
42+
**Module:** `theme-wrapper`
3243

3344
## Installation
3445
Android Utils is available via Jitpack.io as both a full library or individual modules.

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
// Top-level build file where you can add configuration options common to all sub-projects/modules.
1818
group = "com.github.rohankhayech.AndroidUtils"
19-
version = "0.4.0"
19+
version = "0.5.0"
2020

2121
plugins {
2222
id("com.android.application") version "8.1.0" apply false

settings.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,4 @@ include(":preview")
3434
include(":theme")
3535
include(":theme-m3")
3636
include(":layout")
37+
include(":theme-wrapper")

theme-wrapper/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build

theme-wrapper/README.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# Theme Wrapper for Compose Material 3
2+
3+
Library for Jetpack Compose providing wrappers to apply **Material 3** (M3) themes to **Material 2** (M2) components and vice-versa.
4+
5+
## Features
6+
- Provides wrapper composables that take the color, typography and shape values from the applied M2/M3 theme and maps them onto a M3/M2 theme.
7+
8+
- Use existing Compose components and libraries built with M2 in your M3 project, and your theme will be applied.
9+
10+
- Use new M3 components in your existing M2 project.
11+
12+
- Migrate parts of your UI or migrate your theme without worrying about compatibility with old or new Compose libraries and components.
13+
14+
## Basic Usage
15+
16+
Simply wrap a Material 2 composable with a `M2Wrapper` and the Material 3 theme will be applied:
17+
18+
```kotlin
19+
MaterialTheme { // Material 3 Theme
20+
M2Wrapper { // Wrap with a Material 2 Theme Wrapper
21+
// Insert Material 2 components here...
22+
ExampleM2Component()
23+
}
24+
}
25+
```
26+
27+
Material 3 composables can likewise be wrapped with a `M3Wrapper` to apply the Material 2 Theme:
28+
```kotlin
29+
MaterialTheme { // Material 2 Theme
30+
M3Wrapper { // Wrap with a Material 3 Theme Wrapper
31+
// Insert Material 3 components here...
32+
ExampleM3Component()
33+
}
34+
}
35+
```
36+
37+
## Usage
38+
39+
### Best Practice
40+
The library is intended for use with existing custom built components and the wide variety of component libraries available online, in order to increase compatibility and theming support in existing projects and outdated libraries.
41+
42+
It aims to solve some of the migration issues outlined in the [Android Developers documentation](https://developer.android.com/jetpack/compose/designsystems/material2-material3).
43+
44+
As default M2 components *(such as buttons, the top app bar, and other controls)* use different color roles and shape sizes than their M3 counterparts, they will not look exactly the same even with the wrapper applied (and vice-versa). Therefore it is recommended to simply use the default low-level components of the intended theme where possible, and only use the wrapper for more complex components.
45+
46+
The above linked resource explains the difference between the two design systems and their compatibility in greater detail.
47+
48+
### Customisation
49+
By default, the wrappers map the colors and shapes that allow for components to best match their counterparts in the current theme.
50+
51+
If this does not work as expected, the library also provides the `exactColors()`, `exactColorScheme()` and `exactShapes()` mappings which map values 1:1 to their named counterparts in the current theme, which may be more intuitive depending on the component.
52+
53+
These can be specified by modifying the properties of the wrapper:
54+
```kotlin
55+
M2Wrapper(
56+
colors = M2WrapperDefaults.exactColors()
57+
) { /* ... */ }
58+
```
59+
```kotlin
60+
M3Wrapper(
61+
colorScheme = M3WrapperDefaults.exactColorScheme(),
62+
shapes = M3WrapperDefaults.exactShapes()
63+
) { /* ... */ }
64+
```
65+
66+
All of the default color, typography and shape mappings can also be overridden as required, for example:
67+
```kotlin
68+
M2Wrapper(
69+
colors = M2WrapperDefaults.colors(
70+
primaryVariant = MaterialTheme.colorScheme.primaryContainer
71+
)
72+
) { /* ... */ }
73+
```
74+
75+
The `M2WrapperDefaults` and `M3WrapperDefaults` provide the default `colors()` / `colorScheme()`, `shapes()` and `typography()` mappings to allow for complete customisation.
76+
77+
This is useful for ensuring the correct colors etc. are used for components that lack color customisation.
78+
79+
> For best results, use the wrapper as close to the component as possible to allow mappings to be customised per component.
80+
81+
You can also specify your own `Colors` / `ColorScheme`, `Shapes` and `Typography` objects, however this is not recommended.
82+

theme-wrapper/build.gradle.kts

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/*
2+
* Copyright 2025 Rohan Khayech
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
plugins {
18+
id("com.android.library")
19+
id("org.jetbrains.kotlin.android")
20+
id("maven-publish")
21+
}
22+
23+
android {
24+
namespace = "com.rohankhayech.android.util.themewrapper"
25+
compileSdk = 33
26+
27+
defaultConfig {
28+
minSdk = 24
29+
aarMetadata {
30+
minCompileSdk = 24
31+
}
32+
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
33+
consumerProguardFiles("consumer-rules.pro")
34+
}
35+
36+
buildTypes {
37+
release {
38+
isMinifyEnabled = false
39+
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
40+
}
41+
}
42+
43+
publishing {
44+
singleVariant("release") {
45+
withSourcesJar()
46+
withJavadocJar()
47+
}
48+
}
49+
50+
compileOptions {
51+
sourceCompatibility = JavaVersion.VERSION_11
52+
targetCompatibility = JavaVersion.VERSION_11
53+
}
54+
55+
kotlinOptions {
56+
jvmTarget = "11"
57+
}
58+
59+
buildFeatures {
60+
compose = true
61+
}
62+
63+
composeOptions {
64+
kotlinCompilerExtensionVersion = "1.5.1"
65+
}
66+
}
67+
68+
publishing {
69+
publications {
70+
register<MavenPublication>("release") {
71+
groupId = project.group.toString()
72+
artifactId = rootProject.name
73+
version = project.version.toString()
74+
75+
afterEvaluate {
76+
from(components["release"])
77+
}
78+
79+
pom {
80+
name.set("Theme Wrapper for Compose M3")
81+
description.set("Library for Jetpack Compose providing wrappers to apply Material 3 (M3) themes to Material 2 (M2) components and vice-versa.")
82+
url.set("https://github.com/rohankhayech/AndroidUtils")
83+
84+
licenses {
85+
license {
86+
name.set("Apache License, Version 2.0")
87+
url.set("https://github.com/rohankhayech/AndroidUtils/blob/main/LICENSE")
88+
}
89+
}
90+
91+
developers {
92+
developer {
93+
id.set("rohankhayech")
94+
name.set("Rohan Khayech")
95+
}
96+
}
97+
}
98+
}
99+
}
100+
}
101+
102+
dependencies {
103+
implementation("androidx.core:core-ktx:1.10.1")
104+
implementation("androidx.appcompat:appcompat:1.6.1")
105+
implementation("com.google.android.material:material:1.9.0")
106+
testImplementation("junit:junit:4.13.2")
107+
androidTestImplementation("androidx.test.ext:junit:1.1.5")
108+
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
109+
110+
implementation("androidx.compose.material3:material3:1.1.1")
111+
implementation("androidx.compose.material:material:1.4.3")
112+
implementation("androidx.compose.ui:ui-tooling-preview:1.4.3")
113+
debugImplementation("androidx.compose.ui:ui-tooling:1.4.3")
114+
115+
// Dokka
116+
dokkaPlugin("org.jetbrains.dokka:android-documentation-plugin:1.9.0")
117+
}

theme-wrapper/consumer-rules.pro

Whitespace-only changes.

theme-wrapper/proguard-rules.pro

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Add project specific ProGuard rules here.
2+
# You can control the set of applied configuration files using the
3+
# proguardFiles setting in build.gradle.
4+
#
5+
# For more details, see
6+
# http://developer.android.com/guide/developing/tools/proguard.html
7+
8+
# If your project uses WebView with JS, uncomment the following
9+
# and specify the fully qualified class name to the JavaScript interface
10+
# class:
11+
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12+
# public *;
13+
#}
14+
15+
# Uncomment this to preserve the line number information for
16+
# debugging stack traces.
17+
#-keepattributes SourceFile,LineNumberTable
18+
19+
# If you keep the line number information, uncomment this to
20+
# hide the original source file name.
21+
#-renamesourcefileattribute SourceFile
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
~ Copyright 2025 Rohan Khayech
4+
~
5+
~ Licensed under the Apache License, Version 2.0 (the "License");
6+
~ you may not use this file except in compliance with the License.
7+
~ You may obtain a copy of the License at
8+
~
9+
~ http://www.apache.org/licenses/LICENSE-2.0
10+
~
11+
~ Unless required by applicable law or agreed to in writing, software
12+
~ distributed under the License is distributed on an "AS IS" BASIS,
13+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
~ See the License for the specific language governing permissions and
15+
~ limitations under the License.
16+
-->
17+
18+
<manifest>
19+
20+
</manifest>

0 commit comments

Comments
 (0)