@promptui-lib/codegen 0.1.0

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.
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Bootstrap Template
3
+ * Gera componentes React com classes Bootstrap
4
+ */
5
+ import type { IComponentAST } from '@promptui-lib/core';
6
+ /**
7
+ * Gera componente React com Bootstrap
8
+ */
9
+ export declare function generateBootstrapComponent(ast: IComponentAST): string;
10
+ //# sourceMappingURL=bootstrap.template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bootstrap.template.d.ts","sourceRoot":"","sources":["../../src/frameworks/bootstrap.template.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAA4B,MAAM,oBAAoB,CAAC;AA6QlF;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAsCrE"}
@@ -0,0 +1,294 @@
1
+ /**
2
+ * Bootstrap Template
3
+ * Gera componentes React com classes Bootstrap
4
+ */
5
+ /**
6
+ * Mapeamento de tokens SCSS → Bootstrap classes
7
+ */
8
+ const TOKEN_TO_BOOTSTRAP = {
9
+ // Colors - Background
10
+ '$color-primary': 'bg-primary',
11
+ '$color-secondary': 'bg-secondary',
12
+ '$color-success': 'bg-success',
13
+ '$color-error': 'bg-danger',
14
+ '$color-warning': 'bg-warning',
15
+ '$color-bg-primary': 'bg-white',
16
+ '$color-bg-secondary': 'bg-light',
17
+ '$color-bg-tertiary': 'bg-body-secondary',
18
+ // Colors - Text
19
+ '$color-text-primary': 'text-dark',
20
+ '$color-text-secondary': 'text-secondary',
21
+ '$color-text-tertiary': 'text-muted',
22
+ '$color-text-inverse': 'text-white',
23
+ // Border colors
24
+ '$color-border': 'border-light',
25
+ '$color-border-primary': 'border-secondary',
26
+ // Spacing (Bootstrap usa 0-5 scale)
27
+ '$spacing-xs': '1',
28
+ '$spacing-sm': '2',
29
+ '$spacing-md': '3',
30
+ '$spacing-lg': '4',
31
+ '$spacing-xl': '5',
32
+ '$spacing-2xl': '5',
33
+ // Border radius
34
+ '$radius-none': 'rounded-0',
35
+ '$radius-small': 'rounded-1',
36
+ '$radius-medium': 'rounded-2',
37
+ '$radius-large': 'rounded-3',
38
+ '$radius-xl': 'rounded-4',
39
+ '$radius-full': 'rounded-circle',
40
+ // Font sizes
41
+ '$font-size-xs': 'fs-6',
42
+ '$font-size-sm': 'fs-6',
43
+ '$font-size-md': 'fs-5',
44
+ '$font-size-lg': 'fs-4',
45
+ '$font-size-xl': 'fs-3',
46
+ '$font-size-2xl': 'fs-2',
47
+ '$font-size-h1': 'fs-1',
48
+ '$font-size-h2': 'fs-2',
49
+ // Font weights
50
+ '$font-weight-regular': 'fw-normal',
51
+ '$font-weight-medium': 'fw-medium',
52
+ '$font-weight-semibold': 'fw-semibold',
53
+ '$font-weight-bold': 'fw-bold',
54
+ // Shadows
55
+ '$shadow-sm': 'shadow-sm',
56
+ '$shadow-md': 'shadow',
57
+ '$shadow-lg': 'shadow-lg',
58
+ '$shadow-modal': 'shadow-lg',
59
+ };
60
+ /**
61
+ * Mapeamentos de valores CSS → Bootstrap
62
+ */
63
+ const CSS_TO_BOOTSTRAP = {
64
+ 'display': {
65
+ 'flex': 'd-flex',
66
+ 'block': 'd-block',
67
+ 'inline': 'd-inline',
68
+ 'inline-flex': 'd-inline-flex',
69
+ 'grid': 'd-grid',
70
+ 'none': 'd-none',
71
+ },
72
+ 'flex-direction': {
73
+ 'row': 'flex-row',
74
+ 'column': 'flex-column',
75
+ 'row-reverse': 'flex-row-reverse',
76
+ 'column-reverse': 'flex-column-reverse',
77
+ },
78
+ 'align-items': {
79
+ 'flex-start': 'align-items-start',
80
+ 'flex-end': 'align-items-end',
81
+ 'center': 'align-items-center',
82
+ 'baseline': 'align-items-baseline',
83
+ 'stretch': 'align-items-stretch',
84
+ },
85
+ 'justify-content': {
86
+ 'flex-start': 'justify-content-start',
87
+ 'flex-end': 'justify-content-end',
88
+ 'center': 'justify-content-center',
89
+ 'space-between': 'justify-content-between',
90
+ 'space-around': 'justify-content-around',
91
+ 'space-evenly': 'justify-content-evenly',
92
+ },
93
+ 'text-align': {
94
+ 'left': 'text-start',
95
+ 'center': 'text-center',
96
+ 'right': 'text-end',
97
+ },
98
+ 'width': {
99
+ '100%': 'w-100',
100
+ '75%': 'w-75',
101
+ '50%': 'w-50',
102
+ '25%': 'w-25',
103
+ 'auto': 'w-auto',
104
+ },
105
+ 'height': {
106
+ '100%': 'h-100',
107
+ '75%': 'h-75',
108
+ '50%': 'h-50',
109
+ '25%': 'h-25',
110
+ 'auto': 'h-auto',
111
+ },
112
+ };
113
+ /**
114
+ * Converte propriedade CSS para classe Bootstrap
115
+ */
116
+ function cssToBootstrap(property, value) {
117
+ // Se o valor é um token, usa mapeamento direto
118
+ if (value.startsWith('$')) {
119
+ const bootstrapClass = TOKEN_TO_BOOTSTRAP[value];
120
+ if (bootstrapClass) {
121
+ // Verifica se precisa ajustar para a propriedade
122
+ if (property === 'color' && bootstrapClass.startsWith('bg-')) {
123
+ return bootstrapClass.replace('bg-', 'text-');
124
+ }
125
+ return bootstrapClass;
126
+ }
127
+ }
128
+ // Mapeamento de valores específicos
129
+ const valueMap = CSS_TO_BOOTSTRAP[property];
130
+ if (valueMap && valueMap[value]) {
131
+ return valueMap[value];
132
+ }
133
+ // Para spacing, converte para classes Bootstrap
134
+ if (['padding', 'margin'].includes(property)) {
135
+ const numValue = parseInt(value);
136
+ if (!isNaN(numValue)) {
137
+ const prefix = property === 'padding' ? 'p' : 'm';
138
+ // Mapeia px para escala Bootstrap (0-5)
139
+ let scale = 0;
140
+ if (numValue <= 4)
141
+ scale = 1;
142
+ else if (numValue <= 8)
143
+ scale = 2;
144
+ else if (numValue <= 16)
145
+ scale = 3;
146
+ else if (numValue <= 24)
147
+ scale = 4;
148
+ else
149
+ scale = 5;
150
+ return `${prefix}-${scale}`;
151
+ }
152
+ }
153
+ // Padding/Margin específicos
154
+ const spacingMap = {
155
+ 'padding-top': 'pt',
156
+ 'padding-bottom': 'pb',
157
+ 'padding-left': 'ps',
158
+ 'padding-right': 'pe',
159
+ 'margin-top': 'mt',
160
+ 'margin-bottom': 'mb',
161
+ 'margin-left': 'ms',
162
+ 'margin-right': 'me',
163
+ };
164
+ if (spacingMap[property]) {
165
+ const numValue = parseInt(value);
166
+ if (!isNaN(numValue)) {
167
+ let scale = 0;
168
+ if (numValue <= 4)
169
+ scale = 1;
170
+ else if (numValue <= 8)
171
+ scale = 2;
172
+ else if (numValue <= 16)
173
+ scale = 3;
174
+ else if (numValue <= 24)
175
+ scale = 4;
176
+ else
177
+ scale = 5;
178
+ return `${spacingMap[property]}-${scale}`;
179
+ }
180
+ }
181
+ // Gap
182
+ if (property === 'gap') {
183
+ const numValue = parseInt(value);
184
+ if (!isNaN(numValue)) {
185
+ let scale = 0;
186
+ if (numValue <= 4)
187
+ scale = 1;
188
+ else if (numValue <= 8)
189
+ scale = 2;
190
+ else if (numValue <= 16)
191
+ scale = 3;
192
+ else if (numValue <= 24)
193
+ scale = 4;
194
+ else
195
+ scale = 5;
196
+ return `gap-${scale}`;
197
+ }
198
+ }
199
+ return null;
200
+ }
201
+ /**
202
+ * Converte estilos para classes Bootstrap
203
+ */
204
+ function generateBootstrapClasses(styles) {
205
+ const classes = [];
206
+ for (const style of styles) {
207
+ const value = style.token ?? style.value;
208
+ const bootstrapClass = cssToBootstrap(style.property, value);
209
+ if (bootstrapClass) {
210
+ classes.push(bootstrapClass);
211
+ }
212
+ }
213
+ return classes;
214
+ }
215
+ /**
216
+ * Gera JSX com classes Bootstrap
217
+ */
218
+ function generateBootstrapJSX(node, styles, indent = 2) {
219
+ const spaces = ' '.repeat(indent);
220
+ const isRoot = indent === 2;
221
+ const nodeStyles = styles.get(`.${node.className}`) ?? [];
222
+ const bootstrapClasses = generateBootstrapClasses(nodeStyles);
223
+ const classStr = bootstrapClasses.join(' ');
224
+ // Props string
225
+ let className;
226
+ if (isRoot) {
227
+ className = `className={\`${classStr} \${className}\`.trim()}`;
228
+ }
229
+ else {
230
+ className = `className="${classStr}"`;
231
+ }
232
+ // Tag
233
+ const tag = node.tag;
234
+ // Children
235
+ if (node.selfClosing) {
236
+ return `${spaces}<${tag} ${className} />`;
237
+ }
238
+ const childrenContent = [];
239
+ for (const child of node.children) {
240
+ if (typeof child === 'string' || (typeof child === 'object' && 'type' in child && child.type === 'text')) {
241
+ const text = typeof child === 'string' ? child : child.value;
242
+ childrenContent.push(`${spaces} {children ?? '${text}'}`);
243
+ }
244
+ else {
245
+ childrenContent.push(generateBootstrapJSX(child, styles, indent + 2));
246
+ }
247
+ }
248
+ if (childrenContent.length === 0) {
249
+ return `${spaces}<${tag} ${className} />`;
250
+ }
251
+ return [
252
+ `${spaces}<${tag} ${className}>`,
253
+ ...childrenContent,
254
+ `${spaces}</${tag}>`,
255
+ ].join('\n');
256
+ }
257
+ /**
258
+ * Gera componente React com Bootstrap
259
+ */
260
+ export function generateBootstrapComponent(ast) {
261
+ // Cria mapa de estilos por selector
262
+ const stylesMap = new Map();
263
+ for (const block of ast.styles) {
264
+ stylesMap.set(block.selector, block.properties);
265
+ }
266
+ // Props interface
267
+ const propsInterface = `export interface I${ast.name}Props {
268
+ children?: ReactNode;
269
+ className?: string;
270
+ }`;
271
+ // JSX
272
+ const jsx = generateBootstrapJSX(ast.jsx, stylesMap);
273
+ // Component
274
+ const component = `export const ${ast.name} = ({
275
+ children,
276
+ className = '',
277
+ }: I${ast.name}Props) => {
278
+ return (
279
+ ${jsx}
280
+ );
281
+ };`;
282
+ return [
283
+ '/**',
284
+ ` * ${ast.name}`,
285
+ ' * Generated by PromptUI (Bootstrap)',
286
+ ' */',
287
+ '',
288
+ "import type { ReactNode } from 'react';",
289
+ '',
290
+ propsInterface,
291
+ '',
292
+ component,
293
+ ].join('\n');
294
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Framework Templates
3
+ * Templates de geração para diferentes frameworks UI
4
+ */
5
+ export type FrameworkType = 'react' | 'mui' | 'tailwind' | 'bootstrap';
6
+ export interface IFrameworkConfig {
7
+ name: FrameworkType;
8
+ displayName: string;
9
+ description: string;
10
+ fileExtension: string;
11
+ styleExtension: string | null;
12
+ imports: string[];
13
+ componentWrapper?: string;
14
+ }
15
+ export declare const FRAMEWORKS: Record<FrameworkType, IFrameworkConfig>;
16
+ export { generateMuiComponent, generateMuiStyles } from './mui.template.js';
17
+ export { generateTailwindComponent, generateTailwindClasses } from './tailwind.template.js';
18
+ export { generateBootstrapComponent } from './bootstrap.template.js';
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/frameworks/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,KAAK,GAAG,UAAU,GAAG,WAAW,CAAC;AAEvE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,aAAa,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAqC9D,CAAC;AAEF,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAC5F,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Framework Templates
3
+ * Templates de geração para diferentes frameworks UI
4
+ */
5
+ export const FRAMEWORKS = {
6
+ react: {
7
+ name: 'react',
8
+ displayName: 'React + SCSS',
9
+ description: 'React components with BEM SCSS styles',
10
+ fileExtension: 'tsx',
11
+ styleExtension: 'scss',
12
+ imports: ["import type { ReactNode } from 'react';"],
13
+ },
14
+ mui: {
15
+ name: 'mui',
16
+ displayName: 'Material UI',
17
+ description: 'React components with MUI sx props and components',
18
+ fileExtension: 'tsx',
19
+ styleExtension: null, // Inline sx props
20
+ imports: [
21
+ "import type { ReactNode } from 'react';",
22
+ "import { Box, Stack, Typography, Button, Card, CardContent } from '@mui/material';",
23
+ "import type { SxProps, Theme } from '@mui/material/styles';",
24
+ ],
25
+ },
26
+ tailwind: {
27
+ name: 'tailwind',
28
+ displayName: 'Tailwind CSS',
29
+ description: 'React components with Tailwind utility classes',
30
+ fileExtension: 'tsx',
31
+ styleExtension: null, // Inline classes
32
+ imports: ["import type { ReactNode } from 'react';"],
33
+ },
34
+ bootstrap: {
35
+ name: 'bootstrap',
36
+ displayName: 'Bootstrap',
37
+ description: 'React components with Bootstrap classes',
38
+ fileExtension: 'tsx',
39
+ styleExtension: null, // Bootstrap classes
40
+ imports: ["import type { ReactNode } from 'react';"],
41
+ },
42
+ };
43
+ export { generateMuiComponent, generateMuiStyles } from './mui.template.js';
44
+ export { generateTailwindComponent, generateTailwindClasses } from './tailwind.template.js';
45
+ export { generateBootstrapComponent } from './bootstrap.template.js';
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Material UI Template
3
+ * Gera componentes React com MUI sx props
4
+ */
5
+ import type { IComponentAST } from '@promptui-lib/core';
6
+ /**
7
+ * Gera componente React com MUI
8
+ */
9
+ export declare function generateMuiComponent(ast: IComponentAST): string;
10
+ /**
11
+ * Gera arquivo de estilos (para MUI, retorna objeto de sx reusáveis)
12
+ */
13
+ export declare function generateMuiStyles(ast: IComponentAST): string;
14
+ //# sourceMappingURL=mui.template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mui.template.d.ts","sourceRoot":"","sources":["../../src/frameworks/mui.template.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAA4B,MAAM,oBAAoB,CAAC;AA6QlF;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CA+C/D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAwB5D"}