@rn-ave/core 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,467 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.InfoTooltip = InfoTooltip;
37
+ const react_1 = __importStar(require("react"));
38
+ const react_native_1 = require("react-native");
39
+ const source_1 = require("../fiber/source");
40
+ function InfoTooltip({ componentInfo, bounds, onDismiss, onSendToAgent, onOpenInEditor, }) {
41
+ const [prompt, setPrompt] = (0, react_1.useState)('');
42
+ const [copied, setCopied] = (0, react_1.useState)(false);
43
+ const [loadingAgent, setLoadingAgent] = (0, react_1.useState)(null);
44
+ // Local selection of which component in the hierarchy to inspect
45
+ const [selectedIndex, setSelectedIndex] = (0, react_1.useState)(0);
46
+ const { height: screenHeight } = react_native_1.Dimensions.get('window');
47
+ const selectedComponent = componentInfo.componentHierarchy[selectedIndex] || {
48
+ name: componentInfo.componentName,
49
+ props: componentInfo.props,
50
+ source: componentInfo.source
51
+ };
52
+ // Smart positioning: top if element is in bottom half, bottom if in top half
53
+ const elementCenterY = bounds ? bounds.y + bounds.height / 2 : screenHeight / 2;
54
+ const isElementInBottomHalf = elementCenterY > screenHeight / 2;
55
+ const positionStyle = isElementInBottomHalf
56
+ ? { top: 50 } // Show at top (below status bar)
57
+ : { bottom: 34 }; // Show at bottom (above home indicator)
58
+ const filePath = selectedComponent.source
59
+ ? (0, source_1.formatSourceLocation)(selectedComponent.source)
60
+ : null;
61
+ const handleCopyPath = () => {
62
+ if (filePath) {
63
+ try {
64
+ react_native_1.Clipboard.setString(filePath);
65
+ setCopied(true);
66
+ setTimeout(() => setCopied(false), 2000);
67
+ }
68
+ catch (e) {
69
+ // Silent fail
70
+ }
71
+ }
72
+ };
73
+ const handleOpenInEditor = () => {
74
+ console.log(`\n🔧 [rn-ave] Open in Editor pressed for ${selectedComponent.name}`);
75
+ // If we have a source override from selection, we'd pass it here
76
+ // For now the provider uses lastContext.source, so we might need to update the provider
77
+ // or pass the specific source to the callback.
78
+ if (onOpenInEditor) {
79
+ // We pass the selected component's source to the callback if it supports it
80
+ onOpenInEditor(selectedComponent.source);
81
+ }
82
+ };
83
+ const handleSend = async (agentType) => {
84
+ if (!prompt.trim()) {
85
+ react_native_1.Alert.alert('Prompt Required', 'Please enter a prompt describing what you want the AI to do.');
86
+ return;
87
+ }
88
+ if (!onSendToAgent)
89
+ return;
90
+ setLoadingAgent(agentType);
91
+ try {
92
+ // Use the selected component's info for the agent
93
+ const contextOverride = {
94
+ ...componentInfo,
95
+ componentName: selectedComponent.name,
96
+ props: selectedComponent.props,
97
+ source: selectedComponent.source,
98
+ };
99
+ const result = await onSendToAgent(agentType, prompt.trim(), contextOverride);
100
+ if (!result.success && result.error) {
101
+ react_native_1.Alert.alert('Error', result.error);
102
+ }
103
+ }
104
+ catch (e) {
105
+ react_native_1.Alert.alert('Error', 'An unexpected error occurred');
106
+ }
107
+ finally {
108
+ setLoadingAgent(null);
109
+ }
110
+ };
111
+ const isLoading = loadingAgent !== null;
112
+ return (<>
113
+ {/* Subtle backdrop */}
114
+ <react_native_1.Pressable style={styles.backdrop} onPress={onDismiss}/>
115
+
116
+ {/* Smart positioned panel */}
117
+ <react_native_1.View style={[styles.tooltip, positionStyle]}>
118
+ <react_native_1.View style={styles.container}>
119
+ {/* Fixed Header */}
120
+ <react_native_1.View style={styles.header}>
121
+ <react_native_1.View style={styles.titleContainer}>
122
+ <react_native_1.Text style={styles.componentName} numberOfLines={1}>
123
+ {selectedComponent.name}
124
+ </react_native_1.Text>
125
+ </react_native_1.View>
126
+
127
+ {/* Open in Editor button */}
128
+ {!!onOpenInEditor && !!selectedComponent.source && (<react_native_1.TouchableOpacity accessibilityLabel="Open in Editor" onPress={handleOpenInEditor} style={styles.headerButton}>
129
+ <react_native_1.View style={styles.codeIcon}>
130
+ <react_native_1.Text style={styles.codeIconText}>{'</>'}</react_native_1.Text>
131
+ </react_native_1.View>
132
+ </react_native_1.TouchableOpacity>)}
133
+
134
+ {/* Close button */}
135
+ <react_native_1.TouchableOpacity onPress={onDismiss} style={styles.headerButton}>
136
+ <react_native_1.View style={styles.closeIcon}>
137
+ <react_native_1.View style={[styles.closeIconLine, { transform: [{ rotate: '45deg' }] }]}/>
138
+ <react_native_1.View style={[styles.closeIconLine, { transform: [{ rotate: '-45deg' }] }]}/>
139
+ </react_native_1.View>
140
+ </react_native_1.TouchableOpacity>
141
+ </react_native_1.View>
142
+
143
+ {/* Breadcrumbs / Hierarchy Navigation */}
144
+ <react_native_1.View style={styles.breadcrumbContainer}>
145
+ <react_native_1.ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={styles.breadcrumbScroll}>
146
+ {componentInfo.componentHierarchy.slice(0, 6).map((item, index) => (<react_1.default.Fragment key={`${item.name}-${index}`}>
147
+ {index > 0 && <react_native_1.Text style={styles.breadcrumbSeparator}>›</react_native_1.Text>}
148
+ <react_native_1.TouchableOpacity onPress={() => setSelectedIndex(index)} style={[
149
+ styles.breadcrumbItem,
150
+ selectedIndex === index && styles.breadcrumbItemActive
151
+ ]}>
152
+ <react_native_1.Text style={[
153
+ styles.breadcrumbText,
154
+ selectedIndex === index && styles.breadcrumbTextActive,
155
+ !item.source && styles.breadcrumbTextNoSource
156
+ ]}>
157
+ {item.name}
158
+ </react_native_1.Text>
159
+ </react_native_1.TouchableOpacity>
160
+ </react_1.default.Fragment>))}
161
+ </react_native_1.ScrollView>
162
+ </react_native_1.View>
163
+
164
+ {/* Scrollable Content */}
165
+ <react_native_1.ScrollView style={styles.scrollContent} showsVerticalScrollIndicator={false} contentContainerStyle={styles.scrollContentContainer}>
166
+ {/* Dimensions Row (only for the actual host element) */}
167
+ {bounds && selectedIndex === 0 && (<react_native_1.View style={styles.dimensionsRow}>
168
+ <react_native_1.Text style={styles.label}>Size</react_native_1.Text>
169
+ <react_native_1.Text style={styles.dimensionsValue}>
170
+ {Math.round(bounds.width)} × {Math.round(bounds.height)}
171
+ </react_native_1.Text>
172
+ </react_native_1.View>)}
173
+
174
+ {/* Box Model Info - compact display of margin/padding (only for selection 0) */}
175
+ {selectedIndex === 0 && componentInfo.boxModel && (<react_native_1.View style={styles.boxModelRow}>
176
+ {/* Margin */}
177
+ {(componentInfo.boxModel.margin.top > 0 ||
178
+ componentInfo.boxModel.margin.right > 0 ||
179
+ componentInfo.boxModel.margin.bottom > 0 ||
180
+ componentInfo.boxModel.margin.left > 0) && (<react_native_1.View style={styles.boxModelItem}>
181
+ <react_native_1.View style={[styles.boxModelColor, { backgroundColor: 'rgba(246, 178, 107, 0.8)' }]}/>
182
+ <react_native_1.Text style={styles.boxModelLabel}>M</react_native_1.Text>
183
+ <react_native_1.Text style={styles.boxModelValue}>
184
+ {componentInfo.boxModel.margin.top} {componentInfo.boxModel.margin.right} {componentInfo.boxModel.margin.bottom} {componentInfo.boxModel.margin.left}
185
+ </react_native_1.Text>
186
+ </react_native_1.View>)}
187
+ {/* Padding */}
188
+ {(componentInfo.boxModel.padding.top > 0 ||
189
+ componentInfo.boxModel.padding.right > 0 ||
190
+ componentInfo.boxModel.padding.bottom > 0 ||
191
+ componentInfo.boxModel.padding.left > 0) && (<react_native_1.View style={styles.boxModelItem}>
192
+ <react_native_1.View style={[styles.boxModelColor, { backgroundColor: 'rgba(147, 196, 125, 0.8)' }]}/>
193
+ <react_native_1.Text style={styles.boxModelLabel}>P</react_native_1.Text>
194
+ <react_native_1.Text style={styles.boxModelValue}>
195
+ {componentInfo.boxModel.padding.top} {componentInfo.boxModel.padding.right} {componentInfo.boxModel.padding.bottom} {componentInfo.boxModel.padding.left}
196
+ </react_native_1.Text>
197
+ </react_native_1.View>)}
198
+ </react_native_1.View>)}
199
+
200
+ {/* Source Row */}
201
+ {filePath && (<react_native_1.View style={styles.sourceRow}>
202
+ <react_native_1.Text style={styles.label}>Source</react_native_1.Text>
203
+ <react_native_1.ScrollView horizontal showsHorizontalScrollIndicator={false} style={styles.filePathScroll}>
204
+ <react_native_1.Text style={styles.filePath} numberOfLines={1}>
205
+ {filePath}
206
+ </react_native_1.Text>
207
+ </react_native_1.ScrollView>
208
+ <react_native_1.TouchableOpacity style={styles.copyButton} onPress={handleCopyPath}>
209
+ <react_native_1.Text style={styles.copyText}>{copied ? 'Copied' : 'Copy'}</react_native_1.Text>
210
+ </react_native_1.TouchableOpacity>
211
+ </react_native_1.View>)}
212
+
213
+ {/* AI Prompt Section */}
214
+ <react_native_1.View style={styles.divider}/>
215
+ <react_native_1.View style={styles.aiSection}>
216
+ <react_native_1.Text style={styles.sectionTitle}>AI Prompt</react_native_1.Text>
217
+ <react_native_1.TextInput style={styles.input} placeholder={`Tell ${selectedComponent.name} what to do...`} placeholderTextColor="#636366" value={prompt} onChangeText={setPrompt} multiline numberOfLines={2}/>
218
+
219
+ <react_native_1.View style={styles.agentGrid}>
220
+ <react_native_1.TouchableOpacity style={[styles.agentButton, isLoading && styles.agentButtonDisabled]} onPress={() => handleSend('cursor')} disabled={isLoading}>
221
+ {loadingAgent === 'cursor' ? (<react_native_1.ActivityIndicator size="small" color="#8B5CF6"/>) : (<react_native_1.Text style={styles.agentButtonText}>Cursor</react_native_1.Text>)}
222
+ </react_native_1.TouchableOpacity>
223
+
224
+ <react_native_1.TouchableOpacity style={[styles.agentButton, isLoading && styles.agentButtonDisabled]} onPress={() => handleSend('claude-code')} disabled={isLoading}>
225
+ {loadingAgent === 'claude-code' ? (<react_native_1.ActivityIndicator size="small" color="#FF6B35"/>) : (<react_native_1.Text style={styles.agentButtonText}>Claude</react_native_1.Text>)}
226
+ </react_native_1.TouchableOpacity>
227
+
228
+ <react_native_1.TouchableOpacity style={[styles.agentButton, isLoading && styles.agentButtonDisabled]} onPress={() => handleSend('opencode')} disabled={isLoading}>
229
+ {loadingAgent === 'opencode' ? (<react_native_1.ActivityIndicator size="small" color="#10B981"/>) : (<react_native_1.Text style={styles.agentButtonText}>OpenCode</react_native_1.Text>)}
230
+ </react_native_1.TouchableOpacity>
231
+ </react_native_1.View>
232
+ </react_native_1.View>
233
+ </react_native_1.ScrollView>
234
+ </react_native_1.View>
235
+ </react_native_1.View>
236
+ </>);
237
+ }
238
+ const styles = react_native_1.StyleSheet.create({
239
+ backdrop: {
240
+ ...react_native_1.StyleSheet.absoluteFillObject,
241
+ backgroundColor: 'rgba(0, 0, 0, 0.08)', // Very subtle backdrop
242
+ },
243
+ tooltip: {
244
+ position: 'absolute',
245
+ left: 8,
246
+ right: 8,
247
+ zIndex: 1000,
248
+ },
249
+ container: {
250
+ backgroundColor: 'rgba(28, 28, 30, 0.95)', // Semi-transparent dark
251
+ borderRadius: 16,
252
+ maxHeight: 320,
253
+ shadowColor: '#000',
254
+ shadowOffset: { width: 0, height: 8 },
255
+ shadowOpacity: 0.4,
256
+ shadowRadius: 16,
257
+ elevation: 20,
258
+ borderWidth: 1,
259
+ borderColor: 'rgba(255, 255, 255, 0.15)',
260
+ },
261
+ header: {
262
+ flexDirection: 'row',
263
+ alignItems: 'center',
264
+ paddingHorizontal: 16,
265
+ paddingTop: 14,
266
+ paddingBottom: 10,
267
+ borderBottomWidth: 1,
268
+ borderBottomColor: 'rgba(255, 255, 255, 0.1)',
269
+ },
270
+ titleContainer: {
271
+ flex: 1,
272
+ minWidth: 0,
273
+ },
274
+ componentName: {
275
+ fontSize: 18,
276
+ fontWeight: '700',
277
+ color: '#FFFFFF',
278
+ letterSpacing: -0.3,
279
+ },
280
+ headerButton: {
281
+ padding: 6,
282
+ marginLeft: 8,
283
+ },
284
+ codeIcon: {
285
+ paddingHorizontal: 8,
286
+ paddingVertical: 4,
287
+ backgroundColor: '#0A84FF',
288
+ borderRadius: 6,
289
+ },
290
+ codeIconText: {
291
+ color: '#FFFFFF',
292
+ fontSize: 12,
293
+ fontWeight: '700',
294
+ fontFamily: react_native_1.Platform.OS === 'ios' ? 'Menlo' : 'monospace',
295
+ },
296
+ closeIcon: {
297
+ width: 24,
298
+ height: 24,
299
+ borderRadius: 12,
300
+ backgroundColor: 'rgba(255, 255, 255, 0.15)',
301
+ justifyContent: 'center',
302
+ alignItems: 'center',
303
+ },
304
+ closeIconLine: {
305
+ position: 'absolute',
306
+ width: 12,
307
+ height: 2,
308
+ backgroundColor: '#FFFFFF',
309
+ borderRadius: 1,
310
+ },
311
+ breadcrumbContainer: {
312
+ backgroundColor: 'rgba(0, 0, 0, 0.3)',
313
+ borderBottomWidth: 1,
314
+ borderBottomColor: 'rgba(255, 255, 255, 0.05)',
315
+ },
316
+ breadcrumbScroll: {
317
+ paddingHorizontal: 12,
318
+ paddingVertical: 8,
319
+ alignItems: 'center',
320
+ },
321
+ breadcrumbItem: {
322
+ paddingHorizontal: 8,
323
+ paddingVertical: 4,
324
+ borderRadius: 6,
325
+ },
326
+ breadcrumbItemActive: {
327
+ backgroundColor: 'rgba(255, 255, 255, 0.15)',
328
+ },
329
+ breadcrumbText: {
330
+ color: '#8E8E93',
331
+ fontSize: 12,
332
+ fontWeight: '500',
333
+ },
334
+ breadcrumbTextActive: {
335
+ color: '#FFFFFF',
336
+ fontWeight: '700',
337
+ },
338
+ breadcrumbTextNoSource: {
339
+ opacity: 0.5,
340
+ fontStyle: 'italic',
341
+ },
342
+ breadcrumbSeparator: {
343
+ color: 'rgba(255, 255, 255, 0.3)',
344
+ fontSize: 14,
345
+ marginHorizontal: 2,
346
+ },
347
+ scrollContent: {
348
+ maxHeight: 240,
349
+ },
350
+ scrollContentContainer: {
351
+ paddingHorizontal: 16,
352
+ paddingTop: 12,
353
+ paddingBottom: 16,
354
+ },
355
+ divider: {
356
+ height: 1,
357
+ backgroundColor: 'rgba(255, 255, 255, 0.1)',
358
+ marginVertical: 12,
359
+ },
360
+ sourceRow: {
361
+ flexDirection: 'row',
362
+ alignItems: 'center',
363
+ gap: 8,
364
+ },
365
+ dimensionsRow: {
366
+ flexDirection: 'row',
367
+ alignItems: 'center',
368
+ gap: 8,
369
+ marginBottom: 8,
370
+ },
371
+ dimensionsValue: {
372
+ fontSize: 13,
373
+ color: '#FFFFFF',
374
+ fontWeight: '600',
375
+ fontFamily: react_native_1.Platform.OS === 'ios' ? 'Menlo' : 'monospace',
376
+ },
377
+ boxModelRow: {
378
+ flexDirection: 'row',
379
+ gap: 12,
380
+ marginBottom: 8,
381
+ },
382
+ boxModelItem: {
383
+ flexDirection: 'row',
384
+ alignItems: 'center',
385
+ gap: 4,
386
+ },
387
+ boxModelColor: {
388
+ width: 10,
389
+ height: 10,
390
+ borderRadius: 2,
391
+ },
392
+ boxModelLabel: {
393
+ fontSize: 11,
394
+ fontWeight: '600',
395
+ color: '#8E8E93',
396
+ },
397
+ boxModelValue: {
398
+ fontSize: 11,
399
+ color: '#FFFFFF',
400
+ fontFamily: react_native_1.Platform.OS === 'ios' ? 'Menlo' : 'monospace',
401
+ },
402
+ label: {
403
+ fontSize: 11,
404
+ fontWeight: '600',
405
+ color: '#8E8E93',
406
+ textTransform: 'uppercase',
407
+ letterSpacing: 0.5,
408
+ },
409
+ filePathScroll: {
410
+ flex: 1,
411
+ maxWidth: 240,
412
+ },
413
+ filePath: {
414
+ fontSize: 11,
415
+ color: '#FFFFFF',
416
+ fontFamily: react_native_1.Platform.OS === 'ios' ? 'Menlo' : 'monospace',
417
+ },
418
+ copyButton: {
419
+ paddingHorizontal: 8,
420
+ paddingVertical: 4,
421
+ },
422
+ copyText: {
423
+ fontSize: 11,
424
+ color: '#0A84FF',
425
+ fontWeight: '600',
426
+ },
427
+ aiSection: {
428
+ marginTop: 4,
429
+ },
430
+ sectionTitle: {
431
+ fontSize: 13,
432
+ fontWeight: '600',
433
+ color: '#FFFFFF',
434
+ marginBottom: 10,
435
+ },
436
+ input: {
437
+ backgroundColor: 'rgba(255, 255, 255, 0.1)',
438
+ borderRadius: 10,
439
+ padding: 10,
440
+ fontSize: 13,
441
+ color: '#FFFFFF',
442
+ minHeight: 50,
443
+ textAlignVertical: 'top',
444
+ marginBottom: 12,
445
+ },
446
+ agentGrid: {
447
+ flexDirection: 'row',
448
+ gap: 8,
449
+ },
450
+ agentButton: {
451
+ flex: 1,
452
+ paddingVertical: 10,
453
+ borderRadius: 8,
454
+ alignItems: 'center',
455
+ justifyContent: 'center',
456
+ backgroundColor: 'rgba(255, 255, 255, 0.1)',
457
+ minHeight: 40,
458
+ },
459
+ agentButtonDisabled: {
460
+ opacity: 0.5,
461
+ },
462
+ agentButtonText: {
463
+ color: '#FFFFFF',
464
+ fontSize: 12,
465
+ fontWeight: '600',
466
+ },
467
+ });
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ interface RNAVEProviderProps {
3
+ children: React.ReactNode;
4
+ }
5
+ /**
6
+ * Internal provider component for rn-ave
7
+ * This is used by auto-initialization only - not meant to be used directly
8
+ */
9
+ export declare function RNAVEProvider({ children }: RNAVEProviderProps): React.JSX.Element;
10
+ export {};