Skip to content

Commit

Permalink
Try adding layout classnames to inner block wrapper (#44600)
Browse files Browse the repository at this point in the history
* Try adding layout support to Cover block.

* Try adding layout classnames to inner block wrapper.

* Make it work in the editor

* Use WP_HTML_Tag_Processor to add layout classnames

* Use WP_HTML_Tag_Processor to identify inner wrapper classnames

* Improvements to inner content classname logic

* Only add layout classnames to inner blocks

* Manually add layout classnames to Gallery and Post Content edit

* Add comment to inner content classnames logic.

* Mark layoutClassnames unstable

* Add classnames to container in a loop.

* Remove layout support for Cover block.

* Apply layout to outer wrapper if legacy Group

* Off switch for layout classes in inner wrapper

* Change unstable prop name
  • Loading branch information
tellthemachines committed Oct 26, 2022
1 parent 99ad274 commit 5ae17f7
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 29 deletions.
47 changes: 35 additions & 12 deletions lib/block-supports/layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,23 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support
return '';
}

/**
* Gets classname from last tag in a string of HTML.
*
* @param string $html markup to be processed.
* @return string String of inner wrapper classnames.
*/
function gutenberg_get_classnames_from_last_tag( $html ) {
$tags = new WP_HTML_Tag_Processor( $html );
$last_classnames = '';

while ( $tags->next_tag() ) {
$last_classnames = $tags->get_attribute( 'class' );
}

return $last_classnames;
}

/**
* Renders the layout config to the block wrapper.
*
Expand Down Expand Up @@ -320,7 +337,6 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) {

$class_names = array();
$layout_definitions = _wp_array_get( $global_layout_settings, array( 'definitions' ), array() );
$block_classname = wp_get_block_default_classname( $block['blockName'] );
$container_class = wp_unique_id( 'wp-container-' );
$layout_classname = '';

Expand Down Expand Up @@ -397,7 +413,7 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) {
$should_skip_gap_serialization = gutenberg_should_skip_block_supports_serialization( $block_type, 'spacing', 'blockGap' );

$style = gutenberg_get_layout_style(
".$block_classname.$container_class",
".$container_class.$container_class",
$used_layout,
$has_block_gap_support,
$gap_value,
Expand All @@ -412,16 +428,22 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) {
}
}

/*
* This assumes the hook only applies to blocks with a single wrapper.
* A limitation of this hook is that nested inner blocks wrappers are not yet supported.
*/
$content = preg_replace(
'/' . preg_quote( 'class="', '/' ) . '/',
'class="' . esc_attr( implode( ' ', $class_names ) ) . ' ',
$block_content,
1
);
/**
* The first chunk of innerContent contains the block markup up until the inner blocks start.
* We want to target the opening tag of the inner blocks wrapper, which is the last tag in that chunk.
*/
$inner_content_classnames = isset( $block['innerContent'][0] ) && 'string' === gettype( $block['innerContent'][0] ) ? gutenberg_get_classnames_from_last_tag( $block['innerContent'][0] ) : '';

$content = new WP_HTML_Tag_Processor( $block_content );
if ( $inner_content_classnames ) {
$content->next_tag( array( 'class_name' => $inner_content_classnames ) );
foreach ( $class_names as $class_name ) {
$content->add_class( $class_name );
}
} else {
$content->next_tag();
$content->add_class( implode( ' ', $class_names ) );
}

return $content;
}
Expand All @@ -433,6 +455,7 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) {
'register_attribute' => 'gutenberg_register_layout_support',
)
);

if ( function_exists( 'wp_render_layout_support_flag' ) ) {
remove_filter( 'render_block', 'wp_render_layout_support_flag' );
}
Expand Down
3 changes: 2 additions & 1 deletion packages/block-editor/src/components/block-edit/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ import { BlockEditContextProvider, useBlockEditContext } from './context';
export { useBlockEditContext };

export default function BlockEdit( props ) {
const { name, isSelected, clientId } = props;
const { name, isSelected, clientId, __unstableLayoutClassNames } = props;
const context = {
name,
isSelected,
clientId,
__unstableLayoutClassNames,
};
return (
<BlockEditContextProvider
Expand Down
2 changes: 2 additions & 0 deletions packages/block-editor/src/components/block-list/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ function BlockListBlock( {
isSelected,
isSelectionEnabled,
className,
__unstableLayoutClassNames: layoutClassNames,
name,
isValid,
attributes,
Expand Down Expand Up @@ -146,6 +147,7 @@ function BlockListBlock( {
clientId={ clientId }
isSelectionEnabled={ isSelectionEnabled }
toggleSelection={ toggleSelection }
__unstableLayoutClassNames={ layoutClassNames }
/>
);

Expand Down
6 changes: 5 additions & 1 deletion packages/block-editor/src/components/inner-blocks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,9 @@ const ForwardedInnerBlocks = forwardRef( ( props, ref ) => {
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/inner-blocks/README.md
*/
export function useInnerBlocksProps( props = {}, options = {} ) {
const { clientId } = useBlockEditContext();
const { __unstableDisableLayoutClassNames } = options;
const { clientId, __unstableLayoutClassNames: layoutClassNames = '' } =
useBlockEditContext();
const isSmallScreen = useViewportMatch( 'medium', '<' );
const { __experimentalCaptureToolbars, hasOverlay } = useSelect(
( select ) => {
Expand Down Expand Up @@ -200,12 +202,14 @@ export function useInnerBlocksProps( props = {}, options = {} ) {
innerBlocksProps.value && innerBlocksProps.onChange
? ControlledInnerBlocks
: UncontrolledInnerBlocks;

return {
...props,
ref,
className: classnames(
props.className,
'block-editor-block-list__layout',
__unstableDisableLayoutClassNames ? '' : layoutClassNames,
{
'has-overlay': hasOverlay,
}
Expand Down
16 changes: 7 additions & 9 deletions packages/block-editor/src/hooks/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@ import { kebabCase } from 'lodash';
*/
import { createHigherOrderComponent, useInstanceId } from '@wordpress/compose';
import { addFilter } from '@wordpress/hooks';
import {
getBlockDefaultClassName,
getBlockSupport,
hasBlockSupport,
} from '@wordpress/blocks';
import { getBlockSupport, hasBlockSupport } from '@wordpress/blocks';
import { useSelect } from '@wordpress/data';
import {
Button,
Expand Down Expand Up @@ -366,9 +362,8 @@ export const withLayoutStyles = createHigherOrderComponent(
const layoutClasses = hasLayoutBlockSupport
? useLayoutClasses( block )
: null;
const selector = `.${ getBlockDefaultClassName(
name
) }.wp-container-${ id }`;
// Higher specificity to override defaults from theme.json.
const selector = `.wp-container-${ id }.wp-container-${ id }`;
const blockGapSupport = useSetting( 'spacing.blockGap' );
const hasBlockGapSupport = blockGapSupport !== null;

Expand Down Expand Up @@ -413,7 +408,10 @@ export const withLayoutStyles = createHigherOrderComponent(
/>,
element
) }
<BlockListBlock { ...props } className={ className } />
<BlockListBlock
{ ...props }
__unstableLayoutClassNames={ className }
/>
</>
);
}
Expand Down
2 changes: 2 additions & 0 deletions packages/block-library/src/gallery/gallery.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const Gallery = ( props ) => {
mediaPlaceholder,
insertBlocksAfter,
blockProps,
__unstableLayoutClassNames: layoutClassNames,
} = props;

const { align, columns, caption, imageCrop } = attributes;
Expand All @@ -42,6 +43,7 @@ export const Gallery = ( props ) => {
{ ...innerBlocksProps }
className={ classnames(
blockProps.className,
layoutClassNames,
'blocks-gallery-grid',
{
[ `align${ align }` ]: align,
Expand Down
12 changes: 10 additions & 2 deletions packages/block-library/src/group/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@ const htmlElementMessages = {
),
};

function GroupEdit( { attributes, setAttributes, clientId } ) {
function GroupEdit( {
attributes,
setAttributes,
clientId,
__unstableLayoutClassNames: layoutClassNames,
} ) {
const { hasInnerBlocks, themeSupportsLayout } = useSelect(
( select ) => {
const { getBlock, getSettings } = select( blockEditorStore );
Expand All @@ -55,7 +60,9 @@ function GroupEdit( { attributes, setAttributes, clientId } ) {
const { type = 'default' } = usedLayout;
const layoutSupportEnabled = themeSupportsLayout || type === 'flex';

const blockProps = useBlockProps();
const blockProps = useBlockProps( {
className: ! layoutSupportEnabled ? layoutClassNames : null,
} );

const innerBlocksProps = useInnerBlocksProps(
layoutSupportEnabled
Expand All @@ -67,6 +74,7 @@ function GroupEdit( { attributes, setAttributes, clientId } ) {
? undefined
: InnerBlocks.ButtonBlockAppender,
__experimentalLayout: layoutSupportEnabled ? usedLayout : undefined,
__unstableDisableLayoutClassNames: ! layoutSupportEnabled,
}
);

Expand Down
12 changes: 8 additions & 4 deletions packages/block-library/src/post-content/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ function Content( props ) {
);
}

function Placeholder() {
const blockProps = useBlockProps();
function Placeholder( { layoutClassNames } ) {
const blockProps = useBlockProps( { className: layoutClassNames } );
return (
<div { ...blockProps }>
<p>
Expand Down Expand Up @@ -118,7 +118,11 @@ function RecursionError() {
);
}

export default function PostContentEdit( { context, attributes } ) {
export default function PostContentEdit( {
context,
attributes,
__unstableLayoutClassNames: layoutClassNames,
} ) {
const { postId: contextPostId, postType: contextPostType } = context;
const { layout = {} } = attributes;
const hasAlreadyRendered = useHasRecursion( contextPostId );
Expand All @@ -132,7 +136,7 @@ export default function PostContentEdit( { context, attributes } ) {
{ contextPostId && contextPostType ? (
<Content context={ context } layout={ layout } />
) : (
<Placeholder />
<Placeholder layoutClassNames={ layoutClassNames } />
) }
</RecursionProvider>
);
Expand Down

0 comments on commit 5ae17f7

Please sign in to comment.