Automattic\WooCommerce\EmailEditor\Engine\Renderer\ContentRenderer\Layout

Flex_Layout_Renderer::compute_widths_for_flex_layout │ private │ WC 1.0

Compute widths for blocks in flex layout and decide whether the row must wrap.

Method of the class: Flex_Layout_Renderer{}

No Hooks.

Returns

array{0: array, 1: bool}. The inner blocks (with computed widths) and whether the row should wrap instead of rendering as a single row.

Usage

// private - for code of main (parent) class only
$result = $this->compute_widths_for_flex_layout( $parsed_block, $flex_gap ): array;
$parsed_block(array) (required)
Parsed block.
$flex_gap(float) (required)
Flex gap.

Flex_Layout_Renderer::compute_widths_for_flex_layout() code WC 11.1.2

private function compute_widths_for_flex_layout( array $parsed_block, float $flex_gap ): array {
	// When there is no parent width we can't compute widths so auto width will be used, and we
	// can't tell whether the items overflow — fall back to the (non-wrapping) single row.
	if ( ! isset( $parsed_block['email_attrs']['width'] ) ) {
		return array( $parsed_block['innerBlocks'] ?? array(), false );
	}
	$blocks_count     = count( $parsed_block['innerBlocks'] );
	$total_used_width = 0; // Total width assuming items without set width would consume proportional width.
	$parent_width     = Styles_Helper::parse_value( $parsed_block['email_attrs']['width'] );
	$inner_blocks     = $parsed_block['innerBlocks'] ?? array();
	$has_auto_width   = false;

	foreach ( $inner_blocks as $key => $block ) {
		$block_width_percent = ( $block['attrs']['width'] ?? 0 ) ? intval( $block['attrs']['width'] ) : 0;
		$block_width         = floor( $parent_width * ( $block_width_percent / 100 ) );
		// If width is not set, we assume it's 25% of the parent width.
		$total_used_width += $block_width ? $block_width : floor( $parent_width * ( 25 / 100 ) );

		if ( ! $block_width ) {
			$has_auto_width                                      = true;
			$inner_blocks[ $key ]['email_attrs']['layout_width'] = null; // Will be rendered as auto.
			continue;
		}
		$inner_blocks[ $key ]['email_attrs']['layout_width'] = $this->get_width_without_gap( $block_width, $flex_gap, $block_width_percent ) . 'px';
	}

	$overflows = $blocks_count > 1 && $total_used_width > $parent_width;

	// When there is only one block, or the items fit, render the single row as set by the user.
	if ( ! $overflows ) {
		return array( $inner_blocks, false );
	}

	// Auto-width items (e.g. a nav menu of buttons) can't be shrunk to fit, so an overflowing row
	// that contains any of them can only be kept inside the content width by wrapping — the
	// explicitly-sized items in the same row keep their width and flow alongside. A row made up
	// entirely of explicit-width items is instead scaled down proportionally so it still fits on
	// one row, preserving the existing behavior.
	if ( $has_auto_width ) {
		return array( $inner_blocks, true );
	}

	foreach ( $inner_blocks as $key => $block ) {
		$proportional_space_overflow   = $parent_width / $total_used_width;
		$block_width                   = $block['email_attrs']['layout_width'] ? Styles_Helper::parse_value( $block['email_attrs']['layout_width'] ) : 0;
		$block_proportional_width      = $block_width * $proportional_space_overflow;
		$block_proportional_percentage = ( $block_proportional_width / $parent_width ) * 100;
		$inner_blocks[ $key ]['email_attrs']['layout_width'] = $block_width ? $this->get_width_without_gap( $block_proportional_width, $flex_gap, $block_proportional_percentage ) . 'px' : null;
	}
	return array( $inner_blocks, false );
}