@wordpress/block-library 11.1.0 → 11.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/build/accordion-heading/block.json +1 -0
- package/build/archives/block.json +3 -0
- package/build/audio/edit.cjs +2 -1
- package/build/audio/edit.cjs.map +2 -2
- package/build/avatar/block.json +4 -0
- package/build/avatar/edit.cjs +31 -1
- package/build/avatar/edit.cjs.map +3 -3
- package/build/button/block.json +6 -0
- package/build/button/edit.cjs +9 -6
- package/build/button/edit.cjs.map +2 -2
- package/build/buttons/block.json +6 -1
- package/build/code/block.json +4 -0
- package/build/column/edit.cjs +5 -0
- package/build/column/edit.cjs.map +2 -2
- package/build/columns/block.json +4 -0
- package/build/columns/edit.cjs +21 -112
- package/build/columns/edit.cjs.map +3 -3
- package/build/comments/edit/placeholder.cjs +95 -87
- package/build/comments/edit/placeholder.cjs.map +2 -2
- package/build/comments-pagination/block.json +11 -0
- package/build/cover/block.json +2 -1
- package/build/cover/edit/index.cjs +26 -5
- package/build/cover/edit/index.cjs.map +2 -2
- package/build/cover/edit/inspector-controls.cjs +4 -1
- package/build/cover/edit/inspector-controls.cjs.map +2 -2
- package/build/cover/embed-video-utils.cjs +9 -8
- package/build/cover/embed-video-utils.cjs.map +2 -2
- package/build/cover/view.cjs +21 -0
- package/build/cover/view.cjs.map +7 -0
- package/build/details/block.json +3 -0
- package/build/embed/block.json +6 -1
- package/build/file/block.json +5 -0
- package/build/footnotes/block.json +4 -0
- package/build/gallery/block.json +13 -0
- package/build/gallery/dynamic-gallery.cjs +32 -93
- package/build/gallery/dynamic-gallery.cjs.map +3 -3
- package/build/gallery/edit.cjs +103 -40
- package/build/gallery/edit.cjs.map +2 -2
- package/build/gallery/order-controls.cjs +107 -0
- package/build/gallery/order-controls.cjs.map +7 -0
- package/build/gallery/order-images.cjs +92 -0
- package/build/gallery/order-images.cjs.map +7 -0
- package/build/gallery/order-options.cjs +62 -0
- package/build/gallery/order-options.cjs.map +7 -0
- package/build/gallery/use-dynamic-gallery.cjs +1 -7
- package/build/gallery/use-dynamic-gallery.cjs.map +2 -2
- package/build/gallery/use-get-media.cjs +2 -3
- package/build/gallery/use-get-media.cjs.map +2 -2
- package/build/group/edit.cjs +3 -3
- package/build/group/edit.cjs.map +2 -2
- package/build/heading/block.json +5 -0
- package/build/home-link/block.json +12 -0
- package/build/icon/components/custom-inserter/index.cjs +3 -1
- package/build/icon/components/custom-inserter/index.cjs.map +2 -2
- package/build/icon/edit.cjs +49 -5
- package/build/icon/edit.cjs.map +2 -2
- package/build/image/use-open-image-media-editor-modal.cjs +32 -28
- package/build/image/use-open-image-media-editor-modal.cjs.map +2 -2
- package/build/image/view.cjs +44 -50
- package/build/image/view.cjs.map +2 -2
- package/build/latest-comments/block.json +10 -0
- package/build/latest-posts/block.json +4 -0
- package/build/list/block.json +12 -1
- package/build/list-item/block.json +8 -1
- package/build/list-item/index.cjs +4 -0
- package/build/list-item/index.cjs.map +3 -3
- package/build/loginout/block.json +4 -0
- package/build/math/block.json +4 -0
- package/build/media-text/block.json +18 -0
- package/build/navigation-link/link-ui/index.cjs +33 -19
- package/build/navigation-link/link-ui/index.cjs.map +2 -2
- package/build/navigation-link/shared/index.cjs +5 -0
- package/build/navigation-link/shared/index.cjs.map +2 -2
- package/build/navigation-link/shared/use-block-suggestions.cjs +141 -0
- package/build/navigation-link/shared/use-block-suggestions.cjs.map +7 -0
- package/build/page-list/block.json +4 -0
- package/build/paragraph/block.json +1 -0
- package/build/post-author-biography/block.json +1 -0
- package/build/post-comments-form/block.json +5 -0
- package/build/post-content/block.json +2 -1
- package/build/post-excerpt/block.json +4 -0
- package/build/post-featured-image/block.json +1 -0
- package/build/post-featured-image/edit.cjs +1 -1
- package/build/post-featured-image/edit.cjs.map +2 -2
- package/build/post-terms/block.json +4 -0
- package/build/post-time-to-read/block.json +4 -0
- package/build/post-title/block.json +4 -0
- package/build/preformatted/block.json +4 -0
- package/build/pullquote/block.json +2 -1
- package/build/query-no-results/block.json +4 -0
- package/build/query-pagination/block.json +17 -0
- package/build/query-total/block.json +4 -0
- package/build/quote/block.json +2 -0
- package/build/read-more/block.json +5 -0
- package/build/rss/block.json +4 -0
- package/build/search/block.json +2 -1
- package/build/site-tagline/block.json +4 -0
- package/build/site-title/block.json +4 -0
- package/build/social-links/block.json +1 -0
- package/build/tab-list/block.json +4 -0
- package/build/tab-list/edit.cjs +3 -1
- package/build/tab-list/edit.cjs.map +3 -3
- package/build/tab-list/save.cjs +3 -1
- package/build/tab-list/save.cjs.map +3 -3
- package/build/tab-panels/block.json +3 -0
- package/build/tabs/block.json +3 -0
- package/build/term-count/block.json +5 -0
- package/build/term-description/block.json +4 -0
- package/build/term-name/block.json +6 -1
- package/build/term-template/block.json +4 -0
- package/build/utils/waveform-utils.cjs +2 -2
- package/build/utils/waveform-utils.cjs.map +2 -2
- package/build/verse/block.json +4 -0
- package/build/video/block.json +7 -1
- package/build/video/edit.cjs +10 -2
- package/build/video/edit.cjs.map +2 -2
- package/build-module/accordion-heading/block.json +1 -0
- package/build-module/archives/block.json +3 -0
- package/build-module/audio/edit.mjs +2 -1
- package/build-module/audio/edit.mjs.map +2 -2
- package/build-module/avatar/block.json +4 -0
- package/build-module/avatar/edit.mjs +33 -2
- package/build-module/avatar/edit.mjs.map +2 -2
- package/build-module/button/block.json +6 -0
- package/build-module/button/edit.mjs +11 -7
- package/build-module/button/edit.mjs.map +2 -2
- package/build-module/buttons/block.json +6 -1
- package/build-module/code/block.json +4 -0
- package/build-module/column/edit.mjs +5 -0
- package/build-module/column/edit.mjs.map +2 -2
- package/build-module/columns/block.json +4 -0
- package/build-module/columns/edit.mjs +22 -122
- package/build-module/columns/edit.mjs.map +2 -2
- package/build-module/comments/edit/placeholder.mjs +95 -87
- package/build-module/comments/edit/placeholder.mjs.map +2 -2
- package/build-module/comments-pagination/block.json +11 -0
- package/build-module/cover/block.json +2 -1
- package/build-module/cover/edit/index.mjs +32 -6
- package/build-module/cover/edit/index.mjs.map +2 -2
- package/build-module/cover/edit/inspector-controls.mjs +5 -2
- package/build-module/cover/edit/inspector-controls.mjs.map +2 -2
- package/build-module/cover/embed-video-utils.mjs +9 -8
- package/build-module/cover/embed-video-utils.mjs.map +2 -2
- package/build-module/cover/view.mjs +19 -0
- package/build-module/cover/view.mjs.map +7 -0
- package/build-module/details/block.json +3 -0
- package/build-module/embed/block.json +6 -1
- package/build-module/file/block.json +5 -0
- package/build-module/footnotes/block.json +4 -0
- package/build-module/gallery/block.json +13 -0
- package/build-module/gallery/dynamic-gallery.mjs +33 -97
- package/build-module/gallery/dynamic-gallery.mjs.map +2 -2
- package/build-module/gallery/edit.mjs +110 -42
- package/build-module/gallery/edit.mjs.map +2 -2
- package/build-module/gallery/order-controls.mjs +87 -0
- package/build-module/gallery/order-controls.mjs.map +7 -0
- package/build-module/gallery/order-images.mjs +66 -0
- package/build-module/gallery/order-images.mjs.map +7 -0
- package/build-module/gallery/order-options.mjs +33 -0
- package/build-module/gallery/order-options.mjs.map +7 -0
- package/build-module/gallery/use-dynamic-gallery.mjs +1 -7
- package/build-module/gallery/use-dynamic-gallery.mjs.map +2 -2
- package/build-module/gallery/use-get-media.mjs +2 -3
- package/build-module/gallery/use-get-media.mjs.map +2 -2
- package/build-module/group/edit.mjs +4 -4
- package/build-module/group/edit.mjs.map +2 -2
- package/build-module/heading/block.json +5 -0
- package/build-module/home-link/block.json +12 -0
- package/build-module/icon/components/custom-inserter/index.mjs +3 -1
- package/build-module/icon/components/custom-inserter/index.mjs.map +2 -2
- package/build-module/icon/edit.mjs +50 -6
- package/build-module/icon/edit.mjs.map +2 -2
- package/build-module/image/use-open-image-media-editor-modal.mjs +32 -28
- package/build-module/image/use-open-image-media-editor-modal.mjs.map +2 -2
- package/build-module/image/view.mjs +44 -50
- package/build-module/image/view.mjs.map +2 -2
- package/build-module/latest-comments/block.json +10 -0
- package/build-module/latest-posts/block.json +4 -0
- package/build-module/list/block.json +12 -1
- package/build-module/list-item/block.json +8 -1
- package/build-module/list-item/index.mjs +4 -0
- package/build-module/list-item/index.mjs.map +2 -2
- package/build-module/loginout/block.json +4 -0
- package/build-module/math/block.json +4 -0
- package/build-module/media-text/block.json +18 -0
- package/build-module/navigation-link/link-ui/index.mjs +39 -20
- package/build-module/navigation-link/link-ui/index.mjs.map +2 -2
- package/build-module/navigation-link/shared/index.mjs +6 -0
- package/build-module/navigation-link/shared/index.mjs.map +2 -2
- package/build-module/navigation-link/shared/use-block-suggestions.mjs +120 -0
- package/build-module/navigation-link/shared/use-block-suggestions.mjs.map +7 -0
- package/build-module/page-list/block.json +4 -0
- package/build-module/paragraph/block.json +1 -0
- package/build-module/post-author-biography/block.json +1 -0
- package/build-module/post-comments-form/block.json +5 -0
- package/build-module/post-content/block.json +2 -1
- package/build-module/post-excerpt/block.json +4 -0
- package/build-module/post-featured-image/block.json +1 -0
- package/build-module/post-featured-image/edit.mjs +1 -1
- package/build-module/post-featured-image/edit.mjs.map +2 -2
- package/build-module/post-terms/block.json +4 -0
- package/build-module/post-time-to-read/block.json +4 -0
- package/build-module/post-title/block.json +4 -0
- package/build-module/preformatted/block.json +4 -0
- package/build-module/pullquote/block.json +2 -1
- package/build-module/query-no-results/block.json +4 -0
- package/build-module/query-pagination/block.json +17 -0
- package/build-module/query-total/block.json +4 -0
- package/build-module/quote/block.json +2 -0
- package/build-module/read-more/block.json +5 -0
- package/build-module/rss/block.json +4 -0
- package/build-module/search/block.json +2 -1
- package/build-module/site-tagline/block.json +4 -0
- package/build-module/site-title/block.json +4 -0
- package/build-module/social-links/block.json +1 -0
- package/build-module/tab-list/block.json +4 -0
- package/build-module/tab-list/edit.mjs +4 -1
- package/build-module/tab-list/edit.mjs.map +2 -2
- package/build-module/tab-list/save.mjs +4 -1
- package/build-module/tab-list/save.mjs.map +2 -2
- package/build-module/tab-panels/block.json +3 -0
- package/build-module/tabs/block.json +3 -0
- package/build-module/term-count/block.json +5 -0
- package/build-module/term-description/block.json +4 -0
- package/build-module/term-name/block.json +6 -1
- package/build-module/term-template/block.json +4 -0
- package/build-module/utils/waveform-utils.mjs +1 -1
- package/build-module/utils/waveform-utils.mjs.map +1 -1
- package/build-module/verse/block.json +4 -0
- package/build-module/video/block.json +7 -1
- package/build-module/video/edit.mjs +10 -2
- package/build-module/video/edit.mjs.map +2 -2
- package/build-style/avatar/editor-rtl.css +4 -0
- package/build-style/avatar/editor.css +4 -0
- package/build-style/comments-pagination/style-rtl.css +3 -0
- package/build-style/comments-pagination/style.css +3 -0
- package/build-style/common-rtl.css +32 -1
- package/build-style/common.css +35 -2
- package/build-style/editor-rtl.css +11 -4
- package/build-style/editor.css +11 -4
- package/build-style/embed/style-rtl.css +4 -1
- package/build-style/embed/style.css +4 -1
- package/build-style/gallery/editor-rtl.css +1 -3
- package/build-style/gallery/editor.css +1 -3
- package/build-style/image/style-rtl.css +11 -2
- package/build-style/image/style.css +11 -2
- package/build-style/media-text/style-rtl.css +4 -1
- package/build-style/media-text/style.css +4 -1
- package/build-style/query-pagination/style-rtl.css +3 -0
- package/build-style/query-pagination/style.css +3 -0
- package/build-style/style-rtl.css +70 -9
- package/build-style/style.css +73 -10
- package/build-style/table/editor-rtl.css +6 -1
- package/build-style/table/editor.css +6 -1
- package/build-style/table/style-rtl.css +4 -2
- package/build-style/table/style.css +4 -2
- package/build-style/tag-cloud/style-rtl.css +1 -1
- package/build-style/tag-cloud/style.css +1 -1
- package/build-style/verse/style-rtl.css +8 -1
- package/build-style/verse/style.css +8 -1
- package/build-types/gallery/order-controls.d.ts +58 -0
- package/build-types/gallery/order-controls.d.ts.map +1 -0
- package/build-types/gallery/order-options.d.ts +67 -0
- package/build-types/gallery/order-options.d.ts.map +1 -0
- package/package.json +44 -41
- package/src/accordion-heading/README.md +1 -0
- package/src/accordion-heading/block.json +1 -0
- package/src/archives/README.md +2 -0
- package/src/archives/block.json +3 -0
- package/src/audio/edit.jsx +2 -1
- package/src/avatar/README.md +2 -0
- package/src/avatar/block.json +4 -0
- package/src/avatar/edit.jsx +48 -2
- package/src/avatar/editor.scss +4 -0
- package/src/avatar/index.php +5 -3
- package/src/breadcrumbs/index.php +1 -1
- package/src/button/README.md +4 -0
- package/src/button/block.json +6 -0
- package/src/button/edit.jsx +47 -52
- package/src/button/index.php +47 -0
- package/src/buttons/README.md +4 -0
- package/src/buttons/block.json +6 -1
- package/src/code/README.md +3 -0
- package/src/code/block.json +4 -0
- package/src/column/edit.jsx +6 -0
- package/src/columns/README.md +3 -0
- package/src/columns/block.json +4 -0
- package/src/columns/edit.jsx +1 -131
- package/src/comments/edit/placeholder.jsx +5 -1
- package/src/comments-pagination/README.md +4 -0
- package/src/comments-pagination/block.json +11 -0
- package/src/comments-pagination/style.scss +3 -0
- package/src/common.scss +38 -0
- package/src/cover/README.md +1 -0
- package/src/cover/block.json +2 -1
- package/src/cover/edit/index.jsx +38 -6
- package/src/cover/edit/inspector-controls.jsx +10 -1
- package/src/cover/embed-video-utils.js +18 -10
- package/src/cover/index.php +44 -15
- package/src/cover/test/edit.browser.test.js +182 -2
- package/src/cover/test/embed-video-utils.test.js +48 -0
- package/src/cover/view.js +22 -0
- package/src/details/README.md +2 -0
- package/src/details/block.json +3 -0
- package/src/embed/README.md +4 -0
- package/src/embed/block.json +6 -1
- package/src/embed/style.scss +7 -1
- package/src/file/README.md +4 -0
- package/src/file/block.json +5 -0
- package/src/footnotes/README.md +3 -0
- package/src/footnotes/block.json +4 -0
- package/src/gallery/README.md +13 -0
- package/src/gallery/block.json +13 -0
- package/src/gallery/dynamic-gallery.jsx +11 -91
- package/src/gallery/edit.jsx +146 -47
- package/src/gallery/editor.scss +5 -9
- package/src/gallery/order-controls.tsx +143 -0
- package/src/gallery/order-images.js +111 -0
- package/src/gallery/order-options.ts +75 -0
- package/src/gallery/test/edit.jsdom.test.js +87 -10
- package/src/gallery/test/order-images.js +162 -0
- package/src/gallery/use-dynamic-gallery.js +1 -9
- package/src/gallery/use-get-media.js +7 -2
- package/src/group/edit.jsx +5 -5
- package/src/heading/README.md +4 -0
- package/src/heading/block.json +5 -0
- package/src/home-link/README.md +6 -0
- package/src/home-link/block.json +12 -0
- package/src/icon/components/custom-inserter/index.jsx +5 -1
- package/src/icon/edit.jsx +68 -7
- package/src/icon/index.php +1 -1
- package/src/image/index.php +3 -4
- package/src/image/style.scss +14 -2
- package/src/image/test/use-open-image-media-editor-modal.jsdom.test.js +122 -60
- package/src/image/use-open-image-media-editor-modal.js +37 -41
- package/src/image/view.js +64 -68
- package/src/latest-comments/README.md +3 -0
- package/src/latest-comments/block.json +10 -0
- package/src/latest-posts/README.md +3 -0
- package/src/latest-posts/block.json +4 -0
- package/src/list/README.md +6 -0
- package/src/list/block.json +12 -1
- package/src/list-item/README.md +6 -0
- package/src/list-item/block.json +8 -1
- package/src/list-item/index.js +5 -0
- package/src/loginout/README.md +3 -0
- package/src/loginout/block.json +4 -0
- package/src/math/README.md +3 -0
- package/src/math/block.json +4 -0
- package/src/media-text/README.md +17 -0
- package/src/media-text/block.json +18 -0
- package/src/media-text/style.scss +5 -1
- package/src/navigation/test/use-navigation-menu.jsdom.test.js +1 -1
- package/src/navigation-link/README.md +1 -1
- package/src/navigation-link/link-ui/index.jsx +60 -27
- package/src/navigation-link/link-ui/test/get-suggestions-query.jsdom.test.js +67 -0
- package/src/navigation-link/shared/index.js +4 -0
- package/src/navigation-link/shared/test/use-block-suggestions.jsdom.test.js +158 -0
- package/src/navigation-link/shared/test/use-entity-binding.jsdom.test.js +1 -7
- package/src/navigation-link/shared/use-block-suggestions.js +192 -0
- package/src/page-list/README.md +3 -0
- package/src/page-list/block.json +4 -0
- package/src/paragraph/README.md +1 -0
- package/src/paragraph/block.json +1 -0
- package/src/playlist/test/edit-component.jsdom.test.jsx +11 -11
- package/src/playlist-track/test/edit.jsdom.test.jsx +3 -3
- package/src/post-author-biography/README.md +1 -0
- package/src/post-author-biography/block.json +1 -0
- package/src/post-comments-form/README.md +3 -0
- package/src/post-comments-form/block.json +5 -0
- package/src/post-content/README.md +1 -0
- package/src/post-content/block.json +2 -1
- package/src/post-excerpt/README.md +3 -0
- package/src/post-excerpt/block.json +4 -0
- package/src/post-featured-image/block.json +1 -0
- package/src/post-featured-image/edit.jsx +2 -2
- package/src/post-terms/README.md +3 -0
- package/src/post-terms/block.json +4 -0
- package/src/post-time-to-read/README.md +3 -0
- package/src/post-time-to-read/block.json +4 -0
- package/src/post-title/README.md +3 -0
- package/src/post-title/block.json +4 -0
- package/src/preformatted/README.md +3 -0
- package/src/preformatted/block.json +4 -0
- package/src/pullquote/README.md +1 -0
- package/src/pullquote/block.json +2 -1
- package/src/query-no-results/README.md +3 -0
- package/src/query-no-results/block.json +4 -0
- package/src/query-pagination/README.md +4 -0
- package/src/query-pagination/block.json +17 -0
- package/src/query-pagination/style.scss +3 -0
- package/src/query-total/README.md +3 -0
- package/src/query-total/block.json +4 -0
- package/src/quote/README.md +2 -0
- package/src/quote/block.json +2 -0
- package/src/read-more/README.md +3 -0
- package/src/read-more/block.json +5 -0
- package/src/rss/README.md +3 -0
- package/src/rss/block.json +4 -0
- package/src/search/README.md +1 -0
- package/src/search/block.json +2 -1
- package/src/site-tagline/README.md +3 -0
- package/src/site-tagline/block.json +4 -0
- package/src/site-title/README.md +3 -0
- package/src/site-title/block.json +4 -0
- package/src/social-links/README.md +1 -0
- package/src/social-links/block.json +1 -0
- package/src/tab-list/README.md +2 -0
- package/src/tab-list/block.json +4 -0
- package/src/tab-list/edit.jsx +3 -0
- package/src/tab-list/save.jsx +3 -0
- package/src/tab-panels/README.md +2 -0
- package/src/tab-panels/block.json +3 -0
- package/src/table/editor.scss +8 -2
- package/src/table/style.scss +4 -4
- package/src/tabs/README.md +2 -0
- package/src/tabs/block.json +3 -0
- package/src/tag-cloud/style.scss +1 -1
- package/src/template-part/index.php +16 -3
- package/src/term-count/README.md +4 -0
- package/src/term-count/block.json +5 -0
- package/src/term-description/README.md +3 -0
- package/src/term-description/block.json +4 -0
- package/src/term-name/README.md +4 -0
- package/src/term-name/block.json +6 -1
- package/src/term-template/README.md +3 -0
- package/src/term-template/block.json +4 -0
- package/src/utils/test/waveform-player-auto-init.jsdom.test.js +25 -0
- package/src/utils/test/waveform-player-dependency.jsdom.test.js +7 -60
- package/src/utils/test/waveform-utils.browser.test.js +3 -15
- package/src/utils/waveform-utils.js +1 -1
- package/src/verse/README.md +4 -0
- package/src/verse/block.json +4 -0
- package/src/verse/style.scss +11 -2
- package/src/video/README.md +4 -0
- package/src/video/block.json +7 -1
- package/src/video/edit.jsx +13 -2
- package/build/columns/utils.cjs +0 -112
- package/build/columns/utils.cjs.map +0 -7
- package/build-module/columns/utils.mjs +0 -78
- package/build-module/columns/utils.mjs.map +0 -7
- package/src/columns/test/utils.js +0 -331
- package/src/columns/utils.js +0 -176
package/src/gallery/edit.jsx
CHANGED
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
MediaReplaceFlow,
|
|
24
24
|
useSettings,
|
|
25
25
|
} from '@wordpress/block-editor';
|
|
26
|
-
import { useEffect, useMemo, useRef } from '@wordpress/element';
|
|
26
|
+
import { useEffect, useMemo, useRef, useState } from '@wordpress/element';
|
|
27
27
|
import { __, _x, sprintf } from '@wordpress/i18n';
|
|
28
28
|
import { useSelect, useDispatch } from '@wordpress/data';
|
|
29
29
|
import { createBlock } from '@wordpress/blocks';
|
|
@@ -64,7 +64,14 @@ import useGetMedia from './use-get-media';
|
|
|
64
64
|
import GalleryStyles from './gallery-styles';
|
|
65
65
|
import useDynamicGallery from './use-dynamic-gallery';
|
|
66
66
|
import { GallerySourcePanel, GalleryDynamicView } from './dynamic-gallery';
|
|
67
|
-
import {
|
|
67
|
+
import { SortImagesControl, SourceOrderControl } from './order-controls';
|
|
68
|
+
import {
|
|
69
|
+
getDynamicSource,
|
|
70
|
+
ATTACHED_MEDIA,
|
|
71
|
+
DEFAULT_ORDERBY,
|
|
72
|
+
DEFAULT_ORDER,
|
|
73
|
+
} from './dynamic-source';
|
|
74
|
+
import { hasSortableImages, sortImageBlocks } from './order-images';
|
|
68
75
|
import {
|
|
69
76
|
getViewportGalleryStyle,
|
|
70
77
|
getUpdatedGalleryStyle,
|
|
@@ -313,6 +320,22 @@ export default function GalleryEdit( props ) {
|
|
|
313
320
|
const hasImages = !! images.length;
|
|
314
321
|
const isDynamic = !! attributes.dynamicContent;
|
|
315
322
|
|
|
323
|
+
// The static "Order by" control shows the last sort applied from it, for as
|
|
324
|
+
// long as the images stay in the sequence that sort produced. Any other
|
|
325
|
+
// change to the images (a drag, an addition, a removal) drops it back to
|
|
326
|
+
// "Custom"; it never reports an order the user didn't choose. Nothing is
|
|
327
|
+
// stored, so this is local state rather than an attribute.
|
|
328
|
+
const [ appliedSort, setAppliedSort ] = useState( null );
|
|
329
|
+
const currentOrder =
|
|
330
|
+
appliedSort &&
|
|
331
|
+
appliedSort.clientIds.length === innerBlockImages.length &&
|
|
332
|
+
appliedSort.clientIds.every(
|
|
333
|
+
( id, index ) => innerBlockImages[ index ].clientId === id
|
|
334
|
+
)
|
|
335
|
+
? appliedSort.order
|
|
336
|
+
: null;
|
|
337
|
+
const canSortImages = hasSortableImages( innerBlockImages, imageData );
|
|
338
|
+
|
|
316
339
|
// Dynamic mode (resolving images from a source instead of inner blocks):
|
|
317
340
|
// source resolution, the editor-preview blocks, and the mode/ordering
|
|
318
341
|
// actions.
|
|
@@ -545,6 +568,49 @@ export default function GalleryEdit( props ) {
|
|
|
545
568
|
}
|
|
546
569
|
}
|
|
547
570
|
|
|
571
|
+
function selectRandomOrder() {
|
|
572
|
+
setAttributes( { randomOrder: true } );
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
// Choosing any other order turns "Random" off. Called straight after the
|
|
576
|
+
// edit that applies the order, and marked non-persistent so the two writes
|
|
577
|
+
// share one undo level: a single undo restores both the order and Random.
|
|
578
|
+
function clearRandomOrderAfterEdit() {
|
|
579
|
+
if ( randomOrder ) {
|
|
580
|
+
__unstableMarkNextChangeAsNotPersistent();
|
|
581
|
+
setAttributes( { randomOrder: false } );
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// Reorders the inner image blocks in place. Left persistent on purpose so
|
|
586
|
+
// the sort is a single undoable step.
|
|
587
|
+
function sortImages( order ) {
|
|
588
|
+
const sortedBlocks = sortImageBlocks(
|
|
589
|
+
getBlock( clientId ).innerBlocks,
|
|
590
|
+
imageData,
|
|
591
|
+
order
|
|
592
|
+
);
|
|
593
|
+
replaceInnerBlocks( clientId, sortedBlocks );
|
|
594
|
+
clearRandomOrderAfterEdit();
|
|
595
|
+
setAppliedSort( {
|
|
596
|
+
order,
|
|
597
|
+
clientIds: sortedBlocks.map( ( block ) => block.clientId ),
|
|
598
|
+
} );
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
// "Custom" is the order arranged in the editor: it turns Random off and
|
|
602
|
+
// forgets any sort applied earlier, so the control reads "Custom" from
|
|
603
|
+
// here on rather than that sort.
|
|
604
|
+
function selectCustomOrder() {
|
|
605
|
+
setAttributes( { randomOrder: false } );
|
|
606
|
+
setAppliedSort( null );
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
function changeSourceOrder( { orderby, order } ) {
|
|
610
|
+
dynamic.setSourceOrder( orderby, order );
|
|
611
|
+
clearRandomOrderAfterEdit();
|
|
612
|
+
}
|
|
613
|
+
|
|
548
614
|
function onUploadError( message ) {
|
|
549
615
|
createErrorNotice( message, { type: 'snackbar' } );
|
|
550
616
|
}
|
|
@@ -615,10 +681,6 @@ export default function GalleryEdit( props ) {
|
|
|
615
681
|
setGallerySettings( { imageCrop: ! activeImageCrop } );
|
|
616
682
|
}
|
|
617
683
|
|
|
618
|
-
function toggleRandomOrder() {
|
|
619
|
-
setAttributes( { randomOrder: ! randomOrder } );
|
|
620
|
-
}
|
|
621
|
-
|
|
622
684
|
function toggleOpenInNewTab( openInNewTab ) {
|
|
623
685
|
const newLinkTarget = openInNewTab ? '_blank' : undefined;
|
|
624
686
|
setAttributes( { linkTarget: newLinkTarget } );
|
|
@@ -862,7 +924,6 @@ export default function GalleryEdit( props ) {
|
|
|
862
924
|
{ ! isViewportStyleState && (
|
|
863
925
|
<GallerySourcePanel
|
|
864
926
|
dynamic={ dynamic }
|
|
865
|
-
dropdownMenuProps={ dropdownMenuProps }
|
|
866
927
|
hasImages={ hasImages }
|
|
867
928
|
/>
|
|
868
929
|
) }
|
|
@@ -889,6 +950,10 @@ export default function GalleryEdit( props ) {
|
|
|
889
950
|
|
|
890
951
|
setAspectRatio( 'auto' );
|
|
891
952
|
|
|
953
|
+
if ( isDynamic ) {
|
|
954
|
+
dynamic.setSourceOrder( undefined, undefined );
|
|
955
|
+
}
|
|
956
|
+
|
|
892
957
|
if ( sizeSlug !== DEFAULT_MEDIA_SIZE_SLUG ) {
|
|
893
958
|
updateImagesSize( DEFAULT_MEDIA_SIZE_SLUG );
|
|
894
959
|
}
|
|
@@ -930,6 +995,56 @@ export default function GalleryEdit( props ) {
|
|
|
930
995
|
/>
|
|
931
996
|
</ToolsPanelItem>
|
|
932
997
|
) }
|
|
998
|
+
{ ! isViewportStyleState && (
|
|
999
|
+
// "Random" is stored in both modes. Beyond that, a
|
|
1000
|
+
// dynamic gallery's order is a stored query setting,
|
|
1001
|
+
// while a static gallery's orders are one-off actions.
|
|
1002
|
+
<ToolsPanelItem
|
|
1003
|
+
isShownByDefault
|
|
1004
|
+
label={ __( 'Order by' ) }
|
|
1005
|
+
hasValue={ () =>
|
|
1006
|
+
!! randomOrder ||
|
|
1007
|
+
( isDynamic &&
|
|
1008
|
+
( dynamic.sourceOrderby !==
|
|
1009
|
+
DEFAULT_ORDERBY ||
|
|
1010
|
+
dynamic.sourceOrder !==
|
|
1011
|
+
DEFAULT_ORDER ) )
|
|
1012
|
+
}
|
|
1013
|
+
onDeselect={ () => {
|
|
1014
|
+
if ( isDynamic ) {
|
|
1015
|
+
// Two writes, folded into one undo level.
|
|
1016
|
+
dynamic.setSourceOrder(
|
|
1017
|
+
undefined,
|
|
1018
|
+
undefined
|
|
1019
|
+
);
|
|
1020
|
+
clearRandomOrderAfterEdit();
|
|
1021
|
+
} else {
|
|
1022
|
+
selectCustomOrder();
|
|
1023
|
+
}
|
|
1024
|
+
} }
|
|
1025
|
+
>
|
|
1026
|
+
{ isDynamic ? (
|
|
1027
|
+
<SourceOrderControl
|
|
1028
|
+
order={ {
|
|
1029
|
+
orderby: dynamic.sourceOrderby,
|
|
1030
|
+
order: dynamic.sourceOrder,
|
|
1031
|
+
} }
|
|
1032
|
+
isRandom={ !! randomOrder }
|
|
1033
|
+
onChange={ changeSourceOrder }
|
|
1034
|
+
onSelectRandom={ selectRandomOrder }
|
|
1035
|
+
/>
|
|
1036
|
+
) : (
|
|
1037
|
+
<SortImagesControl
|
|
1038
|
+
currentOrder={ currentOrder }
|
|
1039
|
+
isRandom={ !! randomOrder }
|
|
1040
|
+
canSort={ canSortImages }
|
|
1041
|
+
onSort={ sortImages }
|
|
1042
|
+
onSelectCustom={ selectCustomOrder }
|
|
1043
|
+
onSelectRandom={ selectRandomOrder }
|
|
1044
|
+
/>
|
|
1045
|
+
) }
|
|
1046
|
+
</ToolsPanelItem>
|
|
1047
|
+
) }
|
|
933
1048
|
{ ! isViewportStyleState &&
|
|
934
1049
|
imageSizeOptions?.length > 0 && (
|
|
935
1050
|
<ToolsPanelItem
|
|
@@ -954,46 +1069,6 @@ export default function GalleryEdit( props ) {
|
|
|
954
1069
|
/>
|
|
955
1070
|
</ToolsPanelItem>
|
|
956
1071
|
) }
|
|
957
|
-
{ isFlexLayout && (
|
|
958
|
-
<ToolsPanelItem
|
|
959
|
-
isShownByDefault
|
|
960
|
-
label={ __( 'Crop images to fit' ) }
|
|
961
|
-
hasValue={ () =>
|
|
962
|
-
isViewportStyleState
|
|
963
|
-
? hasViewportImageCrop
|
|
964
|
-
: ! activeImageCrop
|
|
965
|
-
}
|
|
966
|
-
onDeselect={ () =>
|
|
967
|
-
setGallerySettings( {
|
|
968
|
-
imageCrop: isViewportStyleState
|
|
969
|
-
? undefined
|
|
970
|
-
: true,
|
|
971
|
-
} )
|
|
972
|
-
}
|
|
973
|
-
>
|
|
974
|
-
<ToggleControl
|
|
975
|
-
label={ __( 'Crop images to fit' ) }
|
|
976
|
-
checked={ activeImageCrop }
|
|
977
|
-
onChange={ toggleImageCrop }
|
|
978
|
-
/>
|
|
979
|
-
</ToolsPanelItem>
|
|
980
|
-
) }
|
|
981
|
-
{ ! isViewportStyleState && (
|
|
982
|
-
<ToolsPanelItem
|
|
983
|
-
isShownByDefault
|
|
984
|
-
label={ __( 'Randomize order' ) }
|
|
985
|
-
hasValue={ () => !! randomOrder }
|
|
986
|
-
onDeselect={ () =>
|
|
987
|
-
setAttributes( { randomOrder: false } )
|
|
988
|
-
}
|
|
989
|
-
>
|
|
990
|
-
<ToggleControl
|
|
991
|
-
label={ __( 'Randomize order' ) }
|
|
992
|
-
checked={ !! randomOrder }
|
|
993
|
-
onChange={ toggleRandomOrder }
|
|
994
|
-
/>
|
|
995
|
-
</ToolsPanelItem>
|
|
996
|
-
) }
|
|
997
1072
|
{ ! isViewportStyleState && hasLinkTo && (
|
|
998
1073
|
<ToolsPanelItem
|
|
999
1074
|
isShownByDefault
|
|
@@ -1037,6 +1112,30 @@ export default function GalleryEdit( props ) {
|
|
|
1037
1112
|
/>
|
|
1038
1113
|
</ToolsPanelItem>
|
|
1039
1114
|
) }
|
|
1115
|
+
{ isFlexLayout && (
|
|
1116
|
+
<ToolsPanelItem
|
|
1117
|
+
isShownByDefault
|
|
1118
|
+
label={ __( 'Crop images to fit' ) }
|
|
1119
|
+
hasValue={ () =>
|
|
1120
|
+
isViewportStyleState
|
|
1121
|
+
? hasViewportImageCrop
|
|
1122
|
+
: ! activeImageCrop
|
|
1123
|
+
}
|
|
1124
|
+
onDeselect={ () =>
|
|
1125
|
+
setGallerySettings( {
|
|
1126
|
+
imageCrop: isViewportStyleState
|
|
1127
|
+
? undefined
|
|
1128
|
+
: true,
|
|
1129
|
+
} )
|
|
1130
|
+
}
|
|
1131
|
+
>
|
|
1132
|
+
<ToggleControl
|
|
1133
|
+
label={ __( 'Crop images to fit' ) }
|
|
1134
|
+
checked={ activeImageCrop }
|
|
1135
|
+
onChange={ toggleImageCrop }
|
|
1136
|
+
/>
|
|
1137
|
+
</ToolsPanelItem>
|
|
1138
|
+
) }
|
|
1040
1139
|
{ ! isViewportStyleState &&
|
|
1041
1140
|
lightboxSetting?.allowEditing &&
|
|
1042
1141
|
hasLightboxImages && (
|
package/src/gallery/editor.scss
CHANGED
|
@@ -125,12 +125,9 @@
|
|
|
125
125
|
gap: $grid-unit-15;
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
// The Source controls
|
|
129
|
-
//
|
|
130
|
-
// button so the button is the last element, keeping the same vertical rhythm to
|
|
131
|
-
// the next control (control -> grid row-gap -> next label) as the other rows.
|
|
128
|
+
// The Source panel's controls: a description above a full-width action button,
|
|
129
|
+
// stacked inside a PanelBody.
|
|
132
130
|
.wp-block-gallery__source-settings {
|
|
133
|
-
grid-column: 1 / -1;
|
|
134
131
|
display: flex;
|
|
135
132
|
flex-direction: column;
|
|
136
133
|
gap: $grid-unit-10;
|
|
@@ -150,9 +147,8 @@
|
|
|
150
147
|
}
|
|
151
148
|
}
|
|
152
149
|
|
|
153
|
-
// The "showing the first N" notice
|
|
154
|
-
//
|
|
150
|
+
// The "showing the first N" notice follows the Source controls in the same
|
|
151
|
+
// PanelBody, which adds no spacing of its own between children.
|
|
155
152
|
.wp-block-gallery__source-notice {
|
|
156
|
-
grid-
|
|
157
|
-
margin: 0;
|
|
153
|
+
margin: $grid-unit-20 0 0;
|
|
158
154
|
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { __ } from '@wordpress/i18n';
|
|
2
|
+
import { SelectControl as WCSelectControl } from '@wordpress/components';
|
|
3
|
+
import {
|
|
4
|
+
ORDER_OPTIONS,
|
|
5
|
+
RANDOM_OPTION,
|
|
6
|
+
RANDOM_ORDER,
|
|
7
|
+
parseOrderValue,
|
|
8
|
+
toOrderValue,
|
|
9
|
+
} from './order-options';
|
|
10
|
+
import type { Order } from './order-options';
|
|
11
|
+
|
|
12
|
+
function getOrderHelp( isRandom: boolean ): string | undefined {
|
|
13
|
+
return isRandom
|
|
14
|
+
? __( 'Images are shown in a random order each time the page loads.' )
|
|
15
|
+
: undefined;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const SOURCE_ORDER_OPTIONS = [ ...ORDER_OPTIONS, RANDOM_OPTION ];
|
|
19
|
+
|
|
20
|
+
type SourceOrderControlProps = {
|
|
21
|
+
/** The stored query order. */
|
|
22
|
+
order: Order;
|
|
23
|
+
/** Whether the gallery's `randomOrder` attribute is set. */
|
|
24
|
+
isRandom: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Called with `{ orderby, order }` to update the query. Choosing an order
|
|
27
|
+
* also turns "Random" off; the handler owns that so both writes land in one
|
|
28
|
+
* undo level.
|
|
29
|
+
*/
|
|
30
|
+
onChange: ( order: Order ) => void;
|
|
31
|
+
/** Called when "Random" is chosen. */
|
|
32
|
+
onSelectRandom: () => void;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Ordering control for a dynamic gallery, shown in the Settings panel. The
|
|
37
|
+
* chosen order is a *setting*: it's stored in the source's query and re-applied
|
|
38
|
+
* every time the source resolves. "Random" is stored separately (the
|
|
39
|
+
* `randomOrder` attribute) and overrides the query order on the front end, so
|
|
40
|
+
* while it's set the control shows it instead of the query order.
|
|
41
|
+
*/
|
|
42
|
+
export function SourceOrderControl( {
|
|
43
|
+
order,
|
|
44
|
+
isRandom,
|
|
45
|
+
onChange,
|
|
46
|
+
onSelectRandom,
|
|
47
|
+
}: SourceOrderControlProps ) {
|
|
48
|
+
return (
|
|
49
|
+
<WCSelectControl
|
|
50
|
+
label={ __( 'Order by' ) }
|
|
51
|
+
value={ isRandom ? RANDOM_ORDER : toOrderValue( order ) }
|
|
52
|
+
options={ SOURCE_ORDER_OPTIONS }
|
|
53
|
+
help={ getOrderHelp( isRandom ) }
|
|
54
|
+
onChange={ ( value ) => {
|
|
55
|
+
if ( value === RANDOM_ORDER ) {
|
|
56
|
+
onSelectRandom();
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
onChange( parseOrderValue( value ) );
|
|
60
|
+
} }
|
|
61
|
+
/>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const CUSTOM_ORDER = 'custom';
|
|
66
|
+
|
|
67
|
+
type SortImagesControlProps = {
|
|
68
|
+
/** The last sort applied, while it still holds, or `null` for a custom order. */
|
|
69
|
+
currentOrder: Order | null;
|
|
70
|
+
/** Whether the gallery's `randomOrder` attribute is set. */
|
|
71
|
+
isRandom: boolean;
|
|
72
|
+
/** Whether the sort orders can be applied (false while media resolves). */
|
|
73
|
+
canSort: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Called with `{ orderby, order }` to sort the images. Sorting also turns
|
|
76
|
+
* "Random" off; the handler owns that so both writes land in one undo level.
|
|
77
|
+
*/
|
|
78
|
+
onSort: ( order: Order ) => void;
|
|
79
|
+
/** Called when "Custom" is chosen, which turns "Random" off. */
|
|
80
|
+
onSelectCustom: () => void;
|
|
81
|
+
/** Called when "Random" is chosen. */
|
|
82
|
+
onSelectRandom: () => void;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Ordering control for a static gallery, shown in the Settings panel.
|
|
87
|
+
*
|
|
88
|
+
* The date and title orders are one-off *actions*: choosing one reorders the
|
|
89
|
+
* inner image blocks once, and the user can drag them into any other order
|
|
90
|
+
* afterwards. Nothing is stored for them, so the caller passes back the last
|
|
91
|
+
* sort it applied for as long as the images remain in that sequence, and
|
|
92
|
+
* `null` ("Custom") otherwise. "Custom" means the order arranged in the
|
|
93
|
+
* editor, and is choosable only while "Random" is on: picking it turns
|
|
94
|
+
* "Random" off without reordering anything.
|
|
95
|
+
*
|
|
96
|
+
* "Random" is the one stored value (the `randomOrder` attribute). It applies
|
|
97
|
+
* on the front end only, leaving the editor order as it is, and choosing any
|
|
98
|
+
* other option clears it.
|
|
99
|
+
*/
|
|
100
|
+
export function SortImagesControl( {
|
|
101
|
+
currentOrder,
|
|
102
|
+
isRandom,
|
|
103
|
+
canSort,
|
|
104
|
+
onSort,
|
|
105
|
+
onSelectCustom,
|
|
106
|
+
onSelectRandom,
|
|
107
|
+
}: SortImagesControlProps ) {
|
|
108
|
+
const options = [
|
|
109
|
+
{ label: __( 'Custom' ), value: CUSTOM_ORDER, disabled: ! isRandom },
|
|
110
|
+
...ORDER_OPTIONS.map( ( option ) => ( {
|
|
111
|
+
...option,
|
|
112
|
+
disabled: ! canSort,
|
|
113
|
+
} ) ),
|
|
114
|
+
RANDOM_OPTION,
|
|
115
|
+
];
|
|
116
|
+
|
|
117
|
+
let value = CUSTOM_ORDER;
|
|
118
|
+
if ( isRandom ) {
|
|
119
|
+
value = RANDOM_ORDER;
|
|
120
|
+
} else if ( currentOrder ) {
|
|
121
|
+
value = toOrderValue( currentOrder );
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return (
|
|
125
|
+
<WCSelectControl
|
|
126
|
+
label={ __( 'Order by' ) }
|
|
127
|
+
value={ value }
|
|
128
|
+
options={ options }
|
|
129
|
+
help={ getOrderHelp( isRandom ) }
|
|
130
|
+
onChange={ ( nextValue ) => {
|
|
131
|
+
if ( nextValue === RANDOM_ORDER ) {
|
|
132
|
+
onSelectRandom();
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if ( nextValue === CUSTOM_ORDER ) {
|
|
136
|
+
onSelectCustom();
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
onSort( parseOrderValue( nextValue ) );
|
|
140
|
+
} }
|
|
141
|
+
/>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the value an image block is ordered by, or `undefined` when it has no
|
|
3
|
+
* resolved attachment record to take it from.
|
|
4
|
+
*
|
|
5
|
+
* @param {Object} block A `core/image` inner block.
|
|
6
|
+
* @param {Array} media Attachment records for the gallery's images.
|
|
7
|
+
* @param {string} orderby `date` or `title`.
|
|
8
|
+
* @return {?string} The sort key.
|
|
9
|
+
*/
|
|
10
|
+
function getSortKey( block, media, orderby ) {
|
|
11
|
+
const { id } = block.attributes;
|
|
12
|
+
if ( id === undefined ) {
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
const record = media.find( ( item ) => item.id === id );
|
|
16
|
+
if ( ! record ) {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
if ( orderby === 'title' ) {
|
|
20
|
+
// The media is fetched in the default (view) context, so `rendered`
|
|
21
|
+
// is the usual source; `raw` is only present with the edit context.
|
|
22
|
+
return record.title?.raw ?? record.title?.rendered ?? '';
|
|
23
|
+
}
|
|
24
|
+
return record.date ?? '';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Whether there's anything to sort: at least two image blocks with a resolved
|
|
29
|
+
* attachment record. With fewer, sorting is a no-op, so the sort options are
|
|
30
|
+
* disabled.
|
|
31
|
+
*
|
|
32
|
+
* @param {Array} blocks The gallery's `core/image` inner blocks.
|
|
33
|
+
* @param {Array} media Attachment records for the gallery's images.
|
|
34
|
+
* @return {boolean} Whether the images can be sorted.
|
|
35
|
+
*/
|
|
36
|
+
export function hasSortableImages( blocks, media ) {
|
|
37
|
+
// Runs on every render, so avoid scanning `media` once per block.
|
|
38
|
+
const mediaIds = new Set( media.map( ( item ) => item.id ) );
|
|
39
|
+
let sortableCount = 0;
|
|
40
|
+
for ( const block of blocks ) {
|
|
41
|
+
if ( ! mediaIds.has( block.attributes.id ) ) {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
sortableCount++;
|
|
45
|
+
if ( sortableCount > 1 ) {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Compares two sort keys for the given field. Titles use a natural,
|
|
54
|
+
* case-insensitive comparison so `IMG_2` sorts before `IMG_10`; dates are ISO
|
|
55
|
+
* 8601 strings, so a plain string comparison orders them chronologically.
|
|
56
|
+
*
|
|
57
|
+
* @param {string} a First key.
|
|
58
|
+
* @param {string} b Second key.
|
|
59
|
+
* @param {string} orderby `date` or `title`.
|
|
60
|
+
* @return {number} Negative when `a` sorts first, positive when `b` does.
|
|
61
|
+
*/
|
|
62
|
+
function compareKeys( a, b, orderby ) {
|
|
63
|
+
if ( orderby === 'title' ) {
|
|
64
|
+
return a.localeCompare( b, undefined, {
|
|
65
|
+
numeric: true,
|
|
66
|
+
sensitivity: 'base',
|
|
67
|
+
} );
|
|
68
|
+
}
|
|
69
|
+
if ( a === b ) {
|
|
70
|
+
return 0;
|
|
71
|
+
}
|
|
72
|
+
return a < b ? -1 : 1;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Sorts a static gallery's image blocks by an attachment field.
|
|
77
|
+
*
|
|
78
|
+
* Blocks without an `id`, or whose attachment record isn't in `media` (still
|
|
79
|
+
* loading, or deleted from the library), can't be placed, so they keep their
|
|
80
|
+
* relative order and move to the end. Blocks with equal keys likewise keep
|
|
81
|
+
* their relative order (`Array.prototype.sort` is stable), so re-applying the
|
|
82
|
+
* current order is a no-op.
|
|
83
|
+
*
|
|
84
|
+
* @param {Array} blocks The gallery's `core/image` inner blocks.
|
|
85
|
+
* @param {Array} media Attachment records for the gallery's images.
|
|
86
|
+
* @param {Object} order The order to apply.
|
|
87
|
+
* @param {string} order.orderby `date` or `title`.
|
|
88
|
+
* @param {string} order.order `asc` or `desc`.
|
|
89
|
+
* @return {Array} A new array holding the same block objects, sorted.
|
|
90
|
+
*/
|
|
91
|
+
export function sortImageBlocks( blocks, media, { orderby, order } ) {
|
|
92
|
+
const direction = order === 'desc' ? -1 : 1;
|
|
93
|
+
const keys = new Map(
|
|
94
|
+
blocks.map( ( block ) => [
|
|
95
|
+
block,
|
|
96
|
+
getSortKey( block, media, orderby ),
|
|
97
|
+
] )
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
return [ ...blocks ].sort( ( a, b ) => {
|
|
101
|
+
const keyA = keys.get( a );
|
|
102
|
+
const keyB = keys.get( b );
|
|
103
|
+
if ( keyA === undefined || keyB === undefined ) {
|
|
104
|
+
if ( keyA === keyB ) {
|
|
105
|
+
return 0;
|
|
106
|
+
}
|
|
107
|
+
return keyA === undefined ? 1 : -1;
|
|
108
|
+
}
|
|
109
|
+
return compareKeys( keyA, keyB, orderby ) * direction;
|
|
110
|
+
} );
|
|
111
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { __ } from '@wordpress/i18n';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* An ordering of gallery images: the field to order by and the direction.
|
|
5
|
+
*/
|
|
6
|
+
export type Order = {
|
|
7
|
+
orderby: string;
|
|
8
|
+
order: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The composite `"orderby/order"` select value for an order. A select needs one
|
|
13
|
+
* string per option, so this format exists only at the select boundary; the
|
|
14
|
+
* rest of the feature passes `Order` objects.
|
|
15
|
+
*
|
|
16
|
+
* @param order The order.
|
|
17
|
+
* @return The select value.
|
|
18
|
+
*/
|
|
19
|
+
export function toOrderValue( order: Order ): string {
|
|
20
|
+
return `${ order.orderby }/${ order.order }`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Parses a composite `"orderby/order"` select value back into an order.
|
|
25
|
+
*
|
|
26
|
+
* @param value The select value.
|
|
27
|
+
* @return The order.
|
|
28
|
+
*/
|
|
29
|
+
export function parseOrderValue( value: string ): Order {
|
|
30
|
+
const [ orderby, order ] = value.split( '/' );
|
|
31
|
+
return { orderby, order };
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Ordering options offered for gallery images. Each value is a composite
|
|
36
|
+
* `orderby/order` string. The two modes share values and labels but differ
|
|
37
|
+
* in their comparison logic:
|
|
38
|
+
*
|
|
39
|
+
* - A dynamic gallery passes `orderby/order` to the REST API in the editor (the
|
|
40
|
+
* `/wp/v2/media` collection params; see `dynamic-source.js`) and to a
|
|
41
|
+
* `WP_Query` on the front end (see `index.php`). Either way the database
|
|
42
|
+
* orders by post date or post title.
|
|
43
|
+
* - A static gallery orders its inner image blocks client-side from the same
|
|
44
|
+
* attachment fields (see `order-images.js`). Dates compare the same way.
|
|
45
|
+
* Titles use a natural, case-insensitive compare, so `IMG_2` sorts before
|
|
46
|
+
* `IMG_10` where the database would put it after. The two title orders can
|
|
47
|
+
* therefore differ for numbered titles.
|
|
48
|
+
*
|
|
49
|
+
* `menu_order` is deliberately omitted — it isn't a valid REST `orderby`
|
|
50
|
+
* value, so the editor preview couldn't reproduce it (see `dynamic-source.js`).
|
|
51
|
+
*/
|
|
52
|
+
export const ORDER_OPTIONS = [
|
|
53
|
+
{ label: __( 'Newest to oldest' ), value: 'date/desc' },
|
|
54
|
+
{ label: __( 'Oldest to newest' ), value: 'date/asc' },
|
|
55
|
+
{
|
|
56
|
+
/* translators: Label for ordering images by title in ascending order. */
|
|
57
|
+
label: __( 'A → Z' ),
|
|
58
|
+
value: 'title/asc',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
/* translators: Label for ordering images by title in descending order. */
|
|
62
|
+
label: __( 'Z → A' ),
|
|
63
|
+
value: 'title/desc',
|
|
64
|
+
},
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* The "Random" order. Unlike the orders above it isn't an `orderby`: it is the
|
|
69
|
+
* gallery's `randomOrder` attribute, applied only on the front end by shuffling
|
|
70
|
+
* the rendered images (see `index.php`), so the editor keeps showing the
|
|
71
|
+
* underlying order. Offered as the last option of both modes' "Order by"
|
|
72
|
+
* control, since it overrides whatever other order is in place.
|
|
73
|
+
*/
|
|
74
|
+
export const RANDOM_ORDER = 'random';
|
|
75
|
+
export const RANDOM_OPTION = { label: __( 'Random' ), value: RANDOM_ORDER };
|