Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
Pulling out the utils from #56622 so we test separately
  • Loading branch information
ramonjd committed Feb 8, 2024
1 parent 5b11266 commit 0da4136
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/**
* WordPress dependencies
*/
import { useSelect } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';
import { useContext, useMemo } from '@wordpress/element';
import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor';

/**
* Internal dependencies
*/
import { unlock } from '../../lock-unlock';
import cloneDeep from '../../utils/clone-deep';
import { mergeBaseAndUserConfigs } from './global-styles-provider';
/**
* Returns a new object with only the properties specified in `properties`.
*
* @param {Object} object The object to filter
* @param {Object} property The property to filter by
* @return {Object} The merged object.
*/
export const filterObjectByProperty = ( object, property ) => {
if ( ! object ) {
return {};
}

const newObject = {};
Object.keys( object ).forEach( ( key ) => {
if ( key === property ) {
newObject[ key ] = object[ key ];
} else if ( typeof object[ key ] === 'object' ) {
const newFilter = filterObjectByProperty( object[ key ], property );
if ( Object.keys( newFilter ).length ) {
newObject[ key ] = newFilter;
}
}
} );
return newObject;
};

/**
* Removes all instances of a property from an object.
*
* @param {Object} object
* @param {string} property
* @return {Object} The modified object.
*/
const removePropertyFromObject = ( object, property ) => {
for ( const key in object ) {
if ( key === property ) {
delete object[ key ];
} else if ( typeof object[ key ] === 'object' ) {
removePropertyFromObject( object[ key ], property );
}
}
return object;
};

/**
* Return style variations with all properties removed except for the one specified in `type`.
*
* @param {Object} user The user variation.
* @param {Array} variations The other style variations.
* @param {string} property The property to filter by.
*
* @return {Array} The style variation with only the specified property filtered.
*/
export const getVariationsByProperty = ( user, variations, property ) => {
const userSettingsWithoutProperty = removePropertyFromObject(
cloneDeep( user ),
property
);

const variationsWithOnlyProperty = variations.map( ( variation ) => {
return {
...filterObjectByProperty( variation, property ),
// Add variation title and description to every variation item.
title: variation?.title,
description: variation?.description,
};
} );

return variationsWithOnlyProperty.map( ( variation ) =>
mergeBaseAndUserConfigs( userSettingsWithoutProperty, variation )
);
};

const { GlobalStylesContext } = unlock( blockEditorPrivateApis );

export default function useThemeStyleVariationsByProperty( {
styleProperty,
filter,
} ) {
const variations = useSelect( ( select ) => {
return select(
coreStore
).__experimentalGetCurrentThemeGlobalStylesVariations();
}, [] );
const { user } = useContext( GlobalStylesContext );

return useMemo( () => {
if ( ! styleProperty || ! variations.length ) {
return [];
}
/*
@TODO:
For colors, should also get filter?
Memoize/cache all this better? E.g., should we memoize the variations?
Test with empty theme
Test with 2022 - typography font families bork for some reason
*/
let styleVariations = getVariationsByProperty(
user,
variations,
styleProperty
);

if ( 'function' === typeof filter ) {
styleVariations = styleVariations.filter( filter );
}

return styleVariations;
}, [ styleProperty, variations, filter ] );
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { store as coreStore } from '@wordpress/core-data';
*/
import { useSupportedStyles } from '../../components/global-styles/hooks';
import { unlock } from '../../lock-unlock';
import cloneDeep from '../../utils/clone-deep';

const { cleanEmptyObject, GlobalStylesContext } = unlock(
blockEditorPrivateApis
Expand Down Expand Up @@ -275,10 +276,6 @@ function setNestedValue( object, path, value ) {
return object;
}

function cloneDeep( object ) {
return ! object ? {} : JSON.parse( JSON.stringify( object ) );
}

function PushChangesToGlobalStylesControl( {
name,
attributes,
Expand Down
8 changes: 8 additions & 0 deletions packages/edit-site/src/utils/clone-deep.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* Makes a copy of an object without storing any references to the original object.
* @param {Object} object
* @return {Object} The cloned object.
*/
export default function cloneDeep( object ) {
return ! object ? {} : JSON.parse( JSON.stringify( object ) );
}

0 comments on commit 0da4136

Please sign in to comment.