diff --git a/packages/block-editor/src/components/block-list/block-list-item.native.js b/packages/block-editor/src/components/block-list/block-list-item.native.js
index ef6bbbe1ffc3ce..f1885196f67f75 100644
--- a/packages/block-editor/src/components/block-list/block-list-item.native.js
+++ b/packages/block-editor/src/components/block-list/block-list-item.native.js
@@ -1,246 +1,209 @@
/**
* External dependencies
*/
-import { View, Dimensions } from 'react-native';
+import { View } from 'react-native';
/**
* WordPress dependencies
*/
-import { Component } from '@wordpress/element';
-import { withSelect } from '@wordpress/data';
-import { compose } from '@wordpress/compose';
-import { ReadableContentView, alignmentHelpers } from '@wordpress/components';
+import { useSelect } from '@wordpress/data';
/**
* Internal dependencies
*/
-import BlockListBlock from './block';
-import BlockInsertionPoint from './insertion-point';
+import Block from './block';
import Grid from './grid-item';
-
-import styles from './block-list-item.native.scss';
+import BlockInsertionPoint from './insertion-point';
import { store as blockEditorStore } from '../../store';
+import { useEditorWrapperStyles } from '../../hooks/use-editor-wrapper-styles';
-const stretchStyle = {
- flex: 1,
-};
-
-export class BlockListItem extends Component {
- getMarginHorizontal() {
- const {
- blockAlignment,
- marginHorizontal,
- parentBlockAlignment,
- hasParents,
- blockName,
- parentBlockName,
- parentWidth,
- blockWidth,
- } = this.props;
- const { isFullWidth, isWideWidth, isWider, isContainerRelated } =
- alignmentHelpers;
-
- if ( isFullWidth( blockAlignment ) ) {
- if ( ! hasParents ) {
- return 0;
- }
- return marginHorizontal;
- }
- if ( isWideWidth( blockAlignment ) ) {
- return marginHorizontal;
- }
-
- const screenWidth = Math.floor( Dimensions.get( 'window' ).width );
-
- if (
- isFullWidth( parentBlockAlignment ) &&
- ! isWider( blockWidth, 'medium' )
- ) {
- if (
- isContainerRelated( blockName ) ||
- isWider( screenWidth, 'mobile' )
- ) {
- return marginHorizontal;
- }
- return marginHorizontal * 2;
- }
-
- if (
- isContainerRelated( parentBlockName ) &&
- ! isContainerRelated( blockName )
- ) {
- const isScreenWidthEqual = parentWidth === screenWidth;
- if ( isScreenWidthEqual || isWider( screenWidth, 'mobile' ) ) {
- return marginHorizontal;
- }
- }
-
- return marginHorizontal;
- }
-
- getContentStyles( readableContentViewStyle ) {
- const { blockAlignment, blockName, hasParents, parentBlockName } =
- this.props;
- const { isFullWidth, isContainerRelated } = alignmentHelpers;
-
- return [
- readableContentViewStyle,
- isFullWidth( blockAlignment ) &&
- ! hasParents && {
- width: styles.fullAlignment.width,
- },
- ! blockAlignment &&
- hasParents &&
- ! isContainerRelated( parentBlockName ) &&
- isContainerRelated( blockName ) && {
- paddingHorizontal: styles.fullAlignmentPadding.paddingLeft,
- },
- ];
- }
-
- renderContent() {
- const {
- blockAlignment,
- clientId,
- index,
- isReadOnly,
- shouldShowInsertionPointBefore,
- shouldShowInsertionPointAfter,
- contentResizeMode,
- shouldShowInnerBlockAppender,
- parentWidth,
- marginHorizontal,
- blockName,
- blockWidth,
- ...restProps
- } = this.props;
-
- const readableContentViewStyle =
- contentResizeMode === 'stretch' && stretchStyle;
- const { isContainerRelated } = alignmentHelpers;
-
- return (
-
-
- { shouldShowInsertionPointBefore && (
-
- ) }
-
- { ! shouldShowInnerBlockAppender() &&
- shouldShowInsertionPointAfter && (
-
- ) }
-
-
- );
- }
-
- render() {
- const { parentWidth, blockWidth, isGridItem } = this.props;
-
- if ( ! blockWidth ) {
- return null;
- }
-
- if ( isGridItem ) {
- const { numOfColumns, tileCount, tileIndex } = this.props;
- return (
-
- { this.renderContent() }
-
- );
- }
- return this.renderContent();
- }
-}
-
-export default compose( [
- withSelect(
- ( select, { rootClientId, isStackedHorizontally, clientId } ) => {
+/**
+ * BlockListItemContent component. Renders a block with an optional insertion point.
+ *
+ * @param {Object} props Component properties.
+ * @param {number} props.blockWidth The width of the block.
+ * @param {string} props.clientId The block client ID.
+ * @param {string} props.contentResizeMode The content resize mode, e.g "stretch".
+ * @param {Object} props.contentStyle Styles for the block content
+ * @param {Object} props.index Block item index
+ * @param {boolean} props.isStackedHorizontally Whether the block is stacked horizontally.
+ * @param {number} props.marginHorizontal The horizontal margin.
+ * @param {number} props.marginVertical The vertical margin.
+ * @param {Function} props.onAddBlock On add block callback.
+ * @param {Function} props.onDeleteBlock On delete block callback.
+ * @param {number} props.parentWidth The width of the parent block.
+ * @param {string} props.rootClientId The root client ID.
+ * @param {Function} props.shouldShowInnerBlockAppender Whether to show the inner block appender.
+ *
+ * @return {WPComponent} The rendered block list item content.
+ */
+function BlockListItemContent( {
+ blockWidth,
+ clientId,
+ contentResizeMode,
+ contentStyle,
+ index,
+ isStackedHorizontally,
+ marginHorizontal,
+ marginVertical,
+ onAddBlock,
+ onDeleteBlock,
+ parentWidth,
+ rootClientId,
+ shouldShowInnerBlockAppender,
+} ) {
+ const {
+ blockAlignment,
+ blockName,
+ hasParents,
+ parentBlockAlignment,
+ parentBlockName,
+ shouldShowInsertionPointAfter,
+ shouldShowInsertionPointBefore,
+ } = useSelect(
+ ( select ) => {
const {
- getBlockOrder,
+ getBlockAttributes,
getBlockInsertionPoint,
+ getBlockName,
+ getBlockOrder,
isBlockInsertionPointVisible,
- getSettings,
- getBlockParents,
- getBlock,
} = select( blockEditorStore );
-
const blockClientIds = getBlockOrder( rootClientId );
const insertionPoint = getBlockInsertionPoint();
- const blockInsertionPointIsVisible = isBlockInsertionPointVisible();
- const shouldShowInsertionPointBefore =
- ! isStackedHorizontally &&
- blockInsertionPointIsVisible &&
- insertionPoint.rootClientId === rootClientId &&
- // If list is empty, show the insertion point (via the default appender)
- ( blockClientIds.length === 0 ||
- // Or if the insertion point is right before the denoted block.
- blockClientIds[ insertionPoint.index ] === clientId );
-
- const shouldShowInsertionPointAfter =
+
+ const insertionPointVisibleInCurrentRoot =
! isStackedHorizontally &&
- blockInsertionPointIsVisible &&
- insertionPoint.rootClientId === rootClientId &&
- // If the insertion point is at the end of the list.
- blockClientIds.length === insertionPoint.index &&
- // And the denoted block is the last one on the list, show the indicator at the end of the block.
+ isBlockInsertionPointVisible() &&
+ insertionPoint.rootClientId === rootClientId;
+
+ const isListEmpty = blockClientIds.length === 0;
+ const isInsertionPointBeforeBlock =
+ blockClientIds[ insertionPoint.index ] === clientId;
+ const isInsertionPointAtEnd =
+ blockClientIds.length === insertionPoint.index;
+ const isBlockLastInList =
blockClientIds[ insertionPoint.index - 1 ] === clientId;
- const isReadOnly = getSettings().readOnly;
+ const showInsertionPointBefore =
+ insertionPointVisibleInCurrentRoot &&
+ ( isListEmpty || isInsertionPointBeforeBlock );
+
+ const showInsertionPointAfter =
+ insertionPointVisibleInCurrentRoot &&
+ isInsertionPointAtEnd &&
+ isBlockLastInList;
- const { attributes, name } = getBlock( clientId ) || {};
- const { align } = attributes || {};
- const parents = getBlockParents( clientId, true );
- const hasParents = !! parents.length;
- const parentBlock = hasParents ? getBlock( parents[ 0 ] ) : {};
- const { align: parentBlockAlignment } =
- parentBlock?.attributes || {};
- const { name: parentBlockName } = parentBlock || {};
+ const blockHasParents = !! rootClientId;
+ const name = getBlockName( clientId );
+ const parentName = getBlockName( rootClientId );
+ const { align } = getBlockAttributes( clientId ) || {};
+ const { align: parentBlockAlign } =
+ getBlockAttributes( rootClientId ) || {};
return {
- shouldShowInsertionPointBefore,
- shouldShowInsertionPointAfter,
- isReadOnly,
- hasParents,
blockAlignment: align,
- parentBlockAlignment,
blockName: name,
- parentBlockName,
+ hasParents: blockHasParents,
+ parentBlockAlignment: parentBlockAlign,
+ parentBlockName: parentName,
+ shouldShowInsertionPointAfter: showInsertionPointAfter,
+ shouldShowInsertionPointBefore: showInsertionPointBefore,
};
- }
- ),
-] )( BlockListItem );
+ },
+ [ isStackedHorizontally, rootClientId, clientId ]
+ );
+
+ const [ wrapperStyles, margin ] = useEditorWrapperStyles( {
+ align: blockAlignment,
+ blockName,
+ blockWidth,
+ contentResizeMode,
+ hasParents,
+ marginHorizontal,
+ parentBlockAlignment,
+ parentBlockName,
+ parentWidth,
+ } );
+
+ const shouldShowBlockInsertionPointAfter =
+ ! shouldShowInnerBlockAppender() && shouldShowInsertionPointAfter;
+
+ return (
+
+ { shouldShowInsertionPointBefore && (
+
+ ) }
+
+ { shouldShowBlockInsertionPointAfter && (
+
+ ) }
+
+ );
+}
+
+/**
+ * BlockListItem component. Renders a block list item either as a grid item or as a standalone item.
+ *
+ * @param {Object} props Component properties.
+ * @param {boolean} props.isGridItem Whether the block is a grid item.
+ * @param {number} props.numOfColumns The number of columns for grid layout.
+ * @param {number} props.parentWidth The width of the parent block.
+ * @param {number} props.tileCount The total number of tiles in the grid.
+ * @param {number} props.tileIndex The index of the current tile in the grid.
+ * @param {number} props.blockWidth The width of the block.
+ * @param {string} props.clientId The block client ID.
+ * @param {string} props.contentResizeMode The content resize mode, e.g "stretch".
+ * @param {Object} props.contentStyle Styles for the block content
+ * @param {Object} props.index Block item index
+ * @param {boolean} props.isStackedHorizontally Whether the block is stacked horizontally.
+ * @param {number} props.marginHorizontal The horizontal margin.
+ * @param {number} props.marginVertical The vertical margin.
+ * @param {Function} props.onAddBlock On add block callback.
+ * @param {Function} props.onDeleteBlock On delete block callback.
+ * @param {string} props.rootClientId The root client ID.
+ * @param {Function} props.shouldShowInnerBlockAppender Whether to show the inner block appender.
+ *
+ * @return {WPComponent|null} The rendered block list item or null if the block width is not provided.
+ */
+function BlockListItem( props ) {
+ const { isGridItem, numOfColumns, tileCount, tileIndex, ...restProps } =
+ props;
+
+ if ( ! props?.blockWidth ) {
+ return null;
+ }
+
+ if ( isGridItem ) {
+ return (
+
+
+
+ );
+ }
+
+ return ;
+}
+
+export default BlockListItem;