/react-native-appearance

React Native 0.59, 0.60, and 0.61 polyfill for the Appearance API

Primary LanguageJavaMIT LicenseMIT

react-native-appearance

Polyfill for Appearance API to detect preferred color scheme (light/dark) in React Native 0.59, 0.60 and perhaps more (ymmv outside of these two!). The Appearance API will likely be available in react-native@>=0.61.

This library is currently iOS only, and on iOS < 13 the color scheme will always be 'no-preference'.

Installation

Installation instructions vary depending on whether you're using a managed Expo project or a bare React Native project.

Managed Expo project

This library is supported in Expo SDK 35+.

expo install react-native-appearance

Bare React Native project

Install the library using either Yarn:

yarn add react-native-appearance

or npm:

npm install react-native-appearance

Mostly automatic install with react-native

  • React Native 0.60+

CLI autolink feature links the module while building the app.

  • React Native <= 0.59
$ react-native link react-native-appearance

Note For iOS using cocoapods, run:

$ cd ios/ && pod install

Manual installation

iOS

  1. In XCode, in the project navigator, right click LibrariesAdd Files to [your project's name]

  2. Go to node_modulesreact-native-appearance and add Appearance.xcodeproj

  3. In XCode, in the project navigator, select your project. Add libAppearance.a to your project's Build PhasesLink Binary With Libraries

  4. Run your project (Cmd+R)<

Android

  1. Open up android/app/src/main/java/[...]/MainApplication.java
  • Add import com.reactlibrary.RNCApperancePackage; to the imports at the top of the file

  • Add new RNCApperancePackage() to the list returned by the getPackages() method

  1. Append the following lines to android/settings.gradle:

include ':react-native-appearance'

project(':react-native-appearance').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-appearance/android')

  1. Insert the following lines inside the dependencies block in android/app/build.gradle:

implementation project(':react-native-appearance')

Configuration (required)

Android

Implement uiMode in AndroidManifest.xml

    <activity
    ...
    android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode">

Implement onConfigurationChanged method in MainActivity.java

    import android.content.Intent; // <--- import
    import android.content.res.Configuration; // <--- import

    public class MainActivity extends ReactActivity {
      ......

      // copy these lines
      @Override
      public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        Intent intent = new Intent("onConfigurationChanged");
        intent.putExtra("newConfig", newConfig);
        sendBroadcast(intent);
      }

      ......
    }

Usage

First, you need to wrap your app in the AppearanceProvider. At the root of your app, do the following:

import { AppearanceProvider } from 'react-native-appearance';

export default () => (
  <AppearanceProvider>
    <App />
  </AppearanceProvider>
);

Now you can use Appearance and useColorScheme anywhere in your app.

import { Appearance, useColorScheme } from 'react-native-appearance';

/**
 * Get the current color scheme
 */
Appearance.getColorScheme();

/**
 * Subscribe to color scheme changes with a hook
 */
function MyComponent() {
  let colorScheme = useColorScheme();
  if (colorScheme === 'dark') {
    // render some dark thing
  } else {
    // render some light thing
  }
}

/**
 * Subscribe to color scheme without a hook
 */
let subscription = Appearance.addChangeListener(({ colorScheme }) => {
  // do something with color scheme
});

// Remove the subscription at some point
subscription.remove()

Attribution

This was mostly written by Facebook for inclusion in React Native core. It is provided here as a separate module so people can opt-in to using it without updating entirely to the newest React Native version.