Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -104,7 +106,7 @@ export class BlockListItem extends Component {
];
}

render() {
renderContent() {
const {
blockAlignment,
clientId,
Expand All @@ -123,10 +125,6 @@ export class BlockListItem extends Component {
contentResizeMode === 'stretch' && stretchStyle;
const { isContainerRelated } = alignmentHelpers;

if ( ! blockWidth ) {
return null;
}

return (
<ReadableContentView
align={ blockAlignment }
Expand Down Expand Up @@ -162,6 +160,34 @@ export class BlockListItem extends Component {
</ReadableContentView>
);
}

render() {
const {
gridProperties,
clientId,
parentWidth,
items,
blockWidth,
} = this.props;

if ( ! blockWidth ) {
return null;
}

if ( gridProperties ) {
return (
<Grid
numOfColumns={ gridProperties.numColumns }
tileCount={ items.length }
index={ items.indexOf( clientId ) }
maxWidth={ parentWidth }
>
{ this.renderContent() }
</Grid>
);
}
return this.renderContent();
}
}

export default compose( [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@
.fullAlignmentPadding {
padding: $block-edge-to-content;
}

.gridItem {
overflow: visible;
}
Original file line number Diff line number Diff line change
@@ -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 (
<View
style={ [
{
width: maxWidth / rowLength,
},
styles.gridItem,
] }
>
{ children }
</View>
);
}

export default Grid;
55 changes: 28 additions & 27 deletions packages/block-editor/src/components/block-list/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,9 @@ const stylesMemo = {};
const getStyles = (
isRootList,
isStackedHorizontally,
horizontalAlignment,
numColumns
horizontalAlignment
) => {
if ( isRootList || numColumns ) {
if ( isRootList ) {
return;
}
const styleName = `${ isStackedHorizontally }-${ horizontalAlignment }`;
Expand All @@ -48,6 +47,7 @@ const getStyles = (
const computedStyles = [
isStackedHorizontally && styles.horizontal,
horizontalAlignment && styles[ `is-aligned-${ horizontalAlignment }` ],
styles.overflowVisible,
];
stylesMemo[ styleName ] = computedStyles;
return computedStyles;
Expand Down Expand Up @@ -129,6 +129,7 @@ export class BlockList extends Component {
onDeleteBlock,
contentStyle,
renderAppender,
gridProperties,
} = this.props;
const { blockWidth } = this.state;
if (
Expand All @@ -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,
Expand All @@ -146,6 +148,7 @@ export class BlockList extends Component {
contentStyle,
renderAppender,
blockWidth,
gridProperties,
};
}
return this.extraData;
Expand Down Expand Up @@ -209,7 +212,6 @@ export class BlockList extends Component {
contentResizeMode,
// eslint-disable-next-line no-unused-vars
blockWidth,
numColumns,
} = this.props;
const { parentScrollRef } = extraProps;

Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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 (
<View style={ { flex: 1 } }>
<BlockListItem
isStackedHorizontally={ isStackedHorizontally }
rootClientId={ rootClientId }
clientId={ clientId }
parentWidth={ parentWidth }
contentResizeMode={ contentResizeMode }
contentStyle={ contentStyle }
onAddBlock={ onAddBlock }
marginVertical={ marginVertical }
marginHorizontal={ marginHorizontal }
onDeleteBlock={ onDeleteBlock }
shouldShowInnerBlockAppender={
this.shouldShowInnerBlockAppender
}
blockWidth={ blockWidth }
/>
</View>
<BlockListItem
isStackedHorizontally={ isStackedHorizontally }
rootClientId={ rootClientId }
clientId={ clientId }
parentWidth={ parentWidth }
contentResizeMode={ contentResizeMode }
contentStyle={ contentStyle }
onAddBlock={ onAddBlock }
marginVertical={ marginVertical }
marginHorizontal={ marginHorizontal }
onDeleteBlock={ onDeleteBlock }
shouldShowInnerBlockAppender={
this.shouldShowInnerBlockAppender
}
blockWidth={ blockWidth }
gridProperties={ gridProperties }
items={ blockClientIds }
/>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ function StylePreview( { onPress, isActive, style, url } ) {
return (
<Animated.View
style={ [ outlineStyle, { opacity }, styles[ name ] ] }
key={ outlineStyle.borderColor }
key={ JSON.stringify( outlineStyle ) }
/>
);
} );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ function UncontrolledInnerBlocks( props ) {
filterInnerBlocks,
blockWidth,
__experimentalLayout: layout = defaultLayout,
numColumns,
gridProperties,
} = props;

const block = useSelect(
Expand Down Expand Up @@ -126,8 +126,8 @@ function UncontrolledInnerBlocks( props ) {
onAddBlock={ onAddBlock }
onDeleteBlock={ onDeleteBlock }
filterInnerBlocks={ filterInnerBlocks }
gridProperties={ gridProperties }
blockWidth={ blockWidth }
numColumns={ numColumns }
/>
);

Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
17 changes: 16 additions & 1 deletion packages/block-library/src/gallery/gallery.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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 {
Expand All @@ -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;

Expand All @@ -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,
}
);

Expand All @@ -77,6 +91,7 @@ export const Gallery = ( props ) => {

return (
<View style={ isFullWidth && styles.fullWidth }>
{ resizeObserver }
<View { ...innerBlocksProps } />
<View
style={ [
Expand Down