diff --git a/packages/@expo/prebuild-config/CHANGELOG.md b/packages/@expo/prebuild-config/CHANGELOG.md index 95fac9112dbcd2..d6b2acd00db435 100644 --- a/packages/@expo/prebuild-config/CHANGELOG.md +++ b/packages/@expo/prebuild-config/CHANGELOG.md @@ -8,6 +8,8 @@ ### 🐛 Bug fixes +- Fixed `STATUS_BAR_PLUGIN` deprecation warning shown on prebuild for default `create-expo-app` template by no longer auto-populating `androidStatusBar.backgroundColor` from the splash background color. ([#43444](https://github.com/expo/expo/issues/43444)) ([#43453](https://github.com/expo/expo/pull/43453) by [@zoontek](https://github.com/zoontek)) + ### 💡 Others ## 55.0.7 — 2026-02-25 diff --git a/packages/@expo/prebuild-config/build/plugins/unversioned/expo-splash-screen/withAndroidSplashScreen.js b/packages/@expo/prebuild-config/build/plugins/unversioned/expo-splash-screen/withAndroidSplashScreen.js index 728a894b55583c..2d47fd54530b88 100644 --- a/packages/@expo/prebuild-config/build/plugins/unversioned/expo-splash-screen/withAndroidSplashScreen.js +++ b/packages/@expo/prebuild-config/build/plugins/unversioned/expo-splash-screen/withAndroidSplashScreen.js @@ -56,18 +56,6 @@ function _withAndroidSplashStyles() { const withAndroidSplashScreen = (config, props) => { const isLegacyConfig = props === undefined; const splashConfig = (0, _getAndroidSplashConfig().getAndroidSplashConfig)(config, props ?? null); - - // Update the android status bar to match the splash screen - // androidStatusBar applies info to the app activity style. - const backgroundColor = splashConfig?.backgroundColor || '#ffffff'; - if (config.androidStatusBar?.backgroundColor) { - if (backgroundColor.toLowerCase() !== config.androidStatusBar?.backgroundColor?.toLowerCase?.()) { - _configPlugins().WarningAggregator.addWarningAndroid('androidStatusBar.backgroundColor', 'Color conflicts with the splash.backgroundColor'); - } - } else { - if (!config.androidStatusBar) config.androidStatusBar = {}; - config.androidStatusBar.backgroundColor = backgroundColor; - } return (0, _configPlugins().withPlugins)(config, [[_withAndroidSplashMainActivity().withAndroidSplashMainActivity, { isLegacyConfig }], [_withAndroidSplashImages().withAndroidSplashImages, splashConfig], [_withAndroidSplashDrawables().withAndroidSplashDrawables, splashConfig], [_withAndroidSplashStyles().withAndroidSplashStyles, { diff --git a/packages/@expo/prebuild-config/build/plugins/unversioned/expo-splash-screen/withAndroidSplashScreen.js.map b/packages/@expo/prebuild-config/build/plugins/unversioned/expo-splash-screen/withAndroidSplashScreen.js.map index ef495c2b9843e9..69652d55ece22a 100644 --- a/packages/@expo/prebuild-config/build/plugins/unversioned/expo-splash-screen/withAndroidSplashScreen.js.map +++ b/packages/@expo/prebuild-config/build/plugins/unversioned/expo-splash-screen/withAndroidSplashScreen.js.map @@ -1 +1 @@ -{"version":3,"file":"withAndroidSplashScreen.js","names":["_configPlugins","data","require","_getAndroidSplashConfig","_withAndroidSplashDrawables","_withAndroidSplashImages","_withAndroidSplashMainActivity","_withAndroidSplashStrings","_withAndroidSplashStyles","withAndroidSplashScreen","config","props","isLegacyConfig","undefined","splashConfig","getAndroidSplashConfig","backgroundColor","androidStatusBar","toLowerCase","WarningAggregator","addWarningAndroid","withPlugins","withAndroidSplashMainActivity","withAndroidSplashImages","withAndroidSplashDrawables","withAndroidSplashStyles","withAndroidSplashStrings","exports"],"sources":["../../../../src/plugins/unversioned/expo-splash-screen/withAndroidSplashScreen.ts"],"sourcesContent":["import { ConfigPlugin, WarningAggregator, withPlugins } from '@expo/config-plugins';\n\nimport { AndroidSplashConfig, getAndroidSplashConfig } from './getAndroidSplashConfig';\nimport { withAndroidSplashDrawables } from './withAndroidSplashDrawables';\nimport { withAndroidSplashImages } from './withAndroidSplashImages';\nimport { withAndroidSplashMainActivity } from './withAndroidSplashMainActivity';\nimport { withAndroidSplashStrings } from './withAndroidSplashStrings';\nimport { withAndroidSplashStyles } from './withAndroidSplashStyles';\n\nexport const withAndroidSplashScreen: ConfigPlugin<\n AndroidSplashConfig | undefined | null | void\n> = (config, props) => {\n const isLegacyConfig = props === undefined;\n const splashConfig = getAndroidSplashConfig(config, props ?? null);\n\n // Update the android status bar to match the splash screen\n // androidStatusBar applies info to the app activity style.\n const backgroundColor = splashConfig?.backgroundColor || '#ffffff';\n if (config.androidStatusBar?.backgroundColor) {\n if (\n backgroundColor.toLowerCase() !== config.androidStatusBar?.backgroundColor?.toLowerCase?.()\n ) {\n WarningAggregator.addWarningAndroid(\n 'androidStatusBar.backgroundColor',\n 'Color conflicts with the splash.backgroundColor'\n );\n }\n } else {\n if (!config.androidStatusBar) config.androidStatusBar = {};\n config.androidStatusBar.backgroundColor = backgroundColor;\n }\n\n return withPlugins(config, [\n [withAndroidSplashMainActivity, { isLegacyConfig }],\n [withAndroidSplashImages, splashConfig],\n [withAndroidSplashDrawables, splashConfig],\n [withAndroidSplashStyles, { splashConfig, isLegacyConfig }],\n [withAndroidSplashStrings, splashConfig],\n ]);\n};\n"],"mappings":";;;;;;AAAA,SAAAA,eAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,cAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA,SAAAE,wBAAA;EAAA,MAAAF,IAAA,GAAAC,OAAA;EAAAC,uBAAA,YAAAA,CAAA;IAAA,OAAAF,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAG,4BAAA;EAAA,MAAAH,IAAA,GAAAC,OAAA;EAAAE,2BAAA,YAAAA,CAAA;IAAA,OAAAH,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAI,yBAAA;EAAA,MAAAJ,IAAA,GAAAC,OAAA;EAAAG,wBAAA,YAAAA,CAAA;IAAA,OAAAJ,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAK,+BAAA;EAAA,MAAAL,IAAA,GAAAC,OAAA;EAAAI,8BAAA,YAAAA,CAAA;IAAA,OAAAL,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAM,0BAAA;EAAA,MAAAN,IAAA,GAAAC,OAAA;EAAAK,yBAAA,YAAAA,CAAA;IAAA,OAAAN,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAO,yBAAA;EAAA,MAAAP,IAAA,GAAAC,OAAA;EAAAM,wBAAA,YAAAA,CAAA;IAAA,OAAAP,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEO,MAAMQ,uBAEZ,GAAGA,CAACC,MAAM,EAAEC,KAAK,KAAK;EACrB,MAAMC,cAAc,GAAGD,KAAK,KAAKE,SAAS;EAC1C,MAAMC,YAAY,GAAG,IAAAC,gDAAsB,EAACL,MAAM,EAAEC,KAAK,IAAI,IAAI,CAAC;;EAElE;EACA;EACA,MAAMK,eAAe,GAAGF,YAAY,EAAEE,eAAe,IAAI,SAAS;EAClE,IAAIN,MAAM,CAACO,gBAAgB,EAAED,eAAe,EAAE;IAC5C,IACEA,eAAe,CAACE,WAAW,CAAC,CAAC,KAAKR,MAAM,CAACO,gBAAgB,EAAED,eAAe,EAAEE,WAAW,GAAG,CAAC,EAC3F;MACAC,kCAAiB,CAACC,iBAAiB,CACjC,kCAAkC,EAClC,iDACF,CAAC;IACH;EACF,CAAC,MAAM;IACL,IAAI,CAACV,MAAM,CAACO,gBAAgB,EAAEP,MAAM,CAACO,gBAAgB,GAAG,CAAC,CAAC;IAC1DP,MAAM,CAACO,gBAAgB,CAACD,eAAe,GAAGA,eAAe;EAC3D;EAEA,OAAO,IAAAK,4BAAW,EAACX,MAAM,EAAE,CACzB,CAACY,8DAA6B,EAAE;IAAEV;EAAe,CAAC,CAAC,EACnD,CAACW,kDAAuB,EAAET,YAAY,CAAC,EACvC,CAACU,wDAA0B,EAAEV,YAAY,CAAC,EAC1C,CAACW,kDAAuB,EAAE;IAAEX,YAAY;IAAEF;EAAe,CAAC,CAAC,EAC3D,CAACc,oDAAwB,EAAEZ,YAAY,CAAC,CACzC,CAAC;AACJ,CAAC;AAACa,OAAA,CAAAlB,uBAAA,GAAAA,uBAAA","ignoreList":[]} \ No newline at end of file +{"version":3,"file":"withAndroidSplashScreen.js","names":["_configPlugins","data","require","_getAndroidSplashConfig","_withAndroidSplashDrawables","_withAndroidSplashImages","_withAndroidSplashMainActivity","_withAndroidSplashStrings","_withAndroidSplashStyles","withAndroidSplashScreen","config","props","isLegacyConfig","undefined","splashConfig","getAndroidSplashConfig","withPlugins","withAndroidSplashMainActivity","withAndroidSplashImages","withAndroidSplashDrawables","withAndroidSplashStyles","withAndroidSplashStrings","exports"],"sources":["../../../../src/plugins/unversioned/expo-splash-screen/withAndroidSplashScreen.ts"],"sourcesContent":["import { ConfigPlugin, withPlugins } from '@expo/config-plugins';\n\nimport { AndroidSplashConfig, getAndroidSplashConfig } from './getAndroidSplashConfig';\nimport { withAndroidSplashDrawables } from './withAndroidSplashDrawables';\nimport { withAndroidSplashImages } from './withAndroidSplashImages';\nimport { withAndroidSplashMainActivity } from './withAndroidSplashMainActivity';\nimport { withAndroidSplashStrings } from './withAndroidSplashStrings';\nimport { withAndroidSplashStyles } from './withAndroidSplashStyles';\n\nexport const withAndroidSplashScreen: ConfigPlugin<\n AndroidSplashConfig | undefined | null | void\n> = (config, props) => {\n const isLegacyConfig = props === undefined;\n const splashConfig = getAndroidSplashConfig(config, props ?? null);\n\n return withPlugins(config, [\n [withAndroidSplashMainActivity, { isLegacyConfig }],\n [withAndroidSplashImages, splashConfig],\n [withAndroidSplashDrawables, splashConfig],\n [withAndroidSplashStyles, { splashConfig, isLegacyConfig }],\n [withAndroidSplashStrings, splashConfig],\n ]);\n};\n"],"mappings":";;;;;;AAAA,SAAAA,eAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,cAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA,SAAAE,wBAAA;EAAA,MAAAF,IAAA,GAAAC,OAAA;EAAAC,uBAAA,YAAAA,CAAA;IAAA,OAAAF,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAG,4BAAA;EAAA,MAAAH,IAAA,GAAAC,OAAA;EAAAE,2BAAA,YAAAA,CAAA;IAAA,OAAAH,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAI,yBAAA;EAAA,MAAAJ,IAAA,GAAAC,OAAA;EAAAG,wBAAA,YAAAA,CAAA;IAAA,OAAAJ,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAK,+BAAA;EAAA,MAAAL,IAAA,GAAAC,OAAA;EAAAI,8BAAA,YAAAA,CAAA;IAAA,OAAAL,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAM,0BAAA;EAAA,MAAAN,IAAA,GAAAC,OAAA;EAAAK,yBAAA,YAAAA,CAAA;IAAA,OAAAN,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAO,yBAAA;EAAA,MAAAP,IAAA,GAAAC,OAAA;EAAAM,wBAAA,YAAAA,CAAA;IAAA,OAAAP,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEO,MAAMQ,uBAEZ,GAAGA,CAACC,MAAM,EAAEC,KAAK,KAAK;EACrB,MAAMC,cAAc,GAAGD,KAAK,KAAKE,SAAS;EAC1C,MAAMC,YAAY,GAAG,IAAAC,gDAAsB,EAACL,MAAM,EAAEC,KAAK,IAAI,IAAI,CAAC;EAElE,OAAO,IAAAK,4BAAW,EAACN,MAAM,EAAE,CACzB,CAACO,8DAA6B,EAAE;IAAEL;EAAe,CAAC,CAAC,EACnD,CAACM,kDAAuB,EAAEJ,YAAY,CAAC,EACvC,CAACK,wDAA0B,EAAEL,YAAY,CAAC,EAC1C,CAACM,kDAAuB,EAAE;IAAEN,YAAY;IAAEF;EAAe,CAAC,CAAC,EAC3D,CAACS,oDAAwB,EAAEP,YAAY,CAAC,CACzC,CAAC;AACJ,CAAC;AAACQ,OAAA,CAAAb,uBAAA,GAAAA,uBAAA","ignoreList":[]} \ No newline at end of file diff --git a/packages/@expo/prebuild-config/build/plugins/unversioned/expo-splash-screen/withAndroidSplashStrings.d.ts b/packages/@expo/prebuild-config/build/plugins/unversioned/expo-splash-screen/withAndroidSplashStrings.d.ts index 7d8e68732f9d06..fda7560d27a774 100644 --- a/packages/@expo/prebuild-config/build/plugins/unversioned/expo-splash-screen/withAndroidSplashStrings.d.ts +++ b/packages/@expo/prebuild-config/build/plugins/unversioned/expo-splash-screen/withAndroidSplashStrings.d.ts @@ -1,4 +1,4 @@ import { AndroidConfig, ConfigPlugin } from '@expo/config-plugins'; import { AndroidSplashConfig } from './getAndroidSplashConfig'; export declare const withAndroidSplashStrings: ConfigPlugin; -export declare function setSplashStrings(strings: AndroidConfig.Resources.ResourceXML, resizeMode: string, statusBarTranslucent: boolean): AndroidConfig.Resources.ResourceXML; +export declare function setSplashStrings(strings: AndroidConfig.Resources.ResourceXML, resizeMode: string): AndroidConfig.Resources.ResourceXML; diff --git a/packages/@expo/prebuild-config/build/plugins/unversioned/expo-splash-screen/withAndroidSplashStrings.js b/packages/@expo/prebuild-config/build/plugins/unversioned/expo-splash-screen/withAndroidSplashStrings.js index a745ceefa762d6..45cbd76ffbc1db 100644 --- a/packages/@expo/prebuild-config/build/plugins/unversioned/expo-splash-screen/withAndroidSplashStrings.js +++ b/packages/@expo/prebuild-config/build/plugins/unversioned/expo-splash-screen/withAndroidSplashStrings.js @@ -20,7 +20,6 @@ function _getAndroidSplashConfig() { return data; } const RESIZE_MODE_KEY = 'expo_splash_screen_resize_mode'; -const STATUS_BAR_TRANSLUCENT_KEY = 'expo_splash_screen_status_bar_translucent'; const withAndroidSplashStrings = (config, props) => { return (0, _configPlugins().withStringsXml)(config, config => { const splashConfig = (0, _getAndroidSplashConfig().getAndroidSplashConfig)(config, props); @@ -28,22 +27,17 @@ const withAndroidSplashStrings = (config, props) => { const { resizeMode } = splashConfig; - const statusBarTranslucent = !!config.androidStatusBar?.translucent; - config.modResults = setSplashStrings(config.modResults, resizeMode, statusBarTranslucent); + config.modResults = setSplashStrings(config.modResults, resizeMode); } return config; }); }; exports.withAndroidSplashStrings = withAndroidSplashStrings; -function setSplashStrings(strings, resizeMode, statusBarTranslucent) { +function setSplashStrings(strings, resizeMode) { return _configPlugins().AndroidConfig.Strings.setStringItem([_configPlugins().AndroidConfig.Resources.buildResourceItem({ name: RESIZE_MODE_KEY, value: resizeMode, translatable: false - }), _configPlugins().AndroidConfig.Resources.buildResourceItem({ - name: STATUS_BAR_TRANSLUCENT_KEY, - value: String(statusBarTranslucent), - translatable: false })], strings); } //# sourceMappingURL=withAndroidSplashStrings.js.map \ No newline at end of file diff --git a/packages/@expo/prebuild-config/build/plugins/unversioned/expo-splash-screen/withAndroidSplashStrings.js.map b/packages/@expo/prebuild-config/build/plugins/unversioned/expo-splash-screen/withAndroidSplashStrings.js.map index 83c278970cb15c..921f4afabf249c 100644 --- a/packages/@expo/prebuild-config/build/plugins/unversioned/expo-splash-screen/withAndroidSplashStrings.js.map +++ b/packages/@expo/prebuild-config/build/plugins/unversioned/expo-splash-screen/withAndroidSplashStrings.js.map @@ -1 +1 @@ -{"version":3,"file":"withAndroidSplashStrings.js","names":["_configPlugins","data","require","_getAndroidSplashConfig","RESIZE_MODE_KEY","STATUS_BAR_TRANSLUCENT_KEY","withAndroidSplashStrings","config","props","withStringsXml","splashConfig","getAndroidSplashConfig","resizeMode","statusBarTranslucent","androidStatusBar","translucent","modResults","setSplashStrings","exports","strings","AndroidConfig","Strings","setStringItem","Resources","buildResourceItem","name","value","translatable","String"],"sources":["../../../../src/plugins/unversioned/expo-splash-screen/withAndroidSplashStrings.ts"],"sourcesContent":["import { AndroidConfig, ConfigPlugin, withStringsXml } from '@expo/config-plugins';\n\nimport { AndroidSplashConfig, getAndroidSplashConfig } from './getAndroidSplashConfig';\n\nconst RESIZE_MODE_KEY = 'expo_splash_screen_resize_mode';\nconst STATUS_BAR_TRANSLUCENT_KEY = 'expo_splash_screen_status_bar_translucent';\n\nexport const withAndroidSplashStrings: ConfigPlugin = (config, props) => {\n return withStringsXml(config, (config) => {\n const splashConfig = getAndroidSplashConfig(config, props);\n if (splashConfig) {\n const { resizeMode } = splashConfig;\n const statusBarTranslucent = !!config.androidStatusBar?.translucent;\n config.modResults = setSplashStrings(config.modResults, resizeMode, statusBarTranslucent);\n }\n return config;\n });\n};\n\nexport function setSplashStrings(\n strings: AndroidConfig.Resources.ResourceXML,\n resizeMode: string,\n statusBarTranslucent: boolean\n): AndroidConfig.Resources.ResourceXML {\n return AndroidConfig.Strings.setStringItem(\n [\n AndroidConfig.Resources.buildResourceItem({\n name: RESIZE_MODE_KEY,\n value: resizeMode,\n translatable: false,\n }),\n AndroidConfig.Resources.buildResourceItem({\n name: STATUS_BAR_TRANSLUCENT_KEY,\n value: String(statusBarTranslucent),\n translatable: false,\n }),\n ],\n strings\n );\n}\n"],"mappings":";;;;;;;AAAA,SAAAA,eAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,cAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA,SAAAE,wBAAA;EAAA,MAAAF,IAAA,GAAAC,OAAA;EAAAC,uBAAA,YAAAA,CAAA;IAAA,OAAAF,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA,MAAMG,eAAe,GAAG,gCAAgC;AACxD,MAAMC,0BAA0B,GAAG,2CAA2C;AAEvE,MAAMC,wBAA2D,GAAGA,CAACC,MAAM,EAAEC,KAAK,KAAK;EAC5F,OAAO,IAAAC,+BAAc,EAACF,MAAM,EAAGA,MAAM,IAAK;IACxC,MAAMG,YAAY,GAAG,IAAAC,gDAAsB,EAACJ,MAAM,EAAEC,KAAK,CAAC;IAC1D,IAAIE,YAAY,EAAE;MAChB,MAAM;QAAEE;MAAW,CAAC,GAAGF,YAAY;MACnC,MAAMG,oBAAoB,GAAG,CAAC,CAACN,MAAM,CAACO,gBAAgB,EAAEC,WAAW;MACnER,MAAM,CAACS,UAAU,GAAGC,gBAAgB,CAACV,MAAM,CAACS,UAAU,EAAEJ,UAAU,EAAEC,oBAAoB,CAAC;IAC3F;IACA,OAAON,MAAM;EACf,CAAC,CAAC;AACJ,CAAC;AAACW,OAAA,CAAAZ,wBAAA,GAAAA,wBAAA;AAEK,SAASW,gBAAgBA,CAC9BE,OAA4C,EAC5CP,UAAkB,EAClBC,oBAA6B,EACQ;EACrC,OAAOO,8BAAa,CAACC,OAAO,CAACC,aAAa,CACxC,CACEF,8BAAa,CAACG,SAAS,CAACC,iBAAiB,CAAC;IACxCC,IAAI,EAAErB,eAAe;IACrBsB,KAAK,EAAEd,UAAU;IACjBe,YAAY,EAAE;EAChB,CAAC,CAAC,EACFP,8BAAa,CAACG,SAAS,CAACC,iBAAiB,CAAC;IACxCC,IAAI,EAAEpB,0BAA0B;IAChCqB,KAAK,EAAEE,MAAM,CAACf,oBAAoB,CAAC;IACnCc,YAAY,EAAE;EAChB,CAAC,CAAC,CACH,EACDR,OACF,CAAC;AACH","ignoreList":[]} \ No newline at end of file +{"version":3,"file":"withAndroidSplashStrings.js","names":["_configPlugins","data","require","_getAndroidSplashConfig","RESIZE_MODE_KEY","withAndroidSplashStrings","config","props","withStringsXml","splashConfig","getAndroidSplashConfig","resizeMode","modResults","setSplashStrings","exports","strings","AndroidConfig","Strings","setStringItem","Resources","buildResourceItem","name","value","translatable"],"sources":["../../../../src/plugins/unversioned/expo-splash-screen/withAndroidSplashStrings.ts"],"sourcesContent":["import { AndroidConfig, ConfigPlugin, withStringsXml } from '@expo/config-plugins';\n\nimport { AndroidSplashConfig, getAndroidSplashConfig } from './getAndroidSplashConfig';\n\nconst RESIZE_MODE_KEY = 'expo_splash_screen_resize_mode';\n\nexport const withAndroidSplashStrings: ConfigPlugin = (config, props) => {\n return withStringsXml(config, (config) => {\n const splashConfig = getAndroidSplashConfig(config, props);\n if (splashConfig) {\n const { resizeMode } = splashConfig;\n config.modResults = setSplashStrings(config.modResults, resizeMode);\n }\n return config;\n });\n};\n\nexport function setSplashStrings(\n strings: AndroidConfig.Resources.ResourceXML,\n resizeMode: string\n): AndroidConfig.Resources.ResourceXML {\n return AndroidConfig.Strings.setStringItem(\n [\n AndroidConfig.Resources.buildResourceItem({\n name: RESIZE_MODE_KEY,\n value: resizeMode,\n translatable: false,\n }),\n ],\n strings\n );\n}\n"],"mappings":";;;;;;;AAAA,SAAAA,eAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,cAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA,SAAAE,wBAAA;EAAA,MAAAF,IAAA,GAAAC,OAAA;EAAAC,uBAAA,YAAAA,CAAA;IAAA,OAAAF,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA,MAAMG,eAAe,GAAG,gCAAgC;AAEjD,MAAMC,wBAA2D,GAAGA,CAACC,MAAM,EAAEC,KAAK,KAAK;EAC5F,OAAO,IAAAC,+BAAc,EAACF,MAAM,EAAGA,MAAM,IAAK;IACxC,MAAMG,YAAY,GAAG,IAAAC,gDAAsB,EAACJ,MAAM,EAAEC,KAAK,CAAC;IAC1D,IAAIE,YAAY,EAAE;MAChB,MAAM;QAAEE;MAAW,CAAC,GAAGF,YAAY;MACnCH,MAAM,CAACM,UAAU,GAAGC,gBAAgB,CAACP,MAAM,CAACM,UAAU,EAAED,UAAU,CAAC;IACrE;IACA,OAAOL,MAAM;EACf,CAAC,CAAC;AACJ,CAAC;AAACQ,OAAA,CAAAT,wBAAA,GAAAA,wBAAA;AAEK,SAASQ,gBAAgBA,CAC9BE,OAA4C,EAC5CJ,UAAkB,EACmB;EACrC,OAAOK,8BAAa,CAACC,OAAO,CAACC,aAAa,CACxC,CACEF,8BAAa,CAACG,SAAS,CAACC,iBAAiB,CAAC;IACxCC,IAAI,EAAEjB,eAAe;IACrBkB,KAAK,EAAEX,UAAU;IACjBY,YAAY,EAAE;EAChB,CAAC,CAAC,CACH,EACDR,OACF,CAAC;AACH","ignoreList":[]} \ No newline at end of file diff --git a/packages/@expo/prebuild-config/src/plugins/__tests__/__snapshots__/withDefaultPlugins-test.ts.snap b/packages/@expo/prebuild-config/src/plugins/__tests__/__snapshots__/withDefaultPlugins-test.ts.snap index d200b95d961437..3ed92adcdd65bc 100644 --- a/packages/@expo/prebuild-config/src/plugins/__tests__/__snapshots__/withDefaultPlugins-test.ts.snap +++ b/packages/@expo/prebuild-config/src/plugins/__tests__/__snapshots__/withDefaultPlugins-test.ts.snap @@ -1025,13 +1025,6 @@ exports[`built-in plugins introspects mods 1`] = ` }, "_": "contain", }, - { - "$": { - "name": "expo_splash_screen_status_bar_translucent", - "translatable": "false", - }, - "_": "true", - }, { "$": { "name": "expo_runtime_version", @@ -1961,13 +1954,6 @@ exports[`built-in plugins introspects mods in a managed project 1`] = ` }, "_": "contain", }, - { - "$": { - "name": "expo_splash_screen_status_bar_translucent", - "translatable": "false", - }, - "_": "true", - }, { "$": { "name": "expo_runtime_version", diff --git a/packages/@expo/prebuild-config/src/plugins/unversioned/expo-splash-screen/__tests__/withAndroidSplashStrings-test.ts b/packages/@expo/prebuild-config/src/plugins/unversioned/expo-splash-screen/__tests__/withAndroidSplashStrings-test.ts index b4730364576f06..39212bf643499d 100644 --- a/packages/@expo/prebuild-config/src/plugins/unversioned/expo-splash-screen/__tests__/withAndroidSplashStrings-test.ts +++ b/packages/@expo/prebuild-config/src/plugins/unversioned/expo-splash-screen/__tests__/withAndroidSplashStrings-test.ts @@ -4,11 +4,10 @@ import { setSplashStrings } from '../withAndroidSplashStrings'; describe(setSplashStrings, () => { it('add expo_splash_screen_strings', () => { - const results = setSplashStrings({ resources: {} }, 'cover', false); + const results = setSplashStrings({ resources: {} }, 'cover'); const expectXML = `\ cover - false `; expect(XML.format(results)).toEqual(expectXML); }); @@ -16,13 +15,11 @@ describe(setSplashStrings, () => { it('override old expo_splash_screen_strings', () => { const results = setSplashStrings( { resources: { string: [{ $: { name: 'expo_splash_screen_resize_mode' }, _: 'contain' }] } }, - 'native', - false + 'native' ); const expectXML = `\ native - false `; expect(XML.format(results)).toEqual(expectXML); }); diff --git a/packages/@expo/prebuild-config/src/plugins/unversioned/expo-splash-screen/withAndroidSplashScreen.ts b/packages/@expo/prebuild-config/src/plugins/unversioned/expo-splash-screen/withAndroidSplashScreen.ts index fd3205cce0a53d..2a3a5ca543421a 100644 --- a/packages/@expo/prebuild-config/src/plugins/unversioned/expo-splash-screen/withAndroidSplashScreen.ts +++ b/packages/@expo/prebuild-config/src/plugins/unversioned/expo-splash-screen/withAndroidSplashScreen.ts @@ -1,4 +1,4 @@ -import { ConfigPlugin, WarningAggregator, withPlugins } from '@expo/config-plugins'; +import { ConfigPlugin, withPlugins } from '@expo/config-plugins'; import { AndroidSplashConfig, getAndroidSplashConfig } from './getAndroidSplashConfig'; import { withAndroidSplashDrawables } from './withAndroidSplashDrawables'; @@ -13,23 +13,6 @@ export const withAndroidSplashScreen: ConfigPlugin< const isLegacyConfig = props === undefined; const splashConfig = getAndroidSplashConfig(config, props ?? null); - // Update the android status bar to match the splash screen - // androidStatusBar applies info to the app activity style. - const backgroundColor = splashConfig?.backgroundColor || '#ffffff'; - if (config.androidStatusBar?.backgroundColor) { - if ( - backgroundColor.toLowerCase() !== config.androidStatusBar?.backgroundColor?.toLowerCase?.() - ) { - WarningAggregator.addWarningAndroid( - 'androidStatusBar.backgroundColor', - 'Color conflicts with the splash.backgroundColor' - ); - } - } else { - if (!config.androidStatusBar) config.androidStatusBar = {}; - config.androidStatusBar.backgroundColor = backgroundColor; - } - return withPlugins(config, [ [withAndroidSplashMainActivity, { isLegacyConfig }], [withAndroidSplashImages, splashConfig], diff --git a/packages/@expo/prebuild-config/src/plugins/unversioned/expo-splash-screen/withAndroidSplashStrings.ts b/packages/@expo/prebuild-config/src/plugins/unversioned/expo-splash-screen/withAndroidSplashStrings.ts index ed3164782e1d2f..a1c3d566962030 100644 --- a/packages/@expo/prebuild-config/src/plugins/unversioned/expo-splash-screen/withAndroidSplashStrings.ts +++ b/packages/@expo/prebuild-config/src/plugins/unversioned/expo-splash-screen/withAndroidSplashStrings.ts @@ -3,15 +3,13 @@ import { AndroidConfig, ConfigPlugin, withStringsXml } from '@expo/config-plugin import { AndroidSplashConfig, getAndroidSplashConfig } from './getAndroidSplashConfig'; const RESIZE_MODE_KEY = 'expo_splash_screen_resize_mode'; -const STATUS_BAR_TRANSLUCENT_KEY = 'expo_splash_screen_status_bar_translucent'; export const withAndroidSplashStrings: ConfigPlugin = (config, props) => { return withStringsXml(config, (config) => { const splashConfig = getAndroidSplashConfig(config, props); if (splashConfig) { const { resizeMode } = splashConfig; - const statusBarTranslucent = !!config.androidStatusBar?.translucent; - config.modResults = setSplashStrings(config.modResults, resizeMode, statusBarTranslucent); + config.modResults = setSplashStrings(config.modResults, resizeMode); } return config; }); @@ -19,8 +17,7 @@ export const withAndroidSplashStrings: ConfigPlugin = (conf export function setSplashStrings( strings: AndroidConfig.Resources.ResourceXML, - resizeMode: string, - statusBarTranslucent: boolean + resizeMode: string ): AndroidConfig.Resources.ResourceXML { return AndroidConfig.Strings.setStringItem( [ @@ -29,11 +26,6 @@ export function setSplashStrings( value: resizeMode, translatable: false, }), - AndroidConfig.Resources.buildResourceItem({ - name: STATUS_BAR_TRANSLUCENT_KEY, - value: String(statusBarTranslucent), - translatable: false, - }), ], strings ); diff --git a/packages/expo-image-picker/CHANGELOG.md b/packages/expo-image-picker/CHANGELOG.md index a6dfb75b993b61..a4ba1efa128c53 100644 --- a/packages/expo-image-picker/CHANGELOG.md +++ b/packages/expo-image-picker/CHANGELOG.md @@ -10,6 +10,8 @@ ### 💡 Others +- [android] bump Android-Image-Cropper dependency ([#43433](https://github.com/expo/expo/pull/43433) by [@vonovak](https://github.com/vonovak)) + ## 55.0.9 — 2026-02-25 _This version does not introduce any user-facing changes._ @@ -63,7 +65,7 @@ _This version does not introduce any user-facing changes._ ### 💡 Others -- [Android] Add `android:maxSdkVersion` annotation to `READ_EXTERNAL_STORAGE` and `WRITE_EXTERNAL_STORAGE` permissions. ([#40976](https://github.com/expo/expo/pull/40976) by [@behenate](https://github.com/behenate)) +- [Android] Add `android:maxSdkVersion` annotation to `READ_EXTERNAL_STORAGE` and `WRITE_EXTERNAL_STORAGE` permissions. ([#40976](https://github.com/expo/expo/pull/40976) by [@behenate](https://github.com/behenate)) ## 17.0.9 - 2025-12-05 diff --git a/packages/expo-image-picker/android/build.gradle b/packages/expo-image-picker/android/build.gradle index d8fba3f62ccafc..afb478cdb0e8fa 100644 --- a/packages/expo-image-picker/android/build.gradle +++ b/packages/expo-image-picker/android/build.gradle @@ -22,7 +22,7 @@ dependencies { implementation "androidx.activity:activity-ktx:1.11.0" implementation "androidx.appcompat:appcompat:1.7.1" implementation "androidx.exifinterface:exifinterface:1.4.1" - implementation "com.vanniktech:android-image-cropper:4.6.0" + implementation "com.vanniktech:android-image-cropper:4.7.0" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2" diff --git a/packages/expo-image-picker/android/src/main/java/expo/modules/imagepicker/ImagePickerModule.kt b/packages/expo-image-picker/android/src/main/java/expo/modules/imagepicker/ImagePickerModule.kt index 2accee30be33b9..50663d81d25054 100644 --- a/packages/expo-image-picker/android/src/main/java/expo/modules/imagepicker/ImagePickerModule.kt +++ b/packages/expo-image-picker/android/src/main/java/expo/modules/imagepicker/ImagePickerModule.kt @@ -4,6 +4,7 @@ import android.Manifest import android.content.Context import android.content.Intent import android.content.pm.PackageManager +import android.graphics.Bitmap import android.os.Build import android.os.Bundle import android.os.OperationCanceledException @@ -211,8 +212,12 @@ class ImagePickerModule : Module() { result.data.size == 1 && result.data[0].first == MediaType.IMAGE ) { + val sourceUri = result.data[0].second + val mediaType = getType(context.contentResolver, sourceUri) + val compressFormat = mediaType?.toBitmapCompressFormat() ?: Bitmap.CompressFormat.JPEG + val outputFile = createOutputFile(cacheDirectory, compressFormat.toImageFileExtension()) result = launchPicker { - cropImageLauncher.launch(CropImageContractOptions(result.data[0].second.toString(), options)) + cropImageLauncher.launch(CropImageContractOptions(sourceUri.toString(), options, outputFile, compressFormat)) } } mediaHandler.readExtras(result.data, options) diff --git a/packages/expo-image-picker/android/src/main/java/expo/modules/imagepicker/ImagePickerUtils.kt b/packages/expo-image-picker/android/src/main/java/expo/modules/imagepicker/ImagePickerUtils.kt index ba5891e76367fb..5811f66716a71d 100644 --- a/packages/expo-image-picker/android/src/main/java/expo/modules/imagepicker/ImagePickerUtils.kt +++ b/packages/expo-image-picker/android/src/main/java/expo/modules/imagepicker/ImagePickerUtils.kt @@ -61,12 +61,19 @@ private fun getTypeFromFileUrl(url: String): String? { return extension?.let { MimeTypeMap.getSingleton().getMimeTypeFromExtension(it) } } +/** + * Convert this [File] to [Uri] that might be accessed by 3rd party Activities but don't mask the exception + */ +internal fun File.getContentUri(context: Context): Uri { + return FileProvider.getUriForFile(context, context.packageName + ".ImagePickerFileProvider", this) +} + /** * Convert this [File] to [Uri] that might be accessed by 3rd party Activities, eg. by camera application */ internal fun File.toContentUri(context: Context): Uri { return try { - FileProvider.getUriForFile(context, context.packageName + ".ImagePickerFileProvider", this) + this.getContentUri(context) } catch (e: Exception) { Uri.fromFile(this) } diff --git a/packages/expo-image-picker/android/src/main/java/expo/modules/imagepicker/contracts/CropImageContract.kt b/packages/expo-image-picker/android/src/main/java/expo/modules/imagepicker/contracts/CropImageContract.kt index adc53e463cd906..6337340258f2e7 100644 --- a/packages/expo-image-picker/android/src/main/java/expo/modules/imagepicker/contracts/CropImageContract.kt +++ b/packages/expo-image-picker/android/src/main/java/expo/modules/imagepicker/contracts/CropImageContract.kt @@ -5,7 +5,6 @@ import android.content.Context import android.content.Intent import android.graphics.Bitmap import android.os.Build -import androidx.core.net.toFile import androidx.core.net.toUri import androidx.core.os.bundleOf import com.canhub.cropper.CropImage @@ -15,29 +14,25 @@ import expo.modules.imagepicker.CropShape import expo.modules.imagepicker.ImagePickerOptions import expo.modules.imagepicker.MediaType import expo.modules.imagepicker.copyExifData -import expo.modules.imagepicker.createOutputFile -import expo.modules.imagepicker.toBitmapCompressFormat -import expo.modules.imagepicker.toImageFileExtension +import expo.modules.imagepicker.getContentUri import expo.modules.kotlin.activityresult.AppContextActivityResultContract import expo.modules.kotlin.providers.AppContextProvider import kotlinx.coroutines.runBlocking +import java.io.File import java.io.Serializable internal class CropImageContract( private val appContextProvider: AppContextProvider ) : AppContextActivityResultContract { override fun createIntent(context: Context, input: CropImageContractOptions) = Intent(context, expo.modules.imagepicker.ExpoCropImageActivity::class.java).apply { - val mediaType = expo.modules.imagepicker.getType(context.contentResolver, input.sourceUri.toUri()) - val compressFormat = mediaType?.toBitmapCompressFormat() ?: Bitmap.CompressFormat.JPEG - val cacheDirectory = appContextProvider.appContext.cacheDirectory - val outputUri = createOutputFile(cacheDirectory, compressFormat.toImageFileExtension()).toUri() + val outputUri = input.outputFile.getContentUri(context) putExtra( CropImage.CROP_IMAGE_EXTRA_BUNDLE, bundleOf( CropImage.CROP_IMAGE_EXTRA_SOURCE to input.sourceUri.toUri(), CropImage.CROP_IMAGE_EXTRA_OPTIONS to CropImageOptions().apply { - outputCompressFormat = compressFormat + outputCompressFormat = input.compressFormat outputCompressQuality = (input.options.quality * 100).toInt() this.customOutputUri = outputUri @@ -70,12 +65,14 @@ internal class CropImageContract( } val targetUri = requireNotNull(result.uriContent) val contentResolver = requireNotNull(appContextProvider.appContext.reactContext) { "React Application Context is null" }.contentResolver - runBlocking { copyExifData(input.sourceUri.toUri(), targetUri.toFile(), contentResolver) } + runBlocking { copyExifData(input.sourceUri.toUri(), input.outputFile, contentResolver) } return ImagePickerContractResult.Success(listOf(MediaType.IMAGE to targetUri)) } } internal data class CropImageContractOptions( val sourceUri: String, - val options: ImagePickerOptions + val options: ImagePickerOptions, + val outputFile: File, + val compressFormat: Bitmap.CompressFormat ) : Serializable diff --git a/packages/expo-widgets/CHANGELOG.md b/packages/expo-widgets/CHANGELOG.md index 987a7d6cb720ef..be80e059d806fa 100644 --- a/packages/expo-widgets/CHANGELOG.md +++ b/packages/expo-widgets/CHANGELOG.md @@ -8,6 +8,8 @@ ### 🐛 Bug fixes +- Add missing project root to `watchFolders` in `metro.config.js` ([#43449](https://github.com/expo/expo/pull/43449) by [@kitten](https://github.com/kitten)) + ### 💡 Others ## 55.0.1 — 2026-02-25 diff --git a/packages/expo-widgets/metro.config.js b/packages/expo-widgets/metro.config.js index f3f36024218241..e6ecf59380aeff 100644 --- a/packages/expo-widgets/metro.config.js +++ b/packages/expo-widgets/metro.config.js @@ -1,19 +1,26 @@ const { getDefaultConfig } = require('expo/metro-config'); const path = require('path'); -const config = getDefaultConfig(process.cwd()); +const projectRoot = process.cwd(); +const config = getDefaultConfig(projectRoot); const expoStubPath = path.resolve(__dirname, './bundle/expo-module-stub.ts'); const reactStubPath = path.resolve(__dirname, './bundle/react-stub.ts'); const jsxRuntimeStubPath = path.resolve(__dirname, './bundle/jsx-runtime-stub.ts'); +// The `projectRoot` won't be included by default, since we alter it to be `__dirname` +// to bundle from `expo-widgets` as the main module +// NOTE: We check the `watchFolders` to start with `projectRoot`, since `expo/metro-config` +// might add folders if we're in a monorepo +const watchFolders = config.watchFolders; +if (!watchFolders.some((entry) => !entry.startsWith(projectRoot))) { + watchFolders.push(projectRoot); +} + const buildConfig = { ...config, - projectRoot: __dirname, - watchFolders: [ - ...config.watchFolders, - __dirname, - ], + projectRoot: __dirname, // Override root to be expo-widgets + watchFolders, resolver: { ...config.resolver, resolveRequest(context, moduleName, platform) {