From a397d330a4cf7e08095faa0e751e38d5106ed5c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ramos?= Date: Sat, 31 Aug 2019 10:02:21 -0700 Subject: [PATCH] Support light and dark themes in RNTester Summary: Initial conversion of RNTester to support light and dark themes. Theming is implemented by providing the desired color theme via context. Example: ``` const ThemedContainer = props => ( {theme => { return ( {props.children} ); }} ); ``` As RNTester's design follows the base iOS system appearance, I've chosen light and dark themes based on the actual iOS 13 semantic colors. The themes are RNTester-specific, however, and we'd expect individual apps to build their own color palettes. ## Examples The new Appearance Examples screen demonstrates how context can be used to force a theme. It also displays the list of colors in each RNTester theme. https://pxl.cl/HmzW (screenshot: Appearance Examples screen on RNTester with Dark Mode enabled. Displays useColorScheme hook, and context examples.) https://pxl.cl/HmB3 (screenshot: Same screen, with light and dark RNTester themes visible) Theming support in this diff mostly focused on the main screen and the Dark Mode examples screen. This required updating the components used by most of the examples, as you can see in this Image example: https://pxl.cl/H0Hv (screenshot: Image Examples screen in Dark Mode theme) Note that I have yet to go through every single example screen to update it. There's individual cases, such as the FlatList example screen, that are not fully converted to use a dark theme when appropriate. This can be taken care later as it's non-blocking. Reviewed By: zackargyle Differential Revision: D16681909 fbshipit-source-id: e47484d4b3f0963ef0cc3d8aff8ce3e9051ddbae --- .../FBReactNativeSpec-generated.mm | 12 +- .../FBReactNativeSpec/FBReactNativeSpec.h | 14 +- RNTester/js/RNTesterApp.ios.js | 87 +++++--- RNTester/js/components/RNTesterBlock.js | 51 +++-- .../js/components/RNTesterExampleFilter.js | 52 +++-- RNTester/js/components/RNTesterExampleList.js | 146 +++++++++---- RNTester/js/components/RNTesterPage.js | 27 ++- RNTester/js/components/RNTesterTheme.js | 88 ++++++++ RNTester/js/components/RNTesterTitle.js | 24 ++- .../examples/Appearance/AppearanceExample.js | 201 ++++++++++++++++++ RNTester/js/examples/Button/ButtonExample.js | 77 ++++--- RNTester/js/utils/RNTesterActions.js | 20 +- RNTester/js/utils/RNTesterList.ios.js | 5 + .../js/utils/RNTesterNavigationReducer.js | 17 ++ 14 files changed, 663 insertions(+), 158 deletions(-) create mode 100644 RNTester/js/components/RNTesterTheme.js create mode 100644 RNTester/js/examples/Appearance/AppearanceExample.js diff --git a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm index 2104b1dbfef..bf8bfae08a4 100644 --- a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm +++ b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm @@ -487,6 +487,12 @@ namespace facebook { } // namespace react } // namespace facebook +@implementation RCTCxxConvert (NativeAppearance_AppearancePreferences) ++ (RCTManagedPointer *)JS_NativeAppearance_AppearancePreferences:(id)json +{ + return facebook::react::managedPointer(json); +} +@end folly::Optional NSStringToNativeAppearanceColorSchemeName(NSString *value) { static NSDictionary *dict = nil; static dispatch_once_t onceToken; @@ -510,12 +516,6 @@ NSString *NativeAppearanceColorSchemeNameToNSString(folly::Optional(json); -} -@end @implementation RCTCxxConvert (NativeAsyncStorage_SpecMultiGetCallbackErrorsElement) + (RCTManagedPointer *)JS_NativeAsyncStorage_SpecMultiGetCallbackErrorsElement:(id)json { diff --git a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h index a5561e3bcce..7548c6ced56 100644 --- a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h +++ b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h @@ -452,13 +452,6 @@ namespace facebook { }; } // namespace react } // namespace facebook -typedef NS_ENUM(NSInteger, NativeAppearanceColorSchemeName) { - NativeAppearanceColorSchemeNameLight = 0, - NativeAppearanceColorSchemeNameDark, -}; - -folly::Optional NSStringToNativeAppearanceColorSchemeName(NSString *value); -NSString *NativeAppearanceColorSchemeNameToNSString(folly::Optional value); namespace JS { namespace NativeAppearance { @@ -475,6 +468,13 @@ namespace JS { @interface RCTCxxConvert (NativeAppearance_AppearancePreferences) + (RCTManagedPointer *)JS_NativeAppearance_AppearancePreferences:(id)json; @end +typedef NS_ENUM(NSInteger, NativeAppearanceColorSchemeName) { + NativeAppearanceColorSchemeNameLight = 0, + NativeAppearanceColorSchemeNameDark, +}; + +folly::Optional NSStringToNativeAppearanceColorSchemeName(NSString *value); +NSString *NativeAppearanceColorSchemeNameToNSString(folly::Optional value); namespace JS { namespace NativeAsyncStorage { diff --git a/RNTester/js/RNTesterApp.ios.js b/RNTester/js/RNTesterApp.ios.js index 646b33920c9..1a333589a39 100644 --- a/RNTester/js/RNTesterApp.ios.js +++ b/RNTester/js/RNTesterApp.ios.js @@ -20,11 +20,13 @@ const SnapshotViewIOS = require('./examples/Snapshot/SnapshotViewIOS.ios'); const URIActionMap = require('./utils/URIActionMap'); const { + Appearance, AppRegistry, AsyncStorage, BackHandler, Button, Linking, + Platform, SafeAreaView, StyleSheet, Text, @@ -35,6 +37,7 @@ const { import type {RNTesterExample} from './types/RNTesterTypes'; import type {RNTesterAction} from './utils/RNTesterActions'; import type {RNTesterNavigationState} from './utils/RNTesterNavigationReducer'; +import {RNTesterThemeContext, themes} from './components/RNTesterTheme'; type Props = { exampleFromAppetizeParams?: ?string, @@ -47,18 +50,40 @@ YellowBox.ignoreWarnings([ const APP_STATE_KEY = 'RNTesterAppState.v2'; const Header = ({onBack, title}: {onBack?: () => mixed, title: string}) => ( - - - - {title} - - {onBack && ( - -