Skip to content

Commit c34ca0a

Browse files
Update JS processing of block style variations
1 parent 4c37968 commit c34ca0a

File tree

3 files changed

+232
-15
lines changed

3 files changed

+232
-15
lines changed

packages/block-editor/src/components/global-styles/test/use-global-styles-output.js

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,35 @@ describe( 'global styles renderer', () => {
2828
text: 'red',
2929
},
3030
blocks: {
31+
'core/group': {
32+
color: {
33+
background: 'linen',
34+
},
35+
variations: {
36+
foo: {
37+
color: 'aliceblue',
38+
blocks: {
39+
'core/heading': {
40+
typography: {
41+
fontSize: '3em',
42+
},
43+
},
44+
},
45+
elements: {
46+
link: {
47+
color: {
48+
text: 'darkcyan',
49+
},
50+
':hover': {
51+
color: {
52+
text: 'darkturqoise',
53+
},
54+
},
55+
},
56+
},
57+
},
58+
},
59+
},
3160
'core/heading': {
3261
color: {
3362
background: 'blue',
@@ -89,6 +118,12 @@ describe( 'global styles renderer', () => {
89118
},
90119
};
91120
const blockSelectors = {
121+
'core/group': {
122+
selector: '.my-group',
123+
styleVariationSelectors: {
124+
foo: '.is-style-foo.my-group',
125+
},
126+
},
92127
'core/heading': {
93128
selector: '.my-heading1, .my-heading2',
94129
},
@@ -129,6 +164,44 @@ describe( 'global styles renderer', () => {
129164
},
130165
selector: ELEMENTS.link,
131166
},
167+
{
168+
selector:
169+
'.is-style-foo.my-group .my-heading1, .is-style-foo.my-group .my-heading2',
170+
styles: {
171+
typography: {
172+
fontSize: '3em',
173+
},
174+
},
175+
},
176+
{
177+
selector: '.is-style-foo.my-group a',
178+
styles: {
179+
color: {
180+
text: 'darkcyan',
181+
},
182+
':hover': {
183+
color: {
184+
text: 'darkturqoise',
185+
},
186+
},
187+
},
188+
},
189+
{
190+
selector: '.my-group',
191+
styles: {
192+
color: {
193+
background: 'linen',
194+
},
195+
variations: {
196+
foo: {
197+
color: 'aliceblue',
198+
},
199+
},
200+
},
201+
styleVariationSelectors: {
202+
foo: '.is-style-foo.my-group',
203+
},
204+
},
132205
{
133206
styles: {
134207
color: {
@@ -549,6 +622,44 @@ describe( 'global styles renderer', () => {
549622
},
550623
},
551624
},
625+
'core/group': {
626+
variations: {
627+
bar: {
628+
color: {
629+
background: 'midnightblue',
630+
text: 'lightskyblue',
631+
},
632+
blocks: {
633+
'core/heading': {
634+
color: {
635+
text: 'royalblue',
636+
},
637+
},
638+
'core/image': {
639+
border: {
640+
color: 'darkcyan',
641+
style: 'dashed',
642+
width: '5px',
643+
},
644+
},
645+
},
646+
elements: {
647+
h2: {
648+
color: {
649+
text: 'turquoise',
650+
},
651+
},
652+
button: {
653+
color: {
654+
background: 'midnightblue',
655+
text: 'powderblue',
656+
},
657+
':hover': {},
658+
},
659+
},
660+
},
661+
},
662+
},
552663
},
553664
},
554665
};
@@ -567,11 +678,21 @@ describe( 'global styles renderer', () => {
567678
foo: '.is-style-foo.wp-image',
568679
},
569680
},
681+
'core/group': {
682+
selector: '.wp-group',
683+
styleVariationSelectors: {
684+
bar: '.is-style-bar.wp-group',
685+
},
686+
},
687+
'core/heading': {
688+
selector: '.wp-heading',
689+
},
570690
};
571691

572692
expect( toStyles( Object.freeze( tree ), blockSelectors ) ).toEqual(
573693
'body {margin: 0;}body .is-layout-flow > .alignleft { float: left; margin-inline-start: 0; margin-inline-end: 2em; }body .is-layout-flow > .alignright { float: right; margin-inline-start: 2em; margin-inline-end: 0; }body .is-layout-flow > .aligncenter { margin-left: auto !important; margin-right: auto !important; }body .is-layout-constrained > .alignleft { float: left; margin-inline-start: 0; margin-inline-end: 2em; }body .is-layout-constrained > .alignright { float: right; margin-inline-start: 2em; margin-inline-end: 0; }body .is-layout-constrained > .aligncenter { margin-left: auto !important; margin-right: auto !important; }body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)) { max-width: var(--wp--style--global--content-size); margin-left: auto !important; margin-right: auto !important; }body .is-layout-constrained > .alignwide { max-width: var(--wp--style--global--wide-size); }body .is-layout-flex { display:flex; }body .is-layout-flex { flex-wrap: wrap; align-items: center; }body .is-layout-flex > * { margin: 0; }body .is-layout-grid { display:grid; }body .is-layout-grid > * { margin: 0; }' +
574694
'.is-style-foo.wp-image.wp-image-spacing{padding-top: 2px;}.is-style-foo.wp-image.wp-image-border-color{border-color: blue;}.is-style-foo.wp-image{color: blue;}' +
695+
'.is-style-bar.wp-group .wp-heading{color: royalblue;}.is-style-bar.wp-group .wp-image-border-color{border-color: darkcyan;}.is-style-bar.wp-group .wp-image-border{border-style: dashed;border-width: 5px;}.is-style-bar.wp-group h2{color: turquoise;}.is-style-bar.wp-group .wp-element-button, .is-style-bar.wp-group .wp-block-button__link{color: powderblue;background-color: midnightblue;}.is-style-bar.wp-group{color: lightskyblue;background-color: midnightblue;}' +
575696
'.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }'
576697
);
577698
} );

packages/block-editor/src/components/global-styles/use-global-styles-output.js

Lines changed: 107 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,33 @@ function pickStyleKeys( treeToPickFrom ) {
607607
return Object.fromEntries( clonedEntries );
608608
}
609609

610+
function scopeFeatureSelectors( scope, selectors ) {
611+
if ( ! scope || ! selectors ) {
612+
return;
613+
}
614+
615+
const featureSelectors = JSON.parse( JSON.stringify( selectors ) );
616+
617+
Object.entries( selectors ).forEach( ( [ feature, selector ] ) => {
618+
if ( typeof selector === 'string' ) {
619+
featureSelectors[ feature ] = scopeSelector( scope, selector );
620+
}
621+
622+
if ( typeof selector === 'object' ) {
623+
Object.entries( selector ).forEach(
624+
( [ subfeature, subfeatureSelector ] ) => {
625+
featureSelectors[ feature ][ subfeature ] = scopeSelector(
626+
scope,
627+
subfeatureSelector
628+
);
629+
}
630+
);
631+
}
632+
} );
633+
634+
return featureSelectors;
635+
}
636+
610637
export const getNodesWithStyles = ( tree, blockSelectors ) => {
611638
const nodes = [];
612639

@@ -639,14 +666,78 @@ export const getNodesWithStyles = ( tree, blockSelectors ) => {
639666

640667
if ( node?.variations ) {
641668
const variations = {};
642-
Object.keys( node.variations ).forEach( ( variation ) => {
643-
variations[ variation ] = pickStyleKeys(
644-
node.variations[ variation ]
645-
);
646-
} );
669+
670+
Object.entries( node.variations ).forEach(
671+
( [ variationName, variation ] ) => {
672+
variations[ variationName ] =
673+
pickStyleKeys( variation );
674+
const variationSelector =
675+
blockSelectors[ blockName ].styleVariationSelectors[
676+
variationName
677+
];
678+
679+
// Process the variations inner block type styles.
680+
Object.entries( variation.blocks ?? {} ).forEach(
681+
( [
682+
variationBlockName,
683+
variationBlockStyles,
684+
] ) => {
685+
const variationBlockSelector = scopeSelector(
686+
variationSelector,
687+
blockSelectors[ variationBlockName ]
688+
.selector
689+
);
690+
const variationDuotoneSelector = scopeSelector(
691+
variationSelector,
692+
blockSelectors[ variationBlockName ]
693+
.duotoneSelector
694+
);
695+
const variationFeatureSelectors =
696+
scopeFeatureSelectors(
697+
variationSelector,
698+
blockSelectors[ variationBlockName ]
699+
.featureSelectors
700+
);
701+
702+
// TODO: Do we need to delay pushing these nodes so they come after the original block's node?
703+
nodes.push( {
704+
selector: variationBlockSelector,
705+
duotoneSelector: variationDuotoneSelector,
706+
featureSelectors: variationFeatureSelectors,
707+
fallbackGapValue:
708+
blockSelectors[ variationBlockName ]
709+
.fallbackGapValue,
710+
hasLayoutSupport:
711+
blockSelectors[ variationBlockName ]
712+
.hasLayoutSupport,
713+
styles: pickStyleKeys(
714+
variationBlockStyles
715+
),
716+
} );
717+
}
718+
);
719+
720+
// Process the variations inner element styles.
721+
Object.entries( variation.elements ?? {} ).forEach(
722+
( [ element, elementStyles ] ) => {
723+
if ( elementStyles && ELEMENTS[ element ] ) {
724+
nodes.push( {
725+
styles: elementStyles,
726+
selector: scopeSelector(
727+
variationSelector,
728+
ELEMENTS[ element ]
729+
),
730+
} );
731+
}
732+
}
733+
);
734+
}
735+
);
736+
647737
blockStyles.variations = variations;
648738
}
649-
if ( blockStyles && blockSelectors?.[ blockName ]?.selector ) {
739+
740+
if ( blockSelectors?.[ blockName ]?.selector ) {
650741
nodes.push( {
651742
duotoneSelector:
652743
blockSelectors[ blockName ].duotoneSelector,
@@ -839,6 +930,7 @@ export const toStyles = (
839930
( [ styleVariationName, styleVariationSelector ] ) => {
840931
const styleVariations =
841932
styles?.variations?.[ styleVariationName ];
933+
842934
if ( styleVariations ) {
843935
// If the block uses any custom selectors for block support, add those first.
844936
if ( featureSelectors ) {
@@ -856,6 +948,7 @@ export const toStyles = (
856948
baseSelector,
857949
styleVariationSelector
858950
);
951+
859952
const rules =
860953
declarations.join( ';' );
861954
ruleset += `${ cssSelector }{${ rules };}`;
@@ -872,6 +965,7 @@ export const toStyles = (
872965
useRootPaddingAlign,
873966
tree
874967
);
968+
875969
if ( styleVariationDeclarations.length ) {
876970
ruleset += `${ styleVariationSelector }{${ styleVariationDeclarations.join(
877971
';'
@@ -1065,13 +1159,12 @@ export const getBlockSelectors = ( blockTypes, getBlockStyles ) => {
10651159

10661160
const blockStyleVariations = getBlockStyles( name );
10671161
const styleVariationSelectors = {};
1068-
if ( blockStyleVariations?.length ) {
1069-
blockStyleVariations.forEach( ( variation ) => {
1070-
const styleVariationSelector = `.is-style-${ variation.name }${ selector }`;
1071-
styleVariationSelectors[ variation.name ] =
1072-
styleVariationSelector;
1073-
} );
1074-
}
1162+
1163+
blockStyleVariations?.forEach( ( variation ) => {
1164+
const styleVariationSelector = `.is-style-${ variation.name }${ selector }`;
1165+
styleVariationSelectors[ variation.name ] = styleVariationSelector;
1166+
} );
1167+
10751168
// For each block support feature add any custom selectors.
10761169
const featureSelectors = getSelectorsConfig( blockType, selector );
10771170

@@ -1084,8 +1177,7 @@ export const getBlockSelectors = ( blockTypes, getBlockStyles ) => {
10841177
hasLayoutSupport,
10851178
name,
10861179
selector,
1087-
styleVariationSelectors: Object.keys( styleVariationSelectors )
1088-
.length
1180+
styleVariationSelectors: blockStyleVariations?.length
10891181
? styleVariationSelectors
10901182
: undefined,
10911183
};

packages/block-editor/src/components/global-styles/utils.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,10 @@ export function getValueFromVariable( features, blockName, variable ) {
380380
* @return {string} Scoped selector.
381381
*/
382382
export function scopeSelector( scope, selector ) {
383+
if ( ! scope || ! selector ) {
384+
return selector;
385+
}
386+
383387
const scopes = scope.split( ',' );
384388
const selectors = selector.split( ',' );
385389

0 commit comments

Comments
 (0)