WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
9.99k stars 4.01k forks source link

Webcomponents with slots and InnerBlocks limitation #18778

Open paales opened 4 years ago

paales commented 4 years ago

I’m trying to get webcomponents working with Gutenberg. I’ve got a webcomponent that has two slots. Those two slots allow for any content to be present:

<fancy-layout size="large" stretch="right">
  <div slot="left">Content goes here</div>
  <div slot="right">Secondary content goes here</div>
</fancy-layout>

I've been trying to build a custom block that allows me to fill those two slots, but it seems it's impossible to do so. I've tried to use <InnerBlocks /> template system, but it seems it will always add wrapper divs, which makes it impossible to actually achieve this structure.

There has been some discussion to actually solve this at the webcomponent level, but because of good reasons it hasn't been implemented https://github.com/w3c/webcomponents/issues/574

I think it should be possible to define multiple areas where we can actually have a blocklist available.

<fancy-layout size="large" stretch="right">
  <div slot="left"><InnerBlocks onContent={(content) => setAttributes({left: content})}/></div>
  <div slot="right"><InnerBlocks onContent={(content) => setAttributes({right: content})}/></div>
</fancy-layout>

Disclaimer: I'm not familiair enough with the internal of Gutenberg yet, so I might be missing something how to actually achieve this with the current setup..

talldan commented 4 years ago

Hi @paales. Yeah, there's a one InnerBlocks component per block limitation at the moment. Not sure if that's something that would change in the future, a lot of code would need to be refactored.

The way this has been solved in core blocks (like columns) is to have an InnerBlocks component that can represent the columns (to which a column can be added), and then those column blocks also implement InnerBlocks and allow 'rows' to be added (any block). Granted that adds divs, which you don't want.

I'm not sure I can help with any web component related questions. I saw @felixarntz talk about them at WordCamp Europe about web components and the block editor, so he might be a good contributor to connect with! (https://github.com/felixarntz/web-components-in-gutenberg)

What should we do with this issue? I'm finding it hard to categorize it! Is it something you'd like to keep open? If you're able to distill it down to an enhancement request that'd be great.

paales commented 4 years ago

Hi @talldan,

Not sure if that's something that would change in the future, a lot of code would need to be refactored.

That's what I figured. I'm looking for a workaround to see if I'm able to create some wrapper component that does JS magic to solve the issue.

The example of @felixarntz doesn't seem to be addressing this issue, there isn't an example where he uses multiple slots.

I think we should keep this issue open. Maybe you can help me mitigate the issue: So I have a hard requirement of the HTML to render correctly, but I might be able to 'copy' all the HTML into slots dynamically in some way. There will be positioning issues here and there, but maybe I can 'overlay' the react editor UI in some way?

paales commented 4 years ago
<editor-wrapper>
    <slot name="editor-ui-html">
        <InnerBlocks/>
    </slot>
    <slot name="render-ui">
        <fancy-layout size="large" stretch="right">
            <div slot="left">[[left]]</div>
            <div slot="right">[[right]]</div>
        </fancy-layout>
    </slot>
</editor-wrapper>

Some form of pseudo code, but it Might be doable?

talldan commented 4 years ago

@paales This PR seems relevant in that it seeks to remove the wrappers around block lists: https://github.com/WordPress/gutenberg/pull/19910.

I'm not completely familiar with web components so its a little hard for me to grasp exactly what's possible.

However, I wondered with that PR whether you may be able to achieve something with a block template that's similar to what you describe. A parent block with a template that has two inner content blocks for the left and right content. Possibly those inner content blocks could have a slot attribute that's hard-coded in the template and that gets output on the wrapping element.

paales commented 4 years ago

With this PR, the DOM tree of the columns block is exactly the same as the DOM tree on the front end. This removes the need add any styling for the editor. There's still a few things that ideally should be adjusted (we shouldn't be adding a margin to blocks by default because some blocks need to reset this). But you get the idea and the direction.

If this is true, that might solve the issue. This is exactly what I was looking for. I'll ask the author of the PR if this solves the issue.