Light and Dark modes
Regardless of whether you are personally on team light or team dark, it's becoming increasingly common for apps to support these two color schemes. This guide explains how you can do that.
Both managed and bare projects for iOS and Android require additional configuration to support switching between light and dark mode. No additional configuration is required for web.
Configure your supported appearance styles in app.json
/ app.config.js
with the userInterfaceStyle
key. You can also configure specific platform to support different appearance styles by setting either android.userInterfaceStyle
or ios.userInterfaceStyle
to preferred value.
The available options are: automatic
(follow system appearance settings and notify about any change user makes), light
(restrict app to support light theme only), and dark
(restrict app to support dark theme only). If this key is absent, the app will default to the light
style.
Example app.json
configuration:
{
"expo": {
"userInterfaceStyle": "automatic"
}
}
You can configure supported styles with the
UIUserInterfaceStyle key in your app
Info.plist
. Use
Automatic
to support both light and dark modes.
Ensure that the uiMode
flag is present on your MainActivity
(and any other activities where this behavior is desired) in AndroidManifest.xml
:
<activity
...
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode">
Implement the onConfigurationChanged
method in MainActivity.java
:
import android.content.Intent;
import android.content.res.Configuration;
public class MainActivity extends ReactActivity {
......
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Intent intent = new Intent("onConfigurationChanged");
intent.putExtra("newConfig", newConfig);
sendBroadcast(intent);
}
......
}
To detect the color scheme in our application, we can use Appearance
and/or useColorScheme
from react-native
:
import { Appearance, useColorScheme } from 'react-native';
You will probably want to use the useColorScheme()
hook:
function MyComponent() {
let colorScheme = useColorScheme();
if (colorScheme === 'dark') {
} else {
}
}
In some cases, you may find it helpful to get the current color scheme imperatively with
Appearance.getColorScheme()
and/or listen to changes with
Appearance.addChangeListener
.
Read more.
Don't forget to configure your project to support automatic color scheme as described above in
Configuration.
import React from 'react';
import { Text, StyleSheet, View, useColorScheme } from 'react-native';
import { StatusBar } from 'expo-status-bar';
export default function App() {
const colorScheme = useColorScheme();
const themeTextStyle = colorScheme === 'light' ? styles.lightThemeText : styles.darkThemeText;
const themeContainerStyle =
colorScheme === 'light' ? styles.lightContainer : styles.darkContainer;
return (
<View style={[styles.container, themeContainerStyle]}>
<Text style={[styles.text, themeTextStyle]}>Color scheme: {colorScheme}</Text>
<StatusBar />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
lightContainer: {
backgroundColor: '#d0d0c0',
},
darkContainer: {
backgroundColor: '#242c40',
},
lightThemeText: {
color: '#242c40',
},
darkThemeText: {
color: '#d0d0c0',
},
});
While you're developing, you may want to change your simulator's or device's appearance.
- If working with an iOS emulator locally, you can use the
command
+ shift
+ a
shortcut to toggle between light and dark mode. - If using a real device or an Android emulator, you can toggle the system dark mode setting in the device's settings.
- Snack is locked to light mode.