@promptui-lib/codegen 0.1.4 → 0.1.6

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,268 @@
1
+ /**
2
+ * Ant Design Template
3
+ * Generates React components with Ant Design components
4
+ */
5
+ import { getComponentMapping, extractComponentType } from '../mappings/index.js';
6
+ /**
7
+ * Token mapping for Ant Design
8
+ */
9
+ const TOKEN_TO_ANTD = {
10
+ // Colors (using CSS variables from Ant Design 5.x)
11
+ '$color-primary': 'var(--ant-color-primary)',
12
+ '$color-secondary': 'var(--ant-color-text-secondary)',
13
+ '$color-success': 'var(--ant-color-success)',
14
+ '$color-error': 'var(--ant-color-error)',
15
+ '$color-warning': 'var(--ant-color-warning)',
16
+ '$color-text-primary': 'var(--ant-color-text)',
17
+ '$color-text-secondary': 'var(--ant-color-text-secondary)',
18
+ '$color-bg-primary': 'var(--ant-color-bg-container)',
19
+ '$color-bg-secondary': 'var(--ant-color-bg-layout)',
20
+ // Spacing
21
+ '$spacing-xs': '4px',
22
+ '$spacing-sm': '8px',
23
+ '$spacing-md': '16px',
24
+ '$spacing-lg': '24px',
25
+ '$spacing-xl': '32px',
26
+ '$spacing-2xl': '48px',
27
+ // Border radius
28
+ '$radius-none': '0',
29
+ '$radius-small': 'var(--ant-border-radius-sm)',
30
+ '$radius-medium': 'var(--ant-border-radius)',
31
+ '$radius-large': 'var(--ant-border-radius-lg)',
32
+ '$radius-xl': '16px',
33
+ '$radius-full': '50%',
34
+ // Typography
35
+ '$font-size-xs': 'var(--ant-font-size-sm)',
36
+ '$font-size-sm': 'var(--ant-font-size)',
37
+ '$font-size-md': 'var(--ant-font-size-lg)',
38
+ '$font-size-lg': 'var(--ant-font-size-xl)',
39
+ '$font-size-xl': 'var(--ant-font-size-heading-4)',
40
+ '$font-size-2xl': 'var(--ant-font-size-heading-3)',
41
+ // Shadows
42
+ '$shadow-sm': 'var(--ant-box-shadow-tertiary)',
43
+ '$shadow-md': 'var(--ant-box-shadow-secondary)',
44
+ '$shadow-lg': 'var(--ant-box-shadow)',
45
+ };
46
+ /**
47
+ * Get Ant Design component mapping from frame name
48
+ */
49
+ function getAntdMapping(componentName) {
50
+ const componentType = extractComponentType(componentName);
51
+ if (!componentType)
52
+ return null;
53
+ const mapping = getComponentMapping(componentType);
54
+ if (!mapping)
55
+ return null;
56
+ return mapping.antd;
57
+ }
58
+ /**
59
+ * Convert token to Ant Design value
60
+ */
61
+ function tokenToAntd(value) {
62
+ if (value.startsWith('$')) {
63
+ return TOKEN_TO_ANTD[value] || value;
64
+ }
65
+ return value;
66
+ }
67
+ /**
68
+ * Convert style blocks to inline style object
69
+ */
70
+ function stylesToInline(styles) {
71
+ const styleEntries = [];
72
+ styles.forEach(block => {
73
+ block.properties.forEach(prop => {
74
+ const key = prop.property.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
75
+ const value = tokenToAntd(prop.value);
76
+ styleEntries.push(`${key}: '${value}'`);
77
+ });
78
+ });
79
+ return styleEntries.length > 0 ? `{{ ${styleEntries.join(', ')} }}` : '{}';
80
+ }
81
+ /**
82
+ * Check if a child is a text node
83
+ */
84
+ function isTextNode(child) {
85
+ return 'type' in child && child.type === 'text';
86
+ }
87
+ /**
88
+ * Check if a child is a JSX node
89
+ */
90
+ function isJSXNode(child) {
91
+ return 'tag' in child;
92
+ }
93
+ /**
94
+ * Collect all imports needed for the component
95
+ */
96
+ function collectImports(node, imports) {
97
+ const mapping = getAntdMapping(node.tag);
98
+ if (mapping?.imports) {
99
+ mapping.imports.forEach(imp => imports.add(imp));
100
+ }
101
+ if (node.children) {
102
+ node.children.forEach(child => {
103
+ if (isJSXNode(child)) {
104
+ collectImports(child, imports);
105
+ }
106
+ });
107
+ }
108
+ }
109
+ /**
110
+ * Generate JSX for a node
111
+ */
112
+ function generateJSX(node, indent = 2) {
113
+ const spaces = ' '.repeat(indent);
114
+ const mapping = getAntdMapping(node.tag);
115
+ // Determine tag/component to use
116
+ let tagName = node.tag || 'div';
117
+ let additionalProps = [];
118
+ if (mapping) {
119
+ tagName = mapping.component;
120
+ if (mapping.props) {
121
+ additionalProps = Object.entries(mapping.props).map(([key, value]) => {
122
+ // Handle boolean values
123
+ if (value === 'true' || value === 'false') {
124
+ return value === 'true' ? key : `${key}={false}`;
125
+ }
126
+ return `${key}="${value}"`;
127
+ });
128
+ }
129
+ }
130
+ // Generate className if exists
131
+ const classAttr = node.className ? ` className="${node.className}"` : '';
132
+ // Generate props from node.props
133
+ const nodePropsStr = Object.entries(node.props || {})
134
+ .map(([key, value]) => {
135
+ if (typeof value === 'boolean') {
136
+ return value ? key : `${key}={false}`;
137
+ }
138
+ if (typeof value === 'string') {
139
+ return `${key}="${value}"`;
140
+ }
141
+ return '';
142
+ })
143
+ .filter(Boolean)
144
+ .join(' ');
145
+ // Additional props string
146
+ const propsStr = [...additionalProps, nodePropsStr].filter(Boolean).join(' ');
147
+ const propsOutput = propsStr ? ' ' + propsStr : '';
148
+ // Handle children
149
+ if (node.children && node.children.length > 0) {
150
+ const childrenJSX = node.children
151
+ .map(child => {
152
+ if (isTextNode(child)) {
153
+ return `${spaces} ${child.value}`;
154
+ }
155
+ if (isJSXNode(child)) {
156
+ return generateJSX(child, indent + 2);
157
+ }
158
+ return '';
159
+ })
160
+ .filter(Boolean)
161
+ .join('\n');
162
+ return `${spaces}<${tagName}${propsOutput}${classAttr}>\n${childrenJSX}\n${spaces}</${tagName}>`;
163
+ }
164
+ else if (node.selfClosing) {
165
+ return `${spaces}<${tagName}${propsOutput}${classAttr} />`;
166
+ }
167
+ else {
168
+ return `${spaces}<${tagName}${propsOutput}${classAttr}></${tagName}>`;
169
+ }
170
+ }
171
+ /**
172
+ * Generate complete Ant Design component
173
+ */
174
+ export function generateAntdComponent(ast) {
175
+ const { name, props, jsx, styles } = ast;
176
+ // Collect all imports
177
+ const imports = new Set();
178
+ imports.add("import React from 'react';");
179
+ collectImports(jsx, imports);
180
+ // Generate props interface
181
+ const propsInterface = props && props.length > 0
182
+ ? `interface ${name}Props {\n${props.map(p => ` ${p.name}${p.required ? '' : '?'}: ${p.type};`).join('\n')}\n}\n\n`
183
+ : '';
184
+ // Generate component
185
+ const propsParam = props && props.length > 0 ? `{ ${props.map(p => p.name).join(', ')} }: ${name}Props` : '';
186
+ const jsxContent = generateJSX(jsx);
187
+ // Generate style object if styles exist
188
+ const styleSection = styles && styles.length > 0
189
+ ? `\nconst styles = ${stylesToInline(styles)};\n`
190
+ : '';
191
+ return `${Array.from(imports).join('\n')}
192
+ ${styleSection}
193
+ ${propsInterface}export const ${name} = (${propsParam}) => {
194
+ return (
195
+ ${jsxContent}
196
+ );
197
+ };
198
+
199
+ export default ${name};
200
+ `;
201
+ }
202
+ /**
203
+ * Generate Ant Design ConfigProvider wrapper with theme
204
+ */
205
+ export function generateAntdThemeConfig(colors) {
206
+ return `import { ConfigProvider } from 'antd';
207
+
208
+ const theme = {
209
+ token: {
210
+ colorPrimary: '${colors.primary || '#1677ff'}',
211
+ colorSuccess: '${colors.success || '#52c41a'}',
212
+ colorWarning: '${colors.warning || '#faad14'}',
213
+ colorError: '${colors.error || '#ff4d4f'}',
214
+ colorInfo: '${colors.info || '#1677ff'}',
215
+ borderRadius: 6,
216
+ },
217
+ };
218
+
219
+ export const ThemeProvider = ({ children }: { children: React.ReactNode }) => (
220
+ <ConfigProvider theme={theme}>
221
+ {children}
222
+ </ConfigProvider>
223
+ );
224
+ `;
225
+ }
226
+ /**
227
+ * Generate complete page with Ant Design Layout
228
+ */
229
+ export function generateAntdLayout(ast) {
230
+ const { name } = ast;
231
+ return `import React from 'react';
232
+ import { Layout, Menu, theme } from 'antd';
233
+
234
+ const { Header, Content, Footer, Sider } = Layout;
235
+
236
+ export const ${name} = () => {
237
+ const {
238
+ token: { colorBgContainer, borderRadiusLG },
239
+ } = theme.useToken();
240
+
241
+ return (
242
+ <Layout style={{ minHeight: '100vh' }}>
243
+ <Header style={{ display: 'flex', alignItems: 'center' }}>
244
+ <div className="logo" />
245
+ <Menu theme="dark" mode="horizontal" defaultSelectedKeys={['1']} />
246
+ </Header>
247
+ <Content style={{ padding: '0 48px' }}>
248
+ <div
249
+ style={{
250
+ background: colorBgContainer,
251
+ minHeight: 280,
252
+ padding: 24,
253
+ borderRadius: borderRadiusLG,
254
+ }}
255
+ >
256
+ {/* Content here */}
257
+ </div>
258
+ </Content>
259
+ <Footer style={{ textAlign: 'center' }}>
260
+ Created with PromptUI
261
+ </Footer>
262
+ </Layout>
263
+ );
264
+ };
265
+
266
+ export default ${name};
267
+ `;
268
+ }
@@ -2,7 +2,7 @@
2
2
  * Framework Templates
3
3
  * Templates for generating different UI frameworks
4
4
  */
5
- export type FrameworkType = 'react' | 'mui' | 'tailwind' | 'bootstrap' | 'flutter' | 'swiftui';
5
+ export type FrameworkType = 'react' | 'mui' | 'antd' | 'tailwind' | 'bootstrap' | 'flutter' | 'swiftui';
6
6
  export interface IFrameworkConfig {
7
7
  name: FrameworkType;
8
8
  displayName: string;
@@ -14,6 +14,7 @@ export interface IFrameworkConfig {
14
14
  }
15
15
  export declare const FRAMEWORKS: Record<FrameworkType, IFrameworkConfig>;
16
16
  export { generateMuiComponent, generateMuiStyles } from './mui.template.js';
17
+ export { generateAntdComponent, generateAntdThemeConfig, generateAntdLayout } from './antd.template.js';
17
18
  export { generateTailwindComponent, generateTailwindClasses } from './tailwind.template.js';
18
19
  export { generateBootstrapComponent } from './bootstrap.template.js';
19
20
  export { generateFlutterComponent } from './flutter.template.js';
@@ -1 +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,GAAG,SAAS,GAAG,SAAS,CAAC;AAE/F,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,CAqD9D,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;AACrE,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC"}
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,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,CAAC;AAExG,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,CAgE9D,CAAC;AAEF,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxG,OAAO,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAC5F,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -23,6 +23,17 @@ export const FRAMEWORKS = {
23
23
  "import type { SxProps, Theme } from '@mui/material/styles';",
24
24
  ],
25
25
  },
26
+ antd: {
27
+ name: 'antd',
28
+ displayName: 'Ant Design',
29
+ description: 'React components with Ant Design components',
30
+ fileExtension: 'tsx',
31
+ styleExtension: null, // Inline styles
32
+ imports: [
33
+ "import React from 'react';",
34
+ "import { Button, Card, Input, Select, Table, Modal, Form } from 'antd';",
35
+ ],
36
+ },
26
37
  tailwind: {
27
38
  name: 'tailwind',
28
39
  displayName: 'Tailwind CSS',
@@ -57,6 +68,7 @@ export const FRAMEWORKS = {
57
68
  },
58
69
  };
59
70
  export { generateMuiComponent, generateMuiStyles } from './mui.template.js';
71
+ export { generateAntdComponent, generateAntdThemeConfig, generateAntdLayout } from './antd.template.js';
60
72
  export { generateTailwindComponent, generateTailwindClasses } from './tailwind.template.js';
61
73
  export { generateBootstrapComponent } from './bootstrap.template.js';
62
74
  export { generateFlutterComponent } from './flutter.template.js';
package/dist/index.d.ts CHANGED
@@ -6,4 +6,5 @@ export * from './generators/index.js';
6
6
  export * from './writers/index.js';
7
7
  export * from './frameworks/index.js';
8
8
  export * from './mappings/index.js';
9
+ export * from './detection/index.js';
9
10
  //# 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;AACtC,cAAc,qBAAqB,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;AACpC,cAAc,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -6,3 +6,4 @@ export * from './generators/index.js';
6
6
  export * from './writers/index.js';
7
7
  export * from './frameworks/index.js';
8
8
  export * from './mappings/index.js';
9
+ export * from './detection/index.js';
@@ -16,6 +16,12 @@ export interface IComponentMapping {
16
16
  props?: Record<string, string>;
17
17
  imports?: string[];
18
18
  };
19
+ /** Ant Design component */
20
+ antd: {
21
+ component: string;
22
+ props?: Record<string, string>;
23
+ imports?: string[];
24
+ };
19
25
  /** Tailwind classes */
20
26
  tailwind: {
21
27
  tag: string;
@@ -1 +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"}
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,2BAA2B;IAC3B,IAAI,EAAE;QACJ,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,CAmkDhE,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"}