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

Allow using multiple controlled inner blocks refering to the same entity #27885

Merged
merged 3 commits into from
Dec 24, 2020

Conversation

youknowriad
Copy link
Contributor

closes #22639

This uses a very simple trick to solve the duplicated controller inner blocks bug (duplicate a template part and edit one of them and see it reflected properly).

The main issue was that the block-editor is meant to only work with unique block ids, the block tree can't contain duplications. To solve this, the trick used in this PR is that for each "controlled inner blocks", instead of editing the controlled blocks directly, clone these blocks when there's an "external" change for these blocks (initialization, changing coming from a duplicated block...) and only pass to the editor clones which means the IDs are different.

Now, this can create infinite loops: an edit in one block, is going to cause changes in the other blocks too. We need to stop the edits in the second block from triggering back an edit on the original block. Fortunately, this is already handled in useBlockSync by saying: "The first change after an external change is ignored.

Also, there might be a small performance impact: All the other duplicated blocks will remount (all blocks change) on a change happening on one of them. That said, I believe this impact is acceptable for two reasons:

  • The "cloning" (remounting) only happens for the clones, not the block being currently edited which means it happens only for unselected blocks which means it's async thanks to async mode.
  • The cloning is not performed unless we're in a controlled inner blocks, and this is limitted to template parts and potentially reusable blocks, I don't expect these reusable entities to be very big (like a long post for instance).

@youknowriad youknowriad added [Type] Bug An existing feature does not function as intended Framework Issues related to broader framework topics, especially as it relates to javascript [Feature] Nested / Inner Blocks Anything related to the experience of nested/inner blocks inside a larger container, like Group or P labels Dec 24, 2020
@youknowriad youknowriad self-assigned this Dec 24, 2020
@@ -113,6 +120,37 @@ export default function useBlockSync( {
onChangeRef.current = onChange;
}, [ onInput, onChange ] );

// Determine if blocks need to be reset when they change.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes after this line are not necessary (just reordering the hooks). I believe this order makes more sense. "External" then "Internal" changes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually it seems the reordering has an effect, without it, this PR doesn't work :)

@github-actions
Copy link

github-actions bot commented Dec 24, 2020

Size Change: +36 B (0%)

Total Size: 1.28 MB

Filename Size Change
build/block-editor/index.js 129 kB +25 B (0%)
build/components/index.js 170 kB +11 B (0%)
ℹ️ View Unchanged
Filename Size Change
build/a11y/index.js 1.14 kB 0 B
build/annotations/index.js 3.81 kB 0 B
build/api-fetch/index.js 3.42 kB 0 B
build/autop/index.js 2.83 kB 0 B
build/blob/index.js 665 B 0 B
build/block-directory/index.js 8.71 kB 0 B
build/block-directory/style-rtl.css 943 B 0 B
build/block-directory/style.css 942 B 0 B
build/block-editor/style-rtl.css 11.2 kB 0 B
build/block-editor/style.css 11.2 kB 0 B
build/block-library/blocks/archives/editor-rtl.css 120 B 0 B
build/block-library/blocks/archives/editor.css 119 B 0 B
build/block-library/blocks/audio/editor-rtl.css 118 B 0 B
build/block-library/blocks/audio/editor.css 118 B 0 B
build/block-library/blocks/audio/style-rtl.css 152 B 0 B
build/block-library/blocks/audio/style.css 152 B 0 B
build/block-library/blocks/block/editor-rtl.css 211 B 0 B
build/block-library/blocks/block/editor.css 211 B 0 B
build/block-library/blocks/button/editor-rtl.css 513 B 0 B
build/block-library/blocks/button/editor.css 513 B 0 B
build/block-library/blocks/button/style-rtl.css 488 B 0 B
build/block-library/blocks/button/style.css 488 B 0 B
build/block-library/blocks/buttons/editor-rtl.css 275 B 0 B
build/block-library/blocks/buttons/editor.css 275 B 0 B
build/block-library/blocks/buttons/style-rtl.css 346 B 0 B
build/block-library/blocks/buttons/style.css 346 B 0 B
build/block-library/blocks/calendar/style-rtl.css 249 B 0 B
build/block-library/blocks/calendar/style.css 249 B 0 B
build/block-library/blocks/categories/editor-rtl.css 135 B 0 B
build/block-library/blocks/categories/editor.css 135 B 0 B
build/block-library/blocks/categories/style-rtl.css 132 B 0 B
build/block-library/blocks/categories/style.css 132 B 0 B
build/block-library/blocks/code/style-rtl.css 141 B 0 B
build/block-library/blocks/code/style.css 141 B 0 B
build/block-library/blocks/columns/editor-rtl.css 239 B 0 B
build/block-library/blocks/columns/editor.css 239 B 0 B
build/block-library/blocks/columns/style-rtl.css 467 B 0 B
build/block-library/blocks/columns/style.css 466 B 0 B
build/block-library/blocks/cover/editor-rtl.css 440 B 0 B
build/block-library/blocks/cover/editor.css 438 B 0 B
build/block-library/blocks/cover/style-rtl.css 1.27 kB 0 B
build/block-library/blocks/cover/style.css 1.27 kB 0 B
build/block-library/blocks/embed/editor-rtl.css 529 B 0 B
build/block-library/blocks/embed/editor.css 529 B 0 B
build/block-library/blocks/embed/style-rtl.css 419 B 0 B
build/block-library/blocks/embed/style.css 419 B 0 B
build/block-library/blocks/file/editor-rtl.css 246 B 0 B
build/block-library/blocks/file/editor.css 245 B 0 B
build/block-library/blocks/file/style-rtl.css 288 B 0 B
build/block-library/blocks/file/style.css 289 B 0 B
build/block-library/blocks/freeform/editor-rtl.css 2.49 kB 0 B
build/block-library/blocks/freeform/editor.css 2.49 kB 0 B
build/block-library/blocks/gallery/editor-rtl.css 692 B 0 B
build/block-library/blocks/gallery/editor.css 693 B 0 B
build/block-library/blocks/gallery/style-rtl.css 1.11 kB 0 B
build/block-library/blocks/gallery/style.css 1.11 kB 0 B
build/block-library/blocks/group/editor-rtl.css 364 B 0 B
build/block-library/blocks/group/editor.css 364 B 0 B
build/block-library/blocks/group/style-rtl.css 117 B 0 B
build/block-library/blocks/group/style.css 117 B 0 B
build/block-library/blocks/heading/editor-rtl.css 174 B 0 B
build/block-library/blocks/heading/editor.css 174 B 0 B
build/block-library/blocks/heading/style-rtl.css 137 B 0 B
build/block-library/blocks/heading/style.css 137 B 0 B
build/block-library/blocks/html/editor-rtl.css 324 B 0 B
build/block-library/blocks/html/editor.css 325 B 0 B
build/block-library/blocks/image/editor-rtl.css 738 B 0 B
build/block-library/blocks/image/editor.css 737 B 0 B
build/block-library/blocks/image/style-rtl.css 510 B 0 B
build/block-library/blocks/image/style.css 511 B 0 B
build/block-library/blocks/latest-comments/editor-rtl.css 201 B 0 B
build/block-library/blocks/latest-comments/editor.css 200 B 0 B
build/block-library/blocks/latest-comments/style-rtl.css 315 B 0 B
build/block-library/blocks/latest-comments/style.css 315 B 0 B
build/block-library/blocks/latest-posts/editor-rtl.css 183 B 0 B
build/block-library/blocks/latest-posts/editor.css 183 B 0 B
build/block-library/blocks/latest-posts/style-rtl.css 568 B 0 B
build/block-library/blocks/latest-posts/style.css 567 B 0 B
build/block-library/blocks/list/editor-rtl.css 129 B 0 B
build/block-library/blocks/list/editor.css 129 B 0 B
build/block-library/blocks/list/style-rtl.css 127 B 0 B
build/block-library/blocks/list/style.css 127 B 0 B
build/block-library/blocks/media-text/editor-rtl.css 240 B 0 B
build/block-library/blocks/media-text/editor.css 240 B 0 B
build/block-library/blocks/media-text/style-rtl.css 579 B 0 B
build/block-library/blocks/media-text/style.css 577 B 0 B
build/block-library/blocks/more/editor-rtl.css 479 B 0 B
build/block-library/blocks/more/editor.css 479 B 0 B
build/block-library/blocks/navigation-link/editor-rtl.css 438 B 0 B
build/block-library/blocks/navigation-link/editor.css 440 B 0 B
build/block-library/blocks/navigation-link/style-rtl.css 747 B 0 B
build/block-library/blocks/navigation-link/style.css 745 B 0 B
build/block-library/blocks/navigation/editor-rtl.css 1.31 kB 0 B
build/block-library/blocks/navigation/editor.css 1.31 kB 0 B
build/block-library/blocks/navigation/style-rtl.css 205 B 0 B
build/block-library/blocks/navigation/style.css 205 B 0 B
build/block-library/blocks/nextpage/editor-rtl.css 440 B 0 B
build/block-library/blocks/nextpage/editor.css 440 B 0 B
build/block-library/blocks/paragraph/editor-rtl.css 161 B 0 B
build/block-library/blocks/paragraph/editor.css 161 B 0 B
build/block-library/blocks/paragraph/style-rtl.css 279 B 0 B
build/block-library/blocks/paragraph/style.css 279 B 0 B
build/block-library/blocks/post-author/editor-rtl.css 255 B 0 B
build/block-library/blocks/post-author/editor.css 255 B 0 B
build/block-library/blocks/post-author/style-rtl.css 229 B 0 B
build/block-library/blocks/post-author/style.css 230 B 0 B
build/block-library/blocks/post-comments-form/style-rtl.css 293 B 0 B
build/block-library/blocks/post-comments-form/style.css 293 B 0 B
build/block-library/blocks/post-content/editor-rtl.css 187 B 0 B
build/block-library/blocks/post-content/editor.css 187 B 0 B
build/block-library/blocks/post-excerpt/editor-rtl.css 134 B 0 B
build/block-library/blocks/post-excerpt/editor.css 134 B 0 B
build/block-library/blocks/post-featured-image/editor-rtl.css 387 B 0 B
build/block-library/blocks/post-featured-image/editor.css 386 B 0 B
build/block-library/blocks/post-featured-image/style-rtl.css 149 B 0 B
build/block-library/blocks/post-featured-image/style.css 149 B 0 B
build/block-library/blocks/preformatted/style-rtl.css 119 B 0 B
build/block-library/blocks/preformatted/style.css 119 B 0 B
build/block-library/blocks/pullquote/editor-rtl.css 231 B 0 B
build/block-library/blocks/pullquote/editor.css 231 B 0 B
build/block-library/blocks/pullquote/style-rtl.css 359 B 0 B
build/block-library/blocks/pullquote/style.css 359 B 0 B
build/block-library/blocks/query-loop/editor-rtl.css 142 B 0 B
build/block-library/blocks/query-loop/editor.css 141 B 0 B
build/block-library/blocks/query-loop/style-rtl.css 361 B 0 B
build/block-library/blocks/query-loop/style.css 363 B 0 B
build/block-library/blocks/query/editor-rtl.css 210 B 0 B
build/block-library/blocks/query/editor.css 210 B 0 B
build/block-library/blocks/quote/editor-rtl.css 121 B 0 B
build/block-library/blocks/quote/editor.css 121 B 0 B
build/block-library/blocks/quote/style-rtl.css 215 B 0 B
build/block-library/blocks/quote/style.css 214 B 0 B
build/block-library/blocks/rss/editor-rtl.css 245 B 0 B
build/block-library/blocks/rss/editor.css 246 B 0 B
build/block-library/blocks/rss/style-rtl.css 329 B 0 B
build/block-library/blocks/rss/style.css 328 B 0 B
build/block-library/blocks/search/editor-rtl.css 213 B 0 B
build/block-library/blocks/search/editor.css 213 B 0 B
build/block-library/blocks/search/style-rtl.css 384 B 0 B
build/block-library/blocks/search/style.css 386 B 0 B
build/block-library/blocks/separator/editor-rtl.css 151 B 0 B
build/block-library/blocks/separator/editor.css 151 B 0 B
build/block-library/blocks/separator/style-rtl.css 281 B 0 B
build/block-library/blocks/separator/style.css 281 B 0 B
build/block-library/blocks/shortcode/editor-rtl.css 547 B 0 B
build/block-library/blocks/shortcode/editor.css 547 B 0 B
build/block-library/blocks/site-logo/editor-rtl.css 251 B 0 B
build/block-library/blocks/site-logo/editor.css 251 B 0 B
build/block-library/blocks/site-logo/style-rtl.css 166 B 0 B
build/block-library/blocks/site-logo/style.css 166 B 0 B
build/block-library/blocks/social-link/editor-rtl.css 211 B 0 B
build/block-library/blocks/social-link/editor.css 211 B 0 B
build/block-library/blocks/social-links/editor-rtl.css 749 B 0 B
build/block-library/blocks/social-links/editor.css 749 B 0 B
build/block-library/blocks/social-links/style-rtl.css 1.37 kB 0 B
build/block-library/blocks/social-links/style.css 1.37 kB 0 B
build/block-library/blocks/spacer/editor-rtl.css 321 B 0 B
build/block-library/blocks/spacer/editor.css 321 B 0 B
build/block-library/blocks/spacer/style-rtl.css 107 B 0 B
build/block-library/blocks/spacer/style.css 107 B 0 B
build/block-library/blocks/subhead/editor-rtl.css 148 B 0 B
build/block-library/blocks/subhead/editor.css 148 B 0 B
build/block-library/blocks/subhead/style-rtl.css 134 B 0 B
build/block-library/blocks/subhead/style.css 134 B 0 B
build/block-library/blocks/table/editor-rtl.css 530 B 0 B
build/block-library/blocks/table/editor.css 530 B 0 B
build/block-library/blocks/table/style-rtl.css 433 B 0 B
build/block-library/blocks/table/style.css 433 B 0 B
build/block-library/blocks/tag-cloud/editor-rtl.css 162 B 0 B
build/block-library/blocks/tag-cloud/editor.css 162 B 0 B
build/block-library/blocks/tag-cloud/style-rtl.css 145 B 0 B
build/block-library/blocks/tag-cloud/style.css 145 B 0 B
build/block-library/blocks/template-part/editor-rtl.css 644 B 0 B
build/block-library/blocks/template-part/editor.css 645 B 0 B
build/block-library/blocks/text-columns/editor-rtl.css 146 B 0 B
build/block-library/blocks/text-columns/editor.css 146 B 0 B
build/block-library/blocks/text-columns/style-rtl.css 209 B 0 B
build/block-library/blocks/text-columns/style.css 209 B 0 B
build/block-library/blocks/verse/editor-rtl.css 118 B 0 B
build/block-library/blocks/verse/editor.css 118 B 0 B
build/block-library/blocks/verse/style-rtl.css 137 B 0 B
build/block-library/blocks/verse/style.css 137 B 0 B
build/block-library/blocks/video/editor-rtl.css 547 B 0 B
build/block-library/blocks/video/editor.css 548 B 0 B
build/block-library/blocks/video/style-rtl.css 241 B 0 B
build/block-library/blocks/video/style.css 241 B 0 B
build/block-library/common-rtl.css 940 B 0 B
build/block-library/common.css 937 B 0 B
build/block-library/editor-rtl.css 9.07 kB 0 B
build/block-library/editor.css 9.07 kB 0 B
build/block-library/index.js 150 kB 0 B
build/block-library/style-rtl.css 8.48 kB 0 B
build/block-library/style.css 8.48 kB 0 B
build/block-library/theme-rtl.css 789 B 0 B
build/block-library/theme.css 790 B 0 B
build/block-serialization-default-parser/index.js 1.88 kB 0 B
build/block-serialization-spec-parser/index.js 3.06 kB 0 B
build/blocks/index.js 48.1 kB 0 B
build/components/style-rtl.css 15.4 kB 0 B
build/components/style.css 15.4 kB 0 B
build/compose/index.js 11 kB 0 B
build/core-data/index.js 15.2 kB 0 B
build/data-controls/index.js 829 B 0 B
build/data/index.js 8.98 kB 0 B
build/date/index.js 31.8 kB 0 B
build/deprecated/index.js 768 B 0 B
build/dom-ready/index.js 571 B 0 B
build/dom/index.js 4.95 kB 0 B
build/edit-navigation/index.js 11.1 kB 0 B
build/edit-navigation/style-rtl.css 881 B 0 B
build/edit-navigation/style.css 885 B 0 B
build/edit-post/index.js 306 kB 0 B
build/edit-post/style-rtl.css 6.47 kB 0 B
build/edit-post/style.css 6.45 kB 0 B
build/edit-site/index.js 24.3 kB 0 B
build/edit-site/style-rtl.css 3.91 kB 0 B
build/edit-site/style.css 3.91 kB 0 B
build/edit-widgets/index.js 26.3 kB 0 B
build/edit-widgets/style-rtl.css 3.1 kB 0 B
build/edit-widgets/style.css 3.1 kB 0 B
build/editor/editor-styles-rtl.css 476 B 0 B
build/editor/editor-styles.css 478 B 0 B
build/editor/index.js 42.6 kB 0 B
build/editor/style-rtl.css 3.84 kB 0 B
build/editor/style.css 3.84 kB 0 B
build/element/index.js 4.63 kB 0 B
build/escape-html/index.js 735 B 0 B
build/format-library/index.js 6.75 kB 0 B
build/format-library/style-rtl.css 547 B 0 B
build/format-library/style.css 548 B 0 B
build/hooks/index.js 2.27 kB 0 B
build/html-entities/index.js 622 B 0 B
build/i18n/index.js 3.57 kB 0 B
build/is-shallow-equal/index.js 698 B 0 B
build/keyboard-shortcuts/index.js 2.54 kB 0 B
build/keycodes/index.js 1.94 kB 0 B
build/list-reusable-blocks/index.js 3.1 kB 0 B
build/list-reusable-blocks/style-rtl.css 476 B 0 B
build/list-reusable-blocks/style.css 476 B 0 B
build/media-utils/index.js 5.32 kB 0 B
build/notices/index.js 1.86 kB 0 B
build/nux/index.js 3.42 kB 0 B
build/nux/style-rtl.css 671 B 0 B
build/nux/style.css 668 B 0 B
build/plugins/index.js 2.54 kB 0 B
build/primitives/index.js 1.43 kB 0 B
build/priority-queue/index.js 789 B 0 B
build/redux-routine/index.js 2.84 kB 0 B
build/reusable-blocks/index.js 2.92 kB 0 B
build/rich-text/index.js 13.5 kB 0 B
build/server-side-render/index.js 2.77 kB 0 B
build/shortcode/index.js 1.7 kB 0 B
build/token-list/index.js 1.27 kB 0 B
build/url/index.js 3.01 kB 0 B
build/viewport/index.js 1.86 kB 0 B
build/warning/index.js 1.14 kB 0 B
build/wordcount/index.js 1.22 kB 0 B

compressed-size-action

@@ -96,8 +98,18 @@ export default function useBlockSync( {
if ( clientId ) {
setHasControlledInnerBlocks( clientId, true );
__unstableMarkNextChangeAsNotPersistent();
replaceInnerBlocks( clientId, controlledBlocks );
// This needs to be called after the setHasControlledInnerBlocks call
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it also say why?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, this is actually not needed anymore, it's an artifact of one of my earlier explorations.

@youknowriad
Copy link
Contributor Author

Going to merge this. I want to follow-up with a few things here:

  • Try this for the reusable blocks
  • Make an e2e test with two reusable blocks in the same page.

@youknowriad youknowriad merged commit a9a5b40 into master Dec 24, 2020
@youknowriad youknowriad deleted the fix/duplicated-controlled-inner-blocks branch December 24, 2020 13:53
@github-actions github-actions bot added this to the Gutenberg 9.7 milestone Dec 24, 2020
@mtias mtias added the [Type] Code Quality Issues or PRs that relate to code quality label Dec 24, 2020
@gziolo
Copy link
Member

gziolo commented Dec 24, 2020

This is very exciting to see, great work 👏

@youknowriad
Copy link
Contributor Author

youknowriad commented Dec 24, 2020

Santa was some hours early this year.

@noahtallen
Copy link
Member

Thanks for getting this fix in @youknowriad! It's very similar to one of my earlier explorations, which would have been way easier had I known about the cloneBlock function. 🙈 I agree with you that performance is hopefully not an issue in most cases -- and only an issue with the new behavior allowed by this PR, not anything existing.

@noisysocks
Copy link
Member

noisysocks commented Jan 7, 2021

This breaks navigation and widgets because both of those screens maintain a mapping of block client IDs to widget / menu item IDs. Cloning the block changes the client ID which makes the screen unable to tell which widget / menu item needs to be updated.

Is there an alternative way to fix this?

@youknowriad
Copy link
Contributor Author

Is there an alternative way to fix this?

Can't think of any to be honest, we tried several approaches with no luck.

block client IDs to widget / menu item IDs

Shouldn't the menuId/widgetId be an attribute of the blocks them selves?

@noahtallen
Copy link
Member

Possibly we could avoid cloning the block in the case that there are no other things referencing the same entity. (I think now it clones every time?)

That might solve it for widgets + navigation, unless those screens have a possibility of showing the same entity in more than one place

@youknowriad
Copy link
Contributor Author

@noahtallen true but it seems that we'll be making the screens dependent on an implementation detail.

It should be made clear whether the "block clientIds" you supply could be changed or not by the editor. I lean towards yes since it's not really the only place where the ids can be swapped. For instance, hitting "Enter" at the end of a paragraph actually changes the id of that paragraph.

@noisysocks
Copy link
Member

Shouldn't the menuId/widgetId be an attribute of the blocks them selves?

Wouldn't this mean that every block has to have a widgetId attribute?

@noahtallen true but it seems that we'll be making the screens dependent on an implementation detail.

I disagree that client IDs are an implementation detail. We expose them in several selectors (getBlocks(), etc.) and accept them in several selectors and actions (getBlock(), updateBlockAttributes(), etc.) It's completely reasonable that a developer would use a client ID as a foreign key and so I think that we need to take care to keep them stable.

@youknowriad
Copy link
Contributor Author

Wouldn't this mean that every block has to have a widgetId attribute?

I'm not really sure how the widgets and navigation screen works tbh to be able to give the right reply here. In my mind (originally), the widget area as a whole is a single "widget" (at least that's how it used to work originally) so it would get a widgetId. If it's different now each block is a widget, then yes, the ones that are widgets should probably get a widget block wrapper or something referring to the corresponding widget, don't you think?

I disagree that client IDs are an implementation detail. We expose them in several selectors (getBlocks(), etc.) and accept them in several selectors and actions (getBlock(), updateBlockAttributes(), etc.) It's completely reasonable that a developer would use a client ID as a foreign key and so I think that we need to take care to keep them stable.

Client IDs are internal to the block editor store, they are APIs inside the block-editor package but I don't think we ever had the expectation that clientIds don't change from an external API point of view. In fact, they are considered "temporary" (not persisted) from the start so subject to change.

@talldan
Copy link
Contributor

talldan commented Jan 11, 2021

Shouldn't the menuId/widgetId be an attribute of the blocks them selves?

@youknowriad I had the same thought separately (link to the slack convo - https://wordpress.slack.com/archives/C01D71823PB/p1610003184385900), but there are still a few challenges with that:

  • Duplicating blocks would cause duplicate widget ids.
  • We could extend all blocks to have a widgetId attribute, but that would make them less portable, I haven't tested this, but I'm not sure copy/pasting them to other editors would work, the concern is the extra widgetId attribute may cause validation issues.

I don't know if we'd consider adding extra properties to attribute declarations like follows to solve those issues:

"widgetId": {
    "type": "string",
    "isSerializable": false, // not serialized to HTML.
    "isDuplicable": false // ignored by `duplicateBlock`.
}

@youknowriad
Copy link
Contributor Author

  • Serializing comment attributes won't be an issue I think, and if you paste it, I believe the attribute might just get removed.
  • Duplicating is an issue, your proposal might work, curious what others would think about it.

@talldan
Copy link
Contributor

talldan commented Jan 11, 2021

Serializing comment attributes won't be an issue I think, and if you paste it, I believe the attribute might just get removed.

You're right, that's good, one less thing to worry about.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Nested / Inner Blocks Anything related to the experience of nested/inner blocks inside a larger container, like Group or P Framework Issues related to broader framework topics, especially as it relates to javascript [Type] Bug An existing feature does not function as intended [Type] Code Quality Issues or PRs that relate to code quality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Adding duplicate Template Part removes both from page, can trigger clearing inner blocks in dirty state.
6 participants