Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support wrapping grouped layouts in InnerBlocks #6895

Closed
chrisvanpatten opened this issue May 22, 2018 · 18 comments
Closed

Support wrapping grouped layouts in InnerBlocks #6895

chrisvanpatten opened this issue May 22, 2018 · 18 comments
Labels
Customization Issues related to Phase 2: Customization efforts [Feature] Nested / Inner Blocks Anything related to the experience of nested/inner blocks inside a larger container, like Group or P [Type] Question Questions about the design or development of the editor.

Comments

@chrisvanpatten
Copy link
Member

chrisvanpatten commented May 22, 2018

The InnerBlocks component allows you to "group" blocks together in "layouts", by providing objects defining each "layout".

This only groups the blocks in the sense that the blocks in each layout are placed adjacent to each other in the markup.

It would be great if it were possible to wrap each layout in a wrapping element as well.

<InnerBlocks layouts={ [
	{
		name: 'group-1',
		label: 'Group 1',
		icon: 'edit',
		wrap: true,
	},
	{
		name: 'group-2',
		label: 'Group 2',
		icon: 'edit',
		wrap: true,
	},
] } />

Or, for more specific control, maybe you could pass a callback, e.g. (pseudocode incoming)…

wrap: ( layout ) => {
	<div className={ layout.name } />
}

The markup in the editor itself already does wrap each group in a containing div, but this markup is not reflected in the code view, and thus not on the front-end.

@chrisvanpatten
Copy link
Member Author

chrisvanpatten commented May 22, 2018

This has been discussed in the context of the Columns block, e.g. in #5351, but has not — as far as I can tell — had a dedicated issue.

I think the extensive discussion about how a theoretical column/row/section/layout block should work has distracted from this specific issue, so I wanted to post something separate, particularly as this could be useful in non-column contexts.

@chrisvanpatten
Copy link
Member Author

See also #5935, which references this problem specifically w/r/t the experimental Columns block.

@mtias mtias added Customization Issues related to Phase 2: Customization efforts [Feature] Nested / Inner Blocks Anything related to the experience of nested/inner blocks inside a larger container, like Group or P [Type] Enhancement A suggestion for improvement. labels May 30, 2018
@roborourke
Copy link
Contributor

I ran into this today putting together a sidebar block. The blocks are separated into their layout contexts when in the editor so the CSS grid approach works as you'd expect there but it falls apart when rendered on the front end. The items in each "column" don't actually stack up under each other. Rather it depends on the height of the items in each row.

100% agree it'd be great to have the option to wrap the blocks in each layout in the save output to get consistent styling.

Currently working around it by filtering the_content and doing some nasty domdoc manipulation isn't ideal.

@easilyamused
Copy link
Contributor

Small work around has been adding nested 1 column "column experimental" block inside the main column and then add blocks to the nested column.

This works but is super hard to use in the WYSIWYG.

@roborourke
Copy link
Contributor

I didn't realise before but an innerBlocks parameter is passed to the save method. I experimented with the following but it doesn't match serialisation when reloading the editor:

save( { innerBlocks } ) {
		const layouts = innerBlocks.reduce( ( out, block ) => {
			const { layout } = block.attributes;
			out[layout] = out[layout] || [];
			out[layout].push( block );
			return out;
		}, {} );

		return (<div className="container container--has-sidebar">
			<div className="base-wrap">
				{Object.entries( layouts ).map( ( [ name, blocks ] ) => {
					return (<div className={`layout-${name}`}>
						<RawHTML>{ serialize( blocks ) }</RawHTML>
					</div>);
				} )}
			</div>
		</div>);
	}

@dougalcampbell
Copy link

MeToo++ The columns block renders great in the editor, just like you'd want. But in the front-end, because each inner content block is rendered with its own layout-column-N class, it ends up rendering more like table cells, with no flow for elements that are supposed to be in columns together. Rendering each column as a wrapper containing that column's content blocks would fix things up, and match the editor's structure more closely.

@chrisvanpatten
Copy link
Member Author

chrisvanpatten commented Jun 15, 2018

The blocks-all-the-way-down solution in #7234 does a bit to address this, but adds additional UI/UX complexity.

I could see it work if the layouts concept was deprecated and replaced with programmatic block templates, and a new block state/type: the "transparent" block. The transparent block is effectively fulfilling the purpose that InnerBlocks layout areas currently fulfil, with the full block API functionality and, critically without any associated UI: the containing block would be responsible for managing all its transparent children.

In that way, the "transparent" block is still technically a block but not exposed in any UI and is really only used as a structural component.

Curious if this is the direction you were thinking of @aduth?

EDIT: Should be noted that I think this is already largely possible, except the ability to completely hide a block's editor chrome/UI, which I think is essential to making this seamless for end users.

@aduth
Copy link
Member

aduth commented Jun 19, 2018

@chrisvanpatten Yes, this is what I have in mind with #7234 , though maybe not so strictly on the idea of the intermediate block being transparent, since I might imagine there could be some properties of the "Column" block we might want to allow a user to manipulate, e.g. a background color or width of the column.

cc also @jasmussen

@jasmussen
Copy link
Contributor

Some of the technical details in this discussion are a bit above my head, so forgive me if I'm responding in the west to a question posed in the east.

The thing that immediately springs to mind, is the "Box" block, or "container" Block, or "Section" block. See #4900.

Just like how a blockquote is a container of nested children, so could you add a "Section" block and add a number of paragraphs inside. There would be a number of reasons to do this, one simple one would be to be able to change the background color, float it to the right, and make a "Info box" in an article. Another simple reason could be to wrap a number of blocks together in a container, then make the container into a shared block. For example you might want to create a section that featured an image, a heading, a paragraph and a separator, group those together, share it as a "Post Footer" and insert it on all your posts using a template.

Imagine if the columns block supported 1 column, that would essentially be a way to test this early.

@chrisvanpatten
Copy link
Member Author

@aduth My main concern there is the UX. I think making the immediately nested blocks "transparent", and standardising around "manage settings through the parent" is an easy way to solve the increasingly fraught complicated hovering/nesting experience. Add in margin clearing, different needs for grid systems, etc. and you start to get into nightmare territory.

Not saying it can't be done, but I do think it would require some major revisions to the block's surrounding UI to make it work.

@roborourke
Copy link
Contributor

roborourke commented Jun 20, 2018 via email

@aduth
Copy link
Member

aduth commented Jun 20, 2018

Related: #6991

I expect the Columns block would be locked, thus hiding some of the default controls (e.g. sibling inserter), where editing its inner blocks is controlled exclusively through the inspector "Controls" range.

@aduth
Copy link
Member

aduth commented Jul 3, 2018

To the original goal of the issue: The recommendation will be to create multiple levels of nesting. The UX of this is important and deserves attention from its current state. We can either adapt this issue to address the specific need, or create a new one.

Generally speaking, moving forward I think the concept of a "grouped vs. ungrouped" layouts will be eliminated altogether. The layouts prop will likely remain, but will exist purely for what is currently represented in its "ungrouped" notion.

@aduth
Copy link
Member

aduth commented Jul 3, 2018

Related: #6459

@chrisvanpatten
Copy link
Member Author

chrisvanpatten commented Jul 3, 2018

@aduth Can you elaborate a little more on the relationship between layouts and template?

In #7234, the columns block implementation has changed from relying on layouts to using template. That makes total sense based on the work there, but it makes the use-case of layouts a little less clear… to me at least 😆

@aduth
Copy link
Member

aduth commented Jul 3, 2018

I'd contemplated removal of the layouts concept altogether, though I think there's some general desire for it to stick around (cc @mtias). I could see it serving some general purpose in applying styles via a nesting context to content within. Historically I even imagined the top-level editor being a nested context, where what we currently call "Wide" and "Full" alignments are merely the "wide" and "full" layouts options. Here's an old CodePen to illustrate the idea:

https://codepen.io/aduth/pen/OzZzQQ

Whether that will come to fruition is not yet certain, but the idea remains, and I could imagine this being a useful tool for blocks.

@chrisvanpatten
Copy link
Member Author

chrisvanpatten commented Jul 3, 2018

I guess it's a little confusing because layouts creates a literal layout. Layout is effectively a per-block property that's managed by the element's physical position in the editor interface, since the editor itself bundles the items from the layouts into wrapping <div>/containers within a BlockList. (Even if grouped layouts goes away, that's still the case; grouped layouts only really impacted the order in which the child blocks' HTML was serialised, not how the interface itself is represented.)

So for me I'm just not sure what the utility is there — what's the use-case to have a collection of blocks that appear together in a drag-n-droppable area in the editor, but aren't otherwise bundled together in the generated markup? I just can't imagine why an implementer would want that type of UI in the editor without a corresponding container element.

Of course if layouts changes to be something unrelated to, or at least more distinct from the current behavior, there might be value there. The align example is an interesting one. But that doesn't totally sync with the way the property is currently implemented.

(I guess, as it turns out, my opinion has changed from "make layouts more robust!" to "get rid of layouts entirely!"… which is unexpected!)

@mtias mtias added [Type] Question Questions about the design or development of the editor. and removed [Type] Enhancement A suggestion for improvement. labels Jul 19, 2018
@chrisvanpatten
Copy link
Member Author

chrisvanpatten commented Jul 20, 2018

Grouped layouts are now deprecated, and the new preferred approach is nested blocks (it's InnerBlocks all the way down).

Thanks for the help on this and related issues, @aduth!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Customization Issues related to Phase 2: Customization efforts [Feature] Nested / Inner Blocks Anything related to the experience of nested/inner blocks inside a larger container, like Group or P [Type] Question Questions about the design or development of the editor.
Projects
None yet
Development

No branches or pull requests

7 participants