@wordpress/global-styles-engine 1.12.0 → 1.12.1-next.v.202605131032.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.
@@ -42,6 +42,30 @@ var VALID_BLOCK_PSEUDO_SELECTORS = {
42
42
  "core/button": [":hover", ":focus", ":focus-visible", ":active"],
43
43
  "core/navigation-link": [":hover", ":focus", ":focus-visible", ":active"]
44
44
  };
45
+ var VALID_ELEMENT_PSEUDO_SELECTORS = {
46
+ link: [
47
+ ":link",
48
+ ":any-link",
49
+ ":visited",
50
+ ":hover",
51
+ ":focus",
52
+ ":focus-visible",
53
+ ":active"
54
+ ],
55
+ button: [
56
+ ":link",
57
+ ":any-link",
58
+ ":visited",
59
+ ":hover",
60
+ ":focus",
61
+ ":focus-visible",
62
+ ":active"
63
+ ]
64
+ };
65
+ var RESPONSIVE_BREAKPOINTS = {
66
+ mobile: "@media (width <= 480px)",
67
+ tablet: "@media (480px < width <= 782px)"
68
+ };
45
69
  function getPresetsClasses(blockSelector = "*", blockPresets = {}) {
46
70
  return PRESET_METADATA.reduce(
47
71
  (declarations, { path, cssVarInfix, classes }) => {
@@ -423,7 +447,7 @@ function pickStyleAndPseudoKeys(treeToPickFrom, blockName) {
423
447
  const entries = Object.entries(treeToPickFrom);
424
448
  const allowedPseudoSelectors = blockName ? VALID_BLOCK_PSEUDO_SELECTORS[blockName] ?? [] : [];
425
449
  const pickedEntries = entries.filter(
426
- ([key]) => STYLE_KEYS.includes(key) || allowedPseudoSelectors.includes(key)
450
+ ([key]) => STYLE_KEYS.includes(key) || allowedPseudoSelectors.includes(key) || RESPONSIVE_BREAKPOINTS[key]
427
451
  );
428
452
  const clonedEntries = pickedEntries.map(([key, style]) => [
429
453
  key,
@@ -431,65 +455,100 @@ function pickStyleAndPseudoKeys(treeToPickFrom, blockName) {
431
455
  ]);
432
456
  return Object.fromEntries(clonedEntries);
433
457
  }
434
- function appendPseudoSelectorStyles(styles, selector, ruleset, featureSelectors, treeSettings, blockName, styleVariationSelector) {
435
- const pseudoSelectorStyles = Object.entries(styles).filter(
436
- ([key]) => key.startsWith(":")
437
- );
438
- if (!pseudoSelectorStyles.length) {
439
- return ruleset;
458
+ function getPseudoStyleNodes(node) {
459
+ const {
460
+ styles,
461
+ selector,
462
+ featureSelectors,
463
+ name,
464
+ elementName,
465
+ mediaQuery
466
+ } = node;
467
+ const pseudoSelectors = name ? VALID_BLOCK_PSEUDO_SELECTORS[name] ?? [] : VALID_ELEMENT_PSEUDO_SELECTORS[elementName ?? ""] ?? [];
468
+ if (!pseudoSelectors.length) {
469
+ return [];
440
470
  }
441
- pseudoSelectorStyles.forEach(([pseudoKey, pseudoStyle]) => {
442
- if (!pseudoStyle || typeof pseudoStyle !== "object") {
443
- return;
471
+ return pseudoSelectors.flatMap((pseudoSelector) => {
472
+ const pseudoStyles = styles?.[pseudoSelector];
473
+ if (!pseudoStyles || typeof pseudoStyles !== "object") {
474
+ return [];
444
475
  }
445
- const remainingPseudoStyles = JSON.parse(
446
- JSON.stringify(pseudoStyle)
447
- );
448
- if (featureSelectors && typeof featureSelectors !== "string") {
449
- let pseudoFeatureDeclarations = getFeatureDeclarations(
450
- featureSelectors,
451
- remainingPseudoStyles
452
- );
453
- pseudoFeatureDeclarations = updateParagraphTextIndentSelector(
454
- pseudoFeatureDeclarations,
455
- treeSettings,
456
- blockName
457
- );
458
- pseudoFeatureDeclarations = updateButtonWidthDeclarations(
459
- pseudoFeatureDeclarations,
460
- treeSettings
461
- );
462
- Object.entries(pseudoFeatureDeclarations).forEach(
463
- ([baseSelector, declarations]) => {
464
- if (!declarations.length) {
465
- return;
466
- }
467
- const pseudoFeatureSelector = appendToSelector(
468
- baseSelector,
469
- pseudoKey
470
- );
471
- const cssSelector = styleVariationSelector ? concatFeatureVariationSelectorString(
472
- pseudoFeatureSelector,
473
- styleVariationSelector
474
- ) : pseudoFeatureSelector;
475
- const rules = declarations.join(";");
476
- ruleset += `:root :where(${cssSelector}){${rules};}`;
476
+ return [
477
+ {
478
+ styles: JSON.parse(JSON.stringify(pseudoStyles)),
479
+ selector,
480
+ selectorSuffix: pseudoSelector,
481
+ mediaQuery,
482
+ featureSelectors: featureSelectors && typeof featureSelectors !== "string" ? featureSelectors : void 0,
483
+ name,
484
+ elementName
485
+ }
486
+ ];
487
+ });
488
+ }
489
+ function getResponsiveStyleNodes(node) {
490
+ const {
491
+ styles,
492
+ selector,
493
+ featureSelectors,
494
+ name,
495
+ elementName,
496
+ isStyleVariation
497
+ } = node;
498
+ if (!name && !elementName) {
499
+ return [];
500
+ }
501
+ return Object.entries(RESPONSIVE_BREAKPOINTS).flatMap(
502
+ ([breakpointKey, mediaQuery]) => {
503
+ const breakpointStyles = styles?.[breakpointKey];
504
+ if (!breakpointStyles || typeof breakpointStyles !== "object") {
505
+ return [];
506
+ }
507
+ return [
508
+ {
509
+ styles: JSON.parse(JSON.stringify(breakpointStyles)),
510
+ selector,
511
+ mediaQuery,
512
+ featureSelectors: featureSelectors && typeof featureSelectors !== "string" ? featureSelectors : void 0,
513
+ name,
514
+ elementName,
515
+ isStyleVariation
477
516
  }
478
- );
479
- }
480
- const pseudoDeclarations = getStylesDeclarations(
481
- remainingPseudoStyles
482
- );
483
- if (!pseudoDeclarations.length) {
484
- return;
517
+ ];
485
518
  }
486
- const pseudoSelector = appendToSelector(selector, pseudoKey);
487
- const pseudoRule = `:root :where(${pseudoSelector}){${pseudoDeclarations.join(
488
- ";"
489
- )};}`;
490
- ruleset += pseudoRule;
491
- });
492
- return ruleset;
519
+ );
520
+ }
521
+ function getVariationFeatureSelectors(featureSelectors, styleVariationSelector) {
522
+ if (!featureSelectors || typeof featureSelectors === "string") {
523
+ return void 0;
524
+ }
525
+ return Object.fromEntries(
526
+ Object.entries(featureSelectors).map(([feature, selector]) => {
527
+ if (typeof selector === "string") {
528
+ return [
529
+ feature,
530
+ concatFeatureVariationSelectorString(
531
+ selector,
532
+ styleVariationSelector
533
+ )
534
+ ];
535
+ }
536
+ return [
537
+ feature,
538
+ Object.fromEntries(
539
+ Object.entries(selector).map(
540
+ ([subfeature, subfeatureSelector]) => [
541
+ subfeature,
542
+ concatFeatureVariationSelectorString(
543
+ subfeatureSelector,
544
+ styleVariationSelector
545
+ )
546
+ ]
547
+ )
548
+ )
549
+ ];
550
+ })
551
+ );
493
552
  }
494
553
  var getNodesWithStyles = (tree, blockSelectors) => {
495
554
  const nodes = [];
@@ -511,6 +570,7 @@ var getNodesWithStyles = (tree, blockSelectors) => {
511
570
  nodes.push({
512
571
  styles: tree.styles?.elements?.[name] ?? {},
513
572
  selector,
573
+ elementName: name,
514
574
  // Top level elements that don't use a class name should not receive the
515
575
  // `:root :where()` wrapper to maintain backwards compatibility.
516
576
  skipSelectorWrapper: !ELEMENT_CLASS_NAMES[name]
@@ -522,19 +582,36 @@ var getNodesWithStyles = (tree, blockSelectors) => {
522
582
  const blockStyles = pickStyleAndPseudoKeys(node, blockName);
523
583
  const typedNode = node;
524
584
  const variationNodesToAdd = [];
585
+ const variationStyleNodesToAdd = [];
525
586
  if (typedNode?.variations) {
526
- const variations = {};
527
587
  Object.entries(typedNode.variations).forEach(
528
588
  ([variationName, variation]) => {
529
589
  const typedVariation = variation;
530
- variations[variationName] = pickStyleAndPseudoKeys(
590
+ const variationStyles = pickStyleAndPseudoKeys(
531
591
  typedVariation,
532
592
  blockName
533
593
  );
534
594
  if (typedVariation?.css) {
535
- variations[variationName].css = typedVariation.css;
595
+ variationStyles.css = typedVariation.css;
536
596
  }
537
597
  const variationSelector = typeof blockSelectors !== "string" ? blockSelectors[blockName]?.styleVariationSelectors?.[variationName] : void 0;
598
+ if (variationSelector && typeof blockSelectors !== "string") {
599
+ const blockSelector = blockSelectors[blockName];
600
+ variationStyleNodesToAdd.push({
601
+ styles: variationStyles,
602
+ selector: variationSelector,
603
+ featureSelectors: getVariationFeatureSelectors(
604
+ blockSelector?.featureSelectors,
605
+ variationSelector
606
+ ),
607
+ fallbackGapValue: blockSelector?.fallbackGapValue,
608
+ hasLayoutSupport: blockSelector?.hasLayoutSupport,
609
+ isStyleVariation: true,
610
+ layoutSelector: variationSelector + blockSelector.selector,
611
+ layoutHasBlockGapSupport: true,
612
+ name: blockName
613
+ });
614
+ }
538
615
  Object.entries(
539
616
  typedVariation?.elements ?? {}
540
617
  ).forEach(([element, elementStyles]) => {
@@ -544,7 +621,9 @@ var getNodesWithStyles = (tree, blockSelectors) => {
544
621
  selector: scopeSelector(
545
622
  variationSelector,
546
623
  ELEMENTS[element]
547
- )
624
+ ),
625
+ elementName: element,
626
+ isStyleVariation: true
548
627
  });
549
628
  }
550
629
  });
@@ -577,6 +656,8 @@ var getNodesWithStyles = (tree, blockSelectors) => {
577
656
  }
578
657
  variationNodesToAdd.push({
579
658
  selector: variationBlockSelector,
659
+ name: variationBlockName,
660
+ isStyleVariation: true,
580
661
  duotoneSelector: variationDuotoneSelector,
581
662
  featureSelectors: variationFeatureSelectors,
582
663
  fallbackGapValue: blockSelectors[variationBlockName]?.fallbackGapValue,
@@ -596,7 +677,9 @@ var getNodesWithStyles = (tree, blockSelectors) => {
596
677
  selector: scopeSelector(
597
678
  variationBlockSelector,
598
679
  ELEMENTS[variationBlockElement]
599
- )
680
+ ),
681
+ elementName: variationBlockElement,
682
+ isStyleVariation: true
600
683
  });
601
684
  }
602
685
  }
@@ -605,7 +688,6 @@ var getNodesWithStyles = (tree, blockSelectors) => {
605
688
  );
606
689
  }
607
690
  );
608
- blockStyles.variations = variations;
609
691
  }
610
692
  if (typeof blockSelectors !== "string" && blockSelectors?.[blockName]?.selector) {
611
693
  nodes.push({
@@ -615,10 +697,10 @@ var getNodesWithStyles = (tree, blockSelectors) => {
615
697
  selector: blockSelectors[blockName].selector,
616
698
  styles: blockStyles,
617
699
  featureSelectors: blockSelectors[blockName].featureSelectors,
618
- styleVariationSelectors: blockSelectors[blockName].styleVariationSelectors,
619
700
  name: blockName
620
701
  });
621
702
  }
703
+ nodes.push(...variationStyleNodesToAdd);
622
704
  Object.entries(typedNode?.elements ?? {}).forEach(
623
705
  ([elementName, value]) => {
624
706
  if (typeof blockSelectors !== "string" && value && blockSelectors?.[blockName] && ELEMENTS[elementName]) {
@@ -629,7 +711,8 @@ var getNodesWithStyles = (tree, blockSelectors) => {
629
711
  return elementSelectors.map(
630
712
  (elementSelector) => sel + " " + elementSelector
631
713
  );
632
- }).join(",")
714
+ }).join(","),
715
+ elementName
633
716
  });
634
717
  }
635
718
  }
@@ -767,6 +850,100 @@ var generateCustomProperties = (tree, blockSelectors) => {
767
850
  }
768
851
  return ruleset;
769
852
  };
853
+ function renderStylesNode(node, {
854
+ tree,
855
+ useRootPaddingAlign,
856
+ disableLayoutStyles,
857
+ hasBlockGapSupport,
858
+ hasFallbackGapSupport,
859
+ disableRootPadding
860
+ }) {
861
+ const {
862
+ selector,
863
+ selectorSuffix,
864
+ mediaQuery,
865
+ duotoneSelector,
866
+ styles,
867
+ fallbackGapValue,
868
+ hasLayoutSupport,
869
+ featureSelectors,
870
+ layoutSelector,
871
+ layoutHasBlockGapSupport,
872
+ skipSelectorWrapper,
873
+ name
874
+ } = node;
875
+ let ruleset = "";
876
+ const effectiveSelector = selectorSuffix ? appendToSelector(selector, selectorSuffix) : selector;
877
+ if (featureSelectors && typeof featureSelectors !== "string") {
878
+ let featureDeclarations = getFeatureDeclarations(
879
+ featureSelectors,
880
+ styles
881
+ );
882
+ featureDeclarations = updateParagraphTextIndentSelector(
883
+ featureDeclarations,
884
+ tree.settings,
885
+ name
886
+ );
887
+ featureDeclarations = updateButtonWidthDeclarations(
888
+ featureDeclarations,
889
+ tree.settings
890
+ );
891
+ Object.entries(featureDeclarations).forEach(
892
+ ([featureSelector, declarations]) => {
893
+ if (declarations.length) {
894
+ const selectorForRule = selectorSuffix ? appendToSelector(featureSelector, selectorSuffix) : featureSelector;
895
+ const rules = declarations.join(";");
896
+ ruleset += `:root :where(${selectorForRule}){${rules};}`;
897
+ }
898
+ }
899
+ );
900
+ }
901
+ if (duotoneSelector) {
902
+ const duotoneStyles = {};
903
+ if (styles?.filter) {
904
+ duotoneStyles.filter = styles.filter;
905
+ delete styles.filter;
906
+ }
907
+ const duotoneDeclarations = getStylesDeclarations(duotoneStyles);
908
+ if (duotoneDeclarations.length) {
909
+ ruleset += `${duotoneSelector}{${duotoneDeclarations.join(
910
+ ";"
911
+ )};}`;
912
+ }
913
+ }
914
+ const selectorForLayout = layoutSelector ?? effectiveSelector;
915
+ const hasBlockGapSupportForLayout = layoutHasBlockGapSupport ?? hasBlockGapSupport;
916
+ if (!disableLayoutStyles && (ROOT_BLOCK_SELECTOR === selectorForLayout || hasLayoutSupport)) {
917
+ ruleset += getLayoutStyles({
918
+ style: styles,
919
+ selector: selectorForLayout,
920
+ hasBlockGapSupport: hasBlockGapSupportForLayout,
921
+ hasFallbackGapSupport,
922
+ fallbackGapValue
923
+ });
924
+ }
925
+ const styleDeclarations = getStylesDeclarations(
926
+ styles,
927
+ effectiveSelector,
928
+ useRootPaddingAlign,
929
+ tree,
930
+ disableRootPadding
931
+ );
932
+ if (styleDeclarations?.length) {
933
+ const generalSelector = skipSelectorWrapper ? effectiveSelector : `:root :where(${effectiveSelector})`;
934
+ ruleset += `${generalSelector}{${styleDeclarations.join(";")};}`;
935
+ }
936
+ if (styles?.css) {
937
+ ruleset += processCSSNesting(
938
+ styles.css,
939
+ `:root :where(${effectiveSelector})`
940
+ );
941
+ }
942
+ if (mediaQuery && ruleset) {
943
+ return `${mediaQuery}{${ruleset}}`;
944
+ }
945
+ return ruleset;
946
+ }
770
947
  var transformToStyles = (tree, blockSelectors, hasBlockGapSupport, hasFallbackGapSupport, disableLayoutStyles = false, disableRootPadding = false, styleOptions = {}) => {
771
948
  const options = {
772
949
  blockGap: true,
@@ -803,166 +980,27 @@ var transformToStyles = (tree, blockSelectors, hasBlockGapSupport, hasFallbackGa
803
980
  ruleset += "}";
804
981
  }
805
982
  if (options.blockStyles) {
806
- nodesWithStyles.forEach(
807
- ({
808
- selector,
809
- duotoneSelector,
810
- styles,
811
- fallbackGapValue,
812
- hasLayoutSupport,
813
- featureSelectors,
814
- styleVariationSelectors,
815
- skipSelectorWrapper,
816
- name
817
- }) => {
818
- if (featureSelectors) {
819
- let featureDeclarations = getFeatureDeclarations(
820
- featureSelectors,
821
- styles
822
- );
823
- featureDeclarations = updateParagraphTextIndentSelector(
824
- featureDeclarations,
825
- tree.settings,
826
- name
827
- );
828
- featureDeclarations = updateButtonWidthDeclarations(
829
- featureDeclarations,
830
- tree.settings
831
- );
832
- Object.entries(featureDeclarations).forEach(
833
- ([cssSelector, declarations]) => {
834
- if (declarations.length) {
835
- const rules = declarations.join(";");
836
- ruleset += `:root :where(${cssSelector}){${rules};}`;
837
- }
838
- }
839
- );
840
- }
841
- if (duotoneSelector) {
842
- const duotoneStyles = {};
843
- if (styles?.filter) {
844
- duotoneStyles.filter = styles.filter;
845
- delete styles.filter;
846
- }
847
- const duotoneDeclarations = getStylesDeclarations(duotoneStyles);
848
- if (duotoneDeclarations.length) {
849
- ruleset += `${duotoneSelector}{${duotoneDeclarations.join(
850
- ";"
851
- )};}`;
852
- }
853
- }
854
- if (!disableLayoutStyles && (ROOT_BLOCK_SELECTOR === selector || hasLayoutSupport)) {
855
- ruleset += getLayoutStyles({
856
- style: styles,
857
- selector,
858
- hasBlockGapSupport,
859
- hasFallbackGapSupport,
860
- fallbackGapValue
861
- });
862
- }
863
- const styleDeclarations = getStylesDeclarations(
864
- styles,
865
- selector,
866
- useRootPaddingAlign,
983
+ nodesWithStyles.forEach((node) => {
984
+ if (node.isStyleVariation && !options.variationStyles) {
985
+ return;
986
+ }
987
+ const responsiveNodes = getResponsiveStyleNodes(node);
988
+ [
989
+ node,
990
+ ...responsiveNodes,
991
+ ...getPseudoStyleNodes(node),
992
+ ...responsiveNodes.flatMap(getPseudoStyleNodes)
993
+ ].forEach((expandedNode) => {
994
+ ruleset += renderStylesNode(expandedNode, {
867
995
  tree,
996
+ useRootPaddingAlign,
997
+ disableLayoutStyles,
998
+ hasBlockGapSupport,
999
+ hasFallbackGapSupport,
868
1000
  disableRootPadding
869
- );
870
- if (styleDeclarations?.length) {
871
- const generalSelector = skipSelectorWrapper ? selector : `:root :where(${selector})`;
872
- ruleset += `${generalSelector}{${styleDeclarations.join(
873
- ";"
874
- )};}`;
875
- }
876
- if (styles?.css) {
877
- ruleset += processCSSNesting(
878
- styles.css,
879
- `:root :where(${selector})`
880
- );
881
- }
882
- if (options.variationStyles && styleVariationSelectors) {
883
- Object.entries(styleVariationSelectors).forEach(
884
- ([styleVariationName, styleVariationSelector]) => {
885
- const styleVariations = styles?.variations?.[styleVariationName];
886
- if (styleVariations) {
887
- if (featureSelectors) {
888
- let featureDeclarations = getFeatureDeclarations(
889
- featureSelectors,
890
- styleVariations
891
- );
892
- featureDeclarations = updateParagraphTextIndentSelector(
893
- featureDeclarations,
894
- tree.settings,
895
- name
896
- );
897
- featureDeclarations = updateButtonWidthDeclarations(
898
- featureDeclarations,
899
- tree.settings
900
- );
901
- Object.entries(
902
- featureDeclarations
903
- ).forEach(
904
- ([baseSelector, declarations]) => {
905
- if (declarations.length) {
906
- const cssSelector = concatFeatureVariationSelectorString(
907
- baseSelector,
908
- styleVariationSelector
909
- );
910
- const rules = declarations.join(";");
911
- ruleset += `:root :where(${cssSelector}){${rules};}`;
912
- }
913
- }
914
- );
915
- }
916
- const styleVariationDeclarations = getStylesDeclarations(
917
- styleVariations,
918
- styleVariationSelector,
919
- useRootPaddingAlign,
920
- tree
921
- );
922
- if (styleVariationDeclarations.length) {
923
- ruleset += `:root :where(${styleVariationSelector}){${styleVariationDeclarations.join(
924
- ";"
925
- )};}`;
926
- }
927
- if (styleVariations?.css) {
928
- ruleset += processCSSNesting(
929
- styleVariations.css,
930
- `:root :where(${styleVariationSelector})`
931
- );
932
- }
933
- ruleset = appendPseudoSelectorStyles(
934
- styleVariations,
935
- styleVariationSelector,
936
- ruleset,
937
- featureSelectors,
938
- tree.settings,
939
- name,
940
- styleVariationSelector
941
- );
942
- if (hasLayoutSupport && styleVariations?.spacing?.blockGap) {
943
- const variationSelectorWithBlock = styleVariationSelector + selector;
944
- ruleset += getLayoutStyles({
945
- style: styleVariations,
946
- selector: variationSelectorWithBlock,
947
- hasBlockGapSupport: true,
948
- hasFallbackGapSupport,
949
- fallbackGapValue
950
- });
951
- }
952
- }
953
- }
954
- );
955
- }
956
- ruleset = appendPseudoSelectorStyles(
957
- styles,
958
- selector,
959
- ruleset,
960
- featureSelectors,
961
- tree.settings,
962
- name
963
- );
964
- }
965
- );
1001
+ });
1002
+ });
1003
+ });
966
1004
  }
967
1005
  if (options.layoutStyles) {
968
1006
  ruleset = ruleset + ".wp-site-blocks > .alignleft { float: left; margin-right: 2em; }";