1import { 2 AndroidConfig, 3 ConfigPlugin, 4 WarningAggregator, 5 withAndroidColors, 6 withAndroidStyles, 7} from '@expo/config-plugins'; 8import { ExpoConfig } from '@expo/config-types'; 9 10const NAVIGATION_BAR_COLOR = 'navigationBarColor'; 11 12export const withNavigationBar: ConfigPlugin = (config) => { 13 const immersiveMode = getNavigationBarImmersiveMode(config); 14 if (immersiveMode) { 15 // Immersive mode needs to be set programmatically 16 WarningAggregator.addWarningAndroid( 17 'androidNavigationBar.visible', 18 'Property is deprecated in Android 11 (API 30) and will be removed from Expo SDK.', 19 'https://expo.fyi/android-navigation-bar-visible-deprecated' 20 ); 21 } 22 23 config = withNavigationBarColors(config); 24 config = withNavigationBarStyles(config); 25 return config; 26}; 27 28const withNavigationBarColors: ConfigPlugin = (config) => { 29 return withAndroidColors(config, (config) => { 30 config.modResults = setNavigationBarColors(config, config.modResults); 31 return config; 32 }); 33}; 34 35const withNavigationBarStyles: ConfigPlugin = (config) => { 36 return withAndroidStyles(config, (config) => { 37 config.modResults = setNavigationBarStyles(config, config.modResults); 38 return config; 39 }); 40}; 41 42export function setNavigationBarColors( 43 config: Pick<ExpoConfig, 'androidNavigationBar'>, 44 colors: AndroidConfig.Resources.ResourceXML 45): AndroidConfig.Resources.ResourceXML { 46 const hexString = getNavigationBarColor(config); 47 if (hexString) { 48 colors = AndroidConfig.Colors.setColorItem( 49 AndroidConfig.Resources.buildResourceItem({ 50 name: NAVIGATION_BAR_COLOR, 51 value: hexString, 52 }), 53 colors 54 ); 55 } 56 return colors; 57} 58 59export function setNavigationBarStyles( 60 config: Pick<ExpoConfig, 'androidNavigationBar'>, 61 styles: AndroidConfig.Resources.ResourceXML 62): AndroidConfig.Resources.ResourceXML { 63 styles = AndroidConfig.Styles.assignStylesValue(styles, { 64 add: getNavigationBarStyle(config) === 'dark-content', 65 parent: AndroidConfig.Styles.getAppThemeLightNoActionBarGroup(), 66 name: 'android:windowLightNavigationBar', 67 value: 'true', 68 }); 69 styles = AndroidConfig.Styles.assignStylesValue(styles, { 70 add: !!getNavigationBarColor(config), 71 parent: AndroidConfig.Styles.getAppThemeLightNoActionBarGroup(), 72 name: `android:${NAVIGATION_BAR_COLOR}`, 73 value: `@color/${NAVIGATION_BAR_COLOR}`, 74 }); 75 76 return styles; 77} 78 79export function getNavigationBarImmersiveMode(config: Pick<ExpoConfig, 'androidNavigationBar'>) { 80 return config.androidNavigationBar?.visible || null; 81} 82 83export function getNavigationBarColor(config: Pick<ExpoConfig, 'androidNavigationBar'>) { 84 return config.androidNavigationBar?.backgroundColor || null; 85} 86 87export function getNavigationBarStyle(config: Pick<ExpoConfig, 'androidNavigationBar'>) { 88 return config.androidNavigationBar?.barStyle || 'light-content'; 89} 90