-
Notifications
You must be signed in to change notification settings - Fork 4.3k
/
Copy pathstyle-variations-container.js
130 lines (119 loc) · 3.7 KB
/
style-variations-container.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/**
* WordPress dependencies
*/
import { store as coreStore } from '@wordpress/core-data';
import { useSelect } from '@wordpress/data';
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
).__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 themeVariations = useMemo( () => {
const withEmptyVariation = [
{
title: __( 'Default' ),
settings: {},
styles: {},
},
...( multiplePropertyVariations ?? [] ),
];
return [
...withEmptyVariation.map( ( variation ) => {
const blockStyles = { ...variation?.styles?.blocks } || {};
// 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 ) {
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, userStyles?.blocks, userStyles?.css ] );
return (
<Grid
columns={ 2 }
className="edit-site-global-styles-style-variations-container"
gap={ gap }
>
{ themeVariations.map( ( variation, index ) => (
<Variation key={ index } variation={ variation }>
{ ( isFocused ) => (
<PreviewStyles
label={ variation?.title }
withHoverView
isFocused={ isFocused }
variation={ variation }
/>
) }
</Variation>
) ) }
</Grid>
);
}