Appearance.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /**
  2. * Copyright (c) Facebook, Inc. and its affiliates.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. *
  7. * @format
  8. * @flow
  9. */
  10. 'use strict';
  11. import EventEmitter from '../vendor/emitter/EventEmitter';
  12. import NativeEventEmitter from '../EventEmitter/NativeEventEmitter';
  13. import NativeAppearance, {
  14. type AppearancePreferences,
  15. type ColorSchemeName,
  16. } from './NativeAppearance';
  17. import invariant from 'invariant';
  18. import {isAsyncDebugging} from './DebugEnvironment';
  19. type AppearanceListener = (preferences: AppearancePreferences) => void;
  20. const eventEmitter = new EventEmitter();
  21. if (NativeAppearance) {
  22. const nativeEventEmitter = new NativeEventEmitter(NativeAppearance);
  23. nativeEventEmitter.addListener(
  24. 'appearanceChanged',
  25. (newAppearance: AppearancePreferences) => {
  26. const {colorScheme} = newAppearance;
  27. invariant(
  28. colorScheme === 'dark' ||
  29. colorScheme === 'light' ||
  30. colorScheme == null,
  31. "Unrecognized color scheme. Did you mean 'dark' or 'light'?",
  32. );
  33. eventEmitter.emit('change', {colorScheme});
  34. },
  35. );
  36. }
  37. module.exports = {
  38. /**
  39. * Note: Although color scheme is available immediately, it may change at any
  40. * time. Any rendering logic or styles that depend on this should try to call
  41. * this function on every render, rather than caching the value (for example,
  42. * using inline styles rather than setting a value in a `StyleSheet`).
  43. *
  44. * Example: `const colorScheme = Appearance.getColorScheme();`
  45. *
  46. * @returns {?ColorSchemeName} Value for the color scheme preference.
  47. */
  48. getColorScheme(): ?ColorSchemeName {
  49. if (__DEV__) {
  50. if (isAsyncDebugging) {
  51. // Hard code light theme when using the async debugger as
  52. // sync calls aren't supported
  53. return 'light';
  54. }
  55. }
  56. // TODO: (hramos) T52919652 Use ?ColorSchemeName once codegen supports union
  57. const nativeColorScheme: ?string =
  58. NativeAppearance == null
  59. ? null
  60. : NativeAppearance.getColorScheme() || null;
  61. invariant(
  62. nativeColorScheme === 'dark' ||
  63. nativeColorScheme === 'light' ||
  64. nativeColorScheme == null,
  65. "Unrecognized color scheme. Did you mean 'dark' or 'light'?",
  66. );
  67. return nativeColorScheme;
  68. },
  69. /**
  70. * Add an event handler that is fired when appearance preferences change.
  71. */
  72. addChangeListener(listener: AppearanceListener): void {
  73. eventEmitter.addListener('change', listener);
  74. },
  75. /**
  76. * Remove an event handler.
  77. */
  78. removeChangeListener(listener: AppearanceListener): void {
  79. eventEmitter.removeListener('change', listener);
  80. },
  81. };