/** * 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. * * @format * @flow strict-local */ import NativeEventEmitter from '../EventEmitter/NativeEventEmitter'; import Platform from '../Utilities/Platform'; import EventEmitter, { type EventSubscription, } from '../vendor/emitter/EventEmitter'; import {isAsyncDebugging} from './DebugEnvironment'; import NativeAppearance, { type AppearancePreferences, type ColorSchemeName, } from './NativeAppearance'; import invariant from 'invariant'; type AppearanceListener = (preferences: AppearancePreferences) => void; const eventEmitter = new EventEmitter<{ change: [AppearancePreferences], }>(); type NativeAppearanceEventDefinitions = { appearanceChanged: [AppearancePreferences], }; if (NativeAppearance) { const nativeEventEmitter = new NativeEventEmitter( // T88715063: NativeEventEmitter only used this parameter on iOS. Now it uses it on all platforms, so this code was modified automatically to preserve its behavior // If you want to use the native module on other platforms, please remove this condition and test its behavior Platform.OS !== 'ios' ? null : NativeAppearance, ); nativeEventEmitter.addListener( 'appearanceChanged', (newAppearance: AppearancePreferences) => { const {colorScheme} = newAppearance; invariant( colorScheme === 'dark' || colorScheme === 'light' || colorScheme == null, "Unrecognized color scheme. Did you mean 'dark' or 'light'?", ); eventEmitter.emit('change', {colorScheme}); }, ); } module.exports = { /** * Note: Although color scheme is available immediately, it may change at any * time. Any rendering logic or styles that depend on this should try to call * this function on every render, rather than caching the value (for example, * using inline styles rather than setting a value in a `StyleSheet`). * * Example: `const colorScheme = Appearance.getColorScheme();` * * @returns {?ColorSchemeName} Value for the color scheme preference. */ getColorScheme(): ?ColorSchemeName { if (__DEV__) { if (isAsyncDebugging) { // Hard code light theme when using the async debugger as // sync calls aren't supported return 'light'; } } // TODO: (hramos) T52919652 Use ?ColorSchemeName once codegen supports union const nativeColorScheme: ?string = NativeAppearance == null ? null : NativeAppearance.getColorScheme() || null; invariant( nativeColorScheme === 'dark' || nativeColorScheme === 'light' || nativeColorScheme == null, "Unrecognized color scheme. Did you mean 'dark' or 'light'?", ); return nativeColorScheme; }, setColorScheme(colorScheme: ?ColorSchemeName): void { const nativeColorScheme = colorScheme == null ? 'unspecified' : colorScheme; invariant( colorScheme === 'dark' || colorScheme === 'light' || colorScheme == null, "Unrecognized color scheme. Did you mean 'dark', 'light' or null?", ); if (NativeAppearance != null && NativeAppearance.setColorScheme != null) { NativeAppearance.setColorScheme(nativeColorScheme); } }, /** * Add an event handler that is fired when appearance preferences change. */ addChangeListener(listener: AppearanceListener): EventSubscription { return eventEmitter.addListener('change', listener); }, };