@cleanuidev/react-native-scanner 1.0.0-beta.1 → 1.0.0-beta.3

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.
package/README.md CHANGED
@@ -2,16 +2,18 @@
2
2
 
3
3
  # 📱 React Native Scanner
4
4
 
5
- **A powerful, native barcode and QR code scanner for React Native**
5
+ **A powerful, native barcode and QR code scanner for React Native with configurable target area scanning**
6
+
7
+ ![React Native Barcode Scanner Demo - QR Code and Barcode Scanning with Target Area](./preview.gif)
6
8
 
7
9
  [![npm version](https://img.shields.io/npm/v/@cleanuidev/react-native-scanner?label=beta&color=blue)](https://www.npmjs.com/package/@cleanuidev/react-native-scanner)
8
10
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
- [![Platform](https://img.shields.io/badge/Platform-Android-blue.svg)](https://www.android.com/)
11
+ [![Platform](https://img.shields.io/badge/Platform-Android%20%7C%20iOS-blue.svg)](https://reactnative.dev/)
10
12
  [![React Native](https://img.shields.io/badge/React%20Native-0.83+-61DAFB?logo=react)](https://reactnative.dev/)
11
13
 
12
14
  **Built with ❤️ by [CleanUI.dev](https://cleanui.dev)**
13
15
 
14
- [Features](#-features) • [Installation](#-installation) • [Documentation](#-documentation) • [Support](#-consulting--support)
16
+ [Features](#-features) • [Installation](#-installation) • [Documentation](#-documentation)
15
17
 
16
18
  </div>
17
19
 
@@ -23,12 +25,12 @@
23
25
 
24
26
  | Feature | Description |
25
27
  |:------:|:-----------|
26
- | 🚀 **Native Performance** | Built with CameraX and ML Kit for optimal performance |
27
- | 🎯 **Focus Area** | Configurable focus area with optional overlay for precise scanning |
28
+ | 🚀 **Native Performance** | Built with CameraX & ML Kit (Android) and AVFoundation & Vision (iOS) for optimal performance |
29
+ | 🎯 **Target Area Scanning** | Scan barcodes within configurable target areas for precise detection |
28
30
  | 🔦 **Torch Control** | Built-in flashlight/torch control |
29
31
  | 📊 **Multiple Formats** | Support for QR codes, Code128, Code39, EAN, UPC, and more |
30
- | 🎨 **Customizable** | Configurable focus area colors, barcode frame visualization, and scanning behavior |
31
- | 📱 **Cross Platform** | Android support (iOS coming soon) |
32
+ | 🎨 **Customizable** | Configurable target area colors, barcode frame visualization, and scanning behavior |
33
+ | 📱 **Cross Platform** | Android & iOS support (new Fabric architecture) |
32
34
 
33
35
  </div>
34
36
 
@@ -56,13 +58,15 @@ npm install @cleanuidev/react-native-scanner@1.0.0-beta.1
56
58
  yarn add @cleanuidev/react-native-scanner@1.0.0-beta.1
57
59
  ```
58
60
 
59
- > **💡 Note**: Once the library reaches stable release (1.0.0), you can install it without the `@beta` tag:
61
+ > **Note**: Once the library reaches stable release (1.0.0), you can install it without the `@beta` tag:
60
62
  > ```bash
61
63
  > npm install @cleanuidev/react-native-scanner
62
64
  > # or
63
65
  > yarn add @cleanuidev/react-native-scanner
64
66
  > ```
65
67
 
68
+ ## Platform Setup
69
+
66
70
  ### Android Setup
67
71
 
68
72
  Add the following permissions to your `android/app/src/main/AndroidManifest.xml`:
@@ -75,9 +79,22 @@ Add the following permissions to your `android/app/src/main/AndroidManifest.xml`
75
79
  <uses-feature android:name="android.hardware.camera.flash" android:required="false" />
76
80
  ```
77
81
 
78
- ---
82
+ ### iOS Setup
83
+
84
+ For iOS, add camera usage description to your `ios/YourApp/Info.plist`:
85
+
86
+ ```xml
87
+ <key>NSCameraUsageDescription</key>
88
+ <string>This app needs camera access to scan barcodes and QR codes</string>
89
+ ```
90
+
91
+ Then install CocoaPods dependencies:
92
+
93
+ ```bash
94
+ cd ios && pod install && cd ..
95
+ ```
79
96
 
80
- ## 🚀 Quick Start
97
+ ## Usage
81
98
 
82
99
  ### Basic Scanner
83
100
 
@@ -112,7 +129,7 @@ const styles = StyleSheet.create({
112
129
  });
113
130
  ```
114
131
 
115
- ### Scanner with Focus Area
132
+ ### Scanner with Target Area
116
133
 
117
134
  ```tsx
118
135
  import React, { useState } from 'react';
@@ -122,12 +139,12 @@ import ScannerView, { BarcodeFormat } from '@cleanuidev/react-native-scanner';
122
139
  export default function FocusAreaScanner() {
123
140
  const [torchEnabled, setTorchEnabled] = useState(false);
124
141
 
125
- // Focus area configuration
142
+ // Target area configuration
126
143
  const focusAreaConfig = {
127
- enabled: true, // Only scan barcodes within the focus area
128
- showOverlay: true, // Show the focus area overlay
129
- size: 300, // Size of the focus area (square)
130
- color: '#00FF00', // Color of the focus area border
144
+ enabled: true, // Only scan barcodes within the target area
145
+ showOverlay: true, // Show overlay outside the target area
146
+ size: 300, // Size of the target area (square)
147
+ color: '#00FF00', // Color of the target area border
131
148
  };
132
149
 
133
150
  // Barcode frames configuration
@@ -174,36 +191,14 @@ export default function FocusAreaScanner() {
174
191
  }
175
192
  ```
176
193
 
177
- ---
178
-
179
- ## 🎨 UI Design Note
180
-
181
- > **💡 Note**: The native overlays and frames are provided to fulfill minimum design requirements and for debugging during development. We **recommend implementing custom React Native UI** for enhanced user experiences.
194
+ ## API Reference
182
195
 
183
- To use custom UI, simply disable the native visual overlays and build your own:
184
-
185
- ```tsx
186
- <ScannerView
187
- focusArea={{ enabled: true, showOverlay: false }} // Disable native overlay
188
- barcodeFrames={{ enabled: false }} // Disable native frames
189
- onBarcodeScanned={handleBarcodeScanned}
190
- />
191
- ```
192
-
193
- Then layer your custom React Native components on top for a fully branded experience.
194
-
195
- ---
196
-
197
- ## 📚 Documentation
198
-
199
- ### API Reference
200
-
201
- #### Props
196
+ ### Props
202
197
 
203
198
  | Prop | Type | Default | Description |
204
- |:----:|:----:|:-------:|:-----------|
199
+ |------|------|---------|-------------|
205
200
  | `barcodeTypes` | `BarcodeFormat[]` | `[BarcodeFormat.QR_CODE]` | Array of barcode formats to scan |
206
- | `focusArea` | `FocusAreaConfig` | - | Focus area configuration |
201
+ | `focusArea` | `FocusAreaConfig` | - | Target area configuration for precise scanning |
207
202
  | `barcodeFrames` | `BarcodeFramesConfig` | - | Barcode frame visualization configuration |
208
203
  | `torch` | `boolean` | `false` | Enable/disable torch/flashlight |
209
204
  | `zoom` | `number` | `1.0` | Camera zoom level |
@@ -214,30 +209,28 @@ Then layer your custom React Native components on top for a fully branded experi
214
209
  | `onScannerError` | `function` | - | Callback when scanner encounters an error |
215
210
  | `onLoad` | `function` | - | Callback when scanner is loaded |
216
211
 
217
- #### Configuration Types
218
-
219
- ##### FocusAreaConfig
212
+ #### FocusAreaConfig
220
213
 
221
214
  ```tsx
222
215
  type FocusAreaConfig = {
223
- enabled?: boolean; // Whether to restrict scanning to focus area only
224
- size?: FrameSize; // Size of the focus area
225
- color?: string; // Color of focus area border
226
- showOverlay?: boolean; // Whether to draw the focus area overlay
216
+ enabled?: boolean; // Whether to restrict scanning to target area only
217
+ size?: FrameSize; // Size of the target area
218
+ color?: string; // Color of target area border
219
+ showOverlay?: boolean; // Whether to draw overlay outside the target area
227
220
  };
228
221
  ```
229
222
 
230
- ##### BarcodeFramesConfig
223
+ #### BarcodeFramesConfig
231
224
 
232
225
  ```tsx
233
226
  type BarcodeFramesConfig = {
234
227
  enabled?: boolean; // Whether to draw frames around detected barcodes
235
228
  color?: string; // Color of barcode frames
236
- onlyInFocusArea?: boolean; // Only show frames for barcodes in focus area
229
+ onlyInFocusArea?: boolean; // Only show frames for barcodes in target area
237
230
  };
238
231
  ```
239
232
 
240
- ##### FrameSize
233
+ #### FrameSize
241
234
 
242
235
  ```tsx
243
236
  type FrameSize = number | { width: number; height: number };
@@ -257,7 +250,7 @@ BarcodeScanStrategy.BIGGEST // Process only the largest barcode by area
257
250
  BarcodeScanStrategy.SORT_BY_BIGGEST // Process all barcodes sorted by size (largest first)
258
251
  ```
259
252
 
260
- #### Barcode Formats
253
+ ### Barcode Formats
261
254
 
262
255
  ```tsx
263
256
  import { BarcodeFormat } from '@cleanuidev/react-native-scanner';
@@ -276,10 +269,9 @@ BarcodeFormat.AZTEC // Aztec
276
269
  BarcodeFormat.ITF // ITF (Interleaved 2 of 5)
277
270
  ```
278
271
 
279
- #### Event Payloads
280
-
281
- ##### onBarcodeScanned
272
+ ### Event Payloads
282
273
 
274
+ #### onBarcodeScanned
283
275
  ```tsx
284
276
  {
285
277
  nativeEvent: [
@@ -299,8 +291,7 @@ BarcodeFormat.ITF // ITF (Interleaved 2 of 5)
299
291
  }
300
292
  ```
301
293
 
302
- ##### onScannerError
303
-
294
+ #### onScannerError
304
295
  ```tsx
305
296
  {
306
297
  nativeEvent: {
@@ -310,8 +301,7 @@ BarcodeFormat.ITF // ITF (Interleaved 2 of 5)
310
301
  }
311
302
  ```
312
303
 
313
- ##### onLoad
314
-
304
+ #### onLoad
315
305
  ```tsx
316
306
  {
317
307
  nativeEvent: {
@@ -321,20 +311,16 @@ BarcodeFormat.ITF // ITF (Interleaved 2 of 5)
321
311
  }
322
312
  ```
323
313
 
324
- ---
314
+ ## Target Area Configuration
325
315
 
326
- ## 🎯 Advanced Usage
316
+ The target area feature provides precise control over where barcodes are scanned:
327
317
 
328
- ### Focus Area Configuration
329
-
330
- The focus area feature provides precise control over where barcodes are scanned:
331
-
332
- #### Basic Focus Area
318
+ ### Basic Target Area
333
319
 
334
320
  ```tsx
335
321
  <ScannerView
336
322
  focusArea={{
337
- showOverlay: true, // Show visual overlay
323
+ showOverlay: true, // Show overlay outside the target area
338
324
  size: 300, // 300x300 pixel square
339
325
  color: '#00FF00', // Green border
340
326
  }}
@@ -342,38 +328,69 @@ The focus area feature provides precise control over where barcodes are scanned:
342
328
  />
343
329
  ```
344
330
 
345
- #### Focus Area with Restricted Scanning
331
+ ### Target Area with Restricted Scanning
346
332
 
347
333
  ```tsx
348
334
  <ScannerView
349
335
  focusArea={{
350
- enabled: true, // Only scan within focus area
351
- showOverlay: true, // Show visual overlay
336
+ enabled: true, // Only scan within target area
337
+ showOverlay: true, // Show overlay outside the target area
352
338
  size: 300, // 300x300 pixel square
353
339
  color: '#00FF00', // Green border
354
340
  }}
355
- // Only scans within the focus area
341
+ // Only scans within the target area
342
+ />
343
+ ```
344
+
345
+ ### Rectangular Target Area
346
+
347
+ ```tsx
348
+ <ScannerView
349
+ focusArea={{
350
+ enabled: true,
351
+ showOverlay: true,
352
+ size: { width: 300, height: 200 }, // Rectangular target area
353
+ color: '#00FF00',
354
+ }}
355
+ />
356
+ ```
357
+
358
+ ### Positioning Target Area with Coordinates
359
+
360
+ You can position the target area anywhere on the screen using percentage-based coordinates (0-100):
361
+
362
+ ```tsx
363
+ <ScannerView
364
+ focusArea={{
365
+ enabled: true,
366
+ showOverlay: true,
367
+ size: 300,
368
+ position: { x: 50, y: 50 }, // Center position (default)
369
+ color: '#00FF00',
370
+ }}
356
371
  />
357
372
  ```
358
373
 
359
- #### Rectangular Focus Area
374
+ **Example: Position target area at top center**
360
375
 
361
376
  ```tsx
362
377
  <ScannerView
363
378
  focusArea={{
364
379
  enabled: true,
365
380
  showOverlay: true,
366
- size: { width: 300, height: 200 }, // Rectangular focus area
381
+ size: 250,
382
+ position: { x: 50, y: 25 }, // Top center
367
383
  color: '#00FF00',
368
384
  }}
385
+ onBarcodeScanned={handleBarcodeScanned}
369
386
  />
370
387
  ```
371
388
 
372
- ### Barcode Frame Visualization
389
+ ## Barcode Frame Visualization
373
390
 
374
391
  The scanner can display visual frames around detected barcodes to help users see what's being scanned:
375
392
 
376
- #### Show All Barcode Frames
393
+ ### Show All Barcode Frames
377
394
 
378
395
  ```tsx
379
396
  <ScannerView
@@ -385,7 +402,7 @@ The scanner can display visual frames around detected barcodes to help users see
385
402
  />
386
403
  ```
387
404
 
388
- #### Show Frames Only in Focus Area
405
+ ### Show Frames Only in Target Area
389
406
 
390
407
  ```tsx
391
408
  <ScannerView
@@ -397,16 +414,16 @@ The scanner can display visual frames around detected barcodes to help users see
397
414
  barcodeFrames={{
398
415
  enabled: true,
399
416
  color: '#FF0000',
400
- onlyInFocusArea: true, // Only show frames for barcodes in focus area
417
+ onlyInFocusArea: true, // Only show frames for barcodes in target area
401
418
  }}
402
419
  />
403
420
  ```
404
421
 
405
- ### Barcode Scan Strategy
422
+ ## Barcode Scan Strategy
406
423
 
407
- The scanner supports different strategies for processing multiple detected barcodes. The `onBarcodeScanned` event always returns an array of barcodes, even when only one barcode is processed.
424
+ The scanner now supports different strategies for processing multiple detected barcodes. The `onBarcodeScanned` event always returns an array of barcodes, even when only one barcode is processed.
408
425
 
409
- #### Process All Barcodes (Default)
426
+ ### Process All Barcodes (Default)
410
427
 
411
428
  ```tsx
412
429
  <ScannerView
@@ -418,7 +435,7 @@ The scanner supports different strategies for processing multiple detected barco
418
435
  />
419
436
  ```
420
437
 
421
- #### Process Only the First Barcode
438
+ ### Process Only the First Barcode
422
439
 
423
440
  ```tsx
424
441
  <ScannerView
@@ -433,7 +450,7 @@ The scanner supports different strategies for processing multiple detected barco
433
450
  />
434
451
  ```
435
452
 
436
- #### Process Only the Largest Barcode
453
+ ### Process Only the Largest Barcode
437
454
 
438
455
  ```tsx
439
456
  <ScannerView
@@ -449,7 +466,7 @@ The scanner supports different strategies for processing multiple detected barco
449
466
  />
450
467
  ```
451
468
 
452
- #### Process All Barcodes Sorted by Size
469
+ ### Process All Barcodes Sorted by Size
453
470
 
454
471
  ```tsx
455
472
  <ScannerView
@@ -464,7 +481,7 @@ The scanner supports different strategies for processing multiple detected barco
464
481
  />
465
482
  ```
466
483
 
467
- ### Torch Control
484
+ ## Torch Control
468
485
 
469
486
  The torch/flashlight can be controlled via the `torch` prop:
470
487
 
@@ -477,11 +494,11 @@ const [torchEnabled, setTorchEnabled] = useState(false);
477
494
  />
478
495
  ```
479
496
 
480
- ### Keep Screen On
497
+ ## Keep Screen On
481
498
 
482
499
  The scanner automatically keeps the screen on while the camera is active to prevent auto-lock during scanning sessions. This behavior can be controlled via the `keepScreenOn` prop:
483
500
 
484
- #### Default Behavior (Screen Stays On)
501
+ ### Default Behavior (Screen Stays On)
485
502
 
486
503
  ```tsx
487
504
  <ScannerView
@@ -490,7 +507,7 @@ The scanner automatically keeps the screen on while the camera is active to prev
490
507
  />
491
508
  ```
492
509
 
493
- #### Allow Screen Auto-Lock
510
+ ### Allow Screen Auto-Lock
494
511
 
495
512
  ```tsx
496
513
  <ScannerView
@@ -499,7 +516,7 @@ The scanner automatically keeps the screen on while the camera is active to prev
499
516
  />
500
517
  ```
501
518
 
502
- #### Dynamic Control
519
+ ### Dynamic Control
503
520
 
504
521
  ```tsx
505
522
  const [keepScreenOn, setKeepScreenOn] = useState(true);
@@ -515,11 +532,23 @@ const [keepScreenOn, setKeepScreenOn] = useState(true);
515
532
  </TouchableOpacity>
516
533
  ```
517
534
 
518
- > **💡 Note**: The screen is kept on by default (`keepScreenOn={true}`) as this is typically desired for scanning applications. When disabled, the screen may auto-lock, which could interrupt scanning sessions.
535
+ **Note**: The screen is kept on by default (`keepScreenOn={true}`) as this is typically desired for scanning applications. When disabled, the screen may auto-lock, which could interrupt scanning sessions.
519
536
 
520
- ---
537
+ ## 🎨 UI Design Note
521
538
 
522
- ## 🔐 Permissions
539
+ > **💡 Note**: The native overlays and frames are provided to fulfill minimum design requirements and for debugging during development. We **recommend implementing custom React Native UI** for enhanced user experiences.
540
+
541
+ To use custom UI, simply disable the native visual overlays and build your own:
542
+
543
+ ```tsx
544
+ <ScannerView
545
+ focusArea={{ enabled: true, showOverlay: false }} // Disable native overlay
546
+ barcodeFrames={{ enabled: false }} // Disable native frames
547
+ onBarcodeScanned={handleBarcodeScanned}
548
+ />
549
+ ```
550
+
551
+ ## Permissions
523
552
 
524
553
  The scanner requires camera permissions. Make sure to request camera permissions in your app before using the scanner:
525
554
 
@@ -549,17 +578,11 @@ const requestCameraPermission = async () => {
549
578
  };
550
579
  ```
551
580
 
552
- ---
553
-
554
- ## 📖 Examples
581
+ ## Example
555
582
 
556
583
  See the `example/` directory for complete working examples, including the "New Props Example" that demonstrates the updated prop structure.
557
584
 
558
- ---
559
-
560
- ## 🤝 Contributing
561
-
562
- We welcome contributions! Please follow these steps:
585
+ ## Contributing
563
586
 
564
587
  1. Fork the repository
565
588
  2. Create your feature branch (`git checkout -b feature/amazing-feature`)
@@ -567,10 +590,6 @@ We welcome contributions! Please follow these steps:
567
590
  4. Push to the branch (`git push origin feature/amazing-feature`)
568
591
  5. Open a Pull Request
569
592
 
570
- For more details, see our [Contributing Guide](CONTRIBUTING.md).
571
-
572
- ---
573
-
574
593
  ## 💼 Consulting & Support
575
594
 
576
595
  ### Community Support (Free)
@@ -579,6 +598,19 @@ For bug reports, feature requests, and general questions:
579
598
  - 📝 [Open an issue](https://github.com/cleanui-dev/react-native-scanner/issues) on GitHub
580
599
  - 💬 Use GitHub Discussions for questions and community help
581
600
 
601
+ ### Support the Maintainer
602
+
603
+ If you find this library useful, consider supporting the maintainer/developer directly through donations:
604
+
605
+ - 💰 [Donate via PayPal](https://paypal.me/rahulgwebdev) - Support the maintainer directly and help keep this project maintained and improved
606
+ - ⭐ Star the repository - Show your appreciation and help others discover this library
607
+
608
+ **Your donations help:**
609
+ - 🐛 Maintain and fix bugs
610
+ - ✨ Add new features and improvements
611
+ - 📚 Keep documentation up to date
612
+ - ⚡ Ensure long-term sustainability of the project
613
+
582
614
  ### Commercial Support & Consulting
583
615
 
584
616
  Need professional help with implementation, custom development, or enterprise support?
@@ -594,16 +626,10 @@ Need professional help with implementation, custom development, or enterprise su
594
626
 
595
627
  ---
596
628
 
597
- ## 📄 License
629
+ ## License
598
630
 
599
631
  This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
600
632
 
601
633
  ---
602
634
 
603
- <div align="center">
604
-
605
- **Made with ❤️ by [CleanUI.dev](https://cleanui.dev)**
606
-
607
- [Website](https://cleanui.dev) • [GitHub](https://github.com/cleanui-dev) • [Support](mailto:hi@cleanuitechnologies.com)
608
-
609
- </div>
635
+ Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)
package/Scanner.podspec CHANGED
@@ -11,7 +11,7 @@ Pod::Spec.new do |s|
11
11
  s.authors = package["author"]
12
12
 
13
13
  s.platforms = { :ios => min_ios_version_supported }
14
- s.source = { :git => "https://github.com/cleanui-dev/react-native-scanner.git", :tag => "#{s.version}" }
14
+ s.source = { :git => "https://github.com/rahulgwebdev/react-native-scanner.git", :tag => "#{s.version}" }
15
15
 
16
16
  s.source_files = "ios/**/*.{h,m,mm,swift,cpp}"
17
17
  s.private_header_files = "ios/**/*.h"
@@ -222,6 +222,7 @@ class ScannerView : FrameLayout {
222
222
 
223
223
  if (!hasCameraPermission()) {
224
224
  Log.e(TAG, "Camera permission not granted")
225
+ emitOnScannerError("Camera permission not granted", "CAMERA_PERMISSION_DENIED")
225
226
  return
226
227
  }
227
228
 
@@ -331,8 +332,16 @@ class ScannerView : FrameLayout {
331
332
  // Set up auto-focus on frame center (if focus area is enabled)
332
333
  setupAutoFocusOnFrame()
333
334
 
335
+ // Emit onLoad event after camera is successfully started
336
+ emitOnLoadEvent(success = true)
337
+
334
338
  } catch (exc: Exception) {
335
339
  Log.e(TAG, "Use case binding failed", exc)
340
+ // Emit onScannerError event for camera initialization failure
341
+ emitOnScannerError(
342
+ error = exc.message ?: "Camera binding failed",
343
+ code = "CAMERA_INITIALIZATION_FAILED"
344
+ )
336
345
  }
337
346
  }
338
347
 
@@ -450,12 +459,14 @@ class ScannerView : FrameLayout {
450
459
  // Debounce: Prevent rapid duplicate emissions
451
460
  // If we've emitted recently (within debounce interval), skip this emission
452
461
  // This prevents multiple alerts when pauseScanning is set but detection callbacks are still in flight
462
+ Log.d(TAG, "📊 Debounce check: interval=${barcodeEmissionDebounceInterval}ms, timeSinceLast=${timeSinceLastEmission}ms")
453
463
  if (timeSinceLastEmission < barcodeEmissionDebounceInterval) {
454
- Log.d(TAG, "⏭️ Skipping barcode emission (debounced, last emission was ${timeSinceLastEmission}ms ago)")
464
+ Log.d(TAG, "⏭️ Skipping barcode emission (debounced, last emission was ${timeSinceLastEmission}ms ago, interval=${barcodeEmissionDebounceInterval}ms)")
455
465
  return@addOnSuccessListener
456
466
  }
457
467
 
458
468
  lastBarcodeEmissionTime = currentTime
469
+ Log.d(TAG, "✅ Emitting barcode (interval=${barcodeEmissionDebounceInterval}ms, timeSinceLast=${timeSinceLastEmission}ms)")
459
470
 
460
471
  // Create array of barcode events
461
472
  val barcodeEvents = Arguments.createArray()
@@ -502,6 +513,11 @@ class ScannerView : FrameLayout {
502
513
  }
503
514
  }
504
515
  .addOnFailureListener { e ->
516
+ // Emit onScannerError event for barcode detection failure
517
+ emitOnScannerError(
518
+ error = e.message ?: "Barcode detection failed",
519
+ code = "BARCODE_DETECTION_FAILED"
520
+ )
505
521
  Log.e(TAG, "Barcode scanning failed", e)
506
522
  }
507
523
  .addOnCompleteListener {
@@ -613,8 +629,48 @@ class ScannerView : FrameLayout {
613
629
 
614
630
  fun setBarcodeEmissionInterval(intervalSeconds: Double) {
615
631
  // Convert seconds to milliseconds, ensure non-negative
632
+ val previousInterval = barcodeEmissionDebounceInterval
633
+ Log.d(TAG, "📊 [ScannerView] setBarcodeEmissionInterval called with: ${intervalSeconds}s")
616
634
  barcodeEmissionDebounceInterval = max(0, (intervalSeconds * 1000).toLong())
617
- Log.d(TAG, "Barcode emission interval set to: ${barcodeEmissionDebounceInterval}ms")
635
+ Log.d(TAG, "📊 ScannerView.setBarcodeEmissionInterval: ${intervalSeconds}s -> ${barcodeEmissionDebounceInterval}ms (was ${previousInterval}ms)")
636
+
637
+ if (barcodeEmissionDebounceInterval == 0L) {
638
+ Log.d(TAG, "📊 ⚠️ Debouncing DISABLED (interval = 0ms)")
639
+ } else {
640
+ Log.d(TAG, "📊 ✅ Debouncing ENABLED (interval = ${barcodeEmissionDebounceInterval}ms)")
641
+ }
642
+ }
643
+
644
+ private fun emitOnLoadEvent(success: Boolean, error: String? = null) {
645
+ val ctx = reactContext
646
+ if (ctx is ThemedReactContext) {
647
+ ctx.runOnUiQueueThread {
648
+ val eventData = Arguments.createMap().apply {
649
+ putBoolean("success", success)
650
+ if (error != null) {
651
+ putString("error", error)
652
+ }
653
+ }
654
+ ctx.getJSModule(RCTEventEmitter::class.java)
655
+ .receiveEvent(this@ScannerView.id, "onLoad", eventData)
656
+ Log.d(TAG, "✅ onLoad event emitted: success=$success, error=$error")
657
+ }
658
+ }
659
+ }
660
+
661
+ private fun emitOnScannerError(error: String, code: String) {
662
+ val ctx = reactContext
663
+ if (ctx is ThemedReactContext) {
664
+ ctx.runOnUiQueueThread {
665
+ val eventData = Arguments.createMap().apply {
666
+ putString("error", error)
667
+ putString("code", code)
668
+ }
669
+ ctx.getJSModule(RCTEventEmitter::class.java)
670
+ .receiveEvent(this@ScannerView.id, "onScannerError", eventData)
671
+ Log.d(TAG, "✅ onScannerError event emitted: code=$code, error=$error")
672
+ }
673
+ }
618
674
  }
619
675
 
620
676
  fun setBarcodeScanStrategy(strategy: String) {
@@ -6,12 +6,20 @@ import com.facebook.react.bridge.*
6
6
  import com.facebook.react.module.annotations.ReactModule
7
7
  import com.facebook.react.uimanager.SimpleViewManager
8
8
  import com.facebook.react.uimanager.ThemedReactContext
9
+ import com.facebook.react.uimanager.ViewManagerDelegate
9
10
  import com.facebook.react.uimanager.annotations.ReactProp
10
11
  import com.facebook.react.uimanager.events.RCTModernEventEmitter
12
+ import com.facebook.react.viewmanagers.ScannerViewManagerInterface
13
+ import com.facebook.react.viewmanagers.ScannerViewManagerDelegate
11
14
 
12
15
  @ReactModule(name = ScannerViewManager.NAME)
13
- class ScannerViewManager : SimpleViewManager<ScannerView>() {
16
+ class ScannerViewManager : SimpleViewManager<ScannerView>(),
17
+ ScannerViewManagerInterface<ScannerView> {
18
+ private val mDelegate: ViewManagerDelegate<ScannerView> = ScannerViewManagerDelegate(this)
14
19
 
20
+ override fun getDelegate(): ViewManagerDelegate<ScannerView> {
21
+ return mDelegate
22
+ }
15
23
  override fun getName(): String {
16
24
  return NAME
17
25
  }
@@ -22,7 +30,7 @@ class ScannerViewManager : SimpleViewManager<ScannerView>() {
22
30
 
23
31
  // Barcode configuration
24
32
  @ReactProp(name = "barcodeTypes")
25
- fun setBarcodeTypes(view: ScannerView?, types: ReadableArray?) {
33
+ override fun setBarcodeTypes(view: ScannerView?, types: ReadableArray?) {
26
34
  if (types != null) {
27
35
  val typeList = mutableListOf<String>()
28
36
  for (i in 0 until types.size()) {
@@ -36,33 +44,33 @@ class ScannerViewManager : SimpleViewManager<ScannerView>() {
36
44
 
37
45
  // Focus area configuration
38
46
  @ReactProp(name = "focusArea")
39
- fun setFocusArea(view: ScannerView?, focusArea: ReadableMap?) {
47
+ override fun setFocusArea(view: ScannerView?, focusArea: ReadableMap?) {
40
48
  if (focusArea != null) {
41
- val enabled = focusArea.getBoolean("enabled") ?: false
42
- val showOverlay = focusArea.getBoolean("showOverlay") ?: false
49
+ val enabled = focusArea.getBoolean("enabled")
50
+ val showOverlay = focusArea.getBoolean("showOverlay")
43
51
  val borderColor = focusArea.getString("borderColor")
44
52
  val tintColor = focusArea.getString("tintColor")
45
53
  val size = focusArea.getDynamic("size")
46
54
  val position = focusArea.getMap("position")
47
-
55
+
48
56
  // Set focus area properties
49
57
  view?.setFocusAreaEnabled(enabled)
50
58
  view?.setEnableFrame(showOverlay)
51
-
59
+
52
60
  if (borderColor != null) {
53
61
  view?.setBorderColor(borderColor)
54
62
  }
55
-
63
+
56
64
  if (tintColor != null) {
57
65
  view?.setTintColor(tintColor)
58
66
  }
59
-
67
+
60
68
  if (position != null) {
61
69
  val x = position.getDouble("x").toFloat()
62
70
  val y = position.getDouble("y").toFloat()
63
71
  view?.setPosition(x, y)
64
72
  }
65
-
73
+
66
74
  if (size != null) {
67
75
  val frameSize: FrameSize = when {
68
76
  size.type == ReadableType.Number -> FrameSize.Square(size.asInt())
@@ -76,40 +84,40 @@ class ScannerViewManager : SimpleViewManager<ScannerView>() {
76
84
  }
77
85
  view?.setFrameSize(frameSize)
78
86
  }
79
-
87
+
80
88
  Log.d("ScannerViewManager", "Focus area configured: enabled=$enabled, showOverlay=$showOverlay, borderColor=$borderColor, tintColor=$tintColor, position=$position")
81
89
  }
82
90
  }
83
91
 
84
92
  // Barcode frames configuration
85
93
  @ReactProp(name = "barcodeFrames")
86
- fun setBarcodeFrames(view: ScannerView?, barcodeFrames: ReadableMap?) {
94
+ override fun setBarcodeFrames(view: ScannerView?, barcodeFrames: ReadableMap?) {
87
95
  if (barcodeFrames != null) {
88
96
  val enabled = barcodeFrames.getBoolean("enabled") ?: false
89
97
  val color = barcodeFrames.getString("color")
90
98
  val onlyInFocusArea = barcodeFrames.getBoolean("onlyInFocusArea") ?: false
91
-
99
+
92
100
  // Set barcode frames properties
93
101
  view?.setBarcodeFramesEnabled(enabled)
94
102
  view?.setShowBarcodeFramesOnlyInFrame(onlyInFocusArea)
95
-
103
+
96
104
  if (color != null) {
97
105
  view?.setBarcodeFramesColor(color)
98
106
  }
99
-
107
+
100
108
  Log.d("ScannerViewManager", "Barcode frames configured: enabled=$enabled, onlyInFocusArea=$onlyInFocusArea, color=$color")
101
109
  }
102
110
  }
103
111
 
104
112
  // Torch control
105
113
  @ReactProp(name = "torch")
106
- fun setTorch(view: ScannerView?, enabled: Boolean?) {
107
- view?.setTorch(enabled ?: false)
114
+ override fun setTorch(view: ScannerView, value: Boolean) {
115
+ view.setTorch(value)
108
116
  }
109
117
 
110
118
  // Event handlers
111
119
  @ReactProp(name = "onBarcodeScanned")
112
- fun setOnBarcodeScanned(view: ScannerView?, onBarcodeScanned: Boolean?) {
120
+ fun setOnBarcodeScanned(view: ScannerView?, onBarcodeScanned: Boolean?) {
113
121
  // This prop is used to register the event handler
114
122
  // The actual event emission happens in ScannerView.processImage()
115
123
  Log.d("ScannerViewManager", "onBarcodeScanned event handler registered")
@@ -128,33 +136,49 @@ class ScannerViewManager : SimpleViewManager<ScannerView>() {
128
136
  }
129
137
 
130
138
  @ReactProp(name = "zoom")
131
- fun setZoom(view: ScannerView?, zoom: Double) {
139
+ override fun setZoom(view: ScannerView?, zoom: Double) {
132
140
  view?.setZoom(zoom.toFloat())
133
141
  }
134
142
 
135
143
  @ReactProp(name = "pauseScanning")
136
- fun setPauseScanning(view: ScannerView?, pause: Boolean?) {
137
- if (pause == true) {
138
- view?.pauseScanning()
144
+ override fun setPauseScanning(view: ScannerView, value: Boolean) {
145
+ if (value) {
146
+ view.pauseScanning()
139
147
  } else {
140
- view?.resumeScanning()
148
+ view.resumeScanning()
141
149
  }
142
150
  }
143
151
 
144
152
  @ReactProp(name = "barcodeScanStrategy")
145
- fun setBarcodeScanStrategy(view: ScannerView?, strategy: String?) {
153
+ override fun setBarcodeScanStrategy(view: ScannerView?, strategy: String?) {
146
154
  view?.setBarcodeScanStrategy(strategy ?: "ALL")
147
155
  }
148
156
 
149
157
  @ReactProp(name = "keepScreenOn")
150
- fun setKeepScreenOn(view: ScannerView?, keepOn: Boolean?) {
151
- view?.setKeepScreenOnEnabled(keepOn ?: true)
158
+ override fun setKeepScreenOn(view: ScannerView, value: Boolean) {
159
+ view.setKeepScreenOnEnabled(value)
152
160
  }
153
161
 
154
162
  @ReactProp(name = "barcodeEmissionInterval")
155
- fun setBarcodeEmissionInterval(view: ScannerView?, interval: Double) {
156
- // Use 0.5 as default if interval is 0 or negative (React Native may pass 0 for undefined)
157
- val actualInterval = if (interval > 0) interval else 0.5
163
+ override fun setBarcodeEmissionInterval(view: ScannerView?, interval: Double) {
164
+ Log.d("ScannerViewManager", "📊 [@ReactProp] barcodeEmissionInterval received: $interval")
165
+
166
+ // WithDefault<Double, 0.5> in TypeScript means codegen handles the default automatically
167
+ // If negative, clamp to 0 (minimum value)
168
+ // If 0, disable debouncing
169
+ // Otherwise, use the provided value (0 or positive)
170
+ val actualInterval = if (interval < 0) {
171
+ Log.d("ScannerViewManager", "📊 Clamping negative interval ($interval) to 0.0 (minimum)")
172
+ 0.0 // Negative values clamped to 0 (minimum)
173
+ } else {
174
+ if (interval == 0.0) {
175
+ Log.d("ScannerViewManager", "📊 Using interval: ${interval}s (explicitly set to 0, will disable debouncing)")
176
+ } else {
177
+ Log.d("ScannerViewManager", "📊 Using interval: ${interval}s")
178
+ }
179
+ interval // Use provided value (0 or positive)
180
+ }
181
+ Log.d("ScannerViewManager", "📊 Final interval to set: ${actualInterval}s")
158
182
  view?.setBarcodeEmissionInterval(actualInterval)
159
183
  }
160
184
 
@@ -169,7 +193,16 @@ class ScannerViewManager : SimpleViewManager<ScannerView>() {
169
193
  "bubbled" to "onBarcodeScanned"
170
194
  )
171
195
  )
172
- // Add more events here if needed
196
+ map["onLoad"] = mapOf(
197
+ "phasedRegistrationNames" to mapOf(
198
+ "bubbled" to "onLoad"
199
+ )
200
+ )
201
+ map["onScannerError"] = mapOf(
202
+ "phasedRegistrationNames" to mapOf(
203
+ "bubbled" to "onScannerError"
204
+ )
205
+ )
173
206
  return map
174
207
  }
175
208
  }
@@ -263,7 +263,11 @@ using namespace facebook::react;
263
263
 
264
264
  // Barcode emission interval
265
265
  if (oldViewProps.barcodeEmissionInterval != newViewProps.barcodeEmissionInterval) {
266
- NSNumber *intervalValue = @(newViewProps.barcodeEmissionInterval);
266
+ // Handle negative values (clamp to 0)
267
+ double interval = newViewProps.barcodeEmissionInterval;
268
+ double actualInterval = interval < 0 ? 0.0 : interval;
269
+
270
+ NSNumber *intervalValue = @(actualInterval);
267
271
  if ([_scannerImpl respondsToSelector:@selector(setBarcodeEmissionInterval:)]) {
268
272
  [_scannerImpl performSelector:@selector(setBarcodeEmissionInterval:) withObject:intervalValue];
269
273
  }
@@ -6,6 +6,7 @@ import {
6
6
  import type {
7
7
  DirectEventHandler,
8
8
  Double,
9
+ WithDefault,
9
10
  } from 'react-native/Libraries/Types/CodegenTypesNamespace';
10
11
 
11
12
  // Define codegen types locally (no longer exported from react-native in 0.83)
@@ -111,7 +112,7 @@ export interface NativeProps extends ViewProps {
111
112
  * Prevents rapid duplicate detections. Set to 0 to disable debouncing.
112
113
  * @default 0.5
113
114
  */
114
- barcodeEmissionInterval?: Double;
115
+ barcodeEmissionInterval?: WithDefault<Double, 0.5>;
115
116
 
116
117
  onBarcodeScanned?: DirectEventHandler<BarcodeScannedEventPayload>;
117
118
  onScannerError?: DirectEventHandler<ScannerErrorEventPayload>;
@@ -1,5 +1,5 @@
1
1
  import { type ViewProps, type NativeSyntheticEvent } from 'react-native';
2
- import type { DirectEventHandler, Double } from 'react-native/Libraries/Types/CodegenTypesNamespace';
2
+ import type { DirectEventHandler, Double, WithDefault } from 'react-native/Libraries/Types/CodegenTypesNamespace';
3
3
  export interface BarcodeScannedEventPayload {
4
4
  barcodes: {
5
5
  data: string;
@@ -81,7 +81,7 @@ export interface NativeProps extends ViewProps {
81
81
  * Prevents rapid duplicate detections. Set to 0 to disable debouncing.
82
82
  * @default 0.5
83
83
  */
84
- barcodeEmissionInterval?: Double;
84
+ barcodeEmissionInterval?: WithDefault<Double, 0.5>;
85
85
  onBarcodeScanned?: DirectEventHandler<BarcodeScannedEventPayload>;
86
86
  onScannerError?: DirectEventHandler<ScannerErrorEventPayload>;
87
87
  onLoad?: DirectEventHandler<OnLoadEventPayload>;
@@ -1 +1 @@
1
- {"version":3,"file":"ScannerViewNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/ScannerViewNativeComponent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ScannerViewNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/ScannerViewNativeComponent.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cleanuidev/react-native-scanner",
3
- "version": "1.0.0-beta.1",
4
- "description": "scanner",
3
+ "version": "1.0.0-beta.3",
4
+ "description": "High-performance native barcode and QR code scanner for React Native. Scan barcodes in configurable target areas for precise detection. Built with CameraX & ML Kit (Android) and AVFoundation & Vision (iOS).",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
7
7
  "exports": {
@@ -45,18 +45,42 @@
45
45
  "keywords": [
46
46
  "react-native",
47
47
  "ios",
48
- "android"
48
+ "android",
49
+ "barcode-scanner",
50
+ "qr-code-scanner",
51
+ "barcode",
52
+ "qr-code",
53
+ "qrcode",
54
+ "scanner",
55
+ "camera",
56
+ "camerax",
57
+ "ml-kit",
58
+ "avfoundation",
59
+ "vision",
60
+ "react-native-scanner",
61
+ "barcode-detection",
62
+ "qr-detection",
63
+ "mobile-scanner",
64
+ "native-scanner",
65
+ "fabric",
66
+ "new architecture",
67
+ "focus area",
68
+ "region scanning",
69
+ "frame scanning",
70
+ "area scanning",
71
+ "targeted-scanning",
72
+ "precise-scanning"
49
73
  ],
50
74
  "repository": {
51
75
  "type": "git",
52
- "url": "git+https://github.com/cleanui-dev/react-native-scanner.git"
76
+ "url": "git+https://github.com/rahulgwebdev/react-native-scanner.git"
53
77
  },
54
78
  "author": "Rahul Gupta <rahulgwebdev@gmail.com> (https://github.com/rahulgwebdev)",
55
79
  "license": "MIT",
56
80
  "bugs": {
57
- "url": "https://github.com/cleanui-dev/react-native-scanner/issues"
81
+ "url": "https://github.com/rahulgwebdev/react-native-scanner/issues"
58
82
  },
59
- "homepage": "https://github.com/cleanui-dev/react-native-scanner#readme",
83
+ "homepage": "https://github.com/rahulgwebdev/react-native-scanner#readme",
60
84
  "publishConfig": {
61
85
  "registry": "https://registry.npmjs.org/",
62
86
  "access": "public"
@@ -6,6 +6,7 @@ import {
6
6
  import type {
7
7
  DirectEventHandler,
8
8
  Double,
9
+ WithDefault,
9
10
  } from 'react-native/Libraries/Types/CodegenTypesNamespace';
10
11
 
11
12
  // Define codegen types locally (no longer exported from react-native in 0.83)
@@ -111,7 +112,7 @@ export interface NativeProps extends ViewProps {
111
112
  * Prevents rapid duplicate detections. Set to 0 to disable debouncing.
112
113
  * @default 0.5
113
114
  */
114
- barcodeEmissionInterval?: Double;
115
+ barcodeEmissionInterval?: WithDefault<Double, 0.5>;
115
116
 
116
117
  onBarcodeScanned?: DirectEventHandler<BarcodeScannedEventPayload>;
117
118
  onScannerError?: DirectEventHandler<ScannerErrorEventPayload>;