From 393fac42c75ad97c5d397255fd4f9aefa9cefc25 Mon Sep 17 00:00:00 2001 From: ramonjd Date: Mon, 9 May 2022 13:33:06 +1000 Subject: [PATCH] Testing out generating block color classnames using the style engine. --- packages/block-editor/src/hooks/color.js | 66 +++++++++---------- packages/style-engine/src/index.ts | 4 +- .../style-engine/src/styles/elements/index.ts | 20 ++++++ packages/style-engine/src/styles/index.ts | 8 ++- packages/style-engine/src/types.ts | 9 ++- 5 files changed, 70 insertions(+), 37 deletions(-) create mode 100644 packages/style-engine/src/styles/elements/index.ts diff --git a/packages/block-editor/src/hooks/color.js b/packages/block-editor/src/hooks/color.js index b02b9f2bfbbad6..13c8b84d423d74 100644 --- a/packages/block-editor/src/hooks/color.js +++ b/packages/block-editor/src/hooks/color.js @@ -17,12 +17,10 @@ import { createHigherOrderComponent } from '@wordpress/compose'; * Internal dependencies */ import { - getColorClassName, getColorObjectByColorValue, getColorObjectByAttributeValues, } from '../components/colors'; import { - __experimentalGetGradientClass, getGradientValueBySlug, getGradientSlugByValue, } from '../components/gradients'; @@ -34,6 +32,7 @@ import { } from './utils'; import ColorPanel from './color-panel'; import useSetting from '../components/use-setting'; +import { getClassnames } from '@wordpress/style-engine'; export const COLOR_SUPPORT_KEY = 'color'; @@ -252,52 +251,51 @@ export function addSaveProps( props, blockType, attributes ) { return props; } - const hasGradient = hasGradientSupport( blockType ); - // I'd have preferred to avoid the "style" attribute usage here const { backgroundColor, textColor, gradient, style } = attributes; const shouldSerialize = ( feature ) => ! shouldSkipSerialization( blockType, COLOR_SUPPORT_KEY, feature ); + const colorStyles = {}; + // Primary color classes must come before the `has-text-color`, // `has-background` and `has-link-color` classes to maintain backwards // compatibility and avoid block invalidations. - const textClass = shouldSerialize( 'text' ) - ? getColorClassName( 'color', textColor ) - : undefined; - - const gradientClass = shouldSerialize( 'gradients' ) - ? __experimentalGetGradientClass( gradient ) - : undefined; + if ( textColor && shouldSerialize( 'text' ) ) { + colorStyles.text = `var:preset|color|${ textColor }`; + } - const backgroundClass = shouldSerialize( 'background' ) - ? getColorClassName( 'background-color', backgroundColor ) - : undefined; + if ( + gradient && + shouldSerialize( 'gradients' ) && + hasGradientSupport( blockType ) + ) { + colorStyles.gradient = `var:preset|gradient|${ gradient }`; + } - const serializeHasBackground = - shouldSerialize( 'background' ) || shouldSerialize( 'gradients' ); - const hasBackground = - backgroundColor || - style?.color?.background || - ( hasGradient && ( gradient || style?.color?.gradient ) ); + if ( backgroundColor && shouldSerialize( 'background' ) ) { + colorStyles.background = `var:preset|color|${ backgroundColor }`; + } const newClassName = classnames( props.className, - textClass, - gradientClass, - { - // Don't apply the background class if there's a custom gradient. - [ backgroundClass ]: - ( ! hasGradient || ! style?.color?.gradient ) && - !! backgroundClass, - 'has-text-color': - shouldSerialize( 'text' ) && - ( textColor || style?.color?.text ), - 'has-background': serializeHasBackground && hasBackground, - 'has-link-color': - shouldSerialize( 'link' ) && style?.elements?.link?.color, - } + ...getClassnames( { + ...style, + color: { + ...colorStyles, + }, + elements: { + ...style?.elements, + link: { + color: { + text: shouldSerialize( 'link' ) + ? style?.elements?.link?.color + : undefined, + }, + }, + }, + } ) ); props.className = newClassName ? newClassName : undefined; diff --git a/packages/style-engine/src/index.ts b/packages/style-engine/src/index.ts index 62a7cac23b2bc9..c0b313501b9046 100644 --- a/packages/style-engine/src/index.ts +++ b/packages/style-engine/src/index.ts @@ -67,7 +67,9 @@ export function getCSSRules( ): GeneratedCSSRule[] { const rules: GeneratedCSSRule[] = []; styleDefinitions.forEach( ( definition: StyleDefinition ) => { - rules.push( ...definition.generate( style, options ) ); + if ( typeof definition.generate === 'function' ) { + rules.push( ...definition.generate( style, options ) ); + } } ); return rules; diff --git a/packages/style-engine/src/styles/elements/index.ts b/packages/style-engine/src/styles/elements/index.ts new file mode 100644 index 00000000000000..13e07aa7a63b67 --- /dev/null +++ b/packages/style-engine/src/styles/elements/index.ts @@ -0,0 +1,20 @@ +/** + * Internal dependencies + */ +import type { Style } from '../../types'; + +const link = { + name: 'link', + getClassNames: ( style: Style ) => { + const classNames = []; + const styleValue: string | undefined = + style?.elements?.link?.color?.text; + if ( styleValue ) { + classNames.push( 'has-link-color' ); + } + + return classNames; + }, +}; + +export default [ link ]; diff --git a/packages/style-engine/src/styles/index.ts b/packages/style-engine/src/styles/index.ts index 79f1c43d8d33f7..db56b35f8803e9 100644 --- a/packages/style-engine/src/styles/index.ts +++ b/packages/style-engine/src/styles/index.ts @@ -2,7 +2,13 @@ * Internal dependencies */ import color from './color'; +import elements from './elements'; import spacing from './spacing'; import typography from './typography'; -export const styleDefinitions = [ ...color, ...spacing, ...typography ]; +export const styleDefinitions = [ + ...color, + ...elements, + ...spacing, + ...typography, +]; diff --git a/packages/style-engine/src/types.ts b/packages/style-engine/src/types.ts index f4d7262ee37a9f..9f60b1b0f6fc03 100644 --- a/packages/style-engine/src/types.ts +++ b/packages/style-engine/src/types.ts @@ -31,6 +31,13 @@ export interface Style { background?: CSSProperties[ 'backgroundColor' ]; gradient?: CSSProperties[ 'background' ]; }; + elements?: { + link?: { + color?: { + text?: CSSProperties[ 'color' ]; + }; + }; + }; } export type StyleOptions = { @@ -52,6 +59,6 @@ export type GeneratedCSSRule = { export interface StyleDefinition { name: string; - generate: ( style: Style, options: StyleOptions ) => GeneratedCSSRule[]; + generate?: ( style: Style, options: StyleOptions ) => GeneratedCSSRule[]; getClassNames?: ( style: Style ) => string[]; }