@promptui-lib/codegen 0.1.2 → 0.1.4

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/README.md CHANGED
@@ -1,8 +1,4 @@
1
- <p align="center">
2
- <img src="./logo.png" alt="PromptUI Logo" width="200" />
3
- </p>
4
-
5
- <h1 align="center">PromptUI</h1>
1
+ <h1 align="center">🎨 PromptUI</h1>
6
2
 
7
3
  <p align="center">
8
4
  <a href="https://www.npmjs.com/package/@promptui-lib/cli"><img src="https://img.shields.io/npm/v/@promptui-lib/cli.svg" alt="npm version" /></a>
@@ -356,6 +352,92 @@ Create `promptui.config.json`:
356
352
 
357
353
  ---
358
354
 
355
+ ## Figma Support
356
+
357
+ ### What We Extract from Figma
358
+
359
+ | Element | Supported | Notes |
360
+ |---------|-----------|-------|
361
+ | **Colors** | ✅ Yes | RGB, Hex, tokens |
362
+ | **Spacing** | ✅ Yes | Padding, margin, gap |
363
+ | **Typography** | ✅ Yes | Font size, weight, family |
364
+ | **Border Radius** | ✅ Yes | All corners |
365
+ | **Shadows** | ✅ Yes | Drop shadow, inner shadow |
366
+ | **Layout** | ✅ Yes | Auto Layout → Flexbox |
367
+ | **SVG/Icons** | ✅ Yes | Exported as inline SVG |
368
+ | **Images** | ⚠️ Partial | Placeholder generated |
369
+ | **Gradients** | ⚠️ Partial | Linear gradients |
370
+ | **Animations** | ❌ No | Not available via Figma API |
371
+ | **Prototype Links** | ❌ No | Prototype data only |
372
+
373
+ ### Bootstrap Components Mapping
374
+
375
+ Name your Figma frames to auto-map to Bootstrap components:
376
+
377
+ | Figma Frame Name | Bootstrap Output |
378
+ |------------------|------------------|
379
+ | `#Alert` | `<div class="alert">` |
380
+ | `#Badge` | `<span class="badge">` |
381
+ | `#Breadcrumb` | `<nav class="breadcrumb">` |
382
+ | `#Button` | `<button class="btn">` |
383
+ | `#ButtonGroup` | `<div class="btn-group">` |
384
+ | `#Card` | `<div class="card">` |
385
+ | `#Carousel` | `<div class="carousel">` |
386
+ | `#Collapse` | `<div class="collapse">` |
387
+ | `#Dropdown` | `<div class="dropdown">` |
388
+ | `#ListGroup` | `<ul class="list-group">` |
389
+ | `#Modal` | `<div class="modal">` |
390
+ | `#Navbar` | `<nav class="navbar">` |
391
+ | `#Nav` or `#Tabs` | `<ul class="nav">` |
392
+ | `#Offcanvas` | `<div class="offcanvas">` |
393
+ | `#Pagination` | `<nav class="pagination">` |
394
+ | `#Progress` | `<div class="progress">` |
395
+ | `#Spinner` | `<div class="spinner">` |
396
+ | `#Toast` | `<div class="toast">` |
397
+ | `#Tooltip` | `data-bs-toggle="tooltip"` |
398
+
399
+ ### Material UI Components Mapping
400
+
401
+ | Figma Frame Name | MUI Output |
402
+ |------------------|------------|
403
+ | `#Alert` | `<Alert>` |
404
+ | `#Avatar` | `<Avatar>` |
405
+ | `#Badge` | `<Badge>` |
406
+ | `#Breadcrumb` | `<Breadcrumbs>` |
407
+ | `#Button` | `<Button>` |
408
+ | `#Card` | `<Card>` |
409
+ | `#Checkbox` | `<Checkbox>` |
410
+ | `#Chip` | `<Chip>` |
411
+ | `#Dialog` or `#Modal` | `<Dialog>` |
412
+ | `#Drawer` | `<Drawer>` |
413
+ | `#Input` or `#TextField` | `<TextField>` |
414
+ | `#List` | `<List>` |
415
+ | `#Menu` | `<Menu>` |
416
+ | `#Pagination` | `<Pagination>` |
417
+ | `#Progress` | `<LinearProgress>` |
418
+ | `#Radio` | `<Radio>` |
419
+ | `#Select` | `<Select>` |
420
+ | `#Slider` | `<Slider>` |
421
+ | `#Snackbar` | `<Snackbar>` |
422
+ | `#Switch` | `<Switch>` |
423
+ | `#Table` | `<Table>` |
424
+ | `#Tabs` | `<Tabs>` |
425
+ | `#Tooltip` | `<Tooltip>` |
426
+
427
+ ### Form Components
428
+
429
+ | Figma Frame Name | React + SCSS | Bootstrap | MUI |
430
+ |------------------|--------------|-----------|-----|
431
+ | `#Input` | `<input>` | `<input class="form-control">` | `<TextField>` |
432
+ | `#Select` | `<select>` | `<select class="form-select">` | `<Select>` |
433
+ | `#Checkbox` | `<input type="checkbox">` | `<input class="form-check-input">` | `<Checkbox>` |
434
+ | `#Radio` | `<input type="radio">` | `<input class="form-check-input">` | `<Radio>` |
435
+ | `#Switch` | `<input type="checkbox">` | `<div class="form-switch">` | `<Switch>` |
436
+ | `#Textarea` | `<textarea>` | `<textarea class="form-control">` | `<TextField multiline>` |
437
+ | `#FormGroup` | `<div class="form-group">` | `<div class="mb-3">` | `<FormControl>` |
438
+
439
+ ---
440
+
359
441
  ## For Designers
360
442
 
361
443
  ### Figma Rules
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * Bootstrap Template
3
- * Gera componentes React com classes Bootstrap
3
+ * Generates React components with Bootstrap classes
4
4
  */
5
5
  import type { IComponentAST } from '@promptui-lib/core';
6
6
  /**
7
- * Gera componente React com Bootstrap
7
+ * Generates React component with Bootstrap classes
8
8
  */
9
9
  export declare function generateBootstrapComponent(ast: IComponentAST): string;
10
10
  //# sourceMappingURL=bootstrap.template.d.ts.map
@@ -1 +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"}
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;AA2RlF;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAkDrE"}
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * Bootstrap Template
3
- * Gera componentes React com classes Bootstrap
3
+ * Generates React components with Bootstrap classes
4
4
  */
5
+ import { getComponentMapping, extractComponentType } from '../mappings/index.js';
5
6
  /**
6
7
  * Mapeamento de tokens SCSS → Bootstrap classes
7
8
  */
@@ -255,21 +256,45 @@ function generateBootstrapJSX(node, styles, indent = 2) {
255
256
  ].join('\n');
256
257
  }
257
258
  /**
258
- * Gera componente React com Bootstrap
259
+ * Gets Bootstrap-specific tag and classes based on component type
260
+ */
261
+ function getBootstrapMapping(componentName) {
262
+ const componentType = extractComponentType(componentName);
263
+ if (!componentType)
264
+ return null;
265
+ const mapping = getComponentMapping(componentType);
266
+ if (!mapping)
267
+ return null;
268
+ return mapping.bootstrap;
269
+ }
270
+ /**
271
+ * Generates React component with Bootstrap classes
259
272
  */
260
273
  export function generateBootstrapComponent(ast) {
261
- // Cria mapa de estilos por selector
274
+ // Create styles map by selector
262
275
  const stylesMap = new Map();
263
276
  for (const block of ast.styles) {
264
277
  stylesMap.set(block.selector, block.properties);
265
278
  }
279
+ // Check for component mapping
280
+ const mapping = getBootstrapMapping(ast.name);
266
281
  // Props interface
267
282
  const propsInterface = `export interface I${ast.name}Props {
268
283
  children?: ReactNode;
269
284
  className?: string;
270
285
  }`;
271
- // JSX
272
- const jsx = generateBootstrapJSX(ast.jsx, stylesMap);
286
+ // JSX - use mapping if available
287
+ let jsx;
288
+ if (mapping) {
289
+ const baseClasses = mapping.classes.join(' ');
290
+ const extraAttrs = mapping.wrapper ? ` ${mapping.wrapper}` : '';
291
+ jsx = ` <${mapping.tag} className={\`${baseClasses} \${className}\`.trim()}${extraAttrs}>
292
+ {children}
293
+ </${mapping.tag}>`;
294
+ }
295
+ else {
296
+ jsx = generateBootstrapJSX(ast.jsx, stylesMap);
297
+ }
273
298
  // Component
274
299
  const component = `export const ${ast.name} = ({
275
300
  children,
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * Material UI Template
3
- * Gera componentes React com MUI sx props
3
+ * Generates React components with MUI components and sx props
4
4
  */
5
5
  import type { IComponentAST } from '@promptui-lib/core';
6
6
  /**
7
- * Gera componente React com MUI
7
+ * Generates React component with MUI
8
8
  */
9
9
  export declare function generateMuiComponent(ast: IComponentAST): string;
10
10
  /**
@@ -1 +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"}
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;AA2RlF;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAgE/D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAwB5D"}
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * Material UI Template
3
- * Gera componentes React com MUI sx props
3
+ * Generates React components with MUI components and sx props
4
4
  */
5
+ import { getComponentMapping, extractComponentType } from '../mappings/index.js';
5
6
  /**
6
7
  * Mapeamento de tokens SCSS → MUI theme
7
8
  */
@@ -232,22 +233,47 @@ function generateMuiJSX(node, styles, indent = 2) {
232
233
  ].join('\n');
233
234
  }
234
235
  /**
235
- * Gera componente React com MUI
236
+ * Gets MUI component mapping based on component name
237
+ */
238
+ function getMuiMapping(componentName) {
239
+ const componentType = extractComponentType(componentName);
240
+ if (!componentType)
241
+ return null;
242
+ const mapping = getComponentMapping(componentType);
243
+ if (!mapping)
244
+ return null;
245
+ return mapping.mui;
246
+ }
247
+ /**
248
+ * Generates React component with MUI
236
249
  */
237
250
  export function generateMuiComponent(ast) {
238
- // Cria mapa de estilos por selector
251
+ // Create styles map by selector
239
252
  const stylesMap = new Map();
240
253
  for (const block of ast.styles) {
241
254
  stylesMap.set(block.selector, block.properties);
242
255
  }
256
+ // Check for component mapping
257
+ const mapping = getMuiMapping(ast.name);
243
258
  // Props interface
244
259
  const propsInterface = `export interface I${ast.name}Props {
245
260
  children?: ReactNode;
246
261
  className?: string;
247
262
  sx?: SxProps<Theme>;
248
263
  }`;
249
- // JSX
250
- const jsx = generateMuiJSX(ast.jsx, stylesMap);
264
+ // JSX - use mapping if available
265
+ let jsx;
266
+ if (mapping) {
267
+ const propsStr = mapping.props
268
+ ? Object.entries(mapping.props).map(([k, v]) => `${k}="${v}"`).join(' ')
269
+ : '';
270
+ jsx = ` <${mapping.component} ${propsStr}>
271
+ {children}
272
+ </${mapping.component}>`;
273
+ }
274
+ else {
275
+ jsx = generateMuiJSX(ast.jsx, stylesMap);
276
+ }
251
277
  // Component
252
278
  const component = `export const ${ast.name} = ({
253
279
  children,
@@ -258,12 +284,15 @@ export function generateMuiComponent(ast) {
258
284
  ${jsx}
259
285
  );
260
286
  };`;
261
- // Imports
262
- const imports = [
287
+ // Imports - include component-specific imports
288
+ const baseImports = [
263
289
  "import type { ReactNode } from 'react';",
264
290
  "import { Box, Stack, Typography, Button } from '@mui/material';",
265
291
  "import type { SxProps, Theme } from '@mui/material/styles';",
266
292
  ];
293
+ const imports = mapping?.imports
294
+ ? [...new Set([...baseImports, ...mapping.imports])]
295
+ : baseImports;
267
296
  return [
268
297
  '/**',
269
298
  ` * ${ast.name}`,
package/dist/index.d.ts CHANGED
@@ -5,4 +5,5 @@
5
5
  export * from './generators/index.js';
6
6
  export * from './writers/index.js';
7
7
  export * from './frameworks/index.js';
8
+ export * from './mappings/index.js';
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -5,3 +5,4 @@
5
5
  export * from './generators/index.js';
6
6
  export * from './writers/index.js';
7
7
  export * from './frameworks/index.js';
8
+ export * from './mappings/index.js';
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Component Mappings
3
+ * Maps Figma frame names to framework-specific components
4
+ */
5
+ export interface IComponentMapping {
6
+ /** Bootstrap classes/structure */
7
+ bootstrap: {
8
+ tag: string;
9
+ classes: string[];
10
+ wrapper?: string;
11
+ children?: string;
12
+ };
13
+ /** MUI component */
14
+ mui: {
15
+ component: string;
16
+ props?: Record<string, string>;
17
+ imports?: string[];
18
+ };
19
+ /** Tailwind classes */
20
+ tailwind: {
21
+ tag: string;
22
+ classes: string[];
23
+ };
24
+ /** React + SCSS (custom implementation) */
25
+ scss: {
26
+ tag: string;
27
+ baseClass: string;
28
+ /** If true, generates animation keyframes */
29
+ hasAnimation?: boolean;
30
+ animationName?: string;
31
+ };
32
+ /** Flutter widget */
33
+ flutter: {
34
+ widget: string;
35
+ props?: Record<string, string>;
36
+ };
37
+ /** SwiftUI view */
38
+ swiftui: {
39
+ view: string;
40
+ modifiers?: string[];
41
+ };
42
+ }
43
+ /**
44
+ * Component mappings by name
45
+ * Key is the component name (without #), case-insensitive matching
46
+ */
47
+ export declare const COMPONENT_MAPPINGS: Record<string, IComponentMapping>;
48
+ /**
49
+ * Get component mapping by name (case-insensitive)
50
+ */
51
+ export declare function getComponentMapping(name: string): IComponentMapping | undefined;
52
+ /**
53
+ * Check if a component name has a mapping
54
+ */
55
+ export declare function hasComponentMapping(name: string): boolean;
56
+ /**
57
+ * Extract component type from name
58
+ * e.g., "#ButtonPrimary" -> "button", "#CardProduct" -> "card"
59
+ */
60
+ export declare function extractComponentType(name: string): string | null;
61
+ //# sourceMappingURL=component-mappings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-mappings.d.ts","sourceRoot":"","sources":["../../src/mappings/component-mappings.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,iBAAiB;IAChC,kCAAkC;IAClC,SAAS,EAAE;QACT,GAAG,EAAE,MAAM,CAAC;QACZ,OAAO,EAAE,MAAM,EAAE,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,oBAAoB;IACpB,GAAG,EAAE;QACH,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;IACF,uBAAuB;IACvB,QAAQ,EAAE;QACR,GAAG,EAAE,MAAM,CAAC;QACZ,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;IACF,2CAA2C;IAC3C,IAAI,EAAE;QACJ,GAAG,EAAE,MAAM,CAAC;QACZ,SAAS,EAAE,MAAM,CAAC;QAClB,6CAA6C;QAC7C,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,qBAAqB;IACrB,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAChC,CAAC;IACF,mBAAmB;IACnB,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;KACtB,CAAC;CACH;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAwkChE,CAAC;AAEF;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAG/E;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYhE"}