diff --git a/packages/block-editor/src/components/block-variation-picker/index.native.js b/packages/block-editor/src/components/block-variation-picker/index.native.js
new file mode 100644
index 00000000000000..0884b5aebdaed2
--- /dev/null
+++ b/packages/block-editor/src/components/block-variation-picker/index.native.js
@@ -0,0 +1,133 @@
+/**
+ * External dependencies
+ */
+import {
+ ScrollView,
+ View,
+ Text,
+ TouchableWithoutFeedback,
+ Platform,
+} from 'react-native';
+import { map } from 'lodash';
+
+/**
+ * WordPress dependencies
+ */
+import { withSelect, useDispatch } from '@wordpress/data';
+import { compose, usePreferredColorSchemeStyle } from '@wordpress/compose';
+import { createBlock } from '@wordpress/blocks';
+import { __ } from '@wordpress/i18n';
+import {
+ PanelBody,
+ BottomSheet,
+ FooterMessageControl,
+} from '@wordpress/components';
+import { Icon, close } from '@wordpress/icons';
+import { useMemo } from '@wordpress/element';
+
+/**
+ * Internal dependencies
+ */
+import MenuItem from '../inserter/menu-item';
+import styles from './style.scss';
+
+const hitSlop = { top: 22, bottom: 22, left: 22, right: 22 };
+
+function createBlocksFromInnerBlocksTemplate( innerBlocksTemplate ) {
+ return map(
+ innerBlocksTemplate,
+ ( [ name, attributes, innerBlocks = [] ] ) =>
+ createBlock(
+ name,
+ attributes,
+ createBlocksFromInnerBlocksTemplate( innerBlocks )
+ )
+ );
+}
+
+function BlockVariationPicker( { isVisible, onClose, clientId, variations } ) {
+ const { replaceInnerBlocks } = useDispatch( 'core/block-editor' );
+ const isIOS = Platform.OS === 'ios';
+
+ const cancelButtonStyle = usePreferredColorSchemeStyle(
+ styles.cancelButton,
+ styles.cancelButtonDark
+ );
+
+ const leftButton = useMemo(
+ () => (
+
+
+ { isIOS ? (
+
+ { __( 'Cancel' ) }
+
+ ) : (
+
+ ) }
+
+
+ ),
+ [ onClose, cancelButtonStyle ]
+ );
+
+ const onVariationSelect = ( variation ) => {
+ replaceInnerBlocks(
+ clientId,
+ createBlocksFromInnerBlocksTemplate( variation.innerBlocks ),
+ false
+ );
+ onClose();
+ };
+
+ return (
+
+
+ { variations.map( ( v ) => {
+ return (
+
+
+
+
+
+ );
+}
+
+export default compose(
+ withSelect( ( select, {} ) => {
+ const { getBlockVariations } = select( 'core/blocks' );
+
+ return {
+ date: getBlockVariations( 'core/columns', 'block' ),
+ };
+ } )
+)( BlockVariationPicker );
diff --git a/packages/block-editor/src/components/block-variation-picker/style.native.scss b/packages/block-editor/src/components/block-variation-picker/style.native.scss
new file mode 100644
index 00000000000000..8c86b4506cc4b1
--- /dev/null
+++ b/packages/block-editor/src/components/block-variation-picker/style.native.scss
@@ -0,0 +1,28 @@
+.contentContainerStyle {
+ flex-direction: row;
+ padding-bottom: $grid-unit-15;
+ padding-left: $grid-unit-20 / 2;
+ padding-right: $grid-unit-20 / 2;
+}
+
+.containerStyle {
+ padding-top: $grid-unit-15;
+}
+
+.contentStyle {
+ padding-left: 0;
+ padding-right: 0;
+}
+
+.cancelButton {
+ color: $blue-wordpress;
+ font-size: 16px;
+}
+
+.cancelButtonDark {
+ color: $blue-30;
+}
+
+.closeIcon {
+ color: $gray;
+}
diff --git a/packages/block-editor/src/components/index.native.js b/packages/block-editor/src/components/index.native.js
index 07b298c6baa53b..2dff50cea14cb9 100644
--- a/packages/block-editor/src/components/index.native.js
+++ b/packages/block-editor/src/components/index.native.js
@@ -46,6 +46,7 @@ export {
export { default as BlockList } from './block-list';
export { default as BlockMover } from './block-mover';
export { default as BlockToolbar } from './block-toolbar';
+export { default as BlockVariationPicker } from './block-variation-picker';
export { default as DefaultBlockAppender } from './default-block-appender';
export { default as __unstableEditorStyles } from './editor-styles';
export { default as Inserter } from './inserter';
diff --git a/packages/block-editor/src/components/inserter/menu-item.native.js b/packages/block-editor/src/components/inserter/menu-item.native.js
index 97c3de091b03b5..be47452eae1fb9 100644
--- a/packages/block-editor/src/components/inserter/menu-item.native.js
+++ b/packages/block-editor/src/components/inserter/menu-item.native.js
@@ -76,7 +76,7 @@ class MenuItem extends Component {
>
diff --git a/packages/block-library/src/column/column-preview.native.js b/packages/block-library/src/column/column-preview.native.js
new file mode 100644
index 00000000000000..2b942be96dfe83
--- /dev/null
+++ b/packages/block-library/src/column/column-preview.native.js
@@ -0,0 +1,45 @@
+/**
+ * External dependencies
+ */
+import { View } from 'react-native';
+
+/**
+ * WordPress dependencies
+ */
+import { usePreferredColorSchemeStyle } from '@wordpress/compose';
+
+/**
+ * Internal dependencies
+ */
+import styles from './editor.scss';
+
+function ColumnsPreview( { columnWidths, selectedColumnIndex } ) {
+ const columnsPreviewStyle = usePreferredColorSchemeStyle(
+ styles.columnsPreview,
+ styles.columnsPreviewDark
+ );
+
+ const columnIndicatorStyle = usePreferredColorSchemeStyle(
+ styles.columnIndicator,
+ styles.columnIndicatorDark
+ );
+
+ return (
+
+ { columnWidths.map( ( width, index ) => {
+ const isSelectedColumn = index === selectedColumnIndex;
+ return (
+
+ );
+ } ) }
+
+ );
+}
+
+export default ColumnsPreview;
diff --git a/packages/block-library/src/column/edit.native.js b/packages/block-library/src/column/edit.native.js
index 70d519ca2e78c6..cd125ef7ac153e 100644
--- a/packages/block-library/src/column/edit.native.js
+++ b/packages/block-library/src/column/edit.native.js
@@ -12,11 +12,20 @@ import {
InnerBlocks,
BlockControls,
BlockVerticalAlignmentToolbar,
+ InspectorControls,
} from '@wordpress/block-editor';
+import {
+ PanelBody,
+ RangeControl,
+ FooterMessageControl,
+} from '@wordpress/components';
+import { __ } from '@wordpress/i18n';
/**
* Internal dependencies
*/
import styles from './editor.scss';
+import ColumnsPreview from './column-preview';
+import { getColumnWidths } from '../columns/utils';
function ColumnEdit( {
attributes,
@@ -26,6 +35,9 @@ function ColumnEdit( {
getStylesFromColorScheme,
isParentSelected,
contentStyle,
+ columns,
+ columnCount,
+ selectedColumnIndex,
} ) {
const { verticalAlignment } = attributes;
@@ -33,6 +45,16 @@ function ColumnEdit( {
setAttributes( { verticalAlignment: alignment } );
};
+ const onWidthChange = ( width ) => {
+ setAttributes( {
+ width,
+ } );
+ };
+
+ const columnWidths = Object.values(
+ getColumnWidths( columns, columnCount )
+ );
+
if ( ! isSelected && ! hasChildren ) {
return (
+ />
);
}
@@ -57,6 +79,31 @@ function ColumnEdit( {
value={ verticalAlignment }
/>
+
+
+
+ }
+ />
+
+
+
+
+
+
+
+
) }
@@ -231,7 +245,8 @@ const ColumnsEditContainerWrapper = withDispatch(
if ( isAddingColumn ) {
// Get verticalAlignment from Columns block to set the same to new Column
- const { verticalAlignment } = getBlockAttributes( clientId );
+ const { verticalAlignment } =
+ getBlockAttributes( clientId ) || {};
innerBlocks = [
...innerBlocks,
@@ -283,20 +298,46 @@ const ColumnsEditContainerWrapper = withDispatch(
)( ColumnsEditContainer );
const ColumnsEdit = ( props ) => {
- const { clientId } = props;
- const { columnCount } = useSelect(
+ const { clientId, isSelected } = props;
+ const { columnCount, isDefaultColumns } = useSelect(
( select ) => {
- const { getBlockCount } = select( 'core/block-editor' );
+ const { getBlockCount, getBlock } = select( 'core/block-editor' );
+ const block = getBlock( clientId );
+ const innerBlocks = block?.innerBlocks;
+ const isContentEmpty = map(
+ innerBlocks,
+ ( innerBlock ) => innerBlock.innerBlocks.length
+ );
return {
columnCount: getBlockCount( clientId ),
+ isDefaultColumns: ! compact( isContentEmpty ).length,
};
},
[ clientId ]
);
+ const [ isVisible, setIsVisible ] = useState( false );
+
+ useEffect( () => {
+ if ( isSelected && isDefaultColumns ) {
+ delay( () => setIsVisible( true ), 100 );
+ }
+ }, [] );
+
return (
-
+ <>
+
+ setIsVisible( false ) }
+ clientId={ clientId }
+ isVisible={ isVisible }
+ />
+ >
);
};
diff --git a/packages/components/src/mobile/bottom-sheet/footer-message-cell.native.js b/packages/components/src/mobile/bottom-sheet/footer-message-cell.native.js
index f9714db0ec5ec3..2163224074c1d3 100644
--- a/packages/components/src/mobile/bottom-sheet/footer-message-cell.native.js
+++ b/packages/components/src/mobile/bottom-sheet/footer-message-cell.native.js
@@ -8,14 +8,14 @@ import { withPreferredColorScheme } from '@wordpress/compose';
import Cell from './cell';
import styles from './styles.scss';
-function FooterMessageCell( props ) {
+function FooterMessageCell( { textAlign = 'center', ...props } ) {
return (
|
);
}
diff --git a/packages/components/src/mobile/bottom-sheet/index.native.js b/packages/components/src/mobile/bottom-sheet/index.native.js
index ade17662f827df..f617098f2ac352 100644
--- a/packages/components/src/mobile/bottom-sheet/index.native.js
+++ b/packages/components/src/mobile/bottom-sheet/index.native.js
@@ -281,6 +281,7 @@ class BottomSheet extends Component {
onDismiss,
isChildrenScrollable,
children,
+ withHeaderSeparator = false,
...rest
} = this.props;
const {
@@ -310,24 +311,16 @@ class BottomSheet extends Component {
},
} );
- const getHeader = () => (
-
-
- { leftButton }
-
- { title }
-
- { rightButton }
-
-
-
- );
-
const backgroundStyle = getStylesFromColorScheme(
styles.background,
styles.backgroundDark
);
+ const bottomSheetHeaderTitleStyle = getStylesFromColorScheme(
+ styles.bottomSheetHeaderTitle,
+ styles.bottomSheetHeaderTitleDark
+ );
+
const listProps = {
disableScrollViewPanResponder: true,
bounces,
@@ -349,6 +342,22 @@ class BottomSheet extends Component {
const WrapperView = isChildrenScrollable ? View : ScrollView;
+ const getHeader = () => (
+ <>
+
+ { leftButton }
+
+ { title }
+
+ { rightButton }
+
+ { withHeaderSeparator && }
+ >
+ );
+
return (
+ { rangePreview }
{ options.footer && (
-
+
) }
{ actions && }
diff --git a/packages/components/src/notice/list.native.js b/packages/components/src/notice/list.native.js
index b91a21407c6c3f..6c43e25abbd60c 100644
--- a/packages/components/src/notice/list.native.js
+++ b/packages/components/src/notice/list.native.js
@@ -35,7 +35,7 @@ class NoticeList extends Component {
}
return (
-
+
{ shouldStack ? (
notices
.reverse()