Skip to content

Conversation

ryanwelcher
Copy link
Contributor

@ryanwelcher ryanwelcher commented Aug 15, 2025

What?

Closes #16484

This pull request adds a an icon block based on @ndiego Icon Block.

To be completed:

@ryanwelcher ryanwelcher self-assigned this Aug 15, 2025
@ryanwelcher ryanwelcher added New Block Suggestion for a new block [Package] Blocks /packages/blocks [Type] Feature New feature to highlight in changelogs. [Type] Enhancement A suggestion for improvement. labels Aug 15, 2025
@ryanwelcher
Copy link
Contributor Author

ryanwelcher commented Aug 15, 2025

The PR is very much a draft that is essentially the source code from @ndiego plugin with changes to work as a core block, pass linting, and display the icons mentioned here.

@ndiego
Copy link
Member

ndiego commented Aug 15, 2025

Thanks for doing the heavy lifting here @ryanwelcher. Excited to see this come to Gutenberg

@mikemcalister
Copy link

Great work, @ryanwelcher and @ndiego! Excited to dig into this. Happy to provide any resources, guidance, or context I can to help get this across the finish line.

@ryanwelcher ryanwelcher removed [Type] Enhancement A suggestion for improvement. [Type] Feature New feature to highlight in changelogs. labels Aug 16, 2025
@ryanwelcher
Copy link
Contributor Author

One thing that I have been thinking about how to handle SVG uploads. To be clear, I don't think we should enable SVG uploads in core - that's another conversation entirely and beyond the scope of this work.

That being said, the existing code from the Icon Block plugin does a mime type check to see if SVG uploads have been enabled and provides the UI to upload them. IMO, this is a big win for extenders and I would love to see it stay in the block.

Copy link

github-actions bot commented Aug 26, 2025

Size Change: +34.1 kB (+1.75%)

Total Size: 1.98 MB

Filename Size Change
build/block-library/editor-rtl.css 13.3 kB +1.76 kB (+15.25%) ⚠️
build/block-library/editor.css 13.3 kB +1.76 kB (+15.25%) ⚠️
build/block-library/index.min.js 262 kB +24.9 kB (+10.51%) ⚠️
build/block-library/style-rtl.css 15.7 kB +253 B (+1.64%)
build/block-library/style.css 15.7 kB +253 B (+1.64%)
build/block-library/blocks/icon/editor-rtl.css 2.21 kB +2.21 kB (new file) 🆕
build/block-library/blocks/icon/editor.css 2.21 kB +2.21 kB (new file) 🆕
build/block-library/blocks/icon/style-rtl.css 372 B +372 B (new file) 🆕
build/block-library/blocks/icon/style.css 372 B +372 B (new file) 🆕
ℹ️ View Unchanged
Filename Size
build-module/a11y/index.min.js 482 B
build-module/block-library/accordion/view.min.js 427 B
build-module/block-library/file/view.min.js 466 B
build-module/block-library/form/view.min.js 533 B
build-module/block-library/image/view.min.js 1.78 kB
build-module/block-library/navigation/view.min.js 1.19 kB
build-module/block-library/query/view.min.js 767 B
build-module/block-library/search/view.min.js 639 B
build-module/interactivity-router/full-page.min.js 565 B
build-module/interactivity-router/index.min.js 11.4 kB
build-module/interactivity/debug.min.js 17.6 kB
build-module/interactivity/index.min.js 14 kB
build/a11y/index.min.js 925 B
build/annotations/index.min.js 2.13 kB
build/api-fetch/index.min.js 2.41 kB
build/autop/index.min.js 2.12 kB
build/blob/index.min.js 579 B
build/block-directory/index.min.js 7.18 kB
build/block-directory/style-rtl.css 1.03 kB
build/block-directory/style.css 1.03 kB
build/block-editor/content-rtl.css 4.43 kB
build/block-editor/content.css 4.42 kB
build/block-editor/default-editor-styles-rtl.css 392 B
build/block-editor/default-editor-styles.css 392 B
build/block-editor/index.min.js 267 kB
build/block-editor/style-rtl.css 15.9 kB
build/block-editor/style.css 15.9 kB
build/block-library/blocks/accordion/style-rtl.css 600 B
build/block-library/blocks/accordion/style.css 599 B
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 61 B
build/block-library/blocks/archives/style-rtl.css 90 B
build/block-library/blocks/archives/style.css 90 B
build/block-library/blocks/audio/editor-rtl.css 149 B
build/block-library/blocks/audio/editor.css 151 B
build/block-library/blocks/audio/style-rtl.css 132 B
build/block-library/blocks/audio/style.css 132 B
build/block-library/blocks/audio/theme-rtl.css 134 B
build/block-library/blocks/audio/theme.css 134 B
build/block-library/blocks/avatar/editor-rtl.css 115 B
build/block-library/blocks/avatar/editor.css 115 B
build/block-library/blocks/avatar/style-rtl.css 104 B
build/block-library/blocks/avatar/style.css 104 B
build/block-library/blocks/button/editor-rtl.css 265 B
build/block-library/blocks/button/editor.css 265 B
build/block-library/blocks/button/style-rtl.css 554 B
build/block-library/blocks/button/style.css 554 B
build/block-library/blocks/buttons/editor-rtl.css 291 B
build/block-library/blocks/buttons/editor.css 291 B
build/block-library/blocks/buttons/style-rtl.css 349 B
build/block-library/blocks/buttons/style.css 349 B
build/block-library/blocks/calendar/style-rtl.css 239 B
build/block-library/blocks/calendar/style.css 239 B
build/block-library/blocks/categories/editor-rtl.css 132 B
build/block-library/blocks/categories/editor.css 131 B
build/block-library/blocks/categories/style-rtl.css 152 B
build/block-library/blocks/categories/style.css 152 B
build/block-library/blocks/code/editor-rtl.css 53 B
build/block-library/blocks/code/editor.css 53 B
build/block-library/blocks/code/style-rtl.css 139 B
build/block-library/blocks/code/style.css 139 B
build/block-library/blocks/code/theme-rtl.css 122 B
build/block-library/blocks/code/theme.css 122 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 420 B
build/block-library/blocks/columns/style.css 420 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 124 B
build/block-library/blocks/comment-author-avatar/editor.css 124 B
build/block-library/blocks/comment-author-name/style-rtl.css 72 B
build/block-library/blocks/comment-author-name/style.css 72 B
build/block-library/blocks/comment-content/style-rtl.css 120 B
build/block-library/blocks/comment-content/style.css 120 B
build/block-library/blocks/comment-date/style-rtl.css 65 B
build/block-library/blocks/comment-date/style.css 65 B
build/block-library/blocks/comment-edit-link/style-rtl.css 70 B
build/block-library/blocks/comment-edit-link/style.css 70 B
build/block-library/blocks/comment-reply-link/style-rtl.css 71 B
build/block-library/blocks/comment-reply-link/style.css 71 B
build/block-library/blocks/comment-template/style-rtl.css 191 B
build/block-library/blocks/comment-template/style.css 191 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 168 B
build/block-library/blocks/comments-pagination/editor.css 168 B
build/block-library/blocks/comments-pagination/style-rtl.css 201 B
build/block-library/blocks/comments-pagination/style.css 201 B
build/block-library/blocks/comments-title/editor-rtl.css 75 B
build/block-library/blocks/comments-title/editor.css 75 B
build/block-library/blocks/comments/editor-rtl.css 842 B
build/block-library/blocks/comments/editor.css 842 B
build/block-library/blocks/comments/style-rtl.css 637 B
build/block-library/blocks/comments/style.css 637 B
build/block-library/blocks/cover/editor-rtl.css 631 B
build/block-library/blocks/cover/editor.css 631 B
build/block-library/blocks/cover/style-rtl.css 1.7 kB
build/block-library/blocks/cover/style.css 1.69 kB
build/block-library/blocks/details/editor-rtl.css 65 B
build/block-library/blocks/details/editor.css 65 B
build/block-library/blocks/details/style-rtl.css 86 B
build/block-library/blocks/details/style.css 86 B
build/block-library/blocks/embed/editor-rtl.css 331 B
build/block-library/blocks/embed/editor.css 331 B
build/block-library/blocks/embed/style-rtl.css 419 B
build/block-library/blocks/embed/style.css 419 B
build/block-library/blocks/embed/theme-rtl.css 133 B
build/block-library/blocks/embed/theme.css 133 B
build/block-library/blocks/file/editor-rtl.css 326 B
build/block-library/blocks/file/editor.css 326 B
build/block-library/blocks/file/style-rtl.css 278 B
build/block-library/blocks/file/style.css 278 B
build/block-library/blocks/footnotes/style-rtl.css 198 B
build/block-library/blocks/footnotes/style.css 197 B
build/block-library/blocks/form-input/editor-rtl.css 229 B
build/block-library/blocks/form-input/editor.css 229 B
build/block-library/blocks/form-input/style-rtl.css 366 B
build/block-library/blocks/form-input/style.css 366 B
build/block-library/blocks/form-submission-notification/editor-rtl.css 344 B
build/block-library/blocks/form-submission-notification/editor.css 341 B
build/block-library/blocks/form-submit-button/style-rtl.css 69 B
build/block-library/blocks/form-submit-button/style.css 69 B
build/block-library/blocks/freeform/editor-rtl.css 2.59 kB
build/block-library/blocks/freeform/editor.css 2.59 kB
build/block-library/blocks/gallery/editor-rtl.css 615 B
build/block-library/blocks/gallery/editor.css 616 B
build/block-library/blocks/gallery/style-rtl.css 1.83 kB
build/block-library/blocks/gallery/style.css 1.83 kB
build/block-library/blocks/gallery/theme-rtl.css 108 B
build/block-library/blocks/gallery/theme.css 108 B
build/block-library/blocks/group/editor-rtl.css 334 B
build/block-library/blocks/group/editor.css 334 B
build/block-library/blocks/group/style-rtl.css 103 B
build/block-library/blocks/group/style.css 103 B
build/block-library/blocks/group/theme-rtl.css 79 B
build/block-library/blocks/group/theme.css 79 B
build/block-library/blocks/heading/style-rtl.css 188 B
build/block-library/blocks/heading/style.css 188 B
build/block-library/blocks/html/editor-rtl.css 353 B
build/block-library/blocks/html/editor.css 354 B
build/block-library/blocks/image/editor-rtl.css 763 B
build/block-library/blocks/image/editor.css 763 B
build/block-library/blocks/image/style-rtl.css 1.6 kB
build/block-library/blocks/image/style.css 1.59 kB
build/block-library/blocks/image/theme-rtl.css 137 B
build/block-library/blocks/image/theme.css 137 B
build/block-library/blocks/latest-comments/style-rtl.css 355 B
build/block-library/blocks/latest-comments/style.css 354 B
build/block-library/blocks/latest-posts/editor-rtl.css 139 B
build/block-library/blocks/latest-posts/editor.css 138 B
build/block-library/blocks/latest-posts/style-rtl.css 520 B
build/block-library/blocks/latest-posts/style.css 520 B
build/block-library/blocks/list/style-rtl.css 107 B
build/block-library/blocks/list/style.css 107 B
build/block-library/blocks/loginout/style-rtl.css 61 B
build/block-library/blocks/loginout/style.css 61 B
build/block-library/blocks/media-text/editor-rtl.css 321 B
build/block-library/blocks/media-text/editor.css 320 B
build/block-library/blocks/media-text/style-rtl.css 543 B
build/block-library/blocks/media-text/style.css 542 B
build/block-library/blocks/more/editor-rtl.css 393 B
build/block-library/blocks/more/editor.css 393 B
build/block-library/blocks/navigation-link/editor-rtl.css 625 B
build/block-library/blocks/navigation-link/editor.css 628 B
build/block-library/blocks/navigation-link/style-rtl.css 190 B
build/block-library/blocks/navigation-link/style.css 188 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 295 B
build/block-library/blocks/navigation-submenu/editor.css 294 B
build/block-library/blocks/navigation/editor-rtl.css 2.23 kB
build/block-library/blocks/navigation/editor.css 2.24 kB
build/block-library/blocks/navigation/style-rtl.css 2.27 kB
build/block-library/blocks/navigation/style.css 2.26 kB
build/block-library/blocks/nextpage/editor-rtl.css 392 B
build/block-library/blocks/nextpage/editor.css 392 B
build/block-library/blocks/page-list/editor-rtl.css 356 B
build/block-library/blocks/page-list/editor.css 356 B
build/block-library/blocks/page-list/style-rtl.css 192 B
build/block-library/blocks/page-list/style.css 192 B
build/block-library/blocks/paragraph/editor-rtl.css 251 B
build/block-library/blocks/paragraph/editor.css 251 B
build/block-library/blocks/paragraph/style-rtl.css 341 B
build/block-library/blocks/paragraph/style.css 340 B
build/block-library/blocks/post-author-biography/style-rtl.css 74 B
build/block-library/blocks/post-author-biography/style.css 74 B
build/block-library/blocks/post-author-name/style-rtl.css 69 B
build/block-library/blocks/post-author-name/style.css 69 B
build/block-library/blocks/post-author/style-rtl.css 188 B
build/block-library/blocks/post-author/style.css 189 B
build/block-library/blocks/post-comments-count/style-rtl.css 72 B
build/block-library/blocks/post-comments-count/style.css 72 B
build/block-library/blocks/post-comments-form/editor-rtl.css 96 B
build/block-library/blocks/post-comments-form/editor.css 96 B
build/block-library/blocks/post-comments-form/style-rtl.css 525 B
build/block-library/blocks/post-comments-form/style.css 525 B
build/block-library/blocks/post-comments-link/style-rtl.css 71 B
build/block-library/blocks/post-comments-link/style.css 71 B
build/block-library/blocks/post-content/style-rtl.css 61 B
build/block-library/blocks/post-content/style.css 61 B
build/block-library/blocks/post-date/style-rtl.css 62 B
build/block-library/blocks/post-date/style.css 62 B
build/block-library/blocks/post-excerpt/editor-rtl.css 71 B
build/block-library/blocks/post-excerpt/editor.css 71 B
build/block-library/blocks/post-excerpt/style-rtl.css 155 B
build/block-library/blocks/post-excerpt/style.css 155 B
build/block-library/blocks/post-featured-image/editor-rtl.css 715 B
build/block-library/blocks/post-featured-image/editor.css 712 B
build/block-library/blocks/post-featured-image/style-rtl.css 347 B
build/block-library/blocks/post-featured-image/style.css 347 B
build/block-library/blocks/post-navigation-link/style-rtl.css 215 B
build/block-library/blocks/post-navigation-link/style.css 214 B
build/block-library/blocks/post-template/style-rtl.css 414 B
build/block-library/blocks/post-template/style.css 414 B
build/block-library/blocks/post-terms/style-rtl.css 96 B
build/block-library/blocks/post-terms/style.css 96 B
build/block-library/blocks/post-time-to-read/style-rtl.css 70 B
build/block-library/blocks/post-time-to-read/style.css 70 B
build/block-library/blocks/post-title/style-rtl.css 162 B
build/block-library/blocks/post-title/style.css 162 B
build/block-library/blocks/preformatted/style-rtl.css 125 B
build/block-library/blocks/preformatted/style.css 125 B
build/block-library/blocks/pullquote/editor-rtl.css 133 B
build/block-library/blocks/pullquote/editor.css 133 B
build/block-library/blocks/pullquote/style-rtl.css 365 B
build/block-library/blocks/pullquote/style.css 365 B
build/block-library/blocks/pullquote/theme-rtl.css 176 B
build/block-library/blocks/pullquote/theme.css 176 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 121 B
build/block-library/blocks/query-pagination-numbers/editor.css 118 B
build/block-library/blocks/query-pagination/editor-rtl.css 154 B
build/block-library/blocks/query-pagination/editor.css 154 B
build/block-library/blocks/query-pagination/style-rtl.css 237 B
build/block-library/blocks/query-pagination/style.css 237 B
build/block-library/blocks/query-title/style-rtl.css 64 B
build/block-library/blocks/query-title/style.css 64 B
build/block-library/blocks/query-total/style-rtl.css 64 B
build/block-library/blocks/query-total/style.css 64 B
build/block-library/blocks/query/editor-rtl.css 432 B
build/block-library/blocks/query/editor.css 432 B
build/block-library/blocks/quote/style-rtl.css 238 B
build/block-library/blocks/quote/style.css 238 B
build/block-library/blocks/quote/theme-rtl.css 233 B
build/block-library/blocks/quote/theme.css 236 B
build/block-library/blocks/read-more/style-rtl.css 131 B
build/block-library/blocks/read-more/style.css 131 B
build/block-library/blocks/rss/editor-rtl.css 126 B
build/block-library/blocks/rss/editor.css 126 B
build/block-library/blocks/rss/style-rtl.css 284 B
build/block-library/blocks/rss/style.css 283 B
build/block-library/blocks/search/editor-rtl.css 199 B
build/block-library/blocks/search/editor.css 199 B
build/block-library/blocks/search/style-rtl.css 665 B
build/block-library/blocks/search/style.css 666 B
build/block-library/blocks/search/theme-rtl.css 113 B
build/block-library/blocks/search/theme.css 113 B
build/block-library/blocks/separator/editor-rtl.css 100 B
build/block-library/blocks/separator/editor.css 100 B
build/block-library/blocks/separator/style-rtl.css 248 B
build/block-library/blocks/separator/style.css 248 B
build/block-library/blocks/separator/theme-rtl.css 195 B
build/block-library/blocks/separator/theme.css 195 B
build/block-library/blocks/shortcode/editor-rtl.css 286 B
build/block-library/blocks/shortcode/editor.css 286 B
build/block-library/blocks/site-logo/editor-rtl.css 773 B
build/block-library/blocks/site-logo/editor.css 770 B
build/block-library/blocks/site-logo/style-rtl.css 218 B
build/block-library/blocks/site-logo/style.css 218 B
build/block-library/blocks/site-tagline/editor-rtl.css 87 B
build/block-library/blocks/site-tagline/editor.css 87 B
build/block-library/blocks/site-tagline/style-rtl.css 65 B
build/block-library/blocks/site-tagline/style.css 65 B
build/block-library/blocks/site-title/editor-rtl.css 85 B
build/block-library/blocks/site-title/editor.css 85 B
build/block-library/blocks/site-title/style-rtl.css 143 B
build/block-library/blocks/site-title/style.css 143 B
build/block-library/blocks/social-link/editor-rtl.css 314 B
build/block-library/blocks/social-link/editor.css 314 B
build/block-library/blocks/social-links/editor-rtl.css 339 B
build/block-library/blocks/social-links/editor.css 338 B
build/block-library/blocks/social-links/style-rtl.css 1.51 kB
build/block-library/blocks/social-links/style.css 1.51 kB
build/block-library/blocks/spacer/editor-rtl.css 346 B
build/block-library/blocks/spacer/editor.css 346 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table-of-contents/style-rtl.css 83 B
build/block-library/blocks/table-of-contents/style.css 83 B
build/block-library/blocks/table/editor-rtl.css 394 B
build/block-library/blocks/table/editor.css 394 B
build/block-library/blocks/table/style-rtl.css 640 B
build/block-library/blocks/table/style.css 639 B
build/block-library/blocks/table/theme-rtl.css 152 B
build/block-library/blocks/table/theme.css 152 B
build/block-library/blocks/tag-cloud/editor-rtl.css 92 B
build/block-library/blocks/tag-cloud/editor.css 92 B
build/block-library/blocks/tag-cloud/style-rtl.css 248 B
build/block-library/blocks/tag-cloud/style.css 248 B
build/block-library/blocks/template-part/editor-rtl.css 368 B
build/block-library/blocks/template-part/editor.css 368 B
build/block-library/blocks/template-part/theme-rtl.css 113 B
build/block-library/blocks/template-part/theme.css 113 B
build/block-library/blocks/term-description/style-rtl.css 126 B
build/block-library/blocks/term-description/style.css 126 B
build/block-library/blocks/term-template/editor-rtl.css 225 B
build/block-library/blocks/term-template/editor.css 225 B
build/block-library/blocks/term-template/style-rtl.css 135 B
build/block-library/blocks/term-template/style.css 135 B
build/block-library/blocks/terms-query/style-rtl.css 70 B
build/block-library/blocks/terms-query/style.css 70 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 165 B
build/block-library/blocks/text-columns/style.css 165 B
build/block-library/blocks/verse/style-rtl.css 98 B
build/block-library/blocks/verse/style.css 98 B
build/block-library/blocks/video/editor-rtl.css 413 B
build/block-library/blocks/video/editor.css 414 B
build/block-library/blocks/video/style-rtl.css 202 B
build/block-library/blocks/video/style.css 202 B
build/block-library/blocks/video/theme-rtl.css 134 B
build/block-library/blocks/video/theme.css 134 B
build/block-library/classic-rtl.css 179 B
build/block-library/classic.css 179 B
build/block-library/common-rtl.css 1.08 kB
build/block-library/common.css 1.08 kB
build/block-library/editor-elements-rtl.css 75 B
build/block-library/editor-elements.css 75 B
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/reset-rtl.css 472 B
build/block-library/reset.css 472 B
build/block-library/theme-rtl.css 715 B
build/block-library/theme.css 719 B
build/block-serialization-default-parser/index.min.js 1.12 kB
build/block-serialization-spec-parser/index.min.js 2.87 kB
build/blocks/index.min.js 52.7 kB
build/commands/index.min.js 16.3 kB
build/commands/style-rtl.css 956 B
build/commands/style.css 953 B
build/components/index.min.js 252 kB
build/components/style-rtl.css 13.7 kB
build/components/style.css 13.7 kB
build/compose/index.min.js 12.8 kB
build/core-commands/index.min.js 3.58 kB
build/core-data/index.min.js 75.4 kB
build/customize-widgets/index.min.js 11 kB
build/customize-widgets/style-rtl.css 1.43 kB
build/customize-widgets/style.css 1.43 kB
build/data-controls/index.min.js 641 B
build/data/index.min.js 8.7 kB
build/date/index.min.js 18 kB
build/deprecated/index.min.js 458 B
build/dom-ready/index.min.js 325 B
build/dom/index.min.js 4.68 kB
build/edit-post/classic-rtl.css 577 B
build/edit-post/classic.css 578 B
build/edit-post/index.min.js 13.4 kB
build/edit-post/style-rtl.css 2.69 kB
build/edit-post/style.css 2.69 kB
build/edit-site/index.min.js 241 kB
build/edit-site/posts-rtl.css 9.35 kB
build/edit-site/posts.css 9.35 kB
build/edit-site/style-rtl.css 15.4 kB
build/edit-site/style.css 15.4 kB
build/edit-widgets/index.min.js 17.8 kB
build/edit-widgets/style-rtl.css 4.05 kB
build/edit-widgets/style.css 4.06 kB
build/editor/index.min.js 134 kB
build/editor/style-rtl.css 9.41 kB
build/editor/style.css 9.42 kB
build/element/index.min.js 4.86 kB
build/escape-html/index.min.js 537 B
build/format-library/index.min.js 8.23 kB
build/format-library/style-rtl.css 472 B
build/format-library/style.css 472 B
build/hooks/index.min.js 1.65 kB
build/html-entities/index.min.js 467 B
build/i18n/index.min.js 2.23 kB
build/is-shallow-equal/index.min.js 526 B
build/keyboard-shortcuts/index.min.js 1.32 kB
build/keycodes/index.min.js 1.46 kB
build/list-reusable-blocks/index.min.js 2.13 kB
build/list-reusable-blocks/style-rtl.css 847 B
build/list-reusable-blocks/style.css 848 B
build/media-utils/index.min.js 3.69 kB
build/notices/index.min.js 946 B
build/nux/index.min.js 1.62 kB
build/nux/style-rtl.css 767 B
build/nux/style.css 763 B
build/patterns/index.min.js 7.55 kB
build/patterns/style-rtl.css 687 B
build/patterns/style.css 685 B
build/plugins/index.min.js 1.87 kB
build/preferences-persistence/index.min.js 2.06 kB
build/preferences/index.min.js 2.9 kB
build/preferences/style-rtl.css 562 B
build/preferences/style.css 562 B
build/primitives/index.min.js 829 B
build/priority-queue/index.min.js 1.54 kB
build/private-apis/index.min.js 978 B
build/react-i18n/index.min.js 640 B
build/react-refresh-entry/index.min.js 9.47 kB
build/react-refresh-runtime/index.min.js 6.76 kB
build/redux-routine/index.min.js 2.7 kB
build/reusable-blocks/index.min.js 2.53 kB
build/reusable-blocks/style-rtl.css 255 B
build/reusable-blocks/style.css 255 B
build/rich-text/index.min.js 12.2 kB
build/router/index.min.js 5.47 kB
build/server-side-render/index.min.js 1.6 kB
build/shortcode/index.min.js 1.4 kB
build/style-engine/index.min.js 2.04 kB
build/token-list/index.min.js 581 B
build/url/index.min.js 3.97 kB
build/vendors/react-dom.min.js 41.7 kB
build/vendors/react-jsx-runtime.min.js 556 B
build/vendors/react.min.js 4.02 kB
build/viewport/index.min.js 965 B
build/vips/index.min.js 36.2 kB
build/warning/index.min.js 250 B
build/widgets/index.min.js 7.16 kB
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.04 kB

compressed-size-action

@t-hamano
Copy link
Contributor

Thanks for the PR!

My biggest concern is that the block is very fragile because the save function relies on the @wordpress/icons package. For example, try the following steps:

  • Check out this Branch and run the project in watch mode: gh pr checkout 71227 && npm run dev
  • Insert an Icon block
  • Click the Icon Library button
  • Select the "Arrow Down" icon
  • Save the post
  • Make some changes to the SVG path: packages/icons/src/library/arrow-down.tsx
  • Reload the browser
  • The block is broken

I don't have any good ideas right now, but I think you need to make it more robust, at least when it comes to the save function.

Another concern is that we might have too many features. These features might be useful in third-party plugins, but we're not sure if they're all necessary for core. Personally, I prefer to ship something small and robust first. After shipping, we can evaluate each feature and continue enhancing it.

@scruffian
Copy link
Contributor

I agree, that this does look a bit too fully featured for a first iteration. Would it be possible to slim it down to a more basic version?

Also I think once the icon is saved, we should break the connection to the library, so that if the library changes the save function doesn't throw an error.

@getdave
Copy link
Contributor

getdave commented Sep 10, 2025

My biggest concern is that the block is very fragile because the save function relies on the @wordpress/icons package.

I looked into this a bit.

The Error

Modifying icon files in packages/icons/src/library/ causes block validation errors on editor reload. Example:

Block validation: Block validation failed for `core/icon`
Content generated by `save` function: <svg viewBox="0 0 24 34">...
Content retrieved from post body: <svg viewBox="0 0 24 24">...

The reason this is a concern is that it's possible that icons in the package will receive design updates (tweaks) in future. This would cause errors as it stands meaning we need to address this prior to merge.

How Block Validation Works

When the editor loads, Gutenberg's block validation system:

  1. Retrieves saved content from the database (what was previously saved)
  2. Runs the save function with current block attributes to generate "expected" content
  3. Compares the two outputs - if they don't match exactly, validation fails

Root Cause

The icon block's save function dynamically fetches icons at runtime (line 71 in save.js):

printedIcon = namedIcon[ 0 ]?.icon; // Gets current icon from @wordpress/icons

The timeline:

  1. Save time: Block saves with icon from current built version of @wordpress/icons
  2. Icon modification: Developer changes source file and rebuilds packages
  3. Editor reload: Validation runs save function again, now getting the updated icon
  4. Mismatch: Saved content (old icon) ≠ newly generated content (new icon) → validation fails

Fix

We could try:

  • Storing the SVG and severing the relationship with the original icon source.
  • Hooking into block validation (is this possible?) and allowing the user to either click to update to the latest icon version, or persist the original version of the icon (thus severing the relationship).

Copy link
Contributor

@getdave getdave left a comment

Choose a reason for hiding this comment

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

If I were to slim this down I'd be looking at creating a version that just allows uploading custom SVG markup directly.

This can then be built upon to add the more advanced functionality in the current version.

@ryanwelcher Do you think you'd be open to doing that? Once the simple version is merged we can raise a followup in which we can look to resolve the issue with the icon picker.

@ryanwelcher
Copy link
Contributor Author

Thanks everyone for your feedback!

This is a pretty full-featured block and I agree that scaling it down might be the best solution - especially if we are aiming for it to be in 6.9.

If I were to slim this down I'd be looking at creating a version that just allows uploading custom SVG markup directly.

My only concern with this is that is requires the user to have access to a list of SVG markup making this block not very useful to those that don't or don't know what SVG markup is. It seems to me that this block needs to provide some default icons.

Would it be possible to slim it down to a more basic version?

I think that the most basic version of this a predefined list of icons that the user can choose from (along with some filters for extenders to introduce more) and the ability to upload markup.

It seems like the best path forward (this is strong opinion, not strongly held) is to fix the issue with changes to the existing icons as providing those icons would be the most MVP that we can get. I am 1000% open to suggestions/comments or people just not liking this approach :)

@ryanwelcher
Copy link
Contributor Author

ryanwelcher commented Sep 10, 2025

Digging into this a little further and it might make sense for an MVP to follow the prior art of the Social Link block. It's a dynamic block that stores the SVGs in PHP as well as in JavaScript.

This does introduce the burden of SVG duplication but as we're starting with a subset of the @wordpress/icons library as the provided icons, perhaps we don't need to be so worried about matching changes 1:1. As a follow up, it might be a good idea to create some kind tool/script that can automate this process.

Proposed Changes:

  • Convert the block to render dynamically to remove any issue with block validation errors.
  • Create PHP array of SVGs to be used by the block on the front end

@getdave
Copy link
Contributor

getdave commented Sep 11, 2025

Thanks for picking this up again.

This does introduce the burden of SVG duplication

Yes it does. I wonder if we could update the @wordpress/icons package to have the icons in PHP as well as in JavaScript. We could then have some (ideally reusable) tooling which converts the canonical source of the icon into the other export format. That way we can consume the icons in JS and PHP which seems to be a requirement.

I suspect that "icon packs" will need the same thing in future (i.e. exposing as JS and PHP).

Do we know who is responsible for maintaining @wordpress/icons? We should ask them for feedback before shipping this.

As a follow up, it might be a good idea to create some kind tool/script that can automate this process.

I think this is a must have so as not to have these icons get outdated over time.

@ryanwelcher
Copy link
Contributor Author

ryanwelcher commented Sep 11, 2025

@getdave I was able to sever the connection between the icons and the library after the block is saved. This means that the icon is saved as is and any changes to the associated icon will not trigger a block validation error and display the icon that was saved in the edit.

I think we can move forward with keeping the block static.

@silaskoehler
Copy link

I’m not sure if this is relevant for the MVP of this block, but when I used Nick’s block in the past and extended it with filters to use the Phosphoricons (an icon pack with around 1500 icons), I experienced performance issues in the editor because all icons were loaded through the large JS file and are all loaded at once.

Would it be possible to load the icons via an endpoint instead, so that not all icons are loaded at once? This would also make it easier to extend the list of icons later.

Does that make sense?

@t-hamano
Copy link
Contributor

Would it be possible to load the icons via an endpoint instead, so that not all icons are loaded at once? This would also make it easier to extend the list of icons later.

This makes sense to me.

Furthermore, and this is just a thought, I wonder if the design approach used in block patterns can be applied to icons as well.

  • Create a single global instance of the WP_Icons_Registry class to manage icons:
    • When wp_register_icon() is executed,, icons are registered in that instance. These icons are stored in memory.
    • Registered icons can be retrieved with code like this: WP_Icons_Registry::get_instance();->get_registered( 'icon-name' );
  • Icons as a post type
    • Create a built-in post type with the slug wp_icon.
    • The SVG data is saved in the post content.
    • All icons, including those registered by users, can be retrieved with code like this: WP_Block_Patterns_Registry::get_instance()->get_all_registered();
  • REST API
    • Expose all icons registered by wp_register_icon() and users under the wp/v2/icons endpoint
  • Icon Block
    • Access the wp/v2/icons endpoint to get available icons.
    • The icon slug is saved as an attribute. The SVG data itself is not saved in the block.
    • During server-side rendering, if an icon with a slug matching the attribute value is found in the WP_Icons_Registry instance, it will be used to render the post content (SVG).

@silaskoehler
Copy link

I also noticed that the outermost prefix is still frequently used, e.g., as ClassName “wp-block-outermost-icon-block.” Should it be called “wp-block-icon-block” instead?

@benoitchantre
Copy link
Contributor

What do you think to add a way to change the tagName (div as default value and button as an alternate choice)?

@ryanwelcher
Copy link
Contributor Author

Furthermore, and this is just a thought, I wonder if the design approach used in block patterns can be applied to icons as well.

  • Create a single global instance of the WP_Icons_Registry class to manage icons:

    • When wp_register_icon() is executed,, icons are registered in that instance. These icons are stored in memory.
    • Registered icons can be retrieved with code like this: WP_Icons_Registry::get_instance();->get_registered( 'icon-name' );
  • Icons as a post type

    • Create a built-in post type with the slug wp_icon.
    • The SVG data is saved in the post content.
    • All icons, including those registered by users, can be retrieved with code like this: WP_Block_Patterns_Registry::get_instance()->get_all_registered();
  • REST API

    • Expose all icons registered by wp_register_icon() and users under the wp/v2/icons endpoint
  • Icon Block

    • Access the wp/v2/icons endpoint to get available icons.
    • The icon slug is saved as an attribute. The SVG data itself is not saved in the block.
    • During server-side rendering, if an icon with a slug matching the attribute value is found in the WP_Icons_Registry instance, it will be used to render the post content (SVG).

This is a great outline on how to approach managing the icons but I would say that it's most likely not attainable for the MVP hoping to be shipped in 6.9. I would advocate for getting the block to a place where it can be included and then starting on how to manage the icons.

To that end, @t-hamano, @scruffian, and @getdave have all mentioned that the block is too full-featured for an MVP. I would like to understand what we think needs to be removed before this can considered ready?

@t-hamano
Copy link
Contributor

t-hamano commented Sep 18, 2025

To ensure the Icon Block seamlessly integrates with future infrastructure, here are my personal thoughts. Please let me know what you think!

  • Extract a minimal set of icons from the @wordpress/icons package and hard-code them as SVG data in both JS and PHP. Each icon has a core/ prefix. Example: core/arrow-down
  • The Icon Block references this icon list. Instead of saving the raw SVG data, save the icon slug as an attribute.
  • Server-side rendering finds the actual SVG data from the icon slug and renders it.
  • Audit the must-to-have attributes. Personally, I think that the width, height, and link settings is sufficient for the initial implementation.
  • Remove the SVG upload and custom icon creation features. To help users understand and edit SVGs, more discussion may be needed from a design and accessibility perspective.

@ryanwelcher
Copy link
Contributor Author

  • Extract a minimal set of icons from the @wordpress/icons package and hard-code them as SVG data in both JS and PHP. Each icon has a core/ prefix. Example: core/arrow-down
  • The Icon Block references this icon list. Instead of saving the raw SVG data, save the icon slug as an attribute.
  • Server-side rendering finds the actual SVG data from the icon slug and renders it.

This does mean that we'll need to convert the block from static to dynamic. I was able to disconnect the save from the list of icons but perhaps the dynamic approach is more scalable?

  • Audit the must-to-have attributes. Personally, I think that the width, height, and link settings is sufficient for the initial implementation.
  • Remove the SVG upload and custom icon creation features. To help users understand and edit SVGs, more discussion may be needed from a design and accessibility perspective.

Great ideas overall, I can start implementing this today.

@t-hamano
Copy link
Contributor

This does mean that we'll need to convert the block from static to dynamic. I was able to disconnect the save from the list of icons but perhaps the dynamic approach is more scalable?

If we consider icon SVG data as content, it would be best to store it in the database, i.e. as a static block. However, to my knowledge, there is currently no way to build it as a static block without destroying the block 🤔

@ryanwelcher
Copy link
Contributor Author

If we consider icon SVG data as content, it would be best to store it in the database, i.e. as a static block. However, to my knowledge, there is currently no way to build it as a static block without destroying the block 🤔

I was able to get this working as a static block by disconnecting the icon from the save. I'll work on the other items and we can take another look at this after.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
New Block Suggestion for a new block [Package] Blocks /packages/blocks
Projects
Status: 🔎 Needs Review
Development

Successfully merging this pull request may close these issues.

Add an Icons block
9 participants