Skip to content

Conversation

@t-hamano
Copy link
Contributor

@t-hamano t-hamano commented Oct 4, 2025

Related:

This is a test PR to verify the construction of the infrastructure for icon registration.

WP_Icons_Registry

This class is very similar to WP_Block_Patterns_Registry. For now, I registered all SVG icons that exist in @wordpress/icons package.

Consumers can also register custom SVG icons like this:

$registry = WP_Icons_Registry::get_instance();
$registry->register(
	'my-custom-icon',
	array(
		'title'   => 'Custom Icon',
		'content' => '<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><circle cx="12" cy="12" r="10"/></svg>',
	)
);

Although not implemented in this PR, we might expose a utility function like the following:

wp_register_icon(
	'my-custom-icon',
	array(
		'title'   => 'Custom Icon',
		'content' => '<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><circle cx="12" cy="12" r="10"/></svg>',
	)
);

WP_REST_Icons_Controller

Expose a list of icons registered via the icon registry.

Icon block

This is a block to test that the above two classes work and that the icon list can be referenced.

image

@t-hamano t-hamano mentioned this pull request Oct 4, 2025
2 tasks
@github-actions
Copy link

github-actions bot commented Oct 4, 2025

Size Change: +210 B (+0.01%)

Total Size: 2.03 MB

Filename Size Change
build/block-library/index.min.js 240 kB +182 B (+0.08%)
build/core-data/index.min.js 75.6 kB +28 B (+0.04%)
ℹ️ View Unchanged
Filename Size
build-module/a11y/index.min.js 355 B
build-module/block-editor/utils/fit-text-frontend.min.js 545 B
build-module/block-library/accordion/view.min.js 656 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 451 B
build-module/interactivity-router/index.min.js 11.5 kB
build-module/interactivity/debug.min.js 18.4 kB
build-module/interactivity/index.min.js 14.8 kB
build/a11y/index.min.js 1.06 kB
build/annotations/index.min.js 2.13 kB
build/api-fetch/index.min.js 2.83 kB
build/autop/index.min.js 2.19 kB
build/blob/index.min.js 631 B
build/block-directory/index.min.js 7.18 kB
build/block-directory/style-rtl.css 1.04 kB
build/block-directory/style.css 1.05 kB
build/block-editor/content-rtl.css 4.51 kB
build/block-editor/content.css 4.5 kB
build/block-editor/default-editor-styles-rtl.css 411 B
build/block-editor/default-editor-styles.css 411 B
build/block-editor/index.min.js 272 kB
build/block-editor/style-rtl.css 15.9 kB
build/block-editor/style.css 15.8 kB
build/block-library/blocks/accordion-heading/style-rtl.css 340 B
build/block-library/blocks/accordion-heading/style.css 340 B
build/block-library/blocks/accordion-item/style-rtl.css 213 B
build/block-library/blocks/accordion-item/style.css 213 B
build/block-library/blocks/accordion-panel/style-rtl.css 99 B
build/block-library/blocks/accordion-panel/style.css 99 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/breadcrumbs/style-rtl.css 203 B
build/block-library/blocks/breadcrumbs/style.css 203 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.11 kB
build/block-library/common.css 1.11 kB
build/block-library/editor-elements-rtl.css 75 B
build/block-library/editor-elements.css 75 B
build/block-library/editor-rtl.css 11.5 kB
build/block-library/editor.css 11.5 kB
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/style-rtl.css 15.5 kB
build/block-library/style.css 15.5 kB
build/block-library/theme-rtl.css 715 B
build/block-library/theme.css 719 B
build/block-serialization-default-parser/index.min.js 1.16 kB
build/block-serialization-spec-parser/index.min.js 2.87 kB
build/blocks/index.min.js 52.9 kB
build/commands/index.min.js 16.3 kB
build/commands/style-rtl.css 997 B
build/commands/style.css 998 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/customize-widgets/index.min.js 11 kB
build/customize-widgets/style-rtl.css 1.44 kB
build/customize-widgets/style.css 1.44 kB
build/data-controls/index.min.js 641 B
build/data/index.min.js 8.7 kB
build/date/index.min.js 23.6 kB
build/deprecated/index.min.js 755 B
build/dom-ready/index.min.js 476 B
build/dom/index.min.js 4.89 kB
build/edit-post/classic-rtl.css 590 B
build/edit-post/classic.css 591 B
build/edit-post/index.min.js 14 kB
build/edit-post/style-rtl.css 3.04 kB
build/edit-post/style.css 3.04 kB
build/edit-site/index.min.js 243 kB
build/edit-site/posts-rtl.css 9.46 kB
build/edit-site/posts.css 9.45 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.3 kB
build/edit-widgets/style.css 4.3 kB
build/editor/index.min.js 139 kB
build/editor/style-rtl.css 9.86 kB
build/editor/style.css 9.86 kB
build/element/index.min.js 5.19 kB
build/escape-html/index.min.js 586 B
build/format-library/index.min.js 8.63 kB
build/format-library/style-rtl.css 490 B
build/format-library/style.css 490 B
build/hooks/index.min.js 1.83 kB
build/html-entities/index.min.js 494 B
build/i18n/index.min.js 2.46 kB
build/is-shallow-equal/index.min.js 568 B
build/keyboard-shortcuts/index.min.js 1.32 kB
build/keycodes/index.min.js 1.53 kB
build/list-reusable-blocks/index.min.js 2.13 kB
build/list-reusable-blocks/style-rtl.css 867 B
build/list-reusable-blocks/style.css 868 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 783 B
build/nux/style.css 780 B
build/patterns/index.min.js 7.55 kB
build/patterns/style-rtl.css 703 B
build/patterns/style.css 703 B
build/plugins/index.min.js 1.87 kB
build/preferences-persistence/index.min.js 2.15 kB
build/preferences/index.min.js 2.89 kB
build/preferences/style-rtl.css 582 B
build/preferences/style.css 582 B
build/primitives/index.min.js 829 B
build/priority-queue/index.min.js 1.61 kB
build/private-apis/index.min.js 1.09 kB
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 3.36 kB
build/reusable-blocks/index.min.js 2.53 kB
build/reusable-blocks/style-rtl.css 273 B
build/reusable-blocks/style.css 273 B
build/rich-text/index.min.js 12.2 kB
build/router/index.min.js 5.58 kB
build/server-side-render/index.min.js 1.6 kB
build/shortcode/index.min.js 1.58 kB
build/style-engine/index.min.js 2.32 kB
build/sync/index.min.js 57.4 kB
build/token-list/index.min.js 740 B
build/undo-manager/index.min.js 915 B
build/url/index.min.js 3.98 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 481 B
build/widgets/index.min.js 7.17 kB
build/widgets/style-rtl.css 1.17 kB
build/widgets/style.css 1.17 kB
build/wordcount/index.min.js 1.04 kB

compressed-size-action

@t-hamano t-hamano added the [Type] Experimental Experimental feature or API. label Oct 4, 2025
@t-hamano t-hamano self-assigned this Oct 5, 2025
@mcsf
Copy link
Contributor

mcsf commented Oct 7, 2025

Thanks so much for getting this going, @t-hamano!

Have you given any thought to how to integrate icons' ReactElement counterparts in this scenario?

@t-hamano
Copy link
Contributor Author

t-hamano commented Oct 7, 2025

Have you given any thought to how to integrate icons' ReactElement counterparts in this scenario?

I have no ideas right now, but does this mean that we should allow icon registration on the client side as well? Example:

registerIcon( {
	title: 'Close',
	name: 'core/close',
	icon: () => (
		<SVG xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
			<Path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" />
		</SVG>
	),
} );

@mcsf
Copy link
Contributor

mcsf commented Oct 7, 2025

I have no ideas right now, but does this mean that we should allow icon registration on the client side as well? Example:

I wasn't really concerned with client-side registration. In my mind it was more about registering both the SVG source path and the TSX build JS one, so that in the editor we could render proper React elements (no dangerouslySetInnerHTML), but on the front end we could interpolate SVGs:

// pseudocode in the editor
const { slug } = props
const iconData = await fetch( `/wp/v2/icons/${ slug }` )
const Icon = await import( iconData.reactSrc )
return <Icon />
// pseudocode in render_callback
$content = WP_Icons_Registry::get_instance()->get_registered( $slug )['content']
return $content

Maybe this is an opportunity for Import Maps, maybe not. I'm not sure. Does this sound silly?

@t-hamano
Copy link
Contributor Author

t-hamano commented Oct 7, 2025

I might not understand it exactly, but it seems like a very interesting approach. If you have concrete code, please feel free to push it to this branch. I consider this PR a playground.

@t-hamano
Copy link
Contributor Author

t-hamano commented Oct 8, 2025

registering both the SVG source path and the TSX build JS one, so that in the editor we could render proper React elements (no dangerouslySetInnerHTML)

So, when a consumer registers an SVG icon string via PHP, does that mean that a React component file will also be automatically generated at the same time? If we expose @wordpress/icons by default, it's fine because the JS files are already generated based on the SVG file, but this is not the case for icons registered by users 🤔

Also, if we adopt your approach, the icon block will be dynamic, meaning it will only store the slug as an attribute, right?

@mcsf
Copy link
Contributor

mcsf commented Oct 8, 2025

I'll start with the last bit, because it's the one I'm most confident about:

Also, if we adopt your approach, the icon block will be dynamic, meaning it will only store the slug as an attribute, right?

Yes, at least that's how I see the Icon block. At least when the user selects an icon from a collection. But, when providing a custom icon via the block interface, maybe it's static.

So, when a consumer registers an SVG icon string via PHP, does that mean that a React component file will also be automatically generated at the same time? If we expose @wordpress/icons by default, it's fine because the JS files are already generated based on the SVG file, but this is not the case for icons registered by users 🤔

Note that I too am very unsure of all this. :) This idea that icons could exist in a pair of SVG+ReactElement came from the original use case of the Icons package: to provide core icons for all our screens, and to remain "bundle-able" in a React project.

This also started from a performance concern. Right now, the icons package is adequate for projects that use a limited set of statically imported icons, so that bundling can be done efficiently. But we'd like to avoid bundling the entire package in block-library just because of one block type that may or may not ever need to display them to the user. And then we'd want to open this up to third parties.

Also thinking of performance, maybe the fetching doesn't need to happen for individual icons, but by collection (where a collection often corresponds to a vendor/plugin). So, when the user edits an Icon block, we should be able to dynamically load n collections to display their icons in a grid.

@t-hamano
Copy link
Contributor Author

t-hamano commented Oct 8, 2025

If we expose @wordpress/icons by default, it's fine because the JS files are already generated based on the SVG file, but this is not the case for icons registered by users 🤔

I came up with the following concept, what do you think?

First, add a tool to the @wordpress/icons package to generate react components from SVG files:

npx @wordpress/icons wp-icons-generate --dir ./icons

Developers using this tool can provide the path to the script file when registering the icon, as shown below:

$icons_directory = plugin_dir_path( __FILE__ ) . '/icons/';
$svg_files       = glob( $icons_directory . '*.svg' );

foreach ( $svg_files as $svg_file ) {
	$icon_slug        = basename( $svg_file, '.svg' );
	$svg_content      = file_get_contents( $svg_file );
	$script_file_path = plugin_dir_path( __FILE__ ) . 'icons/' . $icon_slug . '.js';

	$registry->register(
		'my-plugin/' . $icon_slug,
		array(
			'svg'            => $svg_content,
			'scriptFilePath' => $script_file_path,
		)
	);
}

@mcsf
Copy link
Contributor

mcsf commented Oct 8, 2025

@t-hamano: that could work!

That said... 😬 I feel like I've wasted your time today: I had a fresh look at this and had a nice conversation with @ellatrix, and now I believe that your approach with SVGs should be more than enough, and that trying to expose and import React elements is a big unnecessary complication.

  • The endpoint right now returns the entire collection of registered icons with the SVG source inlined for each icon. That makes for a large-ish response, but it's a single request to make inside the editor ✅
  • If we add a couple of things to the endpoint, like:
    • _fields support
    • a new property src (alongside content)
    • search/filtering support (e.g. to filter by namespace/collection)
    • a single-item route (.../(?<icon_name>...))
  • => then we should have all the pieces in place for performant single-item fetching, for batch-fetching, etc.

The only other thing to consider is: should we keep icon registration closed to third parties for WP 6.9? I think so, so that we can more confidently try this out for core icons first. If you agree, do you have any ideas for limiting registration (other than simply annotating the function with @private, etc.)?

@mcsf
Copy link
Contributor

mcsf commented Oct 8, 2025

Riad also relayed this note:

the only thing I'm uncertain about is whether the svg itself should be returned by the endpoint or not

I think an optimization could be to not return the svg in the endpoint but load them in a url like

<embed src="https://wordpress.site/load-svg.php?set=wordpress/icons&svg=add" type="image/svg+xml" />

But this is something that we can explore separately. Also cc @sgomes, who might be interested in the performance aspect. :)

@t-hamano
Copy link
Contributor Author

t-hamano commented Oct 9, 2025

The only other thing to consider is: should we keep icon registration closed to third parties for WP 6.9? I think so, so that we can more confidently try this out for core icons first. If you agree, do you have any ideas for limiting registration (other than simply annotating the function with @private, etc.)?

We may be able to make the register method itself private. For exanple:

<?php
final class WP_Icons_Registry {
	public function __construct() {
		$this->initialize_core_icons();
	}

	private function register( $icon_name, $icon_properties ) {
		// ...
	}

	private function initialize_core_icons() {
		$icons_directory = __DIR__ . '/../../packages/icons/src/library/';
		$svg_files       = glob( $icons_directory . '*.svg' );
		foreach ( $svg_files as $svg_file ) {
			$this->register(
				// ...
			);
		}
	}
}

@mcsf
Copy link
Contributor

mcsf commented Oct 9, 2025

Yes, that's exactly what I had in mind. So, overall, you agree with the plan? What do you think about the possible endpoint improvements?

@t-hamano
Copy link
Contributor Author

t-hamano commented Oct 9, 2025

you agree with the plan?

I fully support the plan, but I'm not sure we can implement it in 6.9 release 😅

What do you think about the possible endpoint improvements?

I need help implementing the endpoints, as I may not fully understand them yet.

Looking further into the future, I imagine the basic implementation for the icon API will be almost identical to the block pattern. That is,

  • New wp_icon post type
  • User-uploaded icons are recorded as post content
  • Icon categories (WP_Block_Patterns_Registry)
  • Both user-uploaded icons and core icons are exposed to the REST API.

@mcsf
Copy link
Contributor

mcsf commented Oct 9, 2025

So, it's quite close for 6.9, but we can definitely strive for an MVP there. Our requirements are lower:

  • (endpoint) Ability to retrieve all registered icons (core-only for now), with their source included, to display them in a grid
  • (endpoint) Ability to retrieve a single registered icon, source included, to display in the canvas
  • (registry) Ability to internally access the registry so that render_callback can inject the SVG in the front end

That should be enough for the Icon block to support:

  • Registered core icons (via those interfaces)
  • User-uploaded icons (as static content)

@t-hamano
Copy link
Contributor Author

t-hamano commented Oct 9, 2025

Ok, I'll try to implement it tomorrow in a separate PR.

@mcsf
Copy link
Contributor

mcsf commented Oct 9, 2025

@t-hamano: Just pushed 0a91fd0, I think it's small enough. :)

@t-hamano t-hamano closed this Oct 9, 2025
@t-hamano
Copy link
Contributor Author

t-hamano commented Oct 9, 2025

@mcsf, I've submitted a new PR that addresses core compatibility, and your commit is included there. The basic implementation should be complete.

#72215

I'll provide a detailed PR summary tomorrow.

@mcsf
Copy link
Contributor

mcsf commented Oct 9, 2025

@t-hamano: wonderful! I'll have a look.

@github-actions
Copy link

github-actions bot commented Oct 9, 2025

Flaky tests detected in 0a91fd0.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/18378329335
📝 Reported issues:

@t-hamano t-hamano mentioned this pull request Oct 9, 2025
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Type] Experimental Experimental feature or API.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants