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

List View: Allow dragging to all levels of the block hierarchy #49742

Conversation

andrewserong
Copy link
Contributor

@andrewserong andrewserong commented Apr 12, 2023

What?

Fixes #33678

This PR seeks to add the ability to drag to all levels of the block hierarchy within the list view. This is most notable when attempting to drag beneath an expanded Group block, particularly if it is heavily nested.

Why?

It's important that folks can drag beneath a nested block. If we can allow dragging to each level of the block hierarchy, then it should allow for a more powerful drag and drop interface. Enabling this behaviour is a prerequisite for many of the current ideas for visual improvements to drag and drop — first we need to make sure it's possible to accurately determine the drop target, before we can improve how it looks.

How?

  • Calculate the desired nesting level based on the mouse cursor position, and using a hard-coded value to account for the indent for each nesting level (if anyone has a good idea about how to measure this instead, I'm happy to explore it!)
  • Construct a list of parents for the target block, based on the block data and matching based on rootClientIds
  • Update nesting logic so that it also uses a calculation based on the current nesting level to determine where the mouse cursor will be recognised as a nesting gesture
  • Factor in dragged blocks when determining the nesting level of the next block to compare
  • Determine the blockIndex for the dropped block based on either being at the very end of the parent (if the subsequent block is not at the same level) or by using the blockIndex of the next block (if the subsequent block is at the same level)
  • Add some extra tests to try to cover most of the changes with unit tests

To-do

  • Ensure the blockIndex is the correct one for where the user is dragging. That is, it should be the last index of the parent block or one less that the subsequent block if the drag position has the same level as the subsequent block.
  • Ensure dragging to the root level position still works correctly
  • If the block being dragged is the last of the parent's children, then currently it interferes with the check of the last visual child in the list view (as technically it isn't the last child).
  • Fix existing tests, add additional tests
  • Fine-tune the positioning of where each nesting level begins (currently it's hard-coded, but can we determine it based on anything within the DOM?)
  • Ensure this doesn't break if a list view is using a custom rootClientId — I haven't tested this yet, but I think this should work okay

Testing Instructions

Some heavily nested block markup
<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:paragraph -->
<p>A paragraph in a group level 1</p>
<!-- /wp:paragraph -->

<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:paragraph -->
<p>A paragraph in a group level 2</p>
<!-- /wp:paragraph -->

<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:paragraph -->
<p>A paragraph in a group level 3</p>
<!-- /wp:paragraph -->

<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:paragraph -->
<p>A paragraph in a group level 4</p>
<!-- /wp:paragraph -->

<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:paragraph -->
<p>A paragraph in a group level 5</p>
<!-- /wp:paragraph -->

<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:paragraph {"anchor":""} -->
<p>A paragraph in a group level 6</p>
<!-- /wp:paragraph -->

<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:paragraph {"anchor":""} -->
<p>A paragraph in a group level 7</p>
<!-- /wp:paragraph -->

<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:paragraph {"anchor":""} -->
<p>A paragraph in a group level 8</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div>
<!-- /wp:group -->

<!-- wp:heading -->
<h2 class="wp-block-heading">A heading</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>A paragraph</p>
<!-- /wp:paragraph -->
  1. Add a series of nested Group blocks to a post.
  2. Try dragging a block beneath the bottom nested block across all levels of the hierarchy (you need to be hovered over the bottom half of the nested block)
  3. Add additional blocks at each level of the hierarchy
  4. Attempt a lot of different kinds of dragging and see if the updated logic breaks anything

Screenshots or screencast

2023-04-28 14 38 21

@andrewserong andrewserong added [Feature] List View Menu item in the top toolbar to select blocks from a list of links. [Type] Experimental Experimental feature or API. labels Apr 12, 2023
@andrewserong andrewserong self-assigned this Apr 12, 2023
@github-actions
Copy link

github-actions bot commented Apr 12, 2023

Size Change: -242 B (0%)

Total Size: 1.37 MB

Filename Size Change
build/api-fetch/index.min.js 2.33 kB +61 B (+3%)
build/block-editor/content-rtl.css 4.17 kB -6 B (0%)
build/block-editor/content.css 4.16 kB -7 B (0%)
build/block-editor/index.min.js 201 kB +483 B (0%)
build/block-editor/style-rtl.css 15.1 kB -2 B (0%)
build/block-editor/style.css 15.1 kB -2 B (0%)
build/block-library/blocks/cover/style-rtl.css 1.61 kB +12 B (+1%)
build/block-library/blocks/cover/style.css 1.6 kB +12 B (+1%)
build/block-library/index.min.js 204 kB +17 B (0%)
build/block-library/style-rtl.css 12.8 kB +3 B (0%)
build/block-library/style.css 12.8 kB +2 B (0%)
build/commands/index.min.js 14.8 kB +23 B (0%)
build/commands/style-rtl.css 807 B +18 B (+2%)
build/commands/style.css 804 B +18 B (+2%)
build/components/index.min.js 210 kB -47 B (0%)
build/core-data/index.min.js 16.3 kB -15 B (0%)
build/edit-post/index.min.js 35.3 kB +113 B (0%)
build/edit-site/index.min.js 63.7 kB -1.23 kB (-2%)
build/edit-site/style-rtl.css 10.3 kB +38 B (0%)
build/edit-site/style.css 10.3 kB +39 B (0%)
build/editor/index.min.js 46.1 kB +237 B (+1%)
build/editor/style-rtl.css 3.48 kB -8 B (0%)
build/editor/style.css 3.47 kB -8 B (0%)
build/private-apis/index.min.js 952 B +10 B (+1%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 993 B
build/annotations/index.min.js 2.78 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/default-editor-styles-rtl.css 403 B
build/block-editor/default-editor-styles.css 403 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 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 113 B
build/block-library/blocks/categories/editor.css 112 B
build/block-library/blocks/categories/style-rtl.css 124 B
build/block-library/blocks/categories/style.css 124 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 409 B
build/block-library/blocks/columns/style.css 409 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 647 B
build/block-library/blocks/cover/editor.css 650 B
build/block-library/blocks/details-summary/editor-rtl.css 65 B
build/block-library/blocks/details-summary/editor.css 65 B
build/block-library/blocks/details-summary/style-rtl.css 61 B
build/block-library/blocks/details-summary/style.css 61 B
build/block-library/blocks/details/style-rtl.css 54 B
build/block-library/blocks/details/style.css 54 B
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 269 B
build/block-library/blocks/file/style.css 270 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 340 B
build/block-library/blocks/html/editor.css 341 B
build/block-library/blocks/image/editor-rtl.css 834 B
build/block-library/blocks/image/editor.css 833 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.21 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 141 B
build/block-library/blocks/post-excerpt/style.css 141 B
build/block-library/blocks/post-featured-image/editor-rtl.css 588 B
build/block-library/blocks/post-featured-image/editor.css 586 B
build/block-library/blocks/post-featured-image/style-rtl.css 322 B
build/block-library/blocks/post-featured-image/style.css 322 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 281 B
build/block-library/blocks/post-template/style.css 281 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-time-to-read/style-rtl.css 69 B
build/block-library/blocks/post-time-to-read/style.css 69 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 335 B
build/block-library/blocks/pullquote/style.css 335 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 450 B
build/block-library/blocks/query/editor.css 449 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 434 B
build/block-library/blocks/search/style.css 432 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 329 B
build/block-library/blocks/shortcode/editor.css 329 B
build/block-library/blocks/site-logo/editor-rtl.css 756 B
build/block-library/blocks/site-logo/editor.css 756 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 359 B
build/block-library/blocks/spacer/editor.css 359 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 403 B
build/block-library/blocks/template-part/editor.css 403 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.12 kB
build/block-library/common.css 1.12 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.8 kB
build/block-library/editor.css 11.8 kB
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/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.1 kB
build/components/style-rtl.css 11.8 kB
build/components/style.css 11.8 kB
build/compose/index.min.js 12.4 kB
build/core-commands/index.min.js 1.84 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 718 B
build/data/index.min.js 8.68 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.76 kB
build/edit-post/classic-rtl.css 571 B
build/edit-post/classic.css 571 B
build/edit-post/style-rtl.css 7.84 kB
build/edit-post/style.css 7.83 kB
build/edit-widgets/index.min.js 17.3 kB
build/edit-widgets/style-rtl.css 4.56 kB
build/edit-widgets/style.css 4.56 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.94 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/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.1 kB
build/router/index.min.js 1.77 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.55 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

@github-actions
Copy link

github-actions bot commented Apr 12, 2023

Flaky tests detected in d7cab3c.
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/4827537934
📝 Reported issues:

@andrewserong andrewserong force-pushed the update/list-view-to-allow-drag-at-all-levels-of-block-hierarchy branch from e49dac0 to 752bd70 Compare April 27, 2023 06:57
@andrewserong andrewserong changed the title List View: Allow drag to all levels of the block hierarchy List View: Allow dragging to all levels of the block hierarchy Apr 28, 2023
@andrewserong andrewserong marked this pull request as ready for review April 28, 2023 06:29
@andrewserong andrewserong requested a review from ellatrix as a code owner April 28, 2023 06:29
@andrewserong
Copy link
Contributor Author

The code's not perfect for this one (it relies on a hard-coded value for the nesting level), but I think this PR is probably at a good place for review / feedback on the approach.

The overall goal with this PR is to see if we can improve the experience for dragging through all levels of the block hierarchy. My hope is that this PR should improve things a fair bit on its own, but also unlock some of the recent discussions and ideas for how to improve drag and drop in the list view visually — the step taken in this PR is to more accurately determine which level of the block hierarchy to drag to.

Happy for any feedback or ideas! In terms of scope — this PR is just about solving dragging through the different levels of the block hierarchy. I'm hoping we can look at visual changes separately (i.e. here's an exploration into changing the drag chip: #49820).

@jasmussen
Copy link
Contributor

Nice, just from a quick smell test, this feels substantially better and less fiddly:

dragon drop

  • Separate, but nice dropzone indicator matching the in-canvas one.
  • Scrollbars working, and coming into their own.
  • Doesn't seem to suffer from that click and move ever so slightly to invoke a drag and drop, which trunk has.

Seems like a solid step forward. Nice!

@noisysocks
Copy link
Member

I couldn't get this to work at all when testing in Firefox unfortunately:

Kapture.2023-05-01.at.10.26.14.mp4

It works exactly as advertised when testing in Chrome though, so you must be running into some browser discrepancy. I didn't check Edge—probably a good idea to run this through Browserstack before merging.

Definitely less finicky than before. I like it.

More of a question for our design team and shouldn't block this PR at all but I wonder if we should display gutter lines or alternative the background colour of each leaf in the list view so that you can trace a line up with your eye to see what level you're dragging into.

Will read through the code now.

@andrewserong
Copy link
Contributor Author

I couldn't get this to work at all when testing in Firefox unfortunately:

Oh, weird! It's not working in Firefox for me, either, but it is working in Safari, Edge, and Chrome. I'll dig in. Thanks for catching that!

@@ -52,19 +58,91 @@ import { store as blockEditorStore } from '../../store';
* 'inside' refers to nesting as an inner block.
*/

export const NESTING_LEVEL_INDENTATION = 28;
Copy link
Member

@noisysocks noisysocks May 1, 2023

Choose a reason for hiding this comment

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

I suppose we could use getComputedStyle() to get the actual padding used. It might be slow though? Definitely benchmark it if you go down that route.

I don't really hate hardcoding this. To me, the level of indentation is a key part of what ListView communicates to the user and therefore is arguably "content". I don't think it would be inappropriate at all to set marign-left on the expander using an inline style, rewrite this logic using JavaScript, and then that way the same code that's used for setting the margin-left can be used here for calculating the drop destination.

Practically, all that we really care about, is preventing a future developer from updating the CSS I linked to above without also updating this constant. So at the very minimum, put a comment above the CSS that refers to this constant and vice versa.

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 idea to add comments to link these together (added in 5e9068c). I also really like the idea of switching the indentation over to JS styles so that the hard-coded indentation level is used in both places 👍

If / when this PR lands, I'm happy to dig into that as a follow-up!

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think it would be inappropriate at all to set marign-left on the expander using an inline style, rewrite this logic using JavaScript, and then that way the same code that's used for setting the margin-left can be used here for calculating the drop destination.

I wrote it in a similar way originally but using spacer divs (which would possibly have made this PR easier), it was changed here - #32063.

Another option could be injecting css vars for the level and indent, and then doing a calc to multiply them.

list-view/index.js also has BLOCK_LIST_ITEM_HEIGHT that could be improved in a similar way.

Sounds good for a follow-up.

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 ideas, I'll dig into this stuff in follow-ups. Thanks!

return point.x < blockIndentPosition;
}

function getDesiredRelativeParentLevel( point, rect, nestingLevel = 1 ) {
Copy link
Member

Choose a reason for hiding this comment

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

You have nice doc comments on all the functions except this one. Makes me feel bad for it 🥹

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was determined to make sure these were all documented, so thanks for flagging that one, it did look lonely! Updated in ca8ec6d


while ( currentBlockData ) {
candidateBlockParents.push( { ...currentBlockData } );
currentBlockData = blocksData.find(
Copy link
Member

Choose a reason for hiding this comment

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

Is it worth updating getListViewDropTarget and all its helper functions to have blocksData be a Map (keyed by clientId) instead of an array so that we don't need lookups like this find()? I'm not too familiar with this code but it looks like getCandidateBlockParents will be called when the user moves the mouse so I imagine performance could be a problem if there are ~1000s of blocks.

Only bother if it makes an actual difference 😀 (premature optimisation yada yada)

Copy link
Contributor

@talldan talldan May 1, 2023

Choose a reason for hiding this comment

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

When I originally wrote it, I'm sure blockData was supposed to only be computed once when the user starts dragging. I see it's now computed on every dragover event. 🤔

Anyway, my suggestion was going to be to store the parent client ids in blocksData ahead of time, but I think the only real optimization would come from ensuring that blocksData isn't computed so often.

Copy link
Contributor

Choose a reason for hiding this comment

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

I tried a fix for this in this PR - #50210

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks Dan! I like that direction — just left a comment on that PR about whether we then need to add data attributes to the placeholder rows that are used as part of the windowing logic. I think that should still be pretty doable, while preserving the performance improvement?

@andrewserong
Copy link
Contributor Author

Thanks again for reviewing @noisysocks — the Firefox bug took me a little longer than anticipated to debug, but I got there in the end. TIL it turns out that accessing ariaLevel on an element via the Element API isn't supported in Firefox — https://caniuse.com/mdn-api_element_arialevel! I've swapped that usage out for including a data-level attribute that gets used in a similar way to how we're passing down the expanded state, and it appears to be working well for me so far 👍

I also like the idea for the performance improvement of keying blocksData by clientId. I probably lean slightly toward looking into that as a code quality follow-up PR, but also happy to look into that now if folks think it's worth ensuring this change is performant enough.

Copy link
Member

@noisysocks noisysocks left a comment

Choose a reason for hiding this comment

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

Lovely! Nice work.

@noisysocks
Copy link
Member

I also like the idea for the performance improvement of keying blocksData by clientId. I probably lean slightly toward looking into that as a code quality follow-up PR, but also happy to look into that now if folks think it's worth ensuring this change is performant enough.

It looks like in the other thread @talldan decided that the performance impact isn't significant.

@noisysocks noisysocks added [Type] Enhancement A suggestion for improvement. and removed [Type] Experimental Experimental feature or API. labels May 1, 2023
@talldan
Copy link
Contributor

talldan commented May 1, 2023

TIL it turns out that accessing ariaLevel on an element via the Element API isn't supported in Firefox

This is so random! How about element.getAttribute( 'aria-level' )? From what I can tell that works, and it might be preferable to adding a new attribute.

@andrewserong
Copy link
Contributor Author

This is so random! How about element.getAttribute( 'aria-level' )? From what I can tell that works, and it might be preferable to adding a new attribute.

Good call — I think this is preferable to relying on extra data attributes. I've swapped out the data attribute for .getAttribute( 'aria-level' ) and re-tested in FF, Chrome, Safari, and Edge, and it's all still working correctly for me.

Were there any other changes you wanted to see made before this lands @talldan? I'm happy to dig into a few code quality improvements in follow-ups (in particular I really like Rob's idea of moving to JS for the left margins so that the logic there is consolidated).

@andrewserong andrewserong added the [Feature] Drag and Drop Drag and drop functionality when working with blocks label May 2, 2023
@talldan
Copy link
Contributor

talldan commented May 2, 2023

@andrewserong This looks good to me, thanks so much for working on this!

@andrewserong
Copy link
Contributor Author

Thanks for the reviews and feedback! Much appreciated 🙇

@andrewserong andrewserong merged commit 632d780 into trunk May 2, 2023
@andrewserong andrewserong deleted the update/list-view-to-allow-drag-at-all-levels-of-block-hierarchy branch May 2, 2023 04:25
@github-actions github-actions bot added this to the Gutenberg 15.8 milestone May 2, 2023
@scruffian
Copy link
Contributor

I wonder if this would help at all with #46994

@andrewserong
Copy link
Contributor Author

I wonder if this would help at all with #46994

I don't think so, this PR is really just looking at how we determine the correct block drop target from within the list view based on the mouse cursor position relative to the list view items. I think #46994 would likely need to be solved for from the editor canvas drop zone side of things. Dave had a good idea over in #46994 (comment) to potential add context / metadata to the drag operation, and check this from within the editor canvas, which could be a good way to go about it. I've added a comment on that issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Drag and Drop Drag and drop functionality when working with blocks [Feature] List View Menu item in the top toolbar to select blocks from a list of links. Needs User Documentation Needs new user documentation [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

List view drag and drop - make it possible to drop at all levels of the hierarchy
6 participants