diff --git a/packages/edit-site/src/components/global-styles/color-palette-panel.js b/packages/edit-site/src/components/global-styles/color-palette-panel.js index 1a8b503581c99..71fe04a33baad 100644 --- a/packages/edit-site/src/components/global-styles/color-palette-panel.js +++ b/packages/edit-site/src/components/global-styles/color-palette-panel.js @@ -14,7 +14,7 @@ import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor'; */ import { unlock } from '../../lock-unlock'; import ColorVariations from './variations-color'; -import useThemeStyleVariationsByProperty from './use-theme-style-variations-by-property'; +import { useCurrentMergeThemeStyleVariationsWithUserConfig } from '../../hooks/use-theme-style-variations/use-theme-style-variations-by-property'; const { useGlobalSetting } = unlock( blockEditorPrivateApis ); const mobilePopoverProps = { placement: 'bottom-start', offset: 8 }; @@ -47,8 +47,8 @@ export default function ColorPalettePanel( { name } ) { 'color.defaultPalette', name ); - const colorVariations = useThemeStyleVariationsByProperty( { - styleProperty: 'color', + const colorVariations = useCurrentMergeThemeStyleVariationsWithUserConfig( { + property: 'color', filter: ( variation ) => variation?.settings?.color && Object.keys( variation?.settings?.color ).length, diff --git a/packages/edit-site/src/components/global-styles/screen-typography.js b/packages/edit-site/src/components/global-styles/screen-typography.js index 1383c6c5dfecb..1208889292319 100644 --- a/packages/edit-site/src/components/global-styles/screen-typography.js +++ b/packages/edit-site/src/components/global-styles/screen-typography.js @@ -20,7 +20,7 @@ import TypographyElements from './typogrphy-elements'; import FontFamilies from './font-families'; import ScreenHeader from './header'; import { NavigationButtonAsItem } from './navigation-button'; -import useThemeStyleVariationsByProperty from './use-theme-style-variations-by-property'; +import { useCurrentMergeThemeStyleVariationsWithUserConfig } from '../../hooks/use-theme-style-variations/use-theme-style-variations-by-property'; function ScreenTypography() { const fontLibraryEnabled = useSelect( @@ -28,12 +28,14 @@ function ScreenTypography() { select( editorStore ).getEditorSettings().fontLibraryEnabled, [] ); - const typographyVariations = useThemeStyleVariationsByProperty( { - styleProperty: 'typography', - filter: ( variation ) => - variation?.settings?.typography?.fontFamilies && - Object.keys( variation?.settings?.typography?.fontFamilies ).length, - } ); + const typographyVariations = + useCurrentMergeThemeStyleVariationsWithUserConfig( { + property: 'typography', + filter: ( variation ) => + variation?.settings?.typography?.fontFamilies && + Object.keys( variation?.settings?.typography?.fontFamilies ) + .length, + } ); return ( <> diff --git a/packages/edit-site/src/components/global-styles/use-theme-style-variations-by-property.js b/packages/edit-site/src/components/global-styles/use-theme-style-variations-by-property.js deleted file mode 100644 index f7305561680c1..0000000000000 --- a/packages/edit-site/src/components/global-styles/use-theme-style-variations-by-property.js +++ /dev/null @@ -1,125 +0,0 @@ -/** - * 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 ] ); -} diff --git a/packages/edit-site/src/components/global-styles/variations-typography.js b/packages/edit-site/src/components/global-styles/variations-typography.js index 8470db2870e97..e845e4ac7c5c8 100644 --- a/packages/edit-site/src/components/global-styles/variations-typography.js +++ b/packages/edit-site/src/components/global-styles/variations-typography.js @@ -21,7 +21,7 @@ import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor'; import { mergeBaseAndUserConfigs } from './global-styles-provider'; import { unlock } from '../../lock-unlock'; import { getFamilyPreviewStyle } from './font-library-modal/utils/preview-styles'; -import useThemeStyleVariationsByProperty from './use-theme-style-variations-by-property'; +import { useCurrentMergeThemeStyleVariationsWithUserConfig } from '../../hooks/use-theme-style-variations/use-theme-style-variations-by-property'; import Subtitle from './subtitle'; const { GlobalStylesContext, areGlobalStyleConfigsEqual } = unlock( @@ -166,12 +166,14 @@ function TypographyVariation( { variation } ) { } export default function TypographyVariations() { - const typographyVariations = useThemeStyleVariationsByProperty( { - styleProperty: 'typography', - filter: ( variation ) => - variation?.settings?.typography?.fontFamilies && - Object.keys( variation?.settings?.typography?.fontFamilies ).length, - } ); + const typographyVariations = + useCurrentMergeThemeStyleVariationsWithUserConfig( { + property: 'typography', + filter: ( variation ) => + variation?.settings?.typography?.fontFamilies && + Object.keys( variation?.settings?.typography?.fontFamilies ) + .length, + } ); const { base } = useContext( GlobalStylesContext ); const uniqueTypographyVariations = []; diff --git a/packages/edit-site/src/hooks/use-theme-style-variations/use-theme-style-variations-by-property.js b/packages/edit-site/src/hooks/use-theme-style-variations/use-theme-style-variations-by-property.js index b9c1b40ec7c1d..aff5c95ed8809 100644 --- a/packages/edit-site/src/hooks/use-theme-style-variations/use-theme-style-variations-by-property.js +++ b/packages/edit-site/src/hooks/use-theme-style-variations/use-theme-style-variations-by-property.js @@ -1,13 +1,47 @@ /** * WordPress dependencies */ -import { useMemo } from '@wordpress/element'; +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 { mergeBaseAndUserConfigs } from '../../components/global-styles/global-styles-provider'; import cloneDeep from '../../utils/clone-deep'; +import { unlock } from '../../lock-unlock'; + +const { GlobalStylesContext } = unlock( blockEditorPrivateApis ); + +/** + * Fetches the current theme style variations, filters them by the provided property, + * and merges with current user-defined global style/settings object. + * + * @param {Object} props Object of hook args. + * @param {string} props.property The property to filter by. + * @param {Function} props.filter Optional. The filter function to apply to the variations. + * @return {Object[]|*} The merged object. + */ +export function useCurrentMergeThemeStyleVariationsWithUserConfig( { + property, + filter, +} ) { + const variations = useSelect( ( select ) => { + return select( + coreStore + ).__experimentalGetCurrentThemeGlobalStylesVariations(); + }, [] ); + const { user: baseVariation } = useContext( GlobalStylesContext ); + + return useThemeStyleVariationsByProperty( { + variations, + property, + filter, + baseVariation, + } ); +} /** * Returns a new object, with properties specified in `property`,