Skip to content

Conversation

@tellthemachines
Copy link
Contributor

@tellthemachines tellthemachines commented Jul 29, 2025

What?

It's likely this will be needed as DataViews is adopted in more wp-admin screens.

This PR adds an optional infiniteScrollHandler to the DataViews pagination object. If this handler exists, an infinite scroll toggle is enabled in the view config.

If both infiniteScrollHandler exists and infinite scroll is toggled on in the view config, a scroll event handler is attached to the dataviews wrapper.

The PR also updates storybook with an infinite scroll story, though it currently has a double scrollbar as I had to add a fixed height container around it to trigger the scroll event. This won't happen in regular usage, at least provided the dataviews container isn't directly inside an iframe 😅

To try this out, this PR also changes the PostList to pass an infiniteScrollHandler into DataViews, so its functionality can be tested on the Pages screen (provided there are enough pages to trigger pagination).

The PostList change doesn't need to be done in this PR, I just added it so it's easier to test.

Testing Instructions

  1. Go to site editor > Pages;
  2. You'll need to have at least 11 pages to trigger pagination (and set per page to 10)
  3. Select Grid view in the layout picker
  4. Open the Appearance dropdown and check there is an "infinite scroll" toggle (it's very basic for now, label should probably follow the styling of the other controls)
  5. Enable infinite scroll and scroll down the page to see it work.
  6. run npm run storybook:dev and check the infinite scroll story.
infinite-scrolll.mp4
scroll-story.mp4

@tellthemachines tellthemachines self-assigned this Jul 29, 2025
@github-actions
Copy link

github-actions bot commented Jul 29, 2025

Size Change: +1.23 kB (+0.06%)

Total Size: 1.92 MB

Filename Size Change
build/edit-site/index.min.js 236 kB +538 B (+0.23%)
build/edit-site/posts-rtl.css 8.85 kB +170 B (+1.96%)
build/edit-site/posts.css 8.86 kB +174 B (+2%)
build/edit-site/style-rtl.css 14.9 kB +174 B (+1.18%)
build/edit-site/style.css 14.9 kB +176 B (+1.19%)
ℹ️ View Unchanged
Filename Size
build-module/a11y/index.min.js 482 B
build-module/block-library/accordions/view.min.js 427 B
build-module/block-library/file/view.min.js 466 B
build-module/block-library/form/view.min.js 533 B
build-module/block-library/image/view.min.js 1.78 kB
build-module/block-library/navigation/view.min.js 1.19 kB
build-module/block-library/query/view.min.js 767 B
build-module/block-library/search/view.min.js 639 B
build-module/interactivity-router/full-page.min.js 565 B
build-module/interactivity-router/index.min.js 11.4 kB
build-module/interactivity/debug.min.js 17.5 kB
build-module/interactivity/index.min.js 13.9 kB
build/a11y/index.min.js 952 B
build/annotations/index.min.js 2.13 kB
build/api-fetch/index.min.js 2.4 kB
build/autop/index.min.js 2.12 kB
build/blob/index.min.js 579 B
build/block-directory/index.min.js 7.18 kB
build/block-directory/style-rtl.css 1.03 kB
build/block-directory/style.css 1.03 kB
build/block-editor/content-rtl.css 4.43 kB
build/block-editor/content.css 4.42 kB
build/block-editor/default-editor-styles-rtl.css 392 B
build/block-editor/default-editor-styles.css 392 B
build/block-editor/index.min.js 266 kB
build/block-editor/style-rtl.css 15.9 kB
build/block-editor/style.css 15.9 kB
build/block-library/blocks/accordions/style-rtl.css 591 B
build/block-library/blocks/accordions/style.css 590 B
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 61 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 149 B
build/block-library/blocks/audio/editor.css 151 B
build/block-library/blocks/audio/style-rtl.css 132 B
build/block-library/blocks/audio/style.css 132 B
build/block-library/blocks/audio/theme-rtl.css 134 B
build/block-library/blocks/audio/theme.css 134 B
build/block-library/blocks/avatar/editor-rtl.css 115 B
build/block-library/blocks/avatar/editor.css 115 B
build/block-library/blocks/avatar/style-rtl.css 104 B
build/block-library/blocks/avatar/style.css 104 B
build/block-library/blocks/button/editor-rtl.css 265 B
build/block-library/blocks/button/editor.css 265 B
build/block-library/blocks/button/style-rtl.css 554 B
build/block-library/blocks/button/style.css 554 B
build/block-library/blocks/buttons/editor-rtl.css 291 B
build/block-library/blocks/buttons/editor.css 291 B
build/block-library/blocks/buttons/style-rtl.css 349 B
build/block-library/blocks/buttons/style.css 349 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 132 B
build/block-library/blocks/categories/editor.css 131 B
build/block-library/blocks/categories/style-rtl.css 152 B
build/block-library/blocks/categories/style.css 152 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 139 B
build/block-library/blocks/code/style.css 139 B
build/block-library/blocks/code/theme-rtl.css 122 B
build/block-library/blocks/code/theme.css 122 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 420 B
build/block-library/blocks/columns/style.css 420 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 124 B
build/block-library/blocks/comment-author-avatar/editor.css 124 B
build/block-library/blocks/comment-author-name/style-rtl.css 72 B
build/block-library/blocks/comment-author-name/style.css 72 B
build/block-library/blocks/comment-content/style-rtl.css 120 B
build/block-library/blocks/comment-content/style.css 120 B
build/block-library/blocks/comment-date/style-rtl.css 65 B
build/block-library/blocks/comment-date/style.css 65 B
build/block-library/blocks/comment-edit-link/style-rtl.css 70 B
build/block-library/blocks/comment-edit-link/style.css 70 B
build/block-library/blocks/comment-reply-link/style-rtl.css 71 B
build/block-library/blocks/comment-reply-link/style.css 71 B
build/block-library/blocks/comment-template/style-rtl.css 191 B
build/block-library/blocks/comment-template/style.css 191 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 168 B
build/block-library/blocks/comments-pagination/editor.css 168 B
build/block-library/blocks/comments-pagination/style-rtl.css 201 B
build/block-library/blocks/comments-pagination/style.css 201 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 842 B
build/block-library/blocks/comments/editor.css 842 B
build/block-library/blocks/comments/style-rtl.css 637 B
build/block-library/blocks/comments/style.css 637 B
build/block-library/blocks/cover/editor-rtl.css 631 B
build/block-library/blocks/cover/editor.css 631 B
build/block-library/blocks/cover/style-rtl.css 1.7 kB
build/block-library/blocks/cover/style.css 1.69 kB
build/block-library/blocks/details/editor-rtl.css 65 B
build/block-library/blocks/details/editor.css 65 B
build/block-library/blocks/details/style-rtl.css 86 B
build/block-library/blocks/details/style.css 86 B
build/block-library/blocks/embed/editor-rtl.css 331 B
build/block-library/blocks/embed/editor.css 331 B
build/block-library/blocks/embed/style-rtl.css 419 B
build/block-library/blocks/embed/style.css 419 B
build/block-library/blocks/embed/theme-rtl.css 133 B
build/block-library/blocks/embed/theme.css 133 B
build/block-library/blocks/file/editor-rtl.css 326 B
build/block-library/blocks/file/editor.css 326 B
build/block-library/blocks/file/style-rtl.css 278 B
build/block-library/blocks/file/style.css 278 B
build/block-library/blocks/footnotes/style-rtl.css 198 B
build/block-library/blocks/footnotes/style.css 197 B
build/block-library/blocks/form-input/editor-rtl.css 229 B
build/block-library/blocks/form-input/editor.css 229 B
build/block-library/blocks/form-input/style-rtl.css 349 B
build/block-library/blocks/form-input/style.css 349 B
build/block-library/blocks/form-submission-notification/editor-rtl.css 344 B
build/block-library/blocks/form-submission-notification/editor.css 341 B
build/block-library/blocks/form-submit-button/style-rtl.css 69 B
build/block-library/blocks/form-submit-button/style.css 69 B
build/block-library/blocks/freeform/editor-rtl.css 2.59 kB
build/block-library/blocks/freeform/editor.css 2.59 kB
build/block-library/blocks/gallery/editor-rtl.css 615 B
build/block-library/blocks/gallery/editor.css 616 B
build/block-library/blocks/gallery/style-rtl.css 1.83 kB
build/block-library/blocks/gallery/style.css 1.83 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 334 B
build/block-library/blocks/group/editor.css 334 B
build/block-library/blocks/group/style-rtl.css 103 B
build/block-library/blocks/group/style.css 103 B
build/block-library/blocks/group/theme-rtl.css 79 B
build/block-library/blocks/group/theme.css 79 B
build/block-library/blocks/heading/style-rtl.css 188 B
build/block-library/blocks/heading/style.css 188 B
build/block-library/blocks/html/editor-rtl.css 353 B
build/block-library/blocks/html/editor.css 354 B
build/block-library/blocks/image/editor-rtl.css 763 B
build/block-library/blocks/image/editor.css 763 B
build/block-library/blocks/image/style-rtl.css 1.6 kB
build/block-library/blocks/image/style.css 1.59 kB
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 355 B
build/block-library/blocks/latest-comments/style.css 354 B
build/block-library/blocks/latest-posts/editor-rtl.css 139 B
build/block-library/blocks/latest-posts/editor.css 138 B
build/block-library/blocks/latest-posts/style-rtl.css 520 B
build/block-library/blocks/latest-posts/style.css 520 B
build/block-library/blocks/list/style-rtl.css 107 B
build/block-library/blocks/list/style.css 107 B
build/block-library/blocks/loginout/style-rtl.css 61 B
build/block-library/blocks/loginout/style.css 61 B
build/block-library/blocks/media-text/editor-rtl.css 321 B
build/block-library/blocks/media-text/editor.css 320 B
build/block-library/blocks/media-text/style-rtl.css 543 B
build/block-library/blocks/media-text/style.css 542 B
build/block-library/blocks/more/editor-rtl.css 393 B
build/block-library/blocks/more/editor.css 393 B
build/block-library/blocks/navigation-link/editor-rtl.css 566 B
build/block-library/blocks/navigation-link/editor.css 568 B
build/block-library/blocks/navigation-link/style-rtl.css 192 B
build/block-library/blocks/navigation-link/style.css 191 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 295 B
build/block-library/blocks/navigation-submenu/editor.css 294 B
build/block-library/blocks/navigation/editor-rtl.css 2.23 kB
build/block-library/blocks/navigation/editor.css 2.24 kB
build/block-library/blocks/navigation/style-rtl.css 2.27 kB
build/block-library/blocks/navigation/style.css 2.26 kB
build/block-library/blocks/nextpage/editor-rtl.css 392 B
build/block-library/blocks/nextpage/editor.css 392 B
build/block-library/blocks/page-list/editor-rtl.css 356 B
build/block-library/blocks/page-list/editor.css 356 B
build/block-library/blocks/page-list/style-rtl.css 192 B
build/block-library/blocks/page-list/style.css 192 B
build/block-library/blocks/paragraph/editor-rtl.css 251 B
build/block-library/blocks/paragraph/editor.css 251 B
build/block-library/blocks/paragraph/style-rtl.css 341 B
build/block-library/blocks/paragraph/style.css 340 B
build/block-library/blocks/post-author-biography/style-rtl.css 74 B
build/block-library/blocks/post-author-biography/style.css 74 B
build/block-library/blocks/post-author-name/style-rtl.css 69 B
build/block-library/blocks/post-author-name/style.css 69 B
build/block-library/blocks/post-author/style-rtl.css 188 B
build/block-library/blocks/post-author/style.css 189 B
build/block-library/blocks/post-comments-count/style-rtl.css 72 B
build/block-library/blocks/post-comments-count/style.css 72 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 527 B
build/block-library/blocks/post-comments-form/style.css 528 B
build/block-library/blocks/post-comments-link/style-rtl.css 71 B
build/block-library/blocks/post-comments-link/style.css 71 B
build/block-library/blocks/post-content/style-rtl.css 61 B
build/block-library/blocks/post-content/style.css 61 B
build/block-library/blocks/post-date/style-rtl.css 62 B
build/block-library/blocks/post-date/style.css 62 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 155 B
build/block-library/blocks/post-excerpt/style.css 155 B
build/block-library/blocks/post-featured-image/editor-rtl.css 715 B
build/block-library/blocks/post-featured-image/editor.css 712 B
build/block-library/blocks/post-featured-image/style-rtl.css 347 B
build/block-library/blocks/post-featured-image/style.css 347 B
build/block-library/blocks/post-navigation-link/style-rtl.css 215 B
build/block-library/blocks/post-navigation-link/style.css 214 B
build/block-library/blocks/post-template/style-rtl.css 414 B
build/block-library/blocks/post-template/style.css 414 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 70 B
build/block-library/blocks/post-time-to-read/style.css 70 B
build/block-library/blocks/post-title/style-rtl.css 162 B
build/block-library/blocks/post-title/style.css 162 B
build/block-library/blocks/preformatted/style-rtl.css 125 B
build/block-library/blocks/preformatted/style.css 125 B
build/block-library/blocks/pullquote/editor-rtl.css 133 B
build/block-library/blocks/pullquote/editor.css 133 B
build/block-library/blocks/pullquote/style-rtl.css 365 B
build/block-library/blocks/pullquote/style.css 365 B
build/block-library/blocks/pullquote/theme-rtl.css 176 B
build/block-library/blocks/pullquote/theme.css 176 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 121 B
build/block-library/blocks/query-pagination-numbers/editor.css 118 B
build/block-library/blocks/query-pagination/editor-rtl.css 154 B
build/block-library/blocks/query-pagination/editor.css 154 B
build/block-library/blocks/query-pagination/style-rtl.css 237 B
build/block-library/blocks/query-pagination/style.css 237 B
build/block-library/blocks/query-title/style-rtl.css 64 B
build/block-library/blocks/query-title/style.css 64 B
build/block-library/blocks/query-total/style-rtl.css 64 B
build/block-library/blocks/query-total/style.css 64 B
build/block-library/blocks/query/editor-rtl.css 404 B
build/block-library/blocks/query/editor.css 404 B
build/block-library/blocks/quote/style-rtl.css 238 B
build/block-library/blocks/quote/style.css 238 B
build/block-library/blocks/quote/theme-rtl.css 233 B
build/block-library/blocks/quote/theme.css 236 B
build/block-library/blocks/read-more/style-rtl.css 131 B
build/block-library/blocks/read-more/style.css 131 B
build/block-library/blocks/rss/editor-rtl.css 126 B
build/block-library/blocks/rss/editor.css 126 B
build/block-library/blocks/rss/style-rtl.css 284 B
build/block-library/blocks/rss/style.css 283 B
build/block-library/blocks/search/editor-rtl.css 199 B
build/block-library/blocks/search/editor.css 199 B
build/block-library/blocks/search/style-rtl.css 674 B
build/block-library/blocks/search/style.css 671 B
build/block-library/blocks/search/theme-rtl.css 113 B
build/block-library/blocks/search/theme.css 113 B
build/block-library/blocks/separator/editor-rtl.css 100 B
build/block-library/blocks/separator/editor.css 100 B
build/block-library/blocks/separator/style-rtl.css 248 B
build/block-library/blocks/separator/style.css 248 B
build/block-library/blocks/separator/theme-rtl.css 195 B
build/block-library/blocks/separator/theme.css 195 B
build/block-library/blocks/shortcode/editor-rtl.css 286 B
build/block-library/blocks/shortcode/editor.css 286 B
build/block-library/blocks/site-logo/editor-rtl.css 773 B
build/block-library/blocks/site-logo/editor.css 770 B
build/block-library/blocks/site-logo/style-rtl.css 218 B
build/block-library/blocks/site-logo/style.css 218 B
build/block-library/blocks/site-tagline/editor-rtl.css 87 B
build/block-library/blocks/site-tagline/editor.css 87 B
build/block-library/blocks/site-tagline/style-rtl.css 65 B
build/block-library/blocks/site-tagline/style.css 65 B
build/block-library/blocks/site-title/editor-rtl.css 85 B
build/block-library/blocks/site-title/editor.css 85 B
build/block-library/blocks/site-title/style-rtl.css 143 B
build/block-library/blocks/site-title/style.css 143 B
build/block-library/blocks/social-link/editor-rtl.css 314 B
build/block-library/blocks/social-link/editor.css 314 B
build/block-library/blocks/social-links/editor-rtl.css 339 B
build/block-library/blocks/social-links/editor.css 338 B
build/block-library/blocks/social-links/style-rtl.css 1.51 kB
build/block-library/blocks/social-links/style.css 1.51 kB
build/block-library/blocks/spacer/editor-rtl.css 346 B
build/block-library/blocks/spacer/editor.css 346 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-of-contents/style-rtl.css 83 B
build/block-library/blocks/table-of-contents/style.css 83 B
build/block-library/blocks/table/editor-rtl.css 394 B
build/block-library/blocks/table/editor.css 394 B
build/block-library/blocks/table/style-rtl.css 640 B
build/block-library/blocks/table/style.css 639 B
build/block-library/blocks/table/theme-rtl.css 152 B
build/block-library/blocks/table/theme.css 152 B
build/block-library/blocks/tag-cloud/editor-rtl.css 92 B
build/block-library/blocks/tag-cloud/editor.css 92 B
build/block-library/blocks/tag-cloud/style-rtl.css 248 B
build/block-library/blocks/tag-cloud/style.css 248 B
build/block-library/blocks/template-part/editor-rtl.css 368 B
build/block-library/blocks/template-part/editor.css 368 B
build/block-library/blocks/template-part/theme-rtl.css 113 B
build/block-library/blocks/template-part/theme.css 113 B
build/block-library/blocks/term-description/style-rtl.css 126 B
build/block-library/blocks/term-description/style.css 126 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 165 B
build/block-library/blocks/text-columns/style.css 165 B
build/block-library/blocks/verse/style-rtl.css 98 B
build/block-library/blocks/verse/style.css 98 B
build/block-library/blocks/video/editor-rtl.css 413 B
build/block-library/blocks/video/editor.css 414 B
build/block-library/blocks/video/style-rtl.css 202 B
build/block-library/blocks/video/style.css 202 B
build/block-library/blocks/video/theme-rtl.css 134 B
build/block-library/blocks/video/theme.css 134 B
build/block-library/classic-rtl.css 179 B
build/block-library/classic.css 179 B
build/block-library/common-rtl.css 1.08 kB
build/block-library/common.css 1.08 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.4 kB
build/block-library/editor.css 11.4 kB
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/index.min.js 232 kB
build/block-library/reset-rtl.css 472 B
build/block-library/reset.css 472 B
build/block-library/style-rtl.css 15.4 kB
build/block-library/style.css 15.4 kB
build/block-library/theme-rtl.css 715 B
build/block-library/theme.css 719 B
build/block-serialization-default-parser/index.min.js 1.12 kB
build/block-serialization-spec-parser/index.min.js 2.87 kB
build/blocks/index.min.js 52.6 kB
build/commands/index.min.js 16.2 kB
build/commands/style-rtl.css 956 B
build/commands/style.css 953 B
build/components/index.min.js 250 kB
build/components/style-rtl.css 13.6 kB
build/components/style.css 13.6 kB
build/compose/index.min.js 12.8 kB
build/core-commands/index.min.js 3.09 kB
build/core-data/index.min.js 74.9 kB
build/customize-widgets/index.min.js 11 kB
build/customize-widgets/style-rtl.css 1.43 kB
build/customize-widgets/style.css 1.43 kB
build/data-controls/index.min.js 641 B
build/data/index.min.js 8.67 kB
build/date/index.min.js 18 kB
build/deprecated/index.min.js 458 B
build/dom-ready/index.min.js 325 B
build/dom/index.min.js 4.68 kB
build/edit-post/classic-rtl.css 577 B
build/edit-post/classic.css 578 B
build/edit-post/index.min.js 13.4 kB
build/edit-post/style-rtl.css 2.69 kB
build/edit-post/style.css 2.69 kB
build/edit-widgets/index.min.js 17.8 kB
build/edit-widgets/style-rtl.css 4.05 kB
build/edit-widgets/style.css 4.06 kB
build/editor/index.min.js 127 kB
build/editor/style-rtl.css 9.2 kB
build/editor/style.css 9.21 kB
build/element/index.min.js 4.82 kB
build/escape-html/index.min.js 537 B
build/format-library/index.min.js 8.23 kB
build/format-library/style-rtl.css 472 B
build/format-library/style.css 472 B
build/hooks/index.min.js 1.65 kB
build/html-entities/index.min.js 467 B
build/i18n/index.min.js 2.23 kB
build/is-shallow-equal/index.min.js 526 B
build/keyboard-shortcuts/index.min.js 1.31 kB
build/keycodes/index.min.js 1.46 kB
build/list-reusable-blocks/index.min.js 2.13 kB
build/list-reusable-blocks/style-rtl.css 847 B
build/list-reusable-blocks/style.css 848 B
build/media-utils/index.min.js 3.69 kB
build/notices/index.min.js 946 B
build/nux/index.min.js 1.62 kB
build/nux/style-rtl.css 767 B
build/nux/style.css 763 B
build/patterns/index.min.js 7.36 kB
build/patterns/style-rtl.css 687 B
build/patterns/style.css 685 B
build/plugins/index.min.js 1.86 kB
build/preferences-persistence/index.min.js 2.06 kB
build/preferences/index.min.js 2.9 kB
build/preferences/style-rtl.css 562 B
build/preferences/style.css 562 B
build/primitives/index.min.js 829 B
build/priority-queue/index.min.js 1.54 kB
build/private-apis/index.min.js 978 B
build/react-i18n/index.min.js 630 B
build/react-refresh-entry/index.min.js 9.47 kB
build/react-refresh-runtime/index.min.js 6.76 kB
build/redux-routine/index.min.js 2.7 kB
build/reusable-blocks/index.min.js 2.53 kB
build/reusable-blocks/style-rtl.css 255 B
build/reusable-blocks/style.css 255 B
build/rich-text/index.min.js 12.2 kB
build/router/index.min.js 5.44 kB
build/server-side-render/index.min.js 1.6 kB
build/shortcode/index.min.js 1.4 kB
build/style-engine/index.min.js 2.04 kB
build/token-list/index.min.js 581 B
build/url/index.min.js 3.97 kB
build/vendors/react-dom.min.js 41.7 kB
build/vendors/react-jsx-runtime.min.js 556 B
build/vendors/react.min.js 4.02 kB
build/viewport/index.min.js 965 B
build/vips/index.min.js 36.2 kB
build/warning/index.min.js 250 B
build/widgets/index.min.js 7.16 kB
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.04 kB

compressed-size-action

@youknowriad
Copy link
Contributor

  • A few thoughts, There's a paginationInfo prop already in DataViews. I wonder if we should expand the format of that PR instead to handle this instead of a new prop.
  • Any reason to keep this for grid for now, this seems generic to me, just like the pagination component that we have.

@tellthemachines
Copy link
Contributor Author

Any reason to keep this for grid for now, this seems generic to me, just like the pagination component that we have

No particular reason apart from it being a more common UI pattern in that type of view, but given it's an opt-in it should be fine to add it for all views.

@tellthemachines
Copy link
Contributor Author

Thanks for the feedback Riad!

I've updated to add infiniteScrollHandler inside paginationInfo and allow infinite scroll on all view types. There's still a few things that need to be added before the PR is ready; I'll continue working on it in the next few days.

@talldan
Copy link
Contributor

talldan commented Jul 31, 2025

It'd be great to update the stories in the storybook so that it's testable there as well. It should hopefully be pretty easy to update the views:

Possibly we might need a bigger data set in the stories. I thnk Jupiter and Saturn have some more moons that could be added 😄

@tellthemachines tellthemachines force-pushed the try/dataviews-infinite-scroll branch from 50af36d to 6e25cd6 Compare July 31, 2025 06:15
@tellthemachines
Copy link
Contributor Author

I thnk Jupiter and Saturn have some more moons that could be added

How do I get those image URLs from live.staticflickr.com?

@talldan
Copy link
Contributor

talldan commented Aug 1, 2025

Good question. I found this gallery which is creative commons - https://www.flickr.com/photos/lightsinthedark/albums/72157694956141104/

But I'm not sure how you get the links.

edit: Actually, maybe not every image is creative commons, it seems only some, might be ok for our usage.

@tellthemachines
Copy link
Contributor Author

It'd be great to update the stories in the storybook so that it's testable there as well. It should hopefully be pretty easy to update the views:

I've added an infinite scroll story, but it's looking a bit messy because I had to wrap it in a div with a fixed height in order to trigger the event handler by forcing a scrollbar on the dataviews-wrapper (which the event listener is attached to). Otherwise the iframe just adapts to its height and it never becomes scrollable.

@tellthemachines tellthemachines force-pushed the try/dataviews-infinite-scroll branch from 490a0f6 to 9457c81 Compare August 4, 2025 03:55
isInfiniteScroll
? 'feed'
: undefined
}
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'm really not sure if the semantics here are correct: when groupByField is enabled, this means there will be multiple feed role groups on the page. Should we just disable infinite scroll when grouping by field?

Copy link
Contributor

Choose a reason for hiding this comment

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

Good question. I suppose semantically it'd be the containing VStack that would get the "feed" role if there should just be the one?

Should we just disable infinite scroll when grouping by field?

From my perspective it would make sense to start out not supporting "group by" for now, and return to adding it further down the track if it's needed? Aside from the semantics of the feed role, it does feel like the group by case is a slightly different UX from scrolling through a single list 🤔

@tellthemachines tellthemachines marked this pull request as ready for review August 5, 2025 06:37
@github-actions
Copy link

github-actions bot commented Aug 5, 2025

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: tellthemachines <isabel_brison@git.wordpress.org>
Co-authored-by: oandregal <oandregal@git.wordpress.org>
Co-authored-by: ramonjd <ramonopoly@git.wordpress.org>
Co-authored-by: talldan <talldanwp@git.wordpress.org>
Co-authored-by: andrewserong <andrewserong@git.wordpress.org>
Co-authored-by: jasmussen <joen@git.wordpress.org>
Co-authored-by: jameskoster <jameskoster@git.wordpress.org>
Co-authored-by: youknowriad <youknowriad@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@tellthemachines
Copy link
Contributor Author

I had a look at our recommendations regarding the accessibility of the infinite scroll pattern. One thing to bear in mind is that the event handler that actually implements the infinite scroll by loading in more data, etc, is created by the consumer, so there's nothing that can be done on the dataviews side to safeguard a good navigation experience or memory management.

The example implementation in edit-site post list is very simplified and doesn't deal with these matters, mostly because that view doesn't handle URL changes for pagination either, and adding proper navigation would require that. This is why I suggest we don't merge that change in this PR, and follow up with a proper implementation later if/when we want to add infinite scroll to that view.

@tellthemachines tellthemachines added [Type] Enhancement A suggestion for improvement. [Feature] DataViews Work surrounding upgrading and evolving views in the site editor and beyond labels Aug 5, 2025
value={ infiniteScrollEnabled ? 'enabled' : 'disabled' }
onChange={ ( value ) => {
const newValue = value === 'enabled';
onChangeView( {
Copy link
Member

@oandregal oandregal Aug 6, 2025

Choose a reason for hiding this comment

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

When switching it off, we also need to set the page we are in and make sure we only list the perPage number of items (not all of them)? Otherwise, it's like nothing happened:

Screen.Recording.2025-08-06.at.13.20.52.mov

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That was an issue with the storybook implementation, not the toggle control 😅
It should be fixed in 8804ac9.

Copy link
Member

@oandregal oandregal left a comment

Choose a reason for hiding this comment

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

I'm not sure if this is an artifact of the storybook, but I've noticed that the footer is not visible until you've scrolled down all the pages. This is problematic as you can't access bulk selection (in grid) and bulk actions (in all layouts).

Screen.Recording.2025-08-06.at.13.25.54.mov

fields={ fields }
onChangeView={ setView }
actions={ actions }
isLoading={ isLoadingMore }
Copy link
Member

Choose a reason for hiding this comment

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

I wanted to try the "loading" experience. Layouts need to combine it with "has data":

  • when there is no data, display a spinner instead like they do (e.g., table)
  • when there is actually data but is still loading: what do we do? display a "loading item" at the end of the list?
Screen.Recording.2025-08-06.at.13.35.36.mov

Copy link
Member

Choose a reason for hiding this comment

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

Additionally, what do we do about the existing pagination? The current state is that we display the last page that has been fetched. And interacting with it doesn't do anything. Perhaps we hide it if infinite scroll is on?

Screen.Recording.2025-08-06.at.13.37.14.mov

Copy link
Member

Choose a reason for hiding this comment

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

And interacting with it doesn't do anything. Perhaps we hide it if infinite scroll is on?

Interacting does something, but I don't think it's expected. The page jumps when you select pages after all have loaded, and the n items changes.

Kapture.2025-08-07.at.14.40.23.mp4

I wonder if infinite scroll needs some sort of custom footer, e.g., how many have been loaded and/or selected.

Otherwise it's working nicely for me.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Additionally, what do we do about the existing pagination? The current state is that we display the last page that has been fetched. And interacting with it doesn't do anything. Perhaps we hide it if infinite scroll is on?

Yeah I think we just hide the pagination bit.

how many have been loaded and/or selected

This bit is working fine so we can leave it as is for now.

when there is no data, display a spinner instead like they do (e.g., table)

When would we have no data? If the server doesn't respond, shouldn't we display an error message in that case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok I think I get it. When the data is slow to load on the page, the spinner displays. That'll happen for the initial data whether infinite scroll is enabled or not.

If we're loading additional data with infinite scroll, that's where we might display a "loading items...". I can have a play with that and test it on the Pages screen. It might need some design input though.

@oandregal
Copy link
Member

@tellthemachines direction looks good to me, thanks for working on this. I've left some comments about edge cases.

@tellthemachines tellthemachines force-pushed the try/dataviews-infinite-scroll branch from 7134ceb to 98a19ef Compare August 7, 2025 05:07
@tellthemachines
Copy link
Contributor Author

tellthemachines commented Aug 7, 2025

Thanks for the feedback, folks!

I'm not sure if this is an artifact of the storybook, but I've noticed that the footer is not visible until you've scrolled down all the pages.

Yeah it's a storybook issue 😅 it doesn't happen on the Pages screen. I'll see if it's fixable, the story should really reflect how the feature actually works.

Edit: this is now fixed, and I managed to get rid of the double scrollbar too by adding in a hacky <style> tag 🤠

@tellthemachines tellthemachines force-pushed the try/dataviews-infinite-scroll branch from a5f2cd1 to b8e41d7 Compare August 8, 2025 00:58
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.

It's testing well for me so far, other reviewers already noted the same things that I would mention.

Code is looking pretty tidy. I left a few very minor review comments.

Comment on lines 198 to 203
const isInfiniteScroll = useMemo( () => {
if ( ! infiniteScrollHandler ) {
return false;
}
return !! view.layout?.infiniteScroll;
}, [ view, infiniteScrollHandler ] );
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you could remove the useMemo here, and instead have the boolean calculated inline.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can if we assume that view.layout?.infiniteScroll will only exist if the infiniteScrollHandler also exists. Which it should! I might have been overly cautious here.

}, [ view, infiniteScrollHandler ] );

// Attach scroll event listener for infinite scroll
useEffect( () => {
Copy link
Contributor

@talldan talldan Aug 8, 2025

Choose a reason for hiding this comment

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

useRefEffect could be an option here instead of useEffect, but tbh, it's a very minor difference. Only advantage is you wouldn't need to check containerRef.current is set.

config={ {
sizes: size,
} }
posinset={ index + 1 }
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if the value should only be passed value when isInfiniteScroll is true, because when regular pagination is active it'll be providing the incorrect value (e.g. on the second page it'll start from 1 again).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm if you're planning to use posinset when infinite scroll is disabled, then yes that would make sense to do. Otherwise in this PR posinset is only rendered when infinite scroll is on.

Copy link
Contributor

Choose a reason for hiding this comment

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

Defo a nitpick. To me, invalid data is passed to GridItem, and then we're trusting that the component does the right thing with that data. It's not an issue with the current code, but code changes, and some future person might miss the subtlety.

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've found a bit of a problem with the aria attributes on the list layout: they don't play well at all with the Composite component we're using. I've removed them from list for now, though I haven't disabled infinite scroll on it.

Composit is built on ariakit and the error occurs on that side. Basically any posinset value passed to Composite.Row makes it explode 😅

Copy link
Contributor

Choose a reason for hiding this comment

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

😬 What's the error?

Might be worth checking the issues for ariakit to see if anyone has had the same - https://github.com/ariakit/ariakit/issues. I searched for posinset and saw nothing though.

Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure if you tried it, but you could try setting the prop on the <div /> that the Composite.Row renders.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ReferenceError: Cannot access 'rowId' before initialization which is coming from the ariakit component. I haven't really looked into it.

Adding it to the div works 🎉 I also had to add aria-setsize to the div otherwise it ends up attached to the button inside.

I also had to update the CSS selectors directly targeting [role="row"] to target [role="article"] too.

);
}
} }
role={ isInfiniteScroll ? 'article' : undefined }
Copy link
Contributor

Choose a reason for hiding this comment

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

Interesting. I think I'll need a different role for the data picker changes. I'm not sure whether article supports selection. Will need to figure out if infinite scroll can work for a picker or if that's an invalid combination.

I'll also need posinset so it's useful to establish it here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's good question. Aside from whether the roles will work or not, personally I think I'd prefer to infinite scroll through a large picker than to navigate pagination, but it's not a great solution for accessibility so it shouldn't be the default mode. Does it makes sense to have view config options in a picker scenario?

Copy link
Contributor

Choose a reason for hiding this comment

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

Does it makes sense to have view config options in a picker scenario?

Hard to say, possibly a smaller subset of options. But maybe it's not worth differentiating in that case and instead providing all the options.

Comment on lines +804 to 805
<InfiniteScrollToggle />
<ItemsPerPageControl />
Copy link
Contributor

@andrewserong andrewserong Aug 11, 2025

Choose a reason for hiding this comment

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

Edit: Dan raised a good point that my suggestion below should not be followed!


Just thinking out loud, but the toggle control looks quite wide in its current implementation. Would it be worth conditionally wrapping these two controls in an HStack (like the sort and direction controls) when infinite scroll is present? (I imagine we'd need to add a context.hasInfiniteScrollHandler check here if that's the case?)

Here's how it's looking now:

image

But I was wondering if it'd be a bit more efficient use of space if we did something like this:

image

Copy link
Contributor

Choose a reason for hiding this comment

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

IMO that makes Items Per Page look too confined. It can also have up to 6 items specified, so while it has 4 in that screenshot it's not a true reflection of the worst case.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, good point! Ignore me then 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm I'm thinking that looks a bit squished 😄
@jameskoster @jasmussen do you have opinions?

Copy link
Contributor

Choose a reason for hiding this comment

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

The appearance dropdown works decently as is, and yet it can benefit from a revisit given how it's organically grown. But part of that is also reflecting on: what should be here? IMO, and I feel this somewhat strongly, this dropdown should not hold a toggle for infinite scroll.

Infinite scroll has pros and cons. If implemented right, for extremely large amounts of data, such as your entire media library archive of tens of thousands, it can be an excellent way to provide you access to the entire silo of content in one view. When paired with other date-scrolling or letter-jumping tools, it can be one of the best ways to find exactly what you're looking for, in a way that maintains performance.

It's also got plenty of downsides. You can't do an in-page search for something that hasn't loaded yet, and there are some assistive tech challenges as well. I recognize those are largely mitigated by the presence of the pagination control, as well as the "Items per page" choice. In most cases, however, those controls are mutually exclusive: either you have infinite scroll, or you have n items per page.

I'm not saying infinite scroll can't be combined with an items per page choice, but it is unusual. And unlike posts per page which is commonly a per-view relevant choice, infinite scroll feels more like a set it and forget it choice; presumably you either want it everywhere, or nowhere. To frame it as an exercise, if we presumed all of WordPress used dataviews for list views, would you set infinite scroll for some, but not other screens?

For that reason, I'd put infinite scroll as a choice in a global preferences screen, and have it apply to all. Such as Settings > General.

I recognize that's non-trivial as far as progressing the dataviews component, so I could see it temporarily living in this dropdown, if we were to agree to eventually move it to a global place.

Although I feel somewhat strongly about this, it's also not a hill I'll do battle on, and if there's consensus otherwise that infinite scroll should be a per-view setting that's tied to or adjacent to posts per page, I would approach it as a toggle button not quite unlike how Figma does it for their auto-layout wrap button:

wrap

That is, keep the segmented control (or dropdown if need be) for posts per pages, and attach a toggle button to the right of it with a tooltip. This is in part to reduce the prominence of the button.

Copy link
Contributor

Choose a reason for hiding this comment

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

The two problems I have with the above is that 1) it gives huge prominence to something I'm not sure should have prominence, and secondarily that the panel as a whole is already huge:

image

The design can probably work if it moves to a Settings > General page eventually. There's space to be verbose and contextualize there.

I don't want to block this work from moving forward, but the two pieces of followups to look into are just that: moving this to a settings page at some point, and overall looking at whether we can make this list appearance control more dense/compact/glancable. Those two tasks may in fact be the same, I have this vague feeling that most of the "set and forget" settings can live elsewhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The design can probably work if it moves to a Settings > General page eventually.

One thing we need to be aware of regarding infinite scroll as a global setting is that it has to be implemented on a per-screen basis. Dataviews only provides an event listener that the screen using it can attach a handler to. Even if we add infinite scroll handlers on all the core screens using dataviews, it's up to plugin developers to do it on their screens, so the global setting may only work for a subset of admin screens. Is that acceptable?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK I've updated the PR to try out what Jay suggested above:

Screenshot 2025-08-13 at 3 16 27 pm

I've also centered the "loading more results" text:

Screenshot 2025-08-13 at 3 25 04 pm

(that text should only appear over a slow connection)

Does this look OK for now?

Copy link
Contributor

Choose a reason for hiding this comment

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

For me it’s an acceptable starting point from which to refine.

I agree the view options dialog is beginning to feel cumbersome in some circumstances, but I see that as a separate issue that we should approach systematically.

A global setting could makes sense, but ultimately this is a property of each individual dataview so the local option would likely need to remain regardless. I could see a global setting working similarly to ‘Default post category’.

Copy link
Contributor

Choose a reason for hiding this comment

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

Agree we can approach this separately and certainly systematically, and not necessarily urgently.

A global setting could makes sense, but ultimately this is a property of each individual dataview so the local option would likely need to remain regardless. I could see a global setting working similarly to ‘Default post category’.

Honestly this depends for me. In both Proton Drive, Dropbox, and Google Drive, there's not a choice to turn off or on infinite scroll, or even choose items per page. And it feels plenty, honestly. I recognize that doesn't map 1:1 with what DataViews is doing, because it's also handling column visibility properties. So I'm not suggesting we remove these. Perhaps it's just that the cog feels very prominent, and the dropdown it opens is substantial, so perhaps when we get to it changing the cog to an ellipsis or something ligther, and working on the density of the controls inside, is plenty.

isInfiniteScroll
? 'feed'
: undefined
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Good question. I suppose semantically it'd be the containing VStack that would get the "feed" role if there should just be the one?

Should we just disable infinite scroll when grouping by field?

From my perspective it would make sense to start out not supporting "group by" for now, and return to adding it further down the track if it's needed? Aside from the semantics of the feed role, it does feel like the group by case is a slightly different UX from scrolling through a single list 🤔

@tellthemachines tellthemachines force-pushed the try/dataviews-infinite-scroll branch from e14cc29 to fd42a2c Compare August 13, 2025 03:21
type: e.target.value,
...defaultLayouts[ e.target.value ],
} );
} as View );
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Weird that this error disappeared when I added infiniteScroll into layout in the several views, and reappeared when I moved it out. But I think this solution is nicer than the expect error comment.

@jasmussen
Copy link
Contributor

Can I bother you further to take a look at the screenshots in #70955 (comment) and let me know whether we're on the right track with the "loading more results..."? Can we ship that with just a few styling adjustments or should we try something different?

Never a bother.

To specifically answer the question, use a spinner instead of the text, which there's every risk you won't be able to read in time.

As far as the knobs to toggle between items per page and infinite scroll, I've registered my concerns as far as the prominence this receives. As also noted, it's not blocking, if we agree to circle back to this at a later time, for example when we'll be able to move the infinite scroll toggle to a global settings page.

@tellthemachines
Copy link
Contributor Author

@jasmussen thanks, I was able to read it in time 😄

I've now updated to use a spinner on all layout types:

Screenshot 2025-08-13 at 4 59 03 pm Screenshot 2025-08-13 at 4 59 18 pm Screenshot 2025-08-13 at 4 59 30 pm

@jasmussen
Copy link
Contributor

🚀

@tellthemachines
Copy link
Contributor Author

Ok peeps this is now ready for a final code review.

I've removed the post list handler which I'd added just for testing purposes, but you can still test it in storybook: npm run storybook:dev

It might be good to look into building a generic infinite scroll handler hook that can be used by several screens, but that can be done as a follow-up at some point.

@andrewserong
Copy link
Contributor

I haven't had a chance to give this a proper code review, but functionally this is testing great for me!

Copy link
Member

@ramonjd ramonjd left a comment

Choose a reason for hiding this comment

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

I tested in storybook (the description still says it can be tested in Pages?)

Works as described for me, and nothing stands out in the code.

If the design folks are happy with it, then LGTM too for what it's worth, and it can be iterated upon before adding it to the post list as well.

Just left a suggestion re: the boolean var name.

Good show!

/**
* Whether infinite scroll is enabled.
*/
infiniteScroll?: boolean;
Copy link
Member

Choose a reason for hiding this comment

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

Optional: infiniteScroll reads more like a noun (the feature itself) rather than a boolean state. I'm wondering if it'd aid readability to have a name that indicates a true/false condition?

Then assignments like const isInfiniteScroll = view.infiniteScroll; above would be semantically redundant.

E.g.,

infiniteScrollEnabled
hasInfiniteScroll
enableInfiniteScroll
infiniteScrollActive

Copy link
Contributor Author

Choose a reason for hiding this comment

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

infiniteScrollEnabled is probably the most accurate because that's what the setting checks for.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, good discussion. This is the tiniest of tiny nits, but I see in this PR, there's usage of infiniteScrollEnabled and isInfiniteScrollEnabled. Would it be good for consistency to double-check that we're naming them the same in each place? I have a mild preference for prefixing with is for booleans, but don't feel too strongly about it.

if ( ! totalItems || ! totalPages ) {
const isInfiniteScrollEnabled = view.infiniteScroll ?? false;

if ( ! totalItems || ! totalPages || isInfiniteScrollEnabled ) {
Copy link
Member

Choose a reason for hiding this comment

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

Idea for a follow up: what do folks think about a go to top navigation? If you've got 100s of images, it might be helpful to go back to the top. I don't know, maybe it's just me 😄

Another "me" thing is needing an idea of what "infinite" means, e.g., how many items are there.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah we could have a play with that! I'm not sure how it might work if the handler implementation doesn't just straight up load all items but instead loads next and unloads previous (which it might do for performance reasons, especially when catering to mobile devices). But def something to explore.

Copy link
Contributor

@andrewserong andrewserong left a comment

Choose a reason for hiding this comment

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

This is looking great to me, too. I really like the API of infiniteScrollEnabled in the view, and infiniteScrollHandler in the pagination info — it feels like a good starting point to me and will allow consumers a lot of flexibility to explore a variety of different implementations.

LGTM! 🚀

@tellthemachines tellthemachines merged commit ef7421d into trunk Aug 15, 2025
79 of 80 checks passed
@tellthemachines tellthemachines deleted the try/dataviews-infinite-scroll branch August 15, 2025 02:58
@tellthemachines
Copy link
Contributor Author

Thanks for the reviews everyone! 🎉

@github-actions github-actions bot added this to the Gutenberg 21.5 milestone Aug 15, 2025
@oandregal oandregal changed the title Try adding optional infinite scroll to dataviews DataViews: add support for infinite scroll in table, grid, and list layouts Sep 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Feature] DataViews Work surrounding upgrading and evolving views in the site editor and beyond Needs Design Feedback Needs general design feedback. [Type] Enhancement A suggestion for improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants