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' ),
+ };
};