From f02c335796e4cbd71b7de0eaace087c83c5e6d12 Mon Sep 17 00:00:00 2001 From: Ben Dwyer Date: Thu, 2 May 2024 14:15:30 +0100 Subject: [PATCH] Global Styles: Filter out color and typography variations (#60220) * Global Styles: Filter out color and typography variations * Update packages/edit-site/src/components/global-styles/style-variations-container.js Co-authored-by: Andrei Draganescu * Update packages/edit-site/src/components/global-styles/style-variations-container.js Co-authored-by: Andrei Draganescu * update function name * remove variations which are empty once the property has been filtered out * move to a reduce function * remove duplicate values --------- Co-authored-by: Andrei Draganescu --- .../style-variations-container.js | 13 ++- .../use-theme-style-variations-by-property.js | 85 +++++++++++++++---- 2 files changed, 80 insertions(+), 18 deletions(-) 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 5ce6ce25a0fb1..0d19bcedb174b 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 @@ -12,6 +12,7 @@ import { __ } from '@wordpress/i18n'; */ import PreviewStyles from './preview-styles'; import Variation from './variations/variation'; +import { isVariationWithSingleProperty } from '../../hooks/use-theme-style-variations/use-theme-style-variations-by-property'; export default function StyleVariationsContainer( { gap = 2 } ) { const variations = useSelect( ( select ) => { @@ -20,6 +21,14 @@ export default function StyleVariationsContainer( { gap = 2 } ) { ).__experimentalGetCurrentThemeGlobalStylesVariations(); }, [] ); + // Filter out variations that are of single property type, i.e. color or typography variations. + const multiplePropertyVariations = variations?.filter( ( variation ) => { + return ( + ! isVariationWithSingleProperty( variation, 'color' ) && + ! isVariationWithSingleProperty( variation, 'typography' ) + ); + } ); + const withEmptyVariation = useMemo( () => { return [ { @@ -27,13 +36,13 @@ export default function StyleVariationsContainer( { gap = 2 } ) { settings: {}, styles: {}, }, - ...( variations ?? [] ).map( ( variation ) => ( { + ...( multiplePropertyVariations ?? [] ).map( ( variation ) => ( { ...variation, settings: variation.settings ?? {}, styles: variation.styles ?? {}, } ) ), ]; - }, [ variations ] ); + }, [ multiplePropertyVariations ] ); return ( { - let result = { - ...filterObjectByProperty( cloneDeep( variation ), property ), - title: variation?.title, - description: variation?.description, - }; - - if ( clonedBaseVariation ) { - /* - * Overwrites all baseVariation object `styleProperty` properties - * with the theme variation `styleProperty` properties. - */ - result = mergeBaseAndUserConfigs( clonedBaseVariation, result ); - } - return result; - } ); + let processedStyleVariations = variations.reduce( + ( accumulator, variation ) => { + const variationFilteredByProperty = filterObjectByProperty( + cloneDeep( variation ), + property + ); + // Remove variations that are empty once the property is filtered out. + if ( Object.keys( variationFilteredByProperty ).length === 0 ) { + return accumulator; + } + + let result = { + ...variationFilteredByProperty, + title: variation?.title, + description: variation?.description, + }; + + if ( clonedBaseVariation ) { + /* + * Overwrites all baseVariation object `styleProperty` properties + * with the theme variation `styleProperty` properties. + */ + result = mergeBaseAndUserConfigs( + clonedBaseVariation, + result + ); + } + + // Detect if this is a duplicate variation. + const isDuplicate = accumulator.some( ( item ) => { + return ( + JSON.stringify( item.styles ) === + JSON.stringify( result?.styles ) && + JSON.stringify( item.settings ) === + JSON.stringify( result?.settings ) + ); + } ); + if ( isDuplicate ) { + return accumulator; + } + + // If the variation is not a duplicate, add it to the accumulator. + accumulator.push( result ); + return accumulator; + }, + [] // Initial accumulator value. + ); if ( 'function' === typeof filter ) { processedStyleVariations = @@ -178,3 +209,25 @@ export default function useThemeStyleVariationsByProperty( { return processedStyleVariations; }, [ variations, property, baseVariation, filter ] ); } + +/** + * Compares a style variation to the same variation filtered by a single property. + * Returns true if the variation contains only the property specified. + * + * @param {Object} variation The variation to compare. + * @param {string} property The property to compare. + * @return {boolean} Whether the variation contains only a single property. + */ +export function isVariationWithSingleProperty( variation, property ) { + const variationWithProperty = filterObjectByProperty( + cloneDeep( variation ), + property + ); + + return ( + JSON.stringify( variationWithProperty?.styles ) === + JSON.stringify( variation?.styles ) && + JSON.stringify( variationWithProperty?.settings ) === + JSON.stringify( variation?.settings ) + ); +}