diff --git a/packages/block-editor/src/hooks/color.js b/packages/block-editor/src/hooks/color.js index 7f256dfe0474b..36dd8b0c0d8fb 100644 --- a/packages/block-editor/src/hooks/color.js +++ b/packages/block-editor/src/hooks/color.js @@ -133,52 +133,48 @@ export function addSaveProps( props, blockType, attributes ) { const hasGradient = hasGradientSupport( blockType ); const { backgroundColor, textColor, gradient, style } = attributes; - const colorClasses = {}; - const shouldSerialize = ( feature ) => ! shouldSkipSerialization( blockType, COLOR_SUPPORT_KEY, feature ); - // Serialize background color classes. - if ( shouldSerialize( 'background' ) ) { - const backgroundClass = getColorClassName( - 'background-color', - backgroundColor - ); - - // Don't apply the background class if there's a custom gradient - colorClasses[ backgroundClass ] = - ( ! hasGradient || ! style?.color?.gradient ) && !! backgroundClass; - } - - // Serialize gradient color class. - if ( shouldSerialize( 'gradients' ) ) { - const gradientClass = __experimentalGetGradientClass( gradient ); - colorClasses[ gradientClass ] = gradientClass; - } - - // Serialize `has-background` that applies when either background or - // gradient should be serialized. - if ( shouldSerialize( 'background' ) || shouldSerialize( 'gradients' ) ) { - colorClasses[ 'has-background' ] = - backgroundColor || - style?.color?.background || - ( hasGradient && ( gradient || style?.color?.gradient ) ); - } - - // Serialize text color classes. - if ( shouldSerialize( 'text' ) ) { - const textClass = getColorClassName( 'color', textColor ); - - colorClasses[ textClass ] = textClass; - colorClasses[ 'has-text-color' ] = textColor || style?.color?.text; - } - - // Serialize link color class. - if ( shouldSerialize( 'link' ) ) { - colorClasses[ 'has-link-color' ] = style?.elements?.link?.color; - } - - const newClassName = classnames( props.className, colorClasses ); + // 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; + + const backgroundClass = shouldSerialize( 'background' ) + ? getColorClassName( 'background-color', backgroundColor ) + : undefined; + + const serializeHasBackground = + shouldSerialize( 'background' ) || shouldSerialize( 'gradients' ); + const hasBackground = + backgroundColor || + style?.color?.background || + ( hasGradient && ( gradient || style?.color?.gradient ) ); + + 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, + } + ); props.className = newClassName ? newClassName : undefined; return props;