@cleanuidev/react-native-scanner 1.0.0-beta.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.
- package/LICENSE +20 -0
- package/README.md +609 -0
- package/Scanner.podspec +20 -0
- package/android/build.gradle +90 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +8 -0
- package/android/src/main/java/com/scanner/CameraInfoModule.kt +253 -0
- package/android/src/main/java/com/scanner/ScannerPackage.kt +21 -0
- package/android/src/main/java/com/scanner/ScannerView.kt +783 -0
- package/android/src/main/java/com/scanner/ScannerViewManager.kt +181 -0
- package/android/src/main/java/com/scanner/utils/BarcodeFrameManager.kt +170 -0
- package/android/src/main/java/com/scanner/views/BarcodeFrameOverlayView.kt +43 -0
- package/android/src/main/java/com/scanner/views/FocusAreaView.kt +124 -0
- package/ios/BarcodeDetectionManager.swift +229 -0
- package/ios/BarcodeFrameManager.swift +175 -0
- package/ios/BarcodeFrameOverlayView.swift +102 -0
- package/ios/CameraManager.swift +396 -0
- package/ios/CoordinateTransformer.swift +140 -0
- package/ios/FocusAreaOverlayView.swift +161 -0
- package/ios/Models.swift +341 -0
- package/ios/Protocols.swift +194 -0
- package/ios/ScannerView.h +14 -0
- package/ios/ScannerView.mm +358 -0
- package/ios/ScannerViewImpl.swift +580 -0
- package/ios/react-native-scanner-Bridging-Header.h +26 -0
- package/lib/module/CameraInfoModule.js +8 -0
- package/lib/module/CameraInfoModule.js.map +1 -0
- package/lib/module/ScannerViewNativeComponent.ts +121 -0
- package/lib/module/hooks/useCameraInfo.js +106 -0
- package/lib/module/hooks/useCameraInfo.js.map +1 -0
- package/lib/module/index.js +13 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/types.js +47 -0
- package/lib/module/types.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/CameraInfoModule.d.ts +8 -0
- package/lib/typescript/src/CameraInfoModule.d.ts.map +1 -0
- package/lib/typescript/src/ScannerViewNativeComponent.d.ts +91 -0
- package/lib/typescript/src/ScannerViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useCameraInfo.d.ts +25 -0
- package/lib/typescript/src/hooks/useCameraInfo.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +8 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +145 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/package.json +178 -0
- package/src/CameraInfoModule.ts +11 -0
- package/src/ScannerViewNativeComponent.ts +121 -0
- package/src/hooks/useCameraInfo.ts +190 -0
- package/src/index.tsx +30 -0
- package/src/types.ts +177 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Rahul Gupta
|
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
in the Software without restriction, including without limitation the rights
|
|
7
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
furnished to do so, subject to the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,609 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# 📱 React Native Scanner
|
|
4
|
+
|
|
5
|
+
**A powerful, native barcode and QR code scanner for React Native**
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/@cleanuidev/react-native-scanner)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
[](https://www.android.com/)
|
|
10
|
+
[](https://reactnative.dev/)
|
|
11
|
+
|
|
12
|
+
**Built with ❤️ by [CleanUI.dev](https://cleanui.dev)**
|
|
13
|
+
|
|
14
|
+
[Features](#-features) • [Installation](#-installation) • [Documentation](#-documentation) • [Support](#-consulting--support)
|
|
15
|
+
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## ✨ Features
|
|
21
|
+
|
|
22
|
+
<div align="center">
|
|
23
|
+
|
|
24
|
+
| Feature | Description |
|
|
25
|
+
|:------:|:-----------|
|
|
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
|
+
| 🔦 **Torch Control** | Built-in flashlight/torch control |
|
|
29
|
+
| 📊 **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
|
+
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 📦 Installation
|
|
38
|
+
|
|
39
|
+
### Install Beta Version
|
|
40
|
+
|
|
41
|
+
Currently, the library is in beta. Install the beta version using:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npm install @cleanuidev/react-native-scanner@beta
|
|
45
|
+
# or
|
|
46
|
+
yarn add @cleanuidev/react-native-scanner@beta
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Install Specific Version
|
|
50
|
+
|
|
51
|
+
To install a specific beta version:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npm install @cleanuidev/react-native-scanner@1.0.0-beta.1
|
|
55
|
+
# or
|
|
56
|
+
yarn add @cleanuidev/react-native-scanner@1.0.0-beta.1
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
> **💡 Note**: Once the library reaches stable release (1.0.0), you can install it without the `@beta` tag:
|
|
60
|
+
> ```bash
|
|
61
|
+
> npm install @cleanuidev/react-native-scanner
|
|
62
|
+
> # or
|
|
63
|
+
> yarn add @cleanuidev/react-native-scanner
|
|
64
|
+
> ```
|
|
65
|
+
|
|
66
|
+
### Android Setup
|
|
67
|
+
|
|
68
|
+
Add the following permissions to your `android/app/src/main/AndroidManifest.xml`:
|
|
69
|
+
|
|
70
|
+
```xml
|
|
71
|
+
<uses-permission android:name="android.permission.CAMERA" />
|
|
72
|
+
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
|
73
|
+
<uses-feature android:name="android.hardware.camera" android:required="true" />
|
|
74
|
+
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
|
|
75
|
+
<uses-feature android:name="android.hardware.camera.flash" android:required="false" />
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## 🚀 Quick Start
|
|
81
|
+
|
|
82
|
+
### Basic Scanner
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
import React from 'react';
|
|
86
|
+
import { View, StyleSheet } from 'react-native';
|
|
87
|
+
import ScannerView, { BarcodeFormat } from '@cleanuidev/react-native-scanner';
|
|
88
|
+
|
|
89
|
+
export default function App() {
|
|
90
|
+
const handleBarcodeScanned = (event) => {
|
|
91
|
+
console.log('Scanned:', event.nativeEvent.data);
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
return (
|
|
95
|
+
<View style={styles.container}>
|
|
96
|
+
<ScannerView
|
|
97
|
+
style={styles.scanner}
|
|
98
|
+
barcodeTypes={[BarcodeFormat.QR_CODE, BarcodeFormat.CODE_128]}
|
|
99
|
+
onBarcodeScanned={handleBarcodeScanned}
|
|
100
|
+
/>
|
|
101
|
+
</View>
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const styles = StyleSheet.create({
|
|
106
|
+
container: {
|
|
107
|
+
flex: 1,
|
|
108
|
+
},
|
|
109
|
+
scanner: {
|
|
110
|
+
flex: 1,
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Scanner with Focus Area
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
import React, { useState } from 'react';
|
|
119
|
+
import { View, StyleSheet, TouchableOpacity, Text } from 'react-native';
|
|
120
|
+
import ScannerView, { BarcodeFormat } from '@cleanuidev/react-native-scanner';
|
|
121
|
+
|
|
122
|
+
export default function FocusAreaScanner() {
|
|
123
|
+
const [torchEnabled, setTorchEnabled] = useState(false);
|
|
124
|
+
|
|
125
|
+
// Focus area configuration
|
|
126
|
+
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
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// Barcode frames configuration
|
|
134
|
+
const barcodeFramesConfig = {
|
|
135
|
+
enabled: true, // Show frames around detected barcodes
|
|
136
|
+
color: '#FF0000', // Color of barcode frames
|
|
137
|
+
onlyInFocusArea: false, // Show frames for all barcodes
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
return (
|
|
141
|
+
<View style={styles.container}>
|
|
142
|
+
<ScannerView
|
|
143
|
+
style={styles.scanner}
|
|
144
|
+
barcodeTypes={[
|
|
145
|
+
BarcodeFormat.QR_CODE,
|
|
146
|
+
BarcodeFormat.CODE_128,
|
|
147
|
+
BarcodeFormat.EAN_13,
|
|
148
|
+
BarcodeFormat.UPC_A,
|
|
149
|
+
]}
|
|
150
|
+
focusArea={focusAreaConfig}
|
|
151
|
+
barcodeFrames={barcodeFramesConfig}
|
|
152
|
+
torch={torchEnabled}
|
|
153
|
+
onBarcodeScanned={(event) => {
|
|
154
|
+
console.log('Scanned:', event.nativeEvent.data);
|
|
155
|
+
}}
|
|
156
|
+
onScannerError={(event) => {
|
|
157
|
+
console.error('Error:', event.nativeEvent.error);
|
|
158
|
+
}}
|
|
159
|
+
onLoad={(event) => {
|
|
160
|
+
console.log('Scanner loaded:', event.nativeEvent.success);
|
|
161
|
+
}}
|
|
162
|
+
/>
|
|
163
|
+
|
|
164
|
+
<View style={styles.controls}>
|
|
165
|
+
<TouchableOpacity
|
|
166
|
+
style={styles.button}
|
|
167
|
+
onPress={() => setTorchEnabled(!torchEnabled)}
|
|
168
|
+
>
|
|
169
|
+
<Text>Toggle Torch</Text>
|
|
170
|
+
</TouchableOpacity>
|
|
171
|
+
</View>
|
|
172
|
+
</View>
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
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.
|
|
182
|
+
|
|
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
|
|
202
|
+
|
|
203
|
+
| Prop | Type | Default | Description |
|
|
204
|
+
|:----:|:----:|:-------:|:-----------|
|
|
205
|
+
| `barcodeTypes` | `BarcodeFormat[]` | `[BarcodeFormat.QR_CODE]` | Array of barcode formats to scan |
|
|
206
|
+
| `focusArea` | `FocusAreaConfig` | - | Focus area configuration |
|
|
207
|
+
| `barcodeFrames` | `BarcodeFramesConfig` | - | Barcode frame visualization configuration |
|
|
208
|
+
| `torch` | `boolean` | `false` | Enable/disable torch/flashlight |
|
|
209
|
+
| `zoom` | `number` | `1.0` | Camera zoom level |
|
|
210
|
+
| `pauseScanning` | `boolean` | `false` | Pause/resume scanning |
|
|
211
|
+
| `barcodeScanStrategy` | `BarcodeScanStrategy` | `BarcodeScanStrategy.ALL` | Strategy for processing multiple detected barcodes |
|
|
212
|
+
| `keepScreenOn` | `boolean` | `true` | Keep screen on while camera is active (prevents auto-lock) |
|
|
213
|
+
| `onBarcodeScanned` | `function` | - | Callback when barcode is scanned |
|
|
214
|
+
| `onScannerError` | `function` | - | Callback when scanner encounters an error |
|
|
215
|
+
| `onLoad` | `function` | - | Callback when scanner is loaded |
|
|
216
|
+
|
|
217
|
+
#### Configuration Types
|
|
218
|
+
|
|
219
|
+
##### FocusAreaConfig
|
|
220
|
+
|
|
221
|
+
```tsx
|
|
222
|
+
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
|
|
227
|
+
};
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
##### BarcodeFramesConfig
|
|
231
|
+
|
|
232
|
+
```tsx
|
|
233
|
+
type BarcodeFramesConfig = {
|
|
234
|
+
enabled?: boolean; // Whether to draw frames around detected barcodes
|
|
235
|
+
color?: string; // Color of barcode frames
|
|
236
|
+
onlyInFocusArea?: boolean; // Only show frames for barcodes in focus area
|
|
237
|
+
};
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
##### FrameSize
|
|
241
|
+
|
|
242
|
+
```tsx
|
|
243
|
+
type FrameSize = number | { width: number; height: number };
|
|
244
|
+
// number: square frame (e.g., 300)
|
|
245
|
+
// object: rectangular frame (e.g., { width: 300, height: 200 })
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
#### BarcodeScanStrategy
|
|
249
|
+
|
|
250
|
+
```tsx
|
|
251
|
+
import { BarcodeScanStrategy } from '@cleanuidev/react-native-scanner';
|
|
252
|
+
|
|
253
|
+
// Available strategies:
|
|
254
|
+
BarcodeScanStrategy.ONE // Process only the first barcode detected
|
|
255
|
+
BarcodeScanStrategy.ALL // Process all detected barcodes
|
|
256
|
+
BarcodeScanStrategy.BIGGEST // Process only the largest barcode by area
|
|
257
|
+
BarcodeScanStrategy.SORT_BY_BIGGEST // Process all barcodes sorted by size (largest first)
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
#### Barcode Formats
|
|
261
|
+
|
|
262
|
+
```tsx
|
|
263
|
+
import { BarcodeFormat } from '@cleanuidev/react-native-scanner';
|
|
264
|
+
|
|
265
|
+
// Available formats:
|
|
266
|
+
BarcodeFormat.QR_CODE // QR Code
|
|
267
|
+
BarcodeFormat.CODE_128 // Code 128
|
|
268
|
+
BarcodeFormat.CODE_39 // Code 39
|
|
269
|
+
BarcodeFormat.EAN_13 // EAN-13
|
|
270
|
+
BarcodeFormat.EAN_8 // EAN-8
|
|
271
|
+
BarcodeFormat.UPC_A // UPC-A
|
|
272
|
+
BarcodeFormat.UPC_E // UPC-E
|
|
273
|
+
BarcodeFormat.DATA_MATRIX // Data Matrix
|
|
274
|
+
BarcodeFormat.PDF_417 // PDF417
|
|
275
|
+
BarcodeFormat.AZTEC // Aztec
|
|
276
|
+
BarcodeFormat.ITF // ITF (Interleaved 2 of 5)
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
#### Event Payloads
|
|
280
|
+
|
|
281
|
+
##### onBarcodeScanned
|
|
282
|
+
|
|
283
|
+
```tsx
|
|
284
|
+
{
|
|
285
|
+
nativeEvent: [
|
|
286
|
+
{
|
|
287
|
+
data: string; // The scanned barcode data
|
|
288
|
+
format: BarcodeFormat; // The format of the scanned barcode
|
|
289
|
+
timestamp: number; // Timestamp when scanned
|
|
290
|
+
boundingBox?: { // Bounding box coordinates (if available)
|
|
291
|
+
left: number;
|
|
292
|
+
top: number;
|
|
293
|
+
right: number;
|
|
294
|
+
bottom: number;
|
|
295
|
+
};
|
|
296
|
+
area?: number; // Area of the barcode (if available)
|
|
297
|
+
}
|
|
298
|
+
]
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
##### onScannerError
|
|
303
|
+
|
|
304
|
+
```tsx
|
|
305
|
+
{
|
|
306
|
+
nativeEvent: {
|
|
307
|
+
error: string; // Error message
|
|
308
|
+
code: string; // Error code
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
##### onLoad
|
|
314
|
+
|
|
315
|
+
```tsx
|
|
316
|
+
{
|
|
317
|
+
nativeEvent: {
|
|
318
|
+
success: boolean; // Whether scanner loaded successfully
|
|
319
|
+
error?: string; // Error message if loading failed
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
## 🎯 Advanced Usage
|
|
327
|
+
|
|
328
|
+
### Focus Area Configuration
|
|
329
|
+
|
|
330
|
+
The focus area feature provides precise control over where barcodes are scanned:
|
|
331
|
+
|
|
332
|
+
#### Basic Focus Area
|
|
333
|
+
|
|
334
|
+
```tsx
|
|
335
|
+
<ScannerView
|
|
336
|
+
focusArea={{
|
|
337
|
+
showOverlay: true, // Show visual overlay
|
|
338
|
+
size: 300, // 300x300 pixel square
|
|
339
|
+
color: '#00FF00', // Green border
|
|
340
|
+
}}
|
|
341
|
+
// Scans entire camera view
|
|
342
|
+
/>
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
#### Focus Area with Restricted Scanning
|
|
346
|
+
|
|
347
|
+
```tsx
|
|
348
|
+
<ScannerView
|
|
349
|
+
focusArea={{
|
|
350
|
+
enabled: true, // Only scan within focus area
|
|
351
|
+
showOverlay: true, // Show visual overlay
|
|
352
|
+
size: 300, // 300x300 pixel square
|
|
353
|
+
color: '#00FF00', // Green border
|
|
354
|
+
}}
|
|
355
|
+
// Only scans within the focus area
|
|
356
|
+
/>
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
#### Rectangular Focus Area
|
|
360
|
+
|
|
361
|
+
```tsx
|
|
362
|
+
<ScannerView
|
|
363
|
+
focusArea={{
|
|
364
|
+
enabled: true,
|
|
365
|
+
showOverlay: true,
|
|
366
|
+
size: { width: 300, height: 200 }, // Rectangular focus area
|
|
367
|
+
color: '#00FF00',
|
|
368
|
+
}}
|
|
369
|
+
/>
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### Barcode Frame Visualization
|
|
373
|
+
|
|
374
|
+
The scanner can display visual frames around detected barcodes to help users see what's being scanned:
|
|
375
|
+
|
|
376
|
+
#### Show All Barcode Frames
|
|
377
|
+
|
|
378
|
+
```tsx
|
|
379
|
+
<ScannerView
|
|
380
|
+
barcodeFrames={{
|
|
381
|
+
enabled: true,
|
|
382
|
+
color: '#FF0000', // Red frames
|
|
383
|
+
onlyInFocusArea: false, // Show frames for all barcodes
|
|
384
|
+
}}
|
|
385
|
+
/>
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
#### Show Frames Only in Focus Area
|
|
389
|
+
|
|
390
|
+
```tsx
|
|
391
|
+
<ScannerView
|
|
392
|
+
focusArea={{
|
|
393
|
+
enabled: true,
|
|
394
|
+
showOverlay: true,
|
|
395
|
+
size: 300,
|
|
396
|
+
}}
|
|
397
|
+
barcodeFrames={{
|
|
398
|
+
enabled: true,
|
|
399
|
+
color: '#FF0000',
|
|
400
|
+
onlyInFocusArea: true, // Only show frames for barcodes in focus area
|
|
401
|
+
}}
|
|
402
|
+
/>
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
### Barcode Scan Strategy
|
|
406
|
+
|
|
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.
|
|
408
|
+
|
|
409
|
+
#### Process All Barcodes (Default)
|
|
410
|
+
|
|
411
|
+
```tsx
|
|
412
|
+
<ScannerView
|
|
413
|
+
barcodeScanStrategy={BarcodeScanStrategy.ALL}
|
|
414
|
+
onBarcodeScanned={(event) => {
|
|
415
|
+
const barcodes = event.nativeEvent;
|
|
416
|
+
console.log(`Found ${barcodes.length} barcodes:`, barcodes);
|
|
417
|
+
}}
|
|
418
|
+
/>
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
#### Process Only the First Barcode
|
|
422
|
+
|
|
423
|
+
```tsx
|
|
424
|
+
<ScannerView
|
|
425
|
+
barcodeScanStrategy={BarcodeScanStrategy.ONE}
|
|
426
|
+
onBarcodeScanned={(event) => {
|
|
427
|
+
const barcodes = event.nativeEvent;
|
|
428
|
+
// Will always have 0 or 1 barcode
|
|
429
|
+
if (barcodes.length > 0) {
|
|
430
|
+
console.log('First barcode:', barcodes[0]);
|
|
431
|
+
}
|
|
432
|
+
}}
|
|
433
|
+
/>
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
#### Process Only the Largest Barcode
|
|
437
|
+
|
|
438
|
+
```tsx
|
|
439
|
+
<ScannerView
|
|
440
|
+
barcodeScanStrategy={BarcodeScanStrategy.BIGGEST}
|
|
441
|
+
onBarcodeScanned={(event) => {
|
|
442
|
+
const barcodes = event.nativeEvent;
|
|
443
|
+
// Will always have 0 or 1 barcode (the largest one)
|
|
444
|
+
if (barcodes.length > 0) {
|
|
445
|
+
console.log('Largest barcode:', barcodes[0]);
|
|
446
|
+
console.log('Area:', barcodes[0].area);
|
|
447
|
+
}
|
|
448
|
+
}}
|
|
449
|
+
/>
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
#### Process All Barcodes Sorted by Size
|
|
453
|
+
|
|
454
|
+
```tsx
|
|
455
|
+
<ScannerView
|
|
456
|
+
barcodeScanStrategy={BarcodeScanStrategy.SORT_BY_BIGGEST}
|
|
457
|
+
onBarcodeScanned={(event) => {
|
|
458
|
+
const barcodes = event.nativeEvent;
|
|
459
|
+
// Barcodes are sorted from largest to smallest
|
|
460
|
+
barcodes.forEach((barcode, index) => {
|
|
461
|
+
console.log(`Barcode ${index + 1}:`, barcode.data, 'Area:', barcode.area);
|
|
462
|
+
});
|
|
463
|
+
}}
|
|
464
|
+
/>
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
### Torch Control
|
|
468
|
+
|
|
469
|
+
The torch/flashlight can be controlled via the `torch` prop:
|
|
470
|
+
|
|
471
|
+
```tsx
|
|
472
|
+
const [torchEnabled, setTorchEnabled] = useState(false);
|
|
473
|
+
|
|
474
|
+
<ScannerView
|
|
475
|
+
torch={torchEnabled}
|
|
476
|
+
// ... other props
|
|
477
|
+
/>
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
### Keep Screen On
|
|
481
|
+
|
|
482
|
+
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
|
+
|
|
484
|
+
#### Default Behavior (Screen Stays On)
|
|
485
|
+
|
|
486
|
+
```tsx
|
|
487
|
+
<ScannerView
|
|
488
|
+
keepScreenOn={true} // Default behavior
|
|
489
|
+
onBarcodeScanned={handleBarcodeScanned}
|
|
490
|
+
/>
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
#### Allow Screen Auto-Lock
|
|
494
|
+
|
|
495
|
+
```tsx
|
|
496
|
+
<ScannerView
|
|
497
|
+
keepScreenOn={false} // Allow screen to auto-lock
|
|
498
|
+
onBarcodeScanned={handleBarcodeScanned}
|
|
499
|
+
/>
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
#### Dynamic Control
|
|
503
|
+
|
|
504
|
+
```tsx
|
|
505
|
+
const [keepScreenOn, setKeepScreenOn] = useState(true);
|
|
506
|
+
|
|
507
|
+
<ScannerView
|
|
508
|
+
keepScreenOn={keepScreenOn}
|
|
509
|
+
onBarcodeScanned={handleBarcodeScanned}
|
|
510
|
+
/>
|
|
511
|
+
|
|
512
|
+
// Toggle button
|
|
513
|
+
<TouchableOpacity onPress={() => setKeepScreenOn(!keepScreenOn)}>
|
|
514
|
+
<Text>{keepScreenOn ? 'Disable Keep Screen On' : 'Enable Keep Screen On'}</Text>
|
|
515
|
+
</TouchableOpacity>
|
|
516
|
+
```
|
|
517
|
+
|
|
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.
|
|
519
|
+
|
|
520
|
+
---
|
|
521
|
+
|
|
522
|
+
## 🔐 Permissions
|
|
523
|
+
|
|
524
|
+
The scanner requires camera permissions. Make sure to request camera permissions in your app before using the scanner:
|
|
525
|
+
|
|
526
|
+
```tsx
|
|
527
|
+
import { PermissionsAndroid, Platform } from 'react-native';
|
|
528
|
+
|
|
529
|
+
const requestCameraPermission = async () => {
|
|
530
|
+
if (Platform.OS === 'android') {
|
|
531
|
+
try {
|
|
532
|
+
const granted = await PermissionsAndroid.request(
|
|
533
|
+
PermissionsAndroid.PERMISSIONS.CAMERA,
|
|
534
|
+
{
|
|
535
|
+
title: "Camera Permission",
|
|
536
|
+
message: "This app needs camera access to scan barcodes",
|
|
537
|
+
buttonNeutral: "Ask Me Later",
|
|
538
|
+
buttonNegative: "Cancel",
|
|
539
|
+
buttonPositive: "OK"
|
|
540
|
+
}
|
|
541
|
+
);
|
|
542
|
+
return granted === PermissionsAndroid.RESULTS.GRANTED;
|
|
543
|
+
} catch (err) {
|
|
544
|
+
console.warn(err);
|
|
545
|
+
return false;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
return true;
|
|
549
|
+
};
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
---
|
|
553
|
+
|
|
554
|
+
## 📖 Examples
|
|
555
|
+
|
|
556
|
+
See the `example/` directory for complete working examples, including the "New Props Example" that demonstrates the updated prop structure.
|
|
557
|
+
|
|
558
|
+
---
|
|
559
|
+
|
|
560
|
+
## 🤝 Contributing
|
|
561
|
+
|
|
562
|
+
We welcome contributions! Please follow these steps:
|
|
563
|
+
|
|
564
|
+
1. Fork the repository
|
|
565
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
566
|
+
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
|
|
567
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
568
|
+
5. Open a Pull Request
|
|
569
|
+
|
|
570
|
+
For more details, see our [Contributing Guide](CONTRIBUTING.md).
|
|
571
|
+
|
|
572
|
+
---
|
|
573
|
+
|
|
574
|
+
## 💼 Consulting & Support
|
|
575
|
+
|
|
576
|
+
### Community Support (Free)
|
|
577
|
+
|
|
578
|
+
For bug reports, feature requests, and general questions:
|
|
579
|
+
- 📝 [Open an issue](https://github.com/cleanui-dev/react-native-scanner/issues) on GitHub
|
|
580
|
+
- 💬 Use GitHub Discussions for questions and community help
|
|
581
|
+
|
|
582
|
+
### Commercial Support & Consulting
|
|
583
|
+
|
|
584
|
+
Need professional help with implementation, custom development, or enterprise support?
|
|
585
|
+
|
|
586
|
+
- 📧 **Email**: [contact@cleanuitechnologies.com](mailto:contact@cleanuitechnologies.com)
|
|
587
|
+
- 🌐 **Company**: [cleanui.dev](https://cleanui.dev)
|
|
588
|
+
|
|
589
|
+
**We offer:**
|
|
590
|
+
- ✅ Custom implementation assistance
|
|
591
|
+
- ✅ Enterprise support and SLA
|
|
592
|
+
- ✅ Feature development and customization
|
|
593
|
+
- ✅ Code reviews and architecture consulting
|
|
594
|
+
|
|
595
|
+
---
|
|
596
|
+
|
|
597
|
+
## 📄 License
|
|
598
|
+
|
|
599
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
600
|
+
|
|
601
|
+
---
|
|
602
|
+
|
|
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>
|
package/Scanner.podspec
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = "Scanner"
|
|
7
|
+
s.version = package["version"]
|
|
8
|
+
s.summary = package["description"]
|
|
9
|
+
s.homepage = package["homepage"]
|
|
10
|
+
s.license = package["license"]
|
|
11
|
+
s.authors = package["author"]
|
|
12
|
+
|
|
13
|
+
s.platforms = { :ios => min_ios_version_supported }
|
|
14
|
+
s.source = { :git => "https://github.com/cleanui-dev/react-native-scanner.git", :tag => "#{s.version}" }
|
|
15
|
+
|
|
16
|
+
s.source_files = "ios/**/*.{h,m,mm,swift,cpp}"
|
|
17
|
+
s.private_header_files = "ios/**/*.h"
|
|
18
|
+
|
|
19
|
+
install_modules_dependencies(s)
|
|
20
|
+
end
|