Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions packages/block-library/src/icon/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ import HtmlRenderer from '../utils/html-renderer';
import { CustomInserterModal } from './components';
import { unlock } from '../lock-unlock';

const EMPTY_ARRAY = [];

const IconPlaceholder = ( { className, style } ) => (
<SVG
xmlns="http://www.w3.org/2000/svg"
Expand Down Expand Up @@ -70,14 +72,18 @@ export function Edit( { attributes, setAttributes } ) {
const borderProps = useBorderProps( attributes );
const dimensionsProps = useDimensionsProps( attributes );

const allIcons = useSelect( ( select ) => {
return unlock( select( coreDataStore ) ).getIcons();
}, [] );
const { selectedIcon, allIcons } = useSelect(
( select ) => {
const { getIcon, getIcons } = unlock( select( coreDataStore ) );
return {
selectedIcon: icon ? getIcon( icon ) : null,
allIcons: isInserterOpen ? getIcons() : EMPTY_ARRAY,
};
},
[ icon, isInserterOpen ]
);

const iconToDisplay =
allIcons?.length > 0
? allIcons?.find( ( { name } ) => name === icon )?.content
: '';
const iconToDisplay = selectedIcon?.content ?? '';

const blockControls = (
<>
Expand Down
2 changes: 1 addition & 1 deletion packages/core-data/src/private-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ export function receiveEditorAssets( assets ) {
}

/**
* Returns an action object used to receive icons.
* Returns an action object used to receive all available icons.
*
* @param {Array} icons List of icons.
*
Expand Down
26 changes: 23 additions & 3 deletions packages/core-data/src/private-selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import logEntityDeprecation from './utils/log-entity-deprecation';

type EntityRecordKey = string | number;

const EMPTY_ARRAY = [] as [];

/**
* Returns the previous edit from the current undo offset
* for the entity records edits history, if any.
Expand Down Expand Up @@ -311,11 +313,29 @@ export function getEditorAssets( state: State ): Record< string, any > | null {
}

/**
* Returns the list of available icons.
* Returns the list of all available icons.
*
* @param state Data state.
* @return The list of icons or empty array if not loaded.
*/
export function getIcons( state: State ): Icon[] {
return state.icons ?? [];
export const getIcons = createSelector(
( state: State ): Icon[] => {
const icons = state.icons;
if ( ! icons || Object.keys( icons ).length === 0 ) {
return EMPTY_ARRAY;
}
return Object.values( icons );
},
( state: State ) => [ state.icons ]
);

/**
* Returns a single icon by name.
*
* @param state Data state.
* @param name Icon name (e.g. 'core/arrow-left').
* @return The icon object or undefined if not loaded.
*/
export function getIcon( state: State, name: string ): Icon | undefined {
return state.icons?.[ name ];
}
18 changes: 13 additions & 5 deletions packages/core-data/src/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -663,15 +663,23 @@ export function editorAssets( state = null, action ) {
/**
* Reducer managing icons.
*
* @param {Array} state Current state.
* @param {Object} state Current state (keyed by icon name).
* @param {Object} action Action object.
*
* @return {Array} Updated state.
* @return {Object} Updated state.
*/
export function icons( state = [], action ) {
export function icons( state = {}, action ) {
switch ( action.type ) {
case 'RECEIVE_ICONS':
return action.icons;
case 'RECEIVE_ICONS': {
if ( ! action.icons?.length ) {
return state;
}
const next = { ...state };
for ( const icon of action.icons ) {
next[ icon.name ] = icon;
}
return next;
}
Comment on lines 673 to 682
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we should we return prev state early in action.icons is empty.

}
return state;
}
Expand Down
16 changes: 15 additions & 1 deletion packages/core-data/src/resolvers.js
Original file line number Diff line number Diff line change
Expand Up @@ -1257,7 +1257,7 @@ export const getEditorAssets =
};

/**
* Requests icons from the REST API.
* Requests all available icons from the REST API.
*/
export const getIcons =
() =>
Expand All @@ -1267,3 +1267,17 @@ export const getIcons =
} );
dispatch.receiveIcons( icons );
};

/**
* Requests a single icon by name from the REST API.
*
* @param {string} iconName Icon name (e.g. 'core/arrow-left').
*/
export const getIcon =
( iconName ) =>
async ( { dispatch } ) => {
const icon = await apiFetch( {
path: `/wp/v2/icons/${ iconName }`,
} );
dispatch.receiveIcons( [ icon ] );
};
2 changes: 1 addition & 1 deletion packages/core-data/src/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export interface State {
registeredPostMeta: Record< string, Object >;
editorSettings: Record< string, any > | null;
editorAssets: Record< string, any > | null;
icons: Icon[];
icons: Record< string, Icon >;
syncConnectionStatuses?: Record< string, ConnectionStatus >;
}

Expand Down
Loading