@bugpulse/react-native 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 (150) hide show
  1. package/README.md +185 -0
  2. package/dist/AnnotationCanvas.d.ts +11 -0
  3. package/dist/AnnotationCanvas.d.ts.map +1 -0
  4. package/dist/AnnotationCanvas.js +154 -0
  5. package/dist/AnnotationCanvas.js.map +1 -0
  6. package/dist/BugReportModal.d.ts +15 -0
  7. package/dist/BugReportModal.d.ts.map +1 -0
  8. package/dist/BugReportModal.js +303 -0
  9. package/dist/BugReportModal.js.map +1 -0
  10. package/dist/BugReportProvider.d.ts +19 -0
  11. package/dist/BugReportProvider.d.ts.map +1 -0
  12. package/dist/BugReportProvider.js +103 -0
  13. package/dist/BugReportProvider.js.map +1 -0
  14. package/dist/DeviceInfo.d.ts +3 -0
  15. package/dist/DeviceInfo.d.ts.map +1 -0
  16. package/dist/DeviceInfo.js +63 -0
  17. package/dist/DeviceInfo.js.map +1 -0
  18. package/dist/ErrorBoundary.d.ts +19 -0
  19. package/dist/ErrorBoundary.d.ts.map +1 -0
  20. package/dist/ErrorBoundary.js +79 -0
  21. package/dist/ErrorBoundary.js.map +1 -0
  22. package/dist/NavigationTracker.d.ts +7 -0
  23. package/dist/NavigationTracker.d.ts.map +1 -0
  24. package/dist/NavigationTracker.js +61 -0
  25. package/dist/NavigationTracker.js.map +1 -0
  26. package/dist/RingBuffer.d.ts +10 -0
  27. package/dist/RingBuffer.d.ts.map +1 -0
  28. package/dist/RingBuffer.js +26 -0
  29. package/dist/RingBuffer.js.map +1 -0
  30. package/dist/ScreenCapture.d.ts +3 -0
  31. package/dist/ScreenCapture.d.ts.map +1 -0
  32. package/dist/ScreenCapture.js +20 -0
  33. package/dist/ScreenCapture.js.map +1 -0
  34. package/dist/ShakeDetector.d.ts +5 -0
  35. package/dist/ShakeDetector.d.ts.map +1 -0
  36. package/dist/ShakeDetector.js +44 -0
  37. package/dist/ShakeDetector.js.map +1 -0
  38. package/dist/StateCapture.d.ts +13 -0
  39. package/dist/StateCapture.d.ts.map +1 -0
  40. package/dist/StateCapture.js +74 -0
  41. package/dist/StateCapture.js.map +1 -0
  42. package/dist/__tests__/DeviceInfo.test.d.ts +2 -0
  43. package/dist/__tests__/DeviceInfo.test.d.ts.map +1 -0
  44. package/dist/__tests__/DeviceInfo.test.js +63 -0
  45. package/dist/__tests__/DeviceInfo.test.js.map +1 -0
  46. package/dist/__tests__/ErrorBoundary.test.d.ts +2 -0
  47. package/dist/__tests__/ErrorBoundary.test.d.ts.map +1 -0
  48. package/dist/__tests__/ErrorBoundary.test.js +64 -0
  49. package/dist/__tests__/ErrorBoundary.test.js.map +1 -0
  50. package/dist/__tests__/NavigationTracker.test.d.ts +2 -0
  51. package/dist/__tests__/NavigationTracker.test.d.ts.map +1 -0
  52. package/dist/__tests__/NavigationTracker.test.js +54 -0
  53. package/dist/__tests__/NavigationTracker.test.js.map +1 -0
  54. package/dist/__tests__/RingBuffer.test.d.ts +2 -0
  55. package/dist/__tests__/RingBuffer.test.d.ts.map +1 -0
  56. package/dist/__tests__/RingBuffer.test.js +43 -0
  57. package/dist/__tests__/RingBuffer.test.js.map +1 -0
  58. package/dist/__tests__/ScreenCapture.test.d.ts +2 -0
  59. package/dist/__tests__/ScreenCapture.test.d.ts.map +1 -0
  60. package/dist/__tests__/ScreenCapture.test.js +27 -0
  61. package/dist/__tests__/ScreenCapture.test.js.map +1 -0
  62. package/dist/__tests__/ShakeDetector.test.d.ts +2 -0
  63. package/dist/__tests__/ShakeDetector.test.d.ts.map +1 -0
  64. package/dist/__tests__/ShakeDetector.test.js +65 -0
  65. package/dist/__tests__/ShakeDetector.test.js.map +1 -0
  66. package/dist/__tests__/StateCapture.test.d.ts +2 -0
  67. package/dist/__tests__/StateCapture.test.d.ts.map +1 -0
  68. package/dist/__tests__/StateCapture.test.js +128 -0
  69. package/dist/__tests__/StateCapture.test.js.map +1 -0
  70. package/dist/__tests__/__mocks__/expo-clipboard.d.ts +3 -0
  71. package/dist/__tests__/__mocks__/expo-clipboard.d.ts.map +1 -0
  72. package/dist/__tests__/__mocks__/expo-clipboard.js +6 -0
  73. package/dist/__tests__/__mocks__/expo-clipboard.js.map +1 -0
  74. package/dist/__tests__/__mocks__/expo-constants.d.ts +17 -0
  75. package/dist/__tests__/__mocks__/expo-constants.d.ts.map +1 -0
  76. package/dist/__tests__/__mocks__/expo-constants.js +8 -0
  77. package/dist/__tests__/__mocks__/expo-constants.js.map +1 -0
  78. package/dist/__tests__/__mocks__/expo-device.d.ts +2 -0
  79. package/dist/__tests__/__mocks__/expo-device.d.ts.map +1 -0
  80. package/dist/__tests__/__mocks__/expo-device.js +5 -0
  81. package/dist/__tests__/__mocks__/expo-device.js.map +1 -0
  82. package/dist/__tests__/__mocks__/expo-file-system-legacy.d.ts +8 -0
  83. package/dist/__tests__/__mocks__/expo-file-system-legacy.d.ts.map +1 -0
  84. package/dist/__tests__/__mocks__/expo-file-system-legacy.js +10 -0
  85. package/dist/__tests__/__mocks__/expo-file-system-legacy.js.map +1 -0
  86. package/dist/__tests__/__mocks__/expo-localization.d.ts +6 -0
  87. package/dist/__tests__/__mocks__/expo-localization.d.ts.map +1 -0
  88. package/dist/__tests__/__mocks__/expo-localization.js +7 -0
  89. package/dist/__tests__/__mocks__/expo-localization.js.map +1 -0
  90. package/dist/__tests__/__mocks__/expo-router.d.ts +5 -0
  91. package/dist/__tests__/__mocks__/expo-router.d.ts.map +1 -0
  92. package/dist/__tests__/__mocks__/expo-router.js +16 -0
  93. package/dist/__tests__/__mocks__/expo-router.js.map +1 -0
  94. package/dist/__tests__/__mocks__/expo-sensors.d.ts +17 -0
  95. package/dist/__tests__/__mocks__/expo-sensors.d.ts.map +1 -0
  96. package/dist/__tests__/__mocks__/expo-sensors.js +22 -0
  97. package/dist/__tests__/__mocks__/expo-sensors.js.map +1 -0
  98. package/dist/__tests__/__mocks__/react-native-gesture-handler.d.ts +11 -0
  99. package/dist/__tests__/__mocks__/react-native-gesture-handler.d.ts.map +1 -0
  100. package/dist/__tests__/__mocks__/react-native-gesture-handler.js +14 -0
  101. package/dist/__tests__/__mocks__/react-native-gesture-handler.js.map +1 -0
  102. package/dist/__tests__/__mocks__/react-native-svg.d.ts +4 -0
  103. package/dist/__tests__/__mocks__/react-native-svg.d.ts.map +1 -0
  104. package/dist/__tests__/__mocks__/react-native-svg.js +7 -0
  105. package/dist/__tests__/__mocks__/react-native-svg.js.map +1 -0
  106. package/dist/__tests__/__mocks__/react-native-view-shot.d.ts +2 -0
  107. package/dist/__tests__/__mocks__/react-native-view-shot.d.ts.map +1 -0
  108. package/dist/__tests__/__mocks__/react-native-view-shot.js +5 -0
  109. package/dist/__tests__/__mocks__/react-native-view-shot.js.map +1 -0
  110. package/dist/__tests__/__mocks__/react-native.d.ts +20 -0
  111. package/dist/__tests__/__mocks__/react-native.d.ts.map +1 -0
  112. package/dist/__tests__/__mocks__/react-native.js +14 -0
  113. package/dist/__tests__/__mocks__/react-native.js.map +1 -0
  114. package/dist/__tests__/fileToBase64.test.d.ts +2 -0
  115. package/dist/__tests__/fileToBase64.test.d.ts.map +1 -0
  116. package/dist/__tests__/fileToBase64.test.js +21 -0
  117. package/dist/__tests__/fileToBase64.test.js.map +1 -0
  118. package/dist/__tests__/integrations/slack.test.d.ts +2 -0
  119. package/dist/__tests__/integrations/slack.test.d.ts.map +1 -0
  120. package/dist/__tests__/integrations/slack.test.js +123 -0
  121. package/dist/__tests__/integrations/slack.test.js.map +1 -0
  122. package/dist/__tests__/integrations/webhook.test.d.ts +2 -0
  123. package/dist/__tests__/integrations/webhook.test.d.ts.map +1 -0
  124. package/dist/__tests__/integrations/webhook.test.js +98 -0
  125. package/dist/__tests__/integrations/webhook.test.js.map +1 -0
  126. package/dist/index.d.ts +8 -0
  127. package/dist/index.d.ts.map +1 -0
  128. package/dist/index.js +18 -0
  129. package/dist/index.js.map +1 -0
  130. package/dist/integrations/index.d.ts +4 -0
  131. package/dist/integrations/index.d.ts.map +1 -0
  132. package/dist/integrations/index.js +8 -0
  133. package/dist/integrations/index.js.map +1 -0
  134. package/dist/integrations/slack.d.ts +9 -0
  135. package/dist/integrations/slack.d.ts.map +1 -0
  136. package/dist/integrations/slack.js +136 -0
  137. package/dist/integrations/slack.js.map +1 -0
  138. package/dist/integrations/types.d.ts +53 -0
  139. package/dist/integrations/types.d.ts.map +1 -0
  140. package/dist/integrations/types.js +3 -0
  141. package/dist/integrations/types.js.map +1 -0
  142. package/dist/integrations/webhook.d.ts +8 -0
  143. package/dist/integrations/webhook.d.ts.map +1 -0
  144. package/dist/integrations/webhook.js +45 -0
  145. package/dist/integrations/webhook.js.map +1 -0
  146. package/dist/utils/fileToBase64.d.ts +2 -0
  147. package/dist/utils/fileToBase64.d.ts.map +1 -0
  148. package/dist/utils/fileToBase64.js +11 -0
  149. package/dist/utils/fileToBase64.js.map +1 -0
  150. package/package.json +77 -0
package/README.md ADDED
@@ -0,0 +1,185 @@
1
+ # @bugpulse/react-native
2
+
3
+ Lightweight in-app bug reporting for React Native & Expo. Shake to report. Annotate screenshots. Auto-capture app state, navigation history, and JS errors. Send to Slack or any webhook.
4
+
5
+ ## What makes this different
6
+
7
+ Every bug report automatically includes what cross-platform tools don't capture:
8
+ - **Zustand/Redux state snapshots** at the moment of the shake (not when the user hits submit)
9
+ - **Expo Router navigation history** (last 10 routes)
10
+ - **JS error boundary data** (last caught error + component stack)
11
+ - Device info, screenshot with annotation, and user description
12
+
13
+ ## Install
14
+
15
+ ```bash
16
+ npx expo install @bugpulse/react-native react-native-view-shot react-native-svg react-native-gesture-handler expo-sensors expo-device expo-constants
17
+ ```
18
+
19
+ ## Quick Start
20
+
21
+ ```tsx
22
+ import { BugReportProvider, SlackIntegration } from '@bugpulse/react-native';
23
+
24
+ export default function App() {
25
+ return (
26
+ <BugReportProvider
27
+ integrations={[
28
+ SlackIntegration({
29
+ webhookUrl: 'https://hooks.slack.com/services/...',
30
+ imageUploadKey: 'your-imgbb-api-key',
31
+ }),
32
+ ]}
33
+ >
34
+ <YourApp />
35
+ </BugReportProvider>
36
+ );
37
+ }
38
+ ```
39
+
40
+ Shake your phone. That's it.
41
+
42
+ ## RN-Specific Diagnostics
43
+
44
+ ### State Capture (Zustand)
45
+
46
+ Track Zustand stores to include state snapshots in every bug report:
47
+
48
+ ```tsx
49
+ import { trackStore } from '@bugpulse/react-native';
50
+ import { useAppStore } from './stores/app';
51
+
52
+ // Call once at app startup
53
+ trackStore(useAppStore, { name: 'app' });
54
+
55
+ // Track multiple stores
56
+ trackStore(useCartStore, { name: 'cart' });
57
+ ```
58
+
59
+ State is captured at shake time (frozen before the user annotates), so the report reflects the app state when the bug occurred, not when the user hit submit.
60
+
61
+ Call `untrackStore('app')` to stop tracking a store and free the subscription.
62
+
63
+ **Privacy note:** State snapshots are sent as-is. Do not track stores containing passwords, auth tokens, or PII. A redaction API is planned for a future release.
64
+
65
+ ### Navigation History (Expo Router)
66
+
67
+ Auto-captures route changes when using Expo Router:
68
+
69
+ ```tsx
70
+ import { useNavigationTracker } from '@bugpulse/react-native';
71
+
72
+ // Add to your root layout
73
+ export default function RootLayout() {
74
+ useNavigationTracker();
75
+
76
+ return <Slot />;
77
+ }
78
+ ```
79
+
80
+ Each bug report includes the last 10 routes with pathnames and timestamps.
81
+
82
+ Not using Expo Router? Use the `screenNameProvider` prop on `BugReportProvider` to manually pass the current screen name.
83
+
84
+ ### Error Boundary
85
+
86
+ Wrap your app (or specific subtrees) to capture JS errors:
87
+
88
+ ```tsx
89
+ import { BugPulseErrorBoundary } from '@bugpulse/react-native';
90
+
91
+ export default function App() {
92
+ return (
93
+ <BugPulseErrorBoundary>
94
+ <BugReportProvider integrations={[...]}>
95
+ <YourApp />
96
+ </BugReportProvider>
97
+ </BugPulseErrorBoundary>
98
+ );
99
+ }
100
+ ```
101
+
102
+ Caught errors are passively stored and attached to the next bug report. The boundary renders a minimal fallback on error.
103
+
104
+ ## Integrations
105
+
106
+ ### Slack
107
+
108
+ ```tsx
109
+ SlackIntegration({
110
+ webhookUrl: 'https://hooks.slack.com/services/...',
111
+ imageUploadKey: 'your-imgbb-api-key', // for screenshot uploads
112
+ })
113
+ ```
114
+
115
+ Slack messages include a truncated summary of diagnostics (last 3 state snapshots, last 5 routes, error info) to fit within webhook payload limits.
116
+
117
+ ### Webhook
118
+
119
+ ```tsx
120
+ WebhookIntegration({
121
+ url: 'https://your-api.com/bugs',
122
+ headers: { Authorization: 'Bearer ...' },
123
+ })
124
+ ```
125
+
126
+ Webhook payloads include the full diagnostics object with all state snapshots, navigation history, and error data.
127
+
128
+ ### Custom
129
+
130
+ ```tsx
131
+ const MyIntegration: Integration = {
132
+ name: 'my-integration',
133
+ async send(report) {
134
+ // report.diagnostics.stateSnapshots — array of { name, state, timestamp, truncated }
135
+ // report.diagnostics.navHistory — array of { pathname, segments, timestamp }
136
+ // report.diagnostics.lastError — { message, stack, componentStack, timestamp } | null
137
+ return { success: true };
138
+ },
139
+ };
140
+ ```
141
+
142
+ ## Props
143
+
144
+ | Prop | Type | Default | Description |
145
+ |------|------|---------|-------------|
146
+ | `integrations` | `Integration[]` | required | Where bug reports are sent |
147
+ | `metadata` | `Record<string, string>` or `() => Record` | `{}` | App context (user ID, plan, etc.) |
148
+ | `shakeThreshold` | `number` | `1.8` | Accelerometer sensitivity |
149
+ | `shakeEnabled` | `boolean` | `true` | Enable/disable shake trigger |
150
+ | `screenNameProvider` | `() => string` | auto-detect | Current screen name |
151
+ | `enabled` | `boolean` | `true` | Enable/disable the SDK entirely |
152
+
153
+ ## Programmatic Trigger
154
+
155
+ ```tsx
156
+ import { useBugReport } from '@bugpulse/react-native';
157
+
158
+ function SettingsScreen() {
159
+ const { triggerBugReport } = useBugReport();
160
+
161
+ return (
162
+ <Button title="Report Bug" onPress={triggerBugReport} />
163
+ );
164
+ }
165
+ ```
166
+
167
+ ## How It Works
168
+
169
+ 1. User shakes phone (or triggers programmatically)
170
+ 2. SDK freezes state snapshots and navigation history
171
+ 3. SDK captures a screenshot
172
+ 4. User annotates the screenshot (draw circles, arrows)
173
+ 5. User adds a description
174
+ 6. SDK collects device info, attaches diagnostics, and sends to your integrations
175
+
176
+ ## Requirements
177
+
178
+ - Expo SDK 50+
179
+ - React Native 0.72+
180
+ - Dev build required for screenshots (Expo Go gets graceful degradation)
181
+ - Expo Router (optional, for auto navigation tracking)
182
+
183
+ ## License
184
+
185
+ MIT
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ interface AnnotationCanvasProps {
3
+ screenshotUri: string;
4
+ onAnnotationComplete: (annotatedUri: string) => void;
5
+ onSkip: () => void;
6
+ width: number;
7
+ height: number;
8
+ }
9
+ export declare function AnnotationCanvas({ screenshotUri, onAnnotationComplete, onSkip, width, height, }: AnnotationCanvasProps): React.JSX.Element;
10
+ export {};
11
+ //# sourceMappingURL=AnnotationCanvas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnnotationCanvas.d.ts","sourceRoot":"","sources":["../src/AnnotationCanvas.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAwC,MAAM,OAAO,CAAC;AAU7D,UAAU,qBAAqB;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,oBAAoB,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAMD,wBAAgB,gBAAgB,CAAC,EAC/B,aAAa,EACb,oBAAoB,EACpB,MAAM,EACN,KAAK,EACL,MAAM,GACP,EAAE,qBAAqB,qBA2KvB"}
@@ -0,0 +1,154 @@
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.AnnotationCanvas = AnnotationCanvas;
37
+ const react_1 = __importStar(require("react"));
38
+ const react_native_1 = require("react-native");
39
+ const react_native_svg_1 = __importStar(require("react-native-svg"));
40
+ const react_native_gesture_handler_1 = require("react-native-gesture-handler");
41
+ const react_native_view_shot_1 = require("react-native-view-shot");
42
+ function AnnotationCanvas({ screenshotUri, onAnnotationComplete, onSkip, width, height, }) {
43
+ const [paths, setPaths] = (0, react_1.useState)([]);
44
+ const [currentPath, setCurrentPath] = (0, react_1.useState)('');
45
+ const currentPathRef = (0, react_1.useRef)('');
46
+ const compositeRef = (0, react_1.useRef)(null);
47
+ const [isSaving, setIsSaving] = (0, react_1.useState)(false);
48
+ const panGesture = react_native_gesture_handler_1.Gesture.Pan()
49
+ .onStart((event) => {
50
+ const newPath = `M${event.x},${event.y}`;
51
+ currentPathRef.current = newPath;
52
+ setCurrentPath(newPath);
53
+ })
54
+ .onUpdate((event) => {
55
+ const updated = `${currentPathRef.current} L${event.x},${event.y}`;
56
+ currentPathRef.current = updated;
57
+ setCurrentPath(updated);
58
+ })
59
+ .onEnd(() => {
60
+ const pathToSave = currentPathRef.current;
61
+ if (pathToSave) {
62
+ setPaths((prev) => [...prev, { d: pathToSave }]);
63
+ currentPathRef.current = '';
64
+ setCurrentPath('');
65
+ }
66
+ })
67
+ .minDistance(0);
68
+ const handleUndo = (0, react_1.useCallback)(() => {
69
+ setPaths((prev) => prev.slice(0, -1));
70
+ }, []);
71
+ const handleClear = (0, react_1.useCallback)(() => {
72
+ setPaths([]);
73
+ }, []);
74
+ const handleDone = (0, react_1.useCallback)(async () => {
75
+ if (isSaving)
76
+ return;
77
+ setIsSaving(true);
78
+ try {
79
+ const uri = await (0, react_native_view_shot_1.captureRef)(compositeRef, {
80
+ format: 'png',
81
+ quality: 0.9,
82
+ result: 'tmpfile',
83
+ });
84
+ onAnnotationComplete(uri);
85
+ }
86
+ catch {
87
+ onSkip();
88
+ }
89
+ finally {
90
+ setIsSaving(false);
91
+ }
92
+ }, [isSaving, onAnnotationComplete, onSkip]);
93
+ return (<react_native_gesture_handler_1.GestureHandlerRootView style={{ flex: 1 }}>
94
+ <react_native_1.View style={{ flex: 1 }}>
95
+ <react_native_1.View ref={compositeRef} collapsable={false} style={{ width, height, position: 'relative' }}>
96
+ <react_native_1.Image source={{ uri: screenshotUri }} style={{ width, height }} resizeMode="contain"/>
97
+ <react_native_gesture_handler_1.GestureDetector gesture={panGesture}>
98
+ <react_native_svg_1.default style={{
99
+ position: 'absolute',
100
+ top: 0,
101
+ left: 0,
102
+ width,
103
+ height,
104
+ }}>
105
+ {paths.map((path, index) => (<react_native_svg_1.Path key={index} d={path.d} stroke="#FF3B30" strokeWidth={3} fill="none" strokeLinecap="round" strokeLinejoin="round"/>))}
106
+ {currentPath ? (<react_native_svg_1.Path d={currentPath} stroke="#FF3B30" strokeWidth={3} fill="none" strokeLinecap="round" strokeLinejoin="round"/>) : null}
107
+ </react_native_svg_1.default>
108
+ </react_native_gesture_handler_1.GestureDetector>
109
+ </react_native_1.View>
110
+
111
+ <react_native_1.View style={{
112
+ flexDirection: 'row',
113
+ justifyContent: 'space-between',
114
+ paddingHorizontal: 16,
115
+ paddingVertical: 12,
116
+ }}>
117
+ <react_native_1.View style={{ flexDirection: 'row', gap: 12 }}>
118
+ <react_native_1.TouchableOpacity onPress={handleUndo} disabled={paths.length === 0} accessibilityRole="button" accessibilityLabel="Undo last drawing">
119
+ <react_native_1.Text style={{
120
+ fontSize: 16,
121
+ color: paths.length === 0 ? '#ccc' : '#007AFF',
122
+ }}>
123
+ Undo
124
+ </react_native_1.Text>
125
+ </react_native_1.TouchableOpacity>
126
+ <react_native_1.TouchableOpacity onPress={handleClear} disabled={paths.length === 0} accessibilityRole="button" accessibilityLabel="Clear all drawings">
127
+ <react_native_1.Text style={{
128
+ fontSize: 16,
129
+ color: paths.length === 0 ? '#ccc' : '#FF3B30',
130
+ }}>
131
+ Clear
132
+ </react_native_1.Text>
133
+ </react_native_1.TouchableOpacity>
134
+ </react_native_1.View>
135
+
136
+ <react_native_1.View style={{ flexDirection: 'row', gap: 12 }}>
137
+ <react_native_1.TouchableOpacity onPress={onSkip} accessibilityRole="button" accessibilityLabel="Skip annotation">
138
+ <react_native_1.Text style={{ fontSize: 16, color: '#8E8E93' }}>Skip</react_native_1.Text>
139
+ </react_native_1.TouchableOpacity>
140
+ <react_native_1.TouchableOpacity onPress={handleDone} disabled={isSaving} accessibilityRole="button" accessibilityLabel="Done annotating">
141
+ <react_native_1.Text style={{
142
+ fontSize: 16,
143
+ fontWeight: '600',
144
+ color: isSaving ? '#ccc' : '#007AFF',
145
+ }}>
146
+ Done
147
+ </react_native_1.Text>
148
+ </react_native_1.TouchableOpacity>
149
+ </react_native_1.View>
150
+ </react_native_1.View>
151
+ </react_native_1.View>
152
+ </react_native_gesture_handler_1.GestureHandlerRootView>);
153
+ }
154
+ //# sourceMappingURL=AnnotationCanvas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnnotationCanvas.js","sourceRoot":"","sources":["../src/AnnotationCanvas.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import type { Integration, BugReport } from './integrations/types';
3
+ interface BugReportModalProps {
4
+ visible: boolean;
5
+ screenshotUri: string | null;
6
+ integrations: Integration[];
7
+ metadata: Record<string, string> | (() => Record<string, string>);
8
+ screenNameProvider: () => string;
9
+ onClose: () => void;
10
+ onSubmitSuccess?: () => void;
11
+ onError?: (error: Error, report: BugReport) => void;
12
+ }
13
+ export declare function BugReportModal({ visible, screenshotUri, integrations, metadata, screenNameProvider, onClose, onSubmitSuccess, onError, }: BugReportModalProps): React.JSX.Element;
14
+ export {};
15
+ //# sourceMappingURL=BugReportModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BugReportModal.d.ts","sourceRoot":"","sources":["../src/BugReportModal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAmBhE,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEnE,UAAU,mBAAmB;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAClE,kBAAkB,EAAE,MAAM,MAAM,CAAC;IACjC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,KAAK,IAAI,CAAC;CACrD;AAMD,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,aAAa,EACb,YAAY,EACZ,QAAQ,EACR,kBAAkB,EAClB,OAAO,EACP,eAAe,EACf,OAAO,GACR,EAAE,mBAAmB,qBA+XrB"}