IconLibrary

Temporary component. WordPress 7.1 ships an icon library with the core/icon block, but the picker
component behind it is not exported from @wordpress/block-editor. IconLibraryModal is a thin
reimplementation on top of the public root/icon and root/iconCollection core-data entities, and should
be dropped as soon as core exports a picker of its own.

link You probably do not need this directly

IconSelector and BlockIconSelector are
the components blocks use. Both open this modal, so there is one picker on every WordPress version:

Either way the icons are shown in a full screen grid rather than inline, so the control costs a single row of
sidebar space no matter how many icons a project ships.

link Icon names

The core library stores a fully qualified name such as "core/person", where IconSelector used to store
a bare T2 id such as "person".

Both forms keep working. T2's own icons are registered with core as the t2 collection, so "person" and
"t2/person" resolve to the same icon, and toCoreIconName() maps between them. Existing content needs no
migration.

Render either form on the front end with T2\Icons\get_icon(), which delegates namespaced names to
wp_get_icon():

echo get_icon( $attributes['icon'], 24 );

link Example

import { IconSelector } from '@t2/editor';
import { InspectorControls } from '@wordpress/block-editor';
import { PanelBody } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

export default function Edit({ attributes: { icon }, setAttributes }) {
	return (
		<InspectorControls>
			<PanelBody title={__('Icon', 't2')}>
				<IconSelector
					selected={icon}
					label={__('Select Icon', 't2')}
					onSelect={(value) => setAttributes({ icon: value })}
				/>
			</PanelBody>
		</InspectorControls>
	);
}

link Styling

The library modal uses core's wp-block-icon__* class names and DOM structure, but it cannot rely on core's
stylesheet: those styles ship with the core/icon block, which only exists on WordPress 7.1 and later, so the
modal would be unstyled on older versions. Core's rules are mirrored in style.css with the
@wordpress/base-styles variables resolved, scoped under .t2-editor-icon-library so they cannot reach core's
own icon library — and so they win on specificity where both are present, keeping the result identical on every
version.

Keep the two in sync with
packages/block-library/src/icon/editor.scss
while this component exists.

Two deliberate departures from core's implementation:

link Components

Export Description
IconLibraryModal The full screen icon library modal.

Icons are rendered with Icon, which resolves both a bare T2 id and a namespaced name.

link Hooks

Export Description
useHasCoreIconLibrary() true when running on WordPress 7.1 or later.
useCoreIcon(name) A single icon record, or null.
useCoreIcons(collection, allowedIcons) { icons, hasResolved } for one collection, or all collections.
useIconRecords(collection, allowedIcons) { icons, hasResolved } from whichever registry is available.
useIconCollections(allowedCollections) The collections to offer, empty on the T2 registry.
useT2IconRecords(allowedIcons) The T2 icon registry as library records.
getIconLabel(id) Humanises a T2 id — arrowBack becomes "Arrow back". Mirrors the PHP.
isCoreIconName(name) true for a namespaced name such as core/person.
toCoreIconName(name) Maps a T2 id to its core name — arrowBack becomes t2/arrow-back.

link Component Props

export type CoreIconQueryProps = {
	/** Limit the library to these fully qualified icon names, i.e. `['core/star-filled']`. */
	allowedIcons?: string[];

	/** Limit the library to these collection slugs, i.e. `['core']`. */
	allowedCollections?: string[];
};

export type CoreIconSelectorProps = CoreIconQueryProps & {
	/** The icon size in px used for the preview. */
	iconSize?: number;

	/** The component label. */
	label?: string;

	/** Additional help text for the component. */
	help?: string;

	/** Callback returning the selected icon name when the author selects an icon. */
	onSelect?: (selected: string | undefined) => void;

	/** The currently selected fully qualified icon name. */
	selected?: string;
};

export type BlockCoreIconSelectorProps = CoreIconQueryProps & {
	/** The icon size in px. */
	iconSize?: number;

	/** Whether to render a plain, inline toggle instead of a toolbar button. */
	inline?: boolean;

	/** The component label. */
	label?: string;

	/** Callback returning the selected icon name when the author selects an icon. */
	onSelect?: (selected: string | undefined) => void;

	/** The currently selected fully qualified icon name. */
	selected?: string;
};