diff --git a/packages/edit-site/src/components/global-styles/style-variations-container.js b/packages/edit-site/src/components/global-styles/style-variations-container.js index 6cc8b53b800d3a..8ab9c1725454b1 100644 --- a/packages/edit-site/src/components/global-styles/style-variations-container.js +++ b/packages/edit-site/src/components/global-styles/style-variations-container.js @@ -8,9 +8,12 @@ import classnames from 'classnames'; */ import { store as coreStore } from '@wordpress/core-data'; import { useSelect } from '@wordpress/data'; -import { useMemo, useContext, useState } from '@wordpress/element'; +import { useMemo, useContext, useState, useEffect } from '@wordpress/element'; import { ENTER } from '@wordpress/keycodes'; -import { __experimentalGrid as Grid } from '@wordpress/components'; +import { + __experimentalGrid as Grid, + ToggleControl, +} from '@wordpress/components'; import { __, sprintf } from '@wordpress/i18n'; import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor'; @@ -25,9 +28,9 @@ const { GlobalStylesContext, areGlobalStyleConfigsEqual } = unlock( blockEditorPrivateApis ); -function Variation( { variation } ) { +function Variation( { variation, setCurrentVariation, variationId } ) { const [ isFocused, setIsFocused ] = useState( false ); - const { base, user, setUserConfig } = useContext( GlobalStylesContext ); + const { base, user } = useContext( GlobalStylesContext ); const context = useMemo( () => { return { user: { @@ -41,12 +44,7 @@ function Variation( { variation } ) { }, [ variation, base ] ); const selectVariation = () => { - setUserConfig( () => { - return { - settings: variation.settings, - styles: variation.styles, - }; - } ); + setCurrentVariation( variationId ); }; const selectOnEnter = ( event ) => { @@ -101,6 +99,13 @@ function Variation( { variation } ) { } export default function StyleVariationsContainer() { + const { user, setUserConfig } = useContext( GlobalStylesContext ); + const [ currentUserStyles ] = useState( { ...user } ); + const [ currentVariation, setCurrentVariation ] = useState(); + + const [ preserveAdditionalCSS, setPreserveAdditionalCSS ] = + useState( true ); + const variations = useSelect( ( select ) => { return select( coreStore @@ -114,22 +119,110 @@ export default function StyleVariationsContainer() { settings: {}, styles: {}, }, - ...( variations ?? [] ).map( ( variation ) => ( { - ...variation, - settings: variation.settings ?? {}, - styles: variation.styles ?? {}, - } ) ), + ...( variations ?? [] ).map( ( variation ) => { + const blockStyles = { ...variation?.styles?.blocks } || {}; + if ( + currentUserStyles?.styles?.blocks && + preserveAdditionalCSS + ) { + Object.keys( currentUserStyles.styles.blocks ).forEach( + ( blockName ) => { + if ( + currentUserStyles.styles.blocks[ blockName ].css + ) { + blockStyles[ blockName ] = { + ...( blockStyles[ blockName ] + ? blockStyles[ blockName ] + : {} ), + css: `${ + blockStyles[ blockName ]?.css || '' + } ${ + currentUserStyles.styles.blocks[ + blockName + ].css + }`, + }; + } + } + ); + } + + const styles = preserveAdditionalCSS + ? { + ...variation.styles, + ...( currentUserStyles?.styles?.css || + variation?.styles?.css + ? { + css: `${ + variation.styles?.css || '' + } ${ currentUserStyles.styles.css }`, + } + : {} ), + blocks: { + ...blockStyles, + }, + } + : variation.styles; + + return { + ...variation, + settings: variation.settings ?? {}, + styles: styles ?? {}, + }; + } ), ]; - }, [ variations ] ); + }, [ + variations, + currentUserStyles.styles.blocks, + currentUserStyles.styles.css, + preserveAdditionalCSS, + ] ); + + useEffect( () => { + if ( currentVariation ) { + setUserConfig( () => { + return { + settings: withEmptyVariation[ currentVariation ]?.settings, + styles: withEmptyVariation[ currentVariation ]?.styles, + }; + } ); + } + }, [ + currentVariation, + preserveAdditionalCSS, + setUserConfig, + withEmptyVariation, + ] ); return ( - - { withEmptyVariation.map( ( variation, index ) => ( - - ) ) } - + <> + + { withEmptyVariation.map( ( variation, index ) => ( + + ) ) } + + + { + setPreserveAdditionalCSS( + preserveAdditionalCSS ? false : true + ); + } } + /> + ); } diff --git a/packages/edit-site/src/components/sidebar-navigation-screen/style.scss b/packages/edit-site/src/components/sidebar-navigation-screen/style.scss index b856837b7c6b6a..cd1ec9499128eb 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen/style.scss +++ b/packages/edit-site/src/components/sidebar-navigation-screen/style.scss @@ -104,6 +104,10 @@ } } +.edit-site-global-styles-style-variations-preserve-css { + margin-top: $grid-unit-20; +} + .edit-site-sidebar-navigation-screen__footer { position: sticky; bottom: 0;