react-nativedatepickerexpo

Expo: Change accent color of @react-native-community/datetimepicker


I am working on a managed Expo project (Expo SDK version 49). I use @react-native-community/datetimepicker to display a date picker dialog:

import { View } from "react-native";
import RNDateTimePicker from "@react-native-community/datetimepicker";


const DatePickerTest = () => {
        const value = new Date();
        return (
            <View style={{flex: 1}}>
                <RNDateTimePicker
                    mode="date"
                    value={value}
                />
            </View>
        );
    }
;

export default DatePickerTest;

When I run the code on Android, a Date Picker is rendered with a header and selection color inherited from Android's default theme (green, in my case):

date picker green background

I understand that in order to change the accent color, I need to change styles.xml in android/app/src/main/res/values (see e.g. https://stackoverflow.com/a/48369871/4350421). However, in an Expo managed project, I do not have access to the android folder.

How can I change the accent color without ejecting from Expo?


Solution

  • With the introduction of config plugins in SDK Verion 41, it is possible to interact with the Android configuration files at build time without ejecting from the Expo managed workflow. Note that this approach won't work with Expo Go - you will need to build a custom dev client.

    I have posted a detailed description of the generic approach here.

    In order to change the accent color:

    1. Create a plugins directory at the root of your project.
    2. Create a file named custom-android-styles.js in this directory, with the following code:
    const { withAndroidStyles } = require('@expo/config-plugins');
    
    const withCustomStyles = config => {
        return withAndroidStyles(config, async config => {
            config.modResults = applyCustomStyles(config.modResults);
            return config;
        });
    };
    
    function applyCustomStyles(styles) {
        // Add items to the App Theme
        const appTheme = styles.resources.style.find(style => style.$.name === 'AppTheme');
        if (appTheme) {
            appTheme.item.push({ _: '@style/Dialog.Theme', $: { name: 'android:datePickerDialogTheme' } });
            appTheme.item.push({ _: '@style/Dialog.Theme', $: { name: 'android:timePickerDialogTheme' } });
        }
    
        // Add new style definition
        styles.resources.style.push({
            $: { name: 'Dialog.Theme', parent: 'Theme.AppCompat.Light.Dialog' },
            item: [{ _: '#a7243a', $: { name: 'colorAccent' } }],
        });
    
        return styles;
    }
    
    module.exports = withCustomStyles;
    
    1. Add the following to app.config.js:
    export default {
        expo: {
        //...
            plugins: [
                //...
                "./plugins/custom-android-styles.js",
            ]
        }
    }; 
    
    1. Build your custom dev client with EAS.

    If all goes well, your DatePicker will look like this:

    enter image description here