@webmate-studio/builder 0.2.64 → 0.2.66

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webmate-studio/builder",
3
- "version": "0.2.64",
3
+ "version": "0.2.66",
4
4
  "type": "module",
5
5
  "description": "Webmate Studio Component Builder",
6
6
  "keywords": [
@@ -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' // slate-100 - Sehr dezenter Border
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: {
@@ -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: var(--button-${sizeName}-padding-y) var(--button-${sizeName}-padding-x);
632
- font-size: var(--button-${sizeName}-font-size);
633
- line-height: var(--button-${sizeName}-line-height);
634
- border-radius: var(--button-${sizeName}-border-radius);
635
- gap: var(--button-${sizeName}-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
  }
@@ -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
 
@@ -1000,7 +1080,9 @@ export function generateCSSFromTokens(tokens) {
1000
1080
  lines.push(`.btn-${sizeName} {`);
1001
1081
  lines.push(` padding: ${size.paddingY}px ${size.paddingX}px;`);
1002
1082
  lines.push(` font-size: ${size.fontSize}px;`);
1003
- lines.push(` line-height: ${size.lineHeight}px;`);
1083
+ // Calculate unitless line-height (lineHeight in px / fontSize in px)
1084
+ const lineHeightRatio = size.lineHeight / size.fontSize;
1085
+ lines.push(` line-height: ${lineHeightRatio};`);
1004
1086
  lines.push(` min-height: ${size.minHeight}px;`);
1005
1087
  lines.push(` border-radius: ${size.borderRadius}px;`);
1006
1088
  lines.push(` border-width: ${size.borderWidth}px;`);
@@ -1107,57 +1189,10 @@ export function generateCSSFromTokens(tokens) {
1107
1189
  }
1108
1190
  }
1109
1191
 
1110
- // Generate utility classes for semantic colors
1111
- if (tokens.colors) {
1112
- lines.push('');
1113
- lines.push('/* Semantic Color Utilities */');
1114
-
1115
- // Background colors
1116
- const bgColors = [
1117
- 'bgBase', 'bgElevated', 'bgLifted',
1118
- 'bgAccentBase', 'bgAccentElevated', 'bgAccentLifted'
1119
- ];
1120
- for (const colorKey of bgColors) {
1121
- if (tokens.colors[colorKey]) {
1122
- const kebabName = colorKey.replace(/([A-Z])/g, '-$1').toLowerCase().replace('bg-', '');
1123
- const className = `bg-${kebabName}`;
1124
- const colorVar = `--color-${colorKey.replace(/([A-Z])/g, '-$1').toLowerCase()}`;
1125
- lines.push(`.${className} {`);
1126
- lines.push(` background-color: var(${colorVar});`);
1127
- lines.push('}');
1128
- }
1129
- }
1130
-
1131
- // Text colors
1132
- const textColors = [
1133
- 'textBase', 'textSubtle', 'textMuted',
1134
- 'textAccentBase', 'textAccentSubtle', 'textAccentMuted'
1135
- ];
1136
- for (const colorKey of textColors) {
1137
- if (tokens.colors[colorKey]) {
1138
- const kebabName = colorKey.replace(/([A-Z])/g, '-$1').toLowerCase().replace('text-', '');
1139
- const className = `text-${kebabName}`;
1140
- const colorVar = `--color-${colorKey.replace(/([A-Z])/g, '-$1').toLowerCase()}`;
1141
- lines.push(`.${className} {`);
1142
- lines.push(` color: var(${colorVar});`);
1143
- lines.push('}');
1144
- }
1145
- }
1146
-
1147
- // Border colors
1148
- const borderColors = [
1149
- 'borderBase', 'borderSubtle', 'borderMuted'
1150
- ];
1151
- for (const colorKey of borderColors) {
1152
- if (tokens.colors[colorKey]) {
1153
- const kebabName = colorKey.replace(/([A-Z])/g, '-$1').toLowerCase().replace('border-', '');
1154
- const className = `border-${kebabName}`;
1155
- const colorVar = `--color-${colorKey.replace(/([A-Z])/g, '-$1').toLowerCase()}`;
1156
- lines.push(`.${className} {`);
1157
- lines.push(` border-color: var(${colorVar});`);
1158
- lines.push('}');
1159
- }
1160
- }
1192
+ // Add semantic color utilities
1193
+ const semanticUtilities = generateSemanticColorUtilities(tokens);
1194
+ if (semanticUtilities) {
1195
+ lines.push(semanticUtilities);
1161
1196
  }
1162
1197
 
1163
1198
  return lines.join('\n');