Skip to content

Conversation

@tellthemachines
Copy link
Contributor

@tellthemachines tellthemachines commented Sep 29, 2025

What?

Try using DataViewsPicker and the Modal component for an updated media modal that can be used anywhere we need to select media.

I've added an experiment flag for the feature, and a new editor.mediaUploadModal so that the current editor.mediaUpload can remain undisturbed, due to the unfortunate fact that passing a functional component to that filter causes plugin breakage (see #70648).

This now replaces all instances of the media modal. The featured image field one remains unfiltered: because it isn't part of the editor itself, but lives in wp-admin, the filter shouldn't be necessary. (the official purpose of the filter is to enable non-WP block editor instances to use their own media library implementations)

Known issues

  • The modal isn't looking great (footer isn't sticky)
  • We're only displaying images (not videos or pdfs)
  • Adding images from the modal that opens from the media tab errors because mediaType is set incorrectly

Testing Instructions

  1. Enable the quick edit experiment
  2. In the Pages section of the site editor, open the quick edit tab and select a post. Add a featured image to it.
  3. Add an Image block in the editor and click "media library". Once an image is selected also test "Replace" from the block toolbar.
  4. Add a Gallery block and use "Add" from the block toolbar to add more images (note above issue with selecting across pages)
  5. Try dragging and dropping media files into the modal.
Screenshot 2025-10-20 at 3 51 14 pm

@tellthemachines tellthemachines self-assigned this Sep 29, 2025
@tellthemachines tellthemachines added [Type] Enhancement A suggestion for improvement. [Package] Media Utils /packages/media-utils labels Sep 29, 2025
@github-actions
Copy link

github-actions bot commented Sep 29, 2025

Size Change: +72.3 kB (+3.3%)

Total Size: 2.27 MB

Filename Size Change
build/scripts/block-editor/index.min.js 296 kB +408 B (+0.14%)
build/scripts/customize-widgets/index.min.js 12.3 kB +52 B (+0.42%)
build/scripts/edit-widgets/index.min.js 20 kB +39 B (+0.2%)
build/scripts/editor/index.min.js 138 kB +346 B (+0.25%)
build/scripts/media-utils/index.min.js 64.5 kB +60.5 kB (+1529.57%) 🆘
build/styles/editor/style-rtl.css 15.4 kB +5.48 kB (+55.13%) 🆘
build/styles/editor/style.css 15.4 kB +5.48 kB (+55.14%) 🆘
ℹ️ View Unchanged
Filename Size
build/modules/a11y/index.min.js 355 B
build/modules/block-editor/utils/fit-text-frontend.min.js 550 B
build/modules/block-library/accordion/view.min.js 520 B
build/modules/block-library/file/view.min.js 346 B
build/modules/block-library/form/view.min.js 528 B
build/modules/block-library/image/view.min.js 1.64 kB
build/modules/block-library/navigation/view.min.js 1.03 kB
build/modules/block-library/query/view.min.js 518 B
build/modules/block-library/search/view.min.js 498 B
build/modules/interactivity-router/full-page.min.js 451 B
build/modules/interactivity-router/index.min.js 11.6 kB
build/modules/interactivity/index.min.js 14.9 kB
build/modules/latex-to-mathml/index.min.js 56.5 kB
build/modules/latex-to-mathml/loader.min.js 131 B
build/scripts/a11y/index.min.js 1.06 kB
build/scripts/annotations/index.min.js 2.38 kB
build/scripts/api-fetch/index.min.js 2.83 kB
build/scripts/autop/index.min.js 2.18 kB
build/scripts/blob/index.min.js 631 B
build/scripts/block-directory/index.min.js 8.04 kB
build/scripts/block-library/index.min.js 266 kB
build/scripts/block-serialization-default-parser/index.min.js 1.16 kB
build/scripts/block-serialization-spec-parser/index.min.js 3.08 kB
build/scripts/blocks/index.min.js 56.7 kB
build/scripts/commands/index.min.js 17.4 kB
build/scripts/components/index.min.js 271 kB
build/scripts/compose/index.min.js 13.8 kB
build/scripts/core-commands/index.min.js 4.1 kB
build/scripts/core-data/index.min.js 85.1 kB
build/scripts/data-controls/index.min.js 793 B
build/scripts/data/index.min.js 9.61 kB
build/scripts/date/index.min.js 23.6 kB
build/scripts/deprecated/index.min.js 755 B
build/scripts/dom-ready/index.min.js 476 B
build/scripts/dom/index.min.js 4.91 kB
build/scripts/edit-post/index.min.js 16.8 kB
build/scripts/edit-site/index.min.js 271 kB
build/scripts/element/index.min.js 5.19 kB
build/scripts/escape-html/index.min.js 586 B
build/scripts/format-library/index.min.js 10.6 kB
build/scripts/hooks/index.min.js 1.83 kB
build/scripts/html-entities/index.min.js 494 B
build/scripts/i18n/index.min.js 2.46 kB
build/scripts/is-shallow-equal/index.min.js 568 B
build/scripts/keyboard-shortcuts/index.min.js 1.57 kB
build/scripts/keycodes/index.min.js 1.53 kB
build/scripts/latex-to-mathml/index.min.js 56.7 kB
build/scripts/list-reusable-blocks/index.min.js 2.44 kB
build/scripts/notices/index.min.js 1.11 kB
build/scripts/nux/index.min.js 1.88 kB
build/scripts/patterns/index.min.js 8.62 kB
build/scripts/plugins/index.min.js 2.14 kB
build/scripts/preferences-persistence/index.min.js 2.15 kB
build/scripts/preferences/index.min.js 3.3 kB
build/scripts/primitives/index.min.js 1.01 kB
build/scripts/priority-queue/index.min.js 1.61 kB
build/scripts/private-apis/index.min.js 1.05 kB
build/scripts/react-i18n/index.min.js 832 B
build/scripts/react-refresh-entry/index.min.js 9.44 kB
build/scripts/react-refresh-runtime/index.min.js 3.59 kB
build/scripts/redux-routine/index.min.js 3.36 kB
build/scripts/reusable-blocks/index.min.js 2.92 kB
build/scripts/rich-text/index.min.js 12.9 kB
build/scripts/router/index.min.js 5.96 kB
build/scripts/server-side-render/index.min.js 1.9 kB
build/scripts/shortcode/index.min.js 1.58 kB
build/scripts/style-engine/index.min.js 2.31 kB
build/scripts/theme/index.min.js 28.4 kB
build/scripts/token-list/index.min.js 740 B
build/scripts/undo-manager/index.min.js 915 B
build/scripts/url/index.min.js 3.98 kB
build/scripts/vendors/react-dom.min.js 43 kB
build/scripts/vendors/react-jsx-runtime.min.js 691 B
build/scripts/vendors/react.min.js 4.27 kB
build/scripts/viewport/index.min.js 1.22 kB
build/scripts/warning/index.min.js 454 B
build/scripts/widgets/index.min.js 7.83 kB
build/scripts/wordcount/index.min.js 1.04 kB
build/styles/block-directory/style-rtl.css 1.05 kB
build/styles/block-directory/style.css 1.05 kB
build/styles/block-editor/content-rtl.css 4.81 kB
build/styles/block-editor/content.css 4.8 kB
build/styles/block-editor/default-editor-styles-rtl.css 224 B
build/styles/block-editor/default-editor-styles.css 224 B
build/styles/block-editor/style-rtl.css 16.2 kB
build/styles/block-editor/style.css 16.2 kB
build/styles/block-library/accordion-heading/style-rtl.css 340 B
build/styles/block-library/accordion-heading/style.css 340 B
build/styles/block-library/accordion-item/style-rtl.css 213 B
build/styles/block-library/accordion-item/style.css 213 B
build/styles/block-library/accordion-panel/style-rtl.css 99 B
build/styles/block-library/accordion-panel/style.css 99 B
build/styles/block-library/archives/editor-rtl.css 61 B
build/styles/block-library/archives/editor.css 61 B
build/styles/block-library/archives/style-rtl.css 90 B
build/styles/block-library/archives/style.css 90 B
build/styles/block-library/audio/editor-rtl.css 149 B
build/styles/block-library/audio/editor.css 151 B
build/styles/block-library/audio/style-rtl.css 132 B
build/styles/block-library/audio/style.css 132 B
build/styles/block-library/audio/theme-rtl.css 134 B
build/styles/block-library/audio/theme.css 134 B
build/styles/block-library/avatar/editor-rtl.css 115 B
build/styles/block-library/avatar/editor.css 115 B
build/styles/block-library/avatar/style-rtl.css 104 B
build/styles/block-library/avatar/style.css 104 B
build/styles/block-library/breadcrumbs/style-rtl.css 203 B
build/styles/block-library/breadcrumbs/style.css 203 B
build/styles/block-library/button/editor-rtl.css 265 B
build/styles/block-library/button/editor.css 265 B
build/styles/block-library/button/style-rtl.css 554 B
build/styles/block-library/button/style.css 554 B
build/styles/block-library/buttons/editor-rtl.css 291 B
build/styles/block-library/buttons/editor.css 291 B
build/styles/block-library/buttons/style-rtl.css 349 B
build/styles/block-library/buttons/style.css 349 B
build/styles/block-library/calendar/style-rtl.css 239 B
build/styles/block-library/calendar/style.css 239 B
build/styles/block-library/categories/editor-rtl.css 132 B
build/styles/block-library/categories/editor.css 131 B
build/styles/block-library/categories/style-rtl.css 152 B
build/styles/block-library/categories/style.css 152 B
build/styles/block-library/classic-rtl.css 179 B
build/styles/block-library/classic.css 179 B
build/styles/block-library/code/editor-rtl.css 53 B
build/styles/block-library/code/editor.css 53 B
build/styles/block-library/code/style-rtl.css 139 B
build/styles/block-library/code/style.css 139 B
build/styles/block-library/code/theme-rtl.css 122 B
build/styles/block-library/code/theme.css 122 B
build/styles/block-library/columns/editor-rtl.css 108 B
build/styles/block-library/columns/editor.css 108 B
build/styles/block-library/columns/style-rtl.css 421 B
build/styles/block-library/columns/style.css 421 B
build/styles/block-library/comment-author-avatar/editor-rtl.css 124 B
build/styles/block-library/comment-author-avatar/editor.css 124 B
build/styles/block-library/comment-author-name/style-rtl.css 72 B
build/styles/block-library/comment-author-name/style.css 72 B
build/styles/block-library/comment-content/style-rtl.css 120 B
build/styles/block-library/comment-content/style.css 120 B
build/styles/block-library/comment-date/style-rtl.css 65 B
build/styles/block-library/comment-date/style.css 65 B
build/styles/block-library/comment-edit-link/style-rtl.css 70 B
build/styles/block-library/comment-edit-link/style.css 70 B
build/styles/block-library/comment-reply-link/style-rtl.css 71 B
build/styles/block-library/comment-reply-link/style.css 71 B
build/styles/block-library/comment-template/style-rtl.css 191 B
build/styles/block-library/comment-template/style.css 191 B
build/styles/block-library/comments-pagination-numbers/editor-rtl.css 122 B
build/styles/block-library/comments-pagination-numbers/editor.css 121 B
build/styles/block-library/comments-pagination/editor-rtl.css 168 B
build/styles/block-library/comments-pagination/editor.css 168 B
build/styles/block-library/comments-pagination/style-rtl.css 201 B
build/styles/block-library/comments-pagination/style.css 201 B
build/styles/block-library/comments-title/editor-rtl.css 75 B
build/styles/block-library/comments-title/editor.css 75 B
build/styles/block-library/comments/editor-rtl.css 842 B
build/styles/block-library/comments/editor.css 842 B
build/styles/block-library/comments/style-rtl.css 637 B
build/styles/block-library/comments/style.css 637 B
build/styles/block-library/common-rtl.css 1.11 kB
build/styles/block-library/common.css 1.11 kB
build/styles/block-library/cover/editor-rtl.css 631 B
build/styles/block-library/cover/editor.css 631 B
build/styles/block-library/cover/style-rtl.css 1.7 kB
build/styles/block-library/cover/style.css 1.69 kB
build/styles/block-library/details/editor-rtl.css 65 B
build/styles/block-library/details/editor.css 65 B
build/styles/block-library/details/style-rtl.css 86 B
build/styles/block-library/details/style.css 86 B
build/styles/block-library/editor-elements-rtl.css 75 B
build/styles/block-library/editor-elements.css 75 B
build/styles/block-library/editor-rtl.css 11.6 kB
build/styles/block-library/editor.css 11.6 kB
build/styles/block-library/elements-rtl.css 54 B
build/styles/block-library/elements.css 54 B
build/styles/block-library/embed/editor-rtl.css 331 B
build/styles/block-library/embed/editor.css 331 B
build/styles/block-library/embed/style-rtl.css 419 B
build/styles/block-library/embed/style.css 419 B
build/styles/block-library/embed/theme-rtl.css 133 B
build/styles/block-library/embed/theme.css 133 B
build/styles/block-library/file/editor-rtl.css 324 B
build/styles/block-library/file/editor.css 324 B
build/styles/block-library/file/style-rtl.css 278 B
build/styles/block-library/file/style.css 278 B
build/styles/block-library/footnotes/style-rtl.css 198 B
build/styles/block-library/footnotes/style.css 197 B
build/styles/block-library/form-input/editor-rtl.css 229 B
build/styles/block-library/form-input/editor.css 229 B
build/styles/block-library/form-input/style-rtl.css 366 B
build/styles/block-library/form-input/style.css 366 B
build/styles/block-library/form-submission-notification/editor-rtl.css 344 B
build/styles/block-library/form-submission-notification/editor.css 341 B
build/styles/block-library/form-submit-button/style-rtl.css 69 B
build/styles/block-library/form-submit-button/style.css 69 B
build/styles/block-library/freeform/editor-rtl.css 2.59 kB
build/styles/block-library/freeform/editor.css 2.59 kB
build/styles/block-library/gallery/editor-rtl.css 615 B
build/styles/block-library/gallery/editor.css 616 B
build/styles/block-library/gallery/style-rtl.css 1.84 kB
build/styles/block-library/gallery/style.css 1.84 kB
build/styles/block-library/gallery/theme-rtl.css 108 B
build/styles/block-library/gallery/theme.css 108 B
build/styles/block-library/group/editor-rtl.css 335 B
build/styles/block-library/group/editor.css 335 B
build/styles/block-library/group/style-rtl.css 103 B
build/styles/block-library/group/style.css 103 B
build/styles/block-library/group/theme-rtl.css 79 B
build/styles/block-library/group/theme.css 79 B
build/styles/block-library/heading/style-rtl.css 188 B
build/styles/block-library/heading/style.css 188 B
build/styles/block-library/html/editor-rtl.css 357 B
build/styles/block-library/html/editor.css 358 B
build/styles/block-library/image/editor-rtl.css 763 B
build/styles/block-library/image/editor.css 763 B
build/styles/block-library/image/style-rtl.css 1.6 kB
build/styles/block-library/image/style.css 1.59 kB
build/styles/block-library/image/theme-rtl.css 137 B
build/styles/block-library/image/theme.css 137 B
build/styles/block-library/latest-comments/style-rtl.css 355 B
build/styles/block-library/latest-comments/style.css 354 B
build/styles/block-library/latest-posts/editor-rtl.css 139 B
build/styles/block-library/latest-posts/editor.css 138 B
build/styles/block-library/latest-posts/style-rtl.css 520 B
build/styles/block-library/latest-posts/style.css 520 B
build/styles/block-library/list/style-rtl.css 107 B
build/styles/block-library/list/style.css 107 B
build/styles/block-library/loginout/style-rtl.css 61 B
build/styles/block-library/loginout/style.css 61 B
build/styles/block-library/media-text/editor-rtl.css 321 B
build/styles/block-library/media-text/editor.css 320 B
build/styles/block-library/media-text/style-rtl.css 543 B
build/styles/block-library/media-text/style.css 542 B
build/styles/block-library/more/editor-rtl.css 393 B
build/styles/block-library/more/editor.css 393 B
build/styles/block-library/navigation-link/editor-rtl.css 626 B
build/styles/block-library/navigation-link/editor.css 628 B
build/styles/block-library/navigation-link/style-rtl.css 190 B
build/styles/block-library/navigation-link/style.css 188 B
build/styles/block-library/navigation-submenu/editor-rtl.css 295 B
build/styles/block-library/navigation-submenu/editor.css 294 B
build/styles/block-library/navigation/editor-rtl.css 2.24 kB
build/styles/block-library/navigation/editor.css 2.24 kB
build/styles/block-library/navigation/style-rtl.css 2.27 kB
build/styles/block-library/navigation/style.css 2.25 kB
build/styles/block-library/nextpage/editor-rtl.css 392 B
build/styles/block-library/nextpage/editor.css 392 B
build/styles/block-library/page-list/editor-rtl.css 356 B
build/styles/block-library/page-list/editor.css 356 B
build/styles/block-library/page-list/style-rtl.css 192 B
build/styles/block-library/page-list/style.css 192 B
build/styles/block-library/paragraph/editor-rtl.css 251 B
build/styles/block-library/paragraph/editor.css 251 B
build/styles/block-library/paragraph/style-rtl.css 341 B
build/styles/block-library/paragraph/style.css 340 B
build/styles/block-library/post-author-biography/style-rtl.css 74 B
build/styles/block-library/post-author-biography/style.css 74 B
build/styles/block-library/post-author-name/style-rtl.css 69 B
build/styles/block-library/post-author-name/style.css 69 B
build/styles/block-library/post-author/style-rtl.css 188 B
build/styles/block-library/post-author/style.css 189 B
build/styles/block-library/post-comments-count/style-rtl.css 72 B
build/styles/block-library/post-comments-count/style.css 72 B
build/styles/block-library/post-comments-form/editor-rtl.css 96 B
build/styles/block-library/post-comments-form/editor.css 96 B
build/styles/block-library/post-comments-form/style-rtl.css 525 B
build/styles/block-library/post-comments-form/style.css 525 B
build/styles/block-library/post-comments-link/style-rtl.css 71 B
build/styles/block-library/post-comments-link/style.css 71 B
build/styles/block-library/post-content/style-rtl.css 61 B
build/styles/block-library/post-content/style.css 61 B
build/styles/block-library/post-date/style-rtl.css 62 B
build/styles/block-library/post-date/style.css 62 B
build/styles/block-library/post-excerpt/editor-rtl.css 71 B
build/styles/block-library/post-excerpt/editor.css 71 B
build/styles/block-library/post-excerpt/style-rtl.css 155 B
build/styles/block-library/post-excerpt/style.css 155 B
build/styles/block-library/post-featured-image/editor-rtl.css 719 B
build/styles/block-library/post-featured-image/editor.css 717 B
build/styles/block-library/post-featured-image/style-rtl.css 347 B
build/styles/block-library/post-featured-image/style.css 347 B
build/styles/block-library/post-navigation-link/style-rtl.css 215 B
build/styles/block-library/post-navigation-link/style.css 214 B
build/styles/block-library/post-template/style-rtl.css 414 B
build/styles/block-library/post-template/style.css 414 B
build/styles/block-library/post-terms/style-rtl.css 96 B
build/styles/block-library/post-terms/style.css 96 B
build/styles/block-library/post-time-to-read/style-rtl.css 70 B
build/styles/block-library/post-time-to-read/style.css 70 B
build/styles/block-library/post-title/style-rtl.css 162 B
build/styles/block-library/post-title/style.css 162 B
build/styles/block-library/preformatted/style-rtl.css 125 B
build/styles/block-library/preformatted/style.css 125 B
build/styles/block-library/pullquote/editor-rtl.css 133 B
build/styles/block-library/pullquote/editor.css 133 B
build/styles/block-library/pullquote/style-rtl.css 365 B
build/styles/block-library/pullquote/style.css 365 B
build/styles/block-library/pullquote/theme-rtl.css 176 B
build/styles/block-library/pullquote/theme.css 176 B
build/styles/block-library/query-pagination-numbers/editor-rtl.css 121 B
build/styles/block-library/query-pagination-numbers/editor.css 118 B
build/styles/block-library/query-pagination/editor-rtl.css 154 B
build/styles/block-library/query-pagination/editor.css 154 B
build/styles/block-library/query-pagination/style-rtl.css 237 B
build/styles/block-library/query-pagination/style.css 237 B
build/styles/block-library/query-title/style-rtl.css 64 B
build/styles/block-library/query-title/style.css 64 B
build/styles/block-library/query-total/style-rtl.css 64 B
build/styles/block-library/query-total/style.css 64 B
build/styles/block-library/query/editor-rtl.css 438 B
build/styles/block-library/query/editor.css 438 B
build/styles/block-library/quote/style-rtl.css 238 B
build/styles/block-library/quote/style.css 238 B
build/styles/block-library/quote/theme-rtl.css 233 B
build/styles/block-library/quote/theme.css 236 B
build/styles/block-library/read-more/style-rtl.css 131 B
build/styles/block-library/read-more/style.css 131 B
build/styles/block-library/reset-rtl.css 472 B
build/styles/block-library/reset.css 472 B
build/styles/block-library/rss/editor-rtl.css 126 B
build/styles/block-library/rss/editor.css 126 B
build/styles/block-library/rss/style-rtl.css 284 B
build/styles/block-library/rss/style.css 283 B
build/styles/block-library/search/editor-rtl.css 199 B
build/styles/block-library/search/editor.css 199 B
build/styles/block-library/search/style-rtl.css 665 B
build/styles/block-library/search/style.css 666 B
build/styles/block-library/search/theme-rtl.css 113 B
build/styles/block-library/search/theme.css 113 B
build/styles/block-library/separator/editor-rtl.css 100 B
build/styles/block-library/separator/editor.css 100 B
build/styles/block-library/separator/style-rtl.css 248 B
build/styles/block-library/separator/style.css 248 B
build/styles/block-library/separator/theme-rtl.css 195 B
build/styles/block-library/separator/theme.css 195 B
build/styles/block-library/shortcode/editor-rtl.css 286 B
build/styles/block-library/shortcode/editor.css 286 B
build/styles/block-library/site-logo/editor-rtl.css 773 B
build/styles/block-library/site-logo/editor.css 770 B
build/styles/block-library/site-logo/style-rtl.css 218 B
build/styles/block-library/site-logo/style.css 218 B
build/styles/block-library/site-tagline/editor-rtl.css 87 B
build/styles/block-library/site-tagline/editor.css 87 B
build/styles/block-library/site-tagline/style-rtl.css 65 B
build/styles/block-library/site-tagline/style.css 65 B
build/styles/block-library/site-title/editor-rtl.css 85 B
build/styles/block-library/site-title/editor.css 85 B
build/styles/block-library/site-title/style-rtl.css 143 B
build/styles/block-library/site-title/style.css 143 B
build/styles/block-library/social-link/editor-rtl.css 314 B
build/styles/block-library/social-link/editor.css 314 B
build/styles/block-library/social-links/editor-rtl.css 339 B
build/styles/block-library/social-links/editor.css 338 B
build/styles/block-library/social-links/style-rtl.css 1.51 kB
build/styles/block-library/social-links/style.css 1.51 kB
build/styles/block-library/spacer/editor-rtl.css 346 B
build/styles/block-library/spacer/editor.css 346 B
build/styles/block-library/spacer/style-rtl.css 48 B
build/styles/block-library/spacer/style.css 48 B
build/styles/block-library/style-rtl.css 15.6 kB
build/styles/block-library/style.css 15.6 kB
build/styles/block-library/table-of-contents/style-rtl.css 83 B
build/styles/block-library/table-of-contents/style.css 83 B
build/styles/block-library/table/editor-rtl.css 394 B
build/styles/block-library/table/editor.css 394 B
build/styles/block-library/table/style-rtl.css 641 B
build/styles/block-library/table/style.css 640 B
build/styles/block-library/table/theme-rtl.css 152 B
build/styles/block-library/table/theme.css 152 B
build/styles/block-library/tag-cloud/editor-rtl.css 92 B
build/styles/block-library/tag-cloud/editor.css 92 B
build/styles/block-library/tag-cloud/style-rtl.css 248 B
build/styles/block-library/tag-cloud/style.css 248 B
build/styles/block-library/template-part/editor-rtl.css 368 B
build/styles/block-library/template-part/editor.css 368 B
build/styles/block-library/template-part/theme-rtl.css 113 B
build/styles/block-library/template-part/theme.css 113 B
build/styles/block-library/term-count/style-rtl.css 63 B
build/styles/block-library/term-count/style.css 63 B
build/styles/block-library/term-description/style-rtl.css 126 B
build/styles/block-library/term-description/style.css 126 B
build/styles/block-library/term-name/style-rtl.css 62 B
build/styles/block-library/term-name/style.css 62 B
build/styles/block-library/term-template/editor-rtl.css 225 B
build/styles/block-library/term-template/editor.css 225 B
build/styles/block-library/term-template/style-rtl.css 114 B
build/styles/block-library/term-template/style.css 114 B
build/styles/block-library/text-columns/editor-rtl.css 95 B
build/styles/block-library/text-columns/editor.css 95 B
build/styles/block-library/text-columns/style-rtl.css 165 B
build/styles/block-library/text-columns/style.css 165 B
build/styles/block-library/theme-rtl.css 715 B
build/styles/block-library/theme.css 719 B
build/styles/block-library/verse/style-rtl.css 98 B
build/styles/block-library/verse/style.css 98 B
build/styles/block-library/video/editor-rtl.css 415 B
build/styles/block-library/video/editor.css 416 B
build/styles/block-library/video/style-rtl.css 202 B
build/styles/block-library/video/style.css 202 B
build/styles/block-library/video/theme-rtl.css 134 B
build/styles/block-library/video/theme.css 134 B
build/styles/commands/style-rtl.css 999 B
build/styles/commands/style.css 1 kB
build/styles/components/style-rtl.css 14 kB
build/styles/components/style.css 14 kB
build/styles/customize-widgets/style-rtl.css 1.44 kB
build/styles/customize-widgets/style.css 1.44 kB
build/styles/edit-post/classic-rtl.css 426 B
build/styles/edit-post/classic.css 427 B
build/styles/edit-post/style-rtl.css 3.33 kB
build/styles/edit-post/style.css 3.33 kB
build/styles/edit-site/posts-rtl.css 9.95 kB
build/styles/edit-site/posts.css 9.95 kB
build/styles/edit-site/style-rtl.css 15.9 kB
build/styles/edit-site/style.css 15.9 kB
build/styles/edit-widgets/style-rtl.css 4.59 kB
build/styles/edit-widgets/style.css 4.59 kB
build/styles/format-library/style-rtl.css 308 B
build/styles/format-library/style.css 308 B
build/styles/list-reusable-blocks/style-rtl.css 1.02 kB
build/styles/list-reusable-blocks/style.css 1.02 kB
build/styles/nux/style-rtl.css 622 B
build/styles/nux/style.css 618 B
build/styles/patterns/style-rtl.css 703 B
build/styles/patterns/style.css 703 B
build/styles/preferences/style-rtl.css 415 B
build/styles/preferences/style.css 415 B
build/styles/reusable-blocks/style-rtl.css 275 B
build/styles/reusable-blocks/style.css 275 B
build/styles/theme/style.css 52 B
build/styles/widgets/style-rtl.css 1.17 kB
build/styles/widgets/style.css 1.18 kB

compressed-size-action

import { useSelect } from '@wordpress/data';
import { useCallback, useRef } from '@wordpress/element';
import { useCallback, useRef, useState } from '@wordpress/element';
// @ts-ignore
Copy link
Member

Choose a reason for hiding this comment

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

Should this be /* tslint:disable-next-line */? Sorry, that's all I've got tonight 😄

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.

Nice start, great to see progress on new media library work!

image

A couple of questions / thoughts:

  • The featured image field is a natural one to try this out with while it's a proof of concept. At least in theory, it should be possible for consumers to replace the media library by using a filter rather than us needing to change the field directly.

I.e. in the editor package the existing modal is hooked up via:

addFilter(
	'editor.MediaUpload',
	'core/editor/components/media-upload',
	() => MediaUpload
);

If we either update the modal to use a similar interface to MediaUpload (or add a wrapper that conforms to that interface) then this new modal could be used for the block editor and the featured image field without needing to change the field itself. It'd then be possible to toggle the new media library via an experiment as there'd be a single filter to switch on or off. Could something like that work?


Another idea for testing out the modal if you wanted to work on this iteratively before it's integrated to anything could be to add a Storybook entry where we can try it out separately. I recently tried this for the fields package over in #71864 and it seemed to work well for fields so far.


Undocumented declaration.

### MediaUploadModal
Copy link
Contributor

Choose a reason for hiding this comment

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

While this is still experimental, should we export this as a private component (i.e. behind lock/unlock) rather than a public API? That way we can continue altering the params, etc, in subsequent PRs without having to worry about plugins possibly starting to use it.

@tellthemachines
Copy link
Contributor Author

At least in theory, it should be possible for consumers to replace the media library by using a filter rather than us needing to change the field directly.

The filter works on the MediaUpload component exported by the block editor, whereas FeaturedImageEdit is using the media-utils component directly. I'm not sure why this is the case; there's no mention of it in the PR that added the field.

@andrewserong
Copy link
Contributor

andrewserong commented Sep 30, 2025

The filter works on the MediaUpload component exported by the block editor, whereas FeaturedImageEdit is using the media-utils component directly. I'm not sure why this is the case; there's no mention of it in the #64496.

Ah, good catch! That field should most likely be using the filtered one from the block editor, otherwise plugins using custom media libraries likely wouldn't be able to filter it.

@talldan
Copy link
Contributor

talldan commented Sep 30, 2025

If we either update the modal to use a similar interface to MediaUpload (or add a wrapper that conforms to that interface) then this new modal could be used for the block editor and the featured image field without needing to change the field itself. It'd then be possible to toggle the new media library via an experiment as there'd be a single filter to switch on or off. Could something like that work?

If you look at how AMP is modifying the media modal via that filter, I don't think back compat is going to be possible:
https://github.com/ampproject/amp-wp/blob/7b4ed4c001cdc0fbf9adb518fb0b8e1ddebf4d5a/assets/src/block-editor/components/with-media-library-notice.js

Last time I tried changing the component passed to the filter it broke a lot of plugins (#70648). In the long-term, a deprecation of that filter might be the best option. I don't think any updated version of the media modal should be beholden to the filter, and it'll take a while to figure out the right way to provide extensibility for anything new.

Separately I thought I'd mention that FeaturedImageEdit also has a lot of issues, like the tabIndex="-1" that means it can't be focused, and the onKeyDown that unexpectedly opens the modal when any key is pressed (I've been intending to ticket these this week).

@andrewserong
Copy link
Contributor

Last time I tried changing the component passed to the filter it broke a lot of plugins (#70648). In the long-term, a deprecation of that filter might be the best option. I don't think any updated version of the media modal should be beholden to the filter, and it'll take a while to figure out the right way to provide extensibility for anything new.

Oh great point, I'd forgotten about that. So what do you reckon in the shorter-term, would it be a matter of instances that want to use it simply importing the component directly as in this PR? Or could we add a Gutenberg experiment and conditionally export the "new" media library from within the block-editor package where withFilters is currently called 🤔

@tellthemachines
Copy link
Contributor Author

In the long-term, a deprecation of that filter might be the best option. I don't think any updated version of the media modal should be beholden to the filter, and it'll take a while to figure out the right way to provide extensibility for anything new.

How can we best deprecate the filter while ensuring that the editor gets the new modal by default? The only thing that occurs to me is using a wrapper component that checks for the existence of the render prop and uses the old behaviour if it exists, and otherwise renders the new modal (assuming the new modal doesn't need a render prop if we're not trying to be backwards compatible with the old modal). Plus a deprecation notice in the console or something.

In other news, the modal's looking a bit more presentable now, but for some reason the dataviews footer refuses to be sticky:
Screenshot 2025-09-30 at 4 53 16 pm

Not sure what's going on there.

@talldan
Copy link
Contributor

talldan commented Sep 30, 2025

How can we best deprecate the filter

I was thinking that we stop using it entirely (no calls to applyFilters / withFilters for 'editor.MediaUpload'), and then also log a deprecation message if someone tries calling addFilter for 'editor.MediaUpload'.

while ensuring that the editor gets the new modal by default?

Replace the MediaUpload component in the block editor package. If it's part of an experiment then it's a matter of switching out what gets rendered when the experiment is active.

I think this happens some time before the deprecation, the deprecation only happens when stabilizing the updated modal.

If we also want to continue using filters for extensibility, then a new filter is implemented using a different name.

@tellthemachines
Copy link
Contributor Author

I was thinking that we stop using it entirely (no calls to applyFilters / withFilters for 'editor.MediaUpload')

Isn't this going to break things for people? It's not really a deprecation if we don't provide advance notice , just a breaking change 😅 (I wouldn't consider having the new modal behind an experiment flag to be advance notice, because experiments in Gutenberg have very low visibility)

Not saying we shouldn't do it, but maybe we can support the filter for a little while to give folks the chance to move off it (and while we work out extensibility for the new modal). Unless the filter is currently broken already?

@talldan
Copy link
Contributor

talldan commented Oct 1, 2025

Not saying we shouldn't do it, but maybe we can support the filter for a little while to give folks the chance to move off it (and while we work out extensibility for the new modal). Unless the filter is currently broken already?

Some way to allow users to continue using the old modal for a while is probably worth considering, almost like the way there are plugins for classic editor/widgets (though not saying this should be a plugin). Other than that, I'm not sure what other options there are. It's disruptive, but I don't think there's any other way to handle these types of changes.

@tellthemachines
Copy link
Contributor Author

I'm not as concerned about users of the modal because it's mostly a UI redesign: the functionality remains the same. But for anyone who depends on the filter to add some custom workflow, removing the filter will break that. So I was thinking of some way to detect whether the filter is being used or not.

@talldan
Copy link
Contributor

talldan commented Oct 2, 2025

I'm not as concerned about users of the modal because it's mostly a UI redesign: the functionality remains the same. But for anyone who depends on the filter to add some custom workflow, removing the filter will break that. So I was thinking of some way to detect whether the filter is being used or not.

We're talking about keeping it as an experiment first I think, so there's time to decide these things. For me, users using the modal are the people who will have their workflows broken, so it's the same thing.

Detecting active filters could work, but we don't know what the filters do. It may still be that the new modal works better for a user, but some plugin is adding a filter and because of that the user has no option to switch.

@ramonjd
Copy link
Member

ramonjd commented Oct 15, 2025

It lives! Working pretty well.

Pretty minor, but I noticed that the titles overflow doesn't behave coz the titles are flex and, apparently, flex don't do text-overflow: ellipsis;

Screenshot 2025-10-15 at 2 37 58 pm

Tried to fix it here:

privateApis as blockEditorPrivateApis,
// @ts-ignore
privateApis as blockEditorPrivateApis,
} from '@wordpress/block-editor';
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This line was erroring and preventing my commit, not sure why 🤷

Copy link
Contributor Author

Choose a reason for hiding this comment

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

same thing happening here

Copy link
Contributor

Choose a reason for hiding this comment

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

I saw there's an issue here tracking the problem now - #72560.

@tellthemachines
Copy link
Contributor Author

I've updated the PR to add an experiment flag, and replace the block editor MediaUpload component with this one when the experiment is enabled, which allows us to test it better.

This has surfaced a bug with the Dropdown/Modal nesting. When clicking outside the dataviews filters in the modal, the whole thing closes:

modal_closing.mp4

I traced it back to the Dropdown component closing due to an onBlur event targeting the Menu component (which dataviews filters use). I'm not sure why that happens, but it can be fixed by ensuring that Dropdown only listens to its own events. It's a small fix so I'll put up a separate PR for it.

@github-actions
Copy link

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 <[email protected]>
Co-authored-by: ramonjd <[email protected]>
Co-authored-by: andrewserong <[email protected]>
Co-authored-by: talldan <[email protected]>

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

}

// Use onUpload if provided, otherwise fall back to uploadMedia
const handleUpload = onUpload || uploadMedia;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a workaround for featured image, because mediaUpload isn't available in the block editor settings when that component loads. It's not really working properly though, because uploadMedia uses apiFetch directly instead of receiveEntityRecords so the modal items don't refresh 😞

The mediaUpload component the other instances are using lives in the editor package. I'm not sure if it would be worth moving/duplicating or something like that.

@tellthemachines
Copy link
Contributor Author

For reviewers: check the list of "known issues" in the description if you come across any breakage, I'm updating it as I go 😅

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.

This is working well. I think it's good enough to ship for the experiment, with any issues fixable in other PRs. Most of the code comments I left are very minor and I think things will change as the code is iterated on anyway.

There are a few places I noticed the media modal doesn't work:

  • Document Sidebar > Set Feature Image - still shows the old modal
  • Inserter > 'Media' tab > Open Media Library - opens the new modal, but trying to insert something results in a missing 'core/attachment' block being inserted, probably something related to the records being slightly the wrong format.
  • There was another place (I think it was a block) that allows opening the media modal in the sidebar, but I've forgotten where now (sorry!)

* @param {Function} root0.render Render prop function that receives { open } object.
* @return {JSX.Element} The component.
*/
function ConditionalMediaUpload( { render, ...props } ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor: I know it's a temporary component for the experiment, but maybe it's worth only having one of these components in the block editor package that's imported where needed within the package.

I was wondering if the logic could be in the existing MediaUpload, though I guess that means anyone importing the component gets new modal. Maybe there are also other concerns with that.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, I was just going to comment with a similar idea. Could we put ConditionalMediaUpload in components/media-upload-modal to remove a little duplication? Not a huge issue, just a nit 😄

*
* @return {Component} The component to be rendered.
*/
const MediaUploadModal = () => null;
Copy link
Contributor

Choose a reason for hiding this comment

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

Very minor as well, but I wonder if it could be called something like DataViewsMediaModal to distinguish it a bit more from the other component.

privateApis as blockEditorPrivateApis,
// @ts-ignore
privateApis as blockEditorPrivateApis,
} from '@wordpress/block-editor';
Copy link
Contributor

Choose a reason for hiding this comment

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

I saw there's an issue here tracking the problem now - #72560.

// Transform the records to the expected format
const mediaItems = useMemo( () => {
return ( mediaRecords || [] ).map( ( item: any ) =>
transformAttachment( item )
Copy link
Contributor

Choose a reason for hiding this comment

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

So at the moment the media items passed into DataViewsPicker are being transformed? I'm not sure about this choice, I think DataViewsPicker should work with something closer to REST API / core data style records. That way it's more likely to be compatible with fields and other shared DataViews functionality. Maybe I'm not understanding the permutations though.

transformAttachment could still be used for the selected items passed to the callback to make sure it's compatible with the expected results of the old media modal.

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're retrieving the attachment post type which doesn't have a url property, which all the places that use it seem to expect.

I guess we could try only transforming it on selection.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated.

() => [
{
id: 'select',
label: multiple ? __( 'Select' ) : __( 'Select' ),
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: It's the same string 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

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

🤦

id: 'url',
type: 'media' as const,
label: __( 'Media' ),
render: ( { item }: { item: Attachment } ) => (
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 the poster isn't working for audio tracks and videos:
Image

Here's the old media library:
Image

Are there media fields that we can use (from the fields package?) or is this something we'll need to start implementing in a follow-up?


const defaultLayouts = useMemo(
() => ( {
[ LAYOUT_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.

As this never changes, it could be defined in a const outside of the component instead of in a useMemo

@andrewserong
Copy link
Contributor

andrewserong commented Oct 23, 2025

Not a blocker as this is being proposed behind an experiment, but something I'm wondering about is how this modal might work if/when we have media-specific fields for it to use that might exist in the fields package (i.e. a circular dependency issue because the featured image field needs to use the modal, too). Just one idea, but would it be worth it (or feasible) to create the modal in a dedicated media modal package, and have each editor instance output the modal in one place?

Then it'd be up to each button that triggers the modal to dispatch an action to open (and possibly configure) that single instance of the modal, rather than output the modal itself.

Again not a blocker, just wondering how the fields package and modal might interact, but this could be pursued or explored in a follow-up (and perhaps any media fields should be defined alongside a modal?). This already provides a great foundation for those sorts of explorations IMO!

@tellthemachines
Copy link
Contributor Author

if/when we have media-specific fields for it to use that might exist in the fields package (i.e. a circular dependency issue because the featured image field needs to use the modal, too).

I'm not sure I understand. Other media-specific fields would use it just like the featured image field does in this PR, or am I missing something?

@andrewserong
Copy link
Contributor

andrewserong commented Oct 23, 2025

Other media-specific fields would use it just like the featured image field does in this PR, or am I missing something?

Oh, sorry, my statement was ambiguous! What I'm imagining is if/when we have some generic fields that are designed to be used in DataViews instances or the Picker for selecting or viewing media items. And where those fields will live vs where the modal lives. Fields like:

  • alt_text
  • caption
  • description
  • attached_to
  • dimensions
  • filesize

Eventually we might have a suite of those sorts of fields that will need to live somewhere, and this modal might conceivably use those fields within the modal. However if those fields live in the same package as featured_image (which uses this modal) then we might have a circular dependency:

  • featured_image field incorporates a modal for selecting media
  • The modal uses fields alt_text, caption, attached_to and imports them from fields (or wherever these fields should live)
  • We now have a circular dependency as a field in fields is using the modal, but the modal needs to import from fields

It isn't a blocker for now as we don't (yet) have these kinds of dedicated fields specifically for the attachment post type (they're inlined in the modal itself as you've done here). But it's an area that I could imagine we might need if/when we have a DataViews-based media library as well as this modal, so that they can share common fields.

@andrewserong
Copy link
Contributor

andrewserong commented Oct 23, 2025

One idea for those fields, would be for them to live in a separate package, i.e. a media-fields package, so my comment might be moot! But reading over the PR made me think of it, so I thought I'd jot down the thought. I'd be keen to explore ideas in this area after this PR lands.

@tellthemachines
Copy link
Contributor Author

Hmm yeah it's probably unsustainable to lump all the fields in their own package. The editor package also has at least one field defined in it. It might be that fields end up living closer to the places they're used, instead of in their own package. I don't really have opinions on that right now 😄

@andrewserong
Copy link
Contributor

I don't really have opinions on that right now 😄

No worries! I think it'll become clearer as we try out some of these ideas... let's continue the discussion on a subsequent WIP PR 😊

@talldan
Copy link
Contributor

talldan commented Oct 23, 2025

One idea for those fields, would be for them to live in a separate package, i.e. a media-fields package

But would the featured image upload field then also be a media field? 😅

I guess it's a post field really.

I also think the featured image upload field should be changed to a general 'MediaUpload' field at some point. We should capture these things in issues.

@andrewserong
Copy link
Contributor

andrewserong commented Oct 23, 2025

We should capture these things in issues.

Good idea. I'd jotted down a few notes about which fields we might need over in the media library issue #55238, but it could really use its own issue. I'll write one up! Edit: added an issue for the fields in #72612

@ramonjd
Copy link
Member

ramonjd commented Oct 24, 2025

This is working well. I think it's good enough to ship for the experiment, with any issues fixable in other PRs

💯

Does what it says on the tin. Could we merge an iterate?

Kapture.2025-10-24.at.12.55.26.mp4

Just checking, the settings cog dropdown in the media modal allows field selection, but since it's a grid view it doesn't do anything.

Is that a dataviews thing? I mean to say, something we could tell dataviews not to display?

Screenshot 2025-10-24 at 12 56 41 pm

@tellthemachines
Copy link
Contributor Author

Does what it says on the tin. Could we merge an iterate?

We can, I just can't stop tinkering with it 😅

Thanks for the reviews everyone!

@tellthemachines tellthemachines merged commit 3d4320e into trunk Oct 24, 2025
34 checks passed
@tellthemachines tellthemachines deleted the try/new-media-modal branch October 24, 2025 02:43
@github-actions github-actions bot added this to the Gutenberg 22.0 milestone Oct 24, 2025
@ramonjd
Copy link
Member

ramonjd commented Oct 24, 2025

We can, I just can't stop tinkering with it 😅

Sorry, I didn't mean to be pushy 😄 I think it's a great step forward! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Package] Media Utils /packages/media-utils [Type] Enhancement A suggestion for improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants