@bravostudioai/react 0.1.28 → 0.1.29
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 +553 -0
- package/package.json +1 -1
- package/src/codegen/generator.ts +74 -0
- package/src/codegen/parser.ts +47 -707
- package/src/codegen/propQualification.ts +284 -0
- package/src/components/EncoreApp.tsx +92 -540
- package/src/components/EncoreContextProviders.tsx +60 -0
- package/src/hooks/useFontLoader.ts +84 -0
- package/src/hooks/usePusherUpdates.ts +14 -23
- package/src/hooks/useRepeatingContainers.ts +147 -0
- package/src/index.ts +4 -1
- package/src/lib/dataPatching.ts +78 -0
- package/src/lib/dynamicModules.ts +8 -9
- package/src/lib/fetcher.ts +2 -9
- package/src/lib/logger.ts +53 -0
- package/src/lib/moduleRegistry.ts +3 -1
- package/src/stores/useEncoreState.ts +62 -2
- package/src/version.ts +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,553 @@
|
|
|
1
|
+
# @bravostudioai/react
|
|
2
|
+
|
|
3
|
+
> Transform your Encore Studio designs into production-ready, type-safe React components in seconds.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@bravostudioai/react)
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
7
|
+
[](https://reactjs.org/)
|
|
8
|
+
|
|
9
|
+
**What you get:**
|
|
10
|
+
- 🎨 Design in Encore Studio → Generate typed React components
|
|
11
|
+
- 🔒 100% TypeScript with full IntelliSense support
|
|
12
|
+
- 🚀 Zero configuration, instant productivity
|
|
13
|
+
- 📝 Auto-generated documentation for every component
|
|
14
|
+
- 🎯 Human-readable prop names, not cryptic IDs
|
|
15
|
+
|
|
16
|
+
**At a Glance:**
|
|
17
|
+
|
|
18
|
+
| Feature | Included |
|
|
19
|
+
|---------|----------|
|
|
20
|
+
| TypeScript Interfaces | ✅ Yes |
|
|
21
|
+
| Form Handling | ✅ Yes |
|
|
22
|
+
| Event Handlers | ✅ Yes |
|
|
23
|
+
| List/Array Props | ✅ Yes |
|
|
24
|
+
| Dropdown Controls | ✅ Yes |
|
|
25
|
+
| Auto Documentation | ✅ Yes |
|
|
26
|
+
| Production Bundles | ✅ Yes |
|
|
27
|
+
| Live Updates | ✅ Yes (via Pusher) |
|
|
28
|
+
|
|
29
|
+
## Table of Contents
|
|
30
|
+
|
|
31
|
+
- [What is Encore Studio?](#what-is-encore-studio)
|
|
32
|
+
- [Perfect For](#perfect-for)
|
|
33
|
+
- [Installation](#installation)
|
|
34
|
+
- [Quick Start](#quick-start)
|
|
35
|
+
- [What Gets Generated](#what-gets-generated)
|
|
36
|
+
- [Real-World Examples](#real-world-examples)
|
|
37
|
+
- [How It Works](#how-it-works)
|
|
38
|
+
- [CLI Commands](#cli-commands)
|
|
39
|
+
- [Advanced Features](#advanced-features)
|
|
40
|
+
- [Package Exports](#package-exports)
|
|
41
|
+
- [Troubleshooting](#troubleshooting)
|
|
42
|
+
- [Support](#support)
|
|
43
|
+
|
|
44
|
+
## Why This Matters
|
|
45
|
+
|
|
46
|
+
Stop manually translating designs into code. Stop writing boilerplate. Stop maintaining prop interfaces that fall out of sync with your designs.
|
|
47
|
+
|
|
48
|
+
With `@bravostudioai/react`, you design in Encore Studio and instantly get:
|
|
49
|
+
|
|
50
|
+
- **Type-safe React components** with full TypeScript interfaces
|
|
51
|
+
- **Intelligent prop detection** that understands your data bindings, forms, buttons, and interactive elements
|
|
52
|
+
- **Human-readable APIs** with clean, semantic prop names (not cryptic IDs)
|
|
53
|
+
- **Automatic event handlers** for clicks, form submissions, and state changes
|
|
54
|
+
- **Self-documenting code** with README files for every component
|
|
55
|
+
- **Zero manual configuration** - the generator understands your design intent
|
|
56
|
+
|
|
57
|
+
## What is Encore Studio?
|
|
58
|
+
|
|
59
|
+
Encore Studio is a design-to-code platform that lets you create mobile and web app interfaces visually. This package bridges the gap between your Encore Studio designs and your React application, automatically generating type-safe components from your visual designs.
|
|
60
|
+
|
|
61
|
+
## Perfect For
|
|
62
|
+
|
|
63
|
+
✅ **Design teams** who want to iterate quickly without waiting for developers
|
|
64
|
+
✅ **Full-stack developers** building prototypes or MVPs fast
|
|
65
|
+
✅ **Product teams** who need to validate designs with real functionality
|
|
66
|
+
✅ **Agencies** shipping client projects with tight deadlines
|
|
67
|
+
✅ **Startups** optimizing for speed without sacrificing code quality
|
|
68
|
+
|
|
69
|
+
**Not ideal for:**
|
|
70
|
+
❌ Projects without Encore Studio designs
|
|
71
|
+
❌ Teams needing 100% custom, hand-coded components
|
|
72
|
+
|
|
73
|
+
## Installation
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
npm install @bravostudioai/react
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Requirements:**
|
|
80
|
+
- Node.js 16+
|
|
81
|
+
- React 18.2.0+ or 19.0.0+
|
|
82
|
+
- TypeScript (recommended)
|
|
83
|
+
|
|
84
|
+
## Quick Start
|
|
85
|
+
|
|
86
|
+
### Generate Components from Your Encore Studio App
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# Generate all pages from an app
|
|
90
|
+
npx encore-lib generate <appId> ./src/components
|
|
91
|
+
|
|
92
|
+
# Generate a specific page
|
|
93
|
+
npx encore-lib generate <appId> <pageId> ./src/components
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
This creates a folder structure like:
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
src/components/
|
|
100
|
+
YourApp/
|
|
101
|
+
PageName/
|
|
102
|
+
index.tsx # Type-safe React component
|
|
103
|
+
README.md # Complete documentation
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Use Your Generated Component
|
|
107
|
+
|
|
108
|
+
```tsx
|
|
109
|
+
import { PageName } from './components/YourApp/PageName';
|
|
110
|
+
|
|
111
|
+
function App() {
|
|
112
|
+
return (
|
|
113
|
+
<PageName
|
|
114
|
+
headline="Welcome to our app"
|
|
115
|
+
items={[
|
|
116
|
+
{ title: "Item 1", image: "https://..." },
|
|
117
|
+
{ title: "Item 2", image: "https://..." }
|
|
118
|
+
]}
|
|
119
|
+
onSubmitClick={() => console.log('Submitted!')}
|
|
120
|
+
/>
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
That's it. No configuration files. No manual prop mapping. Just clean, typed React components.
|
|
126
|
+
|
|
127
|
+
## What Gets Generated
|
|
128
|
+
|
|
129
|
+
### 1. Type-Safe Component Interfaces
|
|
130
|
+
|
|
131
|
+
Every data binding, form input, and interactive element in your design becomes a typed prop:
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
export interface SalaryCalculatorProps {
|
|
135
|
+
// Data bindings from your design
|
|
136
|
+
estimatedCost?: string;
|
|
137
|
+
|
|
138
|
+
// Dropdown controls
|
|
139
|
+
contractType?: string;
|
|
140
|
+
contractTypeOptions?: Array<string | { value: string; label: string }>;
|
|
141
|
+
onContractTypeChange?: (value: string) => void;
|
|
142
|
+
|
|
143
|
+
// Button actions
|
|
144
|
+
onBookButtonClick?: () => void;
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### 2. Smart List/Repeater Support
|
|
149
|
+
|
|
150
|
+
Repeating containers become typed array props:
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
export interface TimelineItem {
|
|
154
|
+
title: string;
|
|
155
|
+
description: string;
|
|
156
|
+
image: string;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export interface PageProps {
|
|
160
|
+
timeline: TimelineItem[];
|
|
161
|
+
timelineCurrentIndex?: number;
|
|
162
|
+
onTimelineIndexChange?: (index: number) => void;
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Use it like this:
|
|
167
|
+
|
|
168
|
+
```tsx
|
|
169
|
+
<Page
|
|
170
|
+
timeline={[
|
|
171
|
+
{ title: "Step 1", description: "...", image: "..." },
|
|
172
|
+
{ title: "Step 2", description: "...", image: "..." }
|
|
173
|
+
]}
|
|
174
|
+
timelineCurrentIndex={currentSlide}
|
|
175
|
+
onTimelineIndexChange={setCurrentSlide}
|
|
176
|
+
/>
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### 3. Complete Form Handling
|
|
180
|
+
|
|
181
|
+
Forms get typed interfaces and submission callbacks:
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
export interface ContactFormData {
|
|
185
|
+
name: string;
|
|
186
|
+
email: string;
|
|
187
|
+
message: string;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export interface PageProps {
|
|
191
|
+
onContactFormSubmit?: (formData: ContactFormData) => void;
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Your form handler receives clean, typed data:
|
|
196
|
+
|
|
197
|
+
```tsx
|
|
198
|
+
<Page
|
|
199
|
+
onContactFormSubmit={(data) => {
|
|
200
|
+
console.log(data.name); // Type-safe!
|
|
201
|
+
console.log(data.email); // Type-safe!
|
|
202
|
+
console.log(data.message); // Type-safe!
|
|
203
|
+
}}
|
|
204
|
+
/>
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### 4. Comprehensive Documentation
|
|
208
|
+
|
|
209
|
+
Every component includes a README with:
|
|
210
|
+
|
|
211
|
+
- Complete prop documentation
|
|
212
|
+
- Type information for every prop
|
|
213
|
+
- Usage examples
|
|
214
|
+
- Component metadata (App ID, Page ID)
|
|
215
|
+
|
|
216
|
+
## Real-World Examples
|
|
217
|
+
|
|
218
|
+
### Example 1: Interactive Salary Calculator
|
|
219
|
+
|
|
220
|
+
A salary calculator with multiple dropdowns and a submit button:
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
export interface DeelSalaryCalculatorProps {
|
|
224
|
+
estimatedCost?: string;
|
|
225
|
+
|
|
226
|
+
// Three interconnected dropdowns
|
|
227
|
+
contractTypeSelectInput?: string;
|
|
228
|
+
contractTypeSelectInputOptions?: Array<string | { value: string; label: string }>;
|
|
229
|
+
onContractTypeSelectInputChange?: (value: string) => void;
|
|
230
|
+
|
|
231
|
+
contractCountrySelectInput?: string;
|
|
232
|
+
contractCountrySelectInputOptions?: Array<string | { value: string; label: string }>;
|
|
233
|
+
onContractCountrySelectInputChange?: (value: string) => void;
|
|
234
|
+
|
|
235
|
+
contractSalarySelectInput?: string;
|
|
236
|
+
contractSalarySelectInputOptions?: Array<string | { value: string; label: string }>;
|
|
237
|
+
onContractSalarySelectInputChange?: (value: string) => void;
|
|
238
|
+
|
|
239
|
+
onBookButtonClick?: () => void;
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
**Using it in your app:**
|
|
244
|
+
|
|
245
|
+
```tsx
|
|
246
|
+
function SalaryCalculator() {
|
|
247
|
+
const [contractType, setContractType] = useState('full-time');
|
|
248
|
+
const [country, setCountry] = useState('US');
|
|
249
|
+
const [salary, setSalary] = useState('100000');
|
|
250
|
+
|
|
251
|
+
return (
|
|
252
|
+
<DeelSalaryCalculator
|
|
253
|
+
contractTypeSelectInput={contractType}
|
|
254
|
+
contractTypeSelectInputOptions={['full-time', 'contractor', 'part-time']}
|
|
255
|
+
onContractTypeSelectInputChange={setContractType}
|
|
256
|
+
contractCountrySelectInput={country}
|
|
257
|
+
contractCountrySelectInputOptions={['US', 'UK', 'CA', 'AU']}
|
|
258
|
+
onContractCountrySelectInputChange={setCountry}
|
|
259
|
+
contractSalarySelectInput={salary}
|
|
260
|
+
contractSalarySelectInputOptions={['50000', '75000', '100000', '150000']}
|
|
261
|
+
onContractSalarySelectInputChange={setSalary}
|
|
262
|
+
onBookButtonClick={() => console.log('Booking consultation')}
|
|
263
|
+
/>
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Example 2: Content Sections with Data Bindings
|
|
269
|
+
|
|
270
|
+
A simple layout with text content:
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
export interface ContentSectionProps {
|
|
274
|
+
headline?: string;
|
|
275
|
+
topline?: string;
|
|
276
|
+
line1?: string;
|
|
277
|
+
line2?: string;
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
**Using it in your app:**
|
|
282
|
+
|
|
283
|
+
```tsx
|
|
284
|
+
<ContentSection
|
|
285
|
+
headline="Transform Your Business"
|
|
286
|
+
topline="Introducing Our New Platform"
|
|
287
|
+
line1="Built for modern teams"
|
|
288
|
+
line2="Scales with your growth"
|
|
289
|
+
/>
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
Simple, clean props that map directly to your design's data bindings.
|
|
293
|
+
|
|
294
|
+
## How It Works
|
|
295
|
+
|
|
296
|
+
The generator intelligently analyzes your Encore Studio pages and:
|
|
297
|
+
|
|
298
|
+
1. **Detects data bindings** - Any component tagged with `encore:data` becomes a prop
|
|
299
|
+
2. **Identifies repeating containers** - Lists and sliders become array props with typed items
|
|
300
|
+
3. **Finds forms** - Input groups become typed form data interfaces
|
|
301
|
+
4. **Discovers interactive elements** - Buttons, selects, and inputs get event handlers
|
|
302
|
+
5. **Generates human-readable names** - Component names become `headline`, not `component_01ABC123`
|
|
303
|
+
|
|
304
|
+
## CLI Commands
|
|
305
|
+
|
|
306
|
+
### Generate Components
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
# Generate all pages from an app
|
|
310
|
+
npx encore-lib generate <appId> <outputPath>
|
|
311
|
+
|
|
312
|
+
# Generate a specific page
|
|
313
|
+
npx encore-lib generate <appId> <pageId> <outputPath>
|
|
314
|
+
|
|
315
|
+
# Generate with bundled production data (offline mode)
|
|
316
|
+
npx encore-lib generate <appId> <pageId> <outputPath> --production
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Download Raw Data
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
# Download page data for inspection
|
|
323
|
+
npx encore-lib download <appId> <pageId> <targetPath>
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
## Environment Variables
|
|
327
|
+
|
|
328
|
+
Configure the Encore Studio API endpoint:
|
|
329
|
+
|
|
330
|
+
```bash
|
|
331
|
+
APPS_SERVICE_URL=https://your-custom-endpoint.com
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
Or use in your `.env` file:
|
|
335
|
+
|
|
336
|
+
```env
|
|
337
|
+
VITE_APPS_SERVICE_URL=https://your-custom-endpoint.com
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
## Advanced Features
|
|
341
|
+
|
|
342
|
+
### Controlled vs Uncontrolled Components
|
|
343
|
+
|
|
344
|
+
Sliders and repeating containers support both modes:
|
|
345
|
+
|
|
346
|
+
```tsx
|
|
347
|
+
// Uncontrolled (component manages its own state)
|
|
348
|
+
<Page items={myItems} />
|
|
349
|
+
|
|
350
|
+
// Controlled (you control the current slide)
|
|
351
|
+
<Page
|
|
352
|
+
items={myItems}
|
|
353
|
+
itemsCurrentIndex={currentIndex}
|
|
354
|
+
onItemsIndexChange={setCurrentIndex}
|
|
355
|
+
/>
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### Production Mode
|
|
359
|
+
|
|
360
|
+
Bundle your app/page definitions directly into components for offline usage:
|
|
361
|
+
|
|
362
|
+
```bash
|
|
363
|
+
npx encore-lib generate <appId> <pageId> ./src/components --production
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
This creates a `data.json` file with all necessary data baked in.
|
|
367
|
+
|
|
368
|
+
### Page Metadata
|
|
369
|
+
|
|
370
|
+
Every component exports metadata about the original design:
|
|
371
|
+
|
|
372
|
+
```typescript
|
|
373
|
+
export const PageMeta = {
|
|
374
|
+
width: 375,
|
|
375
|
+
height: 812,
|
|
376
|
+
aspectRatio: 0.46,
|
|
377
|
+
};
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
Use this for responsive layouts or aspect ratio containers.
|
|
381
|
+
|
|
382
|
+
## Package Exports
|
|
383
|
+
|
|
384
|
+
```typescript
|
|
385
|
+
// Main component
|
|
386
|
+
import { EncoreApp } from '@bravostudioai/react';
|
|
387
|
+
|
|
388
|
+
// All components
|
|
389
|
+
import * from '@bravostudioai/react/components';
|
|
390
|
+
|
|
391
|
+
// Hooks
|
|
392
|
+
import { useFontLoader } from '@bravostudioai/react/hooks/useFontLoader';
|
|
393
|
+
import { usePusherUpdates } from '@bravostudioai/react/hooks/usePusherUpdates';
|
|
394
|
+
|
|
395
|
+
// State management
|
|
396
|
+
import { useEncoreState } from '@bravostudioai/react/stores/useEncoreState';
|
|
397
|
+
|
|
398
|
+
// Version info
|
|
399
|
+
import { VERSION } from '@bravostudioai/react/version';
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
## TypeScript Support
|
|
403
|
+
|
|
404
|
+
Full TypeScript support out of the box. Every generated component includes:
|
|
405
|
+
|
|
406
|
+
- Exported interfaces for component props
|
|
407
|
+
- Exported interfaces for list item types
|
|
408
|
+
- Exported interfaces for form data
|
|
409
|
+
- Complete type safety for all callbacks
|
|
410
|
+
|
|
411
|
+
## Requirements
|
|
412
|
+
|
|
413
|
+
- React 18.2.0+ or 19.0.0+
|
|
414
|
+
- React DOM 18.2.0+ or 19.0.0+
|
|
415
|
+
- TypeScript (recommended but not required)
|
|
416
|
+
|
|
417
|
+
## Developer Experience
|
|
418
|
+
|
|
419
|
+
This isn't just code generation - it's a complete workflow:
|
|
420
|
+
|
|
421
|
+
1. **Design in Encore Studio** - Use the visual editor, add data bindings with `encore:data` tags
|
|
422
|
+
2. **Run the generator** - One command creates your components
|
|
423
|
+
3. **Import and use** - Type-safe components with IntelliSense support
|
|
424
|
+
4. **Iterate quickly** - Regenerate anytime your design changes
|
|
425
|
+
|
|
426
|
+
The generated code is clean, readable, and maintainable. You can read it, understand it, and even modify it if needed.
|
|
427
|
+
|
|
428
|
+
## Example Output
|
|
429
|
+
|
|
430
|
+
Here's what the generator creates for a real-world salary calculator:
|
|
431
|
+
|
|
432
|
+
**Generated TypeScript Interface:**
|
|
433
|
+
```typescript
|
|
434
|
+
export interface DeelSalaryCalculatorProps {
|
|
435
|
+
estimatedCost?: string;
|
|
436
|
+
contractTypeSelectInput?: string;
|
|
437
|
+
contractTypeSelectInputOptions?: Array<string | { value: string; label: string }>;
|
|
438
|
+
onContractTypeSelectInputChange?: (value: string) => void;
|
|
439
|
+
// ... and more typed props
|
|
440
|
+
}
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
**Generated Component:**
|
|
444
|
+
```typescript
|
|
445
|
+
export function DeelSalaryCalculator(props: DeelSalaryCalculatorProps) {
|
|
446
|
+
const handleAction = (payload: any) => {
|
|
447
|
+
// Automatically generated event routing
|
|
448
|
+
if (action?.action === "select-change") {
|
|
449
|
+
if (nodeId === "..." && props.onContractTypeSelectInputChange) {
|
|
450
|
+
props.onContractTypeSelectInputChange(value);
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
return (
|
|
457
|
+
<EncoreApp
|
|
458
|
+
appId="..."
|
|
459
|
+
pageId="..."
|
|
460
|
+
data={{ /* auto-mapped props */ }}
|
|
461
|
+
onAction={handleAction}
|
|
462
|
+
/>
|
|
463
|
+
);
|
|
464
|
+
}
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
**Generated README.md:**
|
|
468
|
+
Complete documentation with prop descriptions, types, and usage examples.
|
|
469
|
+
|
|
470
|
+
## Why Developers Love This
|
|
471
|
+
|
|
472
|
+
**"No more design-to-code bottleneck"**
|
|
473
|
+
Your designers can iterate in Encore Studio while you work with production-ready components.
|
|
474
|
+
|
|
475
|
+
**"Type safety everywhere"**
|
|
476
|
+
Catch errors at compile time, not runtime. IntelliSense shows you every available prop.
|
|
477
|
+
|
|
478
|
+
**"Self-documenting components"**
|
|
479
|
+
Every component includes documentation. No need to ask "what props does this take?"
|
|
480
|
+
|
|
481
|
+
**"Zero configuration"**
|
|
482
|
+
No webpack configs, no babel plugins, no setup guides. Just `npm install` and `generate`.
|
|
483
|
+
|
|
484
|
+
**"Actually readable code"**
|
|
485
|
+
The generated code looks like code you'd write by hand. Clean, idiomatic React.
|
|
486
|
+
|
|
487
|
+
## Troubleshooting
|
|
488
|
+
|
|
489
|
+
### Common Issues
|
|
490
|
+
|
|
491
|
+
**Q: The generated component shows "Failed to load"**
|
|
492
|
+
- Ensure your `appId` and `pageId` are correct
|
|
493
|
+
- Check that you have network access to the Encore Studio API
|
|
494
|
+
- For offline use, use `--production` flag during generation
|
|
495
|
+
|
|
496
|
+
**Q: TypeScript errors in generated code**
|
|
497
|
+
- Make sure you have `@types/react` installed
|
|
498
|
+
- Verify your TypeScript version is 5.0+
|
|
499
|
+
- Try regenerating the component with the latest package version
|
|
500
|
+
|
|
501
|
+
**Q: Props not updating the component**
|
|
502
|
+
- Remember that data props need to be defined in Encore Studio with `encore:data` tags
|
|
503
|
+
- Check the generated README.md for the exact prop names
|
|
504
|
+
- Verify the component is receiving props correctly using React DevTools
|
|
505
|
+
|
|
506
|
+
**Q: How do I get my App ID and Page ID?**
|
|
507
|
+
- Contact your Bravo Studio team for access credentials
|
|
508
|
+
- IDs are typically found in your Encore Studio project settings
|
|
509
|
+
|
|
510
|
+
### Best Practices
|
|
511
|
+
|
|
512
|
+
1. **Regenerate components when designs change** - Keep your code in sync
|
|
513
|
+
2. **Read the generated README** - Each component documents its own API
|
|
514
|
+
3. **Use TypeScript** - Get the full benefit of type safety
|
|
515
|
+
4. **Version control generated code** - Treat it like any other source code
|
|
516
|
+
5. **Customize carefully** - Remember that regeneration will overwrite changes
|
|
517
|
+
|
|
518
|
+
## Support
|
|
519
|
+
|
|
520
|
+
For questions, issues, or feature requests, please contact the Bravo Studio team.
|
|
521
|
+
|
|
522
|
+
Package: `@bravostudioai/react`
|
|
523
|
+
|
|
524
|
+
## Version & Updates
|
|
525
|
+
|
|
526
|
+
Check your installed version:
|
|
527
|
+
|
|
528
|
+
```bash
|
|
529
|
+
npm list @bravostudioai/react
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
Or programmatically:
|
|
533
|
+
|
|
534
|
+
```typescript
|
|
535
|
+
import { VERSION } from '@bravostudioai/react/version';
|
|
536
|
+
console.log(VERSION);
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
**Updating to the latest version:**
|
|
540
|
+
|
|
541
|
+
```bash
|
|
542
|
+
npm update @bravostudioai/react
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
## Keywords
|
|
546
|
+
|
|
547
|
+
`react`, `typescript`, `code-generation`, `design-to-code`, `encore`, `bravo-studio`, `component-generator`, `figma-to-react`, `type-safe`, `no-code`, `low-code`, `design-system`, `ui-components`
|
|
548
|
+
|
|
549
|
+
---
|
|
550
|
+
|
|
551
|
+
**Start building faster. Start with @bravostudioai/react.**
|
|
552
|
+
|
|
553
|
+
Made with ❤️ by the Bravo Studio team
|
package/package.json
CHANGED
package/src/codegen/generator.ts
CHANGED
|
@@ -12,12 +12,51 @@ import {
|
|
|
12
12
|
sanitizePropName,
|
|
13
13
|
} from "./parser";
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Metadata extracted from generated component
|
|
17
|
+
*/
|
|
15
18
|
export interface ComponentMetadata {
|
|
19
|
+
/** List of prop names */
|
|
16
20
|
props: string[];
|
|
21
|
+
/** List of event handler names */
|
|
17
22
|
events: string[];
|
|
23
|
+
/** Example JSX usage string */
|
|
18
24
|
jsx: string;
|
|
19
25
|
}
|
|
20
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Generates React component wrapper code for an Encore page
|
|
29
|
+
*
|
|
30
|
+
* Creates a TypeScript React component that wraps EncoreApp with typed props
|
|
31
|
+
* for all data-bound components, sliders, forms, and interactive elements.
|
|
32
|
+
*
|
|
33
|
+
* @param appId - Encore app ID
|
|
34
|
+
* @param pageId - Encore page ID
|
|
35
|
+
* @param componentName - Name for the generated component
|
|
36
|
+
* @param sliders - Slider/list metadata from parser
|
|
37
|
+
* @param standaloneComponents - Standalone component metadata
|
|
38
|
+
* @param inputGroups - Input group metadata
|
|
39
|
+
* @param forms - Form metadata
|
|
40
|
+
* @param selectInputs - Select input metadata
|
|
41
|
+
* @param actionButtons - Action button metadata
|
|
42
|
+
* @param isProduction - Whether to include bundled data for production
|
|
43
|
+
* @param pageMeta - Optional page dimensions and aspect ratio
|
|
44
|
+
* @returns TypeScript component source code
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* const code = generateComponentCode(
|
|
48
|
+
* "01ABC123",
|
|
49
|
+
* "01DEF456",
|
|
50
|
+
* "MyPage",
|
|
51
|
+
* sliders,
|
|
52
|
+
* components,
|
|
53
|
+
* inputGroups,
|
|
54
|
+
* forms,
|
|
55
|
+
* selectInputs,
|
|
56
|
+
* actionButtons
|
|
57
|
+
* );
|
|
58
|
+
* fs.writeFileSync("MyPage.tsx", code);
|
|
59
|
+
*/
|
|
21
60
|
export function generateComponentCode(
|
|
22
61
|
appId: string,
|
|
23
62
|
pageId: string,
|
|
@@ -453,6 +492,25 @@ export const PageMeta = {
|
|
|
453
492
|
`;
|
|
454
493
|
}
|
|
455
494
|
|
|
495
|
+
/**
|
|
496
|
+
* Generates README documentation for a generated component
|
|
497
|
+
*
|
|
498
|
+
* Creates comprehensive Markdown documentation explaining all props,
|
|
499
|
+
* events, and usage examples for the generated wrapper component.
|
|
500
|
+
*
|
|
501
|
+
* @param appId - Encore app ID
|
|
502
|
+
* @param pageId - Encore page ID
|
|
503
|
+
* @param appName - Human-readable app name
|
|
504
|
+
* @param pageName - Human-readable page name
|
|
505
|
+
* @param componentName - Generated component name
|
|
506
|
+
* @param sliders - Slider/list metadata
|
|
507
|
+
* @param standaloneComponents - Component metadata
|
|
508
|
+
* @param inputGroups - Input group metadata
|
|
509
|
+
* @param forms - Form metadata
|
|
510
|
+
* @param selectInputs - Select input metadata
|
|
511
|
+
* @param actionButtons - Action button metadata
|
|
512
|
+
* @returns Markdown documentation string
|
|
513
|
+
*/
|
|
456
514
|
export function generateReadme(
|
|
457
515
|
appId: string,
|
|
458
516
|
pageId: string,
|
|
@@ -811,6 +869,22 @@ ${controlExample}
|
|
|
811
869
|
`;
|
|
812
870
|
}
|
|
813
871
|
|
|
872
|
+
/**
|
|
873
|
+
* Extracts component metadata for programmatic use
|
|
874
|
+
*
|
|
875
|
+
* Generates a simplified metadata object listing all props and events
|
|
876
|
+
* without the full code generation.
|
|
877
|
+
*
|
|
878
|
+
* @param _appName - App name (currently unused)
|
|
879
|
+
* @param pageName - Page name for component naming
|
|
880
|
+
* @param sliders - Slider metadata
|
|
881
|
+
* @param standaloneComponents - Component metadata
|
|
882
|
+
* @param inputGroups - Input group metadata
|
|
883
|
+
* @param forms - Form metadata
|
|
884
|
+
* @param selectInputs - Select input metadata
|
|
885
|
+
* @param actionButtons - Action button metadata
|
|
886
|
+
* @returns Component metadata object
|
|
887
|
+
*/
|
|
814
888
|
export function generateComponentMetadata(
|
|
815
889
|
_appName: string,
|
|
816
890
|
pageName: string,
|