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 @@
1
+ {"version":3,"file":"WebSocketBridge.d.ts","sourceRoot":"","sources":["../../src/bridge/WebSocketBridge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C;;;;;;;GAOG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,WAAW,CAAM;IACzB,OAAO,CAAC,SAAS,CAGb;IACJ,OAAO,CAAC,cAAc,CAAS;gBAEnB,IAAI,SAAO;IAIvB,OAAO,IAAI,IAAI;IAqCf,OAAO,CAAC,iBAAiB;IASzB,IAAI,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI;IAM9B,EAAE,CACA,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,EAAE,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,IAAI,GAC/B,MAAM,IAAI;IAWb,UAAU,IAAI,IAAI;CASnB"}
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebSocketBridge = void 0;
4
+ /**
5
+ * WebSocketBridge
6
+ *
7
+ * Runs inside the React Native app (Metro bundle). Maintains a
8
+ * persistent connection to the rn-studio CLI server (default ws://localhost:7878).
9
+ * Automatically reconnects with exponential backoff if the server is
10
+ * not yet running — typical during a fresh `npm run studio`.
11
+ */
12
+ class WebSocketBridge {
13
+ constructor(port = 7878) {
14
+ this.ws = null;
15
+ this.reconnectAttempts = 0;
16
+ this.maxAttempts = 10;
17
+ this.listeners = new Map();
18
+ this.manuallyClosed = false;
19
+ this.port = port;
20
+ }
21
+ connect() {
22
+ this.manuallyClosed = false;
23
+ const url = `ws://localhost:${this.port}`;
24
+ try {
25
+ this.ws = new WebSocket(url);
26
+ }
27
+ catch {
28
+ this.scheduleReconnect();
29
+ return;
30
+ }
31
+ this.ws.onopen = () => {
32
+ this.reconnectAttempts = 0;
33
+ this.send({ type: 'PING' });
34
+ };
35
+ this.ws.onmessage = (e) => {
36
+ try {
37
+ const msg = JSON.parse(typeof e.data === 'string' ? e.data : String(e.data));
38
+ const cbs = this.listeners.get(msg.type);
39
+ if (cbs)
40
+ cbs.forEach((cb) => cb(msg));
41
+ }
42
+ catch {
43
+ // Malformed message — ignore.
44
+ }
45
+ };
46
+ this.ws.onclose = () => {
47
+ if (!this.manuallyClosed)
48
+ this.scheduleReconnect();
49
+ };
50
+ this.ws.onerror = () => {
51
+ // onclose will follow; reconnection handled there.
52
+ };
53
+ }
54
+ scheduleReconnect() {
55
+ if (this.reconnectAttempts >= this.maxAttempts)
56
+ return;
57
+ const delay = Math.min(1000 * 2 ** this.reconnectAttempts, 30000);
58
+ this.reconnectAttempts++;
59
+ setTimeout(() => {
60
+ if (!this.manuallyClosed)
61
+ this.connect();
62
+ }, delay);
63
+ }
64
+ send(msg) {
65
+ if (this.ws && this.ws.readyState === 1 /* WebSocket.OPEN */) {
66
+ this.ws.send(JSON.stringify(msg));
67
+ }
68
+ }
69
+ on(type, cb) {
70
+ if (!this.listeners.has(type))
71
+ this.listeners.set(type, []);
72
+ this.listeners.get(type).push(cb);
73
+ return () => {
74
+ const arr = this.listeners.get(type);
75
+ if (!arr)
76
+ return;
77
+ const idx = arr.indexOf(cb);
78
+ if (idx >= 0)
79
+ arr.splice(idx, 1);
80
+ };
81
+ }
82
+ disconnect() {
83
+ this.manuallyClosed = true;
84
+ if (this.ws) {
85
+ try {
86
+ this.ws.close();
87
+ }
88
+ catch { }
89
+ this.ws = null;
90
+ }
91
+ }
92
+ }
93
+ exports.WebSocketBridge = WebSocketBridge;
94
+ //# sourceMappingURL=WebSocketBridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebSocketBridge.js","sourceRoot":"","sources":["../../src/bridge/WebSocketBridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ /**
3
+ * ComponentTree
4
+ *
5
+ * Recursive tree view of the selected component and its known
6
+ * source-annotated descendants. Tapping a node re-selects it.
7
+ */
8
+ export declare const ComponentTree: React.FC;
9
+ //# sourceMappingURL=ComponentTree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ComponentTree.d.ts","sourceRoot":"","sources":["../../src/components/ComponentTree.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAgBjC,CAAC"}
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ComponentTree = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const react_native_1 = require("react-native");
9
+ const StudioProvider_1 = require("../StudioProvider");
10
+ /**
11
+ * ComponentTree
12
+ *
13
+ * Recursive tree view of the selected component and its known
14
+ * source-annotated descendants. Tapping a node re-selects it.
15
+ */
16
+ const ComponentTree = () => {
17
+ const { selectedComponent } = (0, StudioProvider_1.useStudio)();
18
+ if (!selectedComponent) {
19
+ return (react_1.default.createElement(react_native_1.View, { style: styles.empty },
20
+ react_1.default.createElement(react_native_1.Text, { style: styles.emptyText }, "No component selected")));
21
+ }
22
+ return (react_1.default.createElement(react_native_1.ScrollView, { contentContainerStyle: styles.container },
23
+ react_1.default.createElement(TreeNode, { node: selectedComponent, depth: 0 })));
24
+ };
25
+ exports.ComponentTree = ComponentTree;
26
+ const TreeNode = ({ node, depth }) => {
27
+ const { selectComponent } = (0, StudioProvider_1.useStudio)();
28
+ const fileShort = shortenFile(node.source.file);
29
+ return (react_1.default.createElement(react_native_1.View, null,
30
+ react_1.default.createElement(react_native_1.TouchableOpacity, { onPress: () => selectComponent(node), activeOpacity: 0.6, style: [styles.row, { paddingLeft: 12 + depth * 16 }] },
31
+ react_1.default.createElement(react_native_1.Text, { style: styles.name }, node.componentName),
32
+ react_1.default.createElement(react_native_1.Text, { style: styles.file, numberOfLines: 1 },
33
+ fileShort,
34
+ ":",
35
+ node.source.line)),
36
+ node.children.map((child) => (react_1.default.createElement(TreeNode, { key: child.id, node: child, depth: depth + 1 })))));
37
+ };
38
+ function shortenFile(file) {
39
+ const parts = file.split('/');
40
+ return parts.slice(-2).join('/');
41
+ }
42
+ const styles = react_native_1.StyleSheet.create({
43
+ container: { paddingVertical: 12 },
44
+ row: {
45
+ paddingVertical: 8,
46
+ paddingRight: 12,
47
+ borderBottomWidth: react_native_1.StyleSheet.hairlineWidth,
48
+ borderBottomColor: '#222',
49
+ },
50
+ name: {
51
+ color: '#C6F135',
52
+ fontSize: 14,
53
+ fontWeight: '600',
54
+ fontFamily: 'Menlo',
55
+ },
56
+ file: {
57
+ color: '#666',
58
+ fontSize: 11,
59
+ marginTop: 2,
60
+ fontFamily: 'Menlo',
61
+ },
62
+ empty: { padding: 32, alignItems: 'center' },
63
+ emptyText: { color: '#888', fontSize: 13 },
64
+ });
65
+ //# sourceMappingURL=ComponentTree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ComponentTree.js","sourceRoot":"","sources":["../../src/components/ComponentTree.tsx"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAC1B,+CAAoF;AACpF,sDAA8C;AAG9C;;;;;GAKG;AACI,MAAM,aAAa,GAAa,GAAG,EAAE;IAC1C,MAAM,EAAE,iBAAiB,EAAE,GAAG,IAAA,0BAAS,GAAE,CAAC;IAE1C,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,OAAO,CACL,8BAAC,mBAAI,IAAC,KAAK,EAAE,MAAM,CAAC,KAAK;YACvB,8BAAC,mBAAI,IAAC,KAAK,EAAE,MAAM,CAAC,SAAS,4BAA8B,CACtD,CACR,CAAC;IACJ,CAAC;IAED,OAAO,CACL,8BAAC,yBAAU,IAAC,qBAAqB,EAAE,MAAM,CAAC,SAAS;QACjD,8BAAC,QAAQ,IAAC,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC,GAAI,CACpC,CACd,CAAC;AACJ,CAAC,CAAC;AAhBW,QAAA,aAAa,iBAgBxB;AAOF,MAAM,QAAQ,GAAwB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;IACxD,MAAM,EAAE,eAAe,EAAE,GAAG,IAAA,0BAAS,GAAE,CAAC;IACxC,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAChD,OAAO,CACL,8BAAC,mBAAI;QACH,8BAAC,+BAAgB,IACf,OAAO,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,EACpC,aAAa,EAAE,GAAG,EAClB,KAAK,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,EAAE,GAAG,KAAK,GAAG,EAAE,EAAE,CAAC;YAErD,8BAAC,mBAAI,IAAC,KAAK,EAAE,MAAM,CAAC,IAAI,IAAG,IAAI,CAAC,aAAa,CAAQ;YACrD,8BAAC,mBAAI,IAAC,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,aAAa,EAAE,CAAC;gBACvC,SAAS;;gBAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CACxB,CACU;QAClB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAC5B,8BAAC,QAAQ,IAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,GAAI,CAC3D,CAAC,CACG,CACR,CAAC;AACJ,CAAC,CAAC;AAEF,SAAS,WAAW,CAAC,IAAY;IAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9B,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,MAAM,GAAG,yBAAU,CAAC,MAAM,CAAC;IAC/B,SAAS,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE;IAClC,GAAG,EAAE;QACH,eAAe,EAAE,CAAC;QAClB,YAAY,EAAE,EAAE;QAChB,iBAAiB,EAAE,yBAAU,CAAC,aAAa;QAC3C,iBAAiB,EAAE,MAAM;KAC1B;IACD,IAAI,EAAE;QACJ,KAAK,EAAE,SAAS;QAChB,QAAQ,EAAE,EAAE;QACZ,UAAU,EAAE,KAAK;QACjB,UAAU,EAAE,OAAO;KACpB;IACD,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM;QACb,QAAQ,EAAE,EAAE;QACZ,SAAS,EAAE,CAAC;QACZ,UAAU,EAAE,OAAO;KACpB;IACD,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE;IAC5C,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE;CAC3C,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import type { BubblePosition } from '../types';
3
+ interface Props {
4
+ position?: BubblePosition;
5
+ }
6
+ export declare const FloatingBubble: React.FC<Props>;
7
+ export {};
8
+ //# sourceMappingURL=FloatingBubble.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FloatingBubble.d.ts","sourceRoot":"","sources":["../../src/components/FloatingBubble.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAW3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAoB/C,UAAU,KAAK;IACb,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AA0BD,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAoH1C,CAAC"}
@@ -0,0 +1,205 @@
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.FloatingBubble = void 0;
37
+ const react_1 = __importStar(require("react"));
38
+ const react_native_1 = require("react-native");
39
+ const StudioProvider_1 = require("../StudioProvider");
40
+ // AsyncStorage is optional — if the consumer does not have it installed,
41
+ // we silently fall back to a per-session only position.
42
+ let AsyncStorage = null;
43
+ try {
44
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
45
+ AsyncStorage = require('@react-native-async-storage/async-storage').default;
46
+ }
47
+ catch { }
48
+ // Safe-area-context is a declared peer dependency; if missing we fall
49
+ // back to zero insets rather than crashing.
50
+ let useSafeAreaInsets;
51
+ try {
52
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
53
+ useSafeAreaInsets = require('react-native-safe-area-context').useSafeAreaInsets;
54
+ }
55
+ catch {
56
+ useSafeAreaInsets = () => ({ top: 0, bottom: 0, left: 0, right: 0 });
57
+ }
58
+ const SIZE = 52;
59
+ const STORAGE_KEY = '@rn-studio/bubble-position';
60
+ function initialXY(position, insets) {
61
+ const { width, height } = react_native_1.Dimensions.get('window');
62
+ const pad = 16;
63
+ const right = width - SIZE - pad - insets.right;
64
+ const left = pad + insets.left;
65
+ const top = pad + insets.top;
66
+ const bottom = height - SIZE - pad - insets.bottom;
67
+ switch (position) {
68
+ case 'bottom-left':
69
+ return { x: left, y: bottom };
70
+ case 'top-right':
71
+ return { x: right, y: top };
72
+ case 'top-left':
73
+ return { x: left, y: top };
74
+ case 'bottom-right':
75
+ default:
76
+ return { x: right, y: bottom };
77
+ }
78
+ }
79
+ const FloatingBubble = ({ position = 'bottom-right' }) => {
80
+ const { isActive, toggleActive } = (0, StudioProvider_1.useStudio)();
81
+ const insets = useSafeAreaInsets();
82
+ const [loaded, setLoaded] = (0, react_1.useState)(false);
83
+ const pan = (0, react_1.useRef)(new react_native_1.Animated.ValueXY(initialXY(position, insets))).current;
84
+ const scale = (0, react_1.useRef)(new react_native_1.Animated.Value(1)).current;
85
+ // Load persisted position.
86
+ (0, react_1.useEffect)(() => {
87
+ let mounted = true;
88
+ (async () => {
89
+ try {
90
+ if (AsyncStorage) {
91
+ const raw = await AsyncStorage.getItem(STORAGE_KEY);
92
+ if (raw && mounted) {
93
+ const parsed = JSON.parse(raw);
94
+ if (typeof parsed.x === 'number' && typeof parsed.y === 'number') {
95
+ pan.setValue(parsed);
96
+ }
97
+ }
98
+ }
99
+ }
100
+ catch { }
101
+ if (mounted)
102
+ setLoaded(true);
103
+ })();
104
+ return () => {
105
+ mounted = false;
106
+ };
107
+ }, [pan]);
108
+ const persist = (x, y) => {
109
+ if (AsyncStorage) {
110
+ AsyncStorage.setItem(STORAGE_KEY, JSON.stringify({ x, y })).catch(() => { });
111
+ }
112
+ };
113
+ const panResponder = (0, react_1.useRef)(react_native_1.PanResponder.create({
114
+ onStartShouldSetPanResponder: () => true,
115
+ onMoveShouldSetPanResponder: (_evt, g) => Math.abs(g.dx) > 2 || Math.abs(g.dy) > 2,
116
+ onPanResponderGrant: () => {
117
+ // @ts-ignore — Animated.ValueXY private but stable.
118
+ pan.setOffset({ x: pan.x._value, y: pan.y._value });
119
+ pan.setValue({ x: 0, y: 0 });
120
+ react_native_1.Animated.spring(scale, {
121
+ toValue: 0.9,
122
+ useNativeDriver: true,
123
+ }).start();
124
+ },
125
+ onPanResponderMove: react_native_1.Animated.event([null, { dx: pan.x, dy: pan.y }], { useNativeDriver: false }),
126
+ onPanResponderRelease: (_evt, g) => {
127
+ pan.flattenOffset();
128
+ react_native_1.Animated.spring(scale, {
129
+ toValue: 1,
130
+ useNativeDriver: true,
131
+ friction: 4,
132
+ }).start();
133
+ // Treat near-zero-distance gestures as taps.
134
+ if (Math.abs(g.dx) < 4 && Math.abs(g.dy) < 4) {
135
+ triggerHaptic('impactLight');
136
+ toggleActive();
137
+ return;
138
+ }
139
+ // Snap to nearest horizontal edge.
140
+ const { width, height } = react_native_1.Dimensions.get('window');
141
+ // @ts-ignore
142
+ const currentX = pan.x._value;
143
+ // @ts-ignore
144
+ const currentY = pan.y._value;
145
+ const leftEdge = 16 + insets.left;
146
+ const rightEdge = width - SIZE - 16 - insets.right;
147
+ const targetX = currentX + SIZE / 2 < width / 2 ? leftEdge : rightEdge;
148
+ const clampedY = Math.max(16 + insets.top, Math.min(currentY, height - SIZE - 16 - insets.bottom));
149
+ react_native_1.Animated.spring(pan, {
150
+ toValue: { x: targetX, y: clampedY },
151
+ useNativeDriver: false,
152
+ friction: 6,
153
+ tension: 60,
154
+ }).start(() => persist(targetX, clampedY));
155
+ },
156
+ })).current;
157
+ if (!loaded)
158
+ return null;
159
+ return (react_1.default.createElement(react_native_1.Animated.View, { ...panResponder.panHandlers, pointerEvents: "box-only", style: [
160
+ styles.bubble,
161
+ {
162
+ transform: [
163
+ { translateX: pan.x },
164
+ { translateY: pan.y },
165
+ { scale },
166
+ ],
167
+ backgroundColor: isActive ? '#C6F135' : '#222',
168
+ },
169
+ ] },
170
+ react_1.default.createElement(react_native_1.Text, { style: [styles.icon, { color: isActive ? '#111' : '#fff' }] }, isActive ? '✕' : '🎨')));
171
+ };
172
+ exports.FloatingBubble = FloatingBubble;
173
+ function triggerHaptic(type) {
174
+ try {
175
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
176
+ const Haptic = require('react-native-haptic-feedback').default;
177
+ Haptic.trigger(type, { enableVibrateFallback: false, ignoreAndroidSystemSettings: false });
178
+ }
179
+ catch { }
180
+ }
181
+ const styles = react_native_1.StyleSheet.create({
182
+ bubble: {
183
+ position: 'absolute',
184
+ width: SIZE,
185
+ height: SIZE,
186
+ borderRadius: SIZE / 2,
187
+ alignItems: 'center',
188
+ justifyContent: 'center',
189
+ zIndex: 999999,
190
+ elevation: 12,
191
+ shadowColor: '#000',
192
+ shadowOffset: { width: 0, height: 4 },
193
+ shadowOpacity: 0.3,
194
+ shadowRadius: 8,
195
+ ...react_native_1.Platform.select({
196
+ android: { elevation: 12 },
197
+ default: {},
198
+ }),
199
+ },
200
+ icon: {
201
+ fontSize: 22,
202
+ fontWeight: '700',
203
+ },
204
+ });
205
+ //# sourceMappingURL=FloatingBubble.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FloatingBubble.js","sourceRoot":"","sources":["../../src/components/FloatingBubble.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ /**
3
+ * InspectorPanel
4
+ *
5
+ * Bottom sheet shown when a component is selected. Three tabs:
6
+ * Styles | Tree | Props. Slides up with a spring animation.
7
+ */
8
+ export declare const InspectorPanel: React.FC;
9
+ //# sourceMappingURL=InspectorPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InspectorPanel.d.ts","sourceRoot":"","sources":["../../src/components/InspectorPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAoCnD;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAsBlC,CAAC"}