diff --git a/packages/block-library/src/social-link/edit.js b/packages/block-library/src/social-link/edit.js index 110bc39713699..0def10fa2a752 100644 --- a/packages/block-library/src/social-link/edit.js +++ b/packages/block-library/src/social-link/edit.js @@ -7,7 +7,7 @@ import classNames from 'classnames'; * WordPress dependencies */ import { DELETE, BACKSPACE } from '@wordpress/keycodes'; -import { useDispatch } from '@wordpress/data'; +import { useDispatch, useSelect } from '@wordpress/data'; import { InspectorControls, @@ -22,14 +22,16 @@ import { PanelBody, PanelRow, TextControl, + Icon, } from '@wordpress/components'; import { __, sprintf } from '@wordpress/i18n'; import { keyboardReturn } from '@wordpress/icons'; +import { store as blocksStore } from '@wordpress/blocks'; /** * Internal dependencies */ -import { getIconBySite, getNameBySite } from './social-list'; +import { getSocialService } from './social-list'; const SocialLinkURLPopover = ( { url, @@ -111,8 +113,18 @@ const SocialLinkEdit = ( { // re-renders when the popover's anchor updates. const [ popoverAnchor, setPopoverAnchor ] = useState( null ); - const IconComponent = getIconBySite( service ); - const socialLinkName = getNameBySite( service ); + const activeVariation = useSelect( + ( select ) => { + return select( blocksStore ).getActiveBlockVariation( + 'core/social-link', + attributes + ); + }, + [ attributes ] + ); + + const { icon, label: socialLinkName } = getSocialService( activeVariation ); + const socialLinkLabel = label ?? socialLinkName; const blockProps = useBlockProps( { className: classes, @@ -162,7 +174,7 @@ const SocialLinkEdit = ( { ref={ setPopoverAnchor } onClick={ () => setPopover( true ) } > - + array( - 'name' => '500px', - 'icon' => '', - ), - 'amazon' => array( - 'name' => 'Amazon', - 'icon' => '', - ), - 'bandcamp' => array( - 'name' => 'Bandcamp', - 'icon' => '', - ), - 'behance' => array( - 'name' => 'Behance', - 'icon' => '', - ), - 'chain' => array( - 'name' => 'Link', - 'icon' => '', - ), - 'codepen' => array( - 'name' => 'CodePen', - 'icon' => '', - ), - 'deviantart' => array( - 'name' => 'DeviantArt', - 'icon' => '', - ), - 'dribbble' => array( - 'name' => 'Dribbble', - 'icon' => '', - ), - 'dropbox' => array( - 'name' => 'Dropbox', - 'icon' => '', - ), - 'etsy' => array( - 'name' => 'Etsy', - 'icon' => '', - ), - 'facebook' => array( - 'name' => 'Facebook', - 'icon' => '', - ), - 'feed' => array( - 'name' => 'RSS Feed', - 'icon' => '', - ), - 'flickr' => array( - 'name' => 'Flickr', - 'icon' => '', - ), - 'foursquare' => array( - 'name' => 'Foursquare', - 'icon' => '', - ), - 'goodreads' => array( - 'name' => 'Goodreads', - 'icon' => '', - ), - 'google' => array( - 'name' => 'Google', - 'icon' => '', - ), - 'github' => array( - 'name' => 'GitHub', - 'icon' => '', - ), - 'gravatar' => array( - 'name' => 'Gravatar', - 'icon' => '', - ), - 'instagram' => array( - 'name' => 'Instagram', - 'icon' => '', - ), - 'lastfm' => array( - 'name' => 'Last.fm', - 'icon' => '', - ), - 'linkedin' => array( - 'name' => 'LinkedIn', - 'icon' => '', - ), - 'mail' => array( - 'name' => 'Mail', - 'icon' => '', - ), - 'mastodon' => array( - 'name' => 'Mastodon', - 'icon' => '', - ), - 'meetup' => array( - 'name' => 'Meetup', - 'icon' => '', - ), - 'medium' => array( - 'name' => 'Medium', - 'icon' => '', - ), - 'patreon' => array( - 'name' => 'Patreon', - 'icon' => '', - ), - 'pinterest' => array( - 'name' => 'Pinterest', - 'icon' => '', - ), - 'pocket' => array( - 'name' => 'Pocket', - 'icon' => '', - ), - 'reddit' => array( - 'name' => 'Reddit', - 'icon' => '', - ), - 'share' => array( - 'name' => 'Share Icon', - 'icon' => '', - ), - 'skype' => array( - 'name' => 'Skype', - 'icon' => '', - ), - 'snapchat' => array( - 'name' => 'Snapchat', - 'icon' => '', - ), - 'soundcloud' => array( - 'name' => 'Soundcloud', - 'icon' => '', - ), - 'spotify' => array( - 'name' => 'Spotify', - 'icon' => '', - ), - 'telegram' => array( - 'name' => 'Telegram', - 'icon' => '', - ), - 'threads' => array( - 'name' => 'Threads', - 'icon' => '', - ), - 'tiktok' => array( - 'name' => 'TikTok', - 'icon' => '', - ), - 'tumblr' => array( - 'name' => 'Tumblr', - 'icon' => '', - ), - 'twitch' => array( - 'name' => 'Twitch', - 'icon' => '', - ), - 'twitter' => array( - 'name' => 'Twitter', - 'icon' => '', - ), - 'vimeo' => array( - 'name' => 'Vimeo', - 'icon' => '', - ), - 'vk' => array( - 'name' => 'VK', - 'icon' => '', - ), - 'wordpress' => array( - 'name' => 'WordPress', - 'icon' => '', - ), - 'whatsapp' => array( - 'name' => 'WhatsApp', - 'icon' => '', - ), - 'x' => array( - 'name' => 'X', - 'icon' => '', - ), - 'yelp' => array( - 'name' => 'Yelp', - 'icon' => '', - ), - 'youtube' => array( - 'name' => 'YouTube', - 'icon' => '', - ), - ); + // Cache for repeated access to this function by block_core_social_link_get_icon and block_core_social_link_get_name + static $services_data = null; + + if ( ! $services_data ) { + $services_data = array( + 'fivehundredpx' => array( + 'name' => '500px', + 'icon' => '', + ), + 'amazon' => array( + 'name' => 'Amazon', + 'icon' => '', + ), + 'bandcamp' => array( + 'name' => 'Bandcamp', + 'icon' => '', + ), + 'behance' => array( + 'name' => 'Behance', + 'icon' => '', + ), + 'chain' => array( + 'name' => 'Link', + 'icon' => '', + ), + 'codepen' => array( + 'name' => 'CodePen', + 'icon' => '', + ), + 'deviantart' => array( + 'name' => 'DeviantArt', + 'icon' => '', + ), + 'dribbble' => array( + 'name' => 'Dribbble', + 'icon' => '', + ), + 'dropbox' => array( + 'name' => 'Dropbox', + 'icon' => '', + ), + 'etsy' => array( + 'name' => 'Etsy', + 'icon' => '', + ), + 'facebook' => array( + 'name' => 'Facebook', + 'icon' => '', + ), + 'feed' => array( + 'name' => 'RSS Feed', + 'icon' => '', + ), + 'flickr' => array( + 'name' => 'Flickr', + 'icon' => '', + ), + 'foursquare' => array( + 'name' => 'Foursquare', + 'icon' => '', + ), + 'goodreads' => array( + 'name' => 'Goodreads', + 'icon' => '', + ), + 'google' => array( + 'name' => 'Google', + 'icon' => '', + ), + 'github' => array( + 'name' => 'GitHub', + 'icon' => '', + ), + 'gravatar' => array( + 'name' => 'Gravatar', + 'icon' => '', + ), + 'instagram' => array( + 'name' => 'Instagram', + 'icon' => '', + ), + 'lastfm' => array( + 'name' => 'Last.fm', + 'icon' => '', + ), + 'linkedin' => array( + 'name' => 'LinkedIn', + 'icon' => '', + ), + 'mail' => array( + 'name' => 'Mail', + 'icon' => '', + ), + 'mastodon' => array( + 'name' => 'Mastodon', + 'icon' => '', + ), + 'meetup' => array( + 'name' => 'Meetup', + 'icon' => '', + ), + 'medium' => array( + 'name' => 'Medium', + 'icon' => '', + ), + 'patreon' => array( + 'name' => 'Patreon', + 'icon' => '', + ), + 'pinterest' => array( + 'name' => 'Pinterest', + 'icon' => '', + ), + 'pocket' => array( + 'name' => 'Pocket', + 'icon' => '', + ), + 'reddit' => array( + 'name' => 'Reddit', + 'icon' => '', + ), + 'share' => array( + 'name' => 'Share Icon', + 'icon' => '', + ), + 'skype' => array( + 'name' => 'Skype', + 'icon' => '', + ), + 'snapchat' => array( + 'name' => 'Snapchat', + 'icon' => '', + ), + 'soundcloud' => array( + 'name' => 'Soundcloud', + 'icon' => '', + ), + 'spotify' => array( + 'name' => 'Spotify', + 'icon' => '', + ), + 'telegram' => array( + 'name' => 'Telegram', + 'icon' => '', + ), + 'threads' => array( + 'name' => 'Threads', + 'icon' => '', + ), + 'tiktok' => array( + 'name' => 'TikTok', + 'icon' => '', + ), + 'tumblr' => array( + 'name' => 'Tumblr', + 'icon' => '', + ), + 'twitch' => array( + 'name' => 'Twitch', + 'icon' => '', + ), + 'twitter' => array( + 'name' => 'Twitter', + 'icon' => '', + ), + 'vimeo' => array( + 'name' => 'Vimeo', + 'icon' => '', + ), + 'vk' => array( + 'name' => 'VK', + 'icon' => '', + ), + 'wordpress' => array( + 'name' => 'WordPress', + 'icon' => '', + ), + 'whatsapp' => array( + 'name' => 'WhatsApp', + 'icon' => '', + ), + 'x' => array( + 'name' => 'X', + 'icon' => '', + ), + 'yelp' => array( + 'name' => 'Yelp', + 'icon' => '', + ), + 'youtube' => array( + 'name' => 'YouTube', + 'icon' => '', + ), + ); + + /** + * Filter the list of available social service. + * + * This can be used to change icons or add custom icons (additionally to variations in the editor). + * Icons should be directly renderable - therefore SVGs work best. + * + * @since 6.x.x + * + * @param array $services_data The list of services. Each item is an array containing a 'name' and 'icon' key. + * @return array The list of social services. + */ + $services_data = apply_filters( 'block_core_social_link_services', $services_data ); + } if ( ! empty( $service ) && ! empty( $field ) diff --git a/packages/block-library/src/social-link/social-list.js b/packages/block-library/src/social-link/social-list.js index 909e9b90a54c5..f52fa08a64509 100644 --- a/packages/block-library/src/social-link/social-list.js +++ b/packages/block-library/src/social-link/social-list.js @@ -6,29 +6,38 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import variations from './variations'; import { ChainIcon } from './icons'; /** - * Retrieves the social service's icon component. + * Retrieves the display label for the social service. * - * @param {string} name key for a social service (lowercase slug) + * @param {Object} activeVariation The object of the active social service variation * - * @return {Component} Icon component for social service. + * @return {string} Display label for social service */ -export const getIconBySite = ( name ) => { - const variation = variations.find( ( v ) => v.name === name ); - return variation ? variation.icon : ChainIcon; +const getSocialServiceLabel = ( activeVariation ) => { + const title = activeVariation?.title ?? activeVariation.name; + return title; }; /** - * Retrieves the display name for the social service. + * Retrieves the social service's icon component and label. * - * @param {string} name key for a social service (lowercase slug) + * @param {Object} activeVariation The object of the active social service variation * - * @return {string} Display name for social service + * @return {Object} An opject containing the Icon component for social service and label. */ -export const getNameBySite = ( name ) => { - const variation = variations.find( ( v ) => v.name === name ); - return variation ? variation.title : __( 'Social Icon' ); +export const getSocialService = ( activeVariation ) => { + if ( activeVariation?.name ) { + return { + icon: activeVariation?.icon ?? ChainIcon, + label: getSocialServiceLabel( activeVariation ), + }; + } + + // Default to Mail if no active variation is found. + return { + icon: ChainIcon, + label: __( 'Social Icon' ), + }; };