@webmate-studio/builder 0.2.148 → 0.2.150
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.
- package/package.json +1 -1
- package/src/design-tokens-v2-css.js +72 -14
- package/src/design-tokens-v2-migrate.js +38 -0
- package/src/design-tokens-v2.js +14 -10
- package/src/index.js +2 -2
package/package.json
CHANGED
|
@@ -296,6 +296,8 @@ function generateTypographyVariables(t, lines, responsiveLines) {
|
|
|
296
296
|
const textStyles = t.typography.textStyles;
|
|
297
297
|
if (!textStyles) return;
|
|
298
298
|
|
|
299
|
+
const fluidConfig = t.typography.fluidConfig;
|
|
300
|
+
|
|
299
301
|
for (const voice of TEXT_VOICES) {
|
|
300
302
|
if (!textStyles[voice]) continue;
|
|
301
303
|
|
|
@@ -314,38 +316,94 @@ function generateTypographyVariables(t, lines, responsiveLines) {
|
|
|
314
316
|
lines.push(` ${prefix}-font: "${style.font}", ${fallback};`);
|
|
315
317
|
}
|
|
316
318
|
|
|
317
|
-
// fontWeight, letterSpacing, textTransform — nicht responsive
|
|
318
319
|
if (style.fontWeight != null) lines.push(` ${prefix}-weight: ${style.fontWeight};`);
|
|
319
320
|
if (style.textTransform) lines.push(` ${prefix}-transform: ${style.textTransform};`);
|
|
320
321
|
|
|
321
|
-
// fontSize —
|
|
322
|
-
|
|
322
|
+
// fontSize — fluid clamp() oder statisch
|
|
323
|
+
addFluidVar(prefix + '-size', style.fontSize, lines, fluidConfig);
|
|
323
324
|
|
|
324
|
-
// lineHeight —
|
|
325
|
-
|
|
325
|
+
// lineHeight — fluid clamp() oder statisch
|
|
326
|
+
addFluidVar(prefix + '-line-height', style.lineHeight, lines, fluidConfig);
|
|
326
327
|
|
|
327
|
-
// letterSpacing —
|
|
328
|
-
|
|
328
|
+
// letterSpacing — fluid clamp() oder statisch
|
|
329
|
+
addFluidVar(prefix + '-letter-spacing', style.letterSpacing, lines, fluidConfig);
|
|
329
330
|
}
|
|
330
331
|
}
|
|
331
332
|
}
|
|
332
333
|
|
|
333
|
-
|
|
334
|
+
/**
|
|
335
|
+
* Generates a CSS variable with optional clamp() for fluid values.
|
|
336
|
+
* Static string → plain value. Fluid { min, max } → clamp().
|
|
337
|
+
* Legacy { base, md, lg } → treated as { min: base, max: lg||md } for backward compat.
|
|
338
|
+
*/
|
|
339
|
+
function addFluidVar(varName, value, lines, fluidConfig) {
|
|
334
340
|
if (value == null) return;
|
|
335
341
|
|
|
336
342
|
if (typeof value === 'object') {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
+
let min, max;
|
|
344
|
+
if ('min' in value) {
|
|
345
|
+
min = value.min;
|
|
346
|
+
max = value.max || value.min;
|
|
347
|
+
} else if ('base' in value) {
|
|
348
|
+
// Legacy backward compatibility
|
|
349
|
+
min = value.base;
|
|
350
|
+
max = value.lg || value.md || value.base;
|
|
351
|
+
} else {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
if (min === max || !max) {
|
|
356
|
+
lines.push(` ${varName}: ${min};`);
|
|
357
|
+
} else {
|
|
358
|
+
const clampValue = buildClampValue(min, max, fluidConfig);
|
|
359
|
+
lines.push(` ${varName}: ${clampValue};`);
|
|
343
360
|
}
|
|
344
361
|
} else {
|
|
345
362
|
lines.push(` ${varName}: ${value};`);
|
|
346
363
|
}
|
|
347
364
|
}
|
|
348
365
|
|
|
366
|
+
/**
|
|
367
|
+
* Builds a CSS clamp() expression (Utopia formula).
|
|
368
|
+
* clamp(min, intercept + slope·vw, max)
|
|
369
|
+
* slope = (max - min) / (maxVP - minVP)
|
|
370
|
+
* intercept = min - slope * minVP
|
|
371
|
+
*/
|
|
372
|
+
function buildClampValue(min, max, fluidConfig) {
|
|
373
|
+
const minVP = parseFloat(fluidConfig?.minViewport || '20');
|
|
374
|
+
const maxVP = parseFloat(fluidConfig?.maxViewport || '90');
|
|
375
|
+
|
|
376
|
+
const minNum = parseFloat(min);
|
|
377
|
+
const maxNum = parseFloat(max);
|
|
378
|
+
const unit = min.replace(/[\d.\-]/g, '') || 'rem';
|
|
379
|
+
|
|
380
|
+
// Unitless values (like lineHeight '1.5') can't use vw-based clamp
|
|
381
|
+
if (!unit || unit === '') {
|
|
382
|
+
return min;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
if (isNaN(minNum) || isNaN(maxNum) || minVP >= maxVP) {
|
|
386
|
+
return min;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
const slope = (maxNum - minNum) / (maxVP - minVP);
|
|
390
|
+
const intercept = minNum - slope * minVP;
|
|
391
|
+
|
|
392
|
+
const slopeVw = +(slope * 100).toFixed(3);
|
|
393
|
+
const interceptUnit = +intercept.toFixed(3);
|
|
394
|
+
|
|
395
|
+
let preferred;
|
|
396
|
+
if (interceptUnit === 0) {
|
|
397
|
+
preferred = `${slopeVw}vw`;
|
|
398
|
+
} else if (interceptUnit > 0) {
|
|
399
|
+
preferred = `${interceptUnit}${unit} + ${slopeVw}vw`;
|
|
400
|
+
} else {
|
|
401
|
+
preferred = `${interceptUnit}${unit} + ${slopeVw}vw`;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
return `clamp(${min}, ${preferred}, ${max})`;
|
|
405
|
+
}
|
|
406
|
+
|
|
349
407
|
function findFont(t, fontName) {
|
|
350
408
|
if (!t.typography?.fonts) return null;
|
|
351
409
|
return t.typography.fonts.find(f => f.name === fontName);
|
|
@@ -22,6 +22,27 @@ import {
|
|
|
22
22
|
} from './design-tokens-v2.js';
|
|
23
23
|
|
|
24
24
|
|
|
25
|
+
// ─── Fluid Typography Migration ──────────────────────────────────────────────
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Migriert einen responsiven Wert von Breakpoint-Format zu Fluid-Format.
|
|
29
|
+
* { base: '2.5rem', md: '3.5rem', lg: '4.5rem' } → { min: '2.5rem', max: '4.5rem' }
|
|
30
|
+
* Bereits im Fluid-Format ({ min, max }) → unverändert.
|
|
31
|
+
* Statische Werte (Strings) → unverändert.
|
|
32
|
+
*/
|
|
33
|
+
export function migrateResponsiveToFluid(value) {
|
|
34
|
+
if (value == null || typeof value !== 'object') return value;
|
|
35
|
+
if ('min' in value) return value; // Already fluid
|
|
36
|
+
if ('base' in value) {
|
|
37
|
+
const min = value.base;
|
|
38
|
+
const max = value.lg || value.md || value.base;
|
|
39
|
+
if (min === max) return min; // Collapse to static
|
|
40
|
+
return { min, max };
|
|
41
|
+
}
|
|
42
|
+
return value;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
25
46
|
// ─── Hauptfunktionen ────────────────────────────────────────────────────────
|
|
26
47
|
|
|
27
48
|
/**
|
|
@@ -112,6 +133,23 @@ export function validateDesignTokensV2(tokens) {
|
|
|
112
133
|
}
|
|
113
134
|
}
|
|
114
135
|
|
|
136
|
+
// Migrate breakpoint-based responsive values to fluid { min, max }
|
|
137
|
+
for (const voice of TEXT_VOICES) {
|
|
138
|
+
for (const level of TEXT_LEVELS) {
|
|
139
|
+
const style = v2.typography.textStyles[voice]?.[level];
|
|
140
|
+
if (style) {
|
|
141
|
+
style.fontSize = migrateResponsiveToFluid(style.fontSize);
|
|
142
|
+
style.lineHeight = migrateResponsiveToFluid(style.lineHeight);
|
|
143
|
+
style.letterSpacing = migrateResponsiveToFluid(style.letterSpacing);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Ensure fluidConfig exists
|
|
149
|
+
if (!v2.typography.fluidConfig) {
|
|
150
|
+
v2.typography.fluidConfig = { minViewport: '20rem', maxViewport: '90rem' };
|
|
151
|
+
}
|
|
152
|
+
|
|
115
153
|
// Aliases
|
|
116
154
|
if (!v2.typography.aliases) v2.typography.aliases = { ...DEFAULT_TEXT_ALIASES };
|
|
117
155
|
|
package/src/design-tokens-v2.js
CHANGED
|
@@ -312,7 +312,7 @@ function buildDarkLightnessRamp(darkBaseL, isLowChroma) {
|
|
|
312
312
|
// Chromatische Farben: Steps stärker zur Base hin komprimiert,
|
|
313
313
|
// damit die dunklen Steps nicht zu dunkel (=farblos) werden
|
|
314
314
|
const weights = isLowChroma
|
|
315
|
-
? [0.0, 0.
|
|
315
|
+
? [0.0, 0.10, 0.18, 0.28, 0.40, 0.54, 0.72, 0.92]
|
|
316
316
|
: [0.0, 0.06, 0.14, 0.26, 0.40, 0.55, 0.72, 0.90];
|
|
317
317
|
const darkSteps = weights.map(w => bottomL + w * range);
|
|
318
318
|
|
|
@@ -748,6 +748,10 @@ export const defaultDesignTokensV2 = {
|
|
|
748
748
|
|
|
749
749
|
// ── Typografie ──
|
|
750
750
|
typography: {
|
|
751
|
+
fluidConfig: {
|
|
752
|
+
minViewport: '20rem', // 320px
|
|
753
|
+
maxViewport: '90rem' // 1440px
|
|
754
|
+
},
|
|
751
755
|
fonts: [
|
|
752
756
|
{
|
|
753
757
|
name: 'Inter',
|
|
@@ -766,15 +770,15 @@ export const defaultDesignTokensV2 = {
|
|
|
766
770
|
display: {
|
|
767
771
|
1: {
|
|
768
772
|
font: 'Inter',
|
|
769
|
-
fontSize: {
|
|
773
|
+
fontSize: { min: '2.5rem', max: '4.5rem' },
|
|
770
774
|
fontWeight: 700,
|
|
771
|
-
lineHeight:
|
|
775
|
+
lineHeight: '1.1',
|
|
772
776
|
letterSpacing: '-0.02em',
|
|
773
777
|
textTransform: 'none'
|
|
774
778
|
},
|
|
775
779
|
2: {
|
|
776
780
|
font: 'Inter',
|
|
777
|
-
fontSize: {
|
|
781
|
+
fontSize: { min: '2rem', max: '3rem' },
|
|
778
782
|
fontWeight: 700,
|
|
779
783
|
lineHeight: '1.15',
|
|
780
784
|
letterSpacing: '-0.015em',
|
|
@@ -782,7 +786,7 @@ export const defaultDesignTokensV2 = {
|
|
|
782
786
|
},
|
|
783
787
|
3: {
|
|
784
788
|
font: 'Inter',
|
|
785
|
-
fontSize: {
|
|
789
|
+
fontSize: { min: '1.5rem', max: '2rem' },
|
|
786
790
|
fontWeight: 600,
|
|
787
791
|
lineHeight: '1.2',
|
|
788
792
|
letterSpacing: '-0.01em',
|
|
@@ -790,7 +794,7 @@ export const defaultDesignTokensV2 = {
|
|
|
790
794
|
},
|
|
791
795
|
4: {
|
|
792
796
|
font: 'Inter',
|
|
793
|
-
fontSize: {
|
|
797
|
+
fontSize: { min: '1.25rem', max: '1.5rem' },
|
|
794
798
|
fontWeight: 600,
|
|
795
799
|
lineHeight: '1.3',
|
|
796
800
|
letterSpacing: '-0.005em',
|
|
@@ -798,7 +802,7 @@ export const defaultDesignTokensV2 = {
|
|
|
798
802
|
},
|
|
799
803
|
5: {
|
|
800
804
|
font: 'Inter',
|
|
801
|
-
fontSize: {
|
|
805
|
+
fontSize: { min: '1.125rem', max: '1.25rem' },
|
|
802
806
|
fontWeight: 600,
|
|
803
807
|
lineHeight: '1.3',
|
|
804
808
|
letterSpacing: '0em',
|
|
@@ -808,7 +812,7 @@ export const defaultDesignTokensV2 = {
|
|
|
808
812
|
body: {
|
|
809
813
|
1: {
|
|
810
814
|
font: 'Inter',
|
|
811
|
-
fontSize: {
|
|
815
|
+
fontSize: { min: '1.125rem', max: '1.25rem' },
|
|
812
816
|
fontWeight: 400,
|
|
813
817
|
lineHeight: '1.6',
|
|
814
818
|
letterSpacing: '0em',
|
|
@@ -892,7 +896,7 @@ export const defaultDesignTokensV2 = {
|
|
|
892
896
|
accent: {
|
|
893
897
|
1: {
|
|
894
898
|
font: 'Inter',
|
|
895
|
-
fontSize: {
|
|
899
|
+
fontSize: { min: '1.5rem', max: '2rem' },
|
|
896
900
|
fontWeight: 400,
|
|
897
901
|
lineHeight: '1.5',
|
|
898
902
|
letterSpacing: '0em',
|
|
@@ -900,7 +904,7 @@ export const defaultDesignTokensV2 = {
|
|
|
900
904
|
},
|
|
901
905
|
2: {
|
|
902
906
|
font: 'Inter',
|
|
903
|
-
fontSize: {
|
|
907
|
+
fontSize: { min: '1.25rem', max: '1.5rem' },
|
|
904
908
|
fontWeight: 400,
|
|
905
909
|
lineHeight: '1.4',
|
|
906
910
|
letterSpacing: '0em',
|
package/src/index.js
CHANGED
|
@@ -11,7 +11,7 @@ import { defaultDesignTokens, generateTailwindV4Theme, generateTailwindConfig, g
|
|
|
11
11
|
// V2 Design Tokens
|
|
12
12
|
import { defaultDesignTokensV2, generateColorScale, generateDarkColorScale, calculateOnColor, isV1Format, isV2Format, COLOR_WORLDS, SEMANTIC_COLOR_WORLDS, TEXT_VOICES, TEXT_LEVELS, BUTTON_VARIANTS, BUTTON_SIZES, DEFAULT_SEMANTIC_MAPPINGS, DEFAULT_STATUS_SEMANTIC_MAPPINGS, getDefaultMappingsForWorld, DEFAULT_TEXT_ALIASES } from './design-tokens-v2.js';
|
|
13
13
|
import { generateTailwindV4ThemeV2, generateCSSFromTokensV2, generateFontImportsV2 } from './design-tokens-v2-css.js';
|
|
14
|
-
import { migrateDesignTokensV1toV2, validateDesignTokensV2 } from './design-tokens-v2-migrate.js';
|
|
14
|
+
import { migrateDesignTokensV1toV2, validateDesignTokensV2, migrateResponsiveToFluid } from './design-tokens-v2-migrate.js';
|
|
15
15
|
|
|
16
16
|
import { readFileSync } from 'fs';
|
|
17
17
|
import { fileURLToPath } from 'url';
|
|
@@ -29,4 +29,4 @@ function getMotionRuntime() {
|
|
|
29
29
|
export { build, generateComponentCSS, generateTailwindCSS, extractTailwindClasses, cleanComponentHTML, bundleIsland, bundleComponentIslands, deduplicateCSS, markdownToHtml, processMarkdownProps, SafeHtml, getMotionRuntime, TemplateProcessor, templateProcessor, defaultDesignTokens, generateTailwindV4Theme, generateTailwindConfig, generateCSSFromTokens, generateFontImports };
|
|
30
30
|
|
|
31
31
|
// V2 exports
|
|
32
|
-
export { defaultDesignTokensV2, generateTailwindV4ThemeV2, generateCSSFromTokensV2, generateFontImportsV2, migrateDesignTokensV1toV2, validateDesignTokensV2, generateColorScale, generateDarkColorScale, calculateOnColor, isV1Format, isV2Format, COLOR_WORLDS, SEMANTIC_COLOR_WORLDS, TEXT_VOICES, TEXT_LEVELS, BUTTON_VARIANTS, BUTTON_SIZES, DEFAULT_SEMANTIC_MAPPINGS, DEFAULT_STATUS_SEMANTIC_MAPPINGS, getDefaultMappingsForWorld, DEFAULT_TEXT_ALIASES };
|
|
32
|
+
export { defaultDesignTokensV2, generateTailwindV4ThemeV2, generateCSSFromTokensV2, generateFontImportsV2, migrateDesignTokensV1toV2, validateDesignTokensV2, migrateResponsiveToFluid, generateColorScale, generateDarkColorScale, calculateOnColor, isV1Format, isV2Format, COLOR_WORLDS, SEMANTIC_COLOR_WORLDS, TEXT_VOICES, TEXT_LEVELS, BUTTON_VARIANTS, BUTTON_SIZES, DEFAULT_SEMANTIC_MAPPINGS, DEFAULT_STATUS_SEMANTIC_MAPPINGS, getDefaultMappingsForWorld, DEFAULT_TEXT_ALIASES };
|