meno-core 1.0.44 → 1.0.46

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 (79) hide show
  1. package/build-astro.ts +214 -63
  2. package/dist/bin/cli.js +2 -2
  3. package/dist/build-static.js +9 -9
  4. package/dist/chunks/{chunk-BXB6AX76.js → chunk-2QK6U5UK.js} +7 -3
  5. package/dist/chunks/chunk-2QK6U5UK.js.map +7 -0
  6. package/dist/chunks/{chunk-3XXLBUYA.js → chunk-77ZB6353.js} +33 -21
  7. package/dist/chunks/chunk-77ZB6353.js.map +7 -0
  8. package/dist/chunks/{chunk-5TJA272J.js → chunk-C6U5T5S5.js} +9 -9
  9. package/dist/chunks/{chunk-KPNSCQNA.js → chunk-FED5MME6.js} +285 -19
  10. package/dist/chunks/chunk-FED5MME6.js.map +7 -0
  11. package/dist/chunks/{chunk-5Z5VQRTJ.js → chunk-I7YIGZXT.js} +4 -4
  12. package/dist/chunks/{chunk-5Z5VQRTJ.js.map → chunk-I7YIGZXT.js.map} +2 -2
  13. package/dist/chunks/{chunk-46AVQA4V.js → chunk-IF3RATBY.js} +2 -2
  14. package/dist/chunks/{chunk-S2HXJTAF.js → chunk-KITQJYZV.js} +5 -1
  15. package/dist/chunks/chunk-KITQJYZV.js.map +7 -0
  16. package/dist/chunks/{chunk-G3WIPJN3.js → chunk-ORN7S4AP.js} +6 -6
  17. package/dist/chunks/{chunk-2NBGG2LJ.js → chunk-UUA5LEWF.js} +89 -4
  18. package/dist/chunks/{chunk-2NBGG2LJ.js.map → chunk-UUA5LEWF.js.map} +2 -2
  19. package/dist/chunks/{chunk-X5SH4HXS.js → chunk-XSWR3QLI.js} +33 -1
  20. package/dist/chunks/chunk-XSWR3QLI.js.map +7 -0
  21. package/dist/chunks/{chunk-YEJVSNVF.js → chunk-ZTKHJQ2Z.js} +14 -3
  22. package/dist/chunks/chunk-ZTKHJQ2Z.js.map +7 -0
  23. package/dist/chunks/{chunk-OLNQMCSR.js → chunk-ZWYDT3QJ.js} +3 -3
  24. package/dist/chunks/{configService-KYO3TXDS.js → configService-DYCUEURL.js} +4 -4
  25. package/dist/chunks/{constants-34NUGHQR.js → constants-GWBAD66U.js} +2 -2
  26. package/dist/entries/server-router.js +10 -10
  27. package/dist/lib/client/index.js +5 -5
  28. package/dist/lib/server/index.js +589 -145
  29. package/dist/lib/server/index.js.map +3 -3
  30. package/dist/lib/shared/index.js +14 -6
  31. package/dist/lib/shared/index.js.map +2 -2
  32. package/dist/lib/test-utils/index.js +1 -1
  33. package/lib/client/templateEngine.test.ts +64 -0
  34. package/lib/server/astro/astroEmitHelpers.ts +18 -0
  35. package/lib/server/astro/cmsPageEmitter.ts +31 -1
  36. package/lib/server/astro/componentEmitter.test.ts +59 -0
  37. package/lib/server/astro/componentEmitter.ts +43 -10
  38. package/lib/server/astro/cssCollector.ts +58 -11
  39. package/lib/server/astro/nodeToAstro.test.ts +397 -5
  40. package/lib/server/astro/nodeToAstro.ts +478 -63
  41. package/lib/server/astro/pageEmitter.ts +31 -1
  42. package/lib/server/astro/tailwindMapper.test.ts +119 -0
  43. package/lib/server/astro/tailwindMapper.ts +67 -1
  44. package/lib/server/runtime/httpServer.ts +12 -4
  45. package/lib/server/services/configService.ts +13 -0
  46. package/lib/server/ssr/htmlGenerator.ts +5 -2
  47. package/lib/server/ssr/jsCollector.ts +2 -2
  48. package/lib/server/ssr/ssrRenderer.test.ts +32 -0
  49. package/lib/server/ssr/ssrRenderer.ts +26 -11
  50. package/lib/shared/constants.ts +9 -2
  51. package/lib/shared/cssGeneration.test.ts +109 -3
  52. package/lib/shared/cssGeneration.ts +109 -13
  53. package/lib/shared/cssNamedColors.ts +47 -0
  54. package/lib/shared/cssProperties.ts +99 -4
  55. package/lib/shared/index.ts +1 -0
  56. package/lib/shared/nodeUtils.ts +28 -0
  57. package/lib/shared/responsiveScaling.test.ts +20 -3
  58. package/lib/shared/responsiveScaling.ts +55 -1
  59. package/lib/shared/responsiveStyleUtils.test.ts +7 -8
  60. package/lib/shared/responsiveStyleUtils.ts +6 -7
  61. package/lib/shared/types/components.ts +1 -1
  62. package/lib/shared/types/variables.test.ts +9 -2
  63. package/lib/shared/types/variables.ts +5 -1
  64. package/lib/shared/utilityClassMapper.ts +14 -1
  65. package/lib/shared/validation/propValidator.ts +6 -0
  66. package/lib/shared/validation/schemas.ts +2 -2
  67. package/package.json +1 -1
  68. package/dist/chunks/chunk-3XXLBUYA.js.map +0 -7
  69. package/dist/chunks/chunk-BXB6AX76.js.map +0 -7
  70. package/dist/chunks/chunk-KPNSCQNA.js.map +0 -7
  71. package/dist/chunks/chunk-S2HXJTAF.js.map +0 -7
  72. package/dist/chunks/chunk-X5SH4HXS.js.map +0 -7
  73. package/dist/chunks/chunk-YEJVSNVF.js.map +0 -7
  74. /package/dist/chunks/{chunk-5TJA272J.js.map → chunk-C6U5T5S5.js.map} +0 -0
  75. /package/dist/chunks/{chunk-46AVQA4V.js.map → chunk-IF3RATBY.js.map} +0 -0
  76. /package/dist/chunks/{chunk-G3WIPJN3.js.map → chunk-ORN7S4AP.js.map} +0 -0
  77. /package/dist/chunks/{chunk-OLNQMCSR.js.map → chunk-ZWYDT3QJ.js.map} +0 -0
  78. /package/dist/chunks/{configService-KYO3TXDS.js.map → configService-DYCUEURL.js.map} +0 -0
  79. /package/dist/chunks/{constants-34NUGHQR.js.map → constants-GWBAD66U.js.map} +0 -0
@@ -72,21 +72,20 @@ describe('responsiveStyleUtils', () => {
72
72
 
73
73
  test('should merge base + tablet for tablet viewport', () => {
74
74
  const merged = mergeResponsiveStyles(responsiveStyle, 'viewport', 800, breakpoints);
75
- // viewport 800 falls into tablet range (<=1024), applies all breakpoints with value <= 1024
76
- // This means base + mobile (540) + tablet (1024) are all applied
75
+ // viewport 800 falls into tablet range (<=1024), but NOT mobile range (<=540)
76
+ // Only base + tablet are applied; mobile styles don't bleed into tablet
77
77
  expect(merged.color).toBe('red');
78
- expect(merged.fontSize).toBe('16px'); // tablet overrides mobile
79
- expect(merged.padding).toBe('10px'); // mobile overrides base, then tablet doesn't override
78
+ expect(merged.fontSize).toBe('16px'); // tablet overrides base
79
+ expect(merged.padding).toBe('20px'); // inherits from base, mobile does NOT apply
80
80
  expect(merged.margin).toBe('10px'); // from tablet
81
81
  });
82
82
 
83
83
  test('should merge all for mobile viewport', () => {
84
84
  const merged = mergeResponsiveStyles(responsiveStyle, 'viewport', 480, breakpoints);
85
85
  expect(merged.color).toBe('red');
86
- expect(merged.fontSize).toBe('14px'); // mobile overrides
87
- expect(merged.padding).toBe('10px'); // mobile overrides
88
- // margin from tablet is NOT applied because tablet breakpoint (1024) > mobile breakpoint (540)
89
- expect(merged.margin).toBeUndefined();
86
+ expect(merged.fontSize).toBe('14px'); // mobile overrides tablet and base
87
+ expect(merged.padding).toBe('10px'); // mobile overrides base
88
+ expect(merged.margin).toBe('10px'); // tablet margin cascades down to mobile
90
89
  });
91
90
 
92
91
  test('should handle exact breakpoint values', () => {
@@ -57,16 +57,15 @@ export function mergeResponsiveStyles(
57
57
  return merged;
58
58
  }
59
59
 
60
- // Get all breakpoint names and sort by breakpoint value (ascending) to find which ones to apply
60
+ // Get all breakpoint names and sort by breakpoint value (descending)
61
+ // so larger breakpoints apply first, then smaller ones override — matching CSS cascade
61
62
  const breakpointEntries = Object.entries(breakpointValues);
62
- breakpointEntries.sort((a, b) => a[1] - b[1]); // Sort ascending by value
63
-
64
- const activeBreakpointValue = breakpointValues[activeBreakpoint];
63
+ breakpointEntries.sort((a, b) => b[1] - a[1]); // Sort descending by value
65
64
 
66
- // Apply styles for breakpoints that are <= active breakpoint value
67
- // This means: base (already applied) + all breakpoints up to and including the active one
65
+ // Apply styles for breakpoints whose range includes this viewport width
66
+ // A breakpoint with max-width N only applies when viewportWidth <= N
68
67
  for (const [name, value] of breakpointEntries) {
69
- if (value <= activeBreakpointValue && responsiveStyle[name]) {
68
+ if (viewportWidth <= value && responsiveStyle[name]) {
70
69
  Object.assign(merged, responsiveStyle[name]);
71
70
  }
72
71
  }
@@ -9,7 +9,7 @@ import type { LibrariesConfig } from './libraries';
9
9
  /**
10
10
  * Prop type definitions
11
11
  */
12
- export type PropType = 'string' | 'select' | 'boolean' | 'number' | 'link' | 'file' | 'rich-text' | 'list';
12
+ export type PropType = 'string' | 'select' | 'boolean' | 'number' | 'link' | 'file' | 'rich-text' | 'embed' | 'list';
13
13
 
14
14
  /**
15
15
  * Project-level enum configuration
@@ -10,7 +10,7 @@ import type { CSSVariable } from './variables';
10
10
  describe('VARIABLE_TYPES', () => {
11
11
  it('has all expected scaling types', () => {
12
12
  const values = VARIABLE_TYPES.map(t => t.value);
13
- expect(values).toEqual(['fontSize', 'padding', 'margin', 'gap', 'none']);
13
+ expect(values).toEqual(['fontSize', 'padding', 'margin', 'gap', 'borderRadius', 'size', 'none']);
14
14
  });
15
15
  });
16
16
 
@@ -54,9 +54,16 @@ describe('getDefaultScalingType', () => {
54
54
  expect(getDefaultScalingType('gap')).toBe('gap');
55
55
  });
56
56
 
57
+ it('returns borderRadius for border-radius group', () => {
58
+ expect(getDefaultScalingType('border-radius')).toBe('borderRadius');
59
+ });
60
+
61
+ it('returns size for size group', () => {
62
+ expect(getDefaultScalingType('size')).toBe('size');
63
+ });
64
+
57
65
  it('returns none for other groups', () => {
58
66
  expect(getDefaultScalingType('letter-spacing')).toBe('none');
59
- expect(getDefaultScalingType('border-radius')).toBe('none');
60
67
  expect(getDefaultScalingType('other')).toBe('none');
61
68
  });
62
69
  });
@@ -8,7 +8,7 @@
8
8
  * Maps to responsiveScales categories for automatic responsive scaling
9
9
  * 'none' means no responsive scaling is applied
10
10
  */
11
- export type VariableType = 'fontSize' | 'padding' | 'margin' | 'gap' | 'none';
11
+ export type VariableType = 'fontSize' | 'padding' | 'margin' | 'gap' | 'borderRadius' | 'size' | 'none';
12
12
 
13
13
  /**
14
14
  * UI filtering group for a CSS variable.
@@ -137,6 +137,8 @@ export const VARIABLE_TYPES: { value: VariableType; label: string }[] = [
137
137
  { value: 'padding', label: 'Padding' },
138
138
  { value: 'margin', label: 'Margin' },
139
139
  { value: 'gap', label: 'Gap' },
140
+ { value: 'borderRadius', label: 'Border Radius' },
141
+ { value: 'size', label: 'Width / Height' },
140
142
  { value: 'none', label: 'None' },
141
143
  ];
142
144
 
@@ -156,6 +158,8 @@ export function getDefaultScalingType(group: string, cssProperty?: string): Vari
156
158
  if (group === 'margin') return 'margin';
157
159
  if (group === 'padding') return 'padding';
158
160
  if (group === 'gap') return 'gap';
161
+ if (group === 'border-radius') return 'borderRadius';
162
+ if (group === 'size') return 'size';
159
163
  return 'none';
160
164
  }
161
165
 
@@ -89,7 +89,20 @@ function propertyValueToClass(prop: string, value: string | number): string | nu
89
89
  return className;
90
90
  }
91
91
 
92
- const stringValue = String(value);
92
+ let stringValue = String(value);
93
+
94
+ // Strip outer quotes from fontFamily values (e.g. "Space Grotesk" → Space Grotesk)
95
+ if (prop === 'fontFamily') {
96
+ stringValue = stringValue.split(',').map(font => {
97
+ const trimmed = font.trim();
98
+ if ((trimmed.startsWith('"') && trimmed.endsWith('"')) ||
99
+ (trimmed.startsWith("'") && trimmed.endsWith("'"))) {
100
+ return trimmed.slice(1, -1);
101
+ }
102
+ return trimmed;
103
+ }).join(', ');
104
+ }
105
+
93
106
  let className: string | null = null;
94
107
 
95
108
  // Check for special value mappings first
@@ -168,6 +168,12 @@ function validateSingleProp(
168
168
  typeValid = typeof value === 'string';
169
169
  break;
170
170
 
171
+ case 'embed':
172
+ // Embed type stores raw HTML string
173
+ coercedValue = value;
174
+ typeValid = typeof value === 'string';
175
+ break;
176
+
171
177
  case 'list':
172
178
  // List type accepts arrays and i18n values (i18n values will be resolved later)
173
179
  coercedValue = value;
@@ -15,12 +15,12 @@ import { NODE_TYPE } from '../constants';
15
15
  /**
16
16
  * Prop type schema - validates PropType values (excluding list for base definition)
17
17
  */
18
- export const BasePropTypeSchema = z.enum(['string', 'select', 'boolean', 'number', 'link', 'file', 'rich-text']);
18
+ export const BasePropTypeSchema = z.enum(['string', 'select', 'boolean', 'number', 'link', 'file', 'rich-text', 'embed']);
19
19
 
20
20
  /**
21
21
  * Full prop type schema including list
22
22
  */
23
- export const PropTypeSchema = z.enum(['string', 'select', 'boolean', 'number', 'link', 'file', 'rich-text', 'list']);
23
+ export const PropTypeSchema = z.enum(['string', 'select', 'boolean', 'number', 'link', 'file', 'rich-text', 'embed', 'list']);
24
24
 
25
25
  /**
26
26
  * Base prop definition schema (for non-list props)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "meno-core",
3
- "version": "1.0.44",
3
+ "version": "1.0.46",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "meno": "./dist/bin/cli.js"