Skip to content

DataViews: Add data picker component #70971

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

Open
wants to merge 32 commits into
base: trunk
Choose a base branch
from
Open

Conversation

talldan
Copy link
Contributor

@talldan talldan commented Jul 30, 2025

What?

Related - #70722

Adds a DataPicker component to the DataViews package that can be used for picker/selection flows.

Not finalized, but I'm looking for feedback before consolidating further on the approach.

On the surface this looks like the 'grid' layout for DataViews with a few differences:

  • It's optimized for selection, implemented as a listbox, the list only has one tab stop with left/right arrow keys used for navigation, and space/enter used for selection.
  • It can be configured for single or multiple item selection.
  • Additional actions can't be registered, I've tried to keep the purpose purely for selection to avoid accessibility issues (additional tab stops).

How?

  • Exports a DataPicker component that internally shares some details of DataViews (views, context, search, pagination), but has fewer props and a more specific purpose. It has a similar set of props to DataViews, but also supports:
    • multiple - is single or multiple selection supported
    • label - the label for the listbox (required since the list of items is focusable)
    • onFinish- a callback triggered when the user has made a selection.
  • Implements a DataPickerGrid layout/view for the DataPicker. In the future we can implement different kinds of selection/picker layouts.

Challenges

  • That it shares some parts with DataViews has benefits and challenges. I'm not sure the abstraction I've landed on for these components is completely right.
  • DataPicker views/layouts aren't compatible with DataViews views/layouts. The components enforce that, but the types might need some work to better express this.
  • Supporting selection across pagination. Individual selection does work across pages, but 'Select all' doesn't (since in the code we don't know the IDs for all of the items). Perhaps this is ok, open to feedback on whether we should try to support it.

Todo

  • Docs
  • Tests
  • Should we make it private while it's in development? Is that a practice in the dataviews package?
  • Support 'Free Composition' like DataViews?
  • Add support for showing more fields / view options.

Testing Instructions

  1. Check out this PR and run npm run storybook:dev
  2. Navigate to the DataPicker story (once the storybook has built and opens in your browser)
  3. Test the DataPicker component.

Screenshots or screencast

(when clicking finish there's an alert that shows, but it appeared outside the video crop zone 😄 )

Kapture.2025-07-30.at.15.44.34.mp4

@talldan talldan self-assigned this Jul 30, 2025
@talldan talldan requested a review from oandregal as a code owner July 30, 2025 08:00
@talldan talldan added [Type] Enhancement A suggestion for improvement. [Feature] DataViews Work surrounding upgrading and evolving views in the site editor and beyond labels Jul 30, 2025
Copy link

github-actions bot commented Jul 30, 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: talldan <[email protected]>
Co-authored-by: tellthemachines <[email protected]>
Co-authored-by: youknowriad <[email protected]>
Co-authored-by: ramonjd <[email protected]>
Co-authored-by: andrewserong <[email protected]>
Co-authored-by: oandregal <[email protected]>

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

Copy link

github-actions bot commented Jul 30, 2025

Size Change: +575 B (+0.03%)

Total Size: 1.91 MB

Filename Size Change
build/edit-site/posts-rtl.css 8.73 kB +142 B (+1.65%)
build/edit-site/posts.css 8.73 kB +141 B (+1.64%)
build/edit-site/style-rtl.css 14.8 kB +146 B (+0.99%)
build/edit-site/style.css 14.9 kB +146 B (+0.99%)
ℹ️ View Unchanged
Filename Size
build-module/a11y/index.min.js 482 B
build-module/block-library/file/view.min.js 447 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 264 kB
build/block-editor/style-rtl.css 15.9 kB
build/block-editor/style.css 15.9 kB
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.84 kB
build/block-library/blocks/gallery/style.css 1.84 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 427 B
build/block-library/blocks/more/editor.css 427 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 722 B
build/block-library/blocks/post-featured-image/editor.css 720 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 229 kB
build/block-library/reset-rtl.css 472 B
build/block-library/reset.css 472 B
build/block-library/style-rtl.css 15 kB
build/block-library/style.css 15 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 249 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.4 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.5 kB
build/edit-post/style-rtl.css 2.77 kB
build/edit-post/style.css 2.77 kB
build/edit-site/index.min.js 234 kB
build/edit-widgets/index.min.js 17.7 kB
build/edit-widgets/style-rtl.css 4.05 kB
build/edit-widgets/style.css 4.06 kB
build/editor/index.min.js 126 kB
build/editor/style-rtl.css 9.13 kB
build/editor/style.css 9.14 kB
build/element/index.min.js 4.82 kB
build/escape-html/index.min.js 537 B
build/format-library/index.min.js 8.17 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

Copy link

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

@ramonjd
Copy link
Member

ramonjd commented Jul 31, 2025

Nice work @talldan

In manual testing selection is working well, and how I'd expect it. Thanks for getting things started.

The only question that sprung to mind in relation to the abstraction — bearing in mind I'm still a Dataviews dilettante — what would be an example of its usage in conjunction with Dataviews? Would consumers pick one component or the other or would the <DataPicker /> be mounted based on an action if required? Or is the plan just to test out the API and eventually subsume DataPicker into Dataviews?

I know this was the feedback to create a new component. It just makes me wonder how it all squares with Dataviews' already built-in selection functionality and if we're building "around" an inadequacy.

Sorry if I'm way off, just typing things out 😄

Supporting selection across pagination. Individual selection does work across pages, but 'Select all' doesn't (since in the code we don't know the IDs for all of the items). Perhaps this is ok, open to feedback on whether we should try to support it.

My 2c: I think we'd need to first answer whether users expect "Select all" to work across paginations at all.

Speaking only for myself, when I see "Select all" on a page, I understand it to mean "select all items currently visible" or, "I know I'm working with what I can see".

As far as I can tell this is the standard pattern in apps like Gmail and GitHub 🤷🏻

If the Datapicker allows bulk operations on filtered subsets then that's already a powerful feature, so, unless there's a requirement with sound rationale, I personally don't believe the complexity is worth it.

@andrewserong
Copy link
Contributor

In manual testing selection is working well, and how I'd expect it. Thanks for getting things started.

+1, also looking at the PR, I do like the idea of an opinionated DataPicker component that's kind of pre-set up for the picking use case 👍. Just sharing a couple of quick thoughts that came to mind:

While testing, I felt like we also need the "cog" icon / sort by drop down that DataViews uses, too?

Another challenge with having separate views, is that I imagine if this component is used for something like a post parent picker or a modal for selecting page links, etc, that we'd also really want a Table view for browsing and selecting while viewing more of the fields. So if we have (semi) duplicate Table and Grid views, will that be a challenge for maintenance / ensuring things are always compatible?

Speaking only for myself, when I see "Select all" on a page, I understand it to mean "select all items currently visible" or, "I know I'm working with what I can see".

Yes, personally I'd expect "Select all" to only refer to the items currently in view, and not span across pagination.

@talldan
Copy link
Contributor Author

talldan commented Jul 31, 2025

Would consumers pick one component or the other or would the be mounted based on an action if required?

Rather than having the separate DataPicker component, I think it could potentially be another view of the DataViews component, but there are some parts that don't quite work:

  • DataViews has a lot of extra props that don't mean anything to DataPicker - for example isItemClickable, onClickItem, actions, renderItemLink.
  • DataViews has some opinionated pieces around how selection works. The selection array is filtered here so that it doesn't work across pagination. We'd need to find a way around that constraint.
  • The DefaultUI (particularly the footer) that DataViews comes with doesn't work for a picker, so we'd need a way to switch the footer based on the type of view.

It just makes me wonder how it all squares with Dataviews' already built-in selection functionality and if we're building "around" an inadequacy.

The way it works right now you can still reuse parts of dataviews - the search, pagination are shared, it's the view and the bulk selection parts that are different. I think this is the part where I don't feel the abstraction is quite right in the PR because of the way DataPicker is presented as a sibling of DataViews but is also inheriting parts (this is a weird analogy!).

So if we have (semi) duplicate Table and Grid views, will that be a challenge for maintenance / ensuring things are always compatible?

Yep, I think we will have duplicates, but then internally/semantically I expect they will be quite different. Also I think there's the potential for the presentation to be very different.

We can also try extracting some aspects of the implementation to be usable by both. For example the grid layout might be something we consider extracting so the grids always have the same sizing/responsiveness.

Copy link
Contributor

@tellthemachines tellthemachines 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 very conflicted about this PR 😅

I love how it simplifies keyboard interaction with the component, vs the DataViews component which is simply painful to navigate.

DataPicker is in a weird place because it's both kind of its own DataView and also kind of just a big complex DataForm. It might help to think about (maybe even try out) some different use-cases for it in order to gauge what its best shape would be. Assuming potential uses like media, posts, templates...? What is it going to help us do? Where will it be really necessary to use this component as opposed to a simple (or multi-) select?

I also wonder if its layouts couldn't be a lot more basic than the DataViews ones given the items in this component are much less interactive. Do we really need anything more than image/preview and title? We might not even need different markup for different layouts; in fact, I'm not sure a listbox should be a table at all. Maybe the only thing we need is to switch between list and grid layouts by changing the display on the parent and on the child items 😺

>
<div
className="dataviews-wrapper"
ref={ useMergeRefs( [ containerRef, resizeObserverRef ] ) }
Copy link
Contributor

Choose a reason for hiding this comment

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

I just merged #70493 which removes resizeObserverRef from this wrapper and passes it into DataViews context instead. In any case, you'll only need it here if you decide to enable the previewSizePicker in this layout.
Also, containerRef is only used in the table layout to allow horizontal scroll on long tables, so you shouldn't need it here either.

I think if the strategy is to duplicate the parts of DataViews and their layouts that the picker needs, it might be best to strip this down to just the bare essentials for now and then add more features as needed, because otherwise it will be too easy for this component to fall out of sync as DataViews changes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've rebased to bring in those changes. I might wait for more feedback before settling on an approach, but I can either strip it back or refactor the grid into something shareable across the two layouts.

@@ -0,0 +1,105 @@
.dataviews-picker-grid {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we not reuse the dataviews-view-grid class in the component and avoid adding these styles? Again, this is already out of sync with trunk due to my earlier merge 😳

If we need to add extra styles to the picker, I think it's fine to give it an extra class name for whatever styles are exclusive to it alongside dataviews-view-grid.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Possibly, though I also get told not to share classnames across components. 😄

Another option is for the Grid to be extracted into a reusable component.

Copy link
Contributor

Choose a reason for hiding this comment

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

I will never understand the need to create a whole JS component just to share CSS between components, when CSS itself has a perfectly good system for that, but I suppose that ship has sailed for this repo 😞

@andrewserong
Copy link
Contributor

andrewserong commented Jul 31, 2025

It might help to think about (maybe even try out) some different use-cases

One use case in the back of my mind is to be able to support browsing from and choosing a page parent for sites with a very large number of pages (e.g. enterprise or large knowledge bases). There's an issue in #69608 that the current approach maxes out at 100 pages, so for larger sites I could imagine the DataPicker in a modal being really handy for being able to browse, search and sort before selecting a parent (particularly since it supports pagination).

@talldan
Copy link
Contributor Author

talldan commented Jul 31, 2025

Choosing media or patterns is another use case in WordPress. We have this modal at the moment for patterns, which doesn't have any kind of searching or pagination, and there might be quite a lot of patterns, especially if we support user created patterns in this view in the future:
Screenshot 2025-07-31 at 2 34 46 pm

@talldan talldan force-pushed the add/data-picker-component branch from 792116f to b4e0504 Compare July 31, 2025 07:17
@talldan talldan force-pushed the add/data-picker-component branch from b4e0504 to 9992c14 Compare July 31, 2025 07:54
import type { View } from '../../../types';

export const DEFAULT_VIEW: View = {
type: 'picker-grid',
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this not just "grid"?

paginationInfo={ paginationInfo }
getItemId={ ( item ) => item.id.toString() }
defaultLayouts={ {} }
onFinish={ ( ids ) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

onSubmitSelection or something like that?

startPosition: number;
};

export default function DataPickerGridLayout< Item >( {
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this need to be different that "grid"? I'm trying to understand what are the main differences between the two components, what should be shared or not...?

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 markup, semantics and keyboard navigation are quite different. Also different props.

The parts that are most similar are some of the styles, like the grid columns and responsiveness.

Possibly we could try using the same view, but consider selection a different mode of the view that when active adds the different roles, keyboard nav and so on. It'd need to do quite a lot, like remove all the tabbable elements within items. 🤔

Copy link
Contributor

@youknowriad youknowriad Jul 31, 2025

Choose a reason for hiding this comment

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

Possibly we could try using the same view, but consider selection a different mode of the view that when active adds the different roles, keyboard nav and so on. It'd need to do quite a lot, like remove all the tabbable elements within items. 🤔

Yes, this is what I kind of was thinking about, maybe a "layout" can decide whether it can be used in "DataViews", "DataPicker" or both.

Now it doesn't mean that it can't be two separate components, but I feel like the entry point should at least be the same no?

Now, I do think this PR is a bit "fundamental" in the sense that introduces a new component / new behavior entirely for DataViews package. I would love as much feedback as possible as I do have uncertainties myself. cc @WordPress/gutenberg-core @mtias @aduth

Copy link
Contributor

Choose a reason for hiding this comment

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

If we were to reuse layouts, why not just use DataViews with a "picker" mode instead of creating a dedicated component? Most (maybe all?) of the custom behaviour we need to introduce here concerns the layout structure, semantics and interaction, as well as the structure and interaction of the items, which is also defined inside the layouts.

For the sake of not adding more complexity to the current view layouts, I like the idea of adding a new "picker" layout - or several, but I'm not convinced picker needs more than one layout component. Certainly its HTML shouldn't change because it needs the listbox semantics, so if we want to customise the display I think it would be better to do it purely with CSS variations.

@oandregal
Copy link
Member

oandregal commented Jul 31, 2025

Hey, I'm trying to understand what's this for and why DataViews can't be used. Would this be a good breakdown of what we need in a picker, or did I miss something?

  • hide controls: search, filters, view config
  • prominent CTA for confirming selection (bulk selection of a single item without the action menu in each item)
  • keyboard navigation: easy selection

I'd like to offer an alternative direction that leverages the existing DataViews component instead of creating a new one.

  • Hide controls
    • Search: already possible (DataViews.search set to false)
    • Filters: already possible (fields.filterBy set to false)
    • View config: not possible to hide right, but we require this in other use cases as well (I've seen a table without any header controls). Implementing this solves many use cases.
  • Prominent CTA:
    • Alternative 1: can't this live outside DataViews, like we have in the site editor?
    • Alternative 2: can we leverage the existing "Action.context" to render some actions only as the Selection CTA? There may be other alternatives as well.

Keyboard navigation: both improvements are useful to DataViews grid independently of what we do with pickers, so it'd be good to have them anyway.

  • Select item. Can we change the SPACE key in DataViews Grid layout to select the item while leaving ENTER to click on it (if the item is clickable)? Actually, this already works as expected when the item is not clickable.
  • Speed navigation via arrow-keys. Can we implement this in the DataViews Grid layout as well? Also, I think the behavior should be a grid (support for both right-left navigation and top-down via arrow keys).

Using the existing DataViews, this is where we stand visually (in red what we need to resolve):

Screenshot 2025-07-31 at 12 48 48

@youknowriad
Copy link
Contributor

@oandregal some previous discussions here #70722 (comment)

@oandregal
Copy link
Member

@youknowriad I saw that but didn't see a breakdown of the specifics. Are we settled on a separate component, or is it open to discussion? Based on the breakdown above and unless I've missed some other task, I don't think it's too hard to make DataViews work in that use case.

@youknowriad
Copy link
Contributor

I don't think we're totally settled but I'm personally almost there :P The two arguments for me are:

  • How would a "kanban" view work for selection? Not all layouts make sense for both use-cases. One is about rendering data, the other is about selecting an item (and that's it).
  • The semantics feel different. I don't want to be able to trigger random actions in a "picker".

I also know @ellatrix tried to use DataViews list view for a "picker" once (Site picker in calypso I think) and she reverted because it just didn't fit. Curious if you remember the specifics.

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 [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants