Skip to content

Commit

Permalink
Support group block on mobile (#17251)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
lukewalczak authored and pinarol committed Sep 3, 2019
1 parent 14d482b commit 89664eb
Show file tree
Hide file tree
Showing 10 changed files with 161 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,18 @@ function BlockListAppender( {
rootClientId,
canInsertDefaultBlock,
isLocked,
renderAppender: CustomAppender,
} ) {
if ( isLocked ) {
return null;
}

if ( CustomAppender ) {
return (
<CustomAppender />
);
}

if ( canInsertDefaultBlock ) {
return (
<DefaultBlockAppender
Expand Down
36 changes: 22 additions & 14 deletions packages/block-editor/src/components/block-list/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { KeyboardAwareFlatList, ReadableContentView, useStyle, withTheme } from
*/
import styles from './style.scss';
import BlockListBlock from './block';
import DefaultBlockAppender from '../default-block-appender';
import BlockListAppender from '../block-list-appender';

const innerToolbarHeight = 44;

Expand Down Expand Up @@ -60,23 +60,21 @@ export class BlockList extends Component {
renderDefaultBlockAppender() {
return (
<ReadableContentView>
<DefaultBlockAppender
<BlockListAppender
rootClientId={ this.props.rootClientId }
containerStyle={ [
styles.blockContainerFocused,
this.blockHolderBorderStyle(),
{ borderColor: 'transparent' },
] }
renderAppender={ this.props.renderAppender }
/>
</ReadableContentView>
);
}

render() {
const { clearSelectedBlock, blockClientIds, isFullyBordered, title, header, withFooter = true, renderAppender } = this.props;

return (
<View
style={ { flex: 1 } }
onAccessibilityEscape={ this.props.clearSelectedBlock }
onAccessibilityEscape={ clearSelectedBlock }
>
<KeyboardAwareFlatList
{ ...( Platform.OS === 'android' ? { removeClippedSubviews: false } : {} ) } // Disable clipping on Android to fix focus losing. See https://github.com/wordpress-mobile/gutenberg-mobile/pull/741#issuecomment-472746541
Expand All @@ -86,16 +84,23 @@ export class BlockList extends Component {
extraScrollHeight={ innerToolbarHeight + 10 }
keyboardShouldPersistTaps="always"
style={ useStyle( styles.list, styles.listDark, this.context ) }
data={ this.props.blockClientIds }
extraData={ [ this.props.isFullyBordered ] }
data={ blockClientIds }
extraData={ [ isFullyBordered ] }
keyExtractor={ identity }
renderItem={ this.renderItem }
shouldPreventAutomaticScroll={ this.shouldFlatListPreventAutomaticScroll }
title={ this.props.title }
ListHeaderComponent={ this.props.header }
title={ title }
ListHeaderComponent={ header }
ListEmptyComponent={ this.renderDefaultBlockAppender }
ListFooterComponent={ this.renderBlockListFooter }
ListFooterComponent={ withFooter && this.renderBlockListFooter }
/>

{ renderAppender && blockClientIds.length > 0 &&
<BlockListAppender
rootClientId={ this.props.rootClientId }
renderAppender={ this.props.renderAppender }
/>
}
</View>
);
}
Expand Down Expand Up @@ -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 &&
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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 (
<>
<Inserter
rootClientId={ rootClientId }
renderToggle={ ( { onToggle, disabled, isOpen } ) => (
<Button
onClick={ onToggle }
aria-expanded={ isOpen }
disabled={ disabled }
fixedRatio={ false }
>
<View style={ [ styles.appender, { flex: 1 } ] }>
<Dashicon
icon="plus-alt"
style={ styles.addBlockButton }
color={ styles.addBlockButton.color }
size={ styles.addBlockButton.size }
/>
</View>
</Button>
) }
isAppender
/>
</>
);
}

/**
* @see https://github.com/WordPress/gutenberg/blob/master/packages/block-editor/src/components/button-block-appender/README.md
*/
export default ButtonBlockAppender;
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ class InnerBlocks extends Component {
<BlockList
rootClientId={ clientId }
renderAppender={ renderAppender }
withFooter={ false }
/>
) }
</>
Expand Down
51 changes: 51 additions & 0 deletions packages/block-library/src/group/edit.native.js
Original file line number Diff line number Diff line change
@@ -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 (
<View style={ styles.groupPlaceholder } />
);
}

return (
<InnerBlocks
renderAppender={ isSelected && InnerBlocks.ButtonBlockAppender }
/>
);
}

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 );
6 changes: 6 additions & 0 deletions packages/block-library/src/group/editor.native.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.groupPlaceholder {
padding: 12px;
background-color: $white;
border: $border-width dashed $light-gray-500;
border-radius: 4px;
}
5 changes: 4 additions & 1 deletion packages/block-library/src/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 );
Expand Down
5 changes: 4 additions & 1 deletion packages/components/src/button/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ const styles = StyleSheet.create( {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
},
fixedRatio: {
aspectRatio: 1,
},
buttonActive: {
Expand All @@ -28,7 +30,6 @@ const styles = StyleSheet.create( {
alignItems: 'center',
borderRadius: 6,
borderColor: '#2e4453',
aspectRatio: 1,
backgroundColor: '#2e4453',
},
subscriptInactive: {
Expand All @@ -55,6 +56,7 @@ export default function Button( props ) {
onClick,
disabled,
hint,
fixedRatio = true,
'aria-disabled': ariaDisabled,
'aria-label': ariaLabel,
'aria-pressed': ariaPressed,
Expand All @@ -65,6 +67,7 @@ export default function Button( props ) {

const buttonViewStyle = {
opacity: isDisabled ? 0.2 : 1,
...( fixedRatio && styles.fixedRatio ),
...( ariaPressed ? styles.buttonActive : styles.buttonInactive ),
};

Expand Down
1 change: 1 addition & 0 deletions packages/components/src/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down

0 comments on commit 89664eb

Please sign in to comment.