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

Refactor dropzone for unmodified default blocks with useBlockDropZone and InsertionPoint #44647

Merged
merged 8 commits into from
Oct 13, 2022

Conversation

kevin940726
Copy link
Member

@kevin940726 kevin940726 commented Oct 3, 2022

What?

A follow-up and refactor of #42722, an alternative to #44606.

This refactor basically reverts the implementation in the Paragraph block (#42722) and re-implements the same feature in useBlockDropZone and <InsertionPoint> using
<BlockPopover> and isUnmodifiedDefaultBlock (as suggested in #42722 (comment)). This refactor allows us to reuse the same drop zone and their event listeners so that we don't have to bind them elsewhere.

Why?

The original PR fails some performance metrics when rendering a large list of empty paragraph blocks and it doesn't take setDefaultBlock into account. This PR solves both issues.

How?

  1. We calculate the drop indicator and take unmodified default blocks into account in useBlockDropZone.
  2. If there's an unmodified default block nearby then change the drop operation to replace and call showInsertionPoint with it.
  3. Render the dropzone indicator (fully presentational component) on top of the unmodified default block using <BlockPopover>.

This PR has a nice side effect that dragging in-between unmodified default blocks will also trigger the drop zone indicator and allow dropping. This is smoother than the previous implementation, where only hovering on the empty paragraph blocks will trigger the drop zone (which is often very small). See it in action in the below screencast.

Testing Instructions

  1. Create some empty paragraph blocks (unmodified default blocks) and some other blocks with contents.
  2. Drag something around the post and see that the dropzone indicator appears when hovering on the empty paragraph blocks.
  3. Drop to replace the empty paragraph blocks with some blocks (depending on the dragged data).

Screenshots or screencast

Kapture.2022-10-04.at.12.05.16.mp4

How to review

  1. See useBlockDropZone first, and follow the logic there.
  2. block-editor's actions (showInsertionPoint) -> reducer.
  3. <InsertionPoint> is where the presentational component renders.
  4. <BlockPopoverDropZone> (block-popover/drop-zone.js) is where the presentational drop zone component is.
  5. Other source files are mostly code removals from Allow dropping an image on an empty paragraph block to create an image block #42722.
  6. The rests are tests and renamings.

@kevin940726 kevin940726 added [Type] Enhancement A suggestion for improvement. [Package] Block editor /packages/block-editor labels Oct 3, 2022
@github-actions
Copy link

github-actions bot commented Oct 3, 2022

Size Change: -167 B (0%)

Total Size: 1.27 MB

Filename Size Change
build/block-editor/index.min.js 168 kB +421 B (0%)
build/block-editor/style-rtl.css 15.5 kB +39 B (0%)
build/block-editor/style.css 15.5 kB +43 B (0%)
build/block-library/blocks/paragraph/editor-rtl.css 174 B -143 B (-45%) 🎉
build/block-library/blocks/paragraph/editor.css 174 B -143 B (-45%) 🎉
build/block-library/editor-rtl.css 11.2 kB -54 B (0%)
build/block-library/editor.css 11.2 kB -54 B (0%)
build/block-library/index.min.js 191 kB -374 B (0%)
build/blocks/index.min.js 49.8 kB +3 B (0%)
build/components/index.min.js 202 kB +94 B (0%)
build/edit-navigation/index.min.js 16.1 kB +1 B (0%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 982 B
build/annotations/index.min.js 2.76 kB
build/api-fetch/index.min.js 2.26 kB
build/autop/index.min.js 2.14 kB
build/blob/index.min.js 475 B
build/block-directory/index.min.js 7.09 kB
build/block-directory/style-rtl.css 990 B
build/block-directory/style.css 991 B
build/block-editor/default-editor-styles-rtl.css 378 B
build/block-editor/default-editor-styles.css 378 B
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 126 B
build/block-library/blocks/audio/theme.css 126 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 84 B
build/block-library/blocks/avatar/style.css 84 B
build/block-library/blocks/block/editor-rtl.css 161 B
build/block-library/blocks/block/editor.css 161 B
build/block-library/blocks/button/editor-rtl.css 482 B
build/block-library/blocks/button/editor.css 482 B
build/block-library/blocks/button/style-rtl.css 523 B
build/block-library/blocks/button/style.css 523 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 187 B
build/block-library/blocks/comment-template/style.css 185 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 834 B
build/block-library/blocks/comments/editor.css 832 B
build/block-library/blocks/comments/style-rtl.css 632 B
build/block-library/blocks/comments/style.css 630 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.55 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 126 B
build/block-library/blocks/embed/theme.css 126 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 253 B
build/block-library/blocks/file/style.css 254 B
build/block-library/blocks/file/view.min.js 346 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 948 B
build/block-library/blocks/gallery/editor.css 950 B
build/block-library/blocks/gallery/style-rtl.css 1.53 kB
build/block-library/blocks/gallery/style.css 1.53 kB
build/block-library/blocks/gallery/theme-rtl.css 108 B
build/block-library/blocks/gallery/theme.css 108 B
build/block-library/blocks/group/editor-rtl.css 394 B
build/block-library/blocks/group/editor.css 394 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 327 B
build/block-library/blocks/html/editor.css 329 B
build/block-library/blocks/image/editor-rtl.css 884 B
build/block-library/blocks/image/editor.css 882 B
build/block-library/blocks/image/style-rtl.css 627 B
build/block-library/blocks/image/style.css 630 B
build/block-library/blocks/image/theme-rtl.css 126 B
build/block-library/blocks/image/theme.css 126 B
build/block-library/blocks/latest-comments/style-rtl.css 284 B
build/block-library/blocks/latest-comments/style.css 284 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 463 B
build/block-library/blocks/latest-posts/style.css 462 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 705 B
build/block-library/blocks/navigation-link/editor.css 703 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 296 B
build/block-library/blocks/navigation-submenu/editor.css 295 B
build/block-library/blocks/navigation/editor-rtl.css 2.02 kB
build/block-library/blocks/navigation/editor.css 2.03 kB
build/block-library/blocks/navigation/style-rtl.css 2.17 kB
build/block-library/blocks/navigation/style.css 2.16 kB
build/block-library/blocks/navigation/view-modal.min.js 2.78 kB
build/block-library/blocks/navigation/view.min.js 443 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 363 B
build/block-library/blocks/page-list/editor.css 363 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/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 493 B
build/block-library/blocks/post-comments-form/style.css 493 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 73 B
build/block-library/blocks/post-excerpt/editor.css 73 B
build/block-library/blocks/post-excerpt/style-rtl.css 69 B
build/block-library/blocks/post-excerpt/style.css 69 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 315 B
build/block-library/blocks/post-featured-image/style.css 315 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 282 B
build/block-library/blocks/query-pagination/style.css 278 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 439 B
build/block-library/blocks/query/editor.css 439 B
build/block-library/blocks/quote/style-rtl.css 213 B
build/block-library/blocks/quote/style.css 213 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 202 B
build/block-library/blocks/rss/editor.css 204 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 464 B
build/block-library/blocks/shortcode/editor.css 464 B
build/block-library/blocks/site-logo/editor-rtl.css 490 B
build/block-library/blocks/site-logo/editor.css 490 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 322 B
build/block-library/blocks/spacer/editor.css 322 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 494 B
build/block-library/blocks/table/editor.css 494 B
build/block-library/blocks/table/style-rtl.css 611 B
build/block-library/blocks/table/style.css 609 B
build/block-library/blocks/table/theme-rtl.css 190 B
build/block-library/blocks/table/theme.css 190 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 235 B
build/block-library/blocks/template-part/editor.css 235 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 87 B
build/block-library/blocks/verse/style.css 87 B
build/block-library/blocks/video/editor-rtl.css 691 B
build/block-library/blocks/video/editor.css 694 B
build/block-library/blocks/video/style-rtl.css 174 B
build/block-library/blocks/video/style.css 174 B
build/block-library/blocks/video/theme-rtl.css 126 B
build/block-library/blocks/video/theme.css 126 B
build/block-library/classic-rtl.css 162 B
build/block-library/classic.css 162 B
build/block-library/common-rtl.css 1.02 kB
build/block-library/common.css 1.02 kB
build/block-library/editor-elements-rtl.css 75 B
build/block-library/editor-elements.css 75 B
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/reset-rtl.css 478 B
build/block-library/reset.css 478 B
build/block-library/style-rtl.css 12.3 kB
build/block-library/style.css 12.3 kB
build/block-library/theme-rtl.css 719 B
build/block-library/theme.css 722 B
build/block-serialization-default-parser/index.min.js 1.12 kB
build/block-serialization-spec-parser/index.min.js 2.83 kB
build/components/style-rtl.css 11.3 kB
build/components/style.css 11.3 kB
build/compose/index.min.js 12.2 kB
build/core-data/index.min.js 15.5 kB
build/customize-widgets/index.min.js 11.3 kB
build/customize-widgets/style-rtl.css 1.38 kB
build/customize-widgets/style.css 1.38 kB
build/data-controls/index.min.js 653 B
build/data/index.min.js 8.08 kB
build/date/index.min.js 32.1 kB
build/deprecated/index.min.js 507 B
build/dom-ready/index.min.js 324 B
build/dom/index.min.js 4.7 kB
build/edit-navigation/style-rtl.css 3.99 kB
build/edit-navigation/style.css 4 kB
build/edit-post/classic-rtl.css 546 B
build/edit-post/classic.css 547 B
build/edit-post/index.min.js 31.8 kB
build/edit-post/style-rtl.css 7.13 kB
build/edit-post/style.css 7.13 kB
build/edit-site/index.min.js 57.8 kB
build/edit-site/style-rtl.css 8.36 kB
build/edit-site/style.css 8.35 kB
build/edit-widgets/index.min.js 16.7 kB
build/edit-widgets/style-rtl.css 4.34 kB
build/edit-widgets/style.css 4.34 kB
build/editor/index.min.js 41.6 kB
build/editor/style-rtl.css 3.62 kB
build/editor/style.css 3.61 kB
build/element/index.min.js 4.68 kB
build/escape-html/index.min.js 537 B
build/experiments/index.min.js 868 B
build/format-library/index.min.js 6.95 kB
build/format-library/style-rtl.css 571 B
build/format-library/style.css 571 B
build/hooks/index.min.js 1.64 kB
build/html-entities/index.min.js 448 B
build/i18n/index.min.js 3.77 kB
build/is-shallow-equal/index.min.js 527 B
build/keyboard-shortcuts/index.min.js 1.78 kB
build/keycodes/index.min.js 1.83 kB
build/list-reusable-blocks/index.min.js 2.13 kB
build/list-reusable-blocks/style-rtl.css 835 B
build/list-reusable-blocks/style.css 835 B
build/media-utils/index.min.js 2.93 kB
build/notices/index.min.js 963 B
build/nux/index.min.js 2.06 kB
build/nux/style-rtl.css 732 B
build/nux/style.css 728 B
build/plugins/index.min.js 1.94 kB
build/preferences-persistence/index.min.js 2.22 kB
build/preferences/index.min.js 1.33 kB
build/primitives/index.min.js 933 B
build/priority-queue/index.min.js 1.58 kB
build/react-i18n/index.min.js 696 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.74 kB
build/reusable-blocks/index.min.js 2.21 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 10.6 kB
build/server-side-render/index.min.js 1.77 kB
build/shortcode/index.min.js 1.53 kB
build/style-engine/index.min.js 1.46 kB
build/token-list/index.min.js 644 B
build/url/index.min.js 3.61 kB
build/vendors/inert-polyfill.min.js 2.48 kB
build/vendors/react-dom.min.js 38.5 kB
build/vendors/react.min.js 4.34 kB
build/viewport/index.min.js 1.08 kB
build/warning/index.min.js 268 B
build/widgets/index.min.js 7.21 kB
build/widgets/style-rtl.css 1.18 kB
build/widgets/style.css 1.19 kB
build/wordcount/index.min.js 1.06 kB

compressed-size-action

@kevin940726 kevin940726 changed the title Refactor dropzone for unmodified default blocks with BlockPopover and InsertionPoint Refactor dropzone for unmodified default blocks with useBlockDropZone and InsertionPoint Oct 4, 2022
@kevin940726 kevin940726 self-assigned this Oct 4, 2022
@@ -174,12 +237,10 @@ export default function useBlockDropZone( {
onDragLeave() {
throttled.cancel();
hideInsertionPoint();
setTargetBlockIndex( null );
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'm actually not sure why we needed to set it to null here as it'll get updated on drag over anyway?

This is making the hook returned by useOnBlockDrop receive the wrong index sometimes.

Copy link
Member Author

Choose a reason for hiding this comment

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

Note that there is some flickering in Safari when dragging in between two blocks:

Kapture.2022-10-04.at.12.34.54.mp4

It's because Safari will always return null for event.relatedTarget in the dragleave events. I think there are ways to fix it but probably deserves another PR.

packages/block-library/CHANGELOG.md Show resolved Hide resolved
Copy link
Contributor

@talldan talldan left a comment

Choose a reason for hiding this comment

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

Looks good so far, seems like a good evolution of the feature 👍

packages/block-editor/src/store/actions.js Show resolved Hide resolved
exit: { opacity: 0, scaleY: 0.9 },
};

function BlockPopoverDropZone( {
Copy link
Contributor

Choose a reason for hiding this comment

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

It might be interesting to see whether this component can be used to solve #44064.

I'd imagine it could cover the rootClientId block when a block list is empty.

(Should be a separate PR though)

const { showInsertionPoint, hideInsertionPoint } =
useDispatch( blockEditorStore );

const onBlockDrop = useOnBlockDrop( targetRootClientId, targetBlockIndex );
const onBlockDrop = useOnBlockDrop( targetRootClientId, dropTarget.index, {
operation: dropTarget.operation,
Copy link
Contributor

Choose a reason for hiding this comment

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

Not necessarily something to do, but thinking aloud - I guess the other option (instead of using an index for the drop target), is to use a clientId and then operation is could be 'insert-before', 'insert-after', 'insert-within' or 'replace'. I always found it hard to make a call on this as there were limited use cases at the time.

index was always weird because it was really the index of the gap between a block rather than the block index itself.

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 had this idea too and I totally agree with you. That would probably be worth a bigger refactor of useOnBlockDrop though.

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 backwards compatibility will be difficult 🤔

@kevin940726 kevin940726 force-pushed the add/block-popover-drop-zone branch from 20e380e to cce8d8f Compare October 5, 2022 16:02
@kevin940726 kevin940726 marked this pull request as ready for review October 5, 2022 17:07
@kevin940726 kevin940726 force-pushed the add/block-popover-drop-zone branch from cce8d8f to 43b266e Compare October 6, 2022 02:21
@kevin940726
Copy link
Member Author

Pinging @ellatrix and @youknowriad in case you missed it ;)

@youknowriad
Copy link
Contributor

Screen.Recording.2022-10-06.at.8.16.23.AM.mov

I'm noticing two issues in the following recording:

  • Dragging over the paragraph blocks flickers the "replace" insertion point too much. I suspect that we're calling showInsertionPoint then hideInsertionPoint too much.
  • I expected that if I hover the area between two paragraphs, that I'd be able to insert at that position without replacing the preceding empty paragraph

@kevin940726
Copy link
Member Author

Thanks for trying it out!

Dragging over the paragraph blocks flickers the "replace" insertion point too much. I suspect that we're calling showInsertionPoint then hideInsertionPoint too much.

Are you testing it in Safari? There's a known bug in Safari that I think we should fix in a follow-up.

I expected that if I hover the area between two paragraphs, that I'd be able to insert at that position without replacing the preceding empty paragraph

That's intentional though. From the suggestion in the original PR, I think the idea is to avoid showing the in-between indicator when there's an empty paragraph block because the outcome will be the same. That's up for debate though.

However, it reminds me of the indicator while hovering in the global inserter. I think we should also change that in a follow-up PR (if that's expected). 🤔

@youknowriad
Copy link
Contributor

Are you testing it in Safari? There's a #44647 (comment) in Safari

Yes,

That's intentional though. From the #42722 (comment) in the original PR, I think the idea is to avoid showing the in-between indicator when there's an empty paragraph block because the outcome will be the same. That's up for debate though.

I guess my point is that the outcome shouldn't be the same, I should leave the empty paragraph and insert after it. At least in my testing it felt weird that the "blue area" was visible when I was clearly not on top of it. cc @mtias

@kevin940726
Copy link
Member Author

kevin940726 commented Oct 6, 2022

At least in my testing it felt weird that the "blue area" was visible when I was clearly not on top of it.

I think it makes sense if you think of the dropzone as a variant of the blue line indicator. It indicates where the item should be placed. It feels a bit weird to me if you can't drop in between empty paragraphs while you can do that for other block types. Maybe we can come up with a better design though, maybe even in a different issue?

@youknowriad
Copy link
Contributor

It feels a bit weird to me if you can't drop in between empty paragraphs while you can do that for other block types.

Yeah, that's my feeling too. Anyway, if this is how it already works in trunk, we can track it separately.

Copy link
Contributor

@talldan talldan left a comment

Choose a reason for hiding this comment

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

LGTM, I left a few comments, but nothing blocking.

Great work on refactoring this feature!

Comment on lines +79 to +84
if (
isUnmodifiedDefaultBlock &&
isPointContainedByRect( position, rect )
) {
distance = 0;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

There's probably a chance to break the loop early here.

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 had this plan to use binary search to find the index. Better to do them together in another PR I guess ;)

const { showInsertionPoint, hideInsertionPoint } =
useDispatch( blockEditorStore );

const onBlockDrop = useOnBlockDrop( targetRootClientId, targetBlockIndex );
const onBlockDrop = useOnBlockDrop( targetRootClientId, dropTarget.index, {
operation: dropTarget.operation,
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 backwards compatibility will be difficult 🤔

Comment on lines +215 to +217
showInsertionPoint( targetRootClientId, targetIndex, {
operation,
} );
Copy link
Contributor

Choose a reason for hiding this comment

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

This is subjective, but is operation: 'insert' | 'replace' is the right terminology for the action of showInsertionPoint?

This action displays the UI, so I wonder if the option should be something like appearance: 'inbetween' | 'overlay-block'. That might also better match the terminology in the InsertionPoint component.

useOnBlockDrop could still keep the insert/replace terms because it does seem like the right thing there.

I guess the only thing then is becomes a bit of an overhead to translate insert to inbetween and replace to overlay-block.

The other thing is that it is called 'insertion' point, which implies 'insert' already. 🤔

I am nitpicking now, so feel free to ignore 😄

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, makes sense. It's a bit unfortunate that we're probably too late to change the naming of insertion point now 😅 .

Comment on lines +197 to +200
getBoundingClientRect: () =>
ownerDocument
.getElementById( `block-${ clientId }` )
.getBoundingClientRect(),
Copy link
Contributor

Choose a reason for hiding this comment

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

That is nicer, and it also ensures the blocks don't need to be children of the current element, so should make things more stable. Good improvement 👍

@ellatrix
Copy link
Member

Please allow me to have a look at this PR today.

@ellatrix
Copy link
Member

This refactor allows us to reuse the same drop zone and their event listeners so that we don't have to bind them elsewhere.

Could you elaborate on this? Why is this needed?

const boundingBox = await this.page
.locator( selector )
.boundingBox();
dragOver: async (
Copy link
Member

Choose a reason for hiding this comment

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

Why are we using Playwright here instead of Puppeteer if in Puppeteer drag and drop works out of the box?

Copy link
Member Author

Choose a reason for hiding this comment

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

Several reasons:

  1. We're in the middle of the migration from Puppeteer to Playwright. In order to make the migration path smoother, it makes sense for me to add some missing features in e2e-test-utils-playwright. Once these utils are implemented, I believe it will be easier for contributors to pick up or add more tests.
  2. Puppeteer doesn't fully support drag-and-drop out of the box either. Specifically, if I'm not mistaken, Puppeteer also doesn't support API for dragging files (Add support to drag and drop files puppeteer/puppeteer#7330). It seems like changes need to be made in Chrome Devtools Protocol to support this. If we implement it in Puppeteer, we would still have to implement these utils anyway.

@talldan has opened an issue (microsoft/playwright#16437) in the Playwright repo already, I believe that's a good start. We can iterate and see where it goes from there ;)

@ellatrix
Copy link
Member

I like this way more than the previous implementation! 🙂

When I test dragging a block, I get the following React warning:

Screenshot 2022-10-12 at 15 02 49

@kevin940726
Copy link
Member Author

Could you elaborate on this? Why is this needed?

This is a cleaner implementation as we don't have to lock in to the Paragraph block or any other blocks. The dropzone behaves very similarly to the insertion point, I think it makes sense to combine them both and share common logic. This also allows us to avoid binding event listeners for each dropzone, this could be a performance bottleneck if we render tons of dropzones at the same time.

When I test dragging a block, I get the following React warning:

I believe this is an existing bug in the <Tooltip> component as I didn't touch those in this PR. I can still reproduce it in a commit even before #42722.

@kevin940726 kevin940726 force-pushed the add/block-popover-drop-zone branch from 43b266e to 9216c4b Compare October 13, 2022 03:28
@kevin940726 kevin940726 merged commit 96e5dc7 into trunk Oct 13, 2022
@kevin940726 kevin940726 deleted the add/block-popover-drop-zone branch October 13, 2022 12:23
@github-actions github-actions bot added this to the Gutenberg 14.4 milestone Oct 13, 2022
@youknowriad
Copy link
Contributor

Thanks for iterating on this :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Package] Block editor /packages/block-editor [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants