From 7993da7eb3d7d3cb285c19b7997b6c96a2b5e383 Mon Sep 17 00:00:00 2001 From: Tugdual de Kerviler Date: Wed, 19 Jun 2019 13:41:52 +0200 Subject: [PATCH 1/2] Add native support for BlockListBlock (Ported from Gutenberg mobile) --- .../src/components/block-list/block.native.js | 221 ++++++++++++++++++ .../components/block-list/block.native.scss | 38 +++ .../src/components/index.native.js | 1 + .../block-library/src/missing/index.native.js | 26 +++ 4 files changed, 286 insertions(+) create mode 100644 packages/block-editor/src/components/block-list/block.native.js create mode 100644 packages/block-editor/src/components/block-list/block.native.scss create mode 100644 packages/block-library/src/missing/index.native.js diff --git a/packages/block-editor/src/components/block-list/block.native.js b/packages/block-editor/src/components/block-list/block.native.js new file mode 100644 index 0000000000000..6c3dc97c959cc --- /dev/null +++ b/packages/block-editor/src/components/block-list/block.native.js @@ -0,0 +1,221 @@ +/** + * External dependencies + */ +import { + View, + Text, + TouchableWithoutFeedback, +} from 'react-native'; + +/** + * WordPress dependencies + */ +import { Component } from '@wordpress/element'; +import { withDispatch, withSelect } from '@wordpress/data'; +import { compose } from '@wordpress/compose'; +import { getBlockType } from '@wordpress/blocks'; +import { BlockEdit, BlockInvalidWarning, BlockMobileToolbar } from '@wordpress/block-editor'; +import { __, sprintf } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import styles from './block.scss'; + +class BlockListBlock extends Component { + constructor() { + super( ...arguments ); + + this.insertBlocksAfter = this.insertBlocksAfter.bind( this ); + this.onFocus = this.onFocus.bind( this ); + + this.state = { + isFullyBordered: false, + }; + } + + onFocus() { + if ( ! this.props.isSelected ) { + this.props.onSelect(); + } + } + + insertBlocksAfter( blocks ) { + this.props.onInsertBlocks( blocks, this.props.order + 1 ); + + if ( blocks[ 0 ] ) { + // focus on the first block inserted + this.props.onSelect( blocks[ 0 ].clientId ); + } + } + + getBlockForType() { + return ( + + ); + } + + renderBlockTitle() { + return ( + + BlockType: { this.props.name } + + ); + } + + getAccessibilityLabel() { + const { attributes, name, order, title, getAccessibilityLabelExtra } = this.props; + + let blockName = ''; + + if ( name === 'core/missing' ) { // is the block unrecognized? + blockName = title; + } else { + blockName = sprintf( + /* translators: accessibility text. %s: block name. */ + __( '%s Block' ), + title, //already localized + ); + } + + blockName += '. ' + sprintf( __( 'Row %d.' ), order + 1 ); + + if ( getAccessibilityLabelExtra ) { + const blockAccessibilityLabel = getAccessibilityLabelExtra( attributes ); + blockName += blockAccessibilityLabel ? ' ' + blockAccessibilityLabel : ''; + } + + return blockName; + } + + render() { + const { + borderStyle, + clientId, + focusedBorderColor, + icon, + isSelected, + isValid, + showTitle, + title, + } = this.props; + + const borderColor = isSelected ? focusedBorderColor : 'transparent'; + + const accessibilityLabel = this.getAccessibilityLabel(); + + return ( + // accessible prop needs to be false to access children + // https://facebook.github.io/react-native/docs/accessibility#accessible-ios-android + + + { showTitle && this.renderBlockTitle() } + + { isValid && this.getBlockForType() } + { ! isValid && + + } + + { isSelected && } + + + + ); + } +} + +export default compose( [ + withSelect( ( select, { clientId, rootClientId } ) => { + const { + getBlockIndex, + getBlocks, + isBlockSelected, + __unstableGetBlockWithoutInnerBlocks, + } = select( 'core/block-editor' ); + const order = getBlockIndex( clientId, rootClientId ); + const isSelected = isBlockSelected( clientId ); + const isFirstBlock = order === 0; + const isLastBlock = order === getBlocks().length - 1; + const block = __unstableGetBlockWithoutInnerBlocks( clientId ); + const { name, attributes, isValid } = block || {}; + const blockType = getBlockType( name || 'core/missing' ); + const title = blockType.title; + const icon = blockType.icon; + const getAccessibilityLabelExtra = blockType.__experimentalGetAccessibilityLabel; + + return { + icon, + name: name || 'core/missing', + order, + title, + attributes, + blockType, + isFirstBlock, + isLastBlock, + isSelected, + isValid, + getAccessibilityLabelExtra, + }; + } ), + withDispatch( ( dispatch, ownProps, { select } ) => { + const { + insertBlocks, + mergeBlocks, + replaceBlocks, + selectBlock, + updateBlockAttributes, + } = dispatch( 'core/block-editor' ); + + return { + mergeBlocks( forward ) { + const { clientId } = ownProps; + const { + getPreviousBlockClientId, + getNextBlockClientId, + } = select( 'core/block-editor' ); + + if ( forward ) { + const nextBlockClientId = getNextBlockClientId( clientId ); + if ( nextBlockClientId ) { + mergeBlocks( clientId, nextBlockClientId ); + } + } else { + const previousBlockClientId = getPreviousBlockClientId( clientId ); + if ( previousBlockClientId ) { + mergeBlocks( previousBlockClientId, clientId ); + } + } + }, + onInsertBlocks( blocks: Array, index: number ) { + insertBlocks( blocks, index, ownProps.rootClientId ); + }, + onSelect( clientId = ownProps.clientId, initialPosition ) { + selectBlock( clientId, initialPosition ); + }, + onChange: ( attributes: Object ) => { + updateBlockAttributes( ownProps.clientId, attributes ); + }, + onReplace( blocks: Array, indexToSelect: number ) { + replaceBlocks( [ ownProps.clientId ], blocks, indexToSelect ); + }, + }; + } ), +] )( BlockListBlock ); diff --git a/packages/block-editor/src/components/block-list/block.native.scss b/packages/block-editor/src/components/block-list/block.native.scss new file mode 100644 index 0000000000000..b997cddc72307 --- /dev/null +++ b/packages/block-editor/src/components/block-list/block.native.scss @@ -0,0 +1,38 @@ +.blockHolder { + flex: 1 1 auto; +} + +.blockContainer { + background-color: $white; + padding-left: 16px; + padding-right: 16px; + padding-top: 12px; + padding-bottom: 12px; +} + +.blockContainerFocused { + background-color: $white; + padding-left: 16px; + padding-right: 16px; + padding-top: 12px; + padding-bottom: 0; // will be flushed into inline toolbar height +} + +.blockTitle { + background-color: $gray; + padding-left: 8px; + padding-top: 4px; + padding-bottom: 4px; +} + +.aztec_container { + flex: 1; +} + +.blockCode { + font-family: $default-monospace-font; +} + +.blockText { + min-height: 50px; +} diff --git a/packages/block-editor/src/components/index.native.js b/packages/block-editor/src/components/index.native.js index cd3a53b3f1299..49038ecd6ef2f 100644 --- a/packages/block-editor/src/components/index.native.js +++ b/packages/block-editor/src/components/index.native.js @@ -19,6 +19,7 @@ export { default as URLInput } from './url-input'; export { default as BlockInvalidWarning } from './block-list/block-invalid-warning'; // Content Related Components +export { default as BlockListBlock } from './block-list/block'; export { default as BlockMobileToolbar } from './block-list/block-mobile-toolbar'; export { default as BlockMover } from './block-mover'; export { default as BlockToolbar } from './block-toolbar'; diff --git a/packages/block-library/src/missing/index.native.js b/packages/block-library/src/missing/index.native.js new file mode 100644 index 0000000000000..e902faef9b403 --- /dev/null +++ b/packages/block-library/src/missing/index.native.js @@ -0,0 +1,26 @@ +/** + * WordPress dependencies + */ +import { coreBlocks } from '@wordpress/block-library'; + +/** + * Internal dependencies + */ +import { settings as webSettings } from './index.js'; + +export { metadata, name } from './index.js'; + +export const settings = { + ...webSettings, + __experimentalGetAccessibilityLabel( attributes ) { + const { originalName } = attributes; + + const originalBlockType = originalName && coreBlocks[ originalName ]; + + if ( originalBlockType ) { + return originalBlockType.settings.title || originalName; + } + + return ''; + }, +}; From 27a0abb7304d45cdcdfef3c92933644fab57cb25 Mon Sep 17 00:00:00 2001 From: Tugdual de Kerviler Date: Wed, 19 Jun 2019 15:55:26 +0200 Subject: [PATCH 2/2] Remove Flow syntax in withDispatch --- .../block-editor/src/components/block-list/block.native.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/block-editor/src/components/block-list/block.native.js b/packages/block-editor/src/components/block-list/block.native.js index 6c3dc97c959cc..3d93500ce9d88 100644 --- a/packages/block-editor/src/components/block-list/block.native.js +++ b/packages/block-editor/src/components/block-list/block.native.js @@ -204,16 +204,16 @@ export default compose( [ } } }, - onInsertBlocks( blocks: Array, index: number ) { + onInsertBlocks( blocks, index ) { insertBlocks( blocks, index, ownProps.rootClientId ); }, onSelect( clientId = ownProps.clientId, initialPosition ) { selectBlock( clientId, initialPosition ); }, - onChange: ( attributes: Object ) => { + onChange: ( attributes ) => { updateBlockAttributes( ownProps.clientId, attributes ); }, - onReplace( blocks: Array, indexToSelect: number ) { + onReplace( blocks, indexToSelect ) { replaceBlocks( [ ownProps.clientId ], blocks, indexToSelect ); }, };