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

Copy custom CSS between variations when switching #61752

Merged
merged 9 commits into from
May 30, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,30 @@
*/
import { store as coreStore } from '@wordpress/core-data';
import { useSelect } from '@wordpress/data';
import { useMemo } from '@wordpress/element';
import { useContext, useEffect, useMemo, useState } from '@wordpress/element';
import { __experimentalGrid as Grid } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor';

/**
* Internal dependencies
*/
import PreviewStyles from './preview-styles';
import Variation from './variations/variation';
import { isVariationWithSingleProperty } from '../../hooks/use-theme-style-variations/use-theme-style-variations-by-property';
import { unlock } from '../../lock-unlock';

const { GlobalStylesContext } = unlock( blockEditorPrivateApis );

export default function StyleVariationsContainer( { gap = 2 } ) {
const { user } = useContext( GlobalStylesContext );
const [ currentUserStyles, setCurrentUserStyles ] = useState( user );
const userStyles = currentUserStyles?.styles;

useEffect( () => {
setCurrentUserStyles( user );
}, [ user ] );

const variations = useSelect( ( select ) => {
return select(
coreStore
Expand All @@ -29,28 +41,79 @@ export default function StyleVariationsContainer( { gap = 2 } ) {
);
} );

const withEmptyVariation = useMemo( () => {
return [
const themeVariations = useMemo( () => {
const withEmptyVariation = [
{
title: __( 'Default' ),
settings: {},
styles: {},
},
...( multiplePropertyVariations ?? [] ).map( ( variation ) => ( {
...variation,
settings: variation.settings ?? {},
styles: variation.styles ?? {},
} ) ),
...( multiplePropertyVariations ?? [] ),
];
return [
...withEmptyVariation.map( ( variation ) => {
const blockStyles = { ...variation?.styles?.blocks } || {};
ramonjd marked this conversation as resolved.
Show resolved Hide resolved

// We need to copy any user custom CSS to the variation to prevent it being lost
// when switching variations.
if ( userStyles?.blocks ) {
Object.keys( userStyles.blocks ).forEach( ( blockName ) => {
// First get any block specific custom CSS from the current user styles and merge with any custom CSS for
// that block in the variation.
if ( userStyles.blocks[ blockName ].css ) {
ramonjd marked this conversation as resolved.
Show resolved Hide resolved
const variationBlockStyles =
blockStyles[ blockName ] || {};
const customCSS = {
css: `${
blockStyles[ blockName ]?.css || ''
} ${
userStyles.blocks[ blockName ].css.trim() ||
''
}`,
};
blockStyles[ blockName ] = {
...variationBlockStyles,
...customCSS,
};
}
} );
}
// Now merge any global custom CSS from current user styles with global custom CSS in the variation.
const css =
userStyles?.css || variation.styles?.css
? {
css: `${ variation.styles?.css || '' } ${
userStyles?.css || ''
}`,
}
: {};

const blocks =
Object.keys( blockStyles ).length > 0
? { blocks: blockStyles }
: {};

const styles = {
...variation.styles,
...css,
...blocks,
};
return {
...variation,
settings: variation.settings ?? {},
styles,
};
} ),
];
}, [ multiplePropertyVariations ] );
}, [ multiplePropertyVariations, userStyles?.blocks, userStyles?.css ] );

return (
<Grid
columns={ 2 }
className="edit-site-global-styles-style-variations-container"
gap={ gap }
>
{ withEmptyVariation.map( ( variation, index ) => (
{ themeVariations.map( ( variation, index ) => (
<Variation key={ index } variation={ variation }>
{ ( isFocused ) => (
<PreviewStyles
Expand Down
Loading