@webmate-studio/builder 0.2.157 → 0.2.160

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.157",
3
+ "version": "0.2.160",
4
4
  "type": "module",
5
5
  "description": "Webmate Studio Component Builder",
6
6
  "keywords": [
@@ -15,7 +15,8 @@ import {
15
15
  calculateOnColor,
16
16
  DEFAULT_SURFACE_TOKENS,
17
17
  defaultDesignTokensV2,
18
- normalizeShadowValue
18
+ normalizeShadowValue,
19
+ isGradientValue
19
20
  } from './design-tokens-v2.js';
20
21
 
21
22
 
@@ -52,6 +53,7 @@ export function generateTailwindV4ThemeV2(tokens) {
52
53
  globalStyles += generateTextAliasClasses(t);
53
54
  globalStyles += generateTextResponsiveVariants(t);
54
55
  globalStyles += generateButtonClasses(t);
56
+ globalStyles += generateSpacingStyles(t);
55
57
  globalStyles += generateResponsiveMediaQueries(responsiveLines);
56
58
 
57
59
  return { themeVars, globalStyles };
@@ -600,9 +602,9 @@ function resolveShadowToCSS(shadowValue, t) {
600
602
  }
601
603
 
602
604
  function addButtonVariantVars(lines, prefix, variant, t) {
603
- if (variant.bg) lines.push(` --${prefix}-bg: ${resolveColorRef(variant.bg, t)};`);
604
- if (variant.bgHover) lines.push(` --${prefix}-bg-hover: ${resolveColorRef(variant.bgHover, t)};`);
605
- if (variant.bgActive) lines.push(` --${prefix}-bg-active: ${resolveColorRef(variant.bgActive, t)};`);
605
+ if (variant.bg) lines.push(` --${prefix}-bg: ${resolveBackgroundValue(variant.bg, t)};`);
606
+ if (variant.bgHover) lines.push(` --${prefix}-bg-hover: ${resolveBackgroundValue(variant.bgHover, t)};`);
607
+ if (variant.bgActive) lines.push(` --${prefix}-bg-active: ${resolveBackgroundValue(variant.bgActive, t)};`);
606
608
  if (variant.text) lines.push(` --${prefix}-text: ${resolveColorRef(variant.text, t)};`);
607
609
  if (variant.textHover) lines.push(` --${prefix}-text-hover: ${resolveColorRef(variant.textHover, t)};`);
608
610
  if (variant.textActive) lines.push(` --${prefix}-text-active: ${resolveColorRef(variant.textActive, t)};`);
@@ -652,6 +654,49 @@ function resolveColorRef(ref, t) {
652
654
  return `var(--color-${ref})`;
653
655
  }
654
656
 
657
+ /**
658
+ * Löst einen Hintergrundwert auf — entweder Farbreferenz (String) oder Gradient (Object).
659
+ * String → delegiert an resolveColorRef()
660
+ * Object → buildGradientCSS()
661
+ */
662
+ function resolveBackgroundValue(val, t) {
663
+ if (!val) return 'none';
664
+ if (isGradientValue(val)) return buildGradientCSS(val, t);
665
+ return resolveColorRef(val, t);
666
+ }
667
+
668
+ /**
669
+ * Baut einen CSS-Gradient-String aus einem Gradient-Objekt.
670
+ * Unterstützt linear-gradient, radial-gradient und conic-gradient.
671
+ */
672
+ function buildGradientCSS(gradient, t) {
673
+ const stops = (gradient.stops || []).map(stop => {
674
+ const color = resolveColorRef(stop.color, t);
675
+ const colorCSS = (stop.opacity != null && stop.opacity < 100)
676
+ ? `color-mix(in srgb, ${color} ${stop.opacity}%, transparent)`
677
+ : color;
678
+ return `${colorCSS} ${stop.position}%`;
679
+ }).join(', ');
680
+
681
+ switch (gradient.type) {
682
+ case 'radial': {
683
+ const shape = gradient.shape || 'circle';
684
+ const size = gradient.size || 'farthest-corner';
685
+ const pos = gradient.position || 'center';
686
+ return `radial-gradient(${shape} ${size} at ${pos}, ${stops})`;
687
+ }
688
+ case 'conic': {
689
+ const fromAngle = gradient.fromAngle || 0;
690
+ const pos = gradient.position || 'center';
691
+ return `conic-gradient(from ${fromAngle}deg at ${pos}, ${stops})`;
692
+ }
693
+ default: { // linear
694
+ const angle = gradient.angle ?? 135;
695
+ return `linear-gradient(${angle}deg, ${stops})`;
696
+ }
697
+ }
698
+ }
699
+
655
700
 
656
701
  // ─── Button-Klassen ─────────────────────────────────────────────────────────
657
702
 
@@ -978,6 +1023,11 @@ function generateLayoutVariables(t, lines) {
978
1023
  if (t.borderWidth) lines.push(` --border-width: ${t.borderWidth};`);
979
1024
  if (t.borderRadius) lines.push(` --radius: ${t.borderRadius};`);
980
1025
 
1026
+ if (t.spacing?.component) {
1027
+ lines.push(` /* component spacing */`);
1028
+ lines.push(` --spacing-component: ${t.spacing.component.base || '3rem'};`);
1029
+ }
1030
+
981
1031
  if (t.breakpoints) {
982
1032
  lines.push(' /* breakpoints */');
983
1033
  for (const [key, value] of Object.entries(t.breakpoints)) {
@@ -987,6 +1037,42 @@ function generateLayoutVariables(t, lines) {
987
1037
  }
988
1038
 
989
1039
 
1040
+ // ─── Component Spacing ──────────────────────────────────────────────────────
1041
+
1042
+ function generateSpacingStyles(t) {
1043
+ if (!t.spacing?.component) return '';
1044
+
1045
+ const breakpoints = {
1046
+ sm: '640px', md: '768px', lg: '1024px', xl: '1280px', '2xl': '1536px'
1047
+ };
1048
+
1049
+ let css = '\n\n/* Component Spacing */';
1050
+ css += '\n.component-wrapper {';
1051
+ css += '\n display: flex;';
1052
+ css += '\n flex-direction: column;';
1053
+ css += '\n}';
1054
+ css += '\n.component-wrapper > * + * {';
1055
+ css += '\n margin-top: var(--spacing-component);';
1056
+ css += '\n}';
1057
+
1058
+ // Spacing-Modi
1059
+ css += '\n[data-spacing="none"] { margin-top: 0 !important; }';
1060
+ css += '\n[data-spacing="half"] { margin-top: calc(var(--spacing-component) / 2) !important; }';
1061
+ css += '\n[data-spacing="double"] { margin-top: calc(var(--spacing-component) * 2) !important; }';
1062
+
1063
+ // Responsive Overrides
1064
+ for (const [bp, minWidth] of Object.entries(breakpoints)) {
1065
+ if (t.spacing.component[bp]) {
1066
+ css += `\n@media (min-width: ${minWidth}) {`;
1067
+ css += `\n :root { --spacing-component: ${t.spacing.component[bp]}; }`;
1068
+ css += '\n}';
1069
+ }
1070
+ }
1071
+
1072
+ return css;
1073
+ }
1074
+
1075
+
990
1076
  // ─── Basis-Styles ───────────────────────────────────────────────────────────
991
1077
 
992
1078
  function generateBaseStyles(t) {
@@ -1399,6 +1399,56 @@ export const defaultDesignTokensV2 = {
1399
1399
  };
1400
1400
 
1401
1401
 
1402
+ // ─── Gradient-Hilfsfunktionen ───────────────────────────────────────────────
1403
+
1404
+ /**
1405
+ * Position-Keywords für radial/conic Gradients.
1406
+ */
1407
+ export const GRADIENT_POSITIONS = [
1408
+ 'center', 'top', 'right', 'bottom', 'left',
1409
+ 'top left', 'top right', 'bottom left', 'bottom right'
1410
+ ];
1411
+
1412
+ /**
1413
+ * Size-Keywords für radial Gradients.
1414
+ */
1415
+ export const RADIAL_SIZES = [
1416
+ 'farthest-corner', 'closest-side', 'farthest-side', 'closest-corner'
1417
+ ];
1418
+
1419
+ /**
1420
+ * Prüft ob ein Wert ein Gradient-Objekt ist (statt einer Farbreferenz-String).
1421
+ */
1422
+ export function isGradientValue(val) {
1423
+ return val != null && typeof val === 'object' && val.type && Array.isArray(val.stops);
1424
+ }
1425
+
1426
+ /**
1427
+ * Erzeugt einen Standard-Gradient-Stop.
1428
+ */
1429
+ export function createDefaultGradientStop(position = 0) {
1430
+ return { color: 'primary-9', position, opacity: 100 };
1431
+ }
1432
+
1433
+ /**
1434
+ * Erzeugt ein Standard-Gradient-Objekt mit 2 Stops.
1435
+ */
1436
+ export function createDefaultGradient() {
1437
+ return {
1438
+ type: 'linear',
1439
+ angle: 135,
1440
+ shape: 'circle',
1441
+ position: 'center',
1442
+ size: 'farthest-corner',
1443
+ fromAngle: 0,
1444
+ stops: [
1445
+ { color: 'primary-9', position: 0, opacity: 100 },
1446
+ { color: 'primary-6', position: 100, opacity: 100 }
1447
+ ]
1448
+ };
1449
+ }
1450
+
1451
+
1402
1452
  // ─── Erkennung ──────────────────────────────────────────────────────────────
1403
1453
 
1404
1454
  /**