@shakenbake/react-native 0.0.1

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 (73) hide show
  1. package/dist/ShakeNbakeProvider.d.ts +26 -0
  2. package/dist/ShakeNbakeProvider.d.ts.map +1 -0
  3. package/dist/ShakeNbakeProvider.js +338 -0
  4. package/dist/ShakeNbakeProvider.js.map +1 -0
  5. package/dist/__tests__/capture.test.d.ts +2 -0
  6. package/dist/__tests__/capture.test.d.ts.map +1 -0
  7. package/dist/__tests__/capture.test.js +93 -0
  8. package/dist/__tests__/capture.test.js.map +1 -0
  9. package/dist/__tests__/collectors.test.d.ts +2 -0
  10. package/dist/__tests__/collectors.test.d.ts.map +1 -0
  11. package/dist/__tests__/collectors.test.js +212 -0
  12. package/dist/__tests__/collectors.test.js.map +1 -0
  13. package/dist/__tests__/drawing-canvas.test.d.ts +2 -0
  14. package/dist/__tests__/drawing-canvas.test.d.ts.map +1 -0
  15. package/dist/__tests__/drawing-canvas.test.js +503 -0
  16. package/dist/__tests__/drawing-canvas.test.js.map +1 -0
  17. package/dist/__tests__/provider.test.d.ts +2 -0
  18. package/dist/__tests__/provider.test.d.ts.map +1 -0
  19. package/dist/__tests__/provider.test.js +431 -0
  20. package/dist/__tests__/provider.test.js.map +1 -0
  21. package/dist/__tests__/report-form.test.d.ts +2 -0
  22. package/dist/__tests__/report-form.test.d.ts.map +1 -0
  23. package/dist/__tests__/report-form.test.js +178 -0
  24. package/dist/__tests__/report-form.test.js.map +1 -0
  25. package/dist/__tests__/triggers.test.d.ts +2 -0
  26. package/dist/__tests__/triggers.test.d.ts.map +1 -0
  27. package/dist/__tests__/triggers.test.js +53 -0
  28. package/dist/__tests__/triggers.test.js.map +1 -0
  29. package/dist/annotate/DrawingCanvas.d.ts +13 -0
  30. package/dist/annotate/DrawingCanvas.d.ts.map +1 -0
  31. package/dist/annotate/DrawingCanvas.js +475 -0
  32. package/dist/annotate/DrawingCanvas.js.map +1 -0
  33. package/dist/annotate/types.d.ts +72 -0
  34. package/dist/annotate/types.d.ts.map +1 -0
  35. package/dist/annotate/types.js +34 -0
  36. package/dist/annotate/types.js.map +1 -0
  37. package/dist/annotate/useDrawingOperations.d.ts +88 -0
  38. package/dist/annotate/useDrawingOperations.d.ts.map +1 -0
  39. package/dist/annotate/useDrawingOperations.js +186 -0
  40. package/dist/annotate/useDrawingOperations.js.map +1 -0
  41. package/dist/capture/screenshot.d.ts +31 -0
  42. package/dist/capture/screenshot.d.ts.map +1 -0
  43. package/dist/capture/screenshot.js +90 -0
  44. package/dist/capture/screenshot.js.map +1 -0
  45. package/dist/context/collectors.d.ts +25 -0
  46. package/dist/context/collectors.d.ts.map +1 -0
  47. package/dist/context/collectors.js +244 -0
  48. package/dist/context/collectors.js.map +1 -0
  49. package/dist/hooks/useShakeNbake.d.ts +28 -0
  50. package/dist/hooks/useShakeNbake.d.ts.map +1 -0
  51. package/dist/hooks/useShakeNbake.js +30 -0
  52. package/dist/hooks/useShakeNbake.js.map +1 -0
  53. package/dist/index.d.ts +19 -0
  54. package/dist/index.d.ts.map +1 -0
  55. package/dist/index.js +49 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/triggers/shake.d.ts +16 -0
  58. package/dist/triggers/shake.d.ts.map +1 -0
  59. package/dist/triggers/shake.js +41 -0
  60. package/dist/triggers/shake.js.map +1 -0
  61. package/dist/ui/ReportForm.d.ts +33 -0
  62. package/dist/ui/ReportForm.d.ts.map +1 -0
  63. package/dist/ui/ReportForm.js +608 -0
  64. package/dist/ui/ReportForm.js.map +1 -0
  65. package/dist/ui/form-validation.d.ts +26 -0
  66. package/dist/ui/form-validation.d.ts.map +1 -0
  67. package/dist/ui/form-validation.js +44 -0
  68. package/dist/ui/form-validation.js.map +1 -0
  69. package/dist/ui/state-machine.d.ts +70 -0
  70. package/dist/ui/state-machine.d.ts.map +1 -0
  71. package/dist/ui/state-machine.js +107 -0
  72. package/dist/ui/state-machine.js.map +1 -0
  73. package/package.json +57 -0
@@ -0,0 +1,608 @@
1
+ "use strict";
2
+ // ---------------------------------------------------------------------------
3
+ // @shakenbake/react-native — ReportForm
4
+ //
5
+ // A React Native form component for composing bug reports. Rendered inside a
6
+ // Modal, it collects title, description, severity, category, and displays
7
+ // a preview of the annotated screenshot. Supports light/dark themes.
8
+ //
9
+ // Since `react-native` is a **peer dependency**, all RN components are loaded
10
+ // dynamically at runtime using the same pattern as DrawingCanvas.
11
+ // ---------------------------------------------------------------------------
12
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ var desc = Object.getOwnPropertyDescriptor(m, k);
15
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
16
+ desc = { enumerable: true, get: function() { return m[k]; } };
17
+ }
18
+ Object.defineProperty(o, k2, desc);
19
+ }) : (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ o[k2] = m[k];
22
+ }));
23
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
24
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
25
+ }) : function(o, v) {
26
+ o["default"] = v;
27
+ });
28
+ var __importStar = (this && this.__importStar) || (function () {
29
+ var ownKeys = function(o) {
30
+ ownKeys = Object.getOwnPropertyNames || function (o) {
31
+ var ar = [];
32
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
33
+ return ar;
34
+ };
35
+ return ownKeys(o);
36
+ };
37
+ return function (mod) {
38
+ if (mod && mod.__esModule) return mod;
39
+ var result = {};
40
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
41
+ __setModuleDefault(result, mod);
42
+ return result;
43
+ };
44
+ })();
45
+ Object.defineProperty(exports, "__esModule", { value: true });
46
+ exports.ReportForm = ReportForm;
47
+ const react_1 = __importStar(require("react"));
48
+ const form_validation_js_1 = require("./form-validation.js");
49
+ // ---------------------------------------------------------------------------
50
+ // Constants
51
+ // ---------------------------------------------------------------------------
52
+ const SEVERITIES = ['low', 'medium', 'high', 'critical'];
53
+ const CATEGORIES = ['bug', 'ui', 'crash', 'performance', 'other'];
54
+ const SEVERITY_LABELS = {
55
+ low: 'Low',
56
+ medium: 'Medium',
57
+ high: 'High',
58
+ critical: 'Critical',
59
+ };
60
+ const CATEGORY_LABELS = {
61
+ bug: 'Bug',
62
+ ui: 'UI',
63
+ crash: 'Crash',
64
+ performance: 'Performance',
65
+ other: 'Other',
66
+ };
67
+ function getThemeColors(theme, accentColor) {
68
+ const accent = accentColor ?? '#007AFF';
69
+ if (theme === 'dark') {
70
+ return {
71
+ background: '#1C1C1E',
72
+ surface: '#2C2C2E',
73
+ text: '#FFFFFF',
74
+ textSecondary: '#8E8E93',
75
+ border: '#3A3A3C',
76
+ inputBackground: '#2C2C2E',
77
+ accent,
78
+ error: '#FF453A',
79
+ success: '#30D158',
80
+ buttonText: '#FFFFFF',
81
+ buttonGroupBg: '#3A3A3C',
82
+ buttonGroupActive: accent,
83
+ };
84
+ }
85
+ return {
86
+ background: '#F2F2F7',
87
+ surface: '#FFFFFF',
88
+ text: '#000000',
89
+ textSecondary: '#6C6C70',
90
+ border: '#C6C6C8',
91
+ inputBackground: '#FFFFFF',
92
+ accent,
93
+ error: '#FF3B30',
94
+ success: '#34C759',
95
+ buttonText: '#FFFFFF',
96
+ buttonGroupBg: '#E5E5EA',
97
+ buttonGroupActive: accent,
98
+ };
99
+ }
100
+ // ---------------------------------------------------------------------------
101
+ // Context display helpers
102
+ // ---------------------------------------------------------------------------
103
+ function formatContextSection(label, data) {
104
+ if (!data)
105
+ return [];
106
+ const items = [];
107
+ for (const [k, v] of Object.entries(data)) {
108
+ if (v !== undefined && v !== null && v !== '') {
109
+ items.push({ key: `${label}.${k}`, value: String(v) });
110
+ }
111
+ }
112
+ return items;
113
+ }
114
+ // ---------------------------------------------------------------------------
115
+ // ReportForm component
116
+ // ---------------------------------------------------------------------------
117
+ /**
118
+ * Report form rendered inside a Modal. Collects user input for a bug report
119
+ * and sends it via the provided `onSubmit` callback.
120
+ *
121
+ * Requires `react-native` to be available at runtime (peer dependency).
122
+ */
123
+ function ReportForm(props) {
124
+ const { annotatedScreenshot, originalScreenshot, dimensions, context, onSubmit, onCancel, onReAnnotate, theme = 'dark', accentColor, } = props;
125
+ // ---- Module loading ----
126
+ const [rn, setRn] = (0, react_1.useState)(null);
127
+ const [loadError, setLoadError] = (0, react_1.useState)(null);
128
+ (0, react_1.useEffect)(() => {
129
+ let cancelled = false;
130
+ async function load() {
131
+ try {
132
+ const mod = await import('react-native');
133
+ if (!cancelled)
134
+ setRn(mod);
135
+ }
136
+ catch {
137
+ if (!cancelled)
138
+ setLoadError('react-native is required for ReportForm but is not available.');
139
+ }
140
+ }
141
+ void load();
142
+ return () => {
143
+ cancelled = true;
144
+ };
145
+ }, []);
146
+ // ---- Form state ----
147
+ const [title, setTitle] = (0, react_1.useState)('');
148
+ const [description, setDescription] = (0, react_1.useState)('');
149
+ const [severity, setSeverity] = (0, react_1.useState)('medium');
150
+ const [category, setCategory] = (0, react_1.useState)('bug');
151
+ const [titleError, setTitleError] = (0, react_1.useState)(null);
152
+ const [contextExpanded, setContextExpanded] = (0, react_1.useState)(false);
153
+ // ---- Submission state ----
154
+ const [submitting, setSubmitting] = (0, react_1.useState)(false);
155
+ const [submitResult, setSubmitResult] = (0, react_1.useState)(null);
156
+ const [submitError, setSubmitError] = (0, react_1.useState)(null);
157
+ // ---- Theme ----
158
+ const colors = (0, react_1.useMemo)(() => getThemeColors(theme, accentColor), [theme, accentColor]);
159
+ // ---- Validate on title change ----
160
+ const handleTitleChange = (0, react_1.useCallback)((text) => {
161
+ setTitle(text);
162
+ const error = (0, form_validation_js_1.validateTitle)(text);
163
+ setTitleError(error?.message ?? null);
164
+ }, []);
165
+ // ---- Submit handler ----
166
+ const handleSubmit = (0, react_1.useCallback)(async () => {
167
+ if (!(0, form_validation_js_1.isFormValid)({ title })) {
168
+ const error = (0, form_validation_js_1.validateTitle)(title);
169
+ setTitleError(error?.message ?? null);
170
+ return;
171
+ }
172
+ setSubmitting(true);
173
+ setSubmitError(null);
174
+ try {
175
+ const input = {
176
+ title: title.trim(),
177
+ description: description.trim(),
178
+ severity,
179
+ category,
180
+ annotatedScreenshot,
181
+ originalScreenshot,
182
+ };
183
+ const result = await onSubmit(input);
184
+ setSubmitResult(result);
185
+ }
186
+ catch (err) {
187
+ setSubmitError(err instanceof Error ? err.message : 'Failed to submit report');
188
+ }
189
+ finally {
190
+ setSubmitting(false);
191
+ }
192
+ }, [
193
+ title,
194
+ description,
195
+ severity,
196
+ category,
197
+ annotatedScreenshot,
198
+ originalScreenshot,
199
+ onSubmit,
200
+ ]);
201
+ // ---- Context items for display ----
202
+ const contextItems = (0, react_1.useMemo)(() => {
203
+ const items = [];
204
+ if (context.platform)
205
+ items.push(...formatContextSection('Platform', context.platform));
206
+ if (context.device)
207
+ items.push(...formatContextSection('Device', context.device));
208
+ if (context.screen)
209
+ items.push(...formatContextSection('Screen', context.screen));
210
+ if (context.network)
211
+ items.push(...formatContextSection('Network', context.network));
212
+ if (context.battery)
213
+ items.push(...formatContextSection('Battery', context.battery));
214
+ if (context.locale)
215
+ items.push(...formatContextSection('Locale', context.locale));
216
+ if (context.app)
217
+ items.push(...formatContextSection('App', context.app));
218
+ return items;
219
+ }, [context]);
220
+ // ---- Render: loading / error states ----
221
+ if (loadError) {
222
+ // Cannot render React Native components since the module failed to load.
223
+ // eslint-disable-next-line no-console
224
+ console.error('[ShakeNbake]', loadError);
225
+ return null;
226
+ }
227
+ if (!rn)
228
+ return null;
229
+ const { View, Text, TextInput, TouchableOpacity, ScrollView, Modal, Image, ActivityIndicator, KeyboardAvoidingView, Platform, StyleSheet, Linking, } = rn;
230
+ // ---- Styles ----
231
+ const styles = StyleSheet.create({
232
+ modal: {
233
+ flex: 1,
234
+ backgroundColor: colors.background,
235
+ },
236
+ keyboardAvoid: {
237
+ flex: 1,
238
+ },
239
+ container: {
240
+ flex: 1,
241
+ },
242
+ scrollContent: {
243
+ padding: 16,
244
+ paddingBottom: 40,
245
+ },
246
+ header: {
247
+ flexDirection: 'row',
248
+ justifyContent: 'space-between',
249
+ alignItems: 'center',
250
+ paddingHorizontal: 16,
251
+ paddingTop: 56,
252
+ paddingBottom: 12,
253
+ borderBottomWidth: 1,
254
+ borderBottomColor: colors.border,
255
+ backgroundColor: colors.surface,
256
+ },
257
+ headerTitle: {
258
+ fontSize: 17,
259
+ fontWeight: '600',
260
+ color: colors.text,
261
+ },
262
+ headerButton: {
263
+ paddingHorizontal: 12,
264
+ paddingVertical: 6,
265
+ },
266
+ headerButtonText: {
267
+ fontSize: 16,
268
+ color: colors.accent,
269
+ fontWeight: '500',
270
+ },
271
+ cancelButtonText: {
272
+ fontSize: 16,
273
+ color: colors.error,
274
+ fontWeight: '500',
275
+ },
276
+ label: {
277
+ fontSize: 14,
278
+ fontWeight: '600',
279
+ color: colors.text,
280
+ marginBottom: 6,
281
+ marginTop: 16,
282
+ },
283
+ required: {
284
+ color: colors.error,
285
+ },
286
+ input: {
287
+ backgroundColor: colors.inputBackground,
288
+ borderWidth: 1,
289
+ borderColor: colors.border,
290
+ borderRadius: 8,
291
+ padding: 12,
292
+ fontSize: 16,
293
+ color: colors.text,
294
+ },
295
+ inputError: {
296
+ backgroundColor: colors.inputBackground,
297
+ borderWidth: 1,
298
+ borderColor: colors.error,
299
+ borderRadius: 8,
300
+ padding: 12,
301
+ fontSize: 16,
302
+ color: colors.text,
303
+ },
304
+ multilineInput: {
305
+ backgroundColor: colors.inputBackground,
306
+ borderWidth: 1,
307
+ borderColor: colors.border,
308
+ borderRadius: 8,
309
+ padding: 12,
310
+ fontSize: 16,
311
+ color: colors.text,
312
+ minHeight: 80,
313
+ textAlignVertical: 'top',
314
+ },
315
+ errorText: {
316
+ color: colors.error,
317
+ fontSize: 12,
318
+ marginTop: 4,
319
+ },
320
+ buttonGroup: {
321
+ flexDirection: 'row',
322
+ flexWrap: 'wrap',
323
+ gap: 8,
324
+ },
325
+ buttonGroupItem: {
326
+ paddingHorizontal: 14,
327
+ paddingVertical: 8,
328
+ borderRadius: 8,
329
+ backgroundColor: colors.buttonGroupBg,
330
+ },
331
+ buttonGroupItemActive: {
332
+ paddingHorizontal: 14,
333
+ paddingVertical: 8,
334
+ borderRadius: 8,
335
+ backgroundColor: colors.buttonGroupActive,
336
+ },
337
+ buttonGroupText: {
338
+ fontSize: 14,
339
+ fontWeight: '500',
340
+ color: colors.text,
341
+ },
342
+ buttonGroupTextActive: {
343
+ fontSize: 14,
344
+ fontWeight: '500',
345
+ color: colors.buttonText,
346
+ },
347
+ screenshotContainer: {
348
+ marginTop: 16,
349
+ borderRadius: 8,
350
+ overflow: 'hidden',
351
+ borderWidth: 1,
352
+ borderColor: colors.border,
353
+ },
354
+ screenshotImage: {
355
+ width: '100%',
356
+ height: 200,
357
+ },
358
+ screenshotOverlay: {
359
+ position: 'absolute',
360
+ bottom: 0,
361
+ left: 0,
362
+ right: 0,
363
+ backgroundColor: 'rgba(0,0,0,0.5)',
364
+ paddingVertical: 6,
365
+ alignItems: 'center',
366
+ },
367
+ screenshotOverlayText: {
368
+ color: '#FFFFFF',
369
+ fontSize: 12,
370
+ fontWeight: '500',
371
+ },
372
+ contextHeader: {
373
+ flexDirection: 'row',
374
+ justifyContent: 'space-between',
375
+ alignItems: 'center',
376
+ paddingVertical: 12,
377
+ borderTopWidth: 1,
378
+ borderTopColor: colors.border,
379
+ marginTop: 16,
380
+ },
381
+ contextHeaderText: {
382
+ fontSize: 14,
383
+ fontWeight: '600',
384
+ color: colors.text,
385
+ },
386
+ contextToggle: {
387
+ fontSize: 12,
388
+ color: colors.accent,
389
+ },
390
+ contextRow: {
391
+ flexDirection: 'row',
392
+ justifyContent: 'space-between',
393
+ paddingVertical: 4,
394
+ },
395
+ contextKey: {
396
+ fontSize: 12,
397
+ color: colors.textSecondary,
398
+ flex: 1,
399
+ },
400
+ contextValue: {
401
+ fontSize: 12,
402
+ color: colors.text,
403
+ flex: 1,
404
+ textAlign: 'right',
405
+ },
406
+ submitButton: {
407
+ backgroundColor: colors.accent,
408
+ borderRadius: 10,
409
+ paddingVertical: 14,
410
+ alignItems: 'center',
411
+ marginTop: 24,
412
+ },
413
+ submitButtonDisabled: {
414
+ backgroundColor: colors.accent,
415
+ borderRadius: 10,
416
+ paddingVertical: 14,
417
+ alignItems: 'center',
418
+ marginTop: 24,
419
+ opacity: 0.5,
420
+ },
421
+ submitButtonText: {
422
+ color: colors.buttonText,
423
+ fontSize: 16,
424
+ fontWeight: '600',
425
+ },
426
+ // ---- Success state ----
427
+ successContainer: {
428
+ flex: 1,
429
+ justifyContent: 'center',
430
+ alignItems: 'center',
431
+ padding: 32,
432
+ backgroundColor: colors.background,
433
+ },
434
+ successTitle: {
435
+ fontSize: 24,
436
+ fontWeight: '700',
437
+ color: colors.success,
438
+ marginBottom: 12,
439
+ },
440
+ successMessage: {
441
+ fontSize: 16,
442
+ color: colors.text,
443
+ textAlign: 'center',
444
+ marginBottom: 24,
445
+ },
446
+ successLink: {
447
+ color: colors.accent,
448
+ fontSize: 14,
449
+ textDecorationLine: 'underline',
450
+ marginBottom: 24,
451
+ },
452
+ doneButton: {
453
+ backgroundColor: colors.accent,
454
+ borderRadius: 10,
455
+ paddingHorizontal: 32,
456
+ paddingVertical: 12,
457
+ },
458
+ doneButtonText: {
459
+ color: colors.buttonText,
460
+ fontSize: 16,
461
+ fontWeight: '600',
462
+ },
463
+ // ---- Error state ----
464
+ errorBanner: {
465
+ backgroundColor: colors.error,
466
+ padding: 12,
467
+ borderRadius: 8,
468
+ marginTop: 16,
469
+ },
470
+ errorBannerText: {
471
+ color: '#FFFFFF',
472
+ fontSize: 14,
473
+ textAlign: 'center',
474
+ },
475
+ // ---- Loading overlay ----
476
+ loadingOverlay: {
477
+ position: 'absolute',
478
+ top: 0,
479
+ left: 0,
480
+ right: 0,
481
+ bottom: 0,
482
+ backgroundColor: 'rgba(0,0,0,0.4)',
483
+ justifyContent: 'center',
484
+ alignItems: 'center',
485
+ },
486
+ loadingText: {
487
+ color: '#FFFFFF',
488
+ fontSize: 16,
489
+ marginTop: 12,
490
+ },
491
+ });
492
+ // ---- Success view ----
493
+ if (submitResult) {
494
+ return react_1.default.createElement(Modal, { visible: true, animationType: 'slide' }, react_1.default.createElement(View, { style: styles.successContainer }, react_1.default.createElement(Text, { style: styles.successTitle }, 'Report Submitted'), react_1.default.createElement(Text, { style: styles.successMessage }, 'Your bug report has been created successfully.'), submitResult.url
495
+ ? react_1.default.createElement(TouchableOpacity, {
496
+ onPress: () => {
497
+ void Linking.openURL(submitResult.url);
498
+ },
499
+ }, react_1.default.createElement(Text, { style: styles.successLink }, `View issue: ${submitResult.url}`))
500
+ : null, react_1.default.createElement(TouchableOpacity, { style: styles.doneButton, onPress: onCancel }, react_1.default.createElement(Text, { style: styles.doneButtonText }, 'Done'))));
501
+ }
502
+ // ---- Main form ----
503
+ const canSubmit = (0, form_validation_js_1.isFormValid)({ title }) && !submitting;
504
+ return react_1.default.createElement(Modal, { visible: true, animationType: 'slide' }, react_1.default.createElement(View, { style: styles.modal },
505
+ // Header
506
+ react_1.default.createElement(View, { style: styles.header }, react_1.default.createElement(TouchableOpacity, { style: styles.headerButton, onPress: onCancel, disabled: submitting }, react_1.default.createElement(Text, { style: styles.cancelButtonText }, 'Cancel')), react_1.default.createElement(Text, { style: styles.headerTitle }, 'Report Bug'), react_1.default.createElement(TouchableOpacity, {
507
+ style: styles.headerButton,
508
+ onPress: () => void handleSubmit(),
509
+ disabled: !canSubmit,
510
+ }, react_1.default.createElement(Text, {
511
+ style: {
512
+ ...styles.headerButtonText,
513
+ ...(canSubmit ? {} : { opacity: 0.4 }),
514
+ },
515
+ }, 'Submit'))), react_1.default.createElement(KeyboardAvoidingView, {
516
+ style: styles.keyboardAvoid,
517
+ behavior: Platform.OS === 'ios' ? 'padding' : undefined,
518
+ }, react_1.default.createElement(ScrollView, { style: styles.container, contentContainerStyle: styles.scrollContent },
519
+ // Screenshot preview
520
+ react_1.default.createElement(TouchableOpacity, {
521
+ style: styles.screenshotContainer,
522
+ onPress: onReAnnotate,
523
+ activeOpacity: onReAnnotate ? 0.7 : 1,
524
+ }, react_1.default.createElement(Image, {
525
+ style: styles.screenshotImage,
526
+ source: { uri: `data:image/png;base64,${annotatedScreenshot}` },
527
+ resizeMode: 'contain',
528
+ }), onReAnnotate
529
+ ? react_1.default.createElement(View, { style: styles.screenshotOverlay }, react_1.default.createElement(Text, { style: styles.screenshotOverlayText }, 'Tap to re-annotate'))
530
+ : null),
531
+ // Title
532
+ react_1.default.createElement(Text, { style: styles.label }, react_1.default.createElement(Text, null, 'Title '), react_1.default.createElement(Text, { style: styles.required }, '*')), react_1.default.createElement(TextInput, {
533
+ style: titleError ? styles.inputError : styles.input,
534
+ value: title,
535
+ onChangeText: handleTitleChange,
536
+ placeholder: 'Brief description of the issue...',
537
+ placeholderTextColor: colors.textSecondary,
538
+ autoFocus: true,
539
+ maxLength: 200,
540
+ returnKeyType: 'next',
541
+ }), titleError
542
+ ? react_1.default.createElement(Text, { style: styles.errorText }, titleError)
543
+ : null,
544
+ // Description
545
+ react_1.default.createElement(Text, { style: styles.label }, 'Description'), react_1.default.createElement(TextInput, {
546
+ style: styles.multilineInput,
547
+ value: description,
548
+ onChangeText: setDescription,
549
+ placeholder: 'Steps to reproduce, expected vs actual behavior...',
550
+ placeholderTextColor: colors.textSecondary,
551
+ multiline: true,
552
+ numberOfLines: 4,
553
+ maxLength: 2000,
554
+ }),
555
+ // Severity
556
+ react_1.default.createElement(Text, { style: styles.label }, 'Severity'), react_1.default.createElement(View, { style: styles.buttonGroup }, ...SEVERITIES.map((s) => react_1.default.createElement(TouchableOpacity, {
557
+ key: s,
558
+ style: s === severity
559
+ ? styles.buttonGroupItemActive
560
+ : styles.buttonGroupItem,
561
+ onPress: () => setSeverity(s),
562
+ }, react_1.default.createElement(Text, {
563
+ style: s === severity
564
+ ? styles.buttonGroupTextActive
565
+ : styles.buttonGroupText,
566
+ }, SEVERITY_LABELS[s])))),
567
+ // Category
568
+ react_1.default.createElement(Text, { style: styles.label }, 'Category'), react_1.default.createElement(View, { style: styles.buttonGroup }, ...CATEGORIES.map((c) => react_1.default.createElement(TouchableOpacity, {
569
+ key: c,
570
+ style: c === category
571
+ ? styles.buttonGroupItemActive
572
+ : styles.buttonGroupItem,
573
+ onPress: () => setCategory(c),
574
+ }, react_1.default.createElement(Text, {
575
+ style: c === category
576
+ ? styles.buttonGroupTextActive
577
+ : styles.buttonGroupText,
578
+ }, CATEGORY_LABELS[c])))),
579
+ // Device context (collapsible)
580
+ contextItems.length > 0
581
+ ? react_1.default.createElement(react_1.default.Fragment, null, react_1.default.createElement(TouchableOpacity, {
582
+ style: styles.contextHeader,
583
+ onPress: () => setContextExpanded(!contextExpanded),
584
+ }, react_1.default.createElement(Text, { style: styles.contextHeaderText }, 'Device Context'), react_1.default.createElement(Text, { style: styles.contextToggle }, contextExpanded ? 'Hide' : 'Show')), contextExpanded
585
+ ? react_1.default.createElement(View, null, ...contextItems.map((item) => react_1.default.createElement(View, { key: item.key, style: styles.contextRow }, react_1.default.createElement(Text, { style: styles.contextKey }, item.key), react_1.default.createElement(Text, { style: styles.contextValue, numberOfLines: 1 }, item.value))))
586
+ : null)
587
+ : null,
588
+ // Error banner
589
+ submitError
590
+ ? react_1.default.createElement(View, { style: styles.errorBanner }, react_1.default.createElement(Text, { style: styles.errorBannerText }, submitError))
591
+ : null,
592
+ // Submit button
593
+ react_1.default.createElement(TouchableOpacity, {
594
+ style: canSubmit
595
+ ? styles.submitButton
596
+ : styles.submitButtonDisabled,
597
+ onPress: () => void handleSubmit(),
598
+ disabled: !canSubmit,
599
+ }, react_1.default.createElement(Text, { style: styles.submitButtonText }, submitting ? 'Submitting...' : 'Submit Report')))),
600
+ // Loading overlay
601
+ submitting
602
+ ? react_1.default.createElement(View, { style: styles.loadingOverlay, pointerEvents: 'auto' }, react_1.default.createElement(ActivityIndicator, {
603
+ size: 'large',
604
+ color: '#FFFFFF',
605
+ }), react_1.default.createElement(Text, { style: styles.loadingText }, 'Submitting report...'))
606
+ : null));
607
+ }
608
+ //# sourceMappingURL=ReportForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReportForm.js","sourceRoot":"","sources":["../../src/ui/ReportForm.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Validation result for a single field.
3
+ */
4
+ export interface FieldError {
5
+ field: string;
6
+ message: string;
7
+ }
8
+ /**
9
+ * Validates the title field.
10
+ * - Required (non-empty after trim)
11
+ * - Minimum 3 characters after trim
12
+ */
13
+ export declare function validateTitle(title: string): FieldError | null;
14
+ /**
15
+ * Validates the complete form. Returns an array of field errors (empty = valid).
16
+ */
17
+ export declare function validateForm(fields: {
18
+ title: string;
19
+ }): FieldError[];
20
+ /**
21
+ * Returns true if the form is valid for submission.
22
+ */
23
+ export declare function isFormValid(fields: {
24
+ title: string;
25
+ }): boolean;
26
+ //# sourceMappingURL=form-validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-validation.d.ts","sourceRoot":"","sources":["../../src/ui/form-validation.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAS9D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE;IACnC,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,UAAU,EAAE,CAOf;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAE9D"}