diff --git a/lib/global-styles.php b/lib/global-styles.php index a46473c3a2d772..7e061ec7dc77ce 100644 --- a/lib/global-styles.php +++ b/lib/global-styles.php @@ -308,7 +308,7 @@ function gutenberg_experimental_global_styles_get_block_data() { $registry = WP_Block_Type_Registry::get_instance(); foreach ( $registry->get_all_registered() as $block_name => $block_type ) { - if ( ! is_array( $block_type->supports ) ) { + if ( empty( $block_type->supports ) || ! is_array( $block_type->supports ) ) { continue; } @@ -375,11 +375,12 @@ function gutenberg_experimental_global_styles_get_block_data() { */ function gutenberg_experimental_global_styles_flatten_styles_tree( $styles ) { $mappings = array( - 'line-height' => array( 'typography', 'lineHeight' ), - 'font-size' => array( 'typography', 'fontSize' ), - 'background' => array( 'color', 'gradient' ), - 'background-color' => array( 'color', 'background' ), - 'color' => array( 'color', 'text' ), + 'line-height' => array( 'typography', 'lineHeight' ), + 'font-size' => array( 'typography', 'fontSize' ), + 'background' => array( 'color', 'gradient' ), + 'background-color' => array( 'color', 'background' ), + 'color' => array( 'color', 'text' ), + '--wp--style--color--link' => array( 'color', 'link' ), ); $result = array(); @@ -453,6 +454,16 @@ function gutenberg_experimental_global_styles_resolver( $tree ) { function gutenberg_experimental_global_styles_resolver_styles( $block_selector, $block_supports, $block_styles ) { $css_rule = ''; $css_declarations = ''; + + if ( gutenberg_experimental_global_styles_has_theme_json_support() ) { + // To support all themes, we added in the block-library stylesheet + // a style rule such as .has-link-color a { color: var(--wp--style--color--link, #00e); } + // so that existing link colors themes used didn't break. + // We add this here to make it work for themes that opt-in to theme.json + // In the future, we may do this differently. + $css_rule = 'a { color: var(--wp--style--color--link, #00e); }'; + } + foreach ( $block_styles as $property => $value ) { // Only convert to CSS: // @@ -553,9 +564,6 @@ function gutenberg_experimental_global_styles_get_stylesheet() { * and enqueues the resulting stylesheet. */ function gutenberg_experimental_global_styles_enqueue_assets() { - if ( ! gutenberg_experimental_global_styles_has_theme_json_support() ) { - return; - } $stylesheet = gutenberg_experimental_global_styles_get_stylesheet(); @@ -571,18 +579,17 @@ function gutenberg_experimental_global_styles_enqueue_assets() { * @return array New block editor settings */ function gutenberg_experimental_global_styles_settings( $settings ) { - if ( ! gutenberg_experimental_global_styles_has_theme_json_support() ) { - return $settings; - } - $settings['__experimentalGlobalStylesUserEntityId'] = gutenberg_experimental_global_styles_get_user_cpt_id(); + if ( gutenberg_experimental_global_styles_has_theme_json_support() ) { + $settings['__experimentalGlobalStylesUserEntityId'] = gutenberg_experimental_global_styles_get_user_cpt_id(); - $global_styles = gutenberg_experimental_global_styles_merge_trees( - gutenberg_experimental_global_styles_get_core(), - gutenberg_experimental_global_styles_get_theme() - ); + $global_styles = gutenberg_experimental_global_styles_merge_trees( + gutenberg_experimental_global_styles_get_core(), + gutenberg_experimental_global_styles_get_theme() + ); - $settings['__experimentalGlobalStylesBase'] = $global_styles; + $settings['__experimentalGlobalStylesBase'] = $global_styles; + } // Add the styles for the editor via the settings // so they get processed as if they were added via add_editor_styles: diff --git a/packages/block-editor/src/hooks/color.js b/packages/block-editor/src/hooks/color.js index c4f80ff9c02ef0..0c527226798924 100644 --- a/packages/block-editor/src/hooks/color.js +++ b/packages/block-editor/src/hooks/color.js @@ -34,6 +34,16 @@ export const COLOR_SUPPORT_KEY = '__experimentalColor'; const hasColorSupport = ( blockType ) => Platform.OS === 'web' && hasBlockSupport( blockType, COLOR_SUPPORT_KEY ); +const hasLinkColorSupport = ( blockType ) => { + if ( Platform.OS !== 'web' ) { + return false; + } + + const colorSupport = getBlockSupport( blockType, COLOR_SUPPORT_KEY ); + + return isObject( colorSupport ) && !! colorSupport.linkColor; +}; + const hasGradientSupport = ( blockType ) => { if ( Platform.OS !== 'web' ) { return false; @@ -121,6 +131,7 @@ export function addSaveProps( props, blockType, attributes ) { backgroundColor || style?.color?.background || ( hasGradient && ( gradient || style?.color?.gradient ) ), + 'has-link-color': style?.color?.link, } ); props.className = newClassName ? newClassName : undefined; @@ -151,6 +162,15 @@ export function addEditProps( settings ) { return settings; } +const getLinkColorFromAttributeValue = ( colors, value ) => { + const attributeParsed = /var:preset\|color\|(.+)/.exec( value ); + if ( attributeParsed && attributeParsed[ 1 ] ) { + return getColorObjectByAttributeValues( colors, attributeParsed[ 1 ] ) + .color; + } + return value; +}; + /** * Inspector control panel containing the color related configuration * @@ -245,6 +265,21 @@ export function ColorEdit( props ) { }; }; + const onChangeLinkColor = ( value ) => { + const colorObject = getColorObjectByColorValue( colors, value ); + props.setAttributes( { + style: { + ...props.attributes.style, + color: { + ...props.attributes.style?.color, + link: colorObject?.slug + ? `var:preset|color|${ colorObject.slug }` + : value, + }, + }, + } ); + }; + return ( ); diff --git a/packages/block-editor/src/hooks/style.js b/packages/block-editor/src/hooks/style.js index c7598089013ed8..f8fbf30c6b6e3f 100644 --- a/packages/block-editor/src/hooks/style.js +++ b/packages/block-editor/src/hooks/style.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { has, get } from 'lodash'; +import { has, get, startsWith } from 'lodash'; /** * WordPress dependencies @@ -42,6 +42,20 @@ const typographySupportKeys = [ const hasStyleSupport = ( blockType ) => styleSupportKeys.some( ( key ) => hasBlockSupport( blockType, key ) ); +const VARIABLE_REFERENCE_PREFIX = 'var:'; +const VARIABLE_PATH_SEPARATOR_TOKEN_ATTRIBUTE = '|'; +const VARIABLE_PATH_SEPARATOR_TOKEN_STYLE = '--'; +function compileStyleValue( uncompiledValue ) { + if ( startsWith( uncompiledValue, VARIABLE_REFERENCE_PREFIX ) ) { + const variable = uncompiledValue + .slice( VARIABLE_REFERENCE_PREFIX.length ) + .split( VARIABLE_PATH_SEPARATOR_TOKEN_ATTRIBUTE ) + .join( VARIABLE_PATH_SEPARATOR_TOKEN_STYLE ); + return `var(--wp--${ variable })`; + } + return uncompiledValue; +} + /** * Returns the inline styles to add depending on the style object * @@ -56,12 +70,13 @@ export function getInlineStyles( styles = {} ) { background: [ 'color', 'gradient' ], backgroundColor: [ 'color', 'background' ], color: [ 'color', 'text' ], + '--wp--style--color--link': [ 'color', 'link' ], }; const output = {}; Object.entries( mappings ).forEach( ( [ styleKey, objectKey ] ) => { if ( has( styles, objectKey ) ) { - output[ styleKey ] = get( styles, objectKey ); + output[ styleKey ] = compileStyleValue( get( styles, objectKey ) ); } } ); diff --git a/packages/block-library/src/columns/block.json b/packages/block-library/src/columns/block.json index a27c693b8134b8..352b1e5caaaa48 100644 --- a/packages/block-library/src/columns/block.json +++ b/packages/block-library/src/columns/block.json @@ -14,7 +14,8 @@ "html": false, "lightBlockWrapper": true, "__experimentalColor": { - "gradients": true + "gradients": true, + "linkColor": true } } } diff --git a/packages/block-library/src/group/block.json b/packages/block-library/src/group/block.json index ab4e81aa334426..1e32b1443cbc85 100644 --- a/packages/block-library/src/group/block.json +++ b/packages/block-library/src/group/block.json @@ -16,7 +16,8 @@ "html": false, "lightBlockWrapper": true, "__experimentalColor": { - "gradients": true + "gradients": true, + "linkColor": true } } } diff --git a/packages/block-library/src/heading/block.json b/packages/block-library/src/heading/block.json index d47b35c26eebe1..fd03a4487ee5aa 100644 --- a/packages/block-library/src/heading/block.json +++ b/packages/block-library/src/heading/block.json @@ -23,7 +23,9 @@ "anchor": true, "className": false, "lightBlockWrapper": true, - "__experimentalColor": true, + "__experimentalColor": { + "linkColor": true + }, "__experimentalFontSize": true, "__experimentalLineHeight": true, "__experimentalSelector": { diff --git a/packages/block-library/src/media-text/block.json b/packages/block-library/src/media-text/block.json index 71a706fe1f3a69..91f12cf51b460c 100644 --- a/packages/block-library/src/media-text/block.json +++ b/packages/block-library/src/media-text/block.json @@ -84,7 +84,8 @@ ], "html": false, "__experimentalColor": { - "gradients": true + "gradients": true, + "linkColor": true } } } diff --git a/packages/block-library/src/paragraph/block.json b/packages/block-library/src/paragraph/block.json index c7897c8f92ac08..959fd9294393c8 100644 --- a/packages/block-library/src/paragraph/block.json +++ b/packages/block-library/src/paragraph/block.json @@ -29,7 +29,9 @@ "supports": { "className": false, "lightBlockWrapper": true, - "__experimentalColor": true, + "__experimentalColor": { + "linkColor": true + }, "__experimentalFontSize": true, "__experimentalLineHeight": true, "__experimentalFeatures": { diff --git a/packages/block-library/src/style.scss b/packages/block-library/src/style.scss index deb2c477fb80b5..2ef1a87bba4179 100644 --- a/packages/block-library/src/style.scss +++ b/packages/block-library/src/style.scss @@ -234,8 +234,11 @@ background: linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%); } /* stylelint-enable function-comma-space-after */ -} + .has-link-color a { + color: var(--wp--style--color--link, #00e); + } +} // Font sizes. // The reason we add the editor class wrapper here is