@wordpress/global-styles-engine 1.17.0 → 1.18.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 (58) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/build/core/render.cjs +36 -16
  3. package/build/core/render.cjs.map +2 -2
  4. package/build/index.cjs +3 -0
  5. package/build/index.cjs.map +2 -2
  6. package/build/lock-unlock.cjs +37 -0
  7. package/build/lock-unlock.cjs.map +7 -0
  8. package/build/private-apis.cjs +38 -0
  9. package/build/private-apis.cjs.map +7 -0
  10. package/build/settings/get-setting.cjs +3 -1
  11. package/build/settings/get-setting.cjs.map +2 -2
  12. package/build/types.cjs.map +1 -1
  13. package/build/utils/common.cjs +2 -4
  14. package/build/utils/common.cjs.map +2 -2
  15. package/build/utils/viewport.cjs +108 -0
  16. package/build/utils/viewport.cjs.map +7 -0
  17. package/build-module/core/render.mjs +36 -16
  18. package/build-module/core/render.mjs.map +2 -2
  19. package/build-module/index.mjs +2 -0
  20. package/build-module/index.mjs.map +2 -2
  21. package/build-module/lock-unlock.mjs +11 -0
  22. package/build-module/lock-unlock.mjs.map +7 -0
  23. package/build-module/private-apis.mjs +17 -0
  24. package/build-module/private-apis.mjs.map +7 -0
  25. package/build-module/settings/get-setting.mjs +3 -1
  26. package/build-module/settings/get-setting.mjs.map +2 -2
  27. package/build-module/utils/common.mjs +2 -4
  28. package/build-module/utils/common.mjs.map +2 -2
  29. package/build-module/utils/viewport.mjs +81 -0
  30. package/build-module/utils/viewport.mjs.map +7 -0
  31. package/build-types/core/render.d.ts +1 -1
  32. package/build-types/core/render.d.ts.map +1 -1
  33. package/build-types/index.d.ts +1 -0
  34. package/build-types/index.d.ts.map +1 -1
  35. package/build-types/lock-unlock.d.ts +2 -0
  36. package/build-types/lock-unlock.d.ts.map +1 -0
  37. package/build-types/private-apis.d.ts +2 -0
  38. package/build-types/private-apis.d.ts.map +1 -0
  39. package/build-types/settings/get-setting.d.ts.map +1 -1
  40. package/build-types/style-state-back-compat.d.ts.map +1 -1
  41. package/build-types/types.d.ts +4 -0
  42. package/build-types/types.d.ts.map +1 -1
  43. package/build-types/utils/common.d.ts.map +1 -1
  44. package/build-types/utils/fluid.d.ts +1 -1
  45. package/build-types/utils/fluid.d.ts.map +1 -1
  46. package/build-types/utils/viewport.d.ts +41 -0
  47. package/build-types/utils/viewport.d.ts.map +1 -0
  48. package/package.json +7 -6
  49. package/src/core/render.tsx +45 -21
  50. package/src/index.ts +1 -0
  51. package/src/lock-unlock.ts +10 -0
  52. package/src/private-apis.ts +16 -0
  53. package/src/settings/get-setting.ts +2 -0
  54. package/src/test/render.test.ts +182 -0
  55. package/src/test/viewport-utils.test.ts +168 -0
  56. package/src/types.ts +4 -0
  57. package/src/utils/common.ts +13 -8
  58. package/src/utils/viewport.ts +153 -0
@@ -0,0 +1,153 @@
1
+ import type { GlobalStylesConfig } from '../types';
2
+
3
+ const DEFAULT_VIEWPORT_BREAKPOINTS = {
4
+ mobile: '480px',
5
+ tablet: '782px',
6
+ };
7
+
8
+ type ViewportBreakpoint = keyof typeof DEFAULT_VIEWPORT_BREAKPOINTS;
9
+ type ViewportSettings = Partial< Record< ViewportBreakpoint, string > >;
10
+ type ViewportBreakpoints = Partial< Record< ViewportBreakpoint, string > >;
11
+
12
+ // Matches positive CSS length values supported for viewport breakpoints, and
13
+ // captures the numeric value and unit for conversion to pixels.
14
+ const VIEWPORT_SIZE_REGEXP = /^(\d+|\d*\.\d+)(px|em|rem)$/;
15
+ const DEFAULT_FONT_SIZE = 16;
16
+
17
+ function isViewportSettings(
18
+ configOrSettings: GlobalStylesConfig | ViewportSettings
19
+ ): configOrSettings is ViewportSettings {
20
+ return 'mobile' in configOrSettings || 'tablet' in configOrSettings;
21
+ }
22
+
23
+ function getViewportSettings(
24
+ configOrSettings?: GlobalStylesConfig | ViewportSettings
25
+ ): ViewportSettings {
26
+ if ( ! configOrSettings || typeof configOrSettings !== 'object' ) {
27
+ return {};
28
+ }
29
+
30
+ if ( isViewportSettings( configOrSettings ) ) {
31
+ return configOrSettings;
32
+ }
33
+
34
+ return configOrSettings.settings?.viewport ?? {};
35
+ }
36
+
37
+ function isValidViewportSize( value: unknown ): value is string {
38
+ return (
39
+ typeof value === 'string' && VIEWPORT_SIZE_REGEXP.test( value.trim() )
40
+ );
41
+ }
42
+
43
+ /**
44
+ * Converts a viewport breakpoint value to pixels.
45
+ *
46
+ * Numeric values are returned as-is. CSS length values are only supported when
47
+ * expressed in px, em, or rem units.
48
+ *
49
+ * @param value Breakpoint value as a number or CSS length.
50
+ * @return The breakpoint value in pixels, or undefined when invalid.
51
+ */
52
+ export function getViewportBreakpointValueInPixels(
53
+ value: number | string | undefined
54
+ ): number | undefined {
55
+ if ( typeof value === 'number' ) {
56
+ return value;
57
+ }
58
+
59
+ if ( typeof value !== 'string' ) {
60
+ return undefined;
61
+ }
62
+
63
+ const match = value.trim().match( VIEWPORT_SIZE_REGEXP );
64
+ if ( ! match ) {
65
+ return undefined;
66
+ }
67
+
68
+ const numericValue = Number.parseFloat( match[ 1 ] );
69
+ const unit = match[ 2 ];
70
+
71
+ // Use the most common browser default font size as the base for em/rem
72
+ // media query conversions. This pixel value is used to compare breakpoint
73
+ // order and calculate preview sizes; generated media queries keep the
74
+ // original units.
75
+ return unit === 'px' ? numericValue : numericValue * DEFAULT_FONT_SIZE;
76
+ }
77
+
78
+ /**
79
+ * Returns sanitized viewport breakpoints keyed by viewport state.
80
+ *
81
+ * Falls back to default breakpoints when no valid values are provided. If the
82
+ * mobile breakpoint is missing, a valid tablet breakpoint remains keyed as
83
+ * tablet so the editor can present it as a tablet breakpoint. If the tablet
84
+ * breakpoint is missing, invalid, or not larger than the mobile breakpoint, the
85
+ * result only includes the mobile breakpoint.
86
+ *
87
+ * @param configOrSettings Global styles config or viewport settings.
88
+ * @return Sanitized viewport breakpoints.
89
+ */
90
+ export function getViewportBreakpoints(
91
+ configOrSettings?: GlobalStylesConfig | ViewportSettings
92
+ ): ViewportBreakpoints {
93
+ const viewportSettings = getViewportSettings( configOrSettings );
94
+ const breakpoints: ViewportBreakpoints = {};
95
+ const breakpointValuesInPixels: Partial<
96
+ Record< ViewportBreakpoint, number >
97
+ > = {};
98
+
99
+ Object.keys( DEFAULT_VIEWPORT_BREAKPOINTS ).forEach( ( breakpoint ) => {
100
+ const key = breakpoint as ViewportBreakpoint;
101
+ const value = viewportSettings[ key ];
102
+ const px = getViewportBreakpointValueInPixels( value );
103
+ if ( px !== undefined && isValidViewportSize( value ) ) {
104
+ breakpoints[ key ] = value.trim();
105
+ breakpointValuesInPixels[ key ] = px;
106
+ }
107
+ } );
108
+
109
+ const breakpointNames = Object.keys( breakpoints );
110
+ if ( ! breakpointNames.length ) {
111
+ return { ...DEFAULT_VIEWPORT_BREAKPOINTS };
112
+ }
113
+
114
+ if ( 1 === breakpointNames.length ) {
115
+ return breakpoints;
116
+ }
117
+
118
+ const mobile = breakpoints.mobile!;
119
+ const tablet = breakpoints.tablet!;
120
+ if (
121
+ breakpointValuesInPixels.mobile! >= breakpointValuesInPixels.tablet!
122
+ ) {
123
+ return { mobile };
124
+ }
125
+
126
+ return { mobile, tablet };
127
+ }
128
+
129
+ /**
130
+ * Returns responsive media query aliases for the configured viewport
131
+ * breakpoints.
132
+ *
133
+ * @param configOrSettings Global styles config or viewport settings.
134
+ * @return Responsive media queries keyed by alias.
135
+ */
136
+ export function getResponsiveMediaQueries(
137
+ configOrSettings?: GlobalStylesConfig | ViewportSettings
138
+ ): Record< string, string > {
139
+ const breakpoints = getViewportBreakpoints( configOrSettings );
140
+ const mediaQueries: Record< string, string > = {};
141
+
142
+ if ( breakpoints.mobile ) {
143
+ mediaQueries[ '@mobile' ] = `@media (width <= ${ breakpoints.mobile })`;
144
+ }
145
+
146
+ if ( breakpoints.tablet ) {
147
+ mediaQueries[ '@tablet' ] = breakpoints.mobile
148
+ ? `@media (${ breakpoints.mobile } < width <= ${ breakpoints.tablet })`
149
+ : `@media (width <= ${ breakpoints.tablet })`;
150
+ }
151
+
152
+ return mediaQueries;
153
+ }