Add UiModeUtils.isDarkMode helper (#51925)

Summary:
This PR is part of the [edge-to-edge core implementation effort](https://github.com/facebook/react-native/pull/47554). It adds a helper to `ContextUtils`, called `isDarkMode` in order to be reused accross the Android codebase.

## Changelog:

- [Internal] [Added] - Add `UiModeUtils.isDarkMode` helper

Pull Request resolved: https://github.com/facebook/react-native/pull/51925

Test Plan:
<img width="300" alt="Screenshot 2025-06-10 at 17 50 19" src="https://github.com/user-attachments/assets/48795406-e852-486a-bae8-54507ad769ee" />

<img width="300" alt="Screenshot 2025-06-10 at 17 50 42" src="https://github.com/user-attachments/assets/0dbdece9-04f7-487b-ace8-4786c8da381d" />

Rollback Plan:

Reviewed By: cortinico

Differential Revision: D76352849

Pulled By: alanleedev

fbshipit-source-id: fbbc772d1dfa3e30e62a71a711de11b85cdec446
This commit is contained in:
Mathieu Acthernoene
2025-06-16 10:35:35 -07:00
committed by Facebook GitHub Bot
parent 8174d02811
commit 3c17e101ee
3 changed files with 30 additions and 12 deletions
@@ -8,13 +8,13 @@
package com.facebook.react.modules.appearance
import android.content.Context
import android.content.res.Configuration
import androidx.appcompat.app.AppCompatDelegate
import com.facebook.fbreact.specs.NativeAppearanceSpec
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.UiThreadUtil
import com.facebook.react.bridge.buildReadableMap
import com.facebook.react.module.annotations.ReactModule
import com.facebook.react.views.common.UiModeUtils
/** Module that exposes the user's preferred color scheme. */
@ReactModule(name = NativeAppearanceSpec.NAME)
@@ -41,13 +41,7 @@ constructor(
return overrideColorScheme.getScheme()
}
val currentNightMode =
context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
return when (currentNightMode) {
Configuration.UI_MODE_NIGHT_NO -> "light"
Configuration.UI_MODE_NIGHT_YES -> "dark"
else -> "light"
}
return if (UiModeUtils.isDarkMode(context)) "dark" else "light"
}
public override fun getColorScheme(): String {
@@ -0,0 +1,26 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.views.common
import android.content.Context
import android.content.res.Configuration
/** Utility object providing static methods for working with UI mode properties from Context. */
internal object UiModeUtils {
/**
* Determines whether the current UI mode is dark mode
*
* @param context The context to check the UI mode from
* @return true if the current UI mode is dark mode, false otherwise
*/
@JvmStatic
fun isDarkMode(context: Context): Boolean =
context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK ==
Configuration.UI_MODE_NIGHT_YES
}
@@ -7,7 +7,6 @@
package com.facebook.react.views.view
import android.content.res.Configuration
import android.graphics.Color
import android.os.Build
import android.view.Window
@@ -15,6 +14,7 @@ import android.view.WindowManager
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsControllerCompat
import com.facebook.react.views.common.UiModeUtils
@Suppress("DEPRECATION")
internal fun Window.setStatusBarTranslucency(isTranslucent: Boolean) {
@@ -71,9 +71,7 @@ internal fun Window.setSystemBarsTranslucency(isTranslucent: Boolean) {
WindowCompat.setDecorFitsSystemWindows(this, !isTranslucent)
if (isTranslucent) {
val isDarkMode =
context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK ==
Configuration.UI_MODE_NIGHT_YES
val isDarkMode = UiModeUtils.isDarkMode(context)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
isStatusBarContrastEnforced = false