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

Block editor: new editor.BlockControls filter #48809

Closed
wants to merge 7 commits into from

Conversation

ellatrix
Copy link
Member

@ellatrix ellatrix commented Mar 6, 2023

What?

This PR is easier to review without whitespace changes.

All use cases for the editor.BlockEdit function are adding block controls. We should create a less powerful filters specifically for adding block controls that only renders these when needed.

This is beneficial for performance, and it's easier to understand without the HoC.

For now this filter is private until we're ready to share an interface we want to expose.

Why?

How?

Testing Instructions

Testing Instructions for Keyboard

Screenshots or screencast

@ellatrix ellatrix requested a review from ajitbohra as a code owner March 6, 2023 22:14
@github-actions
Copy link

github-actions bot commented Mar 6, 2023

Size Change: +521 B (0%)

Total Size: 1.34 MB

Filename Size Change
build/block-editor/index.min.js 197 kB +521 B (0%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 993 B
build/annotations/index.min.js 2.78 kB
build/api-fetch/index.min.js 2.27 kB
build/autop/index.min.js 2.15 kB
build/blob/index.min.js 483 B
build/block-directory/index.min.js 7.2 kB
build/block-directory/style-rtl.css 1.04 kB
build/block-directory/style.css 1.04 kB
build/block-editor/content-rtl.css 4.11 kB
build/block-editor/content.css 4.1 kB
build/block-editor/default-editor-styles-rtl.css 403 B
build/block-editor/default-editor-styles.css 403 B
build/block-editor/style-rtl.css 14.4 kB
build/block-editor/style.css 14.4 kB
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 90 B
build/block-library/blocks/archives/style.css 90 B
build/block-library/blocks/audio/editor-rtl.css 150 B
build/block-library/blocks/audio/editor.css 150 B
build/block-library/blocks/audio/style-rtl.css 122 B
build/block-library/blocks/audio/style.css 122 B
build/block-library/blocks/audio/theme-rtl.css 138 B
build/block-library/blocks/audio/theme.css 138 B
build/block-library/blocks/avatar/editor-rtl.css 116 B
build/block-library/blocks/avatar/editor.css 116 B
build/block-library/blocks/avatar/style-rtl.css 91 B
build/block-library/blocks/avatar/style.css 91 B
build/block-library/blocks/block/editor-rtl.css 305 B
build/block-library/blocks/block/editor.css 305 B
build/block-library/blocks/button/editor-rtl.css 587 B
build/block-library/blocks/button/editor.css 587 B
build/block-library/blocks/button/style-rtl.css 628 B
build/block-library/blocks/button/style.css 627 B
build/block-library/blocks/buttons/editor-rtl.css 337 B
build/block-library/blocks/buttons/editor.css 337 B
build/block-library/blocks/buttons/style-rtl.css 332 B
build/block-library/blocks/buttons/style.css 332 B
build/block-library/blocks/calendar/style-rtl.css 239 B
build/block-library/blocks/calendar/style.css 239 B
build/block-library/blocks/categories/editor-rtl.css 84 B
build/block-library/blocks/categories/editor.css 83 B
build/block-library/blocks/categories/style-rtl.css 100 B
build/block-library/blocks/categories/style.css 100 B
build/block-library/blocks/code/editor-rtl.css 53 B
build/block-library/blocks/code/editor.css 53 B
build/block-library/blocks/code/style-rtl.css 121 B
build/block-library/blocks/code/style.css 121 B
build/block-library/blocks/code/theme-rtl.css 124 B
build/block-library/blocks/code/theme.css 124 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 406 B
build/block-library/blocks/columns/style.css 406 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 125 B
build/block-library/blocks/comment-author-avatar/editor.css 125 B
build/block-library/blocks/comment-content/style-rtl.css 92 B
build/block-library/blocks/comment-content/style.css 92 B
build/block-library/blocks/comment-template/style-rtl.css 199 B
build/block-library/blocks/comment-template/style.css 198 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 123 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 222 B
build/block-library/blocks/comments-pagination/editor.css 209 B
build/block-library/blocks/comments-pagination/style-rtl.css 235 B
build/block-library/blocks/comments-pagination/style.css 231 B
build/block-library/blocks/comments-title/editor-rtl.css 75 B
build/block-library/blocks/comments-title/editor.css 75 B
build/block-library/blocks/comments/editor-rtl.css 840 B
build/block-library/blocks/comments/editor.css 839 B
build/block-library/blocks/comments/style-rtl.css 637 B
build/block-library/blocks/comments/style.css 636 B
build/block-library/blocks/cover/editor-rtl.css 612 B
build/block-library/blocks/cover/editor.css 613 B
build/block-library/blocks/cover/style-rtl.css 1.57 kB
build/block-library/blocks/cover/style.css 1.56 kB
build/block-library/blocks/embed/editor-rtl.css 293 B
build/block-library/blocks/embed/editor.css 293 B
build/block-library/blocks/embed/style-rtl.css 410 B
build/block-library/blocks/embed/style.css 410 B
build/block-library/blocks/embed/theme-rtl.css 138 B
build/block-library/blocks/embed/theme.css 138 B
build/block-library/blocks/file/editor-rtl.css 300 B
build/block-library/blocks/file/editor.css 300 B
build/block-library/blocks/file/style-rtl.css 265 B
build/block-library/blocks/file/style.css 265 B
build/block-library/blocks/file/view.min.js 353 B
build/block-library/blocks/freeform/editor-rtl.css 2.44 kB
build/block-library/blocks/freeform/editor.css 2.44 kB
build/block-library/blocks/gallery/editor-rtl.css 984 B
build/block-library/blocks/gallery/editor.css 988 B
build/block-library/blocks/gallery/style-rtl.css 1.55 kB
build/block-library/blocks/gallery/style.css 1.55 kB
build/block-library/blocks/gallery/theme-rtl.css 122 B
build/block-library/blocks/gallery/theme.css 122 B
build/block-library/blocks/group/editor-rtl.css 654 B
build/block-library/blocks/group/editor.css 654 B
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 78 B
build/block-library/blocks/group/theme.css 78 B
build/block-library/blocks/heading/style-rtl.css 76 B
build/block-library/blocks/heading/style.css 76 B
build/block-library/blocks/html/editor-rtl.css 332 B
build/block-library/blocks/html/editor.css 333 B
build/block-library/blocks/image/editor-rtl.css 830 B
build/block-library/blocks/image/editor.css 829 B
build/block-library/blocks/image/style-rtl.css 652 B
build/block-library/blocks/image/style.css 652 B
build/block-library/blocks/image/theme-rtl.css 137 B
build/block-library/blocks/image/theme.css 137 B
build/block-library/blocks/latest-comments/style-rtl.css 357 B
build/block-library/blocks/latest-comments/style.css 357 B
build/block-library/blocks/latest-posts/editor-rtl.css 213 B
build/block-library/blocks/latest-posts/editor.css 212 B
build/block-library/blocks/latest-posts/style-rtl.css 478 B
build/block-library/blocks/latest-posts/style.css 478 B
build/block-library/blocks/list/style-rtl.css 88 B
build/block-library/blocks/list/style.css 88 B
build/block-library/blocks/media-text/editor-rtl.css 266 B
build/block-library/blocks/media-text/editor.css 263 B
build/block-library/blocks/media-text/style-rtl.css 507 B
build/block-library/blocks/media-text/style.css 505 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/editor-rtl.css 716 B
build/block-library/blocks/navigation-link/editor.css 715 B
build/block-library/blocks/navigation-link/style-rtl.css 115 B
build/block-library/blocks/navigation-link/style.css 115 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 299 B
build/block-library/blocks/navigation-submenu/editor.css 299 B
build/block-library/blocks/navigation/editor-rtl.css 2.13 kB
build/block-library/blocks/navigation/editor.css 2.14 kB
build/block-library/blocks/navigation/style-rtl.css 2.22 kB
build/block-library/blocks/navigation/style.css 2.2 kB
build/block-library/blocks/navigation/view-modal.min.js 2.81 kB
build/block-library/blocks/navigation/view.min.js 447 B
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/editor-rtl.css 401 B
build/block-library/blocks/page-list/editor.css 401 B
build/block-library/blocks/page-list/style-rtl.css 175 B
build/block-library/blocks/page-list/style.css 175 B
build/block-library/blocks/paragraph/editor-rtl.css 174 B
build/block-library/blocks/paragraph/editor.css 174 B
build/block-library/blocks/paragraph/style-rtl.css 279 B
build/block-library/blocks/paragraph/style.css 281 B
build/block-library/blocks/post-author/style-rtl.css 175 B
build/block-library/blocks/post-author/style.css 176 B
build/block-library/blocks/post-comments-form/editor-rtl.css 96 B
build/block-library/blocks/post-comments-form/editor.css 96 B
build/block-library/blocks/post-comments-form/style-rtl.css 501 B
build/block-library/blocks/post-comments-form/style.css 501 B
build/block-library/blocks/post-date/style-rtl.css 61 B
build/block-library/blocks/post-date/style.css 61 B
build/block-library/blocks/post-excerpt/editor-rtl.css 71 B
build/block-library/blocks/post-excerpt/editor.css 71 B
build/block-library/blocks/post-excerpt/style-rtl.css 134 B
build/block-library/blocks/post-excerpt/style.css 134 B
build/block-library/blocks/post-featured-image/editor-rtl.css 586 B
build/block-library/blocks/post-featured-image/editor.css 584 B
build/block-library/blocks/post-featured-image/style-rtl.css 318 B
build/block-library/blocks/post-featured-image/style.css 318 B
build/block-library/blocks/post-navigation-link/style-rtl.css 153 B
build/block-library/blocks/post-navigation-link/style.css 153 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 282 B
build/block-library/blocks/post-template/style.css 282 B
build/block-library/blocks/post-terms/style-rtl.css 96 B
build/block-library/blocks/post-terms/style.css 96 B
build/block-library/blocks/post-title/style-rtl.css 100 B
build/block-library/blocks/post-title/style.css 100 B
build/block-library/blocks/preformatted/style-rtl.css 103 B
build/block-library/blocks/preformatted/style.css 103 B
build/block-library/blocks/pullquote/editor-rtl.css 135 B
build/block-library/blocks/pullquote/editor.css 135 B
build/block-library/blocks/pullquote/style-rtl.css 326 B
build/block-library/blocks/pullquote/style.css 325 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-pagination/editor-rtl.css 221 B
build/block-library/blocks/query-pagination/editor.css 211 B
build/block-library/blocks/query-pagination/style-rtl.css 288 B
build/block-library/blocks/query-pagination/style.css 284 B
build/block-library/blocks/query-title/style-rtl.css 63 B
build/block-library/blocks/query-title/style.css 63 B
build/block-library/blocks/query/editor-rtl.css 463 B
build/block-library/blocks/query/editor.css 463 B
build/block-library/blocks/quote/style-rtl.css 222 B
build/block-library/blocks/quote/style.css 222 B
build/block-library/blocks/quote/theme-rtl.css 223 B
build/block-library/blocks/quote/theme.css 226 B
build/block-library/blocks/read-more/style-rtl.css 132 B
build/block-library/blocks/read-more/style.css 132 B
build/block-library/blocks/rss/editor-rtl.css 149 B
build/block-library/blocks/rss/editor.css 149 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 165 B
build/block-library/blocks/search/editor.css 165 B
build/block-library/blocks/search/style-rtl.css 409 B
build/block-library/blocks/search/style.css 406 B
build/block-library/blocks/search/theme-rtl.css 114 B
build/block-library/blocks/search/theme.css 114 B
build/block-library/blocks/separator/editor-rtl.css 146 B
build/block-library/blocks/separator/editor.css 146 B
build/block-library/blocks/separator/style-rtl.css 234 B
build/block-library/blocks/separator/style.css 234 B
build/block-library/blocks/separator/theme-rtl.css 194 B
build/block-library/blocks/separator/theme.css 194 B
build/block-library/blocks/shortcode/editor-rtl.css 474 B
build/block-library/blocks/shortcode/editor.css 474 B
build/block-library/blocks/site-logo/editor-rtl.css 489 B
build/block-library/blocks/site-logo/editor.css 489 B
build/block-library/blocks/site-logo/style-rtl.css 203 B
build/block-library/blocks/site-logo/style.css 203 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 116 B
build/block-library/blocks/site-title/editor.css 116 B
build/block-library/blocks/site-title/style-rtl.css 57 B
build/block-library/blocks/site-title/style.css 57 B
build/block-library/blocks/social-link/editor-rtl.css 184 B
build/block-library/blocks/social-link/editor.css 184 B
build/block-library/blocks/social-links/editor-rtl.css 674 B
build/block-library/blocks/social-links/editor.css 673 B
build/block-library/blocks/social-links/style-rtl.css 1.4 kB
build/block-library/blocks/social-links/style.css 1.39 kB
build/block-library/blocks/spacer/editor-rtl.css 332 B
build/block-library/blocks/spacer/editor.css 332 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table/editor-rtl.css 433 B
build/block-library/blocks/table/editor.css 433 B
build/block-library/blocks/table/style-rtl.css 651 B
build/block-library/blocks/table/style.css 650 B
build/block-library/blocks/table/theme-rtl.css 157 B
build/block-library/blocks/table/theme.css 157 B
build/block-library/blocks/tag-cloud/style-rtl.css 251 B
build/block-library/blocks/tag-cloud/style.css 253 B
build/block-library/blocks/template-part/editor-rtl.css 404 B
build/block-library/blocks/template-part/editor.css 404 B
build/block-library/blocks/template-part/theme-rtl.css 101 B
build/block-library/blocks/template-part/theme.css 101 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/verse/style-rtl.css 99 B
build/block-library/blocks/verse/style.css 99 B
build/block-library/blocks/video/editor-rtl.css 552 B
build/block-library/blocks/video/editor.css 555 B
build/block-library/blocks/video/style-rtl.css 179 B
build/block-library/blocks/video/style.css 179 B
build/block-library/blocks/video/theme-rtl.css 139 B
build/block-library/blocks/video/theme.css 139 B
build/block-library/classic-rtl.css 179 B
build/block-library/classic.css 179 B
build/block-library/common-rtl.css 1.11 kB
build/block-library/common.css 1.11 kB
build/block-library/editor-elements-rtl.css 75 B
build/block-library/editor-elements.css 75 B
build/block-library/editor-rtl.css 11.6 kB
build/block-library/editor.css 11.6 kB
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/index.min.js 201 kB
build/block-library/reset-rtl.css 478 B
build/block-library/reset.css 478 B
build/block-library/style-rtl.css 12.7 kB
build/block-library/style.css 12.7 kB
build/block-library/theme-rtl.css 698 B
build/block-library/theme.css 703 B
build/block-serialization-default-parser/index.min.js 1.13 kB
build/block-serialization-spec-parser/index.min.js 2.83 kB
build/blocks/index.min.js 51 kB
build/components/index.min.js 208 kB
build/components/style-rtl.css 11.6 kB
build/components/style.css 11.7 kB
build/compose/index.min.js 12.4 kB
build/core-data/index.min.js 16.2 kB
build/customize-widgets/index.min.js 12.2 kB
build/customize-widgets/style-rtl.css 1.41 kB
build/customize-widgets/style.css 1.41 kB
build/data-controls/index.min.js 663 B
build/data/index.min.js 8.58 kB
build/date/index.min.js 40.4 kB
build/deprecated/index.min.js 518 B
build/dom-ready/index.min.js 336 B
build/dom/index.min.js 4.72 kB
build/edit-post/classic-rtl.css 571 B
build/edit-post/classic.css 571 B
build/edit-post/index.min.js 34.8 kB
build/edit-post/style-rtl.css 7.53 kB
build/edit-post/style.css 7.52 kB
build/edit-site/index.min.js 64.2 kB
build/edit-site/style-rtl.css 10.1 kB
build/edit-site/style.css 10.1 kB
build/edit-widgets/index.min.js 17.3 kB
build/edit-widgets/style-rtl.css 4.55 kB
build/edit-widgets/style.css 4.55 kB
build/editor/index.min.js 45.7 kB
build/editor/style-rtl.css 3.54 kB
build/editor/style.css 3.53 kB
build/element/index.min.js 4.95 kB
build/escape-html/index.min.js 548 B
build/format-library/index.min.js 7.26 kB
build/format-library/style-rtl.css 557 B
build/format-library/style.css 556 B
build/hooks/index.min.js 1.66 kB
build/html-entities/index.min.js 454 B
build/i18n/index.min.js 3.79 kB
build/is-shallow-equal/index.min.js 535 B
build/keyboard-shortcuts/index.min.js 1.79 kB
build/keycodes/index.min.js 1.94 kB
build/list-reusable-blocks/index.min.js 2.14 kB
build/list-reusable-blocks/style-rtl.css 865 B
build/list-reusable-blocks/style.css 865 B
build/media-utils/index.min.js 2.99 kB
build/notices/index.min.js 977 B
build/plugins/index.min.js 1.95 kB
build/preferences-persistence/index.min.js 2.23 kB
build/preferences/index.min.js 1.35 kB
build/primitives/index.min.js 960 B
build/priority-queue/index.min.js 1.52 kB
build/private-apis/index.min.js 937 B
build/react-i18n/index.min.js 702 B
build/react-refresh-entry/index.min.js 8.44 kB
build/react-refresh-runtime/index.min.js 7.31 kB
build/redux-routine/index.min.js 2.75 kB
build/reusable-blocks/index.min.js 2.26 kB
build/reusable-blocks/style-rtl.css 265 B
build/reusable-blocks/style.css 265 B
build/rich-text/index.min.js 11 kB
build/server-side-render/index.min.js 2.09 kB
build/shortcode/index.min.js 1.52 kB
build/style-engine/index.min.js 1.53 kB
build/token-list/index.min.js 650 B
build/url/index.min.js 3.74 kB
build/vendors/inert-polyfill.min.js 2.48 kB
build/vendors/react-dom.min.js 41.8 kB
build/vendors/react.min.js 4.02 kB
build/viewport/index.min.js 1.09 kB
build/warning/index.min.js 280 B
build/widgets/index.min.js 7.3 kB
build/widgets/style-rtl.css 1.18 kB
build/widgets/style.css 1.18 kB
build/wordcount/index.min.js 1.06 kB

compressed-size-action

@ellatrix ellatrix changed the title Block editor: dedicated block controls filter Block editor: new editor.BlockControls filter Mar 6, 2023
className={ classnames(
props.className,
isEditingAsBlocks &&
'is-content-locked-editing-as-blocks'
Copy link
Member Author

Choose a reason for hiding this comment

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

This class is not used anywhere at all.

@@ -20,6 +24,76 @@ import { BlockEditContextProvider, useBlockEditContext } from './context';
*/
export { useBlockEditContext };

function BlockControlFilters( props ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't this the same thing as just adding an empty component and wrapping it with withFilters or something like that?

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess there are a few differences:

  • The filter doesn't have to render the previous value. This is a great improvement DevX wise.
  • It adds a check shouldDisplayControls: I'm guessing that's to improve performance and avoid rendering these controls if not necessary. While this is a good thing probably, it does add a bit of overhead in the sense that most of these filters actually render InspectorControls or BlockControls that do these checks as well. So using a context value for these checks might still be a good idea. Also, should we support the case where we pass flag to enable __experimentalExposeControlsToChildren behavior or not? (so let's say that this is generally a good thing)
  • The other thing is that folks can render anything in this filter and not just controls, like random Divs... So maybe, we should forbid that by adding some hidden wrapper or something like that or finding a way to check that it renders no DOM nodes.

Copy link
Contributor

Choose a reason for hiding this comment

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

For the performance aspect, we should be a bit careful here to not actually degrade performance. Some existing hooks might have existed earlier (like by checking a block support) while here we first check shouldDisplayControls then check the block supports ... within the hook. So I wonder if we should first land shouldDisplayControls as a context value before this PR.

Copy link
Member Author

Choose a reason for hiding this comment

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

While this is a good thing probably, it does add a bit of overhead in the sense that most of these filters actually render InspectorControls or BlockControls that do these checks as well. So using a context value for these checks might still be a good idea.

The overhead is almost negligible. I'd prefer keeping all this internal instead of exposing it through context, although this context in particular can be entirely internal if we don't use the existing context.

Also, should we support the case where we pass flag to enable __experimentalExposeControlsToChildren behavior or not? (so let's say that this is generally a good thing)

It supports it. The filters will render.

For the performance aspect, we should be a bit careful here to not actually degrade performance. Some existing hooks might have existed earlier (like by checking a block support) while here we first check shouldDisplayControls then check the block supports ... within the hook. So I wonder if we should first land shouldDisplayControls as a context value before this PR.

Not sure how this would degrade performance. We still guard hasSelectedInnerBlock with a __experimentalExposeControlsToChildren check. Using context for InspectorControls and BlockControls would be better yes.

Copy link
Member Author

Choose a reason for hiding this comment

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

The filter doesn't have to render the previous value. This is a great improvement DevX wise.

That's correct. If this is a good pattern for other filters, at some point we could move this to the components package next to withFilters, but let's see how it goes.

Copy link
Member Author

Choose a reason for hiding this comment

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

The other thing is that folks can render anything in this filter and not just controls, like random Divs... So maybe, we should forbid that by adding some hidden wrapper or something like that or finding a way to check that it renders no DOM nodes.

Yes, they could do this previously too. I do like that idea! We should be as restrictive as possible with this new filter.

Copy link
Contributor

Choose a reason for hiding this comment

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

It supports it. The filters will render.

I mean some controls won't render if the block itself is not selected and that additional check and rendering is not necessary in this case.

Copy link
Member Author

Choose a reason for hiding this comment

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

I mean some controls won't render if the block itself is not selected and that additional check and rendering is not necessary in this case.

I'm not sure I'm following 😅

Copy link
Contributor

@youknowriad youknowriad left a comment

Choose a reason for hiding this comment

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

There's still some open questions but I generally like how this avoids the issues we might have with:

  • Removing the need to ensure BlockEdit is rendered properly (unmounting issues...)$
  • Take care of some initial performance optimizations. (though here we must be careful)

@github-actions
Copy link

github-actions bot commented Mar 7, 2023

Flaky tests detected in 49e6aa6.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/4356473636
📝 Reported issues:

@youknowriad youknowriad requested a review from gziolo March 7, 2023 08:49
@youknowriad
Copy link
Contributor

Ok, this is looking more and more as a great approach, I'd appreciate thoughts from @gziolo

withToolbarControls
ifCondition( ( { name } ) => hasBlockSupport( name, 'align' ) )(
ToolbarControls
)
Copy link
Member Author

Choose a reason for hiding this comment

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

It's worth noting that these checks aren't contributing much to the performance improvement, but still, it's good practice to avoid as much calls to hooks as possible. Hopefully new hooks and plugins copy this pattern.

@gziolo
Copy link
Member

gziolo commented Mar 7, 2023

Ok, this is looking more and more as a great approach, I'd appreciate thoughts from @gziolo

In general, you have my 100% support in the efforts to remove make those filters based on withFilters HOC something that will remain no longer used other than as a backward compatibility measure. The proposed solution makes everything much more straightforward, so we should seek ways how to proceed with that.

I was looking at PHP implementation for Block Supports, for example:

// Register the block support.
WP_Block_Supports::get_instance()->register(
'spacing',
array(
'register_attribute' => 'gutenberg_register_spacing_support',
'apply' => 'gutenberg_apply_spacing_support',
)
);

Have you considered a more formal API that is based on the data store instead of further promoting filters?

registerBlockSupport( 'core/anchor', {
    isSupported( name ) {
        return hasBlockSupport( name, 'anchor' );
    },
    updateAttributes( attributes )
        if ( 'type' in ( attributes?.anchor ?? {} ) ) {
		return attributes;
	}

        return {
		...attributes,
		anchor: ANCHOR_SCHEMA,
	};
   }, 
   Edit( props ) {
       return <EditAnchorControls { ...props } />; 
   }
} );

Both updateAttributes and Edit would never get called when isSupported() returns false.

I think it's close to what the community was trying to develop in the early days when struggling with the complexity of the filters-based approach.

Edit: I quickly sketched the API that could get added in JavaScript to complement what exists in PHP. I would like you to treat it as a starting point in the discussion on what the developers could use.

@gziolo gziolo added [Feature] Block API API that allows to express the block paradigm. [Feature] Extensibility The ability to extend blocks or the editing experience [Type] Enhancement A suggestion for improvement. [Type] New API New API to be used by plugin developers or package users. and removed [Type] Enhancement A suggestion for improvement. labels Mar 7, 2023
@youknowriad
Copy link
Contributor

Yeah, I think ultimately, something like @gziolo's proposal would be awesome. Maybe it's an opportunity to start this as a private API (starting with "controls" key proposed in this PR) and enhance it slowly until we arrive to a state that we can confidently share.

return;
}

return blockControlFilters.handlers.map(
Copy link
Member

@gziolo gziolo Mar 7, 2023

Choose a reason for hiding this comment

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

That's probably not quite how WordPress filters were designed to work. I'm not sure I've ever seen usage where the previous value would not get set at all. It works here really well though 😄

@ellatrix
Copy link
Member Author

ellatrix commented Mar 7, 2023

I like that proposal! Ok, let's lock the API here and then explore exposing it through registerBlockSupport later on. The idea remains the same: "Edit" added through registerBlockSupport should only add the controls and not filter the whole Edit component.

@@ -27,6 +27,8 @@ export const settings = {
};

export const init = () => {
// This is a temporary solution so the link is displayed at the top.
// See https://github.com/WordPress/gutenberg/pull/31833/files#r634291993.
Copy link
Member Author

Choose a reason for hiding this comment

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

@ntsekouras Any ideas on how to remove this temporary approach?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure since we don't want to expose blockControlsFilterName. Probably we could just lock it and then export it for use in Query Loop and adjust the filter in a similar fashion.

Also in a different direction this specific functionality could be part of a new SlotFill in block card/description. This is tracked in: #41236 as a task.

@@ -24,6 +29,9 @@ import { store as blockEditorStore } from '../../store';
*/
export { useBlockEditContext };

// Please do not export this at the package level until we have a stable API.
export const blockControlsFilterName = uuid();
Copy link
Member

Choose a reason for hiding this comment

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

Yes, that might work as a first iteration 👍🏻

Copy link
Member Author

Choose a reason for hiding this comment

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

Look like this approach creates flakiness in tests. Not sure why.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, figured out why. Hook names must start with a letter and uuid() will randomly also generate ids starting with a number.

@ellatrix ellatrix force-pushed the try/dedicated-block-controls-filter branch from f79ea8f to 49e6aa6 Compare March 7, 2023 16:45
@ellatrix
Copy link
Member Author

ellatrix commented Mar 7, 2023

For now, let's go ahead with this change.

Here's an iteration on the interface @gziolo shared. If we base it on the support key, we don't even need isSupported.

registerBlockSupport( supportKey, {
    // Can be merged with existing settings.
    blockSettings: {
        attributes: {
            align: { type: 'string' }
        },
    },
   Controls( { attributes, setAttributes } ) {
       return <InspectorControls>; 
   },
   // Maybe this can be optional and use getSaveProps by default.
   useBlockProps( attributes, blockType ) {
       return {
           className: ...
       }
   },
   getSaveProps( attributes, blockType ) {
       return {
           className: ...
       }
   }
} );

@ellatrix
Copy link
Member Author

ellatrix commented Mar 7, 2023

I any case this PR can be seen as preparatory work moving us in the right direction.

@gziolo
Copy link
Member

gziolo commented Mar 8, 2023

Here's an iteration on the interface @gziolo shared. If we base it on the support key, we don't even need isSupported.

Yes, it could work in most cases. I'm not sure about the case where the block supports entry has some complex structure with the nested objects, but maybe it isn't a concern. You should now have a better overview based on the refactoring applied so far.

I any case this PR can be seen as preparatory work moving us in the right direction.

Yes, it definitely could be landed separately with the current approach for a temporary filter that makes it impossible to use it for adding. The only question is whether sites or plugins use the existing filters to unregister controls when they don't want to show them in the UI. That might complicate the gradual rollout a little bit. Although, it isn't impossible to detect, so maybe we can account for that as well by checking whether current filters exist and bail out in the new implementation if they were removed with the assumption they were disabled.

@@ -395,7 +387,9 @@ addFilter(
withPositionStyles
);
addFilter(
'editor.BlockEdit',
'editor.BlockControls',
Copy link
Member

Choose a reason for hiding this comment

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

I think this should be blockControlsFilterName.

@Mamaduka
Copy link
Member

Mamaduka commented Jan 5, 2024

@ellatrix, should we close this now that #56862 is merged?

@ellatrix ellatrix closed this Feb 5, 2024
@ellatrix ellatrix deleted the try/dedicated-block-controls-filter branch February 5, 2024 08:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Block API API that allows to express the block paradigm. [Feature] Extensibility The ability to extend blocks or the editing experience [Type] New API New API to be used by plugin developers or package users.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants