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';