@promakeai/inspector 0.0.4 → 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.
- package/README.md +280 -62
- package/dist/hook.d.ts +38 -5
- package/dist/hook.d.ts.map +1 -1
- package/dist/hook.js +75 -13
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +536 -18
- package/dist/types.d.ts +25 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -11,6 +11,8 @@ Visual element inspector for React apps in iframe with AI prompt support. Perfec
|
|
|
11
11
|
- 🎯 **Element Selection** - Click to select any element on the page
|
|
12
12
|
- 🔍 **React Component Detection** - Automatically detects React components via Fiber
|
|
13
13
|
- 📝 **Dynamic Content Input** - Show/hide text editing on-demand with `showContentInput()`
|
|
14
|
+
- 🖼️ **Image Upload Support** - Custom drag & drop image uploader with preview
|
|
15
|
+
- ⚡ **Immediate DOM Updates** - Optional instant feedback while backend processes
|
|
14
16
|
- 🤖 **AI Prompt Support** - Always-visible prompt input for AI modifications
|
|
15
17
|
- 🎨 **Visual Feedback** - Highlight selected elements with overlay
|
|
16
18
|
- 🔒 **Pause Mode** - Lock selection and disable scroll while editing
|
|
@@ -20,6 +22,8 @@ Visual element inspector for React apps in iframe with AI prompt support. Perfec
|
|
|
20
22
|
- 🌍 **Customizable Labels** - Multi-language support
|
|
21
23
|
- 🚫 **Ignore Elements** - Mark elements as non-inspectable with `data-inspector-ignore`
|
|
22
24
|
- 🔍 **Text Node Detection** - Automatically detect if selected element is a text node
|
|
25
|
+
- 🖼️ **Image Node Detection** - Automatically detect if selected element is an image
|
|
26
|
+
- 🏷️ **Promake Badge** - Optional "Built by Promake" badge with smooth animations
|
|
23
27
|
- 📦 **TypeScript** - Full type safety
|
|
24
28
|
|
|
25
29
|
## Installation
|
|
@@ -55,64 +59,92 @@ import { useInspector } from "@promakeai/inspector/hook";
|
|
|
55
59
|
function App() {
|
|
56
60
|
const iframeRef = useRef<HTMLIFrameElement>(null);
|
|
57
61
|
|
|
58
|
-
const { isInspecting, toggleInspector, showContentInput } =
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
62
|
+
const { isInspecting, toggleInspector, showContentInput, showImageInput } =
|
|
63
|
+
useInspector(
|
|
64
|
+
iframeRef,
|
|
65
|
+
{
|
|
66
|
+
onElementSelected: (data) => {
|
|
67
|
+
console.log("Element selected:", data);
|
|
68
|
+
console.log("Is text node:", data.isTextNode);
|
|
69
|
+
console.log("Is image node:", data.isImageNode);
|
|
70
|
+
|
|
71
|
+
// Access component info
|
|
72
|
+
console.log(data.component?.fileName);
|
|
73
|
+
console.log(data.component?.lineNumber);
|
|
74
|
+
|
|
75
|
+
// Show content input if it's a text node
|
|
76
|
+
if (data.isTextNode) {
|
|
77
|
+
showContentInput(true);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Show image input if it's an image node
|
|
81
|
+
if (data.isImageNode) {
|
|
82
|
+
showImageInput(true);
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
onPromptSubmitted: (data) => {
|
|
86
|
+
console.log("AI Prompt:", data.prompt);
|
|
87
|
+
// Send to your AI service
|
|
88
|
+
fetch("/api/ai-edit", {
|
|
89
|
+
method: "POST",
|
|
90
|
+
body: JSON.stringify({
|
|
91
|
+
prompt: data.prompt,
|
|
92
|
+
element: data.element,
|
|
93
|
+
}),
|
|
94
|
+
});
|
|
95
|
+
},
|
|
96
|
+
onTextUpdated: (data) => {
|
|
97
|
+
console.log("Text updated:", data.text);
|
|
98
|
+
// Save to backend
|
|
99
|
+
},
|
|
100
|
+
onImageUpdated: (data) => {
|
|
101
|
+
console.log("Image updated:", data.imageFile.name);
|
|
102
|
+
console.log("Image data (base64):", data.imageData);
|
|
103
|
+
// Upload to server
|
|
104
|
+
fetch("/api/upload-image", {
|
|
105
|
+
method: "POST",
|
|
106
|
+
body: JSON.stringify(data),
|
|
107
|
+
});
|
|
108
|
+
},
|
|
109
|
+
onInspectorClosed: () => {
|
|
110
|
+
console.log("Inspector closed");
|
|
111
|
+
// Update UI state, re-enable elements, etc.
|
|
112
|
+
},
|
|
113
|
+
onUrlChange: (data) => {
|
|
114
|
+
console.log("URL changed:", data.pathname);
|
|
115
|
+
},
|
|
116
|
+
onError: (data) => {
|
|
117
|
+
console.error("Error in template:", data);
|
|
118
|
+
// Send to error tracking service (Sentry, etc.)
|
|
119
|
+
// Sentry.captureException(new Error(data.message));
|
|
120
|
+
},
|
|
73
121
|
},
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
122
|
+
{
|
|
123
|
+
// Optional: Custom labels
|
|
124
|
+
editText: "Edit Text",
|
|
125
|
+
textPlaceholder: "Enter text...",
|
|
126
|
+
updateText: "Update",
|
|
127
|
+
promptPlaceholder: "Ask AI for changes...",
|
|
128
|
+
editImage: "Change Image",
|
|
129
|
+
imageUploadTitle: "Select Image",
|
|
130
|
+
imageUploadHint: "Click or drag",
|
|
131
|
+
updateImage: "Update Image",
|
|
132
|
+
badgeText: "Built with Promake",
|
|
84
133
|
},
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
// Optional: Custom labels
|
|
100
|
-
editText: "Edit Text",
|
|
101
|
-
textPlaceholder: "Enter text...",
|
|
102
|
-
updateText: "Update",
|
|
103
|
-
promptPlaceholder: "Ask AI for changes...",
|
|
104
|
-
},
|
|
105
|
-
{
|
|
106
|
-
// Optional: Custom theme colors
|
|
107
|
-
backgroundColor: "#ffffff",
|
|
108
|
-
textColor: "#111827",
|
|
109
|
-
buttonColor: "#4417db",
|
|
110
|
-
buttonTextColor: "#ffffff",
|
|
111
|
-
inputBackgroundColor: "#f9fafb",
|
|
112
|
-
inputTextColor: "#111827",
|
|
113
|
-
inputBorderColor: "#d1d5db",
|
|
114
|
-
}
|
|
115
|
-
);
|
|
134
|
+
{
|
|
135
|
+
// Optional: Custom theme colors
|
|
136
|
+
backgroundColor: "#ffffff",
|
|
137
|
+
textColor: "#111827",
|
|
138
|
+
buttonColor: "#4417db",
|
|
139
|
+
buttonTextColor: "#ffffff",
|
|
140
|
+
inputBackgroundColor: "#f9fafb",
|
|
141
|
+
inputTextColor: "#111827",
|
|
142
|
+
inputBorderColor: "#d1d5db",
|
|
143
|
+
badgeGradientStart: "#411E93",
|
|
144
|
+
badgeGradientEnd: "#E87C85",
|
|
145
|
+
badgeTextColor: "#ffffff",
|
|
146
|
+
}
|
|
147
|
+
);
|
|
116
148
|
|
|
117
149
|
return (
|
|
118
150
|
<div>
|
|
@@ -141,9 +173,11 @@ function App() {
|
|
|
141
173
|
|
|
142
174
|
- **iframeRef**: `RefObject<HTMLIFrameElement>` - Reference to the iframe element
|
|
143
175
|
- **callbacks**: `InspectorCallbacks` (optional)
|
|
144
|
-
- `onElementSelected`: Called when an element is selected (receives `isTextNode`
|
|
176
|
+
- `onElementSelected`: Called when an element is selected (receives `isTextNode` and `isImageNode` properties)
|
|
145
177
|
- `onPromptSubmitted`: Called when AI prompt is submitted
|
|
146
178
|
- `onTextUpdated`: Called when text content is updated
|
|
179
|
+
- `onImageUpdated`: Called when image is uploaded
|
|
180
|
+
- `onInspectorClosed`: Called when inspector mode is closed (after submitting prompt/text/image)
|
|
147
181
|
- `onUrlChange`: Called when URL changes in iframe
|
|
148
182
|
- `onError`: Called when an error occurs in iframe
|
|
149
183
|
- **labels**: `InspectorLabels` (optional)
|
|
@@ -151,6 +185,11 @@ function App() {
|
|
|
151
185
|
- `textPlaceholder`: Placeholder for text input
|
|
152
186
|
- `updateText`: Label for update button
|
|
153
187
|
- `promptPlaceholder`: Placeholder for prompt input
|
|
188
|
+
- `editImage`: Label for image edit section
|
|
189
|
+
- `imageUploadTitle`: Upload box title (e.g., "Select Image")
|
|
190
|
+
- `imageUploadHint`: Upload box hint (e.g., "Click or drag")
|
|
191
|
+
- `updateImage`: Label for image update button
|
|
192
|
+
- `badgeText`: Badge text (default: "Built with Promake")
|
|
154
193
|
- **theme**: `InspectorTheme` (optional)
|
|
155
194
|
- `backgroundColor`: Box background color (default: `#ffffff`)
|
|
156
195
|
- `textColor`: Text color (default: `#111827`)
|
|
@@ -159,6 +198,9 @@ function App() {
|
|
|
159
198
|
- `inputBackgroundColor`: Input background color (default: `#f9fafb`)
|
|
160
199
|
- `inputTextColor`: Input text color (default: `#111827`)
|
|
161
200
|
- `inputBorderColor`: Input border color (default: `#d1d5db`)
|
|
201
|
+
- `badgeGradientStart`: Badge gradient start color (default: `#411E93`)
|
|
202
|
+
- `badgeGradientEnd`: Badge gradient end color (default: `#E87C85`)
|
|
203
|
+
- `badgeTextColor`: Badge text color (default: `#ffffff`)
|
|
162
204
|
|
|
163
205
|
#### Returns
|
|
164
206
|
|
|
@@ -166,7 +208,9 @@ function App() {
|
|
|
166
208
|
- **toggleInspector**: `(active?: boolean) => void` - Toggle inspection mode
|
|
167
209
|
- **startInspecting**: `() => void` - Start inspecting
|
|
168
210
|
- **stopInspecting**: `() => void` - Stop inspecting
|
|
169
|
-
- **showContentInput**: `(show: boolean) => void` - Show or hide content input dynamically
|
|
211
|
+
- **showContentInput**: `(show: boolean, updateImmediately?: boolean) => void` - Show or hide text content input dynamically. If `updateImmediately` is true, DOM is updated immediately on submit (useful for slow backend responses)
|
|
212
|
+
- **showImageInput**: `(show: boolean, updateImmediately?: boolean) => void` - Show or hide image input dynamically. If `updateImmediately` is true, DOM is updated immediately on submit (useful for slow backend responses)
|
|
213
|
+
- **setBadgeVisible**: `(visible: boolean) => void` - Show or hide "Built by Promake" badge in bottom-right corner
|
|
170
214
|
|
|
171
215
|
## Types
|
|
172
216
|
|
|
@@ -181,6 +225,8 @@ interface SelectedElementData {
|
|
|
181
225
|
position: ElementPosition;
|
|
182
226
|
isTextNode?: boolean; // Whether the element is a text node
|
|
183
227
|
textContent?: string; // Text content of the element (if text node)
|
|
228
|
+
isImageNode?: boolean; // Whether the element is an image node
|
|
229
|
+
imageUrl?: string; // Image URL (if image node)
|
|
184
230
|
}
|
|
185
231
|
```
|
|
186
232
|
|
|
@@ -214,6 +260,21 @@ interface TextUpdatedData {
|
|
|
214
260
|
}
|
|
215
261
|
```
|
|
216
262
|
|
|
263
|
+
### `ImageUpdatedData`
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
interface ImageUpdatedData {
|
|
267
|
+
imageData: string; // Base64 encoded image data
|
|
268
|
+
imageFile: {
|
|
269
|
+
name: string;
|
|
270
|
+
size: number;
|
|
271
|
+
type: string;
|
|
272
|
+
};
|
|
273
|
+
originalImageUrl: string;
|
|
274
|
+
element: SelectedElementData;
|
|
275
|
+
}
|
|
276
|
+
```
|
|
277
|
+
|
|
217
278
|
### `ErrorData`
|
|
218
279
|
|
|
219
280
|
```typescript
|
|
@@ -228,6 +289,22 @@ interface ErrorData {
|
|
|
228
289
|
}
|
|
229
290
|
```
|
|
230
291
|
|
|
292
|
+
### `InspectorLabels`
|
|
293
|
+
|
|
294
|
+
```typescript
|
|
295
|
+
interface InspectorLabels {
|
|
296
|
+
editText?: string; // Label for text edit section
|
|
297
|
+
textPlaceholder?: string; // Placeholder for text input
|
|
298
|
+
updateText?: string; // Label for text update button
|
|
299
|
+
promptPlaceholder?: string; // Placeholder for prompt input
|
|
300
|
+
editImage?: string; // Label for image edit section
|
|
301
|
+
imageUploadTitle?: string; // Upload box title (e.g., "Select Image")
|
|
302
|
+
imageUploadHint?: string; // Upload box hint (e.g., "Click or drag")
|
|
303
|
+
updateImage?: string; // Label for image update button
|
|
304
|
+
badgeText?: string; // Badge text (default: "Built with Promake")
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
231
308
|
### `InspectorTheme`
|
|
232
309
|
|
|
233
310
|
```typescript
|
|
@@ -239,6 +316,9 @@ interface InspectorTheme {
|
|
|
239
316
|
inputBackgroundColor?: string; // Input background color
|
|
240
317
|
inputTextColor?: string; // Input text color
|
|
241
318
|
inputBorderColor?: string; // Input border color
|
|
319
|
+
badgeGradientStart?: string; // Badge gradient start color
|
|
320
|
+
badgeGradientEnd?: string; // Badge gradient end color
|
|
321
|
+
badgeTextColor?: string; // Badge text color
|
|
242
322
|
}
|
|
243
323
|
```
|
|
244
324
|
|
|
@@ -253,29 +333,167 @@ Click any element to select it. The inspector will:
|
|
|
253
333
|
- Pause scrolling
|
|
254
334
|
- Extract React component information
|
|
255
335
|
- Detect if element is a text-only node (`isTextNode`)
|
|
336
|
+
- Detect if element is an image node (`isImageNode`)
|
|
256
337
|
|
|
257
338
|
### Dynamic Content Input
|
|
258
339
|
|
|
259
|
-
The inspector now uses a
|
|
340
|
+
The inspector now uses a three-stage approach:
|
|
260
341
|
|
|
261
342
|
1. **Prompt Input (Always Visible)**: Every element shows a prompt input for AI instructions
|
|
262
|
-
2. **Content Input (On-Demand)**: Text editing appears only when you call `showContentInput(true)`
|
|
343
|
+
2. **Text Content Input (On-Demand)**: Text editing appears only when you call `showContentInput(true)`
|
|
344
|
+
3. **Image Upload (On-Demand)**: Image upload appears only when you call `showImageInput(true)`
|
|
263
345
|
|
|
264
346
|
This allows you to:
|
|
265
347
|
|
|
266
348
|
- Run AI computations after selection
|
|
267
|
-
- Decide programmatically when to show text editing
|
|
349
|
+
- Decide programmatically when to show text editing or image upload
|
|
268
350
|
- Keep the UI clean and focused
|
|
269
351
|
|
|
270
352
|
```typescript
|
|
271
353
|
onElementSelected: (data) => {
|
|
272
354
|
if (data.isTextNode) {
|
|
273
355
|
// Show content input above prompt input
|
|
274
|
-
|
|
356
|
+
// Pass true as second parameter for immediate DOM update
|
|
357
|
+
showContentInput(true, true);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
if (data.isImageNode) {
|
|
361
|
+
// Show image upload for images
|
|
362
|
+
// Pass true as second parameter for immediate DOM update
|
|
363
|
+
showImageInput(true, true);
|
|
275
364
|
}
|
|
276
365
|
};
|
|
277
366
|
```
|
|
278
367
|
|
|
368
|
+
### Image Upload
|
|
369
|
+
|
|
370
|
+
For image elements:
|
|
371
|
+
|
|
372
|
+
- **Custom Upload Box**: Dashed border box with drag & drop support
|
|
373
|
+
- **Click to Upload**: Click the box to select image from file explorer
|
|
374
|
+
- **Drag & Drop**: Drag image files directly onto the upload box
|
|
375
|
+
- **Preview**: Selected image appears in the same box (max 100px height)
|
|
376
|
+
- **Base64 Encoding**: Image is automatically converted to base64
|
|
377
|
+
- **File Metadata**: File name, size, and type are included
|
|
378
|
+
|
|
379
|
+
The image data is sent to parent app with `onImageUpdated` callback for upload to your server.
|
|
380
|
+
|
|
381
|
+
### Immediate DOM Updates
|
|
382
|
+
|
|
383
|
+
For production environments where backend processing takes time, you can enable immediate DOM updates:
|
|
384
|
+
|
|
385
|
+
```typescript
|
|
386
|
+
// Text updates - DOM is updated immediately, no wait for backend
|
|
387
|
+
showContentInput(true, true); // updateImmediately: true
|
|
388
|
+
|
|
389
|
+
// Image updates - Image appears immediately, no wait for backend
|
|
390
|
+
showImageInput(true, true); // updateImmediately: true
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
**How it works:**
|
|
394
|
+
|
|
395
|
+
1. **Text Updates**: When user submits new text, the DOM text content is updated immediately
|
|
396
|
+
2. **Image Updates**: When user selects an image, the `<img>` src (or background-image) is updated immediately with base64 data
|
|
397
|
+
3. **Backend Sync**: The `onTextUpdated` or `onImageUpdated` callback is still fired for backend sync
|
|
398
|
+
4. **User Experience**: User sees instant feedback, while your backend processes in the background
|
|
399
|
+
|
|
400
|
+
This is perfect for:
|
|
401
|
+
|
|
402
|
+
- Slow API responses
|
|
403
|
+
- AI processing that takes seconds
|
|
404
|
+
- Upload-heavy operations
|
|
405
|
+
- Better perceived performance
|
|
406
|
+
|
|
407
|
+
### Promake Badge
|
|
408
|
+
|
|
409
|
+
Show a beautiful "Built with Promake" badge in the bottom-right corner:
|
|
410
|
+
|
|
411
|
+
```typescript
|
|
412
|
+
// Show badge with default text ("Built with Promake")
|
|
413
|
+
setBadgeVisible(true);
|
|
414
|
+
|
|
415
|
+
// Hide badge
|
|
416
|
+
setBadgeVisible(false);
|
|
417
|
+
|
|
418
|
+
// Customize badge text via labels
|
|
419
|
+
const { setBadgeVisible } = useInspector(iframeRef, callbacks, {
|
|
420
|
+
badgeText: "Made with ❤️ by MyCompany",
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
// Customize badge colors via theme
|
|
424
|
+
const { setBadgeVisible } = useInspector(
|
|
425
|
+
iframeRef,
|
|
426
|
+
callbacks,
|
|
427
|
+
undefined, // no custom labels
|
|
428
|
+
{
|
|
429
|
+
badgeGradientStart: "#10b981", // Green
|
|
430
|
+
badgeGradientEnd: "#3b82f6", // Blue
|
|
431
|
+
badgeTextColor: "#ffffff", // White text
|
|
432
|
+
}
|
|
433
|
+
);
|
|
434
|
+
|
|
435
|
+
// Dark badge with light text
|
|
436
|
+
const { setBadgeVisible } = useInspector(iframeRef, callbacks, undefined, {
|
|
437
|
+
badgeGradientStart: "#1e293b", // Dark slate
|
|
438
|
+
badgeGradientEnd: "#334155", // Slate
|
|
439
|
+
badgeTextColor: "#f8fafc", // Light text
|
|
440
|
+
});
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
**Features:**
|
|
444
|
+
|
|
445
|
+
- 🎨 Beautiful gradient design (purple to violet by default)
|
|
446
|
+
- ⚡ Smooth fade-in/fade-out animations
|
|
447
|
+
- 🖱️ Hover effects with elevation
|
|
448
|
+
- 🔗 Clickable - opens promake.ai in new tab
|
|
449
|
+
- 📍 Fixed position in bottom-right
|
|
450
|
+
- 🚫 Ignored by inspector (has `data-inspector-ignore`)
|
|
451
|
+
- 📝 Customizable text via labels
|
|
452
|
+
- 🎨 Customizable gradient colors via theme
|
|
453
|
+
- 🔤 Customizable text color via theme
|
|
454
|
+
- ❌ Close button appears on hover - users can dismiss the badge
|
|
455
|
+
|
|
456
|
+
**Default**: Badge is hidden by default. Enable it when needed using `setBadgeVisible(true)`. Default text is "Built with Promake". Default gradient colors are deep purple (#411E93) to coral pink (#E87C85). Default text color is white (#ffffff).
|
|
457
|
+
|
|
458
|
+
**Auto-Show**: Badge automatically appears when the app is running in `preview.promake.ai` environment **without** a parent iframe. This ensures the badge is visible in preview deployments where parent control is not available.
|
|
459
|
+
|
|
460
|
+
**Close Button**: When users hover over the badge, a small close button (×) appears in the top-right corner. Clicking it hides the badge with a smooth animation.
|
|
461
|
+
|
|
462
|
+
**Color Examples:**
|
|
463
|
+
|
|
464
|
+
**Gradient Backgrounds:**
|
|
465
|
+
|
|
466
|
+
- **Deep Purple to Coral Pink** (default): `#411E93` → `#E87C85` (white text)
|
|
467
|
+
- **Blue to Cyan**: `#3b82f6` → `#06b6d4` (white text)
|
|
468
|
+
- **Green to Emerald**: `#10b981` → `#059669` (white text)
|
|
469
|
+
- **Pink to Rose**: `#ec4899` → `#f43f5e` (white text)
|
|
470
|
+
- **Orange to Red**: `#f97316` → `#ef4444` (white text)
|
|
471
|
+
- **Dark Slate**: `#1e293b` → `#334155` (light text `#f8fafc`)
|
|
472
|
+
|
|
473
|
+
**Text Colors:**
|
|
474
|
+
|
|
475
|
+
- **White** (default): `#ffffff`
|
|
476
|
+
- **Light**: `#f8fafc`, `#f1f5f9`
|
|
477
|
+
- **Dark**: `#111827`, `#1e293b`
|
|
478
|
+
- **Brand Colors**: Match your brand palette
|
|
479
|
+
|
|
480
|
+
**Auto-Show Behavior:**
|
|
481
|
+
|
|
482
|
+
The badge automatically appears in these conditions:
|
|
483
|
+
|
|
484
|
+
1. The app is **not** inside an iframe (`window.parent === window`)
|
|
485
|
+
2. The URL contains `preview.promake.ai`
|
|
486
|
+
|
|
487
|
+
This ensures the badge is visible in Promake preview deployments where parent window control is unavailable. Users can still close it using the close button on hover.
|
|
488
|
+
|
|
489
|
+
**Use Cases:**
|
|
490
|
+
|
|
491
|
+
- Show attribution to Promake
|
|
492
|
+
- Free tier watermark for preview deployments
|
|
493
|
+
- Branding for templates built with Promake
|
|
494
|
+
- Custom branding with your own text and colors
|
|
495
|
+
- Automatic display in preview environments
|
|
496
|
+
|
|
279
497
|
### AI Prompts
|
|
280
498
|
|
|
281
499
|
For any element:
|
package/dist/hook.d.ts
CHANGED
|
@@ -12,16 +12,22 @@
|
|
|
12
12
|
* function App() {
|
|
13
13
|
* const iframeRef = useRef<HTMLIFrameElement>(null);
|
|
14
14
|
*
|
|
15
|
-
* const { isInspecting, toggleInspector, showContentInput } = useInspector(
|
|
15
|
+
* const { isInspecting, toggleInspector, showContentInput, showImageInput } = useInspector(
|
|
16
16
|
* iframeRef,
|
|
17
17
|
* {
|
|
18
18
|
* onElementSelected: (data) => {
|
|
19
19
|
* console.log('Element selected:', data);
|
|
20
20
|
* console.log('Is text node:', data.isTextNode);
|
|
21
|
+
* console.log('Is image node:', data.isImageNode);
|
|
21
22
|
*
|
|
22
23
|
* // Dynamically show content input for text nodes
|
|
23
24
|
* if (data.isTextNode) {
|
|
24
|
-
* showContentInput(true);
|
|
25
|
+
* showContentInput(true, true); // updateImmediately: true for instant feedback
|
|
26
|
+
* }
|
|
27
|
+
*
|
|
28
|
+
* // Dynamically show image input for image nodes
|
|
29
|
+
* if (data.isImageNode) {
|
|
30
|
+
* showImageInput(true, true); // updateImmediately: true for instant feedback
|
|
25
31
|
* }
|
|
26
32
|
* },
|
|
27
33
|
* onPromptSubmitted: (data) => {
|
|
@@ -35,6 +41,19 @@
|
|
|
35
41
|
* onTextUpdated: (data) => {
|
|
36
42
|
* console.log('Text updated:', data.text);
|
|
37
43
|
* },
|
|
44
|
+
* onImageUpdated: (data) => {
|
|
45
|
+
* console.log('Image updated:', data.imageFile.name);
|
|
46
|
+
* console.log('Image data (base64):', data.imageData);
|
|
47
|
+
* // Upload to server
|
|
48
|
+
* fetch('/api/upload-image', {
|
|
49
|
+
* method: 'POST',
|
|
50
|
+
* body: JSON.stringify(data)
|
|
51
|
+
* });
|
|
52
|
+
* },
|
|
53
|
+
* onInspectorClosed: () => {
|
|
54
|
+
* console.log('Inspector closed');
|
|
55
|
+
* // Update UI state, re-enable elements, etc.
|
|
56
|
+
* },
|
|
38
57
|
* onError: (data) => {
|
|
39
58
|
* console.error('Error:', data);
|
|
40
59
|
* // Send to error tracking service
|
|
@@ -45,7 +64,12 @@
|
|
|
45
64
|
* editText: 'Edit Text',
|
|
46
65
|
* textPlaceholder: 'Enter text...',
|
|
47
66
|
* updateText: 'Update',
|
|
48
|
-
* promptPlaceholder: 'Ask AI for changes...'
|
|
67
|
+
* promptPlaceholder: 'Ask AI for changes...',
|
|
68
|
+
* editImage: 'Change Image',
|
|
69
|
+
* imageUploadTitle: 'Select Image',
|
|
70
|
+
* imageUploadHint: 'Click or drag',
|
|
71
|
+
* updateImage: 'Update Image',
|
|
72
|
+
* badgeText: 'Built with Promake'
|
|
49
73
|
* },
|
|
50
74
|
* {
|
|
51
75
|
* // Optional: Custom theme colors (all optional)
|
|
@@ -55,7 +79,10 @@
|
|
|
55
79
|
* buttonTextColor: '#ffffff',
|
|
56
80
|
* inputBackgroundColor: '#f9fafb',
|
|
57
81
|
* inputTextColor: '#111827',
|
|
58
|
-
* inputBorderColor: '#d1d5db'
|
|
82
|
+
* inputBorderColor: '#d1d5db',
|
|
83
|
+
* badgeGradientStart: '#411E93',
|
|
84
|
+
* badgeGradientEnd: '#E87C85',
|
|
85
|
+
* badgeTextColor: '#ffffff'
|
|
59
86
|
* }
|
|
60
87
|
* );
|
|
61
88
|
*
|
|
@@ -66,7 +93,13 @@
|
|
|
66
93
|
* Toggle Inspector
|
|
67
94
|
* </button>
|
|
68
95
|
* <button onClick={() => showContentInput(true)}>
|
|
69
|
-
* Show
|
|
96
|
+
* Show Text Input
|
|
97
|
+
* </button>
|
|
98
|
+
* <button onClick={() => showImageInput(true)}>
|
|
99
|
+
* Show Image Input
|
|
100
|
+
* </button>
|
|
101
|
+
* <button onClick={() => setBadgeVisible(true)}>
|
|
102
|
+
* Show Promake Badge
|
|
70
103
|
* </button>
|
|
71
104
|
* </div>
|
|
72
105
|
* <iframe ref={iframeRef} src="http://localhost:5173" />
|
package/dist/hook.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../src/hook.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../src/hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6GG;AAEH,OAAO,EAAoC,SAAS,EAAE,MAAM,OAAO,CAAC;AACpE,OAAO,KAAK,EACV,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,kBAAkB,EAOnB,MAAM,SAAS,CAAC;AAsDjB,wBAAgB,YAAY,CAC1B,SAAS,EAAE,SAAS,CAAC,iBAAiB,CAAC,EACvC,SAAS,CAAC,EAAE,kBAAkB,EAC9B,MAAM,CAAC,EAAE,eAAe,EACxB,KAAK,CAAC,EAAE,cAAc,GACrB,kBAAkB,CA4LpB;AAGD,mBAAmB,SAAS,CAAC"}
|