Skip to content

Commit 458c0de

Browse files
authored
Add Material2 / Material3 themes (#42)
1 parent b4336b6 commit 458c0de

File tree

21 files changed

+194
-99
lines changed

21 files changed

+194
-99
lines changed

README.md

+13-1
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,27 @@ Add the library plugin in your `app.json` config file and [create a new build](h
5757
}
5858
```
5959

60+
_📌 The available plugins options are:_
61+
62+
```ts
63+
type Options = {
64+
android?: {
65+
// use an edge-to-edge version of `Theme.{MaterialComponents,Material3}.DayNight.NoActionBar`
66+
parentTheme?: "Material2" | "Material3"; // optional, default is `undefined` (`Theme.EdgeToEdge`)
67+
};
68+
};
69+
```
70+
6071
> [!NOTE]
6172
> This library is not yet supported in the [Expo Go](https://expo.dev/go) sandbox app.
6273
6374
### Bare React Native
6475

65-
Edit your `android/app/src/main/res/values/styles.xml` file to inherit from the provided theme:
76+
Edit your `android/app/src/main/res/values/styles.xml` file to inherit from one of the provided themes:
6677

6778
```diff
6879
<resources>
80+
<!-- inherit from Theme.EdgeToEdge / Theme.EdgeToEdge.Material2 / Theme.EdgeToEdge.Material3 -->
6981
- <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
7082
+ <style name="AppTheme" parent="Theme.EdgeToEdge">
7183
<!-- … -->

android/build.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,5 @@ repositories {
7070
dependencies {
7171
//noinspection GradleDynamicVersion
7272
implementation "com.facebook.react:react-native:+" // From node_modules
73+
implementation "com.google.android.material:material:${safeExtGet("materialVersion", "1.12.0")}"
7374
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<bool name="windowLightSystemBars">false</bool>
4+
</resources>

android/src/main/res/values-night-v27/styles.xml

-7
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<bool name="windowLightSystemBars">false</bool>
4+
</resources>

android/src/main/res/values-night/styles.xml

-6
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<bool name="windowLightSystemBars">true</bool>
4+
</resources>
+10-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<resources>
3-
<style name="Theme.EdgeToEdge.Base" parent="Theme.AppCompat.DayNight.NoActionBar">
4-
<item name="android:windowLightStatusBar">true</item>
5-
<item name="android:windowLightNavigationBar">true</item>
3+
<style name="Theme.EdgeToEdge" parent="Theme.EdgeToEdge.Common">
4+
<item name="android:windowLightNavigationBar">@bool/windowLightSystemBars</item>
5+
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
66
</style>
77

8-
<style name="Theme.EdgeToEdge" parent="Theme.EdgeToEdge.Common">
8+
<style name="Theme.EdgeToEdge.Material2" parent="Theme.EdgeToEdge.Material2.Common">
9+
<item name="android:windowLightNavigationBar">@bool/windowLightSystemBars</item>
10+
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
11+
</style>
12+
13+
<style name="Theme.EdgeToEdge.Material3" parent="Theme.EdgeToEdge.Material3.Common">
14+
<item name="android:windowLightNavigationBar">@bool/windowLightSystemBars</item>
915
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
1016
</style>
1117
</resources>

android/src/main/res/values-v29/styles.xml

+15
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<resources>
33
<style name="Theme.EdgeToEdge" parent="Theme.EdgeToEdge.Common">
4+
<item name="android:windowLightNavigationBar">@bool/windowLightSystemBars</item>
5+
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
6+
<item name="android:enforceStatusBarContrast">false</item>
7+
<item name="android:enforceNavigationBarContrast">true</item>
8+
</style>
9+
10+
<style name="Theme.EdgeToEdge.Material2" parent="Theme.EdgeToEdge.Material2.Common">
11+
<item name="android:windowLightNavigationBar">@bool/windowLightSystemBars</item>
12+
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
13+
<item name="android:enforceStatusBarContrast">false</item>
14+
<item name="android:enforceNavigationBarContrast">true</item>
15+
</style>
16+
17+
<style name="Theme.EdgeToEdge.Material3" parent="Theme.EdgeToEdge.Material3.Common">
18+
<item name="android:windowLightNavigationBar">@bool/windowLightSystemBars</item>
419
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
520
<item name="android:enforceStatusBarContrast">false</item>
621
<item name="android:enforceNavigationBarContrast">true</item>

android/src/main/res/values-v30/styles.xml

+15
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<resources>
33
<style name="Theme.EdgeToEdge" parent="Theme.EdgeToEdge.Common">
4+
<item name="android:windowLightNavigationBar">@bool/windowLightSystemBars</item>
5+
<item name="android:windowLayoutInDisplayCutoutMode">always</item>
6+
<item name="android:enforceStatusBarContrast">false</item>
7+
<item name="android:enforceNavigationBarContrast">true</item>
8+
</style>
9+
10+
<style name="Theme.EdgeToEdge.Material2" parent="Theme.EdgeToEdge.Material2.Common">
11+
<item name="android:windowLightNavigationBar">@bool/windowLightSystemBars</item>
12+
<item name="android:windowLayoutInDisplayCutoutMode">always</item>
13+
<item name="android:enforceStatusBarContrast">false</item>
14+
<item name="android:enforceNavigationBarContrast">true</item>
15+
</style>
16+
17+
<style name="Theme.EdgeToEdge.Material3" parent="Theme.EdgeToEdge.Material3.Common">
18+
<item name="android:windowLightNavigationBar">@bool/windowLightSystemBars</item>
419
<item name="android:windowLayoutInDisplayCutoutMode">always</item>
520
<item name="android:enforceStatusBarContrast">false</item>
621
<item name="android:enforceNavigationBarContrast">true</item>

android/src/main/res/values/bools.xml

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<bool name="windowLightSystemBars">true</bool>
4+
</resources>
+2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<resources>
33
<public name="Theme.EdgeToEdge" type="style" />
4+
<public name="Theme.EdgeToEdge.Material2" type="style" />
5+
<public name="Theme.EdgeToEdge.Material3" type="style" />
46
</resources>
+20-6
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,30 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<resources>
3-
<style name="Theme.EdgeToEdge.Base" parent="Theme.AppCompat.DayNight.NoActionBar">
4-
<item name="android:windowLightStatusBar">true</item>
3+
<style name="Theme.EdgeToEdge.Common" parent="Theme.AppCompat.DayNight.NoActionBar">
4+
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
5+
<item name="android:fitsSystemWindows">false</item>
6+
<item name="android:navigationBarColor">@color/navigationBarColor</item>
7+
<item name="android:statusBarColor">@android:color/transparent</item>
8+
<item name="android:windowLightStatusBar">@bool/windowLightSystemBars</item>
59
</style>
610

7-
<style name="Theme.EdgeToEdge.Common" parent="Theme.EdgeToEdge.Base">
8-
<item name="android:fitsSystemWindows">false</item>
11+
<style name="Theme.EdgeToEdge.Material2.Common" parent="Theme.MaterialComponents.DayNight.NoActionBar">
912
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
10-
<item name="android:statusBarColor">@android:color/transparent</item>
13+
<item name="android:fitsSystemWindows">false</item>
1114
<item name="android:navigationBarColor">@color/navigationBarColor</item>
15+
<item name="android:statusBarColor">@android:color/transparent</item>
16+
<item name="android:windowLightStatusBar">@bool/windowLightSystemBars</item>
1217
</style>
1318

14-
<style name="Theme.EdgeToEdge" parent="Theme.EdgeToEdge.Common">
19+
<style name="Theme.EdgeToEdge.Material3.Common" parent="Theme.Material3.DayNight.NoActionBar">
20+
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
21+
<item name="android:fitsSystemWindows">false</item>
22+
<item name="android:navigationBarColor">@color/navigationBarColor</item>
23+
<item name="android:statusBarColor">@android:color/transparent</item>
24+
<item name="android:windowLightStatusBar">@bool/windowLightSystemBars</item>
1525
</style>
26+
27+
<style name="Theme.EdgeToEdge" parent="Theme.EdgeToEdge.Common" />
28+
<style name="Theme.EdgeToEdge.Material2" parent="Theme.EdgeToEdge.Material2.Common" />
29+
<style name="Theme.EdgeToEdge.Material3" parent="Theme.EdgeToEdge.Material3.Common" />
1630
</resources>

example/Gemfile.lock

+5-3
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ GEM
55
base64
66
nkf
77
rexml
8-
activesupport (7.2.1.2)
8+
activesupport (7.2.2)
99
base64
10+
benchmark (>= 0.3)
1011
bigdecimal
1112
concurrent-ruby (~> 1.0, >= 1.3.1)
1213
connection_pool (>= 2.2.5)
@@ -23,6 +24,7 @@ GEM
2324
json (>= 1.5.1)
2425
atomos (0.1.3)
2526
base64 (0.2.0)
27+
benchmark (0.3.0)
2628
bigdecimal (3.1.8)
2729
claide (1.1.0)
2830
cocoapods (1.15.2)
@@ -76,7 +78,7 @@ GEM
7678
httpclient (2.8.3)
7779
i18n (1.14.6)
7880
concurrent-ruby (~> 1.0)
79-
json (2.7.5)
81+
json (2.7.6)
8082
logger (1.6.1)
8183
minitest (5.25.1)
8284
molinillo (0.8.0)
@@ -112,4 +114,4 @@ RUBY VERSION
112114
ruby 3.3.4p94
113115

114116
BUNDLED WITH
115-
2.5.14
117+
2.5.18

example/ios/Podfile.lock

+6-6
Original file line numberDiff line numberDiff line change
@@ -1242,7 +1242,7 @@ PODS:
12421242
- ReactCommon/turbomodule/bridging
12431243
- ReactCommon/turbomodule/core
12441244
- Yoga
1245-
- react-native-safe-area-context (4.12.0):
1245+
- react-native-safe-area-context (4.14.0):
12461246
- DoubleConversion
12471247
- glog
12481248
- hermes-engine
@@ -1255,8 +1255,8 @@ PODS:
12551255
- React-featureflags
12561256
- React-graphics
12571257
- React-ImageManager
1258-
- react-native-safe-area-context/common (= 4.12.0)
1259-
- react-native-safe-area-context/fabric (= 4.12.0)
1258+
- react-native-safe-area-context/common (= 4.14.0)
1259+
- react-native-safe-area-context/fabric (= 4.14.0)
12601260
- React-NativeModulesApple
12611261
- React-RCTFabric
12621262
- React-rendererdebug
@@ -1265,7 +1265,7 @@ PODS:
12651265
- ReactCommon/turbomodule/bridging
12661266
- ReactCommon/turbomodule/core
12671267
- Yoga
1268-
- react-native-safe-area-context/common (4.12.0):
1268+
- react-native-safe-area-context/common (4.14.0):
12691269
- DoubleConversion
12701270
- glog
12711271
- hermes-engine
@@ -1286,7 +1286,7 @@ PODS:
12861286
- ReactCommon/turbomodule/bridging
12871287
- ReactCommon/turbomodule/core
12881288
- Yoga
1289-
- react-native-safe-area-context/fabric (4.12.0):
1289+
- react-native-safe-area-context/fabric (4.14.0):
12901290
- DoubleConversion
12911291
- glog
12921292
- hermes-engine
@@ -1870,7 +1870,7 @@ SPEC CHECKSUMS:
18701870
React-logger: 97c9dafae1f1a638001a9d1d0e93d431f2f9cb7b
18711871
React-Mapbuffer: 3146a13424f9fec2ea1f1462d49d566e4d69b732
18721872
React-microtasksnativemodule: 02d218c79c72d373a92a8552183f4ead0d1c6e05
1873-
react-native-safe-area-context: 458f6b948437afcb59198016b26bbd02ff9c3b47
1873+
react-native-safe-area-context: 2500e4fe998caad50ad3bc51ec23ef951308569e
18741874
react-native-segmented-control: 6a1ba93bd548d4706df5f472e8c71aea84874d92
18751875
React-nativeconfig: 93fe8c85a8c40820c57814e30f3e44b94c995a7b
18761876
React-NativeModulesApple: b3e076fd0d7b73417fe1e8c8b26e3c57ae9b74aa

example/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"react": "18.3.1",
1919
"react-native": "0.76.1",
2020
"react-native-edge-to-edge": "link:../",
21-
"react-native-safe-area-context": "4.12.0",
21+
"react-native-safe-area-context": "4.14.0",
2222
"react-native-screens": "3.35.0"
2323
},
2424
"devDependencies": {

example/src/App.tsx

+12-5
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@ import {
44
createNativeStackNavigator,
55
NativeStackScreenProps,
66
} from "@react-navigation/native-stack";
7-
import { ReactNode, useState } from "react";
7+
import { ReactNode, useEffect, useState } from "react";
88
import {
99
Appearance,
1010
Text as BaseText,
11-
ColorSchemeName,
1211
Modal,
1312
Platform,
1413
StyleProp,
@@ -101,6 +100,7 @@ const Button = ({
101100
);
102101
};
103102

103+
const SCHEMES = ["system", "light", "dark"];
104104
const STYLES: SystemBarStyle[] = ["auto", "light", "dark"];
105105

106106
type StackParamList = {
@@ -160,11 +160,18 @@ export const HomeScreen = ({
160160
? { false: "#1c1c1f", true: "#2b3e55" }
161161
: { false: "#eeeef0", true: "#ccd8e5" };
162162

163+
const [schemeIndex, setSchemeIndex] = useState(0);
163164
const [styleIndex, setStyleIndex] = useState(0);
164165
const [statusBarHidden, setStatusBarHidden] = useState(false);
165166
const [navigationBarHidden, setNavigationBarHidden] = useState(false);
166167
const [reactNativeModalVisible, setReactNativeModalVisible] = useState(false);
167168

169+
useEffect(() => {
170+
const value = SCHEMES[schemeIndex];
171+
const scheme = value === "light" || value === "dark" ? value : null;
172+
Appearance.setColorScheme(scheme);
173+
}, [schemeIndex]);
174+
168175
const closeReactNativeModal = () => {
169176
setReactNativeModalVisible(false);
170177
};
@@ -182,10 +189,10 @@ export const HomeScreen = ({
182189
<Title>Theme</Title>
183190

184191
<SegmentedControl
185-
values={["light", "dark"] satisfies ColorSchemeName[]}
186-
selectedIndex={dark ? 1 : 0}
192+
values={SCHEMES}
193+
selectedIndex={schemeIndex}
187194
onValueChange={(value) => {
188-
Appearance.setColorScheme(value as ColorSchemeName);
195+
setSchemeIndex(SCHEMES.indexOf(value));
189196
}}
190197
/>
191198

0 commit comments

Comments
 (0)