From 89664ebce2a16230e68efd66609bc3fc67d22b2a Mon Sep 17 00:00:00 2001 From: Luke Walczak Date: Tue, 3 Sep 2019 12:18:11 +0200 Subject: [PATCH] Support group block on mobile (#17251) * First working version of the MediaText component for native mobile * Fix adding a block to an innerblock list * Disable mediaText on production * MediaText native: improve editor visuals * Move BlockToolbar from BlockList to Layout * Remove BlockEditorProvider from BlockList and add native version of EditorProvider to Editor. Plus support InsertionPoint and BlockListAppender * Update BlockMover for native to hide if locked or if it's the only block * Make the vertical align button work, add more styling options for toolbar buttons * Make sure registerCoreBlocks does not break in production * Copy docblock comment from the web version for registerCoreBlocks * Fix focusing on the media placeholder * Only support adding image for now * Update usage of MediaPlaceholder in MediaContainer * Enable autoScroll for just the out most block list * Fix JS Unit tests * Roll back to IconButton refactor and fix tests * Fix BlockVerticalAlignmentToolbar buttons style on mobile * Fix thing for web and ensure ariaPressed is always passed down * Use AriaPressed directly to style SVG on mobile * Update snapshots * Support group block on mobile * Extend shouldShowInsertionPoint condition to be false when group is selected * Code refactor * Update package-lock --- .../block-list-appender/index.native.js | 7 +++ .../src/components/block-list/index.native.js | 36 ++++++++----- .../button-block-appender/index.native.js | 48 +++++++++++++++++ .../button-block-appender/styles.native.scss | 17 +++++++ .../components/inner-blocks/index.native.js | 1 + .../block-library/src/group/edit.native.js | 51 +++++++++++++++++++ .../src/group/editor.native.scss | 6 +++ packages/block-library/src/index.native.js | 5 +- .../components/src/button/index.native.js | 5 +- packages/components/src/index.native.js | 1 + 10 files changed, 161 insertions(+), 16 deletions(-) create mode 100644 packages/block-editor/src/components/button-block-appender/index.native.js create mode 100644 packages/block-editor/src/components/button-block-appender/styles.native.scss create mode 100644 packages/block-library/src/group/edit.native.js create mode 100644 packages/block-library/src/group/editor.native.scss diff --git a/packages/block-editor/src/components/block-list-appender/index.native.js b/packages/block-editor/src/components/block-list-appender/index.native.js index 9a6a24c5575172..6d8fb4e6cee976 100644 --- a/packages/block-editor/src/components/block-list-appender/index.native.js +++ b/packages/block-editor/src/components/block-list-appender/index.native.js @@ -20,11 +20,18 @@ function BlockListAppender( { rootClientId, canInsertDefaultBlock, isLocked, + renderAppender: CustomAppender, } ) { if ( isLocked ) { return null; } + if ( CustomAppender ) { + return ( + + ); + } + if ( canInsertDefaultBlock ) { return ( - ); } render() { + const { clearSelectedBlock, blockClientIds, isFullyBordered, title, header, withFooter = true, renderAppender } = this.props; + return ( + + { renderAppender && blockClientIds.length > 0 && + + } ); } @@ -160,12 +165,15 @@ export default compose( [ getSelectedBlockClientId, getBlockInsertionPoint, isBlockInsertionPointVisible, + getSelectedBlock, } = select( 'core/block-editor' ); const selectedBlockClientId = getSelectedBlockClientId(); const blockClientIds = getBlockOrder( rootClientId ); const insertionPoint = getBlockInsertionPoint(); const blockInsertionPointIsVisible = isBlockInsertionPointVisible(); + const selectedBlock = getSelectedBlock(); + const isSelectedGroup = selectedBlock && selectedBlock.name === 'core/group'; const shouldShowInsertionPoint = ( clientId ) => { return ( blockInsertionPointIsVisible && @@ -177,7 +185,7 @@ export default compose( [ const selectedBlockIndex = getBlockIndex( selectedBlockClientId ); const shouldShowBlockAtIndex = ( index ) => { const shouldHideBlockAtIndex = ( - blockInsertionPointIsVisible && + ! isSelectedGroup && blockInsertionPointIsVisible && // if `index` === `insertionPoint.index`, then block is replaceable index === insertionPoint.index && // only hide selected block diff --git a/packages/block-editor/src/components/button-block-appender/index.native.js b/packages/block-editor/src/components/button-block-appender/index.native.js new file mode 100644 index 00000000000000..b01d3b65109856 --- /dev/null +++ b/packages/block-editor/src/components/button-block-appender/index.native.js @@ -0,0 +1,48 @@ +/** + * External dependencies + */ +import { View } from 'react-native'; + +/** + * WordPress dependencies + */ +import { Button, Dashicon } from '@wordpress/components'; + +/** + * Internal dependencies + */ +import Inserter from '../inserter'; +import styles from './styles.scss'; + +function ButtonBlockAppender( { rootClientId } ) { + return ( + <> + ( + + ) } + isAppender + /> + + ); +} + +/** + * @see https://github.com/WordPress/gutenberg/blob/master/packages/block-editor/src/components/button-block-appender/README.md + */ +export default ButtonBlockAppender; diff --git a/packages/block-editor/src/components/button-block-appender/styles.native.scss b/packages/block-editor/src/components/button-block-appender/styles.native.scss new file mode 100644 index 00000000000000..0fd4cf46274e02 --- /dev/null +++ b/packages/block-editor/src/components/button-block-appender/styles.native.scss @@ -0,0 +1,17 @@ +.appender { + align-items: center; + justify-content: center; + background-color: $gray-light; + padding: 12px; + background-color: $white; + border: $border-width solid $light-gray-500; + border-radius: 4px; +} + +.addBlockButton { + color: $white; + background-color: $gray; + border-radius: $icon-button-size-small / 2; + overflow: hidden; + size: $icon-button-size-small; +} diff --git a/packages/block-editor/src/components/inner-blocks/index.native.js b/packages/block-editor/src/components/inner-blocks/index.native.js index d0515d6d8a58ac..2b6a6c9320c923 100644 --- a/packages/block-editor/src/components/inner-blocks/index.native.js +++ b/packages/block-editor/src/components/inner-blocks/index.native.js @@ -121,6 +121,7 @@ class InnerBlocks extends Component { ) } diff --git a/packages/block-library/src/group/edit.native.js b/packages/block-library/src/group/edit.native.js new file mode 100644 index 00000000000000..32c87e3863c881 --- /dev/null +++ b/packages/block-library/src/group/edit.native.js @@ -0,0 +1,51 @@ + +/** + * External dependencies + */ +import { View } from 'react-native'; + +/** + * WordPress dependencies + */ +import { withSelect } from '@wordpress/data'; +import { compose } from '@wordpress/compose'; +import { + InnerBlocks, + withColors, +} from '@wordpress/block-editor'; +/** + * Internal dependencies + */ +import styles from './editor.scss'; + +function GroupEdit( { + hasInnerBlocks, + isSelected, +} ) { + if ( ! isSelected && ! hasInnerBlocks ) { + return ( + + ); + } + + return ( + + ); +} + +export default compose( [ + withColors( 'backgroundColor' ), + withSelect( ( select, { clientId } ) => { + const { + getBlock, + } = select( 'core/block-editor' ); + + const block = getBlock( clientId ); + + return { + hasInnerBlocks: !! ( block && block.innerBlocks.length ), + }; + } ), +] )( GroupEdit ); diff --git a/packages/block-library/src/group/editor.native.scss b/packages/block-library/src/group/editor.native.scss new file mode 100644 index 00000000000000..5edfa582287ef5 --- /dev/null +++ b/packages/block-library/src/group/editor.native.scss @@ -0,0 +1,6 @@ +.groupPlaceholder { + padding: 12px; + background-color: $white; + border: $border-width dashed $light-gray-500; + border-radius: 4px; +} diff --git a/packages/block-library/src/index.native.js b/packages/block-library/src/index.native.js index ebfeefe38b9dd1..89635d7218b847 100644 --- a/packages/block-library/src/index.native.js +++ b/packages/block-library/src/index.native.js @@ -49,6 +49,7 @@ import * as textColumns from './text-columns'; import * as verse from './verse'; import * as video from './video'; import * as tagCloud from './tag-cloud'; +import * as group from './group'; export const coreBlocks = [ // Common blocks are grouped at the top to prioritize their display @@ -142,7 +143,9 @@ export const registerCoreBlocks = () => { list, quote, // eslint-disable-next-line no-undef - typeof __DEV__ !== 'undefined' && __DEV__ ? mediaText : null, + !! __DEV__ ? mediaText : null, + // eslint-disable-next-line no-undef + !! __DEV__ ? group : null, ].forEach( registerBlock ); setDefaultBlockName( paragraph.name ); diff --git a/packages/components/src/button/index.native.js b/packages/components/src/button/index.native.js index 78d10226e26def..f7fdd94d13f85d 100644 --- a/packages/components/src/button/index.native.js +++ b/packages/components/src/button/index.native.js @@ -19,6 +19,8 @@ const styles = StyleSheet.create( { flexDirection: 'row', justifyContent: 'center', alignItems: 'center', + }, + fixedRatio: { aspectRatio: 1, }, buttonActive: { @@ -28,7 +30,6 @@ const styles = StyleSheet.create( { alignItems: 'center', borderRadius: 6, borderColor: '#2e4453', - aspectRatio: 1, backgroundColor: '#2e4453', }, subscriptInactive: { @@ -55,6 +56,7 @@ export default function Button( props ) { onClick, disabled, hint, + fixedRatio = true, 'aria-disabled': ariaDisabled, 'aria-label': ariaLabel, 'aria-pressed': ariaPressed, @@ -65,6 +67,7 @@ export default function Button( props ) { const buttonViewStyle = { opacity: isDisabled ? 0.2 : 1, + ...( fixedRatio && styles.fixedRatio ), ...( ariaPressed ? styles.buttonActive : styles.buttonInactive ), }; diff --git a/packages/components/src/index.native.js b/packages/components/src/index.native.js index d09b157160003c..209507ec96b440 100644 --- a/packages/components/src/index.native.js +++ b/packages/components/src/index.native.js @@ -10,6 +10,7 @@ export { default as Spinner } from './spinner'; export { createSlotFill, Slot, Fill, Provider as SlotFillProvider } from './slot-fill'; export { default as BaseControl } from './base-control'; export { default as TextareaControl } from './textarea-control'; +export { default as Button } from './button'; // Higher-Order Components export { default as withConstrainedTabbing } from './higher-order/with-constrained-tabbing';