@wordpress/global-styles-engine 1.11.0 → 1.11.1-next.v.202604201441.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/core/render.cjs +94 -21
- package/build/core/render.cjs.map +2 -2
- package/build/settings/get-setting.cjs +1 -0
- package/build/settings/get-setting.cjs.map +2 -2
- package/build-module/core/render.mjs +94 -21
- package/build-module/core/render.mjs.map +2 -2
- package/build-module/settings/get-setting.mjs +1 -0
- package/build-module/settings/get-setting.mjs.map +2 -2
- package/build-types/core/render.d.ts.map +1 -1
- package/build-types/settings/get-setting.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/core/render.tsx +133 -44
- package/src/settings/get-setting.ts +1 -0
- package/src/test/render.test.ts +102 -2
package/src/core/render.tsx
CHANGED
|
@@ -156,6 +156,13 @@ const BLOCK_SUPPORT_FEATURE_LEVEL_SELECTORS = {
|
|
|
156
156
|
typography: 'typography',
|
|
157
157
|
};
|
|
158
158
|
|
|
159
|
+
// The valid pseudo-selectors that can be used for blocks.
|
|
160
|
+
// Keep in sync with WP_Theme_JSON_Gutenberg::VALID_BLOCK_PSEUDO_SELECTORS.
|
|
161
|
+
const VALID_BLOCK_PSEUDO_SELECTORS: Record< string, string[] > = {
|
|
162
|
+
'core/button': [ ':hover', ':focus', ':focus-visible', ':active' ],
|
|
163
|
+
'core/navigation-link': [ ':hover', ':focus', ':focus-visible', ':active' ],
|
|
164
|
+
};
|
|
165
|
+
|
|
159
166
|
/**
|
|
160
167
|
* Transform given preset tree into a set of preset class declarations.
|
|
161
168
|
*
|
|
@@ -854,12 +861,23 @@ const STYLE_KEYS = [
|
|
|
854
861
|
];
|
|
855
862
|
|
|
856
863
|
function pickStyleKeys( treeToPickFrom: any ): any {
|
|
864
|
+
return pickStyleAndPseudoKeys( treeToPickFrom );
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
function pickStyleAndPseudoKeys(
|
|
868
|
+
treeToPickFrom: any,
|
|
869
|
+
blockName?: string
|
|
870
|
+
): any {
|
|
857
871
|
if ( ! treeToPickFrom ) {
|
|
858
872
|
return {};
|
|
859
873
|
}
|
|
860
874
|
const entries = Object.entries( treeToPickFrom );
|
|
861
|
-
const
|
|
862
|
-
|
|
875
|
+
const allowedPseudoSelectors = blockName
|
|
876
|
+
? VALID_BLOCK_PSEUDO_SELECTORS[ blockName ] ?? []
|
|
877
|
+
: [];
|
|
878
|
+
const pickedEntries = entries.filter(
|
|
879
|
+
( [ key ] ) =>
|
|
880
|
+
STYLE_KEYS.includes( key ) || allowedPseudoSelectors.includes( key )
|
|
863
881
|
);
|
|
864
882
|
// clone the style objects so that `getFeatureDeclarations` can remove consumed keys from it
|
|
865
883
|
const clonedEntries = pickedEntries.map( ( [ key, style ] ) => [
|
|
@@ -869,6 +887,92 @@ function pickStyleKeys( treeToPickFrom: any ): any {
|
|
|
869
887
|
return Object.fromEntries( clonedEntries );
|
|
870
888
|
}
|
|
871
889
|
|
|
890
|
+
function appendPseudoSelectorStyles(
|
|
891
|
+
styles: Record< string, any >,
|
|
892
|
+
selector: string,
|
|
893
|
+
ruleset: string,
|
|
894
|
+
featureSelectors:
|
|
895
|
+
| string
|
|
896
|
+
| Record< string, string | Record< string, string > >
|
|
897
|
+
| undefined,
|
|
898
|
+
treeSettings: Record< string, any > | undefined,
|
|
899
|
+
blockName: string | undefined,
|
|
900
|
+
styleVariationSelector?: string
|
|
901
|
+
): string {
|
|
902
|
+
const pseudoSelectorStyles = Object.entries( styles ).filter( ( [ key ] ) =>
|
|
903
|
+
key.startsWith( ':' )
|
|
904
|
+
);
|
|
905
|
+
|
|
906
|
+
if ( ! pseudoSelectorStyles.length ) {
|
|
907
|
+
return ruleset;
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
pseudoSelectorStyles.forEach( ( [ pseudoKey, pseudoStyle ] ) => {
|
|
911
|
+
if ( ! pseudoStyle || typeof pseudoStyle !== 'object' ) {
|
|
912
|
+
return;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
const remainingPseudoStyles = JSON.parse(
|
|
916
|
+
JSON.stringify( pseudoStyle )
|
|
917
|
+
);
|
|
918
|
+
|
|
919
|
+
if ( featureSelectors && typeof featureSelectors !== 'string' ) {
|
|
920
|
+
let pseudoFeatureDeclarations = getFeatureDeclarations(
|
|
921
|
+
featureSelectors,
|
|
922
|
+
remainingPseudoStyles
|
|
923
|
+
);
|
|
924
|
+
|
|
925
|
+
pseudoFeatureDeclarations = updateParagraphTextIndentSelector(
|
|
926
|
+
pseudoFeatureDeclarations,
|
|
927
|
+
treeSettings,
|
|
928
|
+
blockName
|
|
929
|
+
);
|
|
930
|
+
|
|
931
|
+
pseudoFeatureDeclarations = updateButtonWidthDeclarations(
|
|
932
|
+
pseudoFeatureDeclarations,
|
|
933
|
+
treeSettings
|
|
934
|
+
);
|
|
935
|
+
|
|
936
|
+
Object.entries( pseudoFeatureDeclarations ).forEach(
|
|
937
|
+
( [ baseSelector, declarations ] ) => {
|
|
938
|
+
if ( ! declarations.length ) {
|
|
939
|
+
return;
|
|
940
|
+
}
|
|
941
|
+
const pseudoFeatureSelector = appendToSelector(
|
|
942
|
+
baseSelector,
|
|
943
|
+
pseudoKey
|
|
944
|
+
);
|
|
945
|
+
const cssSelector = styleVariationSelector
|
|
946
|
+
? concatFeatureVariationSelectorString(
|
|
947
|
+
pseudoFeatureSelector,
|
|
948
|
+
styleVariationSelector
|
|
949
|
+
)
|
|
950
|
+
: pseudoFeatureSelector;
|
|
951
|
+
const rules = declarations.join( ';' );
|
|
952
|
+
ruleset += `:root :where(${ cssSelector }){${ rules };}`;
|
|
953
|
+
}
|
|
954
|
+
);
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
const pseudoDeclarations = getStylesDeclarations(
|
|
958
|
+
remainingPseudoStyles
|
|
959
|
+
);
|
|
960
|
+
|
|
961
|
+
if ( ! pseudoDeclarations.length ) {
|
|
962
|
+
return;
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
const pseudoSelector = appendToSelector( selector, pseudoKey );
|
|
966
|
+
const pseudoRule = `:root :where(${ pseudoSelector }){${ pseudoDeclarations.join(
|
|
967
|
+
';'
|
|
968
|
+
) };}`;
|
|
969
|
+
|
|
970
|
+
ruleset += pseudoRule;
|
|
971
|
+
} );
|
|
972
|
+
|
|
973
|
+
return ruleset;
|
|
974
|
+
}
|
|
975
|
+
|
|
872
976
|
export const getNodesWithStyles = (
|
|
873
977
|
tree: GlobalStylesConfig,
|
|
874
978
|
blockSelectors: string | BlockSelectors
|
|
@@ -920,7 +1024,7 @@ export const getNodesWithStyles = (
|
|
|
920
1024
|
// Iterate over blocks: they can have styles & elements.
|
|
921
1025
|
Object.entries( tree.styles?.blocks ?? {} ).forEach(
|
|
922
1026
|
( [ blockName, node ] ) => {
|
|
923
|
-
const blockStyles =
|
|
1027
|
+
const blockStyles = pickStyleAndPseudoKeys( node, blockName );
|
|
924
1028
|
const typedNode = node as BlockNode;
|
|
925
1029
|
|
|
926
1030
|
// Store variation data for later processing, but don't add to nodes yet.
|
|
@@ -932,8 +1036,10 @@ export const getNodesWithStyles = (
|
|
|
932
1036
|
Object.entries( typedNode.variations ).forEach(
|
|
933
1037
|
( [ variationName, variation ] ) => {
|
|
934
1038
|
const typedVariation = variation as BlockVariation;
|
|
935
|
-
variations[ variationName ] =
|
|
936
|
-
|
|
1039
|
+
variations[ variationName ] = pickStyleAndPseudoKeys(
|
|
1040
|
+
typedVariation,
|
|
1041
|
+
blockName
|
|
1042
|
+
);
|
|
937
1043
|
if ( typedVariation?.css ) {
|
|
938
1044
|
variations[ variationName ].css =
|
|
939
1045
|
typedVariation.css;
|
|
@@ -1002,7 +1108,10 @@ export const getNodesWithStyles = (
|
|
|
1002
1108
|
: undefined;
|
|
1003
1109
|
|
|
1004
1110
|
const variationBlockStyleNodes =
|
|
1005
|
-
|
|
1111
|
+
pickStyleAndPseudoKeys(
|
|
1112
|
+
variationBlockStyles,
|
|
1113
|
+
variationBlockName
|
|
1114
|
+
);
|
|
1006
1115
|
|
|
1007
1116
|
if ( variationBlockStyles?.css ) {
|
|
1008
1117
|
variationBlockStyleNodes.css =
|
|
@@ -1562,6 +1671,17 @@ export const transformToStyles = (
|
|
|
1562
1671
|
`:root :where(${ styleVariationSelector })`
|
|
1563
1672
|
);
|
|
1564
1673
|
}
|
|
1674
|
+
|
|
1675
|
+
ruleset = appendPseudoSelectorStyles(
|
|
1676
|
+
styleVariations,
|
|
1677
|
+
styleVariationSelector as string,
|
|
1678
|
+
ruleset,
|
|
1679
|
+
featureSelectors,
|
|
1680
|
+
tree.settings,
|
|
1681
|
+
name,
|
|
1682
|
+
styleVariationSelector as string
|
|
1683
|
+
);
|
|
1684
|
+
|
|
1565
1685
|
// Generate layout styles for the variation if it supports layout and has blockGap defined.
|
|
1566
1686
|
if (
|
|
1567
1687
|
hasLayoutSupport &&
|
|
@@ -1583,45 +1703,14 @@ export const transformToStyles = (
|
|
|
1583
1703
|
);
|
|
1584
1704
|
}
|
|
1585
1705
|
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1706
|
+
ruleset = appendPseudoSelectorStyles(
|
|
1707
|
+
styles,
|
|
1708
|
+
selector,
|
|
1709
|
+
ruleset,
|
|
1710
|
+
featureSelectors,
|
|
1711
|
+
tree.settings,
|
|
1712
|
+
name
|
|
1589
1713
|
);
|
|
1590
|
-
|
|
1591
|
-
if ( pseudoSelectorStyles?.length ) {
|
|
1592
|
-
pseudoSelectorStyles.forEach(
|
|
1593
|
-
( [ pseudoKey, pseudoStyle ] ) => {
|
|
1594
|
-
const pseudoDeclarations =
|
|
1595
|
-
getStylesDeclarations( pseudoStyle );
|
|
1596
|
-
|
|
1597
|
-
if ( ! pseudoDeclarations?.length ) {
|
|
1598
|
-
return;
|
|
1599
|
-
}
|
|
1600
|
-
|
|
1601
|
-
// `selector` may be provided in a form
|
|
1602
|
-
// where block level selectors have sub element
|
|
1603
|
-
// selectors appended to them as a comma separated
|
|
1604
|
-
// string.
|
|
1605
|
-
// e.g. `h1 a,h2 a,h3 a,h4 a,h5 a,h6 a`;
|
|
1606
|
-
// Split and append pseudo selector to create
|
|
1607
|
-
// the proper rules to target the elements.
|
|
1608
|
-
const _selector = selector
|
|
1609
|
-
.split( ',' )
|
|
1610
|
-
.map( ( sel: string ) => sel + pseudoKey )
|
|
1611
|
-
.join( ',' );
|
|
1612
|
-
|
|
1613
|
-
// As pseudo classes such as :hover, :focus etc. have class-level
|
|
1614
|
-
// specificity, they must use the `:root :where()` wrapper. This.
|
|
1615
|
-
// caps the specificity at `0-1-0` to allow proper nesting of variations
|
|
1616
|
-
// and block type element styles.
|
|
1617
|
-
const pseudoRule = `:root :where(${ _selector }){${ pseudoDeclarations.join(
|
|
1618
|
-
';'
|
|
1619
|
-
) };}`;
|
|
1620
|
-
|
|
1621
|
-
ruleset += pseudoRule;
|
|
1622
|
-
}
|
|
1623
|
-
);
|
|
1624
|
-
}
|
|
1625
1714
|
}
|
|
1626
1715
|
);
|
|
1627
1716
|
}
|
package/src/test/render.test.ts
CHANGED
|
@@ -652,6 +652,106 @@ describe( 'global styles renderer', () => {
|
|
|
652
652
|
);
|
|
653
653
|
} );
|
|
654
654
|
|
|
655
|
+
it( 'should handle block pseudo selectors', () => {
|
|
656
|
+
const tree = {
|
|
657
|
+
styles: {
|
|
658
|
+
blocks: {
|
|
659
|
+
'core/button': {
|
|
660
|
+
color: {
|
|
661
|
+
text: 'red',
|
|
662
|
+
},
|
|
663
|
+
':hover': {
|
|
664
|
+
color: {
|
|
665
|
+
text: 'blue',
|
|
666
|
+
},
|
|
667
|
+
},
|
|
668
|
+
},
|
|
669
|
+
},
|
|
670
|
+
},
|
|
671
|
+
} as unknown as GlobalStylesConfig;
|
|
672
|
+
|
|
673
|
+
const blockSelectors = {
|
|
674
|
+
'core/button': {
|
|
675
|
+
selector: '.wp-block-button',
|
|
676
|
+
},
|
|
677
|
+
};
|
|
678
|
+
|
|
679
|
+
const result = transformToStyles(
|
|
680
|
+
Object.freeze( tree ),
|
|
681
|
+
blockSelectors,
|
|
682
|
+
false,
|
|
683
|
+
false,
|
|
684
|
+
true,
|
|
685
|
+
true,
|
|
686
|
+
{
|
|
687
|
+
blockGap: false,
|
|
688
|
+
blockStyles: true,
|
|
689
|
+
layoutStyles: false,
|
|
690
|
+
marginReset: false,
|
|
691
|
+
presets: false,
|
|
692
|
+
rootPadding: false,
|
|
693
|
+
}
|
|
694
|
+
);
|
|
695
|
+
|
|
696
|
+
expect( result ).toEqual(
|
|
697
|
+
':root :where(.wp-block-button){color: red;}:root :where(.wp-block-button:hover){color: blue;}'
|
|
698
|
+
);
|
|
699
|
+
} );
|
|
700
|
+
|
|
701
|
+
it( 'should handle style variation pseudo selectors', () => {
|
|
702
|
+
const tree = {
|
|
703
|
+
styles: {
|
|
704
|
+
blocks: {
|
|
705
|
+
'core/button': {
|
|
706
|
+
variations: {
|
|
707
|
+
foo: {
|
|
708
|
+
color: {
|
|
709
|
+
text: 'green',
|
|
710
|
+
},
|
|
711
|
+
':hover': {
|
|
712
|
+
color: {
|
|
713
|
+
text: 'yellow',
|
|
714
|
+
},
|
|
715
|
+
},
|
|
716
|
+
},
|
|
717
|
+
},
|
|
718
|
+
},
|
|
719
|
+
},
|
|
720
|
+
},
|
|
721
|
+
} as unknown as GlobalStylesConfig;
|
|
722
|
+
|
|
723
|
+
const blockSelectors = {
|
|
724
|
+
'core/button': {
|
|
725
|
+
selector: '.wp-block-button',
|
|
726
|
+
styleVariationSelectors: {
|
|
727
|
+
foo: '.is-style-foo.wp-block-button',
|
|
728
|
+
},
|
|
729
|
+
},
|
|
730
|
+
};
|
|
731
|
+
|
|
732
|
+
const result = transformToStyles(
|
|
733
|
+
Object.freeze( tree ),
|
|
734
|
+
blockSelectors,
|
|
735
|
+
false,
|
|
736
|
+
false,
|
|
737
|
+
true,
|
|
738
|
+
true,
|
|
739
|
+
{
|
|
740
|
+
blockGap: false,
|
|
741
|
+
blockStyles: true,
|
|
742
|
+
layoutStyles: false,
|
|
743
|
+
marginReset: false,
|
|
744
|
+
presets: false,
|
|
745
|
+
rootPadding: false,
|
|
746
|
+
variationStyles: true,
|
|
747
|
+
}
|
|
748
|
+
);
|
|
749
|
+
|
|
750
|
+
expect( result ).toEqual(
|
|
751
|
+
':root :where(.is-style-foo.wp-block-button){color: green;}:root :where(.is-style-foo.wp-block-button:hover){color: yellow;}'
|
|
752
|
+
);
|
|
753
|
+
} );
|
|
754
|
+
|
|
655
755
|
it( 'should handle duotone filter', () => {
|
|
656
756
|
const tree = {
|
|
657
757
|
styles: {
|
|
@@ -991,7 +1091,7 @@ describe( 'global styles renderer', () => {
|
|
|
991
1091
|
} );
|
|
992
1092
|
|
|
993
1093
|
it( 'should convert preset percentage width to calc() formula', () => {
|
|
994
|
-
const tree
|
|
1094
|
+
const tree = {
|
|
995
1095
|
settings: {
|
|
996
1096
|
blocks: {
|
|
997
1097
|
'core/button': {
|
|
@@ -1018,7 +1118,7 @@ describe( 'global styles renderer', () => {
|
|
|
1018
1118
|
},
|
|
1019
1119
|
},
|
|
1020
1120
|
},
|
|
1021
|
-
};
|
|
1121
|
+
} as unknown as GlobalStylesConfig;
|
|
1022
1122
|
|
|
1023
1123
|
const blockSelectors = {
|
|
1024
1124
|
'core/button': {
|