From 8c4aa49bc6a9a13b2ce25dff8c4d0965b8c545df Mon Sep 17 00:00:00 2001 From: Dexter Crowley Date: Thu, 27 Jun 2019 17:13:28 -0700 Subject: [PATCH 1/9] Enable High Contrast Events --- vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp | 44 +++++- vnext/ReactUWP/Modules/AppThemeModuleUwp.h | 11 +- .../Modules/AppThemeModule.cpp | 12 ++ .../ReactWindowsCore/Modules/AppThemeModule.h | 2 + vnext/src/Libraries/AppTheme/AppTheme.ts | 19 +++ vnext/src/Libraries/AppTheme/AppTheme.uwp.ts | 65 +++++++++ .../AppTheme/__mocks__/AppTheme.uwp.ts | 0 .../Libraries/Modules/AppTheme/AppTheme.ts | 14 -- .../Modules/AppTheme/AppTheme.uwp.ts | 37 ----- vnext/src/RNTester/AccessibilityExample.tsx | 130 +++++++++--------- vnext/src/RNTester/ThemingExample.uwp.tsx | 55 ++++++++ vnext/src/index.ts | 2 +- vnext/src/index.uwp.ts | 2 +- 13 files changed, 273 insertions(+), 120 deletions(-) create mode 100644 vnext/src/Libraries/AppTheme/AppTheme.ts create mode 100644 vnext/src/Libraries/AppTheme/AppTheme.uwp.ts rename vnext/src/Libraries/{Modules => }/AppTheme/__mocks__/AppTheme.uwp.ts (100%) delete mode 100644 vnext/src/Libraries/Modules/AppTheme/AppTheme.ts delete mode 100644 vnext/src/Libraries/Modules/AppTheme/AppTheme.uwp.ts create mode 100644 vnext/src/RNTester/ThemingExample.uwp.tsx diff --git a/vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp b/vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp index 56afded3dd4..52f138fa9b3 100644 --- a/vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp +++ b/vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp @@ -26,6 +26,17 @@ AppTheme::AppTheme(const std::shared_ptr& reactInstance, const s , m_queueThread(defaultQueueThread) { m_currentTheme = winrt::Application::Current().RequestedTheme(); + m_isHighContrast = m_accessibilitySettings.HighContrast(); + m_RGBValues = getHighContrastRGBValues(); + + m_highContrastChangedRevoker = m_accessibilitySettings.HighContrastChanged(winrt::auto_revoke, + [this](const auto&, const auto&) { + + folly::dynamic eventData = folly::dynamic::object("highContrastRGBValues", getHighContrastRGBValues()) + ("isHighContrast", getIsHighContrast()); + + fireEvent("highContrastChanged", std::move(eventData)); + }); m_colorValuesChangedRevoker = m_uiSettings.ColorValuesChanged(winrt::auto_revoke, [this](const auto&, const auto&) { @@ -43,6 +54,33 @@ AppTheme::AppTheme(const std::shared_ptr& reactInstance, const s }); } +// Returns the RBG values for the 8 relevant High Contrast elements. +folly::dynamic AppTheme::getHighContrastRGBValues() { + winrt::Windows::UI::Color ButtonFaceColor = m_uiSettings.UIElementColor(winrt::Windows::UI::ViewManagement::UIElementType::ButtonFace); + winrt::Windows::UI::Color ButtonTextColor = m_uiSettings.UIElementColor(winrt::Windows::UI::ViewManagement::UIElementType::ButtonText); + winrt::Windows::UI::Color GrayTextColor = m_uiSettings.UIElementColor(winrt::Windows::UI::ViewManagement::UIElementType::GrayText); + winrt::Windows::UI::Color HighlightColor = m_uiSettings.UIElementColor(winrt::Windows::UI::ViewManagement::UIElementType::Highlight); + winrt::Windows::UI::Color HighlightTextColor = m_uiSettings.UIElementColor(winrt::Windows::UI::ViewManagement::UIElementType::HighlightText); + winrt::Windows::UI::Color HotlightColor = m_uiSettings.UIElementColor(winrt::Windows::UI::ViewManagement::UIElementType::Hotlight); + winrt::Windows::UI::Color WindowColor = m_uiSettings.UIElementColor(winrt::Windows::UI::ViewManagement::UIElementType::Window); + winrt::Windows::UI::Color WindowTextColor = m_uiSettings.UIElementColor(winrt::Windows::UI::ViewManagement::UIElementType::WindowText); + folly::dynamic rbgValues = folly::dynamic::object("ButtonFaceRGB", formatRGB(ButtonFaceColor)) + ("ButtonTextRGB", formatRGB(ButtonTextColor)) + ("GrayTextRGB", formatRGB(GrayTextColor)) + ("HighlightRGB", formatRGB(HighlightColor)) + ("HighlightTextRGB", formatRGB(HighlightTextColor)) + ("HotlightRGB", formatRGB(HotlightColor)) + ("WindowRGB", formatRGB(WindowColor)) + ("WindowTextRGB", formatRGB(WindowTextColor)); + return rbgValues; +} + +std::string AppTheme::formatRGB(winrt::Windows::UI::Color ElementColor) { + std::stringstream RGBString; + RGBString << "#" << std::setfill('0') << std::setw(3) << (int)ElementColor.R << std::setfill('0') << std::setw(3) << (int)ElementColor.G << std::setfill('0') << std::setw(3) << (int)ElementColor.B; + return RGBString.str(); +} + AppTheme::~AppTheme() = default; const std::string AppTheme::getCurrentTheme() @@ -50,6 +88,11 @@ const std::string AppTheme::getCurrentTheme() return m_currentTheme == winrt::ApplicationTheme::Light ? AppTheme::light : AppTheme::dark; } +bool AppTheme::getIsHighContrast() +{ + return m_accessibilitySettings.HighContrast();; +} + void AppTheme::fireEvent(std::string const& eventName, folly::dynamic&& eventData) { if (auto instance = m_wkReactInstance.lock()) @@ -57,5 +100,4 @@ void AppTheme::fireEvent(std::string const& eventName, folly::dynamic&& eventDat instance->CallJsFunction("RCTDeviceEventEmitter", "emit", folly::dynamic::array(eventName, std::move(eventData))); } } - } } // namespace react::uwp diff --git a/vnext/ReactUWP/Modules/AppThemeModuleUwp.h b/vnext/ReactUWP/Modules/AppThemeModuleUwp.h index 075ae73fe27..6d9aa1efa9c 100644 --- a/vnext/ReactUWP/Modules/AppThemeModuleUwp.h +++ b/vnext/ReactUWP/Modules/AppThemeModuleUwp.h @@ -4,11 +4,8 @@ #pragma once #include - #include - #include - #include namespace react { namespace uwp { @@ -20,15 +17,23 @@ class AppTheme : public react::windows::AppTheme virtual ~AppTheme(); const std::string getCurrentTheme() override; + bool getIsHighContrast() override; private: + // RGB helper methods + folly::dynamic getHighContrastRGBValues(); + std::string formatRGB(winrt::Windows::UI::Color ElementColor); + void fireEvent(std::string const& eventName, folly::dynamic&& eventData); std::weak_ptr m_wkReactInstance; std::shared_ptr m_queueThread; winrt::Windows::UI::Xaml::ApplicationTheme m_currentTheme{ winrt::Windows::UI::Xaml::ApplicationTheme::Light }; + bool m_isHighContrast; + folly::dynamic m_RGBValues; winrt::Windows::UI::ViewManagement::AccessibilitySettings m_accessibilitySettings{ }; + winrt::Windows::UI::ViewManagement::AccessibilitySettings::HighContrastChanged_revoker m_highContrastChangedRevoker{ }; winrt::Windows::UI::ViewManagement::UISettings m_uiSettings{ }; winrt::Windows::UI::ViewManagement::UISettings::ColorValuesChanged_revoker m_colorValuesChangedRevoker{ }; }; diff --git a/vnext/ReactWindowsCore/Modules/AppThemeModule.cpp b/vnext/ReactWindowsCore/Modules/AppThemeModule.cpp index 92632babd1d..0accbb5e82e 100644 --- a/vnext/ReactWindowsCore/Modules/AppThemeModule.cpp +++ b/vnext/ReactWindowsCore/Modules/AppThemeModule.cpp @@ -19,6 +19,16 @@ const std::string AppTheme::getCurrentTheme() return AppTheme::light; } +bool AppTheme::getIsHighContrast() +{ + return false; +} + +folly::dynamic AppTheme::getHighContrastRGBValues() +{ + return folly::dynamic::object("highContrastRGBValues", "None"); +} + // // AppThemeModule // @@ -32,6 +42,8 @@ auto AppThemeModule::getConstants() -> std::map { return { { "initialAppTheme", folly::dynamic { m_appTheme->getCurrentTheme() } } + { "isHighContrast", folly::dynamic { m_appTheme->getIsHighContrast() }}, + { "highContrastRGBValues", folly::dynamic {m_appTheme->getHighContrastRGBValues()}} }; } diff --git a/vnext/ReactWindowsCore/Modules/AppThemeModule.h b/vnext/ReactWindowsCore/Modules/AppThemeModule.h index 8990961366b..1b28b503931 100644 --- a/vnext/ReactWindowsCore/Modules/AppThemeModule.h +++ b/vnext/ReactWindowsCore/Modules/AppThemeModule.h @@ -19,6 +19,8 @@ class AppTheme virtual ~AppTheme(); virtual const std::string getCurrentTheme(); + virtual bool getIsHighContrast(); + virtual folly::dynamic getHighContrastRGBValues(); }; class AppThemeModule : public facebook::xplat::module::CxxModule diff --git a/vnext/src/Libraries/AppTheme/AppTheme.ts b/vnext/src/Libraries/AppTheme/AppTheme.ts new file mode 100644 index 00000000000..1b35b44ce5c --- /dev/null +++ b/vnext/src/Libraries/AppTheme/AppTheme.ts @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +export interface IRGBValues { + ButtonFaceRGB: string; + ButtonTextRGB: string; + GrayTextRGB: string; + HighlightRGB: string; + HighlightTextRGB: string; + HotlightRGB: string; + WindowRGB: string; + WindowTextRGB: string; +} + +export interface IAppThemeChangedEvent { + isHighContrast: boolean; + highContrastRGBValues: IRGBValues; + currentTheme: string; +} \ No newline at end of file diff --git a/vnext/src/Libraries/AppTheme/AppTheme.uwp.ts b/vnext/src/Libraries/AppTheme/AppTheme.uwp.ts new file mode 100644 index 00000000000..597355f4d59 --- /dev/null +++ b/vnext/src/Libraries/AppTheme/AppTheme.uwp.ts @@ -0,0 +1,65 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +'use strict'; + +import { NativeEventEmitter, NativeModules } from 'react-native'; +const MissingNativeEventEmitterShim = require('MissingNativeEventEmitterShim'); +import { IAppThemeChangedEvent, IRGBValues } from './AppTheme'; + +const NativeAppTheme = NativeModules.RTCAppTheme; + +class AppThemeModule extends NativeEventEmitter { + public isAvailable: boolean; + private _isHighContrast: boolean; + private _currentTheme: string; + private _highContrastRGBValues: IRGBValues; + + constructor() { + super(NativeAppTheme); + this.isAvailable = true; + + this._highContrastRGBValues = NativeAppTheme.highContrastRGBValues; + /* + {ButtonFaceRGB: ThemingNative.highContrastRGBValues.ButtonFaceRGB, + ButtonTextRGB: ThemingNative.highContrastRGBValues.ButtonTextRGB, + GrayTextRGB: ThemingNative.highContrastRGBValues.GrayTextRGB, + HighlightRGB: ThemingNative.highContrastRGBValues.HighlightRGB, + HighlightTextRGB: ThemingNative.highContrastRGBValues.HighlightTextRGB, + HotlightRGB: ThemingNative.highContrastRGBValues.HotlightRGB, + WindowRGB: ThemingNative.highContrastRGBValues.WindowRGB, + WindowTextRGB: ThemingNative.highContrastRGBValues.WindowTextRGB};*/ + + this._isHighContrast = NativeAppTheme.isHighContrast; + this.addListener('highContrastChanged', (nativeEvent: IAppThemeChangedEvent) => { + this._isHighContrast = nativeEvent.isHighContrast; + this._highContrastRGBValues = nativeEvent.highContrastRGBValues; + }); + + this._currentTheme = NativeAppTheme.initialAppTheme; + this.addListener('appThemeChanged', ({currentTheme}:{currentTheme: string}) => { + this._currentTheme = currentTheme; + }); + } + + get currentTheme(): string { + return this._currentTheme; + } + + get isHighContrast(): boolean { + return this._isHighContrast; + } + + get currentRGBValues(): IRGBValues { + return this._highContrastRGBValues; + } +} + +// This module depends on the native `RCTAppTheme` module. If you don't include it, +// `AppTheme.isAvailable` will return `false`, and any method calls will throw. +class MissingNativeAppThemeShim extends MissingNativeEventEmitterShim { + public isAvailable = false; + public currentTheme = ''; +} + +export const AppTheme = (NativeAppTheme ? new AppThemeModule() : new MissingNativeAppThemeShim()); +export default AppTheme; \ No newline at end of file diff --git a/vnext/src/Libraries/Modules/AppTheme/__mocks__/AppTheme.uwp.ts b/vnext/src/Libraries/AppTheme/__mocks__/AppTheme.uwp.ts similarity index 100% rename from vnext/src/Libraries/Modules/AppTheme/__mocks__/AppTheme.uwp.ts rename to vnext/src/Libraries/AppTheme/__mocks__/AppTheme.uwp.ts diff --git a/vnext/src/Libraries/Modules/AppTheme/AppTheme.ts b/vnext/src/Libraries/Modules/AppTheme/AppTheme.ts deleted file mode 100644 index 078bd1d962c..00000000000 --- a/vnext/src/Libraries/Modules/AppTheme/AppTheme.ts +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -'use strict'; - -import { NativeEventEmitter } from 'react-native'; - -class AppThemeModule extends NativeEventEmitter { - get currentTheme(): string { - return ''; - } -} - -export const AppTheme = new AppThemeModule(); -export default AppTheme; \ No newline at end of file diff --git a/vnext/src/Libraries/Modules/AppTheme/AppTheme.uwp.ts b/vnext/src/Libraries/Modules/AppTheme/AppTheme.uwp.ts deleted file mode 100644 index 403d0a3ee1b..00000000000 --- a/vnext/src/Libraries/Modules/AppTheme/AppTheme.uwp.ts +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -'use strict'; - -import { NativeEventEmitter, NativeModules } from 'react-native'; -const MissingNativeEventEmitterShim = require('MissingNativeEventEmitterShim'); - -const NativeAppTheme = NativeModules.RTCAppTheme; - -class AppThemeModule extends NativeEventEmitter { - public isAvailable: boolean; - private _currentTheme: string; - - constructor() { - super(NativeAppTheme); - this.isAvailable = true; - - this._currentTheme = NativeAppTheme.initialAppTheme; - this.addListener('appThemeChanged', ({currentTheme}:{currentTheme: string}) => { - this._currentTheme = currentTheme; - }); - } - - get currentTheme(): string { - return this._currentTheme; - } -} - -// This module depends on the native `RCTAppTheme` module. If you don't include it, -// `AppTheme.isAvailable` will return `false`, and any method calls will throw. -class MissingNativeAppThemeShim extends MissingNativeEventEmitterShim { - public isAvailable = false; - public currentTheme = ''; -} - -export const AppTheme = (NativeAppTheme ? new AppThemeModule() : new MissingNativeAppThemeShim()); -export default AppTheme; \ No newline at end of file diff --git a/vnext/src/RNTester/AccessibilityExample.tsx b/vnext/src/RNTester/AccessibilityExample.tsx index b540c901d7e..e419f42970d 100644 --- a/vnext/src/RNTester/AccessibilityExample.tsx +++ b/vnext/src/RNTester/AccessibilityExample.tsx @@ -4,7 +4,11 @@ /* tslint:disable */ import React = require('react'); -import { FlatList, Text, TouchableHighlight, View } from 'react-native'; +import { Text, TouchableHighlight, View } from 'react-native'; +import { AppTheme } from '../../src/index.uwp'; +import { IAppThemeChangedEvent } from 'src/Libraries/AppTheme/AppTheme'; + +var currentBackgroundColor = ['blue', 'red', '#E6E6E6', '#7fff00']; class AccessibilityBaseExample extends React.Component { public render() { @@ -12,13 +16,68 @@ class AccessibilityBaseExample extends React.Component { The following has accessibilityLabel and accessibilityHint: The following has accessible and accessibilityLabel: + + ); + } +} + +class HighContrastExample extends React.Component { + state = { + isHighContrast: AppTheme.isHighContrast, + RGBValues: AppTheme.currentRGBValues, + currentTheme: AppTheme.currentTheme + }; + + componentDidMount() { + AppTheme.addListener('highContrastChanged', this.onHighContrastChanged); + AppTheme.addListener('appThemeChanged', this.onAppThemeChanged); + } + + componenetWillUnmount() { + AppTheme.removeListener('highContrastChanged', this.onHighContrastChanged); + AppTheme.removeListener('appThemeChanged', this.onAppThemeChanged); + } + + // TODO: Make args props + onHighContrastChanged = (event: IAppThemeChangedEvent) => { + this.setState({isHighContrast : AppTheme.isHighContrast, + RGBValues : AppTheme.currentRGBValues}); + }; + + onAppThemeChanged = (event: any) => { + this.setState({currentTheme : AppTheme.currentTheme}); + } + + public render() { + return ( + + The following has HighContrast Event awareness: + + isHighContrast: {this.state.isHighContrast ? 'true' : 'false'} + + ButtonFaceRGB value: {this.state.RGBValues.ButtonFaceRGB} + ButtonTextRGB value: {this.state.RGBValues.ButtonTextRGB} + GrayTextRGB value: {this.state.RGBValues.GrayTextRGB} + HighlightRGB value: {this.state.RGBValues.HighlightRGB} + HighlightTextRGB value: {this.state.RGBValues.HighlightTextRGB} + HotlightRGB value: {this.state.RGBValues.HotlightRGB} + WindowRGB value: {this.state.RGBValues.WindowRGB} + WindowTextRGB value: {this.state.RGBValues.WindowTextRGB} + @@ -37,7 +96,7 @@ class TouchableExamples extends React.Component<{}, any> { The following TouchableHighlight has accessibilityLabel, accessibilityHint, accessibilityRole, toolip: { > Blue - Pressed {this.state.pressedCount} times + Pressed {this.state.pressedCount} times ); } @@ -56,61 +115,6 @@ class TouchableExamples extends React.Component<{}, any> { } } -class AccessibilityStateExamples extends React.Component { - public state = { - viewDisabled: false, - itemsSelected: [false, false, false], - } - - public render() { - var selectableItems = [{}, {}, {}] - return ( - - The following TouchableHighlight toggles accessibilityState.disabled for the View under it: - - Toggle - - - This View should be {this.state.viewDisabled ? "disabled" : "enabled"} according to UIA - - The following list of TouchableHighlights toggles accessibilityState.selected when touched: - - - this.selectPress(item.index)} - > - {this.state.itemsSelected[item.index] ? "Selected" : "Unselected"} - - } - keyExtractor={(item, index) => index.toString()} - /> - - - ); - } - - private disablePress = () => { - this.setState({viewDisabled: !this.state.viewDisabled}); - } - - private selectPress = (index: number) => { - let tmp = this.state.itemsSelected; - tmp[index] = !tmp[index]; - this.setState({itemsSelected: tmp}); - } -} export const displayName = (_undefined?: string) => {}; export const title = 'Accessibility'; @@ -129,9 +133,9 @@ export const examples = [ }, }, { - title: 'States', + title: 'HighContrast', render: function(): JSX.Element { - return ; + return ; }, } -]; +]; \ No newline at end of file diff --git a/vnext/src/RNTester/ThemingExample.uwp.tsx b/vnext/src/RNTester/ThemingExample.uwp.tsx new file mode 100644 index 00000000000..9f8eb067a8d --- /dev/null +++ b/vnext/src/RNTester/ThemingExample.uwp.tsx @@ -0,0 +1,55 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +/* tslint:disable */ + +import React = require('react'); +import { Text, View } from 'react-native'; +import { AppTheme } from '../../src/index.uwp'; + +class ThemeExample extends React.Component { + state = { + isHighContrast: AppTheme.isHighContrast, + RGBValues: AppTheme.currentRGBValues, + currentTheme: AppTheme.currentTheme + }; + + componentDidMount() { + AppTheme.addListener('highContrastChanged', this.onHighContrastChanged); + AppTheme.addListener('appThemeChanged', this.onAppThemeChanged); + } + + // TODO: Make args props + onHighContrastChanged = (event: any) => { + const isHighContrast = AppTheme.isHighContrast; + const RGBValues = event.RGBValues; + this.setState({ isHighContrast, RGBValues }); + }; + + onAppThemeChanged = (event: any) => { + const currentTheme = AppTheme.currentTheme; + this.setState({currentTheme}); + }; + + public render() { + return ( + + isHighContrast: {this.state.isHighContrast ? 'true' : 'false'} + RBGValues: {this.state.RGBValues} + currentTheme: {this.state.currentTheme} + + ); + } +} + +export const displayName = (_undefined?: string) => {}; +export const title = 'AppTheme'; +export const description = 'Usage of theme properties.'; +export const examples = [ + { + title: 'Theme Aware Control', + render: function(): JSX.Element { + return ; + }, + } +]; \ No newline at end of file diff --git a/vnext/src/index.ts b/vnext/src/index.ts index 886a8328b49..c36cde2ffe0 100644 --- a/vnext/src/index.ts +++ b/vnext/src/index.ts @@ -11,4 +11,4 @@ export * from './Libraries/Components/Keyboard/KeyboardExt'; export * from './Libraries/Components/Keyboard/KeyboardExtProps'; export * from './Libraries/Components/View/ViewWindowsProps'; export * from './Libraries/Components/View/ViewWindows'; -export * from './Libraries/Modules/AppTheme/AppTheme'; +export * from './Libraries/AppTheme/AppTheme'; diff --git a/vnext/src/index.uwp.ts b/vnext/src/index.uwp.ts index 3cd3632a5b4..2d05dcabc8e 100644 --- a/vnext/src/index.uwp.ts +++ b/vnext/src/index.uwp.ts @@ -11,4 +11,4 @@ export * from './Libraries/Components/Keyboard/KeyboardExt.uwp'; export * from './Libraries/Components/Keyboard/KeyboardExtProps'; export * from './Libraries/Components/View/ViewWindowsProps'; export * from './Libraries/Components/View/ViewWindows.uwp'; -export * from './Libraries/Modules/AppTheme/AppTheme.uwp'; \ No newline at end of file +export * from './Libraries/AppTheme/AppTheme.uwp'; \ No newline at end of file From 898e4e5d08bed1a66dd72a51f298bf97c66c3183 Mon Sep 17 00:00:00 2001 From: Dexter Crowley Date: Thu, 27 Jun 2019 17:59:28 -0700 Subject: [PATCH 2/9] Add Theming test --- vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp | 1 + .../Modules/AppThemeModule.cpp | 2 +- .../ReactWindowsCore/Modules/AppThemeModule.h | 2 +- vnext/src/RNTester/RNTesterList.uwp.ts | 4 ++++ vnext/src/RNTester/ThemingExample.uwp.tsx | 22 ++++++++----------- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp b/vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp index 52f138fa9b3..cadf4515815 100644 --- a/vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp +++ b/vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp @@ -3,6 +3,7 @@ #include "pch.h" #include "AppThemeModuleUwp.h" +#include #include diff --git a/vnext/ReactWindowsCore/Modules/AppThemeModule.cpp b/vnext/ReactWindowsCore/Modules/AppThemeModule.cpp index 0accbb5e82e..b8f00e437de 100644 --- a/vnext/ReactWindowsCore/Modules/AppThemeModule.cpp +++ b/vnext/ReactWindowsCore/Modules/AppThemeModule.cpp @@ -41,7 +41,7 @@ AppThemeModule::AppThemeModule(std::shared_ptr&& appTheme) auto AppThemeModule::getConstants() -> std::map { return { - { "initialAppTheme", folly::dynamic { m_appTheme->getCurrentTheme() } } + { "initialAppTheme", folly::dynamic { m_appTheme->getCurrentTheme() } }, { "isHighContrast", folly::dynamic { m_appTheme->getIsHighContrast() }}, { "highContrastRGBValues", folly::dynamic {m_appTheme->getHighContrastRGBValues()}} }; diff --git a/vnext/ReactWindowsCore/Modules/AppThemeModule.h b/vnext/ReactWindowsCore/Modules/AppThemeModule.h index 1b28b503931..d5565ba789b 100644 --- a/vnext/ReactWindowsCore/Modules/AppThemeModule.h +++ b/vnext/ReactWindowsCore/Modules/AppThemeModule.h @@ -31,7 +31,7 @@ class AppThemeModule : public facebook::xplat::module::CxxModule AppThemeModule(std::shared_ptr && appTheme); // CxxModule - std::string getName() override { return name; } + std::string getName() override { return name; }; auto getConstants() -> std::map override; auto getMethods() -> std::vector override; diff --git a/vnext/src/RNTester/RNTesterList.uwp.ts b/vnext/src/RNTester/RNTesterList.uwp.ts index 4ee911de007..fb436f6e3bc 100644 --- a/vnext/src/RNTester/RNTesterList.uwp.ts +++ b/vnext/src/RNTester/RNTesterList.uwp.ts @@ -126,6 +126,10 @@ const APIExamples: Array = [ key: 'AppStateExample', module: require('react-native/RNTester/js/AppStateExample') }, + { + key: 'ThemingExample', + module: require('./ThemingExample'), + }, { key: 'BorderExample', module: require('react-native/RNTester/js/BorderExample'), diff --git a/vnext/src/RNTester/ThemingExample.uwp.tsx b/vnext/src/RNTester/ThemingExample.uwp.tsx index 9f8eb067a8d..3b2df46eaf5 100644 --- a/vnext/src/RNTester/ThemingExample.uwp.tsx +++ b/vnext/src/RNTester/ThemingExample.uwp.tsx @@ -4,39 +4,35 @@ /* tslint:disable */ import React = require('react'); -import { Text, View } from 'react-native'; +import { Text, View, Button } from 'react-native'; import { AppTheme } from '../../src/index.uwp'; class ThemeExample extends React.Component { state = { - isHighContrast: AppTheme.isHighContrast, - RGBValues: AppTheme.currentRGBValues, currentTheme: AppTheme.currentTheme }; componentDidMount() { - AppTheme.addListener('highContrastChanged', this.onHighContrastChanged); AppTheme.addListener('appThemeChanged', this.onAppThemeChanged); } - // TODO: Make args props - onHighContrastChanged = (event: any) => { - const isHighContrast = AppTheme.isHighContrast; - const RGBValues = event.RGBValues; - this.setState({ isHighContrast, RGBValues }); - }; + componentWillUnmount() { + AppTheme.removeListener('appThemeChanged', this.onAppThemeChanged); + } onAppThemeChanged = (event: any) => { const currentTheme = AppTheme.currentTheme; this.setState({currentTheme}); }; + _onPress = () => { + } + public render() { return ( - isHighContrast: {this.state.isHighContrast ? 'true' : 'false'} - RBGValues: {this.state.RGBValues} - currentTheme: {this.state.currentTheme} + currentTheme: {this.state.currentTheme} + ); } From 79e578a711c6b0c326e86113b95728f92f581bbc Mon Sep 17 00:00:00 2001 From: Dexter Crowley Date: Fri, 28 Jun 2019 09:02:35 -0700 Subject: [PATCH 3/9] Convert RGB to hex and rename RGB to Colors --- vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp | 26 ++++++++++--------- vnext/ReactUWP/Modules/AppThemeModuleUwp.h | 6 ++--- .../Modules/AppThemeModule.cpp | 8 +++--- .../ReactWindowsCore/Modules/AppThemeModule.h | 2 +- vnext/src/Libraries/AppTheme/AppTheme.ts | 20 +++++++------- vnext/src/Libraries/AppTheme/AppTheme.uwp.ts | 24 +++++------------ vnext/src/RNTester/AccessibilityExample.tsx | 22 ++++++++-------- 7 files changed, 50 insertions(+), 58 deletions(-) diff --git a/vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp b/vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp index cadf4515815..27c98734585 100644 --- a/vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp +++ b/vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp @@ -28,12 +28,12 @@ AppTheme::AppTheme(const std::shared_ptr& reactInstance, const s { m_currentTheme = winrt::Application::Current().RequestedTheme(); m_isHighContrast = m_accessibilitySettings.HighContrast(); - m_RGBValues = getHighContrastRGBValues(); + m_highContrastColors = getHighContrastColors(); m_highContrastChangedRevoker = m_accessibilitySettings.HighContrastChanged(winrt::auto_revoke, [this](const auto&, const auto&) { - folly::dynamic eventData = folly::dynamic::object("highContrastRGBValues", getHighContrastRGBValues()) + folly::dynamic eventData = folly::dynamic::object("highContrastColors", getHighContrastColors()) ("isHighContrast", getIsHighContrast()); fireEvent("highContrastChanged", std::move(eventData)); @@ -56,7 +56,7 @@ AppTheme::AppTheme(const std::shared_ptr& reactInstance, const s } // Returns the RBG values for the 8 relevant High Contrast elements. -folly::dynamic AppTheme::getHighContrastRGBValues() { +folly::dynamic AppTheme::getHighContrastColors() { winrt::Windows::UI::Color ButtonFaceColor = m_uiSettings.UIElementColor(winrt::Windows::UI::ViewManagement::UIElementType::ButtonFace); winrt::Windows::UI::Color ButtonTextColor = m_uiSettings.UIElementColor(winrt::Windows::UI::ViewManagement::UIElementType::ButtonText); winrt::Windows::UI::Color GrayTextColor = m_uiSettings.UIElementColor(winrt::Windows::UI::ViewManagement::UIElementType::GrayText); @@ -65,20 +65,22 @@ folly::dynamic AppTheme::getHighContrastRGBValues() { winrt::Windows::UI::Color HotlightColor = m_uiSettings.UIElementColor(winrt::Windows::UI::ViewManagement::UIElementType::Hotlight); winrt::Windows::UI::Color WindowColor = m_uiSettings.UIElementColor(winrt::Windows::UI::ViewManagement::UIElementType::Window); winrt::Windows::UI::Color WindowTextColor = m_uiSettings.UIElementColor(winrt::Windows::UI::ViewManagement::UIElementType::WindowText); - folly::dynamic rbgValues = folly::dynamic::object("ButtonFaceRGB", formatRGB(ButtonFaceColor)) - ("ButtonTextRGB", formatRGB(ButtonTextColor)) - ("GrayTextRGB", formatRGB(GrayTextColor)) - ("HighlightRGB", formatRGB(HighlightColor)) - ("HighlightTextRGB", formatRGB(HighlightTextColor)) - ("HotlightRGB", formatRGB(HotlightColor)) - ("WindowRGB", formatRGB(WindowColor)) - ("WindowTextRGB", formatRGB(WindowTextColor)); + folly::dynamic rbgValues = folly::dynamic::object("ButtonFaceColor", formatRGB(ButtonFaceColor)) + ("ButtonTextColor", formatRGB(ButtonTextColor)) + ("GrayTextColor", formatRGB(GrayTextColor)) + ("HighlightColor", formatRGB(HighlightColor)) + ("HighlightTextColor", formatRGB(HighlightTextColor)) + ("HotlightColor", formatRGB(HotlightColor)) + ("WindowColor", formatRGB(WindowColor)) + ("WindowTextColor", formatRGB(WindowTextColor)); return rbgValues; } std::string AppTheme::formatRGB(winrt::Windows::UI::Color ElementColor) { std::stringstream RGBString; - RGBString << "#" << std::setfill('0') << std::setw(3) << (int)ElementColor.R << std::setfill('0') << std::setw(3) << (int)ElementColor.G << std::setfill('0') << std::setw(3) << (int)ElementColor.B; + RGBString << "#" << std::setfill('0') << std::setw(2) << std::hex << (int)ElementColor.R + << std::setfill('0') << std::setw(2) << std::hex << (int)ElementColor.G + << std::setfill('0') << std::setw(2) << std::hex << (int)ElementColor.B; return RGBString.str(); } diff --git a/vnext/ReactUWP/Modules/AppThemeModuleUwp.h b/vnext/ReactUWP/Modules/AppThemeModuleUwp.h index 6d9aa1efa9c..17cbb368e09 100644 --- a/vnext/ReactUWP/Modules/AppThemeModuleUwp.h +++ b/vnext/ReactUWP/Modules/AppThemeModuleUwp.h @@ -20,8 +20,8 @@ class AppTheme : public react::windows::AppTheme bool getIsHighContrast() override; private: - // RGB helper methods - folly::dynamic getHighContrastRGBValues(); + // High Contrast Color helper methods + folly::dynamic getHighContrastColors(); std::string formatRGB(winrt::Windows::UI::Color ElementColor); void fireEvent(std::string const& eventName, folly::dynamic&& eventData); @@ -30,7 +30,7 @@ class AppTheme : public react::windows::AppTheme std::shared_ptr m_queueThread; winrt::Windows::UI::Xaml::ApplicationTheme m_currentTheme{ winrt::Windows::UI::Xaml::ApplicationTheme::Light }; bool m_isHighContrast; - folly::dynamic m_RGBValues; + folly::dynamic m_highContrastColors; winrt::Windows::UI::ViewManagement::AccessibilitySettings m_accessibilitySettings{ }; winrt::Windows::UI::ViewManagement::AccessibilitySettings::HighContrastChanged_revoker m_highContrastChangedRevoker{ }; diff --git a/vnext/ReactWindowsCore/Modules/AppThemeModule.cpp b/vnext/ReactWindowsCore/Modules/AppThemeModule.cpp index b8f00e437de..534029c4816 100644 --- a/vnext/ReactWindowsCore/Modules/AppThemeModule.cpp +++ b/vnext/ReactWindowsCore/Modules/AppThemeModule.cpp @@ -24,9 +24,9 @@ bool AppTheme::getIsHighContrast() return false; } -folly::dynamic AppTheme::getHighContrastRGBValues() +folly::dynamic AppTheme::getHighContrastColors() { - return folly::dynamic::object("highContrastRGBValues", "None"); + return folly::dynamic::object("highContrastColors", "None"); } // @@ -42,8 +42,8 @@ auto AppThemeModule::getConstants() -> std::map { return { { "initialAppTheme", folly::dynamic { m_appTheme->getCurrentTheme() } }, - { "isHighContrast", folly::dynamic { m_appTheme->getIsHighContrast() }}, - { "highContrastRGBValues", folly::dynamic {m_appTheme->getHighContrastRGBValues()}} + { "initialHighContrast", folly::dynamic { m_appTheme->getIsHighContrast() }}, + { "initialHighContrastColors", folly::dynamic {m_appTheme->getHighContrastColors()}} }; } diff --git a/vnext/ReactWindowsCore/Modules/AppThemeModule.h b/vnext/ReactWindowsCore/Modules/AppThemeModule.h index d5565ba789b..da1a693457f 100644 --- a/vnext/ReactWindowsCore/Modules/AppThemeModule.h +++ b/vnext/ReactWindowsCore/Modules/AppThemeModule.h @@ -20,7 +20,7 @@ class AppTheme virtual const std::string getCurrentTheme(); virtual bool getIsHighContrast(); - virtual folly::dynamic getHighContrastRGBValues(); + virtual folly::dynamic getHighContrastColors(); }; class AppThemeModule : public facebook::xplat::module::CxxModule diff --git a/vnext/src/Libraries/AppTheme/AppTheme.ts b/vnext/src/Libraries/AppTheme/AppTheme.ts index 1b35b44ce5c..b53a50a56a6 100644 --- a/vnext/src/Libraries/AppTheme/AppTheme.ts +++ b/vnext/src/Libraries/AppTheme/AppTheme.ts @@ -1,19 +1,19 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -export interface IRGBValues { - ButtonFaceRGB: string; - ButtonTextRGB: string; - GrayTextRGB: string; - HighlightRGB: string; - HighlightTextRGB: string; - HotlightRGB: string; - WindowRGB: string; - WindowTextRGB: string; +export interface IColorValues { + ButtonFaceColor: string; + ButtonTextColor: string; + GrayTextColor: string; + HighlightColor: string; + HighlightTextColor: string; + HotlightColor: string; + WindowColor: string; + WindowTextColor: string; } export interface IAppThemeChangedEvent { isHighContrast: boolean; - highContrastRGBValues: IRGBValues; + highContrastColors: IColorValues; currentTheme: string; } \ No newline at end of file diff --git a/vnext/src/Libraries/AppTheme/AppTheme.uwp.ts b/vnext/src/Libraries/AppTheme/AppTheme.uwp.ts index 597355f4d59..b95b879964b 100644 --- a/vnext/src/Libraries/AppTheme/AppTheme.uwp.ts +++ b/vnext/src/Libraries/AppTheme/AppTheme.uwp.ts @@ -4,7 +4,7 @@ import { NativeEventEmitter, NativeModules } from 'react-native'; const MissingNativeEventEmitterShim = require('MissingNativeEventEmitterShim'); -import { IAppThemeChangedEvent, IRGBValues } from './AppTheme'; +import { IAppThemeChangedEvent, IColorValues } from './AppTheme'; const NativeAppTheme = NativeModules.RTCAppTheme; @@ -12,27 +12,17 @@ class AppThemeModule extends NativeEventEmitter { public isAvailable: boolean; private _isHighContrast: boolean; private _currentTheme: string; - private _highContrastRGBValues: IRGBValues; + private _highContrastColors: IColorValues; constructor() { super(NativeAppTheme); this.isAvailable = true; - this._highContrastRGBValues = NativeAppTheme.highContrastRGBValues; - /* - {ButtonFaceRGB: ThemingNative.highContrastRGBValues.ButtonFaceRGB, - ButtonTextRGB: ThemingNative.highContrastRGBValues.ButtonTextRGB, - GrayTextRGB: ThemingNative.highContrastRGBValues.GrayTextRGB, - HighlightRGB: ThemingNative.highContrastRGBValues.HighlightRGB, - HighlightTextRGB: ThemingNative.highContrastRGBValues.HighlightTextRGB, - HotlightRGB: ThemingNative.highContrastRGBValues.HotlightRGB, - WindowRGB: ThemingNative.highContrastRGBValues.WindowRGB, - WindowTextRGB: ThemingNative.highContrastRGBValues.WindowTextRGB};*/ - - this._isHighContrast = NativeAppTheme.isHighContrast; + this._highContrastColors = NativeAppTheme.initialHighContrastColors; + this._isHighContrast = NativeAppTheme.initialHighContrast; this.addListener('highContrastChanged', (nativeEvent: IAppThemeChangedEvent) => { this._isHighContrast = nativeEvent.isHighContrast; - this._highContrastRGBValues = nativeEvent.highContrastRGBValues; + this._highContrastColors = nativeEvent.highContrastColors; }); this._currentTheme = NativeAppTheme.initialAppTheme; @@ -49,8 +39,8 @@ class AppThemeModule extends NativeEventEmitter { return this._isHighContrast; } - get currentRGBValues(): IRGBValues { - return this._highContrastRGBValues; + get currentHighContrastColorValues(): IColorValues { + return this._highContrastColors; } } diff --git a/vnext/src/RNTester/AccessibilityExample.tsx b/vnext/src/RNTester/AccessibilityExample.tsx index e419f42970d..5d3bab74146 100644 --- a/vnext/src/RNTester/AccessibilityExample.tsx +++ b/vnext/src/RNTester/AccessibilityExample.tsx @@ -34,7 +34,7 @@ class AccessibilityBaseExample extends React.Component { class HighContrastExample extends React.Component { state = { isHighContrast: AppTheme.isHighContrast, - RGBValues: AppTheme.currentRGBValues, + highContrastColorValues: AppTheme.currentHighContrastColorValues, currentTheme: AppTheme.currentTheme }; @@ -51,7 +51,7 @@ class HighContrastExample extends React.Component { // TODO: Make args props onHighContrastChanged = (event: IAppThemeChangedEvent) => { this.setState({isHighContrast : AppTheme.isHighContrast, - RGBValues : AppTheme.currentRGBValues}); + highContrastColorValues : AppTheme.currentHighContrastColorValues}); }; onAppThemeChanged = (event: any) => { @@ -68,16 +68,16 @@ class HighContrastExample extends React.Component { accessibilityHint="A hint for the blue box."> isHighContrast: {this.state.isHighContrast ? 'true' : 'false'} - ButtonFaceRGB value: {this.state.RGBValues.ButtonFaceRGB} - ButtonTextRGB value: {this.state.RGBValues.ButtonTextRGB} - GrayTextRGB value: {this.state.RGBValues.GrayTextRGB} - HighlightRGB value: {this.state.RGBValues.HighlightRGB} - HighlightTextRGB value: {this.state.RGBValues.HighlightTextRGB} - HotlightRGB value: {this.state.RGBValues.HotlightRGB} - WindowRGB value: {this.state.RGBValues.WindowRGB} - WindowTextRGB value: {this.state.RGBValues.WindowTextRGB} + ButtonFaceColor value: {this.state.highContrastColorValues.ButtonFaceColor} + ButtonTextColor value: {this.state.highContrastColorValues.ButtonTextColor} + GrayTextColor value: {this.state.highContrastColorValues.GrayTextColor} + HighlightColor value: {this.state.highContrastColorValues.HighlightColor} + HighlightTextColor value: {this.state.highContrastColorValues.HighlightTextColor} + HotlightColor value: {this.state.highContrastColorValues.HotlightColor} + WindowColor value: {this.state.highContrastColorValues.WindowColor} + WindowTextColor value: {this.state.highContrastColorValues.WindowTextColor} From cbd56253bd658bbc4bb1c3eab4aa82ac7d4b4fa8 Mon Sep 17 00:00:00 2001 From: Dexter Crowley Date: Fri, 28 Jun 2019 09:15:28 -0700 Subject: [PATCH 4/9] PR draft response --- vnext/src/Libraries/AppTheme/AppTheme.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vnext/src/Libraries/AppTheme/AppTheme.ts b/vnext/src/Libraries/AppTheme/AppTheme.ts index b53a50a56a6..e09e8d2191a 100644 --- a/vnext/src/Libraries/AppTheme/AppTheme.ts +++ b/vnext/src/Libraries/AppTheme/AppTheme.ts @@ -13,7 +13,7 @@ export interface IColorValues { } export interface IAppThemeChangedEvent { - isHighContrast: boolean; - highContrastColors: IColorValues; - currentTheme: string; + isHighContrast: boolean; + highContrastColors: IColorValues; + currentTheme: string; } \ No newline at end of file From 029b6e8f6fced2ec59f1281b7a0da263c2c7397f Mon Sep 17 00:00:00 2001 From: Dexter Crowley Date: Fri, 28 Jun 2019 09:27:38 -0700 Subject: [PATCH 5/9] Use interesting color in second View in AccessibilityExample --- vnext/src/RNTester/AccessibilityExample.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vnext/src/RNTester/AccessibilityExample.tsx b/vnext/src/RNTester/AccessibilityExample.tsx index 5d3bab74146..759434adbee 100644 --- a/vnext/src/RNTester/AccessibilityExample.tsx +++ b/vnext/src/RNTester/AccessibilityExample.tsx @@ -77,7 +77,7 @@ class HighContrastExample extends React.Component { WindowColor value: {this.state.highContrastColorValues.WindowColor} WindowTextColor value: {this.state.highContrastColorValues.WindowTextColor} From 70487b7cdffceccc24e8af9ce210b5b0d141fafb Mon Sep 17 00:00:00 2001 From: Dexter Crowley Date: Fri, 28 Jun 2019 10:36:29 -0700 Subject: [PATCH 6/9] Responding to PR feedback --- vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp | 42 +++++------ .../Modules/AppThemeModule.cpp | 2 +- vnext/src/Libraries/AppTheme/AppTheme.ts | 32 +++++---- vnext/src/Libraries/AppTheme/AppTheme.uwp.ts | 4 +- vnext/src/Libraries/AppTheme/AppThemeTypes.ts | 22 ++++++ .../AppTheme/__mocks__/AppTheme.uwp.ts | 9 +++ vnext/src/RNTester/AccessibilityExample.tsx | 71 +++++++++++++++++-- vnext/src/RNTester/ThemingExample.uwp.tsx | 2 +- 8 files changed, 140 insertions(+), 44 deletions(-) create mode 100644 vnext/src/Libraries/AppTheme/AppThemeTypes.ts diff --git a/vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp b/vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp index 27c98734585..d9f4a80e927 100644 --- a/vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp +++ b/vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp @@ -14,6 +14,7 @@ namespace winrt { using namespace Windows::UI::Xaml; + using namespace Windows::UI::ViewManagement; } namespace react { namespace uwp { @@ -55,16 +56,29 @@ AppTheme::AppTheme(const std::shared_ptr& reactInstance, const s }); } +AppTheme::~AppTheme() = default; + +const std::string AppTheme::getCurrentTheme() +{ + return m_currentTheme == winrt::ApplicationTheme::Light ? AppTheme::light : AppTheme::dark; +} + +bool AppTheme::getIsHighContrast() +{ + return m_accessibilitySettings.HighContrast();; +} + // Returns the RBG values for the 8 relevant High Contrast elements. folly::dynamic AppTheme::getHighContrastColors() { - winrt::Windows::UI::Color ButtonFaceColor = m_uiSettings.UIElementColor(winrt::Windows::UI::ViewManagement::UIElementType::ButtonFace); - winrt::Windows::UI::Color ButtonTextColor = m_uiSettings.UIElementColor(winrt::Windows::UI::ViewManagement::UIElementType::ButtonText); - winrt::Windows::UI::Color GrayTextColor = m_uiSettings.UIElementColor(winrt::Windows::UI::ViewManagement::UIElementType::GrayText); - winrt::Windows::UI::Color HighlightColor = m_uiSettings.UIElementColor(winrt::Windows::UI::ViewManagement::UIElementType::Highlight); - winrt::Windows::UI::Color HighlightTextColor = m_uiSettings.UIElementColor(winrt::Windows::UI::ViewManagement::UIElementType::HighlightText); - winrt::Windows::UI::Color HotlightColor = m_uiSettings.UIElementColor(winrt::Windows::UI::ViewManagement::UIElementType::Hotlight); - winrt::Windows::UI::Color WindowColor = m_uiSettings.UIElementColor(winrt::Windows::UI::ViewManagement::UIElementType::Window); - winrt::Windows::UI::Color WindowTextColor = m_uiSettings.UIElementColor(winrt::Windows::UI::ViewManagement::UIElementType::WindowText); + winrt::Windows::UI::Color ButtonFaceColor = m_uiSettings.UIElementColor(winrt::UIElementType::ButtonFace); + winrt::Windows::UI::Color ButtonTextColor = m_uiSettings.UIElementColor(winrt::UIElementType::ButtonText); + winrt::Windows::UI::Color GrayTextColor = m_uiSettings.UIElementColor(winrt::UIElementType::GrayText); + winrt::Windows::UI::Color HighlightColor = m_uiSettings.UIElementColor(winrt::UIElementType::Highlight); + winrt::Windows::UI::Color HighlightTextColor = m_uiSettings.UIElementColor(winrt::UIElementType::HighlightText); + winrt::Windows::UI::Color HotlightColor = m_uiSettings.UIElementColor(winrt::UIElementType::Hotlight); + winrt::Windows::UI::Color WindowColor = m_uiSettings.UIElementColor(winrt::UIElementType::Window); + winrt::Windows::UI::Color WindowTextColor = m_uiSettings.UIElementColor(winrt::UIElementType::WindowText); + folly::dynamic rbgValues = folly::dynamic::object("ButtonFaceColor", formatRGB(ButtonFaceColor)) ("ButtonTextColor", formatRGB(ButtonTextColor)) ("GrayTextColor", formatRGB(GrayTextColor)) @@ -84,18 +98,6 @@ std::string AppTheme::formatRGB(winrt::Windows::UI::Color ElementColor) { return RGBString.str(); } -AppTheme::~AppTheme() = default; - -const std::string AppTheme::getCurrentTheme() -{ - return m_currentTheme == winrt::ApplicationTheme::Light ? AppTheme::light : AppTheme::dark; -} - -bool AppTheme::getIsHighContrast() -{ - return m_accessibilitySettings.HighContrast();; -} - void AppTheme::fireEvent(std::string const& eventName, folly::dynamic&& eventData) { if (auto instance = m_wkReactInstance.lock()) diff --git a/vnext/ReactWindowsCore/Modules/AppThemeModule.cpp b/vnext/ReactWindowsCore/Modules/AppThemeModule.cpp index 534029c4816..213a9b093db 100644 --- a/vnext/ReactWindowsCore/Modules/AppThemeModule.cpp +++ b/vnext/ReactWindowsCore/Modules/AppThemeModule.cpp @@ -26,7 +26,7 @@ bool AppTheme::getIsHighContrast() folly::dynamic AppTheme::getHighContrastColors() { - return folly::dynamic::object("highContrastColors", "None"); + return {}; } // diff --git a/vnext/src/Libraries/AppTheme/AppTheme.ts b/vnext/src/Libraries/AppTheme/AppTheme.ts index e09e8d2191a..8c7eb8e3734 100644 --- a/vnext/src/Libraries/AppTheme/AppTheme.ts +++ b/vnext/src/Libraries/AppTheme/AppTheme.ts @@ -1,19 +1,23 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +'use strict'; -export interface IColorValues { - ButtonFaceColor: string; - ButtonTextColor: string; - GrayTextColor: string; - HighlightColor: string; - HighlightTextColor: string; - HotlightColor: string; - WindowColor: string; - WindowTextColor: string; +import { NativeEventEmitter } from 'react-native'; +import { IColorValues } from './AppThemeTypes'; + +class AppThemeModule extends NativeEventEmitter { + get currentTheme(): string { + return ''; + } + + get isHighContrast(): boolean { + return false; + } + + get currentHighContrastColorValues(): IColorValues { + return { } as IColorValues; + } } -export interface IAppThemeChangedEvent { - isHighContrast: boolean; - highContrastColors: IColorValues; - currentTheme: string; -} \ No newline at end of file +export const AppTheme = new AppThemeModule(); +export default AppTheme; \ No newline at end of file diff --git a/vnext/src/Libraries/AppTheme/AppTheme.uwp.ts b/vnext/src/Libraries/AppTheme/AppTheme.uwp.ts index b95b879964b..864cb6f967b 100644 --- a/vnext/src/Libraries/AppTheme/AppTheme.uwp.ts +++ b/vnext/src/Libraries/AppTheme/AppTheme.uwp.ts @@ -4,7 +4,7 @@ import { NativeEventEmitter, NativeModules } from 'react-native'; const MissingNativeEventEmitterShim = require('MissingNativeEventEmitterShim'); -import { IAppThemeChangedEvent, IColorValues } from './AppTheme'; +import { IColorValues, IHighContrastChangedEvent } from './AppTheme'; const NativeAppTheme = NativeModules.RTCAppTheme; @@ -20,7 +20,7 @@ class AppThemeModule extends NativeEventEmitter { this._highContrastColors = NativeAppTheme.initialHighContrastColors; this._isHighContrast = NativeAppTheme.initialHighContrast; - this.addListener('highContrastChanged', (nativeEvent: IAppThemeChangedEvent) => { + this.addListener('highContrastChanged', (nativeEvent: IHighContrastChangedEvent) => { this._isHighContrast = nativeEvent.isHighContrast; this._highContrastColors = nativeEvent.highContrastColors; }); diff --git a/vnext/src/Libraries/AppTheme/AppThemeTypes.ts b/vnext/src/Libraries/AppTheme/AppThemeTypes.ts new file mode 100644 index 00000000000..14fffc6411c --- /dev/null +++ b/vnext/src/Libraries/AppTheme/AppThemeTypes.ts @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +export interface IColorValues { + ButtonFaceColor: string; + ButtonTextColor: string; + GrayTextColor: string; + HighlightColor: string; + HighlightTextColor: string; + HotlightColor: string; + WindowColor: string; + WindowTextColor: string; +} + +export interface IAppThemeChangedEvent { + currentTheme: string; +} + +export interface IHighContrastChangedEvent { + isHighContrast: boolean; + highContrastColors: IColorValues; +} \ No newline at end of file diff --git a/vnext/src/Libraries/AppTheme/__mocks__/AppTheme.uwp.ts b/vnext/src/Libraries/AppTheme/__mocks__/AppTheme.uwp.ts index 4661293b872..bc117eaf87c 100644 --- a/vnext/src/Libraries/AppTheme/__mocks__/AppTheme.uwp.ts +++ b/vnext/src/Libraries/AppTheme/__mocks__/AppTheme.uwp.ts @@ -2,11 +2,20 @@ 'use strict'; import { NativeEventEmitter } from 'react-native'; +import { IColorValues } from '../AppThemeTypes'; class AppThemeModule extends NativeEventEmitter { get currentTheme(): string { return 'light'; } + + get isHighContrast(): boolean { + return false; + } + + get currentHighContrastColorValues(): IColorValues { + return { } as IColorValues; + } } export const AppTheme = new AppThemeModule(); diff --git a/vnext/src/RNTester/AccessibilityExample.tsx b/vnext/src/RNTester/AccessibilityExample.tsx index 759434adbee..3db9bb63583 100644 --- a/vnext/src/RNTester/AccessibilityExample.tsx +++ b/vnext/src/RNTester/AccessibilityExample.tsx @@ -4,11 +4,9 @@ /* tslint:disable */ import React = require('react'); -import { Text, TouchableHighlight, View } from 'react-native'; +import { FlatList, Text, TouchableHighlight, View } from 'react-native'; import { AppTheme } from '../../src/index.uwp'; -import { IAppThemeChangedEvent } from 'src/Libraries/AppTheme/AppTheme'; - -var currentBackgroundColor = ['blue', 'red', '#E6E6E6', '#7fff00']; +import { IAppThemeChangedEvent } from 'src/Libraries/AppTheme/AppThemeTypes'; class AccessibilityBaseExample extends React.Component { public render() { @@ -63,10 +61,10 @@ class HighContrastExample extends React.Component { The following has HighContrast Event awareness: - isHighContrast: {this.state.isHighContrast ? 'true' : 'false'} + isHighContrast: {this.state.isHighContrast ? 'true' : 'false'} ButtonFaceColor value: {this.state.highContrastColorValues.ButtonFaceColor} ButtonTextColor value: {this.state.highContrastColorValues.ButtonTextColor} @@ -115,6 +113,61 @@ class TouchableExamples extends React.Component<{}, any> { } } +class AccessibilityStateExamples extends React.Component { + public state = { + viewDisabled: false, + itemsSelected: [false, false, false], + } + + public render() { + var selectableItems = [{}, {}, {}] + return ( + + The following TouchableHighlight toggles accessibilityState.disabled for the View under it: + + Toggle + + + This View should be {this.state.viewDisabled ? "disabled" : "enabled"} according to UIA + + The following list of TouchableHighlights toggles accessibilityState.selected when touched: + + + this.selectPress(item.index)} + > + {this.state.itemsSelected[item.index] ? "Selected" : "Unselected"} + + } + keyExtractor={(item, index) => index.toString()} + /> + + + ); + } + + private disablePress = () => { + this.setState({viewDisabled: !this.state.viewDisabled}); +} + + private selectPress = (index: number) => { + let tmp = this.state.itemsSelected; + tmp[index] = !tmp[index]; + this.setState({itemsSelected: tmp}); + } +} export const displayName = (_undefined?: string) => {}; export const title = 'Accessibility'; @@ -137,5 +190,11 @@ export const examples = [ render: function(): JSX.Element { return ; }, + }, + { + title: 'States', + render: function(): JSX.Element { + return ; + }, } ]; \ No newline at end of file diff --git a/vnext/src/RNTester/ThemingExample.uwp.tsx b/vnext/src/RNTester/ThemingExample.uwp.tsx index 3b2df46eaf5..5dd261cf3e2 100644 --- a/vnext/src/RNTester/ThemingExample.uwp.tsx +++ b/vnext/src/RNTester/ThemingExample.uwp.tsx @@ -32,7 +32,7 @@ class ThemeExample extends React.Component { return ( currentTheme: {this.state.currentTheme} - + ); } From 189e41b4bdea4e2d4d8f961d13721fcb5d546d76 Mon Sep 17 00:00:00 2001 From: Dexter Crowley Date: Fri, 28 Jun 2019 11:43:19 -0700 Subject: [PATCH 7/9] Making AccessibilityExample better showcase highcontrast colors --- vnext/src/RNTester/AccessibilityExample.tsx | 95 ++++++++++++++++----- 1 file changed, 76 insertions(+), 19 deletions(-) diff --git a/vnext/src/RNTester/AccessibilityExample.tsx b/vnext/src/RNTester/AccessibilityExample.tsx index 3db9bb63583..897921fa637 100644 --- a/vnext/src/RNTester/AccessibilityExample.tsx +++ b/vnext/src/RNTester/AccessibilityExample.tsx @@ -4,7 +4,7 @@ /* tslint:disable */ import React = require('react'); -import { FlatList, Text, TouchableHighlight, View } from 'react-native'; +import { FlatList, Text, TouchableHighlight, View, StyleSheet } from 'react-native'; import { AppTheme } from '../../src/index.uwp'; import { IAppThemeChangedEvent } from 'src/Libraries/AppTheme/AppThemeTypes'; @@ -60,28 +60,85 @@ class HighContrastExample extends React.Component { return ( The following has HighContrast Event awareness: - - isHighContrast: {this.state.isHighContrast ? 'true' : 'false'} + + isHighContrast: {this.state.isHighContrast ? 'True' : 'False'} + + + ButtonFace High Contrast Color + + + ButtonText High Contrast Color + + + GrayText High Contrast Color + + + Highlight High Contrast Color + + + HighlightText High Contrast Color + + + Hotlight High Contrast Color + + + Window High Contrast Color + + + WindowText High Contrast Color - ButtonFaceColor value: {this.state.highContrastColorValues.ButtonFaceColor} - ButtonTextColor value: {this.state.highContrastColorValues.ButtonTextColor} - GrayTextColor value: {this.state.highContrastColorValues.GrayTextColor} - HighlightColor value: {this.state.highContrastColorValues.HighlightColor} - HighlightTextColor value: {this.state.highContrastColorValues.HighlightTextColor} - HotlightColor value: {this.state.highContrastColorValues.HotlightColor} - WindowColor value: {this.state.highContrastColorValues.WindowColor} - WindowTextColor value: {this.state.highContrastColorValues.WindowTextColor} - ); } + + styles = StyleSheet.create ({ + ButtonFaceEnabled: { + width: 50, + height: 50, + backgroundColor: this.state.highContrastColorValues.ButtonFaceColor + }, + ButtonTextEnabled: { + width: 50, + height: 50, + backgroundColor: this.state.highContrastColorValues.ButtonTextColor + }, + GrayTextEnabled: { + width: 50, + height: 50, + backgroundColor: this.state.highContrastColorValues.GrayTextColor + }, + HighlightEnabled: { + width: 50, + height: 50, + backgroundColor: this.state.highContrastColorValues.HighlightColor + }, + HighlightTextEnabled: { + width: 50, + height: 50, + backgroundColor: this.state.highContrastColorValues.HighlightTextColor + }, + HotlightEnabled: { + width: 50, + height: 50, + backgroundColor: this.state.highContrastColorValues.HotlightColor + }, + WindowEnabled: { + width: 50, + height: 50, + backgroundColor: this.state.highContrastColorValues.WindowColor + }, + WindowTextEnabled: { + width: 50, + height: 50, + backgroundColor: this.state.highContrastColorValues.WindowTextColor + }, + disabled: { + width: 50, + height: 50, + backgroundColor: 'gray', + textColor: 'white' + } + }); } class TouchableExamples extends React.Component<{}, any> { From 2c2c49942d617f15b0b0c16c8c62684b841b9f81 Mon Sep 17 00:00:00 2001 From: Dexter Crowley Date: Fri, 28 Jun 2019 13:01:42 -0700 Subject: [PATCH 8/9] PR reponse and improve AccessibilityExample --- vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp | 8 +- vnext/src/Libraries/AppTheme/AppTheme.ts | 6 +- vnext/src/Libraries/AppTheme/AppTheme.uwp.ts | 8 +- vnext/src/Libraries/AppTheme/AppThemeTypes.ts | 4 +- .../AppTheme/__mocks__/AppTheme.uwp.ts | 22 ----- vnext/src/RNTester/AccessibilityExample.tsx | 83 +++++-------------- vnext/src/index.ts | 1 + vnext/src/index.uwp.ts | 3 +- 8 files changed, 39 insertions(+), 96 deletions(-) delete mode 100644 vnext/src/Libraries/AppTheme/__mocks__/AppTheme.uwp.ts diff --git a/vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp b/vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp index d9f4a80e927..ed91aae8cef 100644 --- a/vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp +++ b/vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp @@ -91,11 +91,9 @@ folly::dynamic AppTheme::getHighContrastColors() { } std::string AppTheme::formatRGB(winrt::Windows::UI::Color ElementColor) { - std::stringstream RGBString; - RGBString << "#" << std::setfill('0') << std::setw(2) << std::hex << (int)ElementColor.R - << std::setfill('0') << std::setw(2) << std::hex << (int)ElementColor.G - << std::setfill('0') << std::setw(2) << std::hex << (int)ElementColor.B; - return RGBString.str(); + char colorChars[8]; + sprintf_s(colorChars, "#%02x%02x%02x", ElementColor.R, ElementColor.G, ElementColor.B); + return colorChars; } void AppTheme::fireEvent(std::string const& eventName, folly::dynamic&& eventData) diff --git a/vnext/src/Libraries/AppTheme/AppTheme.ts b/vnext/src/Libraries/AppTheme/AppTheme.ts index 8c7eb8e3734..c82142922a2 100644 --- a/vnext/src/Libraries/AppTheme/AppTheme.ts +++ b/vnext/src/Libraries/AppTheme/AppTheme.ts @@ -3,7 +3,7 @@ 'use strict'; import { NativeEventEmitter } from 'react-native'; -import { IColorValues } from './AppThemeTypes'; +import { IHighContrastColors } from './AppThemeTypes'; class AppThemeModule extends NativeEventEmitter { get currentTheme(): string { @@ -14,8 +14,8 @@ class AppThemeModule extends NativeEventEmitter { return false; } - get currentHighContrastColorValues(): IColorValues { - return { } as IColorValues; + get currentHighContrastColorValues(): IHighContrastColors { + return { } as IHighContrastColors; } } diff --git a/vnext/src/Libraries/AppTheme/AppTheme.uwp.ts b/vnext/src/Libraries/AppTheme/AppTheme.uwp.ts index 864cb6f967b..a66a1d48835 100644 --- a/vnext/src/Libraries/AppTheme/AppTheme.uwp.ts +++ b/vnext/src/Libraries/AppTheme/AppTheme.uwp.ts @@ -4,7 +4,7 @@ import { NativeEventEmitter, NativeModules } from 'react-native'; const MissingNativeEventEmitterShim = require('MissingNativeEventEmitterShim'); -import { IColorValues, IHighContrastChangedEvent } from './AppTheme'; +import { IHighContrastColors, IHighContrastChangedEvent } from './AppThemeTypes'; const NativeAppTheme = NativeModules.RTCAppTheme; @@ -12,7 +12,7 @@ class AppThemeModule extends NativeEventEmitter { public isAvailable: boolean; private _isHighContrast: boolean; private _currentTheme: string; - private _highContrastColors: IColorValues; + private _highContrastColors: IHighContrastColors; constructor() { super(NativeAppTheme); @@ -39,7 +39,7 @@ class AppThemeModule extends NativeEventEmitter { return this._isHighContrast; } - get currentHighContrastColorValues(): IColorValues { + get currentHighContrastColors(): IHighContrastColors { return this._highContrastColors; } } @@ -49,6 +49,8 @@ class AppThemeModule extends NativeEventEmitter { class MissingNativeAppThemeShim extends MissingNativeEventEmitterShim { public isAvailable = false; public currentTheme = ''; + public isHighContrast = false; + public currentHighContrastColors = {} as IHighContrastColors; } export const AppTheme = (NativeAppTheme ? new AppThemeModule() : new MissingNativeAppThemeShim()); diff --git a/vnext/src/Libraries/AppTheme/AppThemeTypes.ts b/vnext/src/Libraries/AppTheme/AppThemeTypes.ts index 14fffc6411c..fd96afdb9e6 100644 --- a/vnext/src/Libraries/AppTheme/AppThemeTypes.ts +++ b/vnext/src/Libraries/AppTheme/AppThemeTypes.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -export interface IColorValues { +export interface IHighContrastColors { ButtonFaceColor: string; ButtonTextColor: string; GrayTextColor: string; @@ -18,5 +18,5 @@ export interface IAppThemeChangedEvent { export interface IHighContrastChangedEvent { isHighContrast: boolean; - highContrastColors: IColorValues; + highContrastColors: IHighContrastColors; } \ No newline at end of file diff --git a/vnext/src/Libraries/AppTheme/__mocks__/AppTheme.uwp.ts b/vnext/src/Libraries/AppTheme/__mocks__/AppTheme.uwp.ts deleted file mode 100644 index bc117eaf87c..00000000000 --- a/vnext/src/Libraries/AppTheme/__mocks__/AppTheme.uwp.ts +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed under the MIT License. -'use strict'; - -import { NativeEventEmitter } from 'react-native'; -import { IColorValues } from '../AppThemeTypes'; - -class AppThemeModule extends NativeEventEmitter { - get currentTheme(): string { - return 'light'; - } - - get isHighContrast(): boolean { - return false; - } - - get currentHighContrastColorValues(): IColorValues { - return { } as IColorValues; - } -} - -export const AppTheme = new AppThemeModule(); -export default AppTheme; \ No newline at end of file diff --git a/vnext/src/RNTester/AccessibilityExample.tsx b/vnext/src/RNTester/AccessibilityExample.tsx index 897921fa637..847c34ea4ff 100644 --- a/vnext/src/RNTester/AccessibilityExample.tsx +++ b/vnext/src/RNTester/AccessibilityExample.tsx @@ -32,7 +32,7 @@ class AccessibilityBaseExample extends React.Component { class HighContrastExample extends React.Component { state = { isHighContrast: AppTheme.isHighContrast, - highContrastColorValues: AppTheme.currentHighContrastColorValues, + highContrastColorValues: AppTheme.currentHighContrastColors, currentTheme: AppTheme.currentTheme }; @@ -49,7 +49,7 @@ class HighContrastExample extends React.Component { // TODO: Make args props onHighContrastChanged = (event: IAppThemeChangedEvent) => { this.setState({isHighContrast : AppTheme.isHighContrast, - highContrastColorValues : AppTheme.currentHighContrastColorValues}); + highContrastColorValues : AppTheme.currentHighContrastColors}); }; onAppThemeChanged = (event: any) => { @@ -63,80 +63,43 @@ class HighContrastExample extends React.Component { isHighContrast: {this.state.isHighContrast ? 'True' : 'False'} - - ButtonFace High Contrast Color + + ButtonFace High Contrast Hex Value: {this.state.highContrastColorValues.ButtonFaceColor} - - ButtonText High Contrast Color + + ButtonText High Contrast Color Hex Value: {this.state.highContrastColorValues.ButtonTextColor} - - GrayText High Contrast Color + + GrayText High Contrast Color Hex Value: {this.state.highContrastColorValues.GrayTextColor} - - Highlight High Contrast Color + + Highlight High Contrast Color Hex Value: {this.state.highContrastColorValues.HighlightColor} - - HighlightText High Contrast Color + + HighlightText High Contrast Color Hex Value: {this.state.highContrastColorValues.HighlightTextColor} - - Hotlight High Contrast Color + + Hotlight High Contrast Color Hex Value: {this.state.highContrastColorValues.HotlightColor} - - Window High Contrast Color + + Window High Contrast Color Hex Value: {this.state.highContrastColorValues.WindowColor} - - WindowText High Contrast Color + + WindowText High Contrast Color Hex Value: {this.state.highContrastColorValues.WindowTextColor} ); } styles = StyleSheet.create ({ - ButtonFaceEnabled: { - width: 50, - height: 50, - backgroundColor: this.state.highContrastColorValues.ButtonFaceColor - }, - ButtonTextEnabled: { - width: 50, - height: 50, - backgroundColor: this.state.highContrastColorValues.ButtonTextColor - }, - GrayTextEnabled: { - width: 50, - height: 50, - backgroundColor: this.state.highContrastColorValues.GrayTextColor - }, - HighlightEnabled: { - width: 50, - height: 50, - backgroundColor: this.state.highContrastColorValues.HighlightColor - }, - HighlightTextEnabled: { - width: 50, - height: 50, - backgroundColor: this.state.highContrastColorValues.HighlightTextColor - }, - HotlightEnabled: { - width: 50, - height: 50, - backgroundColor: this.state.highContrastColorValues.HotlightColor - }, - WindowEnabled: { - width: 50, - height: 50, - backgroundColor: this.state.highContrastColorValues.WindowColor - }, - WindowTextEnabled: { - width: 50, - height: 50, - backgroundColor: this.state.highContrastColorValues.WindowTextColor + enabled: { + width: 250, + height: 50 }, disabled: { - width: 50, + width: 250, height: 50, - backgroundColor: 'gray', - textColor: 'white' + backgroundColor: '#808080' } }); } diff --git a/vnext/src/index.ts b/vnext/src/index.ts index c36cde2ffe0..973aafc28f9 100644 --- a/vnext/src/index.ts +++ b/vnext/src/index.ts @@ -12,3 +12,4 @@ export * from './Libraries/Components/Keyboard/KeyboardExtProps'; export * from './Libraries/Components/View/ViewWindowsProps'; export * from './Libraries/Components/View/ViewWindows'; export * from './Libraries/AppTheme/AppTheme'; +export * from './Libraries/AppTheme/AppThemeTypes'; diff --git a/vnext/src/index.uwp.ts b/vnext/src/index.uwp.ts index 2d05dcabc8e..3c549d1d1e3 100644 --- a/vnext/src/index.uwp.ts +++ b/vnext/src/index.uwp.ts @@ -11,4 +11,5 @@ export * from './Libraries/Components/Keyboard/KeyboardExt.uwp'; export * from './Libraries/Components/Keyboard/KeyboardExtProps'; export * from './Libraries/Components/View/ViewWindowsProps'; export * from './Libraries/Components/View/ViewWindows.uwp'; -export * from './Libraries/AppTheme/AppTheme.uwp'; \ No newline at end of file +export * from './Libraries/AppTheme/AppTheme.uwp'; +export * from './Libraries/AppTheme/AppThemeTypes'; \ No newline at end of file From 7d1dd7368061fc9ace9db75d4a1c7dc0c0932568 Mon Sep 17 00:00:00 2001 From: Dexter Crowley Date: Fri, 28 Jun 2019 13:50:53 -0700 Subject: [PATCH 9/9] Removing iomanip include --- vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp b/vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp index ed91aae8cef..41ecdda0eae 100644 --- a/vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp +++ b/vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp @@ -3,7 +3,6 @@ #include "pch.h" #include "AppThemeModuleUwp.h" -#include #include