meno-core 1.0.47 → 1.0.49

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 (97) hide show
  1. package/build-astro.ts +2 -2
  2. package/dist/build-static.js +7 -7
  3. package/dist/chunks/{chunk-UUA5LEWF.js → chunk-6IVUG7FY.js} +138 -7
  4. package/dist/chunks/chunk-6IVUG7FY.js.map +7 -0
  5. package/dist/chunks/{chunk-XSWR3QLI.js → chunk-AZQYF6KE.js} +261 -130
  6. package/dist/chunks/chunk-AZQYF6KE.js.map +7 -0
  7. package/dist/chunks/{chunk-47UNLQUU.js → chunk-CHD5UCFF.js} +57 -12
  8. package/dist/chunks/chunk-CHD5UCFF.js.map +7 -0
  9. package/dist/chunks/{chunk-FGUZOYJX.js → chunk-EQYDSPBB.js} +435 -131
  10. package/dist/chunks/chunk-EQYDSPBB.js.map +7 -0
  11. package/dist/chunks/{chunk-IF3RATBY.js → chunk-H4JSCDNW.js} +2 -2
  12. package/dist/chunks/{chunk-KITQJYZV.js → chunk-J23ZX5AP.js} +40 -4
  13. package/dist/chunks/chunk-J23ZX5AP.js.map +7 -0
  14. package/dist/chunks/{chunk-LJFB5EBT.js → chunk-JER5NQVM.js} +5 -5
  15. package/dist/chunks/{chunk-ZTKHJQ2Z.js → chunk-KPU2XHOS.js} +5 -2
  16. package/dist/chunks/{chunk-ZTKHJQ2Z.js.map → chunk-KPU2XHOS.js.map} +2 -2
  17. package/dist/chunks/{chunk-BCLGRZ3U.js → chunk-LKAGAQ3M.js} +2 -2
  18. package/dist/chunks/{chunk-FED5MME6.js → chunk-S2CX6HFM.js} +262 -26
  19. package/dist/chunks/chunk-S2CX6HFM.js.map +7 -0
  20. package/dist/chunks/{configService-DYCUEURL.js → configService-CCA6AIDI.js} +3 -3
  21. package/dist/entries/server-router.js +9 -9
  22. package/dist/entries/server-router.js.map +2 -2
  23. package/dist/lib/client/index.js +64 -20
  24. package/dist/lib/client/index.js.map +3 -3
  25. package/dist/lib/server/index.js +1737 -296
  26. package/dist/lib/server/index.js.map +4 -4
  27. package/dist/lib/shared/index.js +50 -10
  28. package/dist/lib/shared/index.js.map +3 -3
  29. package/entries/server-router.tsx +6 -2
  30. package/lib/client/core/ComponentBuilder.test.ts +17 -0
  31. package/lib/client/core/ComponentBuilder.ts +25 -1
  32. package/lib/client/core/builders/embedBuilder.ts +15 -2
  33. package/lib/client/core/builders/linkNodeBuilder.ts +15 -2
  34. package/lib/client/core/builders/localeListBuilder.ts +17 -6
  35. package/lib/client/styles/StyleInjector.ts +3 -2
  36. package/lib/client/theme.ts +4 -4
  37. package/lib/server/cssGenerator.test.ts +64 -1
  38. package/lib/server/cssGenerator.ts +48 -9
  39. package/lib/server/index.ts +1 -1
  40. package/lib/server/jsonLoader.test.ts +0 -17
  41. package/lib/server/jsonLoader.ts +0 -81
  42. package/lib/server/providers/fileSystemCMSProvider.test.ts +163 -0
  43. package/lib/server/providers/fileSystemCMSProvider.ts +200 -11
  44. package/lib/server/routes/api/variables.ts +4 -2
  45. package/lib/server/routes/index.ts +1 -1
  46. package/lib/server/routes/pages.ts +23 -1
  47. package/lib/server/services/cmsService.test.ts +246 -0
  48. package/lib/server/services/cmsService.ts +122 -5
  49. package/lib/server/services/configService.ts +5 -0
  50. package/lib/server/ssr/attributeBuilder.ts +41 -0
  51. package/lib/server/ssr/htmlGenerator.test.ts +114 -2
  52. package/lib/server/ssr/htmlGenerator.ts +53 -6
  53. package/lib/server/ssr/liveReloadIntegration.test.ts +209 -0
  54. package/lib/server/ssr/ssrRenderer.test.ts +362 -1
  55. package/lib/server/ssr/ssrRenderer.ts +216 -72
  56. package/lib/server/utils/jsonLineMapper.test.ts +53 -1
  57. package/lib/server/utils/jsonLineMapper.ts +43 -3
  58. package/lib/server/webflow/buildWebflow.ts +343 -123
  59. package/lib/server/webflow/index.ts +1 -0
  60. package/lib/server/webflow/nodeToWebflow.test.ts +3170 -0
  61. package/lib/server/webflow/nodeToWebflow.ts +2141 -129
  62. package/lib/server/webflow/styleMapper.test.ts +389 -0
  63. package/lib/server/webflow/styleMapper.ts +517 -63
  64. package/lib/server/webflow/templateWrapper.ts +49 -0
  65. package/lib/server/webflow/types.ts +218 -18
  66. package/lib/shared/cssGeneration.test.ts +267 -1
  67. package/lib/shared/cssGeneration.ts +240 -18
  68. package/lib/shared/cssProperties.test.ts +247 -1
  69. package/lib/shared/cssProperties.ts +196 -6
  70. package/lib/shared/elementClassName.test.ts +15 -0
  71. package/lib/shared/elementClassName.ts +7 -3
  72. package/lib/shared/interfaces/contentProvider.ts +39 -6
  73. package/lib/shared/pathSecurity.ts +16 -0
  74. package/lib/shared/registry/nodeTypes/ListNodeType.ts +1 -1
  75. package/lib/shared/responsiveScaling.test.ts +143 -0
  76. package/lib/shared/responsiveScaling.ts +253 -2
  77. package/lib/shared/themeDefaults.test.ts +3 -3
  78. package/lib/shared/themeDefaults.ts +3 -3
  79. package/lib/shared/types/cms.ts +28 -3
  80. package/lib/shared/types/index.ts +2 -0
  81. package/lib/shared/types/variables.ts +37 -0
  82. package/lib/shared/utilityClassConfig.ts +3 -0
  83. package/lib/shared/utilityClassMapper.test.ts +123 -0
  84. package/lib/shared/utilityClassMapper.ts +179 -8
  85. package/lib/shared/validation/schemas.ts +15 -1
  86. package/lib/shared/validation/validators.ts +26 -1
  87. package/package.json +1 -1
  88. package/dist/chunks/chunk-47UNLQUU.js.map +0 -7
  89. package/dist/chunks/chunk-FED5MME6.js.map +0 -7
  90. package/dist/chunks/chunk-FGUZOYJX.js.map +0 -7
  91. package/dist/chunks/chunk-KITQJYZV.js.map +0 -7
  92. package/dist/chunks/chunk-UUA5LEWF.js.map +0 -7
  93. package/dist/chunks/chunk-XSWR3QLI.js.map +0 -7
  94. /package/dist/chunks/{chunk-IF3RATBY.js.map → chunk-H4JSCDNW.js.map} +0 -0
  95. /package/dist/chunks/{chunk-LJFB5EBT.js.map → chunk-JER5NQVM.js.map} +0 -0
  96. /package/dist/chunks/{chunk-BCLGRZ3U.js.map → chunk-LKAGAQ3M.js.map} +0 -0
  97. /package/dist/chunks/{configService-DYCUEURL.js.map → configService-CCA6AIDI.js.map} +0 -0
@@ -62,127 +62,6 @@ function getBreakpointLabel(name, breakpoints = DEFAULT_BREAKPOINTS) {
62
62
  return name.replace(/([A-Z])/g, " $1").replace(/^./, (str) => str.toUpperCase()).trim();
63
63
  }
64
64
 
65
- // lib/shared/responsiveScaling.ts
66
- function getScaleCategory(property) {
67
- const propertyStr = property;
68
- if (property === "fontSize") return "fontSize";
69
- if (propertyStr.startsWith("padding")) return "padding";
70
- if (propertyStr.startsWith("margin")) return "margin";
71
- if (property === "gap" || property === "rowGap" || property === "columnGap") return "gap";
72
- if (propertyStr === "borderRadius" || propertyStr.startsWith("border") && propertyStr.includes("Radius")) return "borderRadius";
73
- if (property === "width" || property === "height" || property === "maxWidth" || property === "maxHeight" || property === "minWidth" || property === "minHeight") return "size";
74
- return null;
75
- }
76
- function parseValue(valueStr) {
77
- const match = valueStr.trim().match(/^(-?[\d.]+)(px|rem|em|%|pt)$/);
78
- if (!match) return null;
79
- return {
80
- value: parseFloat(match[1]),
81
- unit: match[2]
82
- };
83
- }
84
- function calculateResponsiveValue(baseValue, baseReference, scale) {
85
- if (Math.abs(baseValue) <= baseReference) {
86
- return Math.round(baseValue);
87
- }
88
- const scaled = baseValue + (baseValue - baseReference) * (scale - 1);
89
- return Math.round(scaled);
90
- }
91
- function getScaleMultiplier(scales, property, breakpoint) {
92
- const category = getScaleCategory(property);
93
- if (!category || !scales[category]) return null;
94
- const scaleConfig = scales[category];
95
- return scaleConfig?.[breakpoint] ?? null;
96
- }
97
- function parseMultiValue(valueStr) {
98
- const normalized = valueStr.replace(/(?<=\w)-(?=\d|auto|inherit|initial|unset)/g, " ");
99
- return normalized.trim().split(/\s+/).filter((v) => v.length > 0);
100
- }
101
- function scaleValue(valueStr, baseReference, scale) {
102
- const parsed = parseValue(valueStr);
103
- if (!parsed) return null;
104
- if (parsed.unit === "%" || parsed.unit === "em") {
105
- return valueStr.trim();
106
- }
107
- const scaledValue = calculateResponsiveValue(parsed.value, baseReference, scale);
108
- return `${scaledValue}${parsed.unit}`;
109
- }
110
- function scalePropertyValue(valueStr, baseReference, scale) {
111
- const parts = parseMultiValue(valueStr);
112
- if (parts.length === 0) return null;
113
- const scaledParts = parts.map((part) => {
114
- const scaled = scaleValue(part, baseReference, scale);
115
- if (scaled !== null) {
116
- return scaled;
117
- }
118
- return part;
119
- });
120
- return scaledParts.join(" ");
121
- }
122
- function getResponsiveValues(baseValue, property, scales, breakpointNames) {
123
- if (!scales.enabled) {
124
- return { base: baseValue };
125
- }
126
- const result = {
127
- base: baseValue
128
- };
129
- const baseRef = scales.baseReference || 16;
130
- const breakpoints = breakpointNames ?? ["tablet", "mobile"];
131
- for (const breakpointName of breakpoints) {
132
- const scale = getScaleMultiplier(scales, property, breakpointName);
133
- if (scale !== null) {
134
- result[breakpointName] = scalePropertyValue(baseValue, baseRef, scale);
135
- }
136
- }
137
- return result;
138
- }
139
- function resolveVariableValueAtBreakpoint(variable, breakpoint, responsiveScales) {
140
- if (breakpoint === "base") return variable.value;
141
- const override = variable.scales?.[breakpoint];
142
- if (override !== void 0) return override;
143
- if (responsiveScales?.enabled && variable.type !== "none") {
144
- const scale = getScaleMultiplier(
145
- responsiveScales,
146
- variable.type,
147
- breakpoint
148
- );
149
- if (scale !== null) {
150
- const baseRef = responsiveScales.baseReference || 16;
151
- const scaled = scalePropertyValue(variable.value, baseRef, scale);
152
- if (scaled !== null) return scaled;
153
- }
154
- }
155
- return variable.value;
156
- }
157
- var DEFAULT_RESPONSIVE_SCALES = {
158
- enabled: false,
159
- baseReference: 16,
160
- fontSize: {
161
- tablet: 0.88,
162
- mobile: 0.75
163
- },
164
- padding: {
165
- tablet: 0.75,
166
- mobile: 0.5
167
- },
168
- margin: {
169
- tablet: 0.7,
170
- mobile: 0.45
171
- },
172
- gap: {
173
- tablet: 0.65,
174
- mobile: 0.4
175
- },
176
- borderRadius: {
177
- tablet: 0.85,
178
- mobile: 0.7
179
- },
180
- size: {
181
- tablet: 0.9,
182
- mobile: 0.75
183
- }
184
- };
185
-
186
65
  // lib/shared/i18n.ts
187
66
  var DEFAULT_I18N_CONFIG = {
188
67
  defaultLocale: "en",
@@ -343,6 +222,249 @@ function clearStoredLocale() {
343
222
  }
344
223
  }
345
224
 
225
+ // lib/shared/responsiveScaling.ts
226
+ var DEFAULT_FLUID_RANGE = { min: 320, max: 1440 };
227
+ var DEFAULT_SITE_MARGIN = { min: 16, max: 32 };
228
+ function getScaleCategory(property) {
229
+ const propertyStr = property;
230
+ if (property === "fontSize") return "fontSize";
231
+ if (propertyStr.startsWith("padding")) return "padding";
232
+ if (propertyStr.startsWith("margin")) return "margin";
233
+ if (property === "gap" || property === "rowGap" || property === "columnGap") return "gap";
234
+ if (propertyStr === "borderRadius" || propertyStr.startsWith("border") && propertyStr.includes("Radius")) return "borderRadius";
235
+ if (property === "width" || property === "height" || property === "maxWidth" || property === "maxHeight" || property === "minWidth" || property === "minHeight") return "size";
236
+ return null;
237
+ }
238
+ function parseValue(valueStr) {
239
+ const match = valueStr.trim().match(/^(-?[\d.]+)(px|rem|em|%|pt)$/);
240
+ if (!match) return null;
241
+ return {
242
+ value: parseFloat(match[1]),
243
+ unit: match[2]
244
+ };
245
+ }
246
+ var SCALABLE_CSS_PROPERTIES = /* @__PURE__ */ new Set([
247
+ "padding",
248
+ "padding-left",
249
+ "padding-right",
250
+ "padding-top",
251
+ "padding-bottom",
252
+ "paddingLeft",
253
+ "paddingRight",
254
+ "paddingTop",
255
+ "paddingBottom",
256
+ "margin",
257
+ "margin-left",
258
+ "margin-right",
259
+ "margin-top",
260
+ "margin-bottom",
261
+ "marginLeft",
262
+ "marginRight",
263
+ "marginTop",
264
+ "marginBottom",
265
+ "font-size",
266
+ "fontSize",
267
+ "gap",
268
+ "row-gap",
269
+ "column-gap",
270
+ "rowGap",
271
+ "columnGap",
272
+ "border-radius",
273
+ "borderRadius",
274
+ "border-top-left-radius",
275
+ "border-top-right-radius",
276
+ "border-bottom-left-radius",
277
+ "border-bottom-right-radius",
278
+ "borderTopLeftRadius",
279
+ "borderTopRightRadius",
280
+ "borderBottomLeftRadius",
281
+ "borderBottomRightRadius",
282
+ "width",
283
+ "height",
284
+ "max-width",
285
+ "max-height",
286
+ "min-width",
287
+ "min-height",
288
+ "maxWidth",
289
+ "maxHeight",
290
+ "minWidth",
291
+ "minHeight"
292
+ ]);
293
+ function calculateResponsiveValue(baseValue, baseReference, scale) {
294
+ if (Math.abs(baseValue) <= baseReference) {
295
+ return Math.round(baseValue);
296
+ }
297
+ const scaled = baseValue + (baseValue - baseReference) * (scale - 1);
298
+ return Math.round(scaled);
299
+ }
300
+ function getScaleMultiplier(scales, property, breakpoint) {
301
+ const category = getScaleCategory(property);
302
+ if (!category || !scales[category]) return null;
303
+ const scaleConfig = scales[category];
304
+ return scaleConfig?.[breakpoint] ?? null;
305
+ }
306
+ function parseMultiValue(valueStr) {
307
+ const normalized = valueStr.replace(/(?<=\w)-(?=\d|auto|inherit|initial|unset)/g, " ");
308
+ return normalized.trim().split(/\s+/).filter((v) => v.length > 0);
309
+ }
310
+ function scaleValue(valueStr, baseReference, scale) {
311
+ const parsed = parseValue(valueStr);
312
+ if (!parsed) return null;
313
+ if (parsed.unit === "%" || parsed.unit === "em") {
314
+ return valueStr.trim();
315
+ }
316
+ const scaledValue = calculateResponsiveValue(parsed.value, baseReference, scale);
317
+ return `${scaledValue}${parsed.unit}`;
318
+ }
319
+ function scalePropertyValue(valueStr, baseReference, scale) {
320
+ const parts = parseMultiValue(valueStr);
321
+ if (parts.length === 0) return null;
322
+ const scaledParts = parts.map((part) => {
323
+ const scaled = scaleValue(part, baseReference, scale);
324
+ if (scaled !== null) {
325
+ return scaled;
326
+ }
327
+ return part;
328
+ });
329
+ return scaledParts.join(" ");
330
+ }
331
+ function getResponsiveValues(baseValue, property, scales, breakpointNames) {
332
+ if (!scales.enabled) {
333
+ return { base: baseValue };
334
+ }
335
+ const result = {
336
+ base: baseValue
337
+ };
338
+ const baseRef = scales.baseReference || 16;
339
+ const breakpoints = breakpointNames ?? ["tablet", "mobile"];
340
+ for (const breakpointName of breakpoints) {
341
+ const scale = getScaleMultiplier(scales, property, breakpointName);
342
+ if (scale !== null) {
343
+ result[breakpointName] = scalePropertyValue(baseValue, baseRef, scale);
344
+ }
345
+ }
346
+ return result;
347
+ }
348
+ function resolveVariableValueAtBreakpoint(variable, breakpoint, responsiveScales) {
349
+ if (breakpoint === "base") return variable.value;
350
+ const override = variable.scales?.[breakpoint];
351
+ if (override !== void 0) return override;
352
+ if (responsiveScales?.enabled && variable.type !== "none") {
353
+ const scale = getScaleMultiplier(
354
+ responsiveScales,
355
+ variable.type,
356
+ breakpoint
357
+ );
358
+ if (scale !== null) {
359
+ const baseRef = responsiveScales.baseReference || 16;
360
+ const scaled = scalePropertyValue(variable.value, baseRef, scale);
361
+ if (scaled !== null) return scaled;
362
+ }
363
+ }
364
+ return variable.value;
365
+ }
366
+ function getSmallestBreakpointName(breakpoints) {
367
+ if (!breakpoints) return null;
368
+ const entries = Object.entries(breakpoints);
369
+ if (entries.length === 0) return null;
370
+ let smallestName = entries[0][0];
371
+ let smallestWidth = entries[0][1].breakpoint;
372
+ for (const [name, cfg] of entries) {
373
+ if (cfg.breakpoint < smallestWidth) {
374
+ smallestWidth = cfg.breakpoint;
375
+ smallestName = name;
376
+ }
377
+ }
378
+ return smallestName;
379
+ }
380
+ function buildFluidClamp(baseValue, unit, scale, vpMin, vpMax, baseReference = 16) {
381
+ const max = baseValue;
382
+ const min = calculateResponsiveValue(baseValue, baseReference, scale);
383
+ if (min === max || vpMax === vpMin) {
384
+ return `${formatNumber(max)}${unit}`;
385
+ }
386
+ const unitToPx = unit === "rem" ? 16 : 1;
387
+ const minPx = min * unitToPx;
388
+ const maxPx = max * unitToPx;
389
+ const slopePx = (maxPx - minPx) / (vpMax - vpMin);
390
+ const interceptPx = minPx - slopePx * vpMin;
391
+ const interceptInUnit = interceptPx / unitToPx;
392
+ const slopeVw = slopePx * 100;
393
+ return `clamp(${formatNumber(min)}${unit}, ${formatNumber(interceptInUnit)}${unit} + ${formatNumber(slopeVw)}vw, ${formatNumber(max)}${unit})`;
394
+ }
395
+ function buildFluidClampWithExplicitMin(minValue, maxValue, unit, vpMin, vpMax) {
396
+ if (minValue === maxValue || vpMax === vpMin) {
397
+ return `${formatNumber(maxValue)}${unit}`;
398
+ }
399
+ const unitToPx = unit === "rem" ? 16 : 1;
400
+ const minPx = minValue * unitToPx;
401
+ const maxPx = maxValue * unitToPx;
402
+ const slopePx = (maxPx - minPx) / (vpMax - vpMin);
403
+ const interceptPx = minPx - slopePx * vpMin;
404
+ const interceptInUnit = interceptPx / unitToPx;
405
+ const slopeVw = slopePx * 100;
406
+ return `clamp(${formatNumber(minValue)}${unit}, ${formatNumber(interceptInUnit)}${unit} + ${formatNumber(slopeVw)}vw, ${formatNumber(maxValue)}${unit})`;
407
+ }
408
+ function formatNumber(n) {
409
+ if (Number.isInteger(n)) return String(n);
410
+ return Number(n.toFixed(4)).toString();
411
+ }
412
+ function buildSiteMarginClamp(siteMargin, fluidRange) {
413
+ const { min, max } = siteMargin;
414
+ const { min: vpMin, max: vpMax } = fluidRange;
415
+ if (min === max || vpMax === vpMin) {
416
+ return `${formatNumber(max)}px`;
417
+ }
418
+ const slopePx = (max - min) / (vpMax - vpMin);
419
+ const interceptPx = min - slopePx * vpMin;
420
+ const slopeVw = slopePx * 100;
421
+ return `clamp(${formatNumber(min)}px, ${formatNumber(interceptPx)}px + ${formatNumber(slopeVw)}vw, ${formatNumber(max)}px)`;
422
+ }
423
+ function buildFluidPropertyValue(valueStr, scale, vpMin, vpMax, baseReference = 16) {
424
+ const parts = parseMultiValue(valueStr);
425
+ if (parts.length === 0) return null;
426
+ let anyScaled = false;
427
+ const out = parts.map((part) => {
428
+ const parsed = parseValue(part);
429
+ if (!parsed) return part;
430
+ if (parsed.unit === "%" || parsed.unit === "em") return part;
431
+ anyScaled = true;
432
+ return buildFluidClamp(parsed.value, parsed.unit, scale, vpMin, vpMax, baseReference);
433
+ });
434
+ return anyScaled ? out.join(" ") : null;
435
+ }
436
+ var DEFAULT_RESPONSIVE_SCALES = {
437
+ enabled: false,
438
+ mode: "breakpoints",
439
+ baseReference: 16,
440
+ fluidRange: { ...DEFAULT_FLUID_RANGE },
441
+ siteMargin: { ...DEFAULT_SITE_MARGIN },
442
+ fontSize: {
443
+ tablet: 0.88,
444
+ mobile: 0.75
445
+ },
446
+ padding: {
447
+ tablet: 0.75,
448
+ mobile: 0.5
449
+ },
450
+ margin: {
451
+ tablet: 0.7,
452
+ mobile: 0.45
453
+ },
454
+ gap: {
455
+ tablet: 0.65,
456
+ mobile: 0.4
457
+ },
458
+ borderRadius: {
459
+ tablet: 0.85,
460
+ mobile: 0.7
461
+ },
462
+ size: {
463
+ tablet: 0.9,
464
+ mobile: 0.75
465
+ }
466
+ };
467
+
346
468
  // lib/shared/pxToRem.ts
347
469
  var DEFAULT_REM_CONFIG = {
348
470
  enabled: false,
@@ -397,14 +519,6 @@ export {
397
519
  getAllBreakpointNames,
398
520
  getBreakpointName,
399
521
  getBreakpointLabel,
400
- calculateResponsiveValue,
401
- getScaleMultiplier,
402
- parseMultiValue,
403
- scaleValue,
404
- scalePropertyValue,
405
- getResponsiveValues,
406
- resolveVariableValueAtBreakpoint,
407
- DEFAULT_RESPONSIVE_SCALES,
408
522
  DEFAULT_I18N_CONFIG,
409
523
  getLocaleCodes,
410
524
  findLocaleByCode,
@@ -420,9 +534,26 @@ export {
420
534
  getStoredLocale,
421
535
  setStoredLocale,
422
536
  clearStoredLocale,
537
+ DEFAULT_FLUID_RANGE,
538
+ DEFAULT_SITE_MARGIN,
539
+ parseValue,
540
+ SCALABLE_CSS_PROPERTIES,
541
+ calculateResponsiveValue,
542
+ getScaleMultiplier,
543
+ parseMultiValue,
544
+ scaleValue,
545
+ scalePropertyValue,
546
+ getResponsiveValues,
547
+ resolveVariableValueAtBreakpoint,
548
+ getSmallestBreakpointName,
549
+ buildFluidClamp,
550
+ buildFluidClampWithExplicitMin,
551
+ buildSiteMarginClamp,
552
+ buildFluidPropertyValue,
553
+ DEFAULT_RESPONSIVE_SCALES,
423
554
  DEFAULT_REM_CONFIG,
424
555
  convertPxToRem,
425
556
  shouldConvertProperty,
426
557
  applyRemConversion
427
558
  };
428
- //# sourceMappingURL=chunk-XSWR3QLI.js.map
559
+ //# sourceMappingURL=chunk-AZQYF6KE.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../lib/shared/breakpoints.ts", "../../lib/shared/i18n.ts", "../../lib/shared/responsiveScaling.ts", "../../lib/shared/pxToRem.ts"],
4
+ "sourcesContent": ["/**\n * Shared Breakpoint Configuration\n * Defines breakpoints for responsive design\n * Supports dynamic breakpoints from project.config.json\n */\n\n/**\n * Extended breakpoint entry with separate CSS threshold and editor preview width\n * - breakpoint: The CSS media query threshold (max-width value)\n * - previewPoint: The width used in editor preview mode (defaults to breakpoint if not specified)\n * - label: Optional display label for UI (e.g., \"Tablet Landscape\", \"Phone\")\n */\nexport interface BreakpointEntry {\n breakpoint: number;\n previewPoint: number;\n label?: string;\n}\n\n/**\n * Input format for breakpoint config - supports both legacy (number) and new (object) format\n * Legacy: { tablet: 1024 }\n * New: { tablet: { breakpoint: 1024, previewPoint: 768 } }\n */\nexport type BreakpointConfigInput = Record<string, number | BreakpointEntry>;\n\n/**\n * Normalized breakpoint config - always uses object format\n */\nexport type BreakpointConfig = Record<string, BreakpointEntry>;\n\n/**\n * Legacy format for backward compatibility (simple number values)\n */\nexport type LegacyBreakpointConfig = Record<string, number>;\n\n// BreakpointName is now a string to support dynamic breakpoints\nexport type BreakpointName = string;\n\nexport const DEFAULT_BREAKPOINTS: BreakpointConfig = {\n tablet: { breakpoint: 1024, previewPoint: 768 },\n mobile: { breakpoint: 540, previewPoint: 375 },\n} as const;\n\n/**\n * Normalize a breakpoint config input to the full object format\n * Converts legacy number format to object format\n * If previewPoint is not specified, defaults to breakpoint value\n */\nexport function normalizeBreakpointConfig(\n input: BreakpointConfigInput | LegacyBreakpointConfig\n): BreakpointConfig {\n const result: BreakpointConfig = {};\n\n for (const [name, value] of Object.entries(input)) {\n if (typeof value === 'number') {\n // Legacy format: number -> { breakpoint: value, previewPoint: value }\n result[name] = { breakpoint: value, previewPoint: value };\n } else if (typeof value === 'object' && value !== null) {\n // New format: ensure both values exist, preserve label if present\n result[name] = {\n breakpoint: value.breakpoint,\n previewPoint: value.previewPoint ?? value.breakpoint,\n ...(value.label !== undefined && { label: value.label }),\n };\n }\n }\n\n return result;\n}\n\n/**\n * Get just the breakpoint values for CSS generation (media queries)\n * Returns Record<string, number> with breakpoint values\n */\nexport function getBreakpointValues(config: BreakpointConfig): LegacyBreakpointConfig {\n const result: LegacyBreakpointConfig = {};\n for (const [name, entry] of Object.entries(config)) {\n result[name] = entry.breakpoint;\n }\n return result;\n}\n\n/**\n * Get just the preview point values for editor preview\n * Returns Record<string, number> with previewPoint values\n */\nexport function getPreviewPointValues(config: BreakpointConfig): LegacyBreakpointConfig {\n const result: LegacyBreakpointConfig = {};\n for (const [name, entry] of Object.entries(config)) {\n result[name] = entry.previewPoint;\n }\n return result;\n}\n\n/**\n * Get all breakpoint names from the breakpoint configuration\n * Always includes 'base' plus all keys from the config\n * Order: base (desktop) -> breakpoints sorted by value descending (largest to smallest viewport)\n */\nexport function getAllBreakpointNames(\n breakpoints: BreakpointConfig = DEFAULT_BREAKPOINTS\n): BreakpointName[] {\n // Base is always included first\n const names: BreakpointName[] = ['base'];\n\n // Get all breakpoint names from config and sort by breakpoint value (descending)\n // This ensures proper order: largest viewport first\n const breakpointEntries = Object.entries(breakpoints);\n breakpointEntries.sort((a, b) => b[1].breakpoint - a[1].breakpoint); // Sort descending by breakpoint value\n\n // Add breakpoint names in sorted order\n for (const [name] of breakpointEntries) {\n names.push(name);\n }\n\n return names;\n}\n\n/**\n * Get active breakpoint name based on viewport width\n * Returns the smallest breakpoint that the viewport width is less than or equal to\n * If viewport is larger than all breakpoints, returns 'base'\n * Uses .breakpoint value for comparison (CSS threshold)\n */\nexport function getBreakpointName(\n viewportWidth: number,\n breakpoints: BreakpointConfig = DEFAULT_BREAKPOINTS\n): BreakpointName {\n // Sort breakpoints by breakpoint value (ascending) to find the smallest one that matches\n const breakpointEntries = Object.entries(breakpoints);\n breakpointEntries.sort((a, b) => a[1].breakpoint - b[1].breakpoint); // Sort ascending by breakpoint value\n\n // Find the smallest breakpoint that viewport width is <= to\n for (const [name, entry] of breakpointEntries) {\n if (viewportWidth <= entry.breakpoint) {\n return name;\n }\n }\n\n // If viewport is larger than all breakpoints, return 'base'\n return 'base';\n}\n\n/**\n * Get display label for a breakpoint\n * Priority:\n * 1. Label from config (if set)\n * 2. \"Desktop\" for 'base'\n * 3. Auto-capitalized name (camelCase -> Title Case)\n */\nexport function getBreakpointLabel(\n name: BreakpointName,\n breakpoints: BreakpointConfig = DEFAULT_BREAKPOINTS\n): string {\n // Base always returns \"Desktop\"\n if (name === 'base') {\n return 'Desktop';\n }\n\n // Check for custom label in config\n const entry = breakpoints[name];\n if (entry?.label) {\n return entry.label;\n }\n\n // Auto-format: camelCase -> Title Case\n // e.g., \"tabletLandscape\" -> \"Tablet Landscape\"\n return name\n .replace(/([A-Z])/g, ' $1')\n .replace(/^./, (str) => str.toUpperCase())\n .trim();\n}\n", "/**\n * Internationalization (i18n) utilities\n * Handles inline translation resolution for component props\n */\n\nimport type { I18nValue, I18nConfig, LocaleConfig } from './types/components';\n\n/**\n * Default i18n configuration\n */\nexport const DEFAULT_I18N_CONFIG: I18nConfig = {\n defaultLocale: 'en',\n locales: [\n { code: 'en', name: 'English', nativeName: 'English', langTag: 'en-US' }\n ],\n};\n\n// ============================================\n// Locale helper functions\n// ============================================\n\n/**\n * Get array of locale codes from config\n */\nexport function getLocaleCodes(config: I18nConfig): string[] {\n return config.locales.map(loc => loc.code);\n}\n\n/**\n * Find a locale config by its code\n */\nexport function findLocaleByCode(config: I18nConfig, code: string): LocaleConfig | undefined {\n return config.locales.find(loc => loc.code === code);\n}\n\n/**\n * Check if a locale code is valid/exists in config\n */\nexport function isValidLocaleCode(config: I18nConfig, code: string): boolean {\n return config.locales.some(loc => loc.code === code);\n}\n\n// ============================================\n// Config Migration (old string[] -> new LocaleConfig[])\n// ============================================\n\n/**\n * Convert old locale format (string) to new format (LocaleConfig)\n */\nfunction migrateLocaleString(code: string): LocaleConfig {\n const upperCode = code.toUpperCase();\n return {\n code: code.toLowerCase(),\n name: upperCode,\n nativeName: upperCode,\n langTag: `${code.toLowerCase()}-${upperCode}`,\n };\n}\n\n/**\n * Check if locales array is in old string format\n */\nfunction isOldLocaleFormat(locales: unknown): locales is string[] {\n return Array.isArray(locales) && locales.length > 0 && typeof locales[0] === 'string';\n}\n\n/**\n * Migrate i18n config from old format to new format\n * Old: { defaultLocale: \"en\", locales: [\"en\", \"pl\"] }\n * New: { defaultLocale: \"en\", locales: [{ code: \"en\", name: \"EN\", ... }] }\n */\nexport function migrateI18nConfig(i18n: unknown): I18nConfig {\n if (!i18n || typeof i18n !== 'object') {\n return DEFAULT_I18N_CONFIG;\n }\n\n const config = i18n as Record<string, unknown>;\n const defaultLocale = (config.defaultLocale as string) || 'en';\n const locales = config.locales;\n\n if (!locales || !Array.isArray(locales)) {\n return DEFAULT_I18N_CONFIG;\n }\n\n // Migrate old string[] format\n if (isOldLocaleFormat(locales)) {\n return {\n defaultLocale,\n locales: locales.map(migrateLocaleString),\n };\n }\n\n // Already in new format\n return {\n defaultLocale,\n locales: locales as LocaleConfig[],\n };\n}\n\n/**\n * Type guard to check if a value is an I18nValue object\n */\nexport function isI18nValue(value: unknown): value is I18nValue {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return false;\n }\n return '_i18n' in value && (value as Record<string, unknown>)._i18n === true;\n}\n\n/**\n * Resolve a single translation value for the given locale\n * Fallback order: exact locale -> default locale -> first available -> empty\n * Works with any value type (strings, arrays for list props, etc.)\n */\nexport function resolveTranslation(\n value: I18nValue,\n locale: string,\n config: I18nConfig\n): unknown {\n // Try exact locale match (any type - string, array, etc.)\n if (locale in value && value[locale] !== undefined && locale !== '_i18n') {\n return value[locale];\n }\n\n // Try default locale\n if (config.defaultLocale in value && value[config.defaultLocale] !== undefined) {\n return value[config.defaultLocale];\n }\n\n // Get first available value (skip _i18n marker)\n for (const key of Object.keys(value)) {\n if (key !== '_i18n' && value[key] !== undefined) {\n return value[key];\n }\n }\n\n // Return empty string for string i18n, empty array for list i18n\n // Check if any value is an array to determine the type\n const hasArrayValue = Object.entries(value).some(\n ([k, v]) => k !== '_i18n' && Array.isArray(v)\n );\n return hasArrayValue ? [] : '';\n}\n\n/**\n * Resolve a value that might be an I18nValue or a regular value\n * Returns the original value if not an I18nValue\n */\nexport function resolveI18nValue(\n value: unknown,\n locale: string,\n config: I18nConfig\n): unknown {\n if (isI18nValue(value)) {\n return resolveTranslation(value, locale, config);\n }\n return value;\n}\n\n/**\n * Recursively resolve all I18nValue objects in a props object\n */\nexport function resolveI18nInProps(\n props: Record<string, unknown>,\n locale: string,\n config: I18nConfig\n): Record<string, unknown> {\n const resolved: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(props)) {\n if (isI18nValue(value)) {\n resolved[key] = resolveTranslation(value, locale, config);\n } else if (Array.isArray(value)) {\n resolved[key] = value.map((item) =>\n isI18nValue(item) ? resolveTranslation(item, locale, config) : item\n );\n } else if (typeof value === 'object' && value !== null) {\n // Recursively resolve nested objects (but not I18nValue which is already handled)\n resolved[key] = resolveI18nInProps(\n value as Record<string, unknown>,\n locale,\n config\n );\n } else {\n resolved[key] = value;\n }\n }\n\n return resolved;\n}\n\n/**\n * Extract locale from URL path prefix\n * e.g., '/en/about' -> 'en', '/pl/' -> 'pl', '/about' -> null\n */\nexport function extractLocaleFromPath(\n path: string,\n config: I18nConfig\n): { locale: string | null; pathWithoutLocale: string } {\n // Remove leading slash and split\n const cleanPath = path.startsWith('/') ? path.slice(1) : path;\n const segments = cleanPath.split('/');\n\n if (segments.length > 0 && isValidLocaleCode(config, segments[0])) {\n const locale = segments[0];\n const pathWithoutLocale = '/' + segments.slice(1).join('/');\n return { locale, pathWithoutLocale: pathWithoutLocale || '/' };\n }\n\n return { locale: null, pathWithoutLocale: path };\n}\n\n/**\n * Build a localized path\n * e.g., ('/about', 'pl') -> '/pl/about'\n */\nexport function buildLocalizedPath(path: string, locale: string): string {\n const cleanPath = path.startsWith('/') ? path : '/' + path;\n return `/${locale}${cleanPath === '/' ? '' : cleanPath}`;\n}\n\n/**\n * Locale context containing resolved locale info\n */\nexport interface LocaleContext {\n /** The effective locale (never null) */\n locale: string;\n /** Path with locale prefix removed */\n pathWithoutLocale: string;\n /** Whether the current locale is the default */\n isDefaultLocale: boolean;\n}\n\n/**\n * Parse locale from path and return full context with effective locale\n * Combines extractLocaleFromPath + defaultLocale resolution in one call\n */\nexport function parseLocaleFromPath(\n path: string,\n config: I18nConfig\n): LocaleContext {\n const { locale, pathWithoutLocale } = extractLocaleFromPath(path, config);\n const effectiveLocale = locale || config.defaultLocale;\n\n return {\n locale: effectiveLocale,\n pathWithoutLocale,\n isDefaultLocale: effectiveLocale === config.defaultLocale\n };\n}\n\n// ============================================\n// Client-side locale persistence utilities\n// ============================================\n\nconst LOCALE_STORAGE_KEY = 'meno_locale_preference';\nconst OLD_LOCALE_STORAGE_KEY = 'uplo_locale_preference';\n\n/**\n * Migrate locale storage key from old to new (one-time migration)\n */\nfunction migrateLocaleStorageKey(): void {\n if (typeof window === 'undefined') return;\n try {\n const oldValue = localStorage.getItem(OLD_LOCALE_STORAGE_KEY);\n const newValue = localStorage.getItem(LOCALE_STORAGE_KEY);\n if (oldValue && !newValue) {\n localStorage.setItem(LOCALE_STORAGE_KEY, oldValue);\n localStorage.removeItem(OLD_LOCALE_STORAGE_KEY);\n }\n } catch {\n // Storage not available\n }\n}\n\n/**\n * Get stored locale preference from localStorage (client-side only)\n */\nexport function getStoredLocale(): string | null {\n if (typeof window === 'undefined') return null;\n try {\n // Migrate from old key if needed\n migrateLocaleStorageKey();\n return localStorage.getItem(LOCALE_STORAGE_KEY);\n } catch {\n return null;\n }\n}\n\n/**\n * Store locale preference to localStorage (client-side only)\n */\nexport function setStoredLocale(locale: string): void {\n if (typeof window === 'undefined') return;\n try {\n localStorage.setItem(LOCALE_STORAGE_KEY, locale);\n } catch {\n // Storage not available\n }\n}\n\n/**\n * Clear stored locale preference (client-side only)\n */\nexport function clearStoredLocale(): void {\n if (typeof window === 'undefined') return;\n try {\n localStorage.removeItem(LOCALE_STORAGE_KEY);\n } catch {\n // Storage not available\n }\n}\n", "/**\n * Responsive Scaling Calculator\n * Automatically calculates responsive values for different breakpoints\n * using configured scale multipliers\n */\n\n/**\n * Scale configuration for a CSS property category\n * Keys are breakpoint names (e.g., 'tablet', 'mobile', 'small')\n * Values are scale multipliers (e.g., 0.88, 0.75)\n */\nexport type BreakpointScales = Record<string, number>;\n\nexport type ResponsiveMode = 'breakpoints' | 'fluid';\n\nexport interface FluidRange {\n /** Lower viewport bound in pixels (e.g. 320) */\n min: number;\n /** Upper viewport bound in pixels (e.g. 1440) */\n max: number;\n}\n\nexport interface SiteMarginConfig {\n /** Lower bound of the side margin at smallest viewport (px). */\n min: number;\n /** Upper bound of the side margin at largest viewport (px). */\n max: number;\n}\n\nexport interface ResponsiveScales {\n enabled: boolean;\n /** Scaling strategy. Missing \u2192 'breakpoints' (back-compat with old configs). */\n mode?: ResponsiveMode;\n baseReference: number;\n /** Viewport bounds used when `mode === 'fluid'`. Defaults to 320 / 1440 px. */\n fluidRange?: FluidRange;\n /**\n * Container side margin range, in fluid mode emitted as a CSS variable\n * `--site-margin: clamp(min, \u2026, max)` on `:root`. Lets users write\n * `width: calc(100% - var(--site-margin) * 2)` for the container pattern.\n */\n siteMargin?: SiteMarginConfig;\n fontSize?: BreakpointScales;\n padding?: BreakpointScales;\n margin?: BreakpointScales;\n gap?: BreakpointScales;\n borderRadius?: BreakpointScales;\n size?: BreakpointScales;\n [key: string]: boolean | number | string | BreakpointScales | FluidRange | SiteMarginConfig | undefined;\n}\n\nexport const DEFAULT_FLUID_RANGE: FluidRange = { min: 320, max: 1440 };\nexport const DEFAULT_SITE_MARGIN: SiteMarginConfig = { min: 16, max: 32 };\n\nexport type CSSPropertyType = 'fontSize' | 'padding' | 'margin' | 'gap' | 'paddingTop' | 'paddingRight' | 'paddingBottom' | 'paddingLeft' | 'marginTop' | 'marginRight' | 'marginBottom' | 'marginLeft' | 'rowGap' | 'columnGap' | 'borderRadius' | 'borderTopLeftRadius' | 'borderTopRightRadius' | 'borderBottomLeftRadius' | 'borderBottomRightRadius' | 'width' | 'height' | 'maxWidth' | 'maxHeight' | 'minWidth' | 'minHeight';\n\n/**\n * Map CSS property to its scale category\n * e.g., paddingTop -> padding, marginRight -> margin\n */\nfunction getScaleCategory(property: CSSPropertyType): keyof ResponsiveScales | null {\n const propertyStr = property as string;\n if (property === 'fontSize') return 'fontSize';\n if (propertyStr.startsWith('padding')) return 'padding';\n if (propertyStr.startsWith('margin')) return 'margin';\n if (property === 'gap' || property === 'rowGap' || property === 'columnGap') return 'gap';\n if (propertyStr === 'borderRadius' || (propertyStr.startsWith('border') && propertyStr.includes('Radius'))) return 'borderRadius';\n if (property === 'width' || property === 'height' || property === 'maxWidth' || property === 'maxHeight' || property === 'minWidth' || property === 'minHeight') return 'size';\n return null;\n}\n\n/**\n * Extract numeric value and unit from a CSS value string\n * e.g., \"67px\" -> { value: 67, unit: \"px\" }\n */\nexport function parseValue(valueStr: string): { value: number; unit: string } | null {\n const match = valueStr.trim().match(/^(-?[\\d.]+)(px|rem|em|%|pt)$/);\n if (!match) return null;\n return {\n value: parseFloat(match[1]),\n unit: match[2],\n };\n}\n\n/**\n * CSS properties that get fluid `clamp()` / breakpoint scaling. Mirrors the\n * `AUTO_RESPONSIVE_TYPE_MAP` keys in `cssGeneration.ts`; centralized here so\n * `utilityClassMapper.ts` can consult it without a cross-module import cycle.\n */\nexport const SCALABLE_CSS_PROPERTIES: ReadonlySet<string> = new Set([\n 'padding',\n 'padding-left',\n 'padding-right',\n 'padding-top',\n 'padding-bottom',\n 'paddingLeft',\n 'paddingRight',\n 'paddingTop',\n 'paddingBottom',\n 'margin',\n 'margin-left',\n 'margin-right',\n 'margin-top',\n 'margin-bottom',\n 'marginLeft',\n 'marginRight',\n 'marginTop',\n 'marginBottom',\n 'font-size',\n 'fontSize',\n 'gap',\n 'row-gap',\n 'column-gap',\n 'rowGap',\n 'columnGap',\n 'border-radius',\n 'borderRadius',\n 'border-top-left-radius',\n 'border-top-right-radius',\n 'border-bottom-left-radius',\n 'border-bottom-right-radius',\n 'borderTopLeftRadius',\n 'borderTopRightRadius',\n 'borderBottomLeftRadius',\n 'borderBottomRightRadius',\n 'width',\n 'height',\n 'max-width',\n 'max-height',\n 'min-width',\n 'min-height',\n 'maxWidth',\n 'maxHeight',\n 'minWidth',\n 'minHeight',\n]);\n\n/**\n * Calculate responsive value using the formula:\n * responsive_value = base_value + (base_value - base_reference) * (scale - 1)\n */\nexport function calculateResponsiveValue(\n baseValue: number,\n baseReference: number,\n scale: number\n): number {\n // Values at or below baseReference stay unchanged\n if (Math.abs(baseValue) <= baseReference) {\n return Math.round(baseValue);\n }\n const scaled = baseValue + (baseValue - baseReference) * (scale - 1);\n return Math.round(scaled);\n}\n\n/**\n * Get the scale multiplier for a specific property and breakpoint\n * @param scales - The responsive scales configuration\n * @param property - The CSS property type (e.g., 'fontSize', 'padding')\n * @param breakpoint - The breakpoint name (e.g., 'tablet', 'mobile', 'small')\n */\nexport function getScaleMultiplier(\n scales: ResponsiveScales,\n property: CSSPropertyType,\n breakpoint: string\n): number | null {\n const category = getScaleCategory(property);\n if (!category || !scales[category]) return null;\n\n const scaleConfig = scales[category] as BreakpointScales | undefined;\n return scaleConfig?.[breakpoint] ?? null;\n}\n\n/**\n * Parse multi-value CSS property (e.g., \"20px 40px\" for padding)\n * Handles both space-separated (\"20px 40px\") and hyphen-separated (\"20px-40px\") formats\n * Returns array of individual values\n */\nexport function parseMultiValue(valueStr: string): string[] {\n // First, convert hyphen separators to spaces (for class names like \"p-0-80px\" \u2192 \"0-80px\")\n // But only convert hyphens between values (digit/px followed by hyphen followed by digit/px)\n const normalized = valueStr.replace(/(?<=\\w)-(?=\\d|auto|inherit|initial|unset)/g, ' ');\n return normalized.trim().split(/\\s+/).filter(v => v.length > 0);\n}\n\n/**\n * Scale a single CSS value using the responsive scale\n * Returns null if the value cannot be parsed (no unit)\n */\nexport function scaleValue(\n valueStr: string,\n baseReference: number,\n scale: number\n): string | null {\n const parsed = parseValue(valueStr);\n if (!parsed) return null;\n\n // `%` and `em` are already relative to their rendering context\n // (container / local font-size), so they should not be rescaled.\n if (parsed.unit === '%' || parsed.unit === 'em') {\n return valueStr.trim();\n }\n\n const scaledValue = calculateResponsiveValue(parsed.value, baseReference, scale);\n return `${scaledValue}${parsed.unit}`;\n}\n\n/**\n * Scale a potentially multi-value CSS property\n * e.g., \"20px 40px\" -> \"18px 36px\" (both values scaled independently)\n * Unitless values (0, auto, inherit) are kept as-is\n */\nexport function scalePropertyValue(\n valueStr: string,\n baseReference: number,\n scale: number\n): string | null {\n const parts = parseMultiValue(valueStr);\n if (parts.length === 0) return null;\n\n const scaledParts = parts.map(part => {\n // Try to scale the value\n const scaled = scaleValue(part, baseReference, scale);\n if (scaled !== null) {\n return scaled;\n }\n // If it can't be scaled, keep it as-is (for unitless values like 0, auto, inherit)\n return part;\n });\n\n return scaledParts.join(' ');\n}\n\n/**\n * Get responsive values for all breakpoints\n * Returns object with calculated values for each breakpoint\n *\n * @param baseValue - The base CSS value (e.g., '67px')\n * @param property - The CSS property type (e.g., 'fontSize')\n * @param scales - The responsive scales configuration\n * @param breakpointNames - Optional array of breakpoint names to calculate values for.\n * If not provided, defaults to ['tablet', 'mobile'] for backward compatibility.\n */\nexport function getResponsiveValues(\n baseValue: string,\n property: CSSPropertyType,\n scales: ResponsiveScales,\n breakpointNames?: string[]\n): Record<string, string | null> {\n if (!scales.enabled) {\n return { base: baseValue };\n }\n\n const result: Record<string, string | null> = {\n base: baseValue,\n };\n\n const baseRef = scales.baseReference || 16;\n\n // Use provided breakpoint names or default to tablet/mobile for backward compatibility\n const breakpoints = breakpointNames ?? ['tablet', 'mobile'];\n\n // Calculate value for each breakpoint\n for (const breakpointName of breakpoints) {\n const scale = getScaleMultiplier(scales, property, breakpointName);\n if (scale !== null) {\n result[breakpointName] = scalePropertyValue(baseValue, baseRef, scale);\n }\n }\n\n return result;\n}\n\n/**\n * Resolve the effective value of a CSS variable at a given breakpoint.\n *\n * Precedence (mirrors generateVariablesCSS in cssGenerator.ts so the editor\n * widget stays in sync with what the browser will render):\n * 1. `breakpoint === 'base'` \u2192 variable.value\n * 2. explicit per-variable override \u2192 variable.scales[breakpoint]\n * 3. globally-scaled value (ResponsiveScales multiplier for variable.type)\n * 4. fallback \u2192 variable.value\n */\nexport function resolveVariableValueAtBreakpoint(\n variable: { value: string; type: string; scales?: Record<string, string> },\n breakpoint: string,\n responsiveScales?: ResponsiveScales | null\n): string {\n if (breakpoint === 'base') return variable.value;\n\n const override = variable.scales?.[breakpoint];\n if (override !== undefined) return override;\n\n if (responsiveScales?.enabled && variable.type !== 'none') {\n const scale = getScaleMultiplier(\n responsiveScales,\n variable.type as CSSPropertyType,\n breakpoint\n );\n if (scale !== null) {\n const baseRef = responsiveScales.baseReference || 16;\n const scaled = scalePropertyValue(variable.value, baseRef, scale);\n if (scaled !== null) return scaled;\n }\n }\n\n return variable.value;\n}\n\n/**\n * Pick the smallest (most restrictive) breakpoint name from a config object,\n * by `breakpoint` field. Used in fluid mode to choose which scale multiplier\n * defines the MIN of the clamp.\n *\n * Returns null if there are no entries.\n */\nexport function getSmallestBreakpointName(\n breakpoints: Record<string, { breakpoint: number }> | undefined | null\n): string | null {\n if (!breakpoints) return null;\n const entries = Object.entries(breakpoints);\n if (entries.length === 0) return null;\n let smallestName = entries[0][0];\n let smallestWidth = entries[0][1].breakpoint;\n for (const [name, cfg] of entries) {\n if (cfg.breakpoint < smallestWidth) {\n smallestWidth = cfg.breakpoint;\n smallestName = name;\n }\n }\n return smallestName;\n}\n\n/**\n * Build a `clamp(MIN, intercept + slope*100vw, MAX)` expression that interpolates\n * linearly between (vpMin, MIN) and (vpMax, MAX).\n *\n * - `baseValue` is the desktop/MAX value in CSS units.\n * - `unit` is the CSS unit (\"px\", \"rem\", etc.) used for both bounds.\n * - `scale` is the multiplier applied at the small end (mobile). Reuses\n * `calculateResponsiveValue` so the same multipliers used in 'breakpoints'\n * mode produce the same MIN endpoint in 'fluid' mode.\n * - `vpMin` / `vpMax` are viewport widths in pixels.\n *\n * If MIN === MAX (e.g. value at or below baseReference, or scale === 1),\n * returns a plain `${baseValue}${unit}` \u2014 no clamp emitted.\n */\nexport function buildFluidClamp(\n baseValue: number,\n unit: string,\n scale: number,\n vpMin: number,\n vpMax: number,\n baseReference = 16\n): string {\n const max = baseValue;\n const min = calculateResponsiveValue(baseValue, baseReference, scale);\n\n if (min === max || vpMax === vpMin) {\n return `${formatNumber(max)}${unit}`;\n }\n\n // Convert viewport bounds into the same unit as the value, so the\n // intercept term stays in `unit`. For px / rem we keep px throughout vw maths\n // but emit the intercept in the value's unit by converting (1rem = 16px).\n const unitToPx = unit === 'rem' ? 16 : 1;\n const minPx = min * unitToPx;\n const maxPx = max * unitToPx;\n const slopePx = (maxPx - minPx) / (vpMax - vpMin); // px per px-of-viewport\n const interceptPx = minPx - slopePx * vpMin; // px\n const interceptInUnit = interceptPx / unitToPx;\n const slopeVw = slopePx * 100; // because 1vw = viewport_width / 100 px\n\n return `clamp(${formatNumber(min)}${unit}, ${formatNumber(interceptInUnit)}${unit} + ${formatNumber(slopeVw)}vw, ${formatNumber(max)}${unit})`;\n}\n\n/**\n * Build a `clamp(MIN, intercept + slope*100vw, MAX)` expression where MIN is\n * supplied directly (e.g. from an authored mobile override) rather than\n * derived from `responsiveScales` \u00D7 `baseReference`.\n *\n * Used when a node has both `style.base.<prop>` and `style.mobile.<prop>` in\n * fluid mode \u2014 the mobile value is consumed as the clamp's small end so the\n * smooth interpolation lands exactly on the authored mobile value at the\n * narrow viewport, avoiding the jump that a separate @media override would\n * create.\n *\n * Same units / vw math as `buildFluidClamp`. Returns plain `${max}${unit}`\n * when MIN === MAX or the viewport range degenerates.\n */\nexport function buildFluidClampWithExplicitMin(\n minValue: number,\n maxValue: number,\n unit: string,\n vpMin: number,\n vpMax: number\n): string {\n if (minValue === maxValue || vpMax === vpMin) {\n return `${formatNumber(maxValue)}${unit}`;\n }\n\n const unitToPx = unit === 'rem' ? 16 : 1;\n const minPx = minValue * unitToPx;\n const maxPx = maxValue * unitToPx;\n const slopePx = (maxPx - minPx) / (vpMax - vpMin);\n const interceptPx = minPx - slopePx * vpMin;\n const interceptInUnit = interceptPx / unitToPx;\n const slopeVw = slopePx * 100;\n\n return `clamp(${formatNumber(minValue)}${unit}, ${formatNumber(interceptInUnit)}${unit} + ${formatNumber(slopeVw)}vw, ${formatNumber(maxValue)}${unit})`;\n}\n\n/**\n * Trim noisy floating-point output (e.g. 21.81818181818182 \u2192 21.8182).\n */\nfunction formatNumber(n: number): string {\n if (Number.isInteger(n)) return String(n);\n return Number(n.toFixed(4)).toString();\n}\n\n/**\n * Build the CSS value for the `--site-margin` variable in fluid mode.\n * Always emits a clamp() going from `siteMargin.min` to `siteMargin.max` (px),\n * interpolated linearly across `fluidRange.min`..`fluidRange.max`.\n *\n * If `min === max` the function returns the plain value (no clamp).\n */\nexport function buildSiteMarginClamp(\n siteMargin: SiteMarginConfig,\n fluidRange: FluidRange\n): string {\n const { min, max } = siteMargin;\n const { min: vpMin, max: vpMax } = fluidRange;\n\n if (min === max || vpMax === vpMin) {\n return `${formatNumber(max)}px`;\n }\n\n const slopePx = (max - min) / (vpMax - vpMin);\n const interceptPx = min - slopePx * vpMin;\n const slopeVw = slopePx * 100;\n\n return `clamp(${formatNumber(min)}px, ${formatNumber(interceptPx)}px + ${formatNumber(slopeVw)}vw, ${formatNumber(max)}px)`;\n}\n\n/**\n * Build a fluid clamp() value for a CSS string value (e.g. \"32px\", \"2rem\").\n * Multi-value strings (\"20px 40px\") are scaled per-token, like\n * `scalePropertyValue` does for breakpoint mode. Tokens without a unit\n * (`0`, `auto`, `inherit`) are kept verbatim.\n *\n * Returns null if no token is scalable.\n */\nexport function buildFluidPropertyValue(\n valueStr: string,\n scale: number,\n vpMin: number,\n vpMax: number,\n baseReference = 16\n): string | null {\n const parts = parseMultiValue(valueStr);\n if (parts.length === 0) return null;\n\n let anyScaled = false;\n const out = parts.map(part => {\n const parsed = parseValue(part);\n if (!parsed) return part;\n if (parsed.unit === '%' || parsed.unit === 'em') return part;\n anyScaled = true;\n return buildFluidClamp(parsed.value, parsed.unit, scale, vpMin, vpMax, baseReference);\n });\n\n return anyScaled ? out.join(' ') : null;\n}\n\n/**\n * Default responsive scales configuration\n */\nexport const DEFAULT_RESPONSIVE_SCALES: ResponsiveScales = {\n enabled: false,\n mode: 'breakpoints',\n baseReference: 16,\n fluidRange: { ...DEFAULT_FLUID_RANGE },\n siteMargin: { ...DEFAULT_SITE_MARGIN },\n fontSize: {\n tablet: 0.88,\n mobile: 0.75,\n },\n padding: {\n tablet: 0.75,\n mobile: 0.5,\n },\n margin: {\n tablet: 0.7,\n mobile: 0.45,\n },\n gap: {\n tablet: 0.65,\n mobile: 0.4,\n },\n borderRadius: {\n tablet: 0.85,\n mobile: 0.7,\n },\n size: {\n tablet: 0.9,\n mobile: 0.75,\n },\n};\n", "export interface RemConversionConfig {\n enabled: boolean;\n baseFontSize: number;\n}\n\nexport const DEFAULT_REM_CONFIG: RemConversionConfig = {\n enabled: false,\n baseFontSize: 16,\n};\n\nconst PX_REGEX = /(-?\\d*\\.?\\d+)px/g;\n\n/**\n * Convert all px values in a CSS value string to rem.\n * Handles multi-value shorthands like \"16px 32px\" -> \"1rem 2rem\".\n * 0px becomes \"0\" (unitless).\n */\nexport function convertPxToRem(cssValue: string, baseFontSize: number): string {\n return cssValue.replace(PX_REGEX, (_, num) => {\n const px = parseFloat(num);\n if (px === 0) return '0';\n const rem = px / baseFontSize;\n // Round to 4 decimal places, strip trailing zeros\n const rounded = parseFloat(rem.toFixed(4));\n return `${rounded}rem`;\n });\n}\n\n/**\n * CSS properties that should keep px values (thin borders, shadows).\n */\nconst PX_KEEP_PROPERTIES = new Set([\n 'border-width',\n 'border-top-width',\n 'border-right-width',\n 'border-bottom-width',\n 'border-left-width',\n 'outline-width',\n 'outline-offset',\n 'border',\n 'box-shadow',\n 'text-shadow',\n]);\n\nexport function shouldConvertProperty(cssProperty: string): boolean {\n return !PX_KEEP_PROPERTIES.has(cssProperty);\n}\n\n/**\n * Apply rem conversion to a CSS declarations string (e.g. \"padding: 16px; font-size: 18px\").\n * Checks each property against the exclusion list before converting.\n */\nexport function applyRemConversion(\n declarations: string,\n remConfig?: RemConversionConfig\n): string {\n if (!remConfig?.enabled) return declarations;\n\n return declarations\n .split(';')\n .map(decl => {\n const trimmed = decl.trim();\n if (!trimmed) return '';\n const colonIndex = trimmed.indexOf(':');\n if (colonIndex === -1) return trimmed;\n\n const property = trimmed.substring(0, colonIndex).trim();\n const value = trimmed.substring(colonIndex + 1).trim();\n\n if (shouldConvertProperty(property)) {\n return `${property}: ${convertPxToRem(value, remConfig.baseFontSize)}`;\n }\n return trimmed;\n })\n .filter(Boolean)\n .join('; ');\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }