Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Social Links Block: Add icon and background color options #25372

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
12 changes: 11 additions & 1 deletion packages/block-library/src/social-link/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,20 @@
},
"label": {
"type": "string"
},
"rgbIconColor": {
"type": "string"
},
"rgbBackgroundColor": {
"type": "string"
}
},
"usesContext": [
"openInNewTab"
"openInNewTab",
"iconColor",
"backgroundColor",
"customIconColor",
"customBackgroundColor"
],
"supports": {
"reusable": false,
Expand Down
47 changes: 44 additions & 3 deletions packages/block-library/src/social-link/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* External dependencies
*/
import classNames from 'classnames';
import { find, get } from 'lodash';

/**
* WordPress dependencies
Expand All @@ -11,8 +12,9 @@ import {
URLPopover,
URLInput,
useBlockProps,
__experimentalUseEditorFeature as useEditorFeature,
} from '@wordpress/block-editor';
import { Fragment, useState } from '@wordpress/element';
import { Fragment, useState, useEffect } from '@wordpress/element';
import {
Button,
PanelBody,
Expand All @@ -27,16 +29,55 @@ import { keyboardReturn } from '@wordpress/icons';
*/
import { getIconBySite, getNameBySite } from './social-list';

const SocialLinkEdit = ( { attributes, setAttributes, isSelected } ) => {
const SocialLinkEdit = ( {
attributes,
setAttributes,
isSelected,
context,
} ) => {
const { url, service, label } = attributes;
const [ showURLPopover, setPopover ] = useState( false );

const getColorBySlug = ( colors, slug, customColor ) => {
return customColor || get( find( colors, { slug } ), 'color' ) || null;
};

// Determine colors for this link passed via context from parent.
const {
iconColor,
customIconColor,
backgroundColor,
customBackgroundColor,
} = context;
const colors = useEditorFeature( 'color.palette' ) || [];
const rgbIconColor = getColorBySlug( colors, iconColor, customIconColor );
const rgbBackgroundColor = getColorBySlug(
colors,
backgroundColor,
customBackgroundColor
);

useEffect( () => {
setAttributes( { rgbIconColor, rgbBackgroundColor } );
}, [ rgbIconColor, rgbBackgroundColor, setAttributes ] );

const classes = classNames( 'wp-social-link', 'wp-social-link-' + service, {
'wp-social-link__is-incomplete': ! url,
'has-text-color': rgbIconColor,
[ `has-${ iconColor }-color` ]: !! iconColor,
'has-background': rgbBackgroundColor,
[ `has-${ backgroundColor }-background-color` ]: !! backgroundColor,
} );

const IconComponent = getIconBySite( service );
const socialLinkName = getNameBySite( service );
const blockProps = useBlockProps( { className: classes } );
const blockProps = useBlockProps( {
className: classes,
style: {
color: rgbIconColor,
backgroundColor: rgbBackgroundColor,
},
} );

return (
<Fragment>
Expand Down
80 changes: 74 additions & 6 deletions packages/block-library/src/social-link/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@
*/
function render_block_core_social_link( $attributes, $content, $block ) {
$open_in_new_tab = $block->context['openInNewTab'];

$service = ( isset( $attributes['service'] ) ) ? $attributes['service'] : 'Icon';
$url = ( isset( $attributes['url'] ) ) ? $attributes['url'] : false;
$label = ( isset( $attributes['label'] ) ) ? $attributes['label'] : block_core_social_link_get_name( $service );
$class_name = isset( $attributes['className'] ) ? ' ' . $attributes['className'] : false;
$service = array_key_exists( 'service', $attributes ) ? $attributes['service'] : 'Icon';
$url = array_key_exists( 'url', $attributes ) ? $attributes['url'] : false;
$label = array_key_exists( 'label', $attributes ) ? $attributes['label'] : block_core_social_link_get_name( $service );
$class_name = array_key_exists( 'className', $attributes ) ? ' ' . $attributes['className'] : false;

// Don't render a link if there is no URL set.
if ( ! $url ) {
Expand All @@ -33,7 +32,13 @@ function render_block_core_social_link( $attributes, $content, $block ) {
}

$icon = block_core_social_link_get_icon( $service );
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => 'wp-social-link wp-social-link-' . $service . $class_name ) );
$colors = block_core_social_link_build_css_colors( $block->context );
$wrapper_attributes = get_block_wrapper_attributes(
array(
'class' => 'wp-social-link wp-social-link-' . $service . $class_name . ' ' . $colors,
'style' => block_core_social_link_build_css_styles( $attributes ),
)
);

return '<li ' . $wrapper_attributes . '><a href="' . esc_url( $url ) . '" aria-label="' . esc_attr( $label ) . '" ' . $attribute . '> ' . $icon . '</a></li>';
}
Expand Down Expand Up @@ -280,3 +285,66 @@ function block_core_social_link_services( $service = '', $field = '' ) {

return $services_data;
}

/**
* Determines the CSS classes that should be applied to the Social Link to
* reflect color selections.
*
* @param array $context Social Link block context.
* @return string CSS classes for the link's colors.
*/
function block_core_social_link_build_css_colors( $context ) {
$colors = array();

// Icon color.
$has_named_icon_color = array_key_exists( 'iconColor', $context );
$has_custom_icon_color = array_key_exists( 'customIconColor', $context );

// Add has-text-color class to flag color selection.
if ( $has_named_icon_color || $has_custom_icon_color ) {
$colors[] = 'has-text-color';
}

// Add CSS class for named color.
if ( $has_named_icon_color ) {
$colors[] = sprintf( 'has-%s-color', $context['iconColor'] );
}

// Background color.
$has_named_background_color = array_key_exists( 'backgroundColor', $context );
$has_custom_background_color = array_key_exists( 'customBackgroundColor', $context );

// Add has-background class if color selection made.
if ( $has_custom_background_color || $has_named_background_color ) {
$colors[] = 'has-background';
}

// Add CSS class for named background color.
if ( $has_named_background_color ) {
$colors[] = sprintf( 'has-%s-background-color', $context['backgroundColor'] );
}

return implode( ' ', $colors );
}

/**
* Collects the Social Link's icon and background colors into css rules then
* builds a style attribute ready for adding to rendered markup.
*
* @param array $attributes The Social Link block's attributes.
* @return string An HTML style attribute or empty string.
*/
function block_core_social_link_build_css_styles( $attributes ) {
$styles = array();

// Inline styles allow selected color to override default colors for services.
if ( isset( $attributes['rgbIconColor'] ) ) {
$styles[] = sprintf( 'color: %s;', $attributes['rgbIconColor'] );
}

if ( isset( $attributes['rgbBackgroundColor'] ) ) {
$styles[] = sprintf( 'background-color: %s;', $attributes['rgbBackgroundColor'] );
}

return implode( ' ', $styles );
}
18 changes: 17 additions & 1 deletion packages/block-library/src/social-links/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,26 @@
"openInNewTab": {
"type": "boolean",
"default": false
},
"iconColor": {
"type": "string"
},
"customIconColor": {
"type": "string"
},
"backgroundColor": {
"type": "string"
},
"customBackgroundColor": {
"type": "string"
}
},
"providesContext": {
"openInNewTab": "openInNewTab"
"openInNewTab": "openInNewTab",
"iconColor": "iconColor",
"customIconColor": "customIconColor",
"backgroundColor": "backgroundColor",
"customBackgroundColor": "customBackgroundColor"
},
"supports": {
"align": [
Expand Down
49 changes: 44 additions & 5 deletions packages/block-library/src/social-links/edit.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
/**
* WordPress dependencies
*/

import { Fragment } from '@wordpress/element';

import {
__experimentalUseInnerBlocksProps as useInnerBlocksProps,
useBlockProps,
ContrastChecker,
InspectorControls,
PanelColorSettings,
withColors,
} from '@wordpress/block-editor';
import { ToggleControl, PanelBody } from '@wordpress/components';
import { Fragment, useEffect } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

const ALLOWED_BLOCKS = [ 'core/social-link' ];

export function SocialLinksEdit( props ) {
const {
attributes: { openInNewTab },
attributes: { className, openInNewTab },
setAttributes,
backgroundColor,
setBackgroundColor,
iconColor,
setIconColor,
} = props;

const SocialPlaceholder = (
Expand All @@ -36,6 +41,14 @@ export function SocialLinksEdit( props ) {
templateLock: false,
__experimentalAppenderTagName: 'li',
} );
const logosOnly = className?.indexOf( 'is-style-logos-only' ) >= 0;

useEffect( () => {
if ( logosOnly ) {
setBackgroundColor();
}
}, [ logosOnly, setBackgroundColor ] );

return (
<Fragment>
<InspectorControls>
Expand All @@ -48,10 +61,36 @@ export function SocialLinksEdit( props ) {
}
/>
</PanelBody>
<PanelColorSettings
title={ __( 'Color settings' ) }
colorSettings={ [
{
value: iconColor.color,
onChange: setIconColor,
label: __( 'Icon color' ),
},
! logosOnly && {
value: backgroundColor.color,
onChange: setBackgroundColor,
label: __( 'Background color' ),
},
] }
/>
{ ! logosOnly && (
<ContrastChecker
{ ...{
textColor: iconColor.color,
backgroundColor: backgroundColor.color,
} }
isLargeText={ false }
/>
) }
</InspectorControls>
<ul { ...innerBlocksProps } />
</Fragment>
);
}

export default SocialLinksEdit;
export default withColors( 'backgroundColor', { iconColor: 'color' } )(
SocialLinksEdit
);
2 changes: 1 addition & 1 deletion packages/block-library/src/social-links/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// Reduce the paddings, margins, and UI of inner-blocks.
// @todo: eventually we may add a feature that lets a parent container absorb the block UI of a child block.
// When that happens, leverage that instead of the following overrides.
.editor-styles-wrapper .wp-block-social-link {
.editor-styles-wrapper .wp-block-social-links .wp-block-social-link {
margin: 0 8px 8px 0;

// Prevent toolbar from jumping when selecting / hovering a link.
Expand Down