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 206ac48892a99e..b62d03a5f1fa16 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 @@ -16,6 +16,8 @@ import { ReadableContentView, alignmentHelpers } from '@wordpress/components'; */ import BlockListBlock from './block'; import BlockInsertionPoint from './insertion-point'; +import Grid from './grid-item'; + import styles from './block-list-item.native.scss'; import { store as blockEditorStore } from '../../store'; @@ -104,7 +106,7 @@ export class BlockListItem extends Component { ]; } - render() { + renderContent() { const { blockAlignment, clientId, @@ -123,10 +125,6 @@ export class BlockListItem extends Component { contentResizeMode === 'stretch' && stretchStyle; const { isContainerRelated } = alignmentHelpers; - if ( ! blockWidth ) { - return null; - } - return ( ); } + + render() { + const { + gridProperties, + clientId, + parentWidth, + items, + blockWidth, + } = this.props; + + if ( ! blockWidth ) { + return null; + } + + if ( gridProperties ) { + return ( + + { this.renderContent() } + + ); + } + return this.renderContent(); + } } export default compose( [ diff --git a/packages/block-editor/src/components/block-list/block-list-item.native.scss b/packages/block-editor/src/components/block-list/block-list-item.native.scss index 8e2eca61430341..82baa74a07111a 100644 --- a/packages/block-editor/src/components/block-list/block-list-item.native.scss +++ b/packages/block-editor/src/components/block-list/block-list-item.native.scss @@ -10,3 +10,7 @@ .fullAlignmentPadding { padding: $block-edge-to-content; } + +.gridItem { + overflow: visible; +} diff --git a/packages/block-editor/src/components/block-list/grid-item.native.js b/packages/block-editor/src/components/block-list/grid-item.native.js new file mode 100644 index 00000000000000..053b3ecfe90d5d --- /dev/null +++ b/packages/block-editor/src/components/block-list/grid-item.native.js @@ -0,0 +1,58 @@ +/** + * External dependencies + */ +import { View } from 'react-native'; + +/** + * Internal dependencies + */ +import styles from './block-list-item.scss'; + +function Grid( props ) { + /** + * Since we don't have `calc()`, we must calculate our spacings here in + * order to preserve even spacing between tiles and equal width for tiles + * in a given row. + * + * In order to ensure equal sizing of tile contents, we distribute the + * spacing such that each tile has an equal "share" of the fixed spacing. To + * keep the tiles properly aligned within their rows, we calculate the left + * and right paddings based on the tile's relative position within the row. + * + * Note: we use padding instead of margins so that the fixed spacing is + * included within the relative spacing (i.e. width percentage), and + * wrapping behavior is preserved. + * + * - The left most tile in a row must have left padding of zero. + * - The right most tile in a row must have a right padding of zero. + * + * The values of these left and right paddings are interpolated for tiles in + * between. The right padding is complementary with the left padding of the + * next tile (i.e. the right padding of [tile n] + the left padding of + * [tile n + 1] will be equal for all tiles except the last one in a given + * row). + * + */ + const { numOfColumns, children, tileCount, index, maxWidth } = props; + const lastTile = tileCount - 1; + const lastRow = Math.floor( lastTile / numOfColumns ); + + const row = Math.floor( index / numOfColumns ); + const rowLength = + row === lastRow ? ( lastTile % numOfColumns ) + 1 : numOfColumns; + + return ( + + { children } + + ); +} + +export default Grid; diff --git a/packages/block-editor/src/components/block-list/index.native.js b/packages/block-editor/src/components/block-list/index.native.js index 71bdf217f1b50a..ebf875b390d691 100644 --- a/packages/block-editor/src/components/block-list/index.native.js +++ b/packages/block-editor/src/components/block-list/index.native.js @@ -35,10 +35,9 @@ const stylesMemo = {}; const getStyles = ( isRootList, isStackedHorizontally, - horizontalAlignment, - numColumns + horizontalAlignment ) => { - if ( isRootList || numColumns ) { + if ( isRootList ) { return; } const styleName = `${ isStackedHorizontally }-${ horizontalAlignment }`; @@ -48,6 +47,7 @@ const getStyles = ( const computedStyles = [ isStackedHorizontally && styles.horizontal, horizontalAlignment && styles[ `is-aligned-${ horizontalAlignment }` ], + styles.overflowVisible, ]; stylesMemo[ styleName ] = computedStyles; return computedStyles; @@ -129,6 +129,7 @@ export class BlockList extends Component { onDeleteBlock, contentStyle, renderAppender, + gridProperties, } = this.props; const { blockWidth } = this.state; if ( @@ -137,7 +138,8 @@ export class BlockList extends Component { this.extraData.onDeleteBlock !== onDeleteBlock || this.extraData.contentStyle !== contentStyle || this.extraData.renderAppender !== renderAppender || - this.extraData.blockWidth !== blockWidth + this.extraData.blockWidth !== blockWidth || + this.extraData.gridProperties !== gridProperties ) { this.extraData = { parentWidth, @@ -146,6 +148,7 @@ export class BlockList extends Component { contentStyle, renderAppender, blockWidth, + gridProperties, }; } return this.extraData; @@ -209,7 +212,6 @@ export class BlockList extends Component { contentResizeMode, // eslint-disable-next-line no-unused-vars blockWidth, - numColumns, } = this.props; const { parentScrollRef } = extraProps; @@ -272,14 +274,11 @@ export class BlockList extends Component { style={ getStyles( isRootList, isStackedHorizontally, - horizontalAlignment, - numColumns + horizontalAlignment ) } data={ blockClientIds } keyExtractor={ identity } renderItem={ this.renderItem } - numColumns={ numColumns } - key={ numColumns } shouldPreventAutomaticScroll={ this.shouldFlatListPreventAutomaticScroll } @@ -315,30 +314,32 @@ export class BlockList extends Component { onDeleteBlock, rootClientId, isStackedHorizontally, + blockClientIds, parentWidth, marginVertical = styles.defaultBlock.marginTop, marginHorizontal = styles.defaultBlock.marginLeft, + gridProperties, } = this.props; const { blockWidth } = this.state; return ( - - - + ); } diff --git a/packages/block-editor/src/components/block-styles/preview.native.js b/packages/block-editor/src/components/block-styles/preview.native.js index c5461bf330acb9..c017331ad38a32 100644 --- a/packages/block-editor/src/components/block-styles/preview.native.js +++ b/packages/block-editor/src/components/block-styles/preview.native.js @@ -71,7 +71,7 @@ function StylePreview( { onPress, isActive, style, url } ) { return ( ); } ); 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 50297a561853a9..e1b87087fcbebb 100644 --- a/packages/block-editor/src/components/inner-blocks/index.native.js +++ b/packages/block-editor/src/components/inner-blocks/index.native.js @@ -92,7 +92,7 @@ function UncontrolledInnerBlocks( props ) { filterInnerBlocks, blockWidth, __experimentalLayout: layout = defaultLayout, - numColumns, + gridProperties, } = props; const block = useSelect( @@ -126,8 +126,8 @@ function UncontrolledInnerBlocks( props ) { onAddBlock={ onAddBlock } onDeleteBlock={ onDeleteBlock } filterInnerBlocks={ filterInnerBlocks } + gridProperties={ gridProperties } blockWidth={ blockWidth } - numColumns={ numColumns } /> ); diff --git a/packages/block-library/src/gallery/gallery-styles.native.scss b/packages/block-library/src/gallery/gallery-styles.native.scss index ea986c8a573ccf..a3073592291b93 100644 --- a/packages/block-library/src/gallery/gallery-styles.native.scss +++ b/packages/block-library/src/gallery/gallery-styles.native.scss @@ -1,5 +1,10 @@ @import "./v1/gallery-styles.native.scss"; .galleryAppender { - padding-top: 16px; + padding-top: $grid-unit-20; +} + +.fullWidth { + margin-left: $block-edge-to-content; + margin-right: $block-edge-to-content; } diff --git a/packages/block-library/src/gallery/gallery.native.js b/packages/block-library/src/gallery/gallery.native.js index 092308b0e18ccd..094c96464b061e 100644 --- a/packages/block-library/src/gallery/gallery.native.js +++ b/packages/block-library/src/gallery/gallery.native.js @@ -21,6 +21,7 @@ import { import { useState, useEffect } from '@wordpress/element'; import { mediaUploadSync } from '@wordpress/react-native-bridge'; import { WIDE_ALIGNMENTS } from '@wordpress/components'; +import { useResizeObserver } from '@wordpress/compose'; const TILE_SPACING = 8; @@ -30,6 +31,8 @@ const MAX_DISPLAYED_COLUMNS_NARROW = 2; export const Gallery = ( props ) => { const [ isCaptionSelected, setIsCaptionSelected ] = useState( false ); + const [ resizeObserver, sizes ] = useResizeObserver(); + const [ maxWidth, setMaxWidth ] = useState( 0 ); useEffect( mediaUploadSync, [] ); const { @@ -41,11 +44,17 @@ export const Gallery = ( props ) => { clientId, } = props; + useEffect( () => { + const { width } = sizes || {}; + if ( width ) { + setMaxWidth( width ); + } + }, [ sizes ] ); + const { imageCount, align, columns = defaultColumnsNumber( imageCount ), - // eslint-disable-next-line no-unused-vars imageCrop, } = attributes; @@ -64,6 +73,11 @@ export const Gallery = ( props ) => { numColumns: displayedColumns, marginHorizontal: TILE_SPACING, marginVertical: TILE_SPACING, + __experimentalLayout: { type: 'default', alignments: [] }, + gridProperties: { + numColumns: displayedColumns, + }, + parentWidth: maxWidth + 2 * TILE_SPACING, } ); @@ -77,6 +91,7 @@ export const Gallery = ( props ) => { return ( + { resizeObserver }