From 635108e9d29b907aeb7aa82a103473ad5601d64c Mon Sep 17 00:00:00 2001 From: etoledom Date: Wed, 28 Aug 2019 10:31:39 +0200 Subject: [PATCH] [RNMobile] Native mobile release v1.11.0 (#17181) * [RNMobile] Fix crash when adding separator * Build: remove global install of latest npm since we want to use the paired node/npm version (#17134) * Build: remove global install of latest npm since we want to use the paired node/npm version * Also update travis to remove --latest-npm flag * [RNMobile] Try dark mode (iOS) (#17067) * Adding dark mode component implemented on list and list block * Adding DarkMode handling to RichText, ToolBar and SafeArea * Mobile: Using DarkMode as HOC * iOS DarkMode: Modified colors on block list and block container * iOS DarkMode: Improved Header Toolbar colors * iOS DarkMode: Removing background from buttons * iOS DarkMode warning and unsupported * iOS DarkMode: MediaPlaceholder * iOS DarkMode: BottomSheets * iOS DarkMode: Inserter * iOS DarkMode: DefaultBlockAppender * iOS DarkMode: PostTite * Update hardcoded colors with variables * iOS DarkMode: Fix bottom-sheet cell value color * iOS DarkMode: More - PageBreak - Add Block Here * iOS DarkMode: Better text color * iOS Darkmode: Code block * iOS DarkMode: HTML View * iOS DarkMode: Improve colors on SafeArea * Fix toolbar not avoiding keyboard regression * Fix native unit tests * Fix gutenberg-mobile unit tests * Adding RNDarkMode mocks * RNMobile: Fix crash when viewing HTML on iOS * [RNMobile] Remove toolbar from html view * [RNMobile] Fix MaxListenersExceededWarning caused by dark-mode event emitter (#17186) * Fix MaxListenersExceededWarning caused by dark-mode event emitter * Checking for setMaxListeners trying to avoid CI error * Adding remove listener to DarkMode HOC * DarkMode: Binding this.onModeChanged to `this` * DarkMode: Adding conditional needed to pass UI Tests on CI * Fix focus title on new posts regression (#17180) * BottomSheet: Setting DashIcon color directly when theme is default (light) (#17193) --- .../components/block-list/block.native.scss | 2 - .../src/components/block-list/index.native.js | 16 +++--- .../components/block-list/style.native.scss | 18 ++++++- .../default-block-appender/style.native.scss | 1 - .../src/components/inserter/index.native.js | 12 +++-- .../src/components/inserter/menu.native.js | 14 +++-- .../src/components/inserter/style.native.scss | 17 ++++++ .../media-placeholder/index.native.js | 12 +++-- .../media-placeholder/styles.native.scss | 8 +++ .../src/components/warning/index.native.js | 18 ++++--- .../src/components/warning/style.native.scss | 12 +++++ .../block-library/src/code/edit.native.js | 13 +++-- .../block-library/src/code/theme.native.scss | 11 ++++ .../block-library/src/image/edit.native.js | 9 +++- .../src/image/styles.native.scss | 4 ++ .../block-library/src/missing/edit.native.js | 19 ++++--- .../src/missing/style.native.scss | 12 +++++ .../block-library/src/more/edit.native.js | 11 ++-- .../block-library/src/more/editor.native.scss | 12 ++++- .../block-library/src/nextpage/edit.native.js | 11 ++-- .../src/nextpage/editor.native.scss | 13 ++++- packages/block-library/src/separator/edit.js | 28 ++++------ .../src/separator/separator-settings.js | 26 +++++++++ .../separator/separator-settings.native.js | 3 ++ .../block-library/src/video/edit.native.js | 9 +++- .../block-library/src/video/style.native.scss | 4 ++ .../components/src/button/index.native.js | 2 +- packages/components/src/index.native.js | 1 + .../src/mobile/bottom-sheet/cell.native.js | 29 +++++++--- .../src/mobile/bottom-sheet/index.native.js | 20 ++++--- .../mobile/bottom-sheet/styles.native.scss | 24 +++++++++ .../src/mobile/dark-mode/index.native.js | 53 +++++++++++++++++++ .../mobile/html-text-input/index.native.js | 8 ++- .../html-text-input/style-common.native.scss | 10 +++- .../mobile/html-text-input/style.android.scss | 2 - .../src/mobile/html-text-input/style.ios.scss | 6 ++- .../src/primitives/svg/style.native.scss | 14 ++++- .../components/src/toolbar/style.native.scss | 4 ++ .../src/toolbar/toolbar-container.native.js | 5 +- .../header/header-toolbar/index.native.js | 6 ++- .../header/header-toolbar/style.native.scss | 5 ++ .../src/components/layout/index.native.js | 28 +++++----- .../src/components/layout/style.native.scss | 13 +++++ .../components/visual-editor/index.native.js | 8 +-- .../visual-editor/style.native.scss | 4 ++ packages/edit-post/src/editor.native.js | 21 ++++++++ .../src/components/provider/index.native.js | 17 ------ .../src/link/test/modal.native.js | 8 +-- .../rich-text/src/component/index.native.js | 15 ++++-- .../rich-text/src/component/style.native.scss | 14 ++++- .../__mocks__/react-native-dark-mode/index.js | 0 test/native/__mocks__/styleMock.js | 11 +++- test/native/setup.js | 9 ++++ 53 files changed, 507 insertions(+), 145 deletions(-) create mode 100644 packages/block-library/src/separator/separator-settings.js create mode 100644 packages/block-library/src/separator/separator-settings.native.js create mode 100644 packages/components/src/mobile/dark-mode/index.native.js create mode 100644 test/native/__mocks__/react-native-dark-mode/index.js diff --git a/packages/block-editor/src/components/block-list/block.native.scss b/packages/block-editor/src/components/block-list/block.native.scss index b997cddc723073..a7dbae3b46516b 100644 --- a/packages/block-editor/src/components/block-list/block.native.scss +++ b/packages/block-editor/src/components/block-list/block.native.scss @@ -3,7 +3,6 @@ } .blockContainer { - background-color: $white; padding-left: 16px; padding-right: 16px; padding-top: 12px; @@ -11,7 +10,6 @@ } .blockContainerFocused { - background-color: $white; padding-left: 16px; padding-right: 16px; padding-top: 12px; diff --git a/packages/block-editor/src/components/block-list/index.native.js b/packages/block-editor/src/components/block-list/index.native.js index facef0cc5e01ca..10a5cfcbcf1bae 100644 --- a/packages/block-editor/src/components/block-list/index.native.js +++ b/packages/block-editor/src/components/block-list/index.native.js @@ -12,7 +12,7 @@ import { __ } from '@wordpress/i18n'; import { withDispatch, withSelect } from '@wordpress/data'; import { compose } from '@wordpress/compose'; import { createBlock, isUnmodifiedDefaultBlock } from '@wordpress/blocks'; -import { KeyboardAwareFlatList, ReadableContentView } from '@wordpress/components'; +import { KeyboardAwareFlatList, ReadableContentView, useStyle, withTheme } from '@wordpress/components'; /** * Internal dependencies @@ -103,7 +103,7 @@ export class BlockList extends Component { innerRef={ this.scrollViewInnerRef } extraScrollHeight={ innerToolbarHeight + 10 } keyboardShouldPersistTaps="always" - style={ styles.list } + style={ useStyle( styles.list, styles.listDark, this.context ) } data={ this.props.blockClientIds } extraData={ [ this.props.isFullyBordered ] } keyExtractor={ identity } @@ -126,6 +126,7 @@ export class BlockList extends Component { } renderItem( { item: clientId, index } ) { + const blockHolderFocusedStyle = useStyle( styles.blockHolderFocused, styles.blockHolderFocusedDark, this.props.theme ); const { shouldShowBlockAtIndex, shouldShowInsertionPoint } = this.props; return ( @@ -138,18 +139,20 @@ export class BlockList extends Component { rootClientId={ this.props.rootClientId } onCaretVerticalPositionChange={ this.onCaretVerticalPositionChange } borderStyle={ this.blockHolderBorderStyle() } - focusedBorderColor={ styles.blockHolderFocused.borderColor } + focusedBorderColor={ blockHolderFocusedStyle } /> ) } ); } renderAddBlockSeparator() { + const lineStyle = useStyle( styles.lineStyleAddHere, styles.lineStyleAddHereDark, this.props.theme ); + const labelStyle = useStyle( styles.labelStyleAddHere, styles.labelStyleAddHereDark, this.props.theme ); return ( - - { __( 'ADD BLOCK HERE' ) } - + + { __( 'ADD BLOCK HERE' ) } + ); } @@ -228,5 +231,6 @@ export default compose( [ replaceBlock, }; } ), + withTheme, ] )( BlockList ); diff --git a/packages/block-editor/src/components/block-list/style.native.scss b/packages/block-editor/src/components/block-list/style.native.scss index b6961600b95c67..e1f8e96abc948f 100644 --- a/packages/block-editor/src/components/block-list/style.native.scss +++ b/packages/block-editor/src/components/block-list/style.native.scss @@ -8,6 +8,10 @@ flex: 1; } +.listDark { + background: #1c1c1e; +} + .switch { flex-direction: row; justify-content: flex-start; @@ -26,6 +30,10 @@ height: 2px; } +.lineStyleAddHereDark { + background-color: $gray-50; +} + .labelStyleAddHere { flex: 1; text-align: center; @@ -34,9 +42,12 @@ font-weight: bold; } +.labelStyleAddHereDark { + color: $gray-20; +} + .containerStyleAddHere { flex-direction: row; - background-color: $white; } .blockHolderSemiBordered { @@ -54,7 +65,6 @@ } .blockContainerFocused { - background-color: $white; padding-left: 16; padding-right: 16; padding-top: 12; @@ -65,6 +75,10 @@ border-color: $gray-lighten-30; } +.blockHolderFocusedDark { + border-color: $gray-70; +} + .blockListFooter { height: 80px; } diff --git a/packages/block-editor/src/components/default-block-appender/style.native.scss b/packages/block-editor/src/components/default-block-appender/style.native.scss index 5193611fa45d58..9e2ffd2f293b01 100644 --- a/packages/block-editor/src/components/default-block-appender/style.native.scss +++ b/packages/block-editor/src/components/default-block-appender/style.native.scss @@ -5,7 +5,6 @@ } .blockContainer { - background-color: $white; padding-top: 0; padding-left: 16px; padding-right: 16px; diff --git a/packages/block-editor/src/components/inserter/index.native.js b/packages/block-editor/src/components/inserter/index.native.js index b20eb8387992d6..1a757a65a502b2 100644 --- a/packages/block-editor/src/components/inserter/index.native.js +++ b/packages/block-editor/src/components/inserter/index.native.js @@ -2,7 +2,7 @@ * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { Dropdown, ToolbarButton, Dashicon } from '@wordpress/components'; +import { Dropdown, ToolbarButton, Dashicon, withTheme, useStyle } from '@wordpress/components'; import { Component } from '@wordpress/element'; import { withSelect } from '@wordpress/data'; import { compose } from '@wordpress/compose'; @@ -14,10 +14,10 @@ import { getUnregisteredTypeHandlerName } from '@wordpress/blocks'; import styles from './style.scss'; import InserterMenu from './menu'; -const defaultRenderToggle = ( { onToggle, disabled } ) => ( +const defaultRenderToggle = ( { onToggle, disabled, style } ) => ( ) } + icon={ ( ) } onClick={ onToggle } extraProps={ { hint: __( 'Double tap to add a block' ) } } isDisabled={ disabled } @@ -56,9 +56,10 @@ class Inserter extends Component { const { disabled, renderToggle = defaultRenderToggle, + theme, } = this.props; - - return renderToggle( { onToggle, isOpen, disabled } ); + const style = useStyle( styles.addBlockButton, styles.addBlockButtonDark, theme ); + return renderToggle( { onToggle, isOpen, disabled, style } ); } /** @@ -118,4 +119,5 @@ export default compose( [ items: inserterItems.filter( ( { name } ) => name !== getUnregisteredTypeHandlerName() ), }; } ), + withTheme, ] )( Inserter ); diff --git a/packages/block-editor/src/components/inserter/menu.native.js b/packages/block-editor/src/components/inserter/menu.native.js index 7870f41954afe3..3b0e27a156ddb8 100644 --- a/packages/block-editor/src/components/inserter/menu.native.js +++ b/packages/block-editor/src/components/inserter/menu.native.js @@ -14,7 +14,7 @@ import { } from '@wordpress/blocks'; import { withDispatch, withSelect } from '@wordpress/data'; import { withInstanceId, compose } from '@wordpress/compose'; -import { BottomSheet, Icon } from '@wordpress/components'; +import { BottomSheet, Icon, withTheme, useStyle } from '@wordpress/components'; /** * Internal dependencies @@ -63,6 +63,9 @@ export class InserterMenu extends Component { render() { const numberOfColumns = this.calculateNumberOfColumns(); const bottomPadding = styles.contentBottomPadding; + const modalIconWrapperStyle = useStyle( styles.modalIconWrapper, styles.modalIconWrapperDark, this.props.theme ); + const modalIconStyle = useStyle( styles.modalIcon, styles.modalIconDark, this.props.theme ); + const modalItemLabelStyle = useStyle( styles.modalItemLabel, styles.modalItemLabelDark, this.props.theme ); return ( this.props.onSelect( item ) }> - - - + + + - { item.title } + { item.title } } @@ -213,4 +216,5 @@ export default compose( }; } ), withInstanceId, + withTheme, )( InserterMenu ); diff --git a/packages/block-editor/src/components/inserter/style.native.scss b/packages/block-editor/src/components/inserter/style.native.scss index e10b685dda406c..899b3f676827db 100644 --- a/packages/block-editor/src/components/inserter/style.native.scss +++ b/packages/block-editor/src/components/inserter/style.native.scss @@ -37,6 +37,10 @@ align-items: center; } +.modalIconWrapperDark { + background-color: rgba($white, 0.07); +} + .modalIcon { width: 32px; height: 32px; @@ -45,6 +49,10 @@ fill: $gray-dark; } +.modalIconDark { + fill: $white; +} + .modalItemLabel { background-color: transparent; padding-left: 2; @@ -56,9 +64,18 @@ color: $gray-dark; } +.modalItemLabelDark { + color: $white; +} + .addBlockButton { color: $blue-wordpress; border: 2px; border-radius: 10px; border-color: $blue-wordpress; } + +.addBlockButtonDark { + color: $blue-30; + border-color: $blue-30; +} diff --git a/packages/block-editor/src/components/media-placeholder/index.native.js b/packages/block-editor/src/components/media-placeholder/index.native.js index a19a28588200c9..e04361b71f3307 100644 --- a/packages/block-editor/src/components/media-placeholder/index.native.js +++ b/packages/block-editor/src/components/media-placeholder/index.native.js @@ -8,6 +8,7 @@ import { View, Text, TouchableWithoutFeedback } from 'react-native'; */ import { __, sprintf } from '@wordpress/i18n'; import { MediaUpload, MEDIA_TYPE_IMAGE, MEDIA_TYPE_VIDEO } from '@wordpress/block-editor'; +import { withTheme, useStyle } from '@wordpress/components'; /** * Internal dependencies @@ -15,7 +16,7 @@ import { MediaUpload, MEDIA_TYPE_IMAGE, MEDIA_TYPE_VIDEO } from '@wordpress/bloc import styles from './styles.scss'; function MediaPlaceholder( props ) { - const { mediaType, labels = {}, icon, onSelectURL } = props; + const { mediaType, labels = {}, icon, onSelectURL, theme } = props; const isImage = MEDIA_TYPE_IMAGE === mediaType; const isVideo = MEDIA_TYPE_VIDEO === mediaType; @@ -46,6 +47,9 @@ function MediaPlaceholder( props ) { accessibilityHint = __( 'Double tap to select a video' ); } + const emptyStateContainerStyle = useStyle( styles.emptyStateContainer, styles.emptyStateContainerDark, theme ); + const emptyStateTitleStyle = useStyle( styles.emptyStateTitle, styles.emptyStateTitleDark, theme ); + return ( - + { getMediaOptions() } { icon } - + { placeholderTitle } @@ -83,4 +87,4 @@ function MediaPlaceholder( props ) { ); } -export default MediaPlaceholder; +export default withTheme( MediaPlaceholder ); diff --git a/packages/block-editor/src/components/media-placeholder/styles.native.scss b/packages/block-editor/src/components/media-placeholder/styles.native.scss index f76be4b8f36a42..7a192f078e2090 100644 --- a/packages/block-editor/src/components/media-placeholder/styles.native.scss +++ b/packages/block-editor/src/components/media-placeholder/styles.native.scss @@ -11,6 +11,10 @@ padding-bottom: 12; } +.emptyStateContainerDark { + background-color: $background-dark-secondary; +} + .emptyStateTitle { text-align: center; margin-top: 8; @@ -19,6 +23,10 @@ color: #2e4453; } +.emptyStateTitleDark { + color: $white; +} + .emptyStateDescription { text-align: center; color: $blue-wordpress; diff --git a/packages/block-editor/src/components/warning/index.native.js b/packages/block-editor/src/components/warning/index.native.js index 7d0cced3408cca..071fd30a0738a3 100644 --- a/packages/block-editor/src/components/warning/index.native.js +++ b/packages/block-editor/src/components/warning/index.native.js @@ -6,7 +6,7 @@ import { View, Text } from 'react-native'; /** * WordPress dependencies */ -import { Icon } from '@wordpress/components'; +import { Icon, withTheme, useStyle } from '@wordpress/components'; import { normalizeIconObject } from '@wordpress/blocks'; /** @@ -14,29 +14,33 @@ import { normalizeIconObject } from '@wordpress/blocks'; */ import styles from './style.scss'; -function Warning( { title, message, icon, iconClass, ...viewProps } ) { +function Warning( { title, message, icon, iconClass, theme, ...viewProps } ) { icon = icon && normalizeIconObject( icon ); + const internalIconClass = 'warning-icon' + '-' + theme; + const titleStyle = useStyle( styles.title, styles.titleDark, theme ); + const messageStyle = useStyle( styles.message, styles.messageDark, theme ); + return ( { icon && ( ) } { title && ( - { title } + { title } ) } { message && ( - { message } + { message } ) } ); } -export default Warning; +export default withTheme( Warning ); diff --git a/packages/block-editor/src/components/warning/style.native.scss b/packages/block-editor/src/components/warning/style.native.scss index a96045ada1fd55..2bfc52da454d25 100644 --- a/packages/block-editor/src/components/warning/style.native.scss +++ b/packages/block-editor/src/components/warning/style.native.scss @@ -10,6 +10,10 @@ justify-content: center; } +.containerDark { + background-color: $background-dark-secondary; +} + .icon { width: 24px; height: 24px; @@ -24,8 +28,16 @@ color: $gray-dark; } +.titleDark { + color: $white; +} + .message { text-align: center; color: $gray-text-min; font-size: 12; } + +.messageDark { + color: $white; +} diff --git a/packages/block-library/src/code/edit.native.js b/packages/block-library/src/code/edit.native.js index 3f021790c2a403..0363fcfebc61d0 100644 --- a/packages/block-library/src/code/edit.native.js +++ b/packages/block-library/src/code/edit.native.js @@ -6,12 +6,13 @@ import { View } from 'react-native'; /** * WordPress dependencies */ +import { PlainText } from '@wordpress/block-editor'; import { __ } from '@wordpress/i18n'; +import { withTheme, useStyle } from '@wordpress/components'; /** * Internal dependencies */ -import { PlainText } from '@wordpress/block-editor'; import { escape, unescape } from './utils'; /** @@ -21,14 +22,16 @@ import styles from './theme.scss'; // Note: styling is applied directly to the (nested) PlainText component. Web-side components // apply it to the container 'div' but we don't have a proper proposal for cascading styling yet. -export default function CodeEdit( props ) { - const { attributes, setAttributes, style, onFocus, onBlur } = props; +export function CodeEdit( props ) { + const { attributes, setAttributes, style, onFocus, onBlur, theme } = props; + const codeStyle = useStyle( styles.blockCode, styles.blockCodeDark, theme ); + const placeholderStyle = useStyle( styles.placeholder, styles.placeholderDark, theme ); return ( setAttributes( { content: escape( content ) } ) } @@ -38,8 +41,10 @@ export default function CodeEdit( props ) { onFocus={ onFocus } onBlur={ onBlur } fontFamily={ ( styles.blockCode.fontFamily ) } + placeholderTextColor={ placeholderStyle.color } /> </View> ); } +export default withTheme( CodeEdit ); diff --git a/packages/block-library/src/code/theme.native.scss b/packages/block-library/src/code/theme.native.scss index 668b9f92dd1f53..40a4ba9bfcbfdf 100644 --- a/packages/block-library/src/code/theme.native.scss +++ b/packages/block-library/src/code/theme.native.scss @@ -4,3 +4,14 @@ font-family: $default-monospace-font; } +.blockCodeDark { + color: $white; +} + +.placeholder { + color: $gray; +} + +.placeholderDark { + color: $gray-50; +} diff --git a/packages/block-library/src/image/edit.native.js b/packages/block-library/src/image/edit.native.js index 3eb19a6bfa991b..a21d4bb72830f5 100644 --- a/packages/block-library/src/image/edit.native.js +++ b/packages/block-library/src/image/edit.native.js @@ -19,7 +19,10 @@ import { Icon, Toolbar, ToolbarButton, + withTheme, + useStyle, } from '@wordpress/components'; + import { Caption, MediaPlaceholder, @@ -192,11 +195,13 @@ class ImageEdit extends React.Component { } getIcon( isRetryIcon ) { + const iconStyle = useStyle( styles.icon, styles.iconDark, this.props.theme ); + if ( isRetryIcon ) { return <Icon icon={ SvgIconRetry } { ...styles.iconRetry } />; } - return <Icon icon={ SvgIcon } { ...styles.icon } />; + return <Icon icon={ SvgIcon } { ...iconStyle } />; } render() { @@ -368,4 +373,4 @@ class ImageEdit extends React.Component { } } -export default ImageEdit; +export default withTheme( ImageEdit ); diff --git a/packages/block-library/src/image/styles.native.scss b/packages/block-library/src/image/styles.native.scss index 81578bd734ba3e..aaafc3ae5457c8 100644 --- a/packages/block-library/src/image/styles.native.scss +++ b/packages/block-library/src/image/styles.native.scss @@ -45,3 +45,7 @@ width: 100%; height: 100%; } + +.iconDark { + fill: $white; +} diff --git a/packages/block-library/src/missing/edit.native.js b/packages/block-library/src/missing/edit.native.js index 838c64d88b56c4..c5a604144b7e7b 100644 --- a/packages/block-library/src/missing/edit.native.js +++ b/packages/block-library/src/missing/edit.native.js @@ -6,7 +6,7 @@ import { View, Text } from 'react-native'; /** * WordPress dependencies */ -import { Icon } from '@wordpress/components'; +import { Icon, withTheme, useStyle } from '@wordpress/components'; import { coreBlocks } from '@wordpress/block-library'; import { normalizeIconObject } from '@wordpress/blocks'; import { Component } from '@wordpress/element'; @@ -17,18 +17,25 @@ import { __ } from '@wordpress/i18n'; */ import styles from './style.scss'; -export default class UnsupportedBlockEdit extends Component { +export class UnsupportedBlockEdit extends Component { render() { const { originalName } = this.props.attributes; + const theme = this.props.theme; const blockType = coreBlocks[ originalName ]; + const title = blockType ? blockType.settings.title : __( 'Unsupported' ); - const icon = blockType ? normalizeIconObject( blockType.settings.icon ) : 'admin-plugins'; + const titleStyle = useStyle( styles.unsupportedBlockMessage, styles.unsupportedBlockMessageDark, theme ); + const icon = blockType ? normalizeIconObject( blockType.settings.icon ) : 'admin-plugins'; + const iconStyle = useStyle( styles.unsupportedBlockIcon, styles.unsupportedBlockIconDark, theme ); + const iconClassName = 'unsupported-icon' + '-' + theme; return ( - <View style={ styles.unsupportedBlock }> - <Icon className="unsupported-icon" icon={ icon && icon.src ? icon.src : icon } /> - <Text style={ styles.unsupportedBlockMessage }>{ title }</Text> + <View style={ useStyle( styles.unsupportedBlock, styles.unsupportedBlockDark, theme ) }> + <Icon className={ iconClassName } icon={ icon && icon.src ? icon.src : icon } color={ iconStyle.color } /> + <Text style={ titleStyle }>{ title }</Text> </View> ); } } + +export default withTheme( UnsupportedBlockEdit ); diff --git a/packages/block-library/src/missing/style.native.scss b/packages/block-library/src/missing/style.native.scss index 95a86122d70983..c3f9c3a935c630 100644 --- a/packages/block-library/src/missing/style.native.scss +++ b/packages/block-library/src/missing/style.native.scss @@ -10,13 +10,25 @@ justify-content: center; } +.unsupportedBlockDark { + background-color: $background-dark-secondary; +} + .unsupportedBlockIcon { color: $gray-dark; } +.unsupportedBlockIconDark { + color: $white; +} + .unsupportedBlockMessage { margin-top: 2; text-align: center; color: $gray-dark; font-size: 14; } + +.unsupportedBlockMessageDark { + color: $white; +} diff --git a/packages/block-library/src/more/edit.native.js b/packages/block-library/src/more/edit.native.js index 8b369284cb5962..e177213a7f1f6f 100644 --- a/packages/block-library/src/more/edit.native.js +++ b/packages/block-library/src/more/edit.native.js @@ -9,13 +9,14 @@ import Hr from 'react-native-hr'; */ import { __ } from '@wordpress/i18n'; import { Component } from '@wordpress/element'; +import { withTheme, useStyle } from '@wordpress/components'; /** * Internal dependencies */ import styles from './editor.scss'; -export default class MoreEdit extends Component { +export class MoreEdit extends Component { constructor() { super( ...arguments ); @@ -28,6 +29,8 @@ export default class MoreEdit extends Component { const { customText } = this.props.attributes; const { defaultText } = this.state; const content = customText || defaultText; + const textStyle = useStyle( styles.moreText, styles.moreTextDark, this.props.theme ); + const lineStyle = useStyle( styles.moreLine, styles.moreLineDark, this.props.theme ); return ( <View> @@ -35,10 +38,12 @@ export default class MoreEdit extends Component { text={ content } marginLeft={ 0 } marginRight={ 0 } - textStyle={ styles[ 'block-library-more__text' ] } - lineStyle={ styles[ 'block-library-more__line' ] } + textStyle={ textStyle } + lineStyle={ lineStyle } /> </View> ); } } + +export default withTheme( MoreEdit ); diff --git a/packages/block-library/src/more/editor.native.scss b/packages/block-library/src/more/editor.native.scss index eb4a1d60d9431f..b0dece50736e6b 100644 --- a/packages/block-library/src/more/editor.native.scss +++ b/packages/block-library/src/more/editor.native.scss @@ -1,13 +1,21 @@ // @format -.block-library-more__line { +.moreLine { background-color: $gray-lighten-20; height: 2; } -.block-library-more__text { +.moreLineDark { + background-color: $gray-50; +} + +.moreText { color: $gray; text-decoration-style: solid; text-transform: uppercase; } +.moreTextDark { + color: $gray-20; +} + diff --git a/packages/block-library/src/nextpage/edit.native.js b/packages/block-library/src/nextpage/edit.native.js index e3aa69b15e5e41..be9ad283576401 100644 --- a/packages/block-library/src/nextpage/edit.native.js +++ b/packages/block-library/src/nextpage/edit.native.js @@ -8,16 +8,19 @@ import Hr from 'react-native-hr'; * WordPress dependencies */ import { __, sprintf } from '@wordpress/i18n'; +import { withTheme, useStyle } from '@wordpress/components'; /** * Internal dependencies */ import styles from './editor.scss'; -export default function NextPageEdit( { attributes, isSelected, onFocus } ) { +export function NextPageEdit( { attributes, isSelected, onFocus, theme } ) { const { customText = __( 'Page break' ) } = attributes; const accessibilityTitle = attributes.customText || ''; const accessibilityState = isSelected ? [ 'selected' ] : []; + const textStyle = useStyle( styles.nextpageText, styles.nextpageTextDark, theme ); + const lineStyle = useStyle( styles.nextpageLine, styles.nextpageLineDark, theme ); return ( <View @@ -35,8 +38,10 @@ export default function NextPageEdit( { attributes, isSelected, onFocus } ) { <Hr text={ customText } marginLeft={ 0 } marginRight={ 0 } - textStyle={ styles[ 'block-library-nextpage__text' ] } - lineStyle={ styles[ 'block-library-nextpage__line' ] } /> + textStyle={ textStyle } + lineStyle={ lineStyle } /> </View> ); } + +export default withTheme( NextPageEdit ); diff --git a/packages/block-library/src/nextpage/editor.native.scss b/packages/block-library/src/nextpage/editor.native.scss index 869851fdd37c63..01ed97ac577473 100644 --- a/packages/block-library/src/nextpage/editor.native.scss +++ b/packages/block-library/src/nextpage/editor.native.scss @@ -1,12 +1,21 @@ // @format -.block-library-nextpage__line { +.nextpageLine { background-color: $gray-lighten-20; height: 2; } -.block-library-nextpage__text { +.nextpageLineDark { + background-color: $gray-50; +} + +.nextpageText { color: $gray; text-decoration-style: solid; text-transform: uppercase; } + +.nextpageTextDark { + color: $gray-20; +} + diff --git a/packages/block-library/src/separator/edit.js b/packages/block-library/src/separator/edit.js index 050bd7423fb665..30dd0e85d71549 100644 --- a/packages/block-library/src/separator/edit.js +++ b/packages/block-library/src/separator/edit.js @@ -6,13 +6,12 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { __ } from '@wordpress/i18n'; import { HorizontalRule } from '@wordpress/components'; -import { - InspectorControls, - withColors, - PanelColorSettings, -} from '@wordpress/block-editor'; +import { withColors } from '@wordpress/block-editor'; +/** + * Internal dependencies + */ +import SeparatorSettings from './separator-settings'; function SeparatorEdit( { color, setColor, className } ) { return ( @@ -29,19 +28,10 @@ function SeparatorEdit( { color, setColor, className } ) { color: color.color, } } /> - <InspectorControls> - <PanelColorSettings - title={ __( 'Color Settings' ) } - colorSettings={ [ - { - value: color.color, - onChange: setColor, - label: __( 'Color' ), - }, - ] } - > - </PanelColorSettings> - </InspectorControls> + <SeparatorSettings + color={ color } + setColor={ setColor } + /> </> ); } diff --git a/packages/block-library/src/separator/separator-settings.js b/packages/block-library/src/separator/separator-settings.js new file mode 100644 index 00000000000000..bb3a3a57aa1fa0 --- /dev/null +++ b/packages/block-library/src/separator/separator-settings.js @@ -0,0 +1,26 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { + InspectorControls, + PanelColorSettings, +} from '@wordpress/block-editor'; + +const SeparatorSettings = ( { color, setColor } ) => ( + <InspectorControls> + <PanelColorSettings + title={ __( 'Color Settings' ) } + colorSettings={ [ + { + value: color.color, + onChange: setColor, + label: __( 'Color' ), + }, + ] } + > + </PanelColorSettings> + </InspectorControls> +); + +export default SeparatorSettings; diff --git a/packages/block-library/src/separator/separator-settings.native.js b/packages/block-library/src/separator/separator-settings.native.js new file mode 100644 index 00000000000000..d2bdd8ef6443a3 --- /dev/null +++ b/packages/block-library/src/separator/separator-settings.native.js @@ -0,0 +1,3 @@ +// Mobile has no separator settings at this time, so render nothing +const SeparatorSettings = () => null; +export default SeparatorSettings; diff --git a/packages/block-library/src/video/edit.native.js b/packages/block-library/src/video/edit.native.js index 3b0a9d186d3084..9d004832d37f69 100644 --- a/packages/block-library/src/video/edit.native.js +++ b/packages/block-library/src/video/edit.native.js @@ -20,7 +20,10 @@ import { Icon, Toolbar, ToolbarButton, + withTheme, + useStyle, } from '@wordpress/components'; + import { Caption, MediaPlaceholder, @@ -147,11 +150,13 @@ class VideoEdit extends React.Component { } getIcon( isRetryIcon, isMediaPlaceholder ) { + const iconStyle = useStyle( style.icon, style.iconDark, this.props.theme ); + if ( isRetryIcon ) { return <Icon icon={ SvgIconRetry } { ...style.icon } />; } - return <Icon icon={ SvgIcon } { ...( ! isMediaPlaceholder ? style.iconUploading : style.icon ) } />; + return <Icon icon={ SvgIcon } { ...( ! isMediaPlaceholder ? style.iconUploading : iconStyle ) } />; } render() { @@ -262,4 +267,4 @@ class VideoEdit extends React.Component { } } -export default VideoEdit; +export default withTheme( VideoEdit ); diff --git a/packages/block-library/src/video/style.native.scss b/packages/block-library/src/video/style.native.scss index dd4d70ae0a4752..5eb36be46605e3 100644 --- a/packages/block-library/src/video/style.native.scss +++ b/packages/block-library/src/video/style.native.scss @@ -59,6 +59,10 @@ height: 100%; } +.iconDark { + fill: $white; +} + .iconUploading { fill: $gray-lighten-20; width: 100%; diff --git a/packages/components/src/button/index.native.js b/packages/components/src/button/index.native.js index 7a90dd53131661..78d10226e26def 100644 --- a/packages/components/src/button/index.native.js +++ b/packages/components/src/button/index.native.js @@ -20,7 +20,6 @@ const styles = StyleSheet.create( { justifyContent: 'center', alignItems: 'center', aspectRatio: 1, - backgroundColor: 'white', }, buttonActive: { flex: 1, @@ -63,6 +62,7 @@ export default function Button( props ) { } = props; const isDisabled = ariaDisabled || disabled; + const buttonViewStyle = { opacity: isDisabled ? 0.2 : 1, ...( ariaPressed ? styles.buttonActive : styles.buttonInactive ), diff --git a/packages/components/src/index.native.js b/packages/components/src/index.native.js index 4984cdde2fd36d..d09b157160003c 100644 --- a/packages/components/src/index.native.js +++ b/packages/components/src/index.native.js @@ -27,3 +27,4 @@ export { default as KeyboardAvoidingView } from './mobile/keyboard-avoiding-view export { default as KeyboardAwareFlatList } from './mobile/keyboard-aware-flat-list'; export { default as Picker } from './mobile/picker'; export { default as ReadableContentView } from './mobile/readable-content-view'; +export * from './mobile/dark-mode'; diff --git a/packages/components/src/mobile/bottom-sheet/cell.native.js b/packages/components/src/mobile/bottom-sheet/cell.native.js index cebfc6a91c1826..cbc10928478704 100644 --- a/packages/components/src/mobile/bottom-sheet/cell.native.js +++ b/packages/components/src/mobile/bottom-sheet/cell.native.js @@ -16,8 +16,10 @@ import { __, _x, sprintf } from '@wordpress/i18n'; */ import styles from './styles.scss'; import platformStyles from './cellStyles.scss'; +// `useStyle as getStyle`: Hack to avoid lint thinking this is a React Hook +import { withTheme, useStyle as getStyle } from '../dark-mode'; -export default class BottomSheetCell extends Component { +class BottomSheetCell extends Component { constructor( props ) { super( ...arguments ); this.state = { @@ -48,12 +50,15 @@ export default class BottomSheetCell extends Component { editable = true, separatorType, style = {}, + theme, ...valueProps } = this.props; const showValue = value !== undefined; const isValueEditable = editable && onChangeValue !== undefined; - const defaultLabelStyle = showValue || icon !== undefined ? styles.cellLabel : styles.cellLabelCentered; + const cellLabelStyle = getStyle( styles.cellLabel, styles.cellTextDark, theme ); + const cellLabelCenteredStyle = getStyle( styles.cellLabelCentered, styles.cellTextDark, theme ); + const defaultLabelStyle = showValue || icon !== undefined ? cellLabelStyle : cellLabelCenteredStyle; const drawSeparator = ( separatorType && separatorType !== 'none' ) || separatorStyle === undefined; const onCellPress = () => { @@ -75,22 +80,26 @@ export default class BottomSheetCell extends Component { }; const separatorStyle = () => { - const leftMarginStyle = { ...styles.cellSeparator, ...platformStyles.separatorMarginLeft }; + //eslint-disable-next-line @wordpress/no-unused-vars-before-return + const defaultSeparatorStyle = getStyle( styles.separator, styles.separatorDark, theme ); + const cellSeparatorStyle = getStyle( styles.cellSeparator, styles.cellSeparatorDark, theme ); + const leftMarginStyle = { ...cellSeparatorStyle, ...platformStyles.separatorMarginLeft }; switch ( separatorType ) { case 'leftMargin': return leftMarginStyle; case 'fullWidth': - return styles.separator; + return defaultSeparatorStyle; case 'none': return undefined; case undefined: - return showValue ? leftMarginStyle : styles.separator; + return showValue ? leftMarginStyle : defaultSeparatorStyle; } }; const getValueComponent = () => { const styleRTL = I18nManager.isRTL && styles.cellValueRTL; - const finalStyle = { ...styles.cellValue, ...valueStyle, ...styleRTL }; + const cellValueStyle = getStyle( styles.cellValue, styles.cellTextDark, theme ); + const finalStyle = { ...cellValueStyle, ...valueStyle, ...styleRTL }; // To be able to show the `middle` ellipsizeMode on editable cells // we show the TextInput just when the user wants to edit the value, @@ -114,7 +123,7 @@ export default class BottomSheetCell extends Component { /> ) : ( <Text - style={ { ...styles.cellValue, ...valueStyle } } + style={ { ...cellValueStyle, ...valueStyle } } numberOfLines={ 1 } ellipsizeMode={ 'middle' } > @@ -142,6 +151,8 @@ export default class BottomSheetCell extends Component { ); }; + const iconStyle = getStyle( styles.icon, styles.iconDark, theme ); + return ( <TouchableOpacity accessible={ ! this.state.isEditingValue } @@ -159,7 +170,7 @@ export default class BottomSheetCell extends Component { <View style={ styles.cellRowContainer }> { icon && ( <View style={ styles.cellRowContainer }> - <Dashicon icon={ icon } size={ 24 } /> + <Dashicon icon={ icon } size={ 24 } color={ iconStyle.color } /> <View style={ platformStyles.labelIconSeparator } /> </View> ) } @@ -177,3 +188,5 @@ export default class BottomSheetCell extends Component { ); } } + +export default withTheme( BottomSheetCell ); diff --git a/packages/components/src/mobile/bottom-sheet/index.native.js b/packages/components/src/mobile/bottom-sheet/index.native.js index 9106709cea25ef..e3209713e49449 100644 --- a/packages/components/src/mobile/bottom-sheet/index.native.js +++ b/packages/components/src/mobile/bottom-sheet/index.native.js @@ -19,6 +19,7 @@ import Cell from './cell'; import PickerCell from './picker-cell'; import SwitchCell from './switch-cell'; import KeyboardAvoidingView from './keyboard-avoiding-view'; +import { withTheme, useStyle } from '../dark-mode'; class BottomSheet extends Component { constructor() { @@ -63,6 +64,7 @@ class BottomSheet extends Component { hideHeader, style = {}, contentStyle = {}, + theme, } = this.props; const panResponder = PanResponder.create( { @@ -118,6 +120,8 @@ class BottomSheet extends Component { }, }; + const backgroundStyle = useStyle( styles.background, styles.backgroundDark, theme ); + return ( <Modal isVisible={ isVisible } @@ -139,7 +143,7 @@ class BottomSheet extends Component { > <KeyboardAvoidingView behavior={ Platform.OS === 'ios' && 'padding' } - style={ { ...styles.background, borderColor: 'rgba(0, 0, 0, 0.1)', ...style } } + style={ { ...backgroundStyle, borderColor: 'rgba(0, 0, 0, 0.1)', ...style } } keyboardVerticalOffset={ -this.state.safeAreaBottomInset } > <View style={ styles.dragIndicator } /> @@ -160,10 +164,12 @@ function getWidth() { return Math.min( Dimensions.get( 'window' ).width, styles.background.maxWidth ); } -BottomSheet.getWidth = getWidth; -BottomSheet.Button = Button; -BottomSheet.Cell = Cell; -BottomSheet.PickerCell = PickerCell; -BottomSheet.SwitchCell = SwitchCell; +const ThemedBottomSheet = withTheme( BottomSheet ); + +ThemedBottomSheet.getWidth = getWidth; +ThemedBottomSheet.Button = Button; +ThemedBottomSheet.Cell = Cell; +ThemedBottomSheet.PickerCell = PickerCell; +ThemedBottomSheet.SwitchCell = SwitchCell; -export default BottomSheet; +export default ThemedBottomSheet; diff --git a/packages/components/src/mobile/bottom-sheet/styles.native.scss b/packages/components/src/mobile/bottom-sheet/styles.native.scss index 53764ee4fe38f1..8f153715c16705 100644 --- a/packages/components/src/mobile/bottom-sheet/styles.native.scss +++ b/packages/components/src/mobile/bottom-sheet/styles.native.scss @@ -21,6 +21,10 @@ width: 100%; } +.separatorDark { + background-color: $gray-70; +} + .emptyHeaderSpace { height: 14; } @@ -34,6 +38,10 @@ padding-bottom: 0; } +.backgroundDark { + background-color: $background-dark-elevated; +} + .content { padding: 0 16px 0 16px; } @@ -86,6 +94,10 @@ width: 100%; } +.cellSeparatorDark { + background-color: $gray-70; +} + .cellRowContainer { flex-direction: row; align-items: center; @@ -115,6 +127,18 @@ flex: 1; } +.cellTextDark { + color: $white; +} + .cellValueRTL { text-align: left; } + +.icon { + color: #7b9ab1; +} + +.iconDark { + color: #c3c4c7; +} diff --git a/packages/components/src/mobile/dark-mode/index.native.js b/packages/components/src/mobile/dark-mode/index.native.js new file mode 100644 index 00000000000000..d2b13020f027f9 --- /dev/null +++ b/packages/components/src/mobile/dark-mode/index.native.js @@ -0,0 +1,53 @@ +/** + * External dependencies + */ +import { eventEmitter, initialMode } from 'react-native-dark-mode'; +import React from 'react'; + +// This was failing on CI +if ( eventEmitter.setMaxListeners ) { + eventEmitter.setMaxListeners( 150 ); +} + +export function useStyle( light, dark, theme ) { + const finalDark = { + ...light, + ...dark, + }; + + return theme === 'dark' ? finalDark : light; +} + +// This function takes a component... +export function withTheme( WrappedComponent ) { + return class extends React.Component { + constructor( props ) { + super( props ); + + this.onModeChanged = this.onModeChanged.bind( this ); + + this.state = { + mode: initialMode, + }; + } + + onModeChanged( newMode ) { + this.setState( { mode: newMode } ); + } + + componentDidMount() { + this.subscription = eventEmitter.on( 'currentModeChanged', this.onModeChanged ); + } + + componentWillUnmount() { + // Conditional needed to pass UI Tests on CI + if ( eventEmitter.removeListener ) { + eventEmitter.removeListener( 'currentModeChanged', this.onModeChanged ); + } + } + + render() { + return <WrappedComponent theme={ this.state.mode } { ...this.props } />; + } + }; +} diff --git a/packages/components/src/mobile/html-text-input/index.native.js b/packages/components/src/mobile/html-text-input/index.native.js index e25f7a1af71c4d..1408be65c90530 100644 --- a/packages/components/src/mobile/html-text-input/index.native.js +++ b/packages/components/src/mobile/html-text-input/index.native.js @@ -15,6 +15,7 @@ import { withInstanceId, compose } from '@wordpress/compose'; /** * Internal dependencies */ +import { withTheme, useStyle } from '../dark-mode'; import HTMLInputContainer from './container'; import styles from './style.scss'; @@ -60,6 +61,8 @@ export class HTMLTextInput extends Component { } render() { + const htmlStyle = useStyle( styles.htmlView, styles.htmlViewDark, this.props.theme ); + const placeholderStyle = useStyle( styles.placeholder, styles.placeholderDark, this.props.theme ); return ( <HTMLInputContainer parentHeight={ this.props.parentHeight }> <TextInput @@ -70,6 +73,7 @@ export class HTMLTextInput extends Component { style={ styles.htmlViewTitle } value={ this.props.title } placeholder={ __( 'Add title' ) } + placeholderTextColor={ placeholderStyle.color } onChangeText={ this.props.editTitle } /> <TextInput @@ -77,11 +81,12 @@ export class HTMLTextInput extends Component { accessibilityLabel="html-view-content" textAlignVertical="top" multiline - style={ styles.htmlView } + style={ htmlStyle } value={ this.state.value } onChangeText={ this.edit } onBlur={ this.stopEditing } placeholder={ __( 'Start writing…' ) } + placeholderTextColor={ placeholderStyle.color } scrollEnabled={ HTMLInputContainer.scrollEnabled } /> </HTMLInputContainer> @@ -117,4 +122,5 @@ export default compose( [ }; } ), withInstanceId, + withTheme, ] )( HTMLTextInput ); diff --git a/packages/components/src/mobile/html-text-input/style-common.native.scss b/packages/components/src/mobile/html-text-input/style-common.native.scss index 4db5b985161402..c1ac9f155d4c79 100644 --- a/packages/components/src/mobile/html-text-input/style-common.native.scss +++ b/packages/components/src/mobile/html-text-input/style-common.native.scss @@ -1,6 +1,6 @@ $padding: 8; -$backgroundColor: $white; $htmlFont: $default-monospace-font; +$textColorDark: $white; .keyboardAvoidingView { position: absolute; @@ -13,3 +13,11 @@ $htmlFont: $default-monospace-font; .container { flex: 1; } + +.placeholder { + color: $gray; +} + +.placeholderDark { + color: $gray-50; +} diff --git a/packages/components/src/mobile/html-text-input/style.android.scss b/packages/components/src/mobile/html-text-input/style.android.scss index 10594358722c37..1dca01274d75b5 100644 --- a/packages/components/src/mobile/html-text-input/style.android.scss +++ b/packages/components/src/mobile/html-text-input/style.android.scss @@ -2,7 +2,6 @@ .htmlView { font-family: $htmlFont; - background-color: $backgroundColor; padding-left: $padding; padding-right: $padding; padding-top: $padding; @@ -11,7 +10,6 @@ .htmlViewTitle { font-family: $htmlFont; - background-color: $backgroundColor; padding-left: $padding; padding-right: $padding; padding-top: $padding; diff --git a/packages/components/src/mobile/html-text-input/style.ios.scss b/packages/components/src/mobile/html-text-input/style.ios.scss index 8b13392b95a9ae..97cf00a7512ff5 100644 --- a/packages/components/src/mobile/html-text-input/style.ios.scss +++ b/packages/components/src/mobile/html-text-input/style.ios.scss @@ -4,15 +4,17 @@ $title-height: 32; .htmlView { font-family: $htmlFont; - background-color: $backgroundColor; padding-left: $padding; padding-right: $padding; padding-bottom: $title-height + $padding; } +.htmlViewDark { + color: $textColorDark; +} + .htmlViewTitle { font-family: $htmlFont; - background-color: $backgroundColor; padding-left: $padding; padding-right: $padding; padding-top: $padding; diff --git a/packages/components/src/primitives/svg/style.native.scss b/packages/components/src/primitives/svg/style.native.scss index e5a64ea140d0d8..595372b06329e1 100644 --- a/packages/components/src/primitives/svg/style.native.scss +++ b/packages/components/src/primitives/svg/style.native.scss @@ -13,12 +13,22 @@ fill: currentColor; } -.unsupported-icon { +.unsupported-icon-light { color: $gray-dark; fill: currentColor; } -.warning-icon { +.unsupported-icon-dark { + color: $white; + fill: currentColor; +} + +.warning-icon-light { color: $gray-dark; fill: currentColor; } + +.warning-icon-dark { + color: $white; + fill: currentColor; +} diff --git a/packages/components/src/toolbar/style.native.scss b/packages/components/src/toolbar/style.native.scss index 1e0d176e275d80..3038ea8e491d8d 100644 --- a/packages/components/src/toolbar/style.native.scss +++ b/packages/components/src/toolbar/style.native.scss @@ -5,3 +5,7 @@ padding-left: 5px; padding-right: 5px; } + +.containerDark { + border-color: #515459; +} diff --git a/packages/components/src/toolbar/toolbar-container.native.js b/packages/components/src/toolbar/toolbar-container.native.js index 887991d2ea1238..f9d019450266c2 100644 --- a/packages/components/src/toolbar/toolbar-container.native.js +++ b/packages/components/src/toolbar/toolbar-container.native.js @@ -7,11 +7,12 @@ import { View } from 'react-native'; * Internal dependencies */ import styles from './style.scss'; +import { withTheme, useStyle } from '../mobile/dark-mode'; const ToolbarContainer = ( props ) => ( - <View style={ [ styles.container, props.passedStyle ] }> + <View style={ [ useStyle( styles.container, styles.containerDark, props.theme ), props.passedStyle ] }> { props.children } </View> ); -export default ToolbarContainer; +export default withTheme( ToolbarContainer ); diff --git a/packages/edit-post/src/components/header/header-toolbar/index.native.js b/packages/edit-post/src/components/header/header-toolbar/index.native.js index 7c33856a629180..97ca3a62349bc5 100644 --- a/packages/edit-post/src/components/header/header-toolbar/index.native.js +++ b/packages/edit-post/src/components/header/header-toolbar/index.native.js @@ -15,7 +15,7 @@ import { Inserter, BlockToolbar, } from '@wordpress/block-editor'; -import { Toolbar, ToolbarButton } from '@wordpress/components'; +import { Toolbar, ToolbarButton, useStyle, withTheme } from '@wordpress/components'; /** * Internal dependencies @@ -31,6 +31,7 @@ function HeaderToolbar( { showInserter, showKeyboardHideButton, clearSelectedBlock, + theme, } ) { const scrollViewRef = useRef( null ); const scrollToStart = () => { @@ -38,7 +39,7 @@ function HeaderToolbar( { }; return ( - <View style={ styles.container }> + <View style={ useStyle( styles.container, styles.containerDark, theme ) }> <ScrollView ref={ scrollViewRef } onContentSizeChange={ scrollToStart } @@ -99,4 +100,5 @@ export default compose( [ clearSelectedBlock: dispatch( 'core/block-editor' ).clearSelectedBlock, } ) ), withViewportMatch( { isLargeViewport: 'medium' } ), + withTheme, ] )( HeaderToolbar ); diff --git a/packages/edit-post/src/components/header/header-toolbar/style.native.scss b/packages/edit-post/src/components/header/header-toolbar/style.native.scss index 0aa03b90ed81cc..9210ce5506d620 100644 --- a/packages/edit-post/src/components/header/header-toolbar/style.native.scss +++ b/packages/edit-post/src/components/header/header-toolbar/style.native.scss @@ -7,6 +7,11 @@ border-top-width: 1px; } +.containerDark { + background-color: $background-dark-elevated; + border-top-color: $background-dark-elevated; +} + .scrollableContent { flex-grow: 1; // Fixes RTL issue on Android. } diff --git a/packages/edit-post/src/components/layout/index.native.js b/packages/edit-post/src/components/layout/index.native.js index 3242628c021b89..5b6813067211d2 100644 --- a/packages/edit-post/src/components/layout/index.native.js +++ b/packages/edit-post/src/components/layout/index.native.js @@ -11,7 +11,7 @@ import { sendNativeEditorDidLayout } from 'react-native-gutenberg-bridge'; import { Component } from '@wordpress/element'; import { withSelect } from '@wordpress/data'; import { compose } from '@wordpress/compose'; -import { HTMLTextInput, KeyboardAvoidingView, ReadableContentView } from '@wordpress/components'; +import { HTMLTextInput, KeyboardAvoidingView, ReadableContentView, useStyle, withTheme } from '@wordpress/components'; /** * Internal dependencies @@ -75,7 +75,7 @@ class Layout extends Component { renderHTML() { return ( - <HTMLTextInput /> + <HTMLTextInput parentHeight={ this.state.rootViewHeight } /> ); } @@ -101,8 +101,10 @@ class Layout extends Component { mode, } = this.props; + const isHtmlView = mode === 'text'; + // add a margin view at the bottom for the header - const marginBottom = Platform.OS === 'android' ? headerToolbarStyles.container.height : 0; + const marginBottom = Platform.OS === 'android' && ! isHtmlView ? headerToolbarStyles.container.height : 0; const toolbarKeyboardAvoidingViewStyle = { ...styles.toolbarKeyboardAvoidingView, @@ -112,18 +114,19 @@ class Layout extends Component { }; return ( - <SafeAreaView style={ styles.container } onLayout={ this.onRootViewLayout }> - <View style={ { flex: 1 } }> - { mode === 'text' ? this.renderHTML() : this.renderVisual() } + <SafeAreaView style={ useStyle( styles.container, styles.containerDark, this.props.theme ) } onLayout={ this.onRootViewLayout }> + <View style={ useStyle( styles.background, styles.backgroundDark, this.props.theme ) }> + { isHtmlView ? this.renderHTML() : this.renderVisual() } </View> <View style={ { flex: 0, flexBasis: marginBottom, height: marginBottom } }> </View> - <KeyboardAvoidingView - parentHeight={ this.state.rootViewHeight } - style={ toolbarKeyboardAvoidingViewStyle } - > - <Header /> - </KeyboardAvoidingView> + { ! isHtmlView && ( + <KeyboardAvoidingView + parentHeight={ this.state.rootViewHeight } + style={ toolbarKeyboardAvoidingViewStyle } + > + <Header /> + </KeyboardAvoidingView> ) } </SafeAreaView> ); } @@ -143,4 +146,5 @@ export default compose( [ mode: getEditorMode(), }; } ), + withTheme, ] )( Layout ); diff --git a/packages/edit-post/src/components/layout/style.native.scss b/packages/edit-post/src/components/layout/style.native.scss index e6d7e241bcd0df..7a5026d6664dc9 100644 --- a/packages/edit-post/src/components/layout/style.native.scss +++ b/packages/edit-post/src/components/layout/style.native.scss @@ -5,6 +5,19 @@ background-color: #fff; } +.containerDark { + background-color: $background-dark-elevated; +} + +.background { + flex: 1; + background-color: $white; +} + +.backgroundDark { + background-color: $black; +} + .toolbarKeyboardAvoidingView { position: absolute; bottom: 0; diff --git a/packages/edit-post/src/components/visual-editor/index.native.js b/packages/edit-post/src/components/visual-editor/index.native.js index 15ca4ed9d451bc..9d1925356a9138 100644 --- a/packages/edit-post/src/components/visual-editor/index.native.js +++ b/packages/edit-post/src/components/visual-editor/index.native.js @@ -7,7 +7,7 @@ import { withDispatch, withSelect } from '@wordpress/data'; import { compose } from '@wordpress/compose'; import { BlockList } from '@wordpress/block-editor'; import { PostTitle } from '@wordpress/editor'; -import { ReadableContentView } from '@wordpress/components'; +import { ReadableContentView, withTheme, useStyle } from '@wordpress/components'; /** * Internal dependencies @@ -20,8 +20,9 @@ class VisualEditor extends Component { editTitle, setTitleRef, title, + theme, } = this.props; - + const blockHolderFocusedStyle = useStyle( styles.blockHolderFocused, styles.blockHolderFocusedDark, theme ); return ( <ReadableContentView> <PostTitle @@ -34,7 +35,7 @@ class VisualEditor extends Component { styles.blockHolderFullBordered : styles.blockHolderSemiBordered } - focusedBorderColor={ styles.blockHolderFocused.borderColor } + focusedBorderColor={ blockHolderFocusedStyle.borderColor } accessibilityLabel="post-title" /> </ReadableContentView> @@ -81,4 +82,5 @@ export default compose( [ }, }; } ), + withTheme, ] )( VisualEditor ); diff --git a/packages/edit-post/src/components/visual-editor/style.native.scss b/packages/edit-post/src/components/visual-editor/style.native.scss index 02b49a1515584c..4ade220b5dd9e9 100644 --- a/packages/edit-post/src/components/visual-editor/style.native.scss +++ b/packages/edit-post/src/components/visual-editor/style.native.scss @@ -15,3 +15,7 @@ .blockHolderFocused { border-color: $gray-lighten-30; } + +.blockHolderFocusedDark { + border-color: $gray-70; +} diff --git a/packages/edit-post/src/editor.native.js b/packages/edit-post/src/editor.native.js index 23e0bad6a9e60a..87acaaf96669c0 100644 --- a/packages/edit-post/src/editor.native.js +++ b/packages/edit-post/src/editor.native.js @@ -3,6 +3,7 @@ */ import memize from 'memize'; import { size, map, without } from 'lodash'; +import { subscribeSetFocusOnTitle } from 'react-native-gutenberg-bridge'; /** * WordPress dependencies @@ -31,6 +32,8 @@ class Editor extends Component { this.getEditorSettings = memize( this.getEditorSettings, { maxSize: 1, } ); + + this.setTitleRef = this.setTitleRef.bind( this ); } getEditorSettings( @@ -66,6 +69,24 @@ class Editor extends Component { return settings; } + componentDidMount() { + this.subscriptionParentSetFocusOnTitle = subscribeSetFocusOnTitle( () => { + if ( this.postTitleRef ) { + this.postTitleRef.focus(); + } + } ); + } + + componentWillUnmount() { + if ( this.subscriptionParentSetFocusOnTitle ) { + this.subscriptionParentSetFocusOnTitle.remove(); + } + } + + setTitleRef( titleRef ) { + this.postTitleRef = titleRef; + } + render() { const { settings, diff --git a/packages/editor/src/components/provider/index.native.js b/packages/editor/src/components/provider/index.native.js index d19da119ef0ba5..7a055f438f4d91 100644 --- a/packages/editor/src/components/provider/index.native.js +++ b/packages/editor/src/components/provider/index.native.js @@ -5,7 +5,6 @@ import RNReactNativeGutenbergBridge, { subscribeParentGetHtml, subscribeParentToggleHTMLMode, subscribeUpdateHtml, - subscribeSetFocusOnTitle, subscribeSetTitle, } from 'react-native-gutenberg-bridge'; @@ -28,8 +27,6 @@ class NativeEditorProvider extends Component { // Keep a local reference to `post` to detect changes this.post = props.post; - - this.setTitleRef = this.setTitleRef.bind( this ); } componentDidMount() { @@ -48,12 +45,6 @@ class NativeEditorProvider extends Component { this.subscriptionParentUpdateHtml = subscribeUpdateHtml( ( payload ) => { this.updateHtmlAction( payload.html ); } ); - - this.subscriptionParentSetFocusOnTitle = subscribeSetFocusOnTitle( () => { - if ( this.postTitleRef ) { - this.postTitleRef.focus(); - } - } ); } componentWillUnmount() { @@ -72,10 +63,6 @@ class NativeEditorProvider extends Component { if ( this.subscriptionParentUpdateHtml ) { this.subscriptionParentUpdateHtml.remove(); } - - if ( this.subscriptionParentSetFocusOnTitle ) { - this.subscriptionParentSetFocusOnTitle.remove(); - } } componentDidUpdate( prevProps ) { @@ -87,10 +74,6 @@ class NativeEditorProvider extends Component { } } - setTitleRef( titleRef ) { - this.postTitleRef = titleRef; - } - serializeToNativeAction() { if ( this.props.mode === 'text' ) { this.updateHtmlAction( this.props.getEditedPostContent() ); diff --git a/packages/format-library/src/link/test/modal.native.js b/packages/format-library/src/link/test/modal.native.js index 03594a4ef1c380..44153ea3a40185 100644 --- a/packages/format-library/src/link/test/modal.native.js +++ b/packages/format-library/src/link/test/modal.native.js @@ -23,7 +23,7 @@ describe( 'LinksUI', () => { onRemove={ onRemove } onClose={ jest.fn() } /> - ).dive(); // -> dive() removes the HOC layer that was blocking access to ModalLinkUI + ).dive().dive(); // -> dive() removes the HOC layer that was blocking access to ModalLinkUI // When @@ -52,8 +52,10 @@ describe( 'LinksUI', () => { // When // Simulate user typing on the URL Cell. - const bottomSheet = wrapper.find( 'BottomSheet' ).first(); - const cell = bottomSheet.find( 'BottomSheetCell' ).first(); + const bottomSheet = wrapper.dive().find( 'BottomSheet' ).first(); + // withTheme is type "_class", we search for it and dive into BottomSheetCell + const cell = bottomSheet.dive().find( '_class' ).first().dive(); + cell.simulate( 'changeValue', 'wordpress.com' ); // Close the BottomSheet diff --git a/packages/rich-text/src/component/index.native.js b/packages/rich-text/src/component/index.native.js index fe705d8ad5b386..6191e627d56962 100644 --- a/packages/rich-text/src/component/index.native.js +++ b/packages/rich-text/src/component/index.native.js @@ -20,6 +20,7 @@ import { childrenBlock } from '@wordpress/blocks'; import { decodeEntities } from '@wordpress/html-entities'; import { BACKSPACE } from '@wordpress/keycodes'; import { isURL } from '@wordpress/url'; +import { useStyle, withTheme } from '@wordpress/components'; /** * Internal dependencies @@ -770,25 +771,28 @@ export class RichText extends Component { style, __unstableIsSelected: isSelected, children, + theme, } = this.props; const record = this.getRecord(); const html = this.getHtmlToRender( record, tagName ); - let minHeight = styles[ 'rich-text' ].minHeight; + let minHeight = styles.richText.minHeight; if ( style && style.minHeight ) { minHeight = style.minHeight; } + const placeholderStyle = useStyle( styles.richTextPlaceholder, styles.richTextPlaceholderDark, theme ); + const { color: defaultPlaceholderTextColor, - } = styles[ 'rich-text-placeholder' ]; + } = placeholderStyle; const { color: defaultColor, textDecorationColor: defaultTextDecorationColor, fontFamily: defaultFontFamily, - } = styles[ 'rich-text' ]; + } = useStyle( styles.richText, styles.richTextDark, theme ); let selection = null; if ( this.needsSelectionUpdate ) { @@ -817,6 +821,8 @@ export class RichText extends Component { this.firedAfterTextChanged = false; } + const dynamicStyle = useStyle( style, styles.richTextDark, theme ); + return ( <View> { children && children( { @@ -833,7 +839,7 @@ export class RichText extends Component { } } } style={ { - ...style, + ...dynamicStyle, minHeight: Math.max( minHeight, this.state.height ), } } text={ { text: html, eventCount: this.lastEventCount, selection } } @@ -878,4 +884,5 @@ export default compose( [ withSelect( ( select ) => ( { formatTypes: select( 'core/rich-text' ).getFormatTypes(), } ) ), + withTheme, ] )( RichText ); diff --git a/packages/rich-text/src/component/style.native.scss b/packages/rich-text/src/component/style.native.scss index 6481c415694127..4ed93f7f70239d 100644 --- a/packages/rich-text/src/component/style.native.scss +++ b/packages/rich-text/src/component/style.native.scss @@ -1,11 +1,21 @@ -.rich-text { +.richText { font-family: $default-regular-font; min-height: $min-height-paragraph; color: $gray-900; text-decoration-color: $blue-500; } -.rich-text-placeholder { +.richTextDark { + color: $white; + text-decoration-color: $blue-30; + background-color: $black; +} + +.richTextPlaceholder { color: $gray; } + +.richTextPlaceholderDark { + color: $gray-50; +} diff --git a/test/native/__mocks__/react-native-dark-mode/index.js b/test/native/__mocks__/react-native-dark-mode/index.js new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/test/native/__mocks__/styleMock.js b/test/native/__mocks__/styleMock.js index 182af41388dc0a..4e63b494feff94 100644 --- a/test/native/__mocks__/styleMock.js +++ b/test/native/__mocks__/styleMock.js @@ -15,7 +15,7 @@ module.exports = { blockCode: { fontFamily: 'serif', }, - 'rich-text': { + richText: { fontFamily: 'serif', minHeight: 30, }, @@ -66,4 +66,13 @@ module.exports = { iconUploading: { fill: 'gray', }, + placeholder: { + color: 'gray', + }, + richTextPlaceholder: { + color: 'gray', + }, + unsupportedBlockIcon: { + color: 'white', + }, }; diff --git a/test/native/setup.js b/test/native/setup.js index cfd2417a11ad9d..c0e3e0942a9180 100644 --- a/test/native/setup.js +++ b/test/native/setup.js @@ -21,6 +21,15 @@ jest.mock( 'react-native-gutenberg-bridge', () => { }; } ); +jest.mock( 'react-native-dark-mode', () => { + return { + eventEmitter: { + on: jest.fn(), + }, + initialMode: 'light', + }; +} ); + jest.mock( 'react-native-modal', () => () => 'Modal' ); jest.mock( 'react-native-hr', () => () => 'Hr' );