diff --git a/packages/block-library/src/column/edit.js b/packages/block-library/src/column/edit.js index f200ba2bd02ec..979d01115c741 100644 --- a/packages/block-library/src/column/edit.js +++ b/packages/block-library/src/column/edit.js @@ -2,7 +2,6 @@ * External dependencies */ import classnames from 'classnames'; -import { forEach, find, difference } from 'lodash'; /** * WordPress dependencies @@ -18,22 +17,11 @@ import { withDispatch, withSelect } from '@wordpress/data'; import { compose } from '@wordpress/compose'; import { __ } from '@wordpress/i18n'; -/** - * Internal dependencies - */ -import { - toWidthPrecision, - getTotalColumnsWidth, - getColumnWidths, - getAdjacentBlocks, - getRedistributedColumnWidths, -} from '../columns/utils'; - function ColumnEdit( { attributes, + setAttributes, className, updateAlignment, - updateWidth, hasChildBlocks, } ) { const { verticalAlignment, width } = attributes; @@ -55,11 +43,17 @@ function ColumnEdit( { { + setAttributes( { width: nextWidth } ); + } } min={ 0 } max={ 100 } + step={ 0.1 } required allowReset + placeholder={ + width === undefined ? __( 'Auto' ) : undefined + } /> @@ -104,54 +98,6 @@ export default compose( verticalAlignment: null, } ); }, - updateWidth( width ) { - const { clientId } = ownProps; - const { updateBlockAttributes } = dispatch( - 'core/block-editor' - ); - const { getBlockRootClientId, getBlocks } = registry.select( - 'core/block-editor' - ); - - // Constrain or expand siblings to account for gain or loss of - // total columns area. - const columns = getBlocks( getBlockRootClientId( clientId ) ); - const adjacentColumns = getAdjacentBlocks( columns, clientId ); - - // The occupied width is calculated as the sum of the new width - // and the total width of blocks _not_ in the adjacent set. - const occupiedWidth = - width + - getTotalColumnsWidth( - difference( columns, [ - find( columns, { clientId } ), - ...adjacentColumns, - ] ) - ); - - // Compute _all_ next column widths, in case the updated column - // is in the middle of a set of columns which don't yet have - // any explicit widths assigned (include updates to those not - // part of the adjacent blocks). - const nextColumnWidths = { - ...getColumnWidths( columns, columns.length ), - [ clientId ]: toWidthPrecision( width ), - ...getRedistributedColumnWidths( - adjacentColumns, - 100 - occupiedWidth, - columns.length - ), - }; - - forEach( - nextColumnWidths, - ( nextColumnWidth, columnClientId ) => { - updateBlockAttributes( columnClientId, { - width: nextColumnWidth, - } ); - } - ); - }, }; } ) )( ColumnEdit ); diff --git a/packages/block-library/src/column/index.js b/packages/block-library/src/column/index.js index 611a160ed8962..7ed663db38558 100644 --- a/packages/block-library/src/column/index.js +++ b/packages/block-library/src/column/index.js @@ -32,6 +32,7 @@ export const settings = { style: { flexBasis: width + '%', }, + 'data-has-explicit-width': true, }; } }, diff --git a/packages/block-library/src/columns/editor.scss b/packages/block-library/src/columns/editor.scss index 2d77224a917d6..b62b3f6221514 100644 --- a/packages/block-library/src/columns/editor.scss +++ b/packages/block-library/src/columns/editor.scss @@ -66,10 +66,18 @@ // Responsiveness: Show at most one columns on mobile. flex-basis: 100%; - // Beyond mobile, allow 2 columns. @include break-small() { - flex-basis: calc(50% - (#{$grid-size-large})); - flex-grow: 0; + flex-grow: 1; + flex-basis: auto; + + // Beyond mobile, allow columns. Columns with an explicitly- + // assigned width should maintain their `flex-basis` width and + // not grow. All other blocks should automatically inherit the + // `flex-grow` to occupy the available space. + &[data-has-explicit-width] { + flex-grow: 0; + } + margin-left: 0; margin-right: 0; } diff --git a/packages/block-library/src/columns/style.scss b/packages/block-library/src/columns/style.scss index 899414c24f407..b32377cc3522e 100644 --- a/packages/block-library/src/columns/style.scss +++ b/packages/block-library/src/columns/style.scss @@ -32,9 +32,13 @@ @include break-small() { - // Beyond mobile, allow 2 columns. - flex-basis: calc(50% - #{$grid-size-large}); - flex-grow: 0; + // Beyond mobile, allow columns. Columns with an explicitly-assigned + // width should maintain their `flex-basis` width and not grow. All + // other blocks should automatically inherit the `flex-grow` to occupy + // the available space. + &[style] { + flex-grow: 0; + } // Add space between the multiple columns. Themes can customize this if they wish to work differently. // Only apply this beyond the mobile breakpoint, as there's only a single column on mobile. diff --git a/packages/block-library/src/columns/test/utils.js b/packages/block-library/src/columns/test/utils.js index 67ef6dd033272..96ad53950d6e5 100644 --- a/packages/block-library/src/columns/test/utils.js +++ b/packages/block-library/src/columns/test/utils.js @@ -3,7 +3,6 @@ */ import { toWidthPrecision, - getAdjacentBlocks, getEffectiveColumnWidth, getTotalColumnsWidth, getColumnWidths, @@ -25,25 +24,6 @@ describe( 'toWidthPrecision', () => { } ); } ); -describe( 'getAdjacentBlocks', () => { - const blockA = { clientId: 'a' }; - const blockB = { clientId: 'b' }; - const blockC = { clientId: 'c' }; - const blocks = [ blockA, blockB, blockC ]; - - it( 'should return blocks after clientId', () => { - const result = getAdjacentBlocks( blocks, 'b' ); - - expect( result ).toEqual( [ blockC ] ); - } ); - - it( 'should return blocks before clientId if clientId is last', () => { - const result = getAdjacentBlocks( blocks, 'c' ); - - expect( result ).toEqual( [ blockA, blockB ] ); - } ); -} ); - describe( 'getEffectiveColumnWidth', () => { it( 'should return attribute value if set, rounded to precision', () => { const block = { attributes: { width: 50.108 } }; @@ -186,7 +166,29 @@ describe( 'hasExplicitColumnWidths', () => { } ); it( 'returns true if a block has explicit width', () => { - const blocks = [ { attributes: { width: 10 } } ]; + const blocks = [ { attributes: { width: 100 } } ]; + + const result = hasExplicitColumnWidths( blocks ); + + expect( result ).toBe( true ); + } ); + + it( 'returns false if some, not all blocks have explicit width', () => { + const blocks = [ + { attributes: { width: 10 } }, + { attributes: { width: undefined } }, + ]; + + const result = hasExplicitColumnWidths( blocks ); + + expect( result ).toBe( false ); + } ); + + it( 'returns true if all blocks have explicit width', () => { + const blocks = [ + { attributes: { width: 10 } }, + { attributes: { width: 90 } }, + ]; const result = hasExplicitColumnWidths( blocks ); diff --git a/packages/block-library/src/columns/utils.js b/packages/block-library/src/columns/utils.js index 0631d59cf9dfb..31f0d9f87cfd5 100644 --- a/packages/block-library/src/columns/utils.js +++ b/packages/block-library/src/columns/utils.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { findIndex, sumBy, merge, mapValues } from 'lodash'; +import { sumBy, merge, mapValues } from 'lodash'; /** * Returns a column width attribute value rounded to standard precision. @@ -14,24 +14,6 @@ import { findIndex, sumBy, merge, mapValues } from 'lodash'; export const toWidthPrecision = ( value ) => Number.isFinite( value ) ? parseFloat( value.toFixed( 2 ) ) : undefined; -/** - * Returns the considered adjacent to that of the specified `clientId` for - * resizing consideration. Adjacent blocks are those occurring after, except - * when the given block is the last block in the set. For the last block, the - * behavior is reversed. - * - * @param {WPBlock[]} blocks Block objects. - * @param {string} clientId Client ID to consider for adjacent blocks. - * - * @return {WPBlock[]} Adjacent block objects. - */ -export function getAdjacentBlocks( blocks, clientId ) { - const index = findIndex( blocks, { clientId } ); - const isLastBlock = index === blocks.length - 1; - - return isLastBlock ? blocks.slice( 0, index ) : blocks.slice( index + 1 ); -} - /** * Returns an effective width for a given block. An effective width is equal to * its attribute value if set, or a computed value assuming equal distribution. @@ -115,7 +97,7 @@ export function getRedistributedColumnWidths( * @return {boolean} Whether columns have explicit widths. */ export function hasExplicitColumnWidths( blocks ) { - return blocks.some( ( block ) => + return blocks.every( ( block ) => Number.isFinite( block.attributes.width ) ); }