@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 +138 -112
- package/Scanner.podspec +1 -1
- package/android/src/main/java/com/scanner/ScannerView.kt +58 -2
- package/android/src/main/java/com/scanner/ScannerViewManager.kt +63 -30
- package/ios/ScannerView.mm +5 -1
- package/lib/module/ScannerViewNativeComponent.ts +2 -1
- package/lib/typescript/src/ScannerViewNativeComponent.d.ts +2 -2
- package/lib/typescript/src/ScannerViewNativeComponent.d.ts.map +1 -1
- package/package.json +30 -6
- package/src/ScannerViewNativeComponent.ts +2 -1
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
|
+

|
|
6
8
|
|
|
7
9
|
[](https://www.npmjs.com/package/@cleanuidev/react-native-scanner)
|
|
8
10
|
[](https://opensource.org/licenses/MIT)
|
|
9
|
-
[](https://
|
|
11
|
+
[](https://reactnative.dev/)
|
|
10
12
|
[](https://reactnative.dev/)
|
|
11
13
|
|
|
12
14
|
**Built with ❤️ by [CleanUI.dev](https://cleanui.dev)**
|
|
13
15
|
|
|
14
|
-
[Features](#-features) • [Installation](#-installation) • [Documentation](#-documentation)
|
|
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
|
|
27
|
-
| 🎯 **
|
|
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
|
|
31
|
-
| 📱 **Cross Platform** | Android support (
|
|
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
|
-
>
|
|
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
|
-
##
|
|
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
|
|
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
|
-
//
|
|
142
|
+
// Target area configuration
|
|
126
143
|
const focusAreaConfig = {
|
|
127
|
-
enabled: true, // Only scan barcodes within the
|
|
128
|
-
showOverlay: true, // Show the
|
|
129
|
-
size: 300, // Size of the
|
|
130
|
-
color: '#00FF00', // Color of the
|
|
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
|
-
|
|
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` | - |
|
|
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
|
-
####
|
|
218
|
-
|
|
219
|
-
##### FocusAreaConfig
|
|
212
|
+
#### FocusAreaConfig
|
|
220
213
|
|
|
221
214
|
```tsx
|
|
222
215
|
type FocusAreaConfig = {
|
|
223
|
-
enabled?: boolean; // Whether to restrict scanning to
|
|
224
|
-
size?: FrameSize; // Size of the
|
|
225
|
-
color?: string; // Color of
|
|
226
|
-
showOverlay?: boolean; // Whether to draw the
|
|
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
|
-
|
|
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
|
|
229
|
+
onlyInFocusArea?: boolean; // Only show frames for barcodes in target area
|
|
237
230
|
};
|
|
238
231
|
```
|
|
239
232
|
|
|
240
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
316
|
+
The target area feature provides precise control over where barcodes are scanned:
|
|
327
317
|
|
|
328
|
-
###
|
|
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
|
|
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
|
-
|
|
331
|
+
### Target Area with Restricted Scanning
|
|
346
332
|
|
|
347
333
|
```tsx
|
|
348
334
|
<ScannerView
|
|
349
335
|
focusArea={{
|
|
350
|
-
enabled: true, // Only scan within
|
|
351
|
-
showOverlay: true, // Show
|
|
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
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
417
|
+
onlyInFocusArea: true, // Only show frames for barcodes in target area
|
|
401
418
|
}}
|
|
402
419
|
/>
|
|
403
420
|
```
|
|
404
421
|
|
|
405
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
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/
|
|
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, "
|
|
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")
|
|
42
|
-
val showOverlay = focusArea.getBoolean("showOverlay")
|
|
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
|
|
107
|
-
view
|
|
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
|
-
|
|
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
|
|
137
|
-
if (
|
|
138
|
-
view
|
|
144
|
+
override fun setPauseScanning(view: ScannerView, value: Boolean) {
|
|
145
|
+
if (value) {
|
|
146
|
+
view.pauseScanning()
|
|
139
147
|
} else {
|
|
140
|
-
view
|
|
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
|
|
151
|
-
view
|
|
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
|
-
|
|
157
|
-
|
|
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
|
-
|
|
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
|
}
|
package/ios/ScannerView.mm
CHANGED
|
@@ -263,7 +263,11 @@ using namespace facebook::react;
|
|
|
263
263
|
|
|
264
264
|
// Barcode emission interval
|
|
265
265
|
if (oldViewProps.barcodeEmissionInterval != newViewProps.barcodeEmissionInterval) {
|
|
266
|
-
|
|
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":"AAAA,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,oBAAoB,EAC1B,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EACV,kBAAkB,EAClB,MAAM,
|
|
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.
|
|
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/
|
|
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/
|
|
81
|
+
"url": "https://github.com/rahulgwebdev/react-native-scanner/issues"
|
|
58
82
|
},
|
|
59
|
-
"homepage": "https://github.com/
|
|
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>;
|