@wordpress/global-styles-engine 1.15.1 → 1.16.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.
Files changed (34) hide show
  1. package/build/core/merge.cjs +22 -17
  2. package/build/core/merge.cjs.map +2 -2
  3. package/build/core/render.cjs +16 -8
  4. package/build/core/render.cjs.map +2 -2
  5. package/build/settings/get-style.cjs +17 -1
  6. package/build/settings/get-style.cjs.map +2 -2
  7. package/build/settings/set-style.cjs +2 -1
  8. package/build/settings/set-style.cjs.map +2 -2
  9. package/build/style-state-back-compat.cjs +94 -0
  10. package/build/style-state-back-compat.cjs.map +7 -0
  11. package/build-module/core/merge.mjs +22 -17
  12. package/build-module/core/merge.mjs.map +2 -2
  13. package/build-module/core/render.mjs +16 -8
  14. package/build-module/core/render.mjs.map +2 -2
  15. package/build-module/settings/get-style.mjs +17 -1
  16. package/build-module/settings/get-style.mjs.map +2 -2
  17. package/build-module/settings/set-style.mjs +2 -1
  18. package/build-module/settings/set-style.mjs.map +2 -2
  19. package/build-module/style-state-back-compat.mjs +68 -0
  20. package/build-module/style-state-back-compat.mjs.map +7 -0
  21. package/build-types/core/merge.d.ts.map +1 -1
  22. package/build-types/core/render.d.ts.map +1 -1
  23. package/build-types/settings/get-style.d.ts.map +1 -1
  24. package/build-types/settings/set-style.d.ts.map +1 -1
  25. package/build-types/style-state-back-compat.d.ts +28 -0
  26. package/build-types/style-state-back-compat.d.ts.map +1 -0
  27. package/package.json +6 -6
  28. package/src/core/merge.ts +25 -19
  29. package/src/core/render.tsx +18 -8
  30. package/src/settings/get-style.ts +23 -1
  31. package/src/settings/set-style.ts +2 -1
  32. package/src/style-state-back-compat.ts +137 -0
  33. package/src/test/render.test.ts +47 -8
  34. package/src/test/style-state-back-compat.test.ts +170 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/style-state-back-compat.ts"],
4
+ "sourcesContent": ["/**\n * Internal dependencies\n */\nimport type { GlobalStylesConfig } from './types';\n\n/**\n * Temporary aliases for persisted style state keys shipped before breakpoint\n * states used the `@` prefix and custom states used the `-` prefix.\n *\n * Gutenberg plugin back compat for data saved before state keys were prefixed.\n * Guarded by `IS_GUTENBERG_PLUGIN` so synced Core package code does not apply it.\n */\nconst LEGACY_STYLE_STATE_ALIASES: Record< string, string > = {\n\t'@mobile': 'mobile',\n\t'@tablet': 'tablet',\n\t'-current': '@current',\n};\n\n/* eslint-disable @wordpress/wp-global-usage */\ndeclare global {\n\tvar IS_GUTENBERG_PLUGIN: boolean | undefined;\n}\n/* eslint-enable @wordpress/wp-global-usage */\n\n/**\n * Returns whether a value is a non-array object.\n *\n * @param value Value to check.\n * @return Whether the value is a non-array object.\n */\nfunction isObjectRecord( value: unknown ): value is Record< string, any > {\n\treturn !! value && typeof value === 'object' && ! Array.isArray( value );\n}\n\n/**\n * Normalizes legacy persisted style state aliases within a style node.\n *\n * For example, `{ mobile: { color: ... } }` becomes\n * `{ '@mobile': { color: ... } }`, and `{ '@current': { color: ... } }`\n * becomes `{ '-current': { color: ... } }`.\n *\n * @param node Style node or nested value.\n * @return Normalized style node or original value.\n */\nfunction normalizeStyleStateNode( node: any ): any {\n\tif ( ! isObjectRecord( node ) ) {\n\t\treturn node;\n\t}\n\n\tlet normalized = node;\n\n\t// Normalize legacy keys at the current style node before walking children.\n\tObject.entries( LEGACY_STYLE_STATE_ALIASES ).forEach(\n\t\t( [ state, legacyState ] ) => {\n\t\t\tif ( Object.hasOwn( node, legacyState ) ) {\n\t\t\t\t// Clone lazily before mutating this node.\n\t\t\t\tif ( normalized === node ) {\n\t\t\t\t\tnormalized = { ...node };\n\t\t\t\t}\n\t\t\t\tif ( ! Object.hasOwn( node, state ) ) {\n\t\t\t\t\tnormalized[ state ] = node[ legacyState ];\n\t\t\t\t}\n\t\t\t\tdelete normalized[ legacyState ];\n\t\t\t}\n\t\t}\n\t);\n\n\t// Recurse into nested style nodes, such as blocks, elements, and variations.\n\tObject.entries( normalized ).forEach( ( [ key, value ] ) => {\n\t\tif ( ! isObjectRecord( value ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst normalizedValue = normalizeStyleStateNode( value );\n\t\tif ( normalizedValue !== value ) {\n\t\t\t// Clone lazily before mutating this node.\n\t\t\tif ( normalized === node ) {\n\t\t\t\tnormalized = { ...node };\n\t\t\t}\n\t\t\tnormalized[ key ] = normalizedValue;\n\t\t}\n\t} );\n\n\treturn normalized;\n}\n\n/**\n * Normalizes legacy persisted style state aliases in a global styles config.\n *\n * For example, `styles.blocks['core/button'].mobile` becomes\n * `styles.blocks['core/button']['@mobile']`.\n *\n * @param globalStyles Global styles config to normalize.\n * @return Global styles config with canonical style state keys.\n */\nexport function normalizeStyleStateAliases(\n\tglobalStyles: GlobalStylesConfig\n): GlobalStylesConfig {\n\tif ( ! globalThis.IS_GUTENBERG_PLUGIN ) {\n\t\treturn globalStyles;\n\t}\n\n\tif ( ! globalStyles?.styles ) {\n\t\treturn globalStyles;\n\t}\n\n\tconst styles = normalizeStyleStateNode( globalStyles.styles );\n\treturn styles === globalStyles.styles\n\t\t? globalStyles\n\t\t: { ...globalStyles, styles };\n}\n\n/**\n * Returns the legacy equivalent of a canonical style state path.\n *\n * For example, `styles.blocks.core/button.@mobile.color.text` maps to\n * `styles.blocks.core/button.mobile.color.text`.\n *\n * @param path Canonical dot-separated object path.\n * @return Legacy path when one differs, otherwise undefined.\n */\nexport function getLegacyStyleStatePath( path: string ): string | undefined {\n\tif ( ! globalThis.IS_GUTENBERG_PLUGIN ) {\n\t\treturn undefined;\n\t}\n\n\tconst pathParts = path.split( '.' );\n\tconst legacyPathParts = pathParts.map(\n\t\t( part ) => LEGACY_STYLE_STATE_ALIASES[ part ] ?? part\n\t);\n\n\treturn legacyPathParts.some(\n\t\t( part, index ) => part !== pathParts[ index ]\n\t)\n\t\t? legacyPathParts.join( '.' )\n\t\t: undefined;\n}\n"],
5
+ "mappings": ";AAYA,IAAM,6BAAuD;AAAA,EAC5D,WAAW;AAAA,EACX,WAAW;AAAA,EACX,YAAY;AACb;AAcA,SAAS,eAAgB,OAAiD;AACzE,SAAO,CAAC,CAAE,SAAS,OAAO,UAAU,YAAY,CAAE,MAAM,QAAS,KAAM;AACxE;AAYA,SAAS,wBAAyB,MAAiB;AAClD,MAAK,CAAE,eAAgB,IAAK,GAAI;AAC/B,WAAO;AAAA,EACR;AAEA,MAAI,aAAa;AAGjB,SAAO,QAAS,0BAA2B,EAAE;AAAA,IAC5C,CAAE,CAAE,OAAO,WAAY,MAAO;AAC7B,UAAK,OAAO,OAAQ,MAAM,WAAY,GAAI;AAEzC,YAAK,eAAe,MAAO;AAC1B,uBAAa,EAAE,GAAG,KAAK;AAAA,QACxB;AACA,YAAK,CAAE,OAAO,OAAQ,MAAM,KAAM,GAAI;AACrC,qBAAY,KAAM,IAAI,KAAM,WAAY;AAAA,QACzC;AACA,eAAO,WAAY,WAAY;AAAA,MAChC;AAAA,IACD;AAAA,EACD;AAGA,SAAO,QAAS,UAAW,EAAE,QAAS,CAAE,CAAE,KAAK,KAAM,MAAO;AAC3D,QAAK,CAAE,eAAgB,KAAM,GAAI;AAChC;AAAA,IACD;AAEA,UAAM,kBAAkB,wBAAyB,KAAM;AACvD,QAAK,oBAAoB,OAAQ;AAEhC,UAAK,eAAe,MAAO;AAC1B,qBAAa,EAAE,GAAG,KAAK;AAAA,MACxB;AACA,iBAAY,GAAI,IAAI;AAAA,IACrB;AAAA,EACD,CAAE;AAEF,SAAO;AACR;AAWO,SAAS,2BACf,cACqB;AACrB,MAAK,CAAE,WAAW,qBAAsB;AACvC,WAAO;AAAA,EACR;AAEA,MAAK,CAAE,cAAc,QAAS;AAC7B,WAAO;AAAA,EACR;AAEA,QAAM,SAAS,wBAAyB,aAAa,MAAO;AAC5D,SAAO,WAAW,aAAa,SAC5B,eACA,EAAE,GAAG,cAAc,OAAO;AAC9B;AAWO,SAAS,wBAAyB,MAAmC;AAC3E,MAAK,CAAE,WAAW,qBAAsB;AACvC,WAAO;AAAA,EACR;AAEA,QAAM,YAAY,KAAK,MAAO,GAAI;AAClC,QAAM,kBAAkB,UAAU;AAAA,IACjC,CAAE,SAAU,2BAA4B,IAAK,KAAK;AAAA,EACnD;AAEA,SAAO,gBAAgB;AAAA,IACtB,CAAE,MAAM,UAAW,SAAS,UAAW,KAAM;AAAA,EAC9C,IACG,gBAAgB,KAAM,GAAI,IAC1B;AACJ;",
6
+ "names": []
7
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/core/merge.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAEnD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAChC,IAAI,EAAE,kBAAkB,EACxB,IAAI,EAAE,kBAAkB,GACtB,kBAAkB,CAoBpB"}
1
+ {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/core/merge.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAGnD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAChC,IAAI,EAAE,kBAAkB,EACxB,IAAI,EAAE,kBAAkB,GACtB,kBAAkB,CAyBpB"}
@@ -1 +1 @@
1
- {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/core/render.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/core/render.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"get-style.d.ts","sourceRoot":"","sources":["../../src/settings/get-style.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAmB,MAAM,UAAU,CAAC;AAEpE,wBAAgB,QAAQ,CAAE,CAAC,GAAG,GAAG,EAChC,YAAY,CAAC,EAAE,kBAAkB,EACjC,IAAI,CAAC,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,MAAM,EAClB,kBAAkB,UAAO,GACvB,CAAC,GAAG,SAAS,CAgBf"}
1
+ {"version":3,"file":"get-style.d.ts","sourceRoot":"","sources":["../../src/settings/get-style.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAmB,MAAM,UAAU,CAAC;AAGpE,wBAAgB,QAAQ,CAAE,CAAC,GAAG,GAAG,EAChC,YAAY,CAAC,EAAE,kBAAkB,EACjC,IAAI,CAAC,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,MAAM,EAClB,kBAAkB,UAAO,GACvB,CAAC,GAAG,SAAS,CAqCf"}
@@ -1 +1 @@
1
- {"version":3,"file":"set-style.d.ts","sourceRoot":"","sources":["../../src/settings/set-style.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAEnD,wBAAgB,QAAQ,CAAE,CAAC,GAAG,GAAG,EAChC,YAAY,EAAE,kBAAkB,EAChC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,CAAC,GAAG,SAAS,EACvB,SAAS,CAAC,EAAE,MAAM,GAChB,kBAAkB,CAWpB"}
1
+ {"version":3,"file":"set-style.d.ts","sourceRoot":"","sources":["../../src/settings/set-style.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAGnD,wBAAgB,QAAQ,CAAE,CAAC,GAAG,GAAG,EAChC,YAAY,EAAE,kBAAkB,EAChC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,CAAC,GAAG,SAAS,EACvB,SAAS,CAAC,EAAE,MAAM,GAChB,kBAAkB,CAWpB"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import type { GlobalStylesConfig } from './types';
5
+ declare global {
6
+ var IS_GUTENBERG_PLUGIN: boolean | undefined;
7
+ }
8
+ /**
9
+ * Normalizes legacy persisted style state aliases in a global styles config.
10
+ *
11
+ * For example, `styles.blocks['core/button'].mobile` becomes
12
+ * `styles.blocks['core/button']['@mobile']`.
13
+ *
14
+ * @param globalStyles Global styles config to normalize.
15
+ * @return Global styles config with canonical style state keys.
16
+ */
17
+ export declare function normalizeStyleStateAliases(globalStyles: GlobalStylesConfig): GlobalStylesConfig;
18
+ /**
19
+ * Returns the legacy equivalent of a canonical style state path.
20
+ *
21
+ * For example, `styles.blocks.core/button.@mobile.color.text` maps to
22
+ * `styles.blocks.core/button.mobile.color.text`.
23
+ *
24
+ * @param path Canonical dot-separated object path.
25
+ * @return Legacy path when one differs, otherwise undefined.
26
+ */
27
+ export declare function getLegacyStyleStatePath(path: string): string | undefined;
28
+ //# sourceMappingURL=style-state-back-compat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style-state-back-compat.d.ts","sourceRoot":"","sources":["../src/style-state-back-compat.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAgBlD,OAAO,CAAC,MAAM,CAAC,CAAC;IACf,IAAI,mBAAmB,EAAE,OAAO,GAAG,SAAS,CAAC;CAC7C;AAiED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACzC,YAAY,EAAE,kBAAkB,GAC9B,kBAAkB,CAapB;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAE,IAAI,EAAE,MAAM,GAAI,MAAM,GAAG,SAAS,CAe1E"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/global-styles-engine",
3
- "version": "1.15.1",
3
+ "version": "1.16.0",
4
4
  "description": "Pure CSS generation engine for WordPress global styles.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -42,10 +42,10 @@
42
42
  "types": "build-types/index.d.ts",
43
43
  "sideEffects": false,
44
44
  "dependencies": {
45
- "@wordpress/blocks": "^15.21.1",
46
- "@wordpress/data": "^10.48.1",
47
- "@wordpress/i18n": "^6.21.1",
48
- "@wordpress/style-engine": "^2.48.1",
45
+ "@wordpress/blocks": "^15.22.0",
46
+ "@wordpress/data": "^10.49.0",
47
+ "@wordpress/i18n": "^6.22.0",
48
+ "@wordpress/style-engine": "^2.49.0",
49
49
  "colord": "^2.9.3",
50
50
  "deepmerge": "^4.3.1",
51
51
  "fast-deep-equal": "^3.1.3",
@@ -59,5 +59,5 @@
59
59
  "publishConfig": {
60
60
  "access": "public"
61
61
  },
62
- "gitHead": "99df7432c5c7cb83ba41146fd1f57f3c19004305"
62
+ "gitHead": "0e7112a4f4fde4ea15bd9060489b8f6fe11eb6ca"
63
63
  }
package/src/core/merge.ts CHANGED
@@ -9,6 +9,7 @@ import { isPlainObject } from 'is-plain-object';
9
9
  * Internal dependencies
10
10
  */
11
11
  import type { GlobalStylesConfig } from '../types';
12
+ import { normalizeStyleStateAliases } from '../style-state-back-compat';
12
13
 
13
14
  /**
14
15
  * Merges base and user global styles configurations
@@ -21,23 +22,28 @@ export function mergeGlobalStyles(
21
22
  base: GlobalStylesConfig,
22
23
  user: GlobalStylesConfig
23
24
  ): GlobalStylesConfig {
24
- return deepmerge( base, user, {
25
- /*
26
- * We only pass as arrays the presets,
27
- * in which case we want the new array of values
28
- * to override the old array (no merging).
29
- */
30
- isMergeableObject: isPlainObject,
31
- /*
32
- * Exceptions to the above rule.
33
- * Background images should be replaced, not merged,
34
- * as they themselves are specific object definitions for the style.
35
- */
36
- customMerge: ( key ) => {
37
- if ( key === 'backgroundImage' ) {
38
- return ( baseConfig, userConfig ) => userConfig ?? baseConfig;
39
- }
40
- return undefined;
41
- },
42
- } );
25
+ return deepmerge(
26
+ normalizeStyleStateAliases( base ),
27
+ normalizeStyleStateAliases( user ),
28
+ {
29
+ /*
30
+ * We only pass as arrays the presets,
31
+ * in which case we want the new array of values
32
+ * to override the old array (no merging).
33
+ */
34
+ isMergeableObject: isPlainObject,
35
+ /*
36
+ * Exceptions to the above rule.
37
+ * Background images should be replaced, not merged,
38
+ * as they themselves are specific object definitions for the style.
39
+ */
40
+ customMerge: ( key ) => {
41
+ if ( key === 'backgroundImage' ) {
42
+ return ( baseConfig, userConfig ) =>
43
+ userConfig ?? baseConfig;
44
+ }
45
+ return undefined;
46
+ },
47
+ }
48
+ );
43
49
  }
@@ -36,6 +36,7 @@ import { LAYOUT_DEFINITIONS } from '../utils/layout';
36
36
  import { getValueFromObjectPath, setImmutably } from '../utils/object';
37
37
  import { getSetting } from '../settings/get-setting';
38
38
  import type { GlobalStylesConfig, GlobalStylesStyles } from '../types';
39
+ import { normalizeStyleStateAliases } from '../style-state-back-compat';
39
40
 
40
41
  // =============================================================================
41
42
  // LOCAL TYPE DEFINITIONS
@@ -232,8 +233,8 @@ const VALID_ELEMENT_PSEUDO_SELECTORS: Record< string, string[] > = {
232
233
  * Keep in sync with WP_Theme_JSON_Gutenberg::RESPONSIVE_BREAKPOINTS.
233
234
  */
234
235
  const RESPONSIVE_BREAKPOINTS: Record< string, string > = {
235
- mobile: '@media (width <= 480px)',
236
- tablet: '@media (480px < width <= 782px)',
236
+ '@mobile': '@media (width <= 480px)',
237
+ '@tablet': '@media (480px < width <= 782px)',
237
238
  };
238
239
 
239
240
  /**
@@ -1699,10 +1700,18 @@ export const transformToStyles = (
1699
1700
  variationStyles: false,
1700
1701
  ...styleOptions,
1701
1702
  };
1702
- const nodesWithStyles = getNodesWithStyles( tree, blockSelectors );
1703
- const nodesWithSettings = getNodesWithSettings( tree, blockSelectors );
1704
- const useRootPaddingAlign = tree?.settings?.useRootPaddingAwareAlignments;
1705
- const { contentSize, wideSize } = tree?.settings?.layout || {};
1703
+ const normalizedTree = normalizeStyleStateAliases( tree );
1704
+ const nodesWithStyles = getNodesWithStyles(
1705
+ normalizedTree,
1706
+ blockSelectors
1707
+ );
1708
+ const nodesWithSettings = getNodesWithSettings(
1709
+ normalizedTree,
1710
+ blockSelectors
1711
+ );
1712
+ const useRootPaddingAlign =
1713
+ normalizedTree?.settings?.useRootPaddingAwareAlignments;
1714
+ const { contentSize, wideSize } = normalizedTree?.settings?.layout || {};
1706
1715
  const hasBodyStyles =
1707
1716
  options.marginReset || options.rootPadding || options.layoutStyles;
1708
1717
 
@@ -1762,7 +1771,7 @@ export const transformToStyles = (
1762
1771
  ...responsiveNodes.flatMap( getPseudoStyleNodes ),
1763
1772
  ].forEach( ( expandedNode ) => {
1764
1773
  ruleset += renderStylesNode( expandedNode, {
1765
- tree,
1774
+ tree: normalizedTree,
1766
1775
  useRootPaddingAlign,
1767
1776
  disableLayoutStyles,
1768
1777
  hasBlockGapSupport,
@@ -1789,7 +1798,8 @@ export const transformToStyles = (
1789
1798
  if ( options.blockGap && hasBlockGapSupport ) {
1790
1799
  // Use fallback of `0.5em` just in case, however if there is blockGap support, there should nearly always be a real value.
1791
1800
  const gapValue =
1792
- getGapCSSValue( tree?.styles?.spacing?.blockGap ) || '0.5em';
1801
+ getGapCSSValue( normalizedTree?.styles?.spacing?.blockGap ) ||
1802
+ '0.5em';
1793
1803
  ruleset =
1794
1804
  ruleset +
1795
1805
  `:root :where(.wp-site-blocks) > * { margin-block-start: ${ gapValue }; margin-block-end: 0; }`;
@@ -4,6 +4,7 @@
4
4
  import { getValueFromObjectPath } from '../utils/object';
5
5
  import { getValueFromVariable } from '../utils/common';
6
6
  import type { GlobalStylesConfig, UnresolvedValue } from '../types';
7
+ import { getLegacyStyleStatePath } from '../style-state-back-compat';
7
8
 
8
9
  export function getStyle< T = any >(
9
10
  globalStyles?: GlobalStylesConfig,
@@ -19,9 +20,30 @@ export function getStyle< T = any >(
19
20
  return undefined;
20
21
  }
21
22
 
22
- const rawResult = getValueFromObjectPath( globalStyles, finalPath ) as
23
+ let rawResult = getValueFromObjectPath( globalStyles, finalPath ) as
23
24
  | string
24
25
  | UnresolvedValue;
26
+ const legacyPath = getLegacyStyleStatePath( finalPath );
27
+ if ( rawResult === undefined && legacyPath ) {
28
+ let hasCanonicalPath = true;
29
+ let currentValue: any = globalStyles;
30
+ for ( const pathPart of finalPath.split( '.' ) ) {
31
+ if (
32
+ ! currentValue ||
33
+ typeof currentValue !== 'object' ||
34
+ ! Object.hasOwn( currentValue, pathPart )
35
+ ) {
36
+ hasCanonicalPath = false;
37
+ break;
38
+ }
39
+ currentValue = currentValue[ pathPart ];
40
+ }
41
+ if ( ! hasCanonicalPath ) {
42
+ rawResult = getValueFromObjectPath( globalStyles, legacyPath ) as
43
+ | string
44
+ | UnresolvedValue;
45
+ }
46
+ }
25
47
  const result = shouldDecodeEncode
26
48
  ? getValueFromVariable( globalStyles, blockName, rawResult )
27
49
  : rawResult;
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import { setImmutably } from '../utils/object';
5
5
  import type { GlobalStylesConfig } from '../types';
6
+ import { normalizeStyleStateAliases } from '../style-state-back-compat';
6
7
 
7
8
  export function setStyle< T = any >(
8
9
  globalStyles: GlobalStylesConfig,
@@ -16,7 +17,7 @@ export function setStyle< T = any >(
16
17
  : `styles.blocks.${ blockName }${ appendedPath }`;
17
18
 
18
19
  return setImmutably(
19
- globalStyles,
20
+ normalizeStyleStateAliases( globalStyles ),
20
21
  finalPath.split( '.' ),
21
22
  newValue
22
23
  ) as GlobalStylesConfig;
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import type { GlobalStylesConfig } from './types';
5
+
6
+ /**
7
+ * Temporary aliases for persisted style state keys shipped before breakpoint
8
+ * states used the `@` prefix and custom states used the `-` prefix.
9
+ *
10
+ * Gutenberg plugin back compat for data saved before state keys were prefixed.
11
+ * Guarded by `IS_GUTENBERG_PLUGIN` so synced Core package code does not apply it.
12
+ */
13
+ const LEGACY_STYLE_STATE_ALIASES: Record< string, string > = {
14
+ '@mobile': 'mobile',
15
+ '@tablet': 'tablet',
16
+ '-current': '@current',
17
+ };
18
+
19
+ /* eslint-disable @wordpress/wp-global-usage */
20
+ declare global {
21
+ var IS_GUTENBERG_PLUGIN: boolean | undefined;
22
+ }
23
+ /* eslint-enable @wordpress/wp-global-usage */
24
+
25
+ /**
26
+ * Returns whether a value is a non-array object.
27
+ *
28
+ * @param value Value to check.
29
+ * @return Whether the value is a non-array object.
30
+ */
31
+ function isObjectRecord( value: unknown ): value is Record< string, any > {
32
+ return !! value && typeof value === 'object' && ! Array.isArray( value );
33
+ }
34
+
35
+ /**
36
+ * Normalizes legacy persisted style state aliases within a style node.
37
+ *
38
+ * For example, `{ mobile: { color: ... } }` becomes
39
+ * `{ '@mobile': { color: ... } }`, and `{ '@current': { color: ... } }`
40
+ * becomes `{ '-current': { color: ... } }`.
41
+ *
42
+ * @param node Style node or nested value.
43
+ * @return Normalized style node or original value.
44
+ */
45
+ function normalizeStyleStateNode( node: any ): any {
46
+ if ( ! isObjectRecord( node ) ) {
47
+ return node;
48
+ }
49
+
50
+ let normalized = node;
51
+
52
+ // Normalize legacy keys at the current style node before walking children.
53
+ Object.entries( LEGACY_STYLE_STATE_ALIASES ).forEach(
54
+ ( [ state, legacyState ] ) => {
55
+ if ( Object.hasOwn( node, legacyState ) ) {
56
+ // Clone lazily before mutating this node.
57
+ if ( normalized === node ) {
58
+ normalized = { ...node };
59
+ }
60
+ if ( ! Object.hasOwn( node, state ) ) {
61
+ normalized[ state ] = node[ legacyState ];
62
+ }
63
+ delete normalized[ legacyState ];
64
+ }
65
+ }
66
+ );
67
+
68
+ // Recurse into nested style nodes, such as blocks, elements, and variations.
69
+ Object.entries( normalized ).forEach( ( [ key, value ] ) => {
70
+ if ( ! isObjectRecord( value ) ) {
71
+ return;
72
+ }
73
+
74
+ const normalizedValue = normalizeStyleStateNode( value );
75
+ if ( normalizedValue !== value ) {
76
+ // Clone lazily before mutating this node.
77
+ if ( normalized === node ) {
78
+ normalized = { ...node };
79
+ }
80
+ normalized[ key ] = normalizedValue;
81
+ }
82
+ } );
83
+
84
+ return normalized;
85
+ }
86
+
87
+ /**
88
+ * Normalizes legacy persisted style state aliases in a global styles config.
89
+ *
90
+ * For example, `styles.blocks['core/button'].mobile` becomes
91
+ * `styles.blocks['core/button']['@mobile']`.
92
+ *
93
+ * @param globalStyles Global styles config to normalize.
94
+ * @return Global styles config with canonical style state keys.
95
+ */
96
+ export function normalizeStyleStateAliases(
97
+ globalStyles: GlobalStylesConfig
98
+ ): GlobalStylesConfig {
99
+ if ( ! globalThis.IS_GUTENBERG_PLUGIN ) {
100
+ return globalStyles;
101
+ }
102
+
103
+ if ( ! globalStyles?.styles ) {
104
+ return globalStyles;
105
+ }
106
+
107
+ const styles = normalizeStyleStateNode( globalStyles.styles );
108
+ return styles === globalStyles.styles
109
+ ? globalStyles
110
+ : { ...globalStyles, styles };
111
+ }
112
+
113
+ /**
114
+ * Returns the legacy equivalent of a canonical style state path.
115
+ *
116
+ * For example, `styles.blocks.core/button.@mobile.color.text` maps to
117
+ * `styles.blocks.core/button.mobile.color.text`.
118
+ *
119
+ * @param path Canonical dot-separated object path.
120
+ * @return Legacy path when one differs, otherwise undefined.
121
+ */
122
+ export function getLegacyStyleStatePath( path: string ): string | undefined {
123
+ if ( ! globalThis.IS_GUTENBERG_PLUGIN ) {
124
+ return undefined;
125
+ }
126
+
127
+ const pathParts = path.split( '.' );
128
+ const legacyPathParts = pathParts.map(
129
+ ( part ) => LEGACY_STYLE_STATE_ALIASES[ part ] ?? part
130
+ );
131
+
132
+ return legacyPathParts.some(
133
+ ( part, index ) => part !== pathParts[ index ]
134
+ )
135
+ ? legacyPathParts.join( '.' )
136
+ : undefined;
137
+ }
@@ -682,7 +682,7 @@ describe( 'global styles renderer', () => {
682
682
  text: 'blue',
683
683
  },
684
684
  },
685
- mobile: {
685
+ '@mobile': {
686
686
  color: {
687
687
  text: 'green',
688
688
  },
@@ -790,7 +790,7 @@ describe( 'global styles renderer', () => {
790
790
  text: 'blue',
791
791
  },
792
792
  },
793
- mobile: {
793
+ '@mobile': {
794
794
  color: {
795
795
  text: 'red',
796
796
  },
@@ -832,7 +832,7 @@ describe( 'global styles renderer', () => {
832
832
  text: 'blue',
833
833
  },
834
834
  },
835
- mobile: {
835
+ '@mobile': {
836
836
  color: {
837
837
  text: 'green',
838
838
  },
@@ -945,7 +945,7 @@ describe( 'global styles renderer', () => {
945
945
  width: '20rem',
946
946
  },
947
947
  },
948
- tablet: {
948
+ '@tablet': {
949
949
  color: {
950
950
  text: 'red',
951
951
  },
@@ -1002,6 +1002,45 @@ describe( 'global styles renderer', () => {
1002
1002
  } );
1003
1003
 
1004
1004
  it( 'handles responsive block styles', () => {
1005
+ const tree = {
1006
+ styles: {
1007
+ blocks: {
1008
+ 'core/button': {
1009
+ color: {
1010
+ text: 'red',
1011
+ },
1012
+ '@mobile': {
1013
+ color: {
1014
+ text: 'blue',
1015
+ },
1016
+ },
1017
+ },
1018
+ },
1019
+ },
1020
+ } as unknown as GlobalStylesConfig;
1021
+
1022
+ const blockSelectors = {
1023
+ 'core/button': {
1024
+ selector: '.wp-block-button',
1025
+ },
1026
+ };
1027
+
1028
+ const result = transformToStyles(
1029
+ Object.freeze( tree ),
1030
+ blockSelectors,
1031
+ false,
1032
+ false,
1033
+ true,
1034
+ true,
1035
+ minimalStyleOptions
1036
+ );
1037
+
1038
+ expect( result ).toEqual(
1039
+ ':root :where(.wp-block-button){color: red;}@media (width <= 480px){:root :where(.wp-block-button){color: blue;}}'
1040
+ );
1041
+ } );
1042
+
1043
+ it( 'handles legacy responsive block styles', () => {
1005
1044
  const tree = {
1006
1045
  styles: {
1007
1046
  blocks: {
@@ -1050,7 +1089,7 @@ describe( 'global styles renderer', () => {
1050
1089
  text: 'blue',
1051
1090
  },
1052
1091
  },
1053
- mobile: {
1092
+ '@mobile': {
1054
1093
  color: {
1055
1094
  text: 'red',
1056
1095
  },
@@ -1095,7 +1134,7 @@ describe( 'global styles renderer', () => {
1095
1134
  dimensions: {
1096
1135
  width: '25%',
1097
1136
  },
1098
- mobile: {
1137
+ '@mobile': {
1099
1138
  dimensions: {
1100
1139
  width: '50%',
1101
1140
  },
@@ -1140,7 +1179,7 @@ describe( 'global styles renderer', () => {
1140
1179
  color: {
1141
1180
  text: 'blue',
1142
1181
  },
1143
- mobile: {
1182
+ '@mobile': {
1144
1183
  color: {
1145
1184
  text: 'red',
1146
1185
  },
@@ -1180,7 +1219,7 @@ describe( 'global styles renderer', () => {
1180
1219
  color: {
1181
1220
  text: 'green',
1182
1221
  },
1183
- mobile: {
1222
+ '@mobile': {
1184
1223
  color: {
1185
1224
  text: 'yellow',
1186
1225
  },