rn-studio 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.
Files changed (57) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +116 -0
  3. package/babel-plugin/index.js +68 -0
  4. package/bin/rn-studio-server.js +98 -0
  5. package/dist/StudioProvider.d.ts +25 -0
  6. package/dist/StudioProvider.d.ts.map +1 -0
  7. package/dist/StudioProvider.js +131 -0
  8. package/dist/StudioProvider.js.map +1 -0
  9. package/dist/ast/AstEngine.d.ts +16 -0
  10. package/dist/ast/AstEngine.d.ts.map +1 -0
  11. package/dist/ast/AstEngine.js +153 -0
  12. package/dist/ast/AstEngine.js.map +1 -0
  13. package/dist/bridge/WebSocketBridge.d.ts +24 -0
  14. package/dist/bridge/WebSocketBridge.d.ts.map +1 -0
  15. package/dist/bridge/WebSocketBridge.js +94 -0
  16. package/dist/bridge/WebSocketBridge.js.map +1 -0
  17. package/dist/components/ComponentTree.d.ts +9 -0
  18. package/dist/components/ComponentTree.d.ts.map +1 -0
  19. package/dist/components/ComponentTree.js +65 -0
  20. package/dist/components/ComponentTree.js.map +1 -0
  21. package/dist/components/FloatingBubble.d.ts +8 -0
  22. package/dist/components/FloatingBubble.d.ts.map +1 -0
  23. package/dist/components/FloatingBubble.js +205 -0
  24. package/dist/components/FloatingBubble.js.map +1 -0
  25. package/dist/components/InspectorPanel.d.ts +9 -0
  26. package/dist/components/InspectorPanel.d.ts.map +1 -0
  27. package/dist/components/InspectorPanel.js +242 -0
  28. package/dist/components/InspectorPanel.js.map +1 -0
  29. package/dist/components/SelectionOverlay.d.ts +15 -0
  30. package/dist/components/SelectionOverlay.d.ts.map +1 -0
  31. package/dist/components/SelectionOverlay.js +152 -0
  32. package/dist/components/SelectionOverlay.js.map +1 -0
  33. package/dist/components/StyleEditor.d.ts +10 -0
  34. package/dist/components/StyleEditor.d.ts.map +1 -0
  35. package/dist/components/StyleEditor.js +144 -0
  36. package/dist/components/StyleEditor.js.map +1 -0
  37. package/dist/context/StudioContext.d.ts +7 -0
  38. package/dist/context/StudioContext.d.ts.map +1 -0
  39. package/dist/context/StudioContext.js +10 -0
  40. package/dist/context/StudioContext.js.map +1 -0
  41. package/dist/index.d.ts +24 -0
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +34 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/types.d.ts +95 -0
  46. package/dist/types.d.ts.map +1 -0
  47. package/dist/types.js +10 -0
  48. package/dist/types.js.map +1 -0
  49. package/dist/utils/fiberWalker.d.ts +36 -0
  50. package/dist/utils/fiberWalker.d.ts.map +1 -0
  51. package/dist/utils/fiberWalker.js +122 -0
  52. package/dist/utils/fiberWalker.js.map +1 -0
  53. package/dist/utils/measureComponent.d.ts +15 -0
  54. package/dist/utils/measureComponent.d.ts.map +1 -0
  55. package/dist/utils/measureComponent.js +28 -0
  56. package/dist/utils/measureComponent.js.map +1 -0
  57. package/package.json +72 -0
@@ -0,0 +1,242 @@
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.InspectorPanel = void 0;
37
+ const react_1 = __importStar(require("react"));
38
+ const react_native_1 = require("react-native");
39
+ const StudioProvider_1 = require("../StudioProvider");
40
+ const StyleEditor_1 = require("./StyleEditor");
41
+ const ComponentTree_1 = require("./ComponentTree");
42
+ // Reanimated is a declared peer dependency. We attempt to use it for
43
+ // the spring-based slide, falling back to the stock Animated API so the
44
+ // overlay remains functional in environments where reanimated is not
45
+ // yet configured.
46
+ let Reanimated = null;
47
+ let useSharedValue = null;
48
+ let useAnimatedStyle = null;
49
+ let withSpring = null;
50
+ let withTiming = null;
51
+ try {
52
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
53
+ const r = require('react-native-reanimated');
54
+ Reanimated = r.default;
55
+ useSharedValue = r.useSharedValue;
56
+ useAnimatedStyle = r.useAnimatedStyle;
57
+ withSpring = r.withSpring;
58
+ withTiming = r.withTiming;
59
+ }
60
+ catch { }
61
+ const { height: SCREEN_HEIGHT } = react_native_1.Dimensions.get('window');
62
+ const PANEL_HEIGHT = SCREEN_HEIGHT * 0.6;
63
+ /**
64
+ * InspectorPanel
65
+ *
66
+ * Bottom sheet shown when a component is selected. Three tabs:
67
+ * Styles | Tree | Props. Slides up with a spring animation.
68
+ */
69
+ const InspectorPanel = () => {
70
+ const { selectedComponent, clearSelection } = (0, StudioProvider_1.useStudio)();
71
+ const [tab, setTab] = (0, react_1.useState)('styles');
72
+ const visible = !!selectedComponent;
73
+ if (Reanimated && useSharedValue) {
74
+ return (react_1.default.createElement(ReanimatedPanel, { visible: visible, onDismiss: clearSelection, tab: tab, setTab: setTab }));
75
+ }
76
+ // Fallback: render plainly when reanimated is unavailable.
77
+ if (!visible)
78
+ return null;
79
+ return (react_1.default.createElement(react_native_1.View, { style: [styles.panel, { transform: [{ translateY: 0 }] }] },
80
+ react_1.default.createElement(PanelChrome, { tab: tab, setTab: setTab, onDismiss: clearSelection }),
81
+ tab === 'styles' && react_1.default.createElement(StyleEditor_1.StyleEditor, null),
82
+ tab === 'tree' && react_1.default.createElement(ComponentTree_1.ComponentTree, null),
83
+ tab === 'props' && react_1.default.createElement(PropsView, null)));
84
+ };
85
+ exports.InspectorPanel = InspectorPanel;
86
+ const ReanimatedPanel = ({ visible, onDismiss, tab, setTab }) => {
87
+ const translateY = useSharedValue(PANEL_HEIGHT);
88
+ (0, react_1.useEffect)(() => {
89
+ translateY.value = visible
90
+ ? withSpring(0, { damping: 20, stiffness: 200 })
91
+ : withTiming(PANEL_HEIGHT, { duration: 220 });
92
+ }, [visible, translateY]);
93
+ const animStyle = useAnimatedStyle(() => ({
94
+ transform: [{ translateY: translateY.value }],
95
+ }));
96
+ if (!visible)
97
+ return null;
98
+ const AnimatedView = Reanimated.View;
99
+ return (react_1.default.createElement(react_1.default.Fragment, null,
100
+ react_1.default.createElement(react_native_1.TouchableOpacity, { activeOpacity: 1, onPress: onDismiss, style: styles.backdrop }),
101
+ react_1.default.createElement(AnimatedView, { style: [styles.panel, animStyle] },
102
+ react_1.default.createElement(PanelChrome, { tab: tab, setTab: setTab, onDismiss: onDismiss }),
103
+ tab === 'styles' && react_1.default.createElement(StyleEditor_1.StyleEditor, null),
104
+ tab === 'tree' && react_1.default.createElement(ComponentTree_1.ComponentTree, null),
105
+ tab === 'props' && react_1.default.createElement(PropsView, null))));
106
+ };
107
+ const PanelChrome = ({ tab, setTab, onDismiss }) => {
108
+ const { selectedComponent } = (0, StudioProvider_1.useStudio)();
109
+ return (react_1.default.createElement(react_native_1.View, null,
110
+ react_1.default.createElement(react_native_1.View, { style: styles.handleWrap },
111
+ react_1.default.createElement(react_native_1.View, { style: styles.handle })),
112
+ react_1.default.createElement(react_native_1.View, { style: styles.header },
113
+ react_1.default.createElement(react_native_1.Text, { style: styles.title, numberOfLines: 1 }, selectedComponent ? selectedComponent.componentName : 'Inspector'),
114
+ react_1.default.createElement(react_native_1.TouchableOpacity, { onPress: onDismiss, hitSlop: { top: 12, bottom: 12, left: 12, right: 12 } },
115
+ react_1.default.createElement(react_native_1.Text, { style: styles.close }, "\u2715"))),
116
+ react_1.default.createElement(react_native_1.View, { style: styles.tabs },
117
+ react_1.default.createElement(TabButton, { label: "Styles", active: tab === 'styles', onPress: () => setTab('styles') }),
118
+ react_1.default.createElement(TabButton, { label: "Tree", active: tab === 'tree', onPress: () => setTab('tree') }),
119
+ react_1.default.createElement(TabButton, { label: "Props", active: tab === 'props', onPress: () => setTab('props') }))));
120
+ };
121
+ const TabButton = ({ label, active, onPress, }) => (react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.tab, active && styles.tabActive], onPress: onPress },
122
+ react_1.default.createElement(react_native_1.Text, { style: [styles.tabText, active && styles.tabTextActive] }, label)));
123
+ const PropsView = () => {
124
+ const { selectedComponent } = (0, StudioProvider_1.useStudio)();
125
+ if (!selectedComponent) {
126
+ return (react_1.default.createElement(react_native_1.View, { style: styles.empty },
127
+ react_1.default.createElement(react_native_1.Text, { style: styles.emptyText }, "No component selected")));
128
+ }
129
+ const entries = Object.entries(selectedComponent.props).filter(([k]) => k !== 'style' && k !== 'children' && k !== '__rnStudioSource');
130
+ if (!entries.length) {
131
+ return (react_1.default.createElement(react_native_1.View, { style: styles.empty },
132
+ react_1.default.createElement(react_native_1.Text, { style: styles.emptyText }, "No inspectable props")));
133
+ }
134
+ return (react_1.default.createElement(react_native_1.View, { style: { padding: 16 } }, entries.map(([k, v]) => (react_1.default.createElement(react_native_1.View, { key: k, style: styles.propRow },
135
+ react_1.default.createElement(react_native_1.Text, { style: styles.propKey }, k),
136
+ react_1.default.createElement(react_native_1.Text, { style: styles.propValue, numberOfLines: 2 }, safeStringify(v)))))));
137
+ };
138
+ function safeStringify(v) {
139
+ if (v === null)
140
+ return 'null';
141
+ if (typeof v === 'function')
142
+ return 'ƒ()';
143
+ if (typeof v === 'object') {
144
+ try {
145
+ return JSON.stringify(v);
146
+ }
147
+ catch {
148
+ return '[object]';
149
+ }
150
+ }
151
+ return String(v);
152
+ }
153
+ const styles = react_native_1.StyleSheet.create({
154
+ backdrop: {
155
+ position: 'absolute',
156
+ top: 0,
157
+ left: 0,
158
+ right: 0,
159
+ bottom: PANEL_HEIGHT,
160
+ backgroundColor: 'transparent',
161
+ },
162
+ panel: {
163
+ position: 'absolute',
164
+ left: 0,
165
+ right: 0,
166
+ bottom: 0,
167
+ height: PANEL_HEIGHT,
168
+ backgroundColor: '#111',
169
+ borderTopLeftRadius: 16,
170
+ borderTopRightRadius: 16,
171
+ zIndex: 999998,
172
+ elevation: 16,
173
+ shadowColor: '#000',
174
+ shadowOffset: { width: 0, height: -4 },
175
+ shadowOpacity: 0.4,
176
+ shadowRadius: 12,
177
+ },
178
+ handleWrap: { alignItems: 'center', paddingTop: 8 },
179
+ handle: {
180
+ width: 40,
181
+ height: 4,
182
+ borderRadius: 2,
183
+ backgroundColor: '#444',
184
+ },
185
+ header: {
186
+ flexDirection: 'row',
187
+ alignItems: 'center',
188
+ justifyContent: 'space-between',
189
+ paddingHorizontal: 16,
190
+ paddingVertical: 12,
191
+ },
192
+ title: {
193
+ color: '#fff',
194
+ fontSize: 16,
195
+ fontWeight: '700',
196
+ },
197
+ close: {
198
+ color: '#888',
199
+ fontSize: 18,
200
+ },
201
+ tabs: {
202
+ flexDirection: 'row',
203
+ backgroundColor: '#1a1a1a',
204
+ },
205
+ tab: {
206
+ flex: 1,
207
+ paddingVertical: 12,
208
+ alignItems: 'center',
209
+ },
210
+ tabActive: {
211
+ borderBottomWidth: 2,
212
+ borderBottomColor: '#C6F135',
213
+ },
214
+ tabText: {
215
+ color: '#888',
216
+ fontSize: 13,
217
+ fontWeight: '600',
218
+ },
219
+ tabTextActive: {
220
+ color: '#C6F135',
221
+ },
222
+ empty: { padding: 32, alignItems: 'center' },
223
+ emptyText: { color: '#888', fontSize: 13 },
224
+ propRow: {
225
+ paddingVertical: 8,
226
+ borderBottomWidth: react_native_1.StyleSheet.hairlineWidth,
227
+ borderBottomColor: '#222',
228
+ },
229
+ propKey: {
230
+ color: '#C6F135',
231
+ fontSize: 12,
232
+ fontFamily: 'Menlo',
233
+ fontWeight: '600',
234
+ },
235
+ propValue: {
236
+ color: '#ddd',
237
+ fontSize: 12,
238
+ fontFamily: 'Menlo',
239
+ marginTop: 2,
240
+ },
241
+ });
242
+ //# sourceMappingURL=InspectorPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InspectorPanel.js","sourceRoot":"","sources":["../../src/components/InspectorPanel.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ /**
3
+ * SelectionOverlay
4
+ *
5
+ * Full-screen overlay that dims the app when selection mode is active
6
+ * and draws a lime-green highlight box around the selected component.
7
+ *
8
+ * Touch resolution strategy: the overlay captures the touch, then asks
9
+ * the UIManager which native view is under the touch point via
10
+ * `findSubviewIn`. From that view ref we walk the fiber tree upwards
11
+ * (see fiberWalker.ts) to find the nearest component with
12
+ * `__rnStudioSource` metadata.
13
+ */
14
+ export declare const SelectionOverlay: React.FC;
15
+ //# sourceMappingURL=SelectionOverlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectionOverlay.d.ts","sourceRoot":"","sources":["../../src/components/SelectionOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAa3D;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAqHpC,CAAC"}
@@ -0,0 +1,152 @@
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.SelectionOverlay = void 0;
37
+ const react_1 = __importStar(require("react"));
38
+ const react_native_1 = require("react-native");
39
+ const StudioProvider_1 = require("../StudioProvider");
40
+ const fiberWalker_1 = require("../utils/fiberWalker");
41
+ /**
42
+ * SelectionOverlay
43
+ *
44
+ * Full-screen overlay that dims the app when selection mode is active
45
+ * and draws a lime-green highlight box around the selected component.
46
+ *
47
+ * Touch resolution strategy: the overlay captures the touch, then asks
48
+ * the UIManager which native view is under the touch point via
49
+ * `findSubviewIn`. From that view ref we walk the fiber tree upwards
50
+ * (see fiberWalker.ts) to find the nearest component with
51
+ * `__rnStudioSource` metadata.
52
+ */
53
+ const SelectionOverlay = () => {
54
+ const { isActive, isSelecting, selectedComponent, selectComponent } = (0, StudioProvider_1.useStudio)();
55
+ const rootRef = (0, react_1.useRef)(null);
56
+ const [highlight, setHighlight] = (0, react_1.useState)(null);
57
+ const opacity = (0, react_1.useRef)(new react_native_1.Animated.Value(0)).current;
58
+ const borderOpacity = (0, react_1.useRef)(new react_native_1.Animated.Value(0)).current;
59
+ (0, react_1.useEffect)(() => {
60
+ react_native_1.Animated.timing(opacity, {
61
+ toValue: isActive ? 1 : 0,
62
+ duration: 200,
63
+ useNativeDriver: true,
64
+ }).start();
65
+ }, [isActive, opacity]);
66
+ (0, react_1.useEffect)(() => {
67
+ if (selectedComponent) {
68
+ react_native_1.Animated.timing(borderOpacity, {
69
+ toValue: 1,
70
+ duration: 150,
71
+ useNativeDriver: true,
72
+ }).start();
73
+ }
74
+ else {
75
+ borderOpacity.setValue(0);
76
+ }
77
+ }, [selectedComponent, borderOpacity]);
78
+ const handleTouch = (evt) => {
79
+ if (!isSelecting)
80
+ return false;
81
+ const { pageX, pageY } = evt.nativeEvent;
82
+ const rootHandle = (0, react_native_1.findNodeHandle)(rootRef.current);
83
+ if (!rootHandle)
84
+ return true;
85
+ // findSubviewIn gives us the native view at a point. Then we climb
86
+ // the fiber tree to locate the nearest source-annotated owner.
87
+ try {
88
+ react_native_1.UIManager.findSubviewIn(rootHandle, [pageX, pageY, 1, 1], (_nativeX, _nativeY, _w, _h, tag) => {
89
+ if (!tag)
90
+ return;
91
+ const fiber = (0, fiberWalker_1.fiberFromRef)({ stateNode: { _nativeTag: tag } });
92
+ // Most RN versions expose the fiber via private keys on the
93
+ // underlying view component instance; the walker defensively
94
+ // searches for them. If no fiber is found we still draw a
95
+ // placeholder highlight at the touch location.
96
+ let owner = null;
97
+ if (fiber)
98
+ owner = (0, fiberWalker_1.findSourceOwner)(fiber);
99
+ if (owner) {
100
+ const node = (0, fiberWalker_1.buildComponentNode)(owner.fiber, owner.source);
101
+ selectComponent(node);
102
+ }
103
+ // Draw highlight at touch point (approximate). A production
104
+ // implementation would call measureInWindow on the resolved
105
+ // native component for a pixel-perfect box.
106
+ setHighlight({
107
+ x: pageX - 30,
108
+ y: pageY - 30,
109
+ width: 60,
110
+ height: 60,
111
+ });
112
+ });
113
+ }
114
+ catch {
115
+ // UIManager.findSubviewIn is not available on every platform; in
116
+ // that case we still acknowledge the touch so the user gets
117
+ // feedback.
118
+ }
119
+ triggerHaptic('impactMedium');
120
+ return true;
121
+ };
122
+ if (!isActive)
123
+ return null;
124
+ const { width, height } = react_native_1.Dimensions.get('window');
125
+ return (react_1.default.createElement(react_native_1.View, { ref: rootRef, pointerEvents: isSelecting ? 'box-only' : 'none', style: react_native_1.StyleSheet.absoluteFill, onStartShouldSetResponder: () => isSelecting, onResponderGrant: handleTouch },
126
+ react_1.default.createElement(react_native_1.Animated.View, { pointerEvents: "none", style: [
127
+ react_native_1.StyleSheet.absoluteFill,
128
+ { backgroundColor: 'rgba(0,0,0,0.3)', opacity },
129
+ ] }),
130
+ highlight && (react_1.default.createElement(react_native_1.Animated.View, { pointerEvents: "none", style: {
131
+ position: 'absolute',
132
+ left: highlight.x,
133
+ top: highlight.y,
134
+ width: highlight.width,
135
+ height: highlight.height,
136
+ borderWidth: 2,
137
+ borderColor: '#C6F135',
138
+ borderRadius: 4,
139
+ opacity: borderOpacity,
140
+ } })),
141
+ react_1.default.createElement(react_native_1.View, { pointerEvents: "none", style: { position: 'absolute', width, height } })));
142
+ };
143
+ exports.SelectionOverlay = SelectionOverlay;
144
+ function triggerHaptic(type) {
145
+ try {
146
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
147
+ const Haptic = require('react-native-haptic-feedback').default;
148
+ Haptic.trigger(type, { enableVibrateFallback: false, ignoreAndroidSystemSettings: false });
149
+ }
150
+ catch { }
151
+ }
152
+ //# sourceMappingURL=SelectionOverlay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectionOverlay.js","sourceRoot":"","sources":["../../src/components/SelectionOverlay.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ /**
3
+ * StyleEditor
4
+ *
5
+ * Flat list of editable style properties for the currently selected
6
+ * component. Value changes are debounced (300ms) before being flushed
7
+ * through the WebSocket bridge.
8
+ */
9
+ export declare const StyleEditor: React.FC;
10
+ //# sourceMappingURL=StyleEditor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StyleEditor.d.ts","sourceRoot":"","sources":["../../src/components/StyleEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAY3D;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAkC/B,CAAC"}
@@ -0,0 +1,144 @@
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.StyleEditor = void 0;
37
+ const react_1 = __importStar(require("react"));
38
+ const react_native_1 = require("react-native");
39
+ const StudioProvider_1 = require("../StudioProvider");
40
+ /**
41
+ * StyleEditor
42
+ *
43
+ * Flat list of editable style properties for the currently selected
44
+ * component. Value changes are debounced (300ms) before being flushed
45
+ * through the WebSocket bridge.
46
+ */
47
+ const StyleEditor = () => {
48
+ const { selectedComponent, updateStyle } = (0, StudioProvider_1.useStudio)();
49
+ if (!selectedComponent) {
50
+ return (react_1.default.createElement(react_native_1.View, { style: styles.empty },
51
+ react_1.default.createElement(react_native_1.Text, { style: styles.emptyText }, "No component selected")));
52
+ }
53
+ if (!selectedComponent.styles.length) {
54
+ return (react_1.default.createElement(react_native_1.View, { style: styles.empty },
55
+ react_1.default.createElement(react_native_1.Text, { style: styles.emptyText }, "This component has no inline styles to edit.")));
56
+ }
57
+ return (react_1.default.createElement(react_native_1.FlatList, { data: selectedComponent.styles, keyExtractor: (s) => s.key, contentContainerStyle: styles.list, renderItem: ({ item }) => (react_1.default.createElement(StyleRow, { property: item, onCommit: (value) => updateStyle(item.key, value) })) }));
58
+ };
59
+ exports.StyleEditor = StyleEditor;
60
+ const StyleRow = ({ property, onCommit }) => {
61
+ const [value, setValue] = (0, react_1.useState)(String(property.value));
62
+ const [ackVisible, setAckVisible] = (0, react_1.useState)(false);
63
+ const debounce = (0, react_1.useRef)(null);
64
+ (0, react_1.useEffect)(() => {
65
+ setValue(String(property.value));
66
+ }, [property.value]);
67
+ const schedule = (next) => {
68
+ setValue(next);
69
+ if (debounce.current)
70
+ clearTimeout(debounce.current);
71
+ debounce.current = setTimeout(() => {
72
+ const coerced = property.type === 'number' ? Number(next) : next;
73
+ if (property.type === 'number' && Number.isNaN(coerced))
74
+ return;
75
+ onCommit(coerced);
76
+ setAckVisible(true);
77
+ setTimeout(() => setAckVisible(false), 1000);
78
+ }, 300);
79
+ };
80
+ return (react_1.default.createElement(react_native_1.View, { style: styles.row },
81
+ react_1.default.createElement(react_native_1.View, { style: styles.labelWrap },
82
+ property.type === 'color' && (react_1.default.createElement(react_native_1.TouchableOpacity, { style: [
83
+ styles.swatch,
84
+ { backgroundColor: String(property.value) },
85
+ ], activeOpacity: 0.7 })),
86
+ react_1.default.createElement(react_native_1.Text, { style: styles.label }, property.key)),
87
+ react_1.default.createElement(react_native_1.View, { style: styles.inputWrap },
88
+ react_1.default.createElement(react_native_1.TextInput, { style: styles.input, value: value, onChangeText: schedule, keyboardType: property.type === 'number' ? 'numeric' : 'default', autoCapitalize: "none", autoCorrect: false, selectionColor: "#C6F135", placeholderTextColor: "#666" }),
89
+ ackVisible && react_1.default.createElement(react_native_1.Text, { style: styles.check }, "\u2713"))));
90
+ };
91
+ const styles = react_native_1.StyleSheet.create({
92
+ list: { padding: 16 },
93
+ row: {
94
+ flexDirection: 'row',
95
+ alignItems: 'center',
96
+ paddingVertical: 10,
97
+ borderBottomWidth: react_native_1.StyleSheet.hairlineWidth,
98
+ borderBottomColor: '#2a2a2a',
99
+ },
100
+ labelWrap: {
101
+ flex: 1,
102
+ flexDirection: 'row',
103
+ alignItems: 'center',
104
+ },
105
+ swatch: {
106
+ width: 16,
107
+ height: 16,
108
+ borderRadius: 4,
109
+ marginRight: 8,
110
+ borderWidth: 1,
111
+ borderColor: '#333',
112
+ },
113
+ label: {
114
+ color: '#ddd',
115
+ fontSize: 14,
116
+ fontFamily: 'Menlo',
117
+ },
118
+ inputWrap: {
119
+ flex: 1,
120
+ flexDirection: 'row',
121
+ alignItems: 'center',
122
+ justifyContent: 'flex-end',
123
+ },
124
+ input: {
125
+ backgroundColor: '#1a1a1a',
126
+ color: '#C6F135',
127
+ borderRadius: 6,
128
+ paddingHorizontal: 10,
129
+ paddingVertical: 6,
130
+ minWidth: 120,
131
+ textAlign: 'right',
132
+ fontFamily: 'Menlo',
133
+ fontSize: 13,
134
+ },
135
+ check: {
136
+ color: '#C6F135',
137
+ marginLeft: 8,
138
+ fontSize: 14,
139
+ fontWeight: '700',
140
+ },
141
+ empty: { padding: 32, alignItems: 'center' },
142
+ emptyText: { color: '#888', fontSize: 13 },
143
+ });
144
+ //# sourceMappingURL=StyleEditor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StyleEditor.js","sourceRoot":"","sources":["../../src/components/StyleEditor.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { StudioContextValue } from '../types';
2
+ /**
3
+ * React context carrying the live studio state. Consumers access it via
4
+ * the `useStudio()` hook exported from `StudioProvider`.
5
+ */
6
+ export declare const StudioContext: React.Context<StudioContextValue | null>;
7
+ //# sourceMappingURL=StudioContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StudioContext.d.ts","sourceRoot":"","sources":["../../src/context/StudioContext.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAEnD;;;GAGG;AACH,eAAO,MAAM,aAAa,0CAAiD,CAAC"}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StudioContext = void 0;
4
+ const react_1 = require("react");
5
+ /**
6
+ * React context carrying the live studio state. Consumers access it via
7
+ * the `useStudio()` hook exported from `StudioProvider`.
8
+ */
9
+ exports.StudioContext = (0, react_1.createContext)(null);
10
+ //# sourceMappingURL=StudioContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StudioContext.js","sourceRoot":"","sources":["../../src/context/StudioContext.ts"],"names":[],"mappings":";;;AAAA,iCAAsC;AAGtC;;;GAGG;AACU,QAAA,aAAa,GAAG,IAAA,qBAAa,EAA4B,IAAI,CAAC,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * rn-studio — public barrel exports
3
+ *
4
+ * Consumer usage:
5
+ *
6
+ * import { StudioProvider, useStudio } from 'rn-studio';
7
+ *
8
+ * export default function App() {
9
+ * return (
10
+ * <StudioProvider enabled={__DEV__} bubblePosition="bottom-right">
11
+ * <YourApp />
12
+ * </StudioProvider>
13
+ * );
14
+ * }
15
+ */
16
+ export { StudioProvider, useStudio } from './StudioProvider';
17
+ export { WebSocketBridge } from './bridge/WebSocketBridge';
18
+ export { FloatingBubble } from './components/FloatingBubble';
19
+ export { SelectionOverlay } from './components/SelectionOverlay';
20
+ export { InspectorPanel } from './components/InspectorPanel';
21
+ export { StyleEditor } from './components/StyleEditor';
22
+ export { ComponentTree } from './components/ComponentTree';
23
+ export type { SourceLocation, ComponentNode, StyleProperty, StudioConfig, BubblePosition, StudioContextValue, StudioMessage, StudioState, } from './types';
24
+ //# sourceMappingURL=index.d.ts.map