@promptui-lib/codegen 0.1.7 → 0.1.9

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.
@@ -1,3 +1,4 @@
1
1
  export { generateTSX, generateIndex } from './tsx-generator.js';
2
2
  export { generateSCSS, generateFlatSCSS } from './scss-generator.js';
3
+ export { generateDefaultVariables } from './variables-generator.js';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generators/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generators/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACrE,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC"}
@@ -1,2 +1,3 @@
1
1
  export { generateTSX, generateIndex } from './tsx-generator.js';
2
2
  export { generateSCSS, generateFlatSCSS } from './scss-generator.js';
3
+ export { generateDefaultVariables } from './variables-generator.js';
@@ -1 +1 @@
1
- {"version":3,"file":"scss-generator.d.ts","sourceRoot":"","sources":["../../src/generators/scss-generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAA+B,MAAM,oBAAoB,CAAC;AAoHrF;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAavD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAc3D"}
1
+ {"version":3,"file":"scss-generator.d.ts","sourceRoot":"","sources":["../../src/generators/scss-generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAA+B,MAAM,oBAAoB,CAAC;AAiJrF;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAYvD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAU3D"}
@@ -30,14 +30,29 @@ function generateStyleBlock(block, indent = 0) {
30
30
  lines.push(`${spaces}}`);
31
31
  return lines.join('\n');
32
32
  }
33
+ /**
34
+ * Remove seletores duplicados, mantendo apenas o primeiro de cada
35
+ */
36
+ function deduplicateStyles(styles) {
37
+ const seen = new Set();
38
+ return styles.filter((style) => {
39
+ if (seen.has(style.selector)) {
40
+ return false;
41
+ }
42
+ seen.add(style.selector);
43
+ return true;
44
+ });
45
+ }
33
46
  /**
34
47
  * Agrupa estilos por bloco BEM
35
48
  */
36
49
  function groupStylesByBlock(styles, blockName) {
37
50
  const rootSelector = `.${blockName}`;
38
- const root = styles.find((s) => s.selector === rootSelector) ?? null;
39
- const elements = styles.filter((s) => s.selector.includes('__') && !s.selector.includes('--'));
40
- const modifiers = styles.filter((s) => s.selector.includes('--'));
51
+ // Deduplica antes de processar
52
+ const uniqueStyles = deduplicateStyles(styles);
53
+ const root = uniqueStyles.find((s) => s.selector === rootSelector) ?? null;
54
+ const elements = uniqueStyles.filter((s) => s.selector.includes('__') && !s.selector.includes('--'));
55
+ const modifiers = uniqueStyles.filter((s) => s.selector.includes('--'));
41
56
  return { root, elements, modifiers };
42
57
  }
43
58
  /**
@@ -55,10 +70,15 @@ function generateBEMStructure(styles, blockName) {
55
70
  }
56
71
  }
57
72
  // Elementos (__element)
58
- if (elements.length > 0) {
73
+ // Filtra elementos com nome válido (não vazio)
74
+ const validElements = elements.filter((element) => {
75
+ const elementName = element.selector.replace(`.${blockName}__`, '');
76
+ return elementName && elementName.trim() !== '';
77
+ });
78
+ if (validElements.length > 0) {
59
79
  lines.push('');
60
80
  lines.push(' // Elements');
61
- for (const element of elements) {
81
+ for (const element of validElements) {
62
82
  const elementName = element.selector.replace(`.${blockName}__`, '');
63
83
  lines.push('');
64
84
  lines.push(` &__${elementName} {`);
@@ -69,10 +89,15 @@ function generateBEMStructure(styles, blockName) {
69
89
  }
70
90
  }
71
91
  // Modificadores (--modifier)
72
- if (modifiers.length > 0) {
92
+ // Filtra modificadores com nome válido (não vazio)
93
+ const validModifiers = modifiers.filter((modifier) => {
94
+ const modifierName = modifier.selector.split('--')[1];
95
+ return modifierName && modifierName.trim() !== '';
96
+ });
97
+ if (validModifiers.length > 0) {
73
98
  lines.push('');
74
99
  lines.push(' // Modifiers');
75
- for (const modifier of modifiers) {
100
+ for (const modifier of validModifiers) {
76
101
  const modifierName = modifier.selector.split('--')[1];
77
102
  lines.push('');
78
103
  lines.push(` &--${modifierName} {`);
@@ -90,13 +115,12 @@ function generateBEMStructure(styles, blockName) {
90
115
  */
91
116
  export function generateSCSS(ast) {
92
117
  const lines = [];
93
- // Import de variáveis
94
- lines.push("@use '@styles/variables' as *;");
118
+ // Import do arquivo de variáveis (caminho relativo para src/styles/_variables.scss)
119
+ lines.push("@use '../../../styles/variables' as *;");
95
120
  lines.push('');
96
121
  // Gera estrutura BEM
97
122
  const blockName = ast.fileName;
98
- const bemCode = generateBEMStructure(ast.styles, blockName);
99
- lines.push(bemCode);
123
+ lines.push(generateBEMStructure(ast.styles, blockName));
100
124
  return lines.join('\n');
101
125
  }
102
126
  /**
@@ -104,9 +128,6 @@ export function generateSCSS(ast) {
104
128
  */
105
129
  export function generateFlatSCSS(ast) {
106
130
  const lines = [];
107
- // Import de variáveis
108
- lines.push("@use '@styles/variables' as *;");
109
- lines.push('');
110
131
  // Blocos individuais
111
132
  for (const block of ast.styles) {
112
133
  lines.push(generateStyleBlock(block));
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Variables Generator
3
+ * Gera arquivo SCSS com variáveis padrão (tokens)
4
+ */
5
+ /**
6
+ * Gera o conteúdo do arquivo _variables.scss com tokens padrão
7
+ */
8
+ export declare function generateDefaultVariables(): string;
9
+ //# sourceMappingURL=variables-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"variables-generator.d.ts","sourceRoot":"","sources":["../../src/generators/variables-generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAuIjD"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Variables Generator
3
+ * Gera arquivo SCSS com variáveis padrão (tokens)
4
+ */
5
+ /**
6
+ * Gera o conteúdo do arquivo _variables.scss com tokens padrão
7
+ */
8
+ export function generateDefaultVariables() {
9
+ return `// PromptUI - Design Tokens
10
+ // Auto-generated by PromptUI CLI
11
+ // Run 'promptui sync tokens' to update from Figma
12
+
13
+ // =============================================================================
14
+ // COLORS
15
+ // =============================================================================
16
+
17
+ // Brand Colors
18
+ $color-primary: #2d6dff;
19
+ $color-primary-light: #5a8fff;
20
+ $color-primary-dark: #1a4fcc;
21
+ $color-secondary: #5f6368;
22
+
23
+ // Semantic Colors
24
+ $color-success: #34a853;
25
+ $color-error: #ea4335;
26
+ $color-warning: #fbbc04;
27
+ $color-info: #4285f4;
28
+
29
+ // Text Colors
30
+ $color-text-primary: #1a1a1a;
31
+ $color-text-secondary: #4f4f4f;
32
+ $color-text-tertiary: #9c9c9c;
33
+ $color-text-disabled: #9aa0a6;
34
+ $color-text-inverse: #ffffff;
35
+
36
+ // Background Colors
37
+ $color-bg-primary: #ffffff;
38
+ $color-bg-secondary: #f8f9fa;
39
+ $color-bg-tertiary: #e8eaed;
40
+
41
+ // Border Colors
42
+ $color-border: #dadce0;
43
+ $color-border-primary: #d8d8d8;
44
+ $color-divider: #e8eaed;
45
+
46
+ // =============================================================================
47
+ // TYPOGRAPHY
48
+ // =============================================================================
49
+
50
+ // Font Families
51
+ $font-family-primary: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
52
+ $font-family-secondary: "Manrope", sans-serif;
53
+ $font-family-mono: "Fira Code", "Consolas", monospace;
54
+
55
+ // Font Sizes
56
+ $font-size-xs: 12px;
57
+ $font-size-sm: 14px;
58
+ $font-size-md: 16px;
59
+ $font-size-lg: 18px;
60
+ $font-size-xl: 20px;
61
+ $font-size-2xl: 24px;
62
+ $font-size-3xl: 30px;
63
+ $font-size-4xl: 36px;
64
+
65
+ // Font Weights
66
+ $font-weight-regular: 400;
67
+ $font-weight-medium: 500;
68
+ $font-weight-semibold: 600;
69
+ $font-weight-bold: 700;
70
+
71
+ // Line Heights
72
+ $line-height-tight: 1.25;
73
+ $line-height-normal: 1.5;
74
+ $line-height-relaxed: 1.75;
75
+
76
+ // =============================================================================
77
+ // SPACING
78
+ // =============================================================================
79
+
80
+ $spacing-xs: 4px;
81
+ $spacing-sm: 8px;
82
+ $spacing-md: 16px;
83
+ $spacing-lg: 24px;
84
+ $spacing-xl: 32px;
85
+ $spacing-2xl: 48px;
86
+ $spacing-3xl: 64px;
87
+
88
+ // Gap (for flexbox/grid)
89
+ $gap-1: 4px;
90
+ $gap-2: 8px;
91
+ $gap-3: 12px;
92
+ $gap-4: 16px;
93
+ $gap-5: 20px;
94
+ $gap-6: 24px;
95
+ $gap-8: 32px;
96
+
97
+ // =============================================================================
98
+ // BORDERS
99
+ // =============================================================================
100
+
101
+ // Border Radius
102
+ $radius-none: 0;
103
+ $radius-small: 4px;
104
+ $radius-medium: 8px;
105
+ $radius-large: 12px;
106
+ $radius-xl: 16px;
107
+ $radius-full: 9999px;
108
+
109
+ // Border Width
110
+ $border-width-thin: 1px;
111
+ $border-width-medium: 2px;
112
+ $border-width-thick: 4px;
113
+
114
+ // =============================================================================
115
+ // SHADOWS
116
+ // =============================================================================
117
+
118
+ $shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
119
+ $shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
120
+ $shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
121
+ $shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.15);
122
+
123
+ // =============================================================================
124
+ // TRANSITIONS
125
+ // =============================================================================
126
+
127
+ $transition-fast: 150ms ease;
128
+ $transition-normal: 250ms ease;
129
+ $transition-slow: 350ms ease;
130
+
131
+ // =============================================================================
132
+ // Z-INDEX
133
+ // =============================================================================
134
+
135
+ $z-dropdown: 1000;
136
+ $z-sticky: 1020;
137
+ $z-fixed: 1030;
138
+ $z-modal-backdrop: 1040;
139
+ $z-modal: 1050;
140
+ $z-popover: 1060;
141
+ $z-tooltip: 1070;
142
+ `;
143
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"file-writer.d.ts","sourceRoot":"","sources":["../../src/writers/file-writer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAIxF,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE;QACL,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAqBD;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAM/D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,cAAc,EACrB,QAAQ,EAAE,MAAM,GACf,MAAM,CAER;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,YAAY,CAAC,CAmDvB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,aAAa,EAAE,EACrB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,YAAY,EAAE,CAAC,CASzB"}
1
+ {"version":3,"file":"file-writer.d.ts","sourceRoot":"","sources":["../../src/writers/file-writer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAKxF,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE;QACL,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAqBD;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAM/D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,cAAc,EACrB,QAAQ,EAAE,MAAM,GACf,MAAM,CAER;AA2BD;;GAEG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,YAAY,CAAC,CAyDvB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,aAAa,EAAE,EACrB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,YAAY,EAAE,CAAC,CASzB"}
@@ -3,9 +3,10 @@
3
3
  * Escreve arquivos gerados no sistema de arquivos
4
4
  */
5
5
  import { mkdir, writeFile, access } from 'node:fs/promises';
6
- import { join } from 'node:path';
6
+ import { join, dirname } from 'node:path';
7
7
  import { generateTSX, generateIndex } from '../generators/tsx-generator.js';
8
8
  import { generateSCSS } from '../generators/scss-generator.js';
9
+ import { generateDefaultVariables } from '../generators/variables-generator.js';
9
10
  /**
10
11
  * Verifica se um arquivo existe
11
12
  */
@@ -40,6 +41,29 @@ export function generateCode(ast) {
40
41
  export function getOutputPath(basePath, layer, fileName) {
41
42
  return join(basePath, layer, fileName);
42
43
  }
44
+ /**
45
+ * Garante que o arquivo de variáveis existe
46
+ */
47
+ async function ensureVariablesFile(basePath) {
48
+ // Calcula o caminho da pasta styles (irmã de components)
49
+ // basePath = src/components -> stylesDir = src/styles
50
+ const parentDir = dirname(basePath);
51
+ const stylesDir = join(parentDir, 'styles');
52
+ const variablesPath = join(stylesDir, '_variables.scss');
53
+ // Verifica se já existe
54
+ const exists = await fileExists(variablesPath);
55
+ if (exists) {
56
+ return null; // Já existe, não precisa criar
57
+ }
58
+ try {
59
+ await ensureDir(stylesDir);
60
+ await writeFile(variablesPath, generateDefaultVariables(), 'utf-8');
61
+ return variablesPath;
62
+ }
63
+ catch {
64
+ return null;
65
+ }
66
+ }
43
67
  /**
44
68
  * Escreve os arquivos do componente
45
69
  */
@@ -64,6 +88,11 @@ export async function writeComponent(ast, options) {
64
88
  }
65
89
  }
66
90
  try {
91
+ // Garante que o arquivo de variáveis existe
92
+ const variablesCreated = await ensureVariablesFile(options.basePath);
93
+ if (variablesCreated) {
94
+ console.log(` 📁 Created: ${variablesCreated}`);
95
+ }
67
96
  // Cria diretório
68
97
  await ensureDir(componentDir);
69
98
  // Escreve arquivos
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@promptui-lib/codegen",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "private": false,
5
5
  "description": "Code generator for PromptUI - generates React TSX and SCSS",
6
6
  "license": "UNLICENSED",
@@ -30,7 +30,7 @@
30
30
  "dist"
31
31
  ],
32
32
  "dependencies": {
33
- "@promptui-lib/core": "0.1.7"
33
+ "@promptui-lib/core": "0.1.9"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/node": "^20.0.0",