@webmate-studio/builder 0.2.65 → 0.2.67
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.js +95 -62
package/package.json
CHANGED
package/src/design-tokens.js
CHANGED
|
@@ -1,3 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate color utility classes (bg-*, text-*, border-*)
|
|
3
|
+
* ALL colors are available in ALL variants (text, bg, border)
|
|
4
|
+
* Used by both generateTailwindV4Theme and generateCSSFromTokens
|
|
5
|
+
*/
|
|
6
|
+
function generateSemanticColorUtilities(tokens) {
|
|
7
|
+
if (!tokens.colors) return '';
|
|
8
|
+
|
|
9
|
+
let utilities = '\n/* Color Utilities */';
|
|
10
|
+
|
|
11
|
+
// Map of all colors: token name -> utility class base name
|
|
12
|
+
const colorMap = {
|
|
13
|
+
// Brand colors
|
|
14
|
+
'primary': 'primary',
|
|
15
|
+
'secondary': 'secondary',
|
|
16
|
+
|
|
17
|
+
// Base semantic colors
|
|
18
|
+
'bgBase': 'default',
|
|
19
|
+
'bgElevated': 'elevated',
|
|
20
|
+
'bgLifted': 'lifted',
|
|
21
|
+
'textBase': 'default',
|
|
22
|
+
'textSubtle': 'subtle',
|
|
23
|
+
'textMuted': 'muted',
|
|
24
|
+
'borderBase': 'default',
|
|
25
|
+
'borderSubtle': 'subtle',
|
|
26
|
+
'borderMuted': 'muted',
|
|
27
|
+
|
|
28
|
+
// Accent colors
|
|
29
|
+
'bgAccentBase': 'accent-default',
|
|
30
|
+
'bgAccentElevated': 'accent-elevated',
|
|
31
|
+
'bgAccentLifted': 'accent-lifted',
|
|
32
|
+
'textAccentBase': 'accent-default',
|
|
33
|
+
'textAccentSubtle': 'accent-subtle',
|
|
34
|
+
'textAccentMuted': 'accent-muted',
|
|
35
|
+
'borderAccentBase': 'accent-default',
|
|
36
|
+
'borderAccentSubtle': 'accent-subtle',
|
|
37
|
+
'borderAccentMuted': 'accent-muted'
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// Collect unique base names (deduplicate)
|
|
41
|
+
const processedNames = new Set();
|
|
42
|
+
|
|
43
|
+
for (const [tokenKey, baseName] of Object.entries(colorMap)) {
|
|
44
|
+
if (!tokens.colors[tokenKey]) continue;
|
|
45
|
+
|
|
46
|
+
// Skip if we already processed this base name
|
|
47
|
+
if (processedNames.has(baseName)) continue;
|
|
48
|
+
processedNames.add(baseName);
|
|
49
|
+
|
|
50
|
+
const colorVar = `--color-${tokenKey.replace(/([A-Z])/g, '-$1').toLowerCase()}`;
|
|
51
|
+
|
|
52
|
+
// Generate all three variants for every color
|
|
53
|
+
utilities += `\n.text-${baseName} {`;
|
|
54
|
+
utilities += `\n color: var(${colorVar});`;
|
|
55
|
+
utilities += `\n}`;
|
|
56
|
+
|
|
57
|
+
utilities += `\n.bg-${baseName} {`;
|
|
58
|
+
utilities += `\n background-color: var(${colorVar});`;
|
|
59
|
+
utilities += `\n}`;
|
|
60
|
+
|
|
61
|
+
utilities += `\n.border-${baseName} {`;
|
|
62
|
+
utilities += `\n border-color: var(${colorVar});`;
|
|
63
|
+
utilities += `\n}`;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return utilities;
|
|
67
|
+
}
|
|
68
|
+
|
|
1
69
|
/**
|
|
2
70
|
* Default Design Tokens für Website-Design
|
|
3
71
|
* Tailwind v4 kompatibel - verwendet Base-Values wo möglich
|
|
@@ -49,7 +117,12 @@ export const defaultDesignTokens = {
|
|
|
49
117
|
// Border Colors (Semantic)
|
|
50
118
|
borderBase: '#d1d5db', // slate-300 - Standard Border
|
|
51
119
|
borderSubtle: '#e5e7eb', // slate-200 - Dezenter Border
|
|
52
|
-
borderMuted: '#f3f4f6'
|
|
120
|
+
borderMuted: '#f3f4f6', // slate-100 - Sehr dezenter Border
|
|
121
|
+
|
|
122
|
+
// Border Colors (Accent)
|
|
123
|
+
borderAccentBase: '#8b5cf6', // violet-500
|
|
124
|
+
borderAccentSubtle: '#a78bfa', // violet-400
|
|
125
|
+
borderAccentMuted: '#c4b5fd' // violet-300
|
|
53
126
|
},
|
|
54
127
|
|
|
55
128
|
typography: {
|
|
@@ -441,7 +514,7 @@ export function generateTailwindV4Theme(tokens) {
|
|
|
441
514
|
// Text Styles - Generate CSS variables for each style (with responsive support)
|
|
442
515
|
if (tokens.textStyles) {
|
|
443
516
|
for (const [styleName, style] of Object.entries(tokens.textStyles)) {
|
|
444
|
-
const kebabName = styleName.replace(/([A-
|
|
517
|
+
const kebabName = styleName.replace(/([A-Z0-9])/g, '-$1').toLowerCase();
|
|
445
518
|
|
|
446
519
|
// Font family (not responsive)
|
|
447
520
|
if (style.fontFamily) {
|
|
@@ -581,7 +654,7 @@ body {
|
|
|
581
654
|
if (tokens.textStyles) {
|
|
582
655
|
globalStyles += '\n\n/* Text Style Utilities */';
|
|
583
656
|
for (const [styleName, style] of Object.entries(tokens.textStyles)) {
|
|
584
|
-
const kebabName = styleName.replace(/([A-
|
|
657
|
+
const kebabName = styleName.replace(/([A-Z0-9])/g, '-$1').toLowerCase();
|
|
585
658
|
const className = `text-${kebabName}`;
|
|
586
659
|
|
|
587
660
|
globalStyles += `\n.${className} {`;
|
|
@@ -627,12 +700,16 @@ body {
|
|
|
627
700
|
// Size classes
|
|
628
701
|
if (tokens.buttons.sizes) {
|
|
629
702
|
for (const sizeName of Object.keys(tokens.buttons.sizes)) {
|
|
703
|
+
const size = tokens.buttons.sizes[sizeName];
|
|
704
|
+
// Calculate unitless line-height (lineHeight in px / fontSize in px)
|
|
705
|
+
const lineHeightRatio = size.lineHeight / size.fontSize;
|
|
706
|
+
|
|
630
707
|
globalStyles += `\n.btn-${sizeName} {
|
|
631
|
-
padding:
|
|
632
|
-
font-size:
|
|
633
|
-
line-height:
|
|
634
|
-
border-radius:
|
|
635
|
-
gap:
|
|
708
|
+
padding: ${size.paddingY}px ${size.paddingX}px;
|
|
709
|
+
font-size: ${size.fontSize}px;
|
|
710
|
+
line-height: ${lineHeightRatio};
|
|
711
|
+
border-radius: ${size.borderRadius}px;
|
|
712
|
+
gap: ${size.gap}px;
|
|
636
713
|
}`;
|
|
637
714
|
}
|
|
638
715
|
}
|
|
@@ -667,7 +744,7 @@ body {
|
|
|
667
744
|
const mediaQueryLines = [];
|
|
668
745
|
|
|
669
746
|
for (const [styleName, style] of Object.entries(tokens.textStyles)) {
|
|
670
|
-
const kebabName = styleName.replace(/([A-
|
|
747
|
+
const kebabName = styleName.replace(/([A-Z0-9])/g, '-$1').toLowerCase();
|
|
671
748
|
|
|
672
749
|
// Font size
|
|
673
750
|
if (style.fontSize && typeof style.fontSize === 'object' && style.fontSize[bp]) {
|
|
@@ -693,6 +770,9 @@ body {
|
|
|
693
770
|
}
|
|
694
771
|
}
|
|
695
772
|
|
|
773
|
+
// Add semantic color utilities
|
|
774
|
+
globalStyles += generateSemanticColorUtilities(tokens);
|
|
775
|
+
|
|
696
776
|
return { themeVars, globalStyles };
|
|
697
777
|
}
|
|
698
778
|
|
|
@@ -867,7 +947,7 @@ export function generateCSSFromTokens(tokens) {
|
|
|
867
947
|
lines.push('');
|
|
868
948
|
lines.push('/* Text Style Utilities */');
|
|
869
949
|
for (const [styleName, style] of Object.entries(tokens.textStyles)) {
|
|
870
|
-
const kebabName = styleName.replace(/([A-
|
|
950
|
+
const kebabName = styleName.replace(/([A-Z0-9])/g, '-$1').toLowerCase();
|
|
871
951
|
const className = `text-${kebabName}`;
|
|
872
952
|
|
|
873
953
|
lines.push(`.${className} {`);
|
|
@@ -913,7 +993,7 @@ export function generateCSSFromTokens(tokens) {
|
|
|
913
993
|
const mediaQueryLines = [];
|
|
914
994
|
|
|
915
995
|
for (const [styleName, style] of Object.entries(tokens.textStyles)) {
|
|
916
|
-
const kebabName = styleName.replace(/([A-
|
|
996
|
+
const kebabName = styleName.replace(/([A-Z0-9])/g, '-$1').toLowerCase();
|
|
917
997
|
const className = `text-${kebabName}`;
|
|
918
998
|
const hasResponsive = (
|
|
919
999
|
(style.fontSize && typeof style.fontSize === 'object' && style.fontSize[bp]) ||
|
|
@@ -1109,57 +1189,10 @@ export function generateCSSFromTokens(tokens) {
|
|
|
1109
1189
|
}
|
|
1110
1190
|
}
|
|
1111
1191
|
|
|
1112
|
-
//
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
lines.push(
|
|
1116
|
-
|
|
1117
|
-
// Background colors
|
|
1118
|
-
const bgColors = [
|
|
1119
|
-
'bgBase', 'bgElevated', 'bgLifted',
|
|
1120
|
-
'bgAccentBase', 'bgAccentElevated', 'bgAccentLifted'
|
|
1121
|
-
];
|
|
1122
|
-
for (const colorKey of bgColors) {
|
|
1123
|
-
if (tokens.colors[colorKey]) {
|
|
1124
|
-
const kebabName = colorKey.replace(/([A-Z])/g, '-$1').toLowerCase().replace('bg-', '');
|
|
1125
|
-
const className = `bg-${kebabName}`;
|
|
1126
|
-
const colorVar = `--color-${colorKey.replace(/([A-Z])/g, '-$1').toLowerCase()}`;
|
|
1127
|
-
lines.push(`.${className} {`);
|
|
1128
|
-
lines.push(` background-color: var(${colorVar});`);
|
|
1129
|
-
lines.push('}');
|
|
1130
|
-
}
|
|
1131
|
-
}
|
|
1132
|
-
|
|
1133
|
-
// Text colors
|
|
1134
|
-
const textColors = [
|
|
1135
|
-
'textBase', 'textSubtle', 'textMuted',
|
|
1136
|
-
'textAccentBase', 'textAccentSubtle', 'textAccentMuted'
|
|
1137
|
-
];
|
|
1138
|
-
for (const colorKey of textColors) {
|
|
1139
|
-
if (tokens.colors[colorKey]) {
|
|
1140
|
-
const kebabName = colorKey.replace(/([A-Z])/g, '-$1').toLowerCase().replace('text-', '');
|
|
1141
|
-
const className = `text-${kebabName}`;
|
|
1142
|
-
const colorVar = `--color-${colorKey.replace(/([A-Z])/g, '-$1').toLowerCase()}`;
|
|
1143
|
-
lines.push(`.${className} {`);
|
|
1144
|
-
lines.push(` color: var(${colorVar});`);
|
|
1145
|
-
lines.push('}');
|
|
1146
|
-
}
|
|
1147
|
-
}
|
|
1148
|
-
|
|
1149
|
-
// Border colors
|
|
1150
|
-
const borderColors = [
|
|
1151
|
-
'borderBase', 'borderSubtle', 'borderMuted'
|
|
1152
|
-
];
|
|
1153
|
-
for (const colorKey of borderColors) {
|
|
1154
|
-
if (tokens.colors[colorKey]) {
|
|
1155
|
-
const kebabName = colorKey.replace(/([A-Z])/g, '-$1').toLowerCase().replace('border-', '');
|
|
1156
|
-
const className = `border-${kebabName}`;
|
|
1157
|
-
const colorVar = `--color-${colorKey.replace(/([A-Z])/g, '-$1').toLowerCase()}`;
|
|
1158
|
-
lines.push(`.${className} {`);
|
|
1159
|
-
lines.push(` border-color: var(${colorVar});`);
|
|
1160
|
-
lines.push('}');
|
|
1161
|
-
}
|
|
1162
|
-
}
|
|
1192
|
+
// Add semantic color utilities
|
|
1193
|
+
const semanticUtilities = generateSemanticColorUtilities(tokens);
|
|
1194
|
+
if (semanticUtilities) {
|
|
1195
|
+
lines.push(semanticUtilities);
|
|
1163
1196
|
}
|
|
1164
1197
|
|
|
1165
1198
|
return lines.join('\n');
|