From b5e8cf84c81809f06cc0decb07c2e98aec9cc37e Mon Sep 17 00:00:00 2001 From: Rostislav Wolny Date: Wed, 11 Dec 2024 14:00:02 +0100 Subject: [PATCH] Fix issue with CSS variables in the style panel Some components in the style setting (e.g., SpacingSizesControl) don't work with the CSS variables when present in valid CSS form (e.g., var(--wp--preset--spacing--10)). To prevent issues, we need to transform CSS variables to the shortened variant. The core uses more sophisticated functions for that, see https://github.com/WordPress/gutenberg/blob/f2ba0fdb4c7714e516f7e9045ac53e59401d5b82/packages/block-editor/src/components/global-styles/utils.js#L307-L358 The functionality is private, so I've created a simpler version. [MAILPOET-6335] --- .../src/hooks/use-email-styles.ts | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/packages/js/email-editor/src/hooks/use-email-styles.ts b/packages/js/email-editor/src/hooks/use-email-styles.ts index 9a502902b5..00b675eec1 100644 --- a/packages/js/email-editor/src/hooks/use-email-styles.ts +++ b/packages/js/email-editor/src/hooks/use-email-styles.ts @@ -1,6 +1,6 @@ import deepmerge from 'deepmerge'; import { useSelect } from '@wordpress/data'; -import { useCallback } from '@wordpress/element'; +import { useCallback, useMemo } from '@wordpress/element'; import { storeName, TypographyProperties } from '../store'; import { useUserTheme } from './use-user-theme'; @@ -67,12 +67,51 @@ export function setImmutably( setObject, setPath, value ): typeof setObject { return object; } +/** + * Shorten the variable names in the styles object. Some components need the h + * Transforms variables like var(--wp--preset--spacing--10) to var:preset|spacing|10 + * + * @param {Object} obj The object to shorten the variable names in. + * @return {Object} The object with the shortened variable names. + */ +function shortenWpPresetVariables( obj ) { + // Helper function to replace the variable string + const replaceVariable = ( value ) => { + return value.replace( + /var\(--([a-z]+)--([a-z]+(?:--[a-z0-9]+(?:-[a-z0-9]+)*)*)--([a-z0-9-]+)\)/g, + ( _match, _prefix, group1, group2 ) => { + const groups = group1.split( '--' ).concat( group2 ); + return `var:${ groups.join( '|' ) }`; + } + ); + }; + + // Recursive function to traverse the object + const traverse = ( current ) => { + if ( typeof current === 'object' && current !== null ) { + for ( const key in current ) { + if ( current.hasOwnProperty( key ) ) { + current[ key ] = traverse( current[ key ] ); + } + } + } else if ( typeof current === 'string' ) { + return replaceVariable( current ); + } + return current; + }; + + return traverse( obj ); +} + export const useEmailStyles = (): EmailStylesData => { // const { templateTheme, updateTemplateTheme } = useEmailTheme(); const { userTheme, updateUserTheme } = useUserTheme(); // This is email level styling stored in post meta. - const styles = userTheme?.styles; + const styles = useMemo( + () => shortenWpPresetVariables( userTheme?.styles ), + [ userTheme ] + ); // Default styles from theme.json. const { styles: defaultStyles } = useSelect( ( select ) => ( {