meno-core 1.0.38 → 1.0.39

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.
@@ -0,0 +1,547 @@
1
+ /**
2
+ * Tailwind CSS Class Mapper for Astro Export
3
+ * Converts CSS property:value pairs to Tailwind utility classes.
4
+ * Uses exact-match table for common values, arbitrary value fallback for the rest.
5
+ */
6
+
7
+ import type {
8
+ StyleObject,
9
+ ResponsiveStyleObject,
10
+ StyleMapping,
11
+ } from '../../shared/types/styles';
12
+ import type { BreakpointConfig } from '../../shared/breakpoints';
13
+
14
+ // ---------------------------------------------------------------------------
15
+ // Helpers
16
+ // ---------------------------------------------------------------------------
17
+
18
+ function isStyleMapping(value: unknown): value is StyleMapping {
19
+ return (
20
+ typeof value === 'object' &&
21
+ value !== null &&
22
+ '_mapping' in value &&
23
+ (value as StyleMapping)._mapping === true
24
+ );
25
+ }
26
+
27
+ function hasTemplateExpression(value: string): boolean {
28
+ return /\{\{.+?\}\}/.test(value);
29
+ }
30
+
31
+ function isResponsiveStyle(
32
+ style: StyleObject | ResponsiveStyleObject
33
+ ): style is ResponsiveStyleObject {
34
+ return 'base' in style || 'tablet' in style || 'mobile' in style;
35
+ }
36
+
37
+ // ---------------------------------------------------------------------------
38
+ // Exact match table: property+value → Tailwind class
39
+ // ---------------------------------------------------------------------------
40
+
41
+ const exactMatches: Record<string, Record<string, string>> = {
42
+ display: {
43
+ flex: 'flex',
44
+ grid: 'grid',
45
+ block: 'block',
46
+ none: 'hidden',
47
+ inline: 'inline',
48
+ 'inline-block': 'inline-block',
49
+ 'inline-flex': 'inline-flex',
50
+ 'inline-grid': 'inline-grid',
51
+ },
52
+ flexDirection: {
53
+ column: 'flex-col',
54
+ row: 'flex-row',
55
+ 'column-reverse': 'flex-col-reverse',
56
+ 'row-reverse': 'flex-row-reverse',
57
+ },
58
+ justifyContent: {
59
+ center: 'justify-center',
60
+ 'flex-start': 'justify-start',
61
+ 'flex-end': 'justify-end',
62
+ 'space-between': 'justify-between',
63
+ 'space-around': 'justify-around',
64
+ 'space-evenly': 'justify-evenly',
65
+ // camelCase aliases (component data uses camelCase)
66
+ spaceBetween: 'justify-between',
67
+ spaceAround: 'justify-around',
68
+ spaceEvenly: 'justify-evenly',
69
+ flexStart: 'justify-start',
70
+ flexEnd: 'justify-end',
71
+ },
72
+ alignItems: {
73
+ center: 'items-center',
74
+ 'flex-start': 'items-start',
75
+ 'flex-end': 'items-end',
76
+ stretch: 'items-stretch',
77
+ baseline: 'items-baseline',
78
+ // camelCase aliases
79
+ flexStart: 'items-start',
80
+ flexEnd: 'items-end',
81
+ },
82
+ alignContent: {
83
+ center: 'content-center',
84
+ 'flex-start': 'content-start',
85
+ 'flex-end': 'content-end',
86
+ 'space-between': 'content-between',
87
+ 'space-around': 'content-around',
88
+ stretch: 'content-stretch',
89
+ },
90
+ alignSelf: {
91
+ auto: 'self-auto',
92
+ center: 'self-center',
93
+ 'flex-start': 'self-start',
94
+ 'flex-end': 'self-end',
95
+ stretch: 'self-stretch',
96
+ },
97
+ position: {
98
+ relative: 'relative',
99
+ absolute: 'absolute',
100
+ fixed: 'fixed',
101
+ sticky: 'sticky',
102
+ static: 'static',
103
+ },
104
+ overflow: {
105
+ hidden: 'overflow-hidden',
106
+ auto: 'overflow-auto',
107
+ scroll: 'overflow-scroll',
108
+ visible: 'overflow-visible',
109
+ },
110
+ overflowX: {
111
+ hidden: 'overflow-x-hidden',
112
+ auto: 'overflow-x-auto',
113
+ scroll: 'overflow-x-scroll',
114
+ visible: 'overflow-x-visible',
115
+ },
116
+ overflowY: {
117
+ hidden: 'overflow-y-hidden',
118
+ auto: 'overflow-y-auto',
119
+ scroll: 'overflow-y-scroll',
120
+ visible: 'overflow-y-visible',
121
+ },
122
+ cursor: {
123
+ pointer: 'cursor-pointer',
124
+ default: 'cursor-default',
125
+ 'not-allowed': 'cursor-not-allowed',
126
+ grab: 'cursor-grab',
127
+ grabbing: 'cursor-grabbing',
128
+ text: 'cursor-text',
129
+ move: 'cursor-move',
130
+ wait: 'cursor-wait',
131
+ },
132
+ textAlign: {
133
+ center: 'text-center',
134
+ left: 'text-left',
135
+ right: 'text-right',
136
+ justify: 'text-justify',
137
+ },
138
+ textDecoration: {
139
+ none: 'no-underline',
140
+ underline: 'underline',
141
+ 'line-through': 'line-through',
142
+ overline: 'overline',
143
+ },
144
+ textTransform: {
145
+ uppercase: 'uppercase',
146
+ lowercase: 'lowercase',
147
+ capitalize: 'capitalize',
148
+ none: 'normal-case',
149
+ },
150
+ objectFit: {
151
+ cover: 'object-cover',
152
+ contain: 'object-contain',
153
+ fill: 'object-fill',
154
+ none: 'object-none',
155
+ 'scale-down': 'object-scale-down',
156
+ },
157
+ objectPosition: {
158
+ center: 'object-center',
159
+ top: 'object-top',
160
+ bottom: 'object-bottom',
161
+ left: 'object-left',
162
+ right: 'object-right',
163
+ },
164
+ flexWrap: {
165
+ wrap: 'flex-wrap',
166
+ nowrap: 'flex-nowrap',
167
+ 'wrap-reverse': 'flex-wrap-reverse',
168
+ },
169
+ pointerEvents: {
170
+ none: 'pointer-events-none',
171
+ auto: 'pointer-events-auto',
172
+ },
173
+ userSelect: {
174
+ none: 'select-none',
175
+ auto: 'select-auto',
176
+ text: 'select-text',
177
+ all: 'select-all',
178
+ },
179
+ visibility: {
180
+ hidden: 'invisible',
181
+ visible: 'visible',
182
+ },
183
+ whiteSpace: {
184
+ normal: 'whitespace-normal',
185
+ nowrap: 'whitespace-nowrap',
186
+ pre: 'whitespace-pre',
187
+ 'pre-wrap': 'whitespace-pre-wrap',
188
+ 'pre-line': 'whitespace-pre-line',
189
+ },
190
+ wordBreak: {
191
+ 'break-all': 'break-all',
192
+ 'break-word': 'break-words',
193
+ normal: 'break-normal',
194
+ },
195
+ listStyleType: {
196
+ none: 'list-none',
197
+ disc: 'list-disc',
198
+ decimal: 'list-decimal',
199
+ },
200
+ listStylePosition: {
201
+ inside: 'list-inside',
202
+ outside: 'list-outside',
203
+ },
204
+ boxSizing: {
205
+ 'border-box': 'box-border',
206
+ 'content-box': 'box-content',
207
+ },
208
+ gridAutoFlow: {
209
+ row: 'grid-flow-row',
210
+ column: 'grid-flow-col',
211
+ dense: 'grid-flow-dense',
212
+ 'row dense': 'grid-flow-row-dense',
213
+ 'column dense': 'grid-flow-col-dense',
214
+ },
215
+ };
216
+
217
+ // Single-value exact matches (property → class when value matches)
218
+ const singleValueMatches: Record<string, string> = {
219
+ // width/height 100%
220
+ 'width:100%': 'w-full',
221
+ 'height:100%': 'h-full',
222
+ 'width:100vw': 'w-screen',
223
+ 'height:100vh': 'h-screen',
224
+ 'width:auto': 'w-auto',
225
+ 'height:auto': 'h-auto',
226
+ 'width:fit-content': 'w-fit',
227
+ 'height:fit-content': 'h-fit',
228
+ 'width:min-content': 'w-min',
229
+ 'height:min-content': 'h-min',
230
+ 'width:max-content': 'w-max',
231
+ 'height:max-content': 'h-max',
232
+ 'maxWidth:100%': 'max-w-full',
233
+ 'maxWidth:none': 'max-w-none',
234
+ 'maxHeight:100%': 'max-h-full',
235
+ 'maxHeight:none': 'max-h-none',
236
+ 'minWidth:0': 'min-w-0',
237
+ 'minHeight:0': 'min-h-0',
238
+ 'margin:auto': 'm-auto',
239
+ 'margin:0 auto': 'mx-auto',
240
+ 'marginLeft:auto': 'ml-auto',
241
+ 'marginRight:auto': 'mr-auto',
242
+ 'marginInline:auto': 'mx-auto',
243
+ 'borderRadius:50%': 'rounded-full',
244
+ 'borderRadius:9999px': 'rounded-full',
245
+ 'borderRadius:0': 'rounded-none',
246
+ 'flex:1': 'flex-1',
247
+ 'flex:none': 'flex-none',
248
+ 'flex:auto': 'flex-auto',
249
+ 'flexGrow:0': 'grow-0',
250
+ 'flexGrow:1': 'grow',
251
+ 'flexShrink:0': 'shrink-0',
252
+ 'flexShrink:1': 'shrink',
253
+ 'opacity:0': 'opacity-0',
254
+ 'opacity:1': 'opacity-100',
255
+ 'zIndex:0': 'z-0',
256
+ 'zIndex:10': 'z-10',
257
+ 'zIndex:20': 'z-20',
258
+ 'zIndex:30': 'z-30',
259
+ 'zIndex:40': 'z-40',
260
+ 'zIndex:50': 'z-50',
261
+ 'inset:0': 'inset-0',
262
+ 'top:0': 'top-0',
263
+ 'right:0': 'right-0',
264
+ 'bottom:0': 'bottom-0',
265
+ 'left:0': 'left-0',
266
+ };
267
+
268
+ // ---------------------------------------------------------------------------
269
+ // Arbitrary value prefix map: CSS property → Tailwind prefix
270
+ // ---------------------------------------------------------------------------
271
+
272
+ const arbitraryPrefixMap: Record<string, string> = {
273
+ // Spacing
274
+ padding: 'p',
275
+ paddingTop: 'pt',
276
+ paddingRight: 'pr',
277
+ paddingBottom: 'pb',
278
+ paddingLeft: 'pl',
279
+ paddingInline: 'px',
280
+ paddingBlock: 'py',
281
+ margin: 'm',
282
+ marginTop: 'mt',
283
+ marginRight: 'mr',
284
+ marginBottom: 'mb',
285
+ marginLeft: 'ml',
286
+ marginInline: 'mx',
287
+ marginBlock: 'my',
288
+ gap: 'gap',
289
+ rowGap: 'gap-y',
290
+ columnGap: 'gap-x',
291
+
292
+ // Sizing
293
+ width: 'w',
294
+ height: 'h',
295
+ maxWidth: 'max-w',
296
+ maxHeight: 'max-h',
297
+ minWidth: 'min-w',
298
+ minHeight: 'min-h',
299
+
300
+ // Typography
301
+ fontSize: 'text',
302
+ fontWeight: 'font',
303
+ fontFamily: 'font',
304
+ lineHeight: 'leading',
305
+ letterSpacing: 'tracking',
306
+
307
+ // Borders
308
+ borderRadius: 'rounded',
309
+ borderTopLeftRadius: 'rounded-tl',
310
+ borderTopRightRadius: 'rounded-tr',
311
+ borderBottomLeftRadius: 'rounded-bl',
312
+ borderBottomRightRadius: 'rounded-br',
313
+ border: 'border',
314
+ borderTop: 'border-t',
315
+ borderRight: 'border-r',
316
+ borderBottom: 'border-b',
317
+ borderLeft: 'border-l',
318
+ borderColor: 'border',
319
+
320
+ // Colors
321
+ color: 'text',
322
+ backgroundColor: 'bg',
323
+ background: 'bg',
324
+ backgroundImage: 'bg',
325
+
326
+ // Effects
327
+ opacity: 'opacity',
328
+ boxShadow: 'shadow',
329
+ textShadow: '[text-shadow]',
330
+ filter: '[filter]',
331
+ backdropFilter: 'backdrop',
332
+ transform: '[transform]',
333
+ transformOrigin: 'origin',
334
+ transition: 'transition',
335
+ mixBlendMode: 'mix-blend',
336
+ clipPath: '[clip-path]',
337
+
338
+ // Positioning
339
+ top: 'top',
340
+ right: 'right',
341
+ bottom: 'bottom',
342
+ left: 'left',
343
+ inset: 'inset',
344
+ zIndex: 'z',
345
+
346
+ // Grid
347
+ gridTemplateColumns: 'grid-cols',
348
+ gridTemplateRows: 'grid-rows',
349
+ gridColumn: 'col',
350
+ gridRow: 'row',
351
+ gridAutoRows: 'auto-rows',
352
+ gridAutoColumns: 'auto-cols',
353
+
354
+ // Flexbox extras
355
+ flexGrow: 'grow',
356
+ flexShrink: 'shrink',
357
+ flexBasis: 'basis',
358
+ order: 'order',
359
+ flex: 'flex',
360
+
361
+ // Aspect ratio
362
+ aspectRatio: 'aspect',
363
+
364
+ // Outline
365
+ outline: 'outline',
366
+ outlineWidth: 'outline',
367
+ outlineOffset: 'outline-offset',
368
+ outlineColor: 'outline',
369
+
370
+ // Other
371
+ accentColor: 'accent',
372
+ textIndent: '[text-indent]',
373
+ verticalAlign: 'align',
374
+ overflowWrap: '[overflow-wrap]',
375
+ scrollBehavior: 'scroll',
376
+ resize: 'resize',
377
+ };
378
+
379
+ // ---------------------------------------------------------------------------
380
+ // Core conversion functions
381
+ // ---------------------------------------------------------------------------
382
+
383
+ /**
384
+ * Convert a single CSS property:value pair to a Tailwind class.
385
+ * Returns null if the value should be skipped (mappings, templates).
386
+ */
387
+ export function propertyToTailwind(
388
+ property: string,
389
+ value: string | number
390
+ ): string | null {
391
+ const strValue = String(value);
392
+
393
+ // Skip empty values — they produce broken classes like gap-[], mt-[]
394
+ if (strValue === '') return null;
395
+
396
+ // Skip template expressions — these must be handled via inline style
397
+ if (hasTemplateExpression(strValue)) return null;
398
+
399
+ // Check single-value exact matches first
400
+ const singleKey = `${property}:${strValue}`;
401
+ if (singleValueMatches[singleKey]) {
402
+ return singleValueMatches[singleKey];
403
+ }
404
+
405
+ // Check exact match table
406
+ if (exactMatches[property]?.[strValue]) {
407
+ return exactMatches[property][strValue];
408
+ }
409
+
410
+ // Color variable handling:
411
+ // "var(--text)" → "text-[var(--text)]"
412
+ // Bare color name like "text" → "text-[var(--text)]"
413
+ if (property === 'color' || property === 'backgroundColor' || property === 'borderColor') {
414
+ const prefix = property === 'color' ? 'text' : property === 'backgroundColor' ? 'bg' : 'border';
415
+ if (strValue.includes('var(')) {
416
+ return `${prefix}-[${strValue}]`;
417
+ }
418
+ // Bare name (not a hex, rgb, or number-starting value)
419
+ if (!strValue.match(/^[#\d]/) && !strValue.includes('rgb') && !strValue.includes('hsl')) {
420
+ return `${prefix}-[var(--${strValue})]`;
421
+ }
422
+ }
423
+
424
+ // Arbitrary value fallback
425
+ const twPrefix = arbitraryPrefixMap[property];
426
+ if (!twPrefix) {
427
+ // Unknown property: use arbitrary property syntax
428
+ const cssProp = property.replace(/([A-Z])/g, '-$1').toLowerCase();
429
+ const sanitized = strValue.replace(/\s+/g, '_');
430
+ return `[${cssProp}:${sanitized}]`;
431
+ }
432
+
433
+ // For prefixes that start with '[' it's an arbitrary property
434
+ if (twPrefix.startsWith('[')) {
435
+ const sanitized = strValue.replace(/\s+/g, '_');
436
+ return `${twPrefix.slice(0, -1)}:${sanitized}]`;
437
+ }
438
+
439
+ // Standard arbitrary value: prefix-[value]
440
+ const sanitized = strValue.replace(/\s+/g, '_');
441
+
442
+ // Font family names need quotes in arbitrary syntax for Tailwind to parse correctly
443
+ if (property === 'fontFamily' && !sanitized.includes(',') && !sanitized.startsWith("'")) {
444
+ return `${twPrefix}-['${sanitized}']`;
445
+ }
446
+
447
+ return `${twPrefix}-[${sanitized}]`;
448
+ }
449
+
450
+ /**
451
+ * Convert a flat style object to an array of Tailwind classes.
452
+ * Skips StyleMapping values (handled separately via class:list).
453
+ * Returns { classes, dynamicStyles } where dynamicStyles are template-expression
454
+ * styles that need inline style attributes.
455
+ */
456
+ export function stylesToTailwind(
457
+ style: StyleObject | Record<string, string | number>
458
+ ): { classes: string[]; dynamicStyles: Record<string, string> } {
459
+ const classes: string[] = [];
460
+ const dynamicStyles: Record<string, string> = {};
461
+
462
+ for (const [prop, value] of Object.entries(style)) {
463
+ if (isStyleMapping(value)) continue;
464
+
465
+ const strValue = String(value);
466
+
467
+ // Template expressions go to dynamic/inline styles
468
+ if (hasTemplateExpression(strValue)) {
469
+ const cssProp = prop.replace(/([A-Z])/g, '-$1').toLowerCase();
470
+ dynamicStyles[cssProp] = strValue;
471
+ continue;
472
+ }
473
+
474
+ const twClass = propertyToTailwind(prop, value);
475
+ if (twClass) {
476
+ classes.push(twClass);
477
+ }
478
+ }
479
+
480
+ return { classes, dynamicStyles };
481
+ }
482
+
483
+ /**
484
+ * Convert a responsive style object to Tailwind classes with responsive prefixes.
485
+ * Uses desktop-first max-width breakpoints.
486
+ *
487
+ * - base styles → no prefix (desktop default)
488
+ * - tablet styles → max-[{breakpoint}px]: prefix
489
+ * - mobile styles → max-[{breakpoint}px]: prefix
490
+ */
491
+ export function responsiveStylesToTailwind(
492
+ style: StyleObject | ResponsiveStyleObject | null | undefined,
493
+ breakpoints: BreakpointConfig
494
+ ): { classes: string[]; dynamicStyles: Record<string, string> } {
495
+ if (!style) return { classes: [], dynamicStyles: {} };
496
+
497
+ const allClasses: string[] = [];
498
+ const allDynamicStyles: Record<string, string> = {};
499
+
500
+ if (isResponsiveStyle(style)) {
501
+ const responsive = style as ResponsiveStyleObject;
502
+
503
+ // Base styles (no prefix)
504
+ if (responsive.base) {
505
+ const { classes, dynamicStyles } = stylesToTailwind(responsive.base);
506
+ allClasses.push(...classes);
507
+ Object.assign(allDynamicStyles, dynamicStyles);
508
+ }
509
+
510
+ // Tablet styles
511
+ if (responsive.tablet) {
512
+ const bpValue = breakpoints.tablet?.breakpoint ?? 1024;
513
+ const prefix = `max-[${bpValue}px]:`;
514
+ const { classes, dynamicStyles } = stylesToTailwind(responsive.tablet);
515
+ allClasses.push(...classes.map(cls => `${prefix}${cls}`));
516
+ // Dynamic styles for tablet — just merge (can't do responsive inline styles easily)
517
+ Object.assign(allDynamicStyles, dynamicStyles);
518
+ }
519
+
520
+ // Mobile styles
521
+ if (responsive.mobile) {
522
+ const bpValue = breakpoints.mobile?.breakpoint ?? 540;
523
+ const prefix = `max-[${bpValue}px]:`;
524
+ const { classes, dynamicStyles } = stylesToTailwind(responsive.mobile);
525
+ allClasses.push(...classes.map(cls => `${prefix}${cls}`));
526
+ Object.assign(allDynamicStyles, dynamicStyles);
527
+ }
528
+
529
+ // Handle any other custom breakpoints
530
+ for (const [bpName, bpStyle] of Object.entries(responsive)) {
531
+ if (bpName === 'base' || bpName === 'tablet' || bpName === 'mobile' || !bpStyle) continue;
532
+ const bpValue = breakpoints[bpName]?.breakpoint;
533
+ if (!bpValue) continue;
534
+ const prefix = `max-[${bpValue}px]:`;
535
+ const { classes, dynamicStyles } = stylesToTailwind(bpStyle);
536
+ allClasses.push(...classes.map(cls => `${prefix}${cls}`));
537
+ Object.assign(allDynamicStyles, dynamicStyles);
538
+ }
539
+ } else {
540
+ // Flat style object — treat as base
541
+ const { classes, dynamicStyles } = stylesToTailwind(style as StyleObject);
542
+ allClasses.push(...classes);
543
+ Object.assign(allDynamicStyles, dynamicStyles);
544
+ }
545
+
546
+ return { classes: allClasses, dynamicStyles: allDynamicStyles };
547
+ }
@@ -62,6 +62,9 @@ export { migrateTemplatesDirectory } from './migrateTemplates';
62
62
  // Static build
63
63
  export { buildStaticPages } from '../../build-static';
64
64
 
65
+ // Astro export
66
+ export { buildAstroProject } from '../../build-astro';
67
+
65
68
  // Utilities
66
69
  export * from './utils';
67
70
 
@@ -401,6 +401,9 @@ img {
401
401
  width: 100%;
402
402
  height: 100%;
403
403
  }
404
+ picture {
405
+ display: block;
406
+ }
404
407
  .olink {
405
408
  text-decoration: none;
406
409
  display: block;
@@ -2327,7 +2327,7 @@ describe('ssrRenderer', () => {
2327
2327
  expect(html).toContain('sizes="(max-width: 768px) 100vw, 50vw"');
2328
2328
  });
2329
2329
 
2330
- test('picture element splits classes between picture and img tags', async () => {
2330
+ test('picture element splits classes: layout on picture, objf/objp on img', async () => {
2331
2331
  mockImageMetadataMap.set('/split.jpg', {
2332
2332
  srcset: '/split.webp 400w',
2333
2333
  avifSrcset: '/split.avif 400w',
@@ -2336,11 +2336,15 @@ describe('ssrRenderer', () => {
2336
2336
  const node = {
2337
2337
  type: 'node',
2338
2338
  tag: 'img',
2339
- attributes: { src: '/split.jpg', alt: 'Split', className: 'w-full objf-cover' },
2339
+ attributes: { src: '/split.jpg', alt: 'Split', className: 'w-full objf-cover objp-center' },
2340
2340
  };
2341
2341
  const html = await render(node);
2342
- expect(html).toContain('<picture');
2343
- // objf-* class should be on img, layout classes on picture
2342
+ // Layout classes go on <picture>
2343
+ expect(html).toContain('<picture class="w-full">');
2344
+ // Image-specific classes go on <img>
2345
+ expect(html).toContain('class="objf-cover objp-center"');
2346
+ // No display:contents
2347
+ expect(html).not.toContain('display:contents');
2344
2348
  });
2345
2349
  });
2346
2350
 
@@ -1461,7 +1461,7 @@ function renderImageElement(
1461
1461
  }
1462
1462
 
1463
1463
  // Render as <picture> element if AVIF is available
1464
- // Split classes: layout/sizing on <picture>, image-specific on <img>
1464
+ // Layout classes go on <picture> (block container), image-specific classes on <img>
1465
1465
  if (metadata?.avifSrcset) {
1466
1466
  // Image-specific class prefixes that should stay on <img>
1467
1467
  const imgClassPrefixes = [
@@ -1471,11 +1471,9 @@ function renderImageElement(
1471
1471
  // Opacity classes (o-NUMBER) go on img, but overflow (o-h, o-a, o-s, o-v) stays on picture
1472
1472
  const opacityPattern = /^o-\d/;
1473
1473
 
1474
- // Parse classes from classAttr
1475
1474
  const classMatch = classAttr.match(/class="([^"]*)"/);
1476
1475
  const allClasses = classMatch ? classMatch[1].split(/\s+/).filter(Boolean) : [];
1477
1476
 
1478
- // Split classes between picture and img
1479
1477
  const imgClasses: string[] = [];
1480
1478
  const pictureClasses: string[] = [];
1481
1479
 
@@ -88,7 +88,7 @@ describe('themeDefaults', () => {
88
88
  });
89
89
 
90
90
  test('should have code syntax colors', () => {
91
- expect(DEFAULT_PROPS_PANEL_COLORS.codeString).toBe('#ce9178');
91
+ expect(DEFAULT_PROPS_PANEL_COLORS.codeString).toBe('#ffffff');
92
92
  expect(DEFAULT_PROPS_PANEL_COLORS.codeNumber).toBe('#b5cea8');
93
93
  expect(DEFAULT_PROPS_PANEL_COLORS.codeKey).toBe('#9cdcfe');
94
94
  expect(DEFAULT_PROPS_PANEL_COLORS.codeType).toBe('#4ec9b0');
@@ -24,6 +24,7 @@ export interface PropsPanelColors {
24
24
  inputBackground: string;
25
25
  inputBorder: string;
26
26
  hoverBackground: string;
27
+ variableBackground?: string;
27
28
  }
28
29
 
29
30
  /**
@@ -87,7 +88,7 @@ export const DEFAULT_PROPS_PANEL_COLORS: PropsPanelColors = {
87
88
  text: '#cccccc',
88
89
  textSecondary: '#cccccc',
89
90
  textMuted: '#888888',
90
- codeString: '#ce9178',
91
+ codeString: '#ffffff',
91
92
  codeNumber: '#b5cea8',
92
93
  codeKey: '#9cdcfe',
93
94
  codeType: '#4ec9b0',
@@ -99,6 +100,7 @@ export const DEFAULT_PROPS_PANEL_COLORS: PropsPanelColors = {
99
100
  inputBackground: '#2a2a2a',
100
101
  inputBorder: '#444444',
101
102
  hoverBackground: '#2a2d2e',
103
+ variableBackground: '#2a2a2a',
102
104
  };
103
105
 
104
106
  /**
@@ -125,5 +127,6 @@ export const LIGHT_PROPS_PANEL_COLORS: PropsPanelColors = {
125
127
  inputBackground: '#f5f7fa',
126
128
  inputBorder: '#d0d0d0',
127
129
  hoverBackground: '#f0f0f0',
130
+ variableBackground: '#ebedf0',
128
131
  };
129
132
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "meno-core",
3
- "version": "1.0.38",
3
+ "version": "1.0.39",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "meno": "./dist/bin/cli.js"