react-native-customizable-image-crop-picker 1.0.7 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +90 -325
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -6,24 +6,35 @@
6
6
  ![Platform - Android](https://img.shields.io/badge/platform-android-3DDC84?logo=android&logoColor=white)
7
7
  ![Platform - iOS](https://img.shields.io/badge/platform-iOS-000000?logo=apple&logoColor=white)
8
8
 
9
- This library is developed by **Amit Kumar**.
10
-
11
- A high performance, beautiful and fully customizable **image crop picker** for React Native.
12
-
13
- iOS/Android image picker + cropper with support for **camera**, **gallery**, optional **base64**, and a **highly customizable native full-screen crop UI** (header/footer/buttons/icons/layout) driven by JS props.
9
+ A high-performance, fully customizable **image crop picker** for React Native (iOS + Android).
14
10
 
15
11
  - **Android**: system photo picker / camera + **uCrop**
16
12
  - **iOS**: `UIImagePickerController` / camera + **TOCropViewController**
17
13
 
18
- ## Platforms Supported
19
-
20
- - [x] iOS
21
- - [x] Android
14
+ This library is developed and maintained by **Amit Kumar**.
15
+
16
+ ## Table of contents
17
+
18
+ - [Features](#features)
19
+ - [Roadmap / future features](#roadmap--future-features)
20
+ - [Demo](#demo)
21
+ - [Installation](#installation)
22
+ - [Permissions](#permissions)
23
+ - [Quick start](#quick-start)
24
+ - [Icons (including SVG on Android)](#icons-including-svg-on-android)
25
+ - [API: `openImageCropPicker(options)`](#api-openimagecroppickeroptions)
26
+ - [Response object](#response-object)
27
+ - [Errors](#errors)
28
+ - [Known limitations](#known-limitations)
29
+ - [Peer dependencies](#peer-dependencies)
30
+ - [Contributing](#contributing)
31
+ - [Support](#support)
32
+ - [License](#license)
22
33
 
23
34
  ## Features
24
35
 
25
36
  - Camera + gallery
26
- - Cropping with configurable aspect ratio (`cropWidth` / `cropHeight`)
37
+ - Cropping with configurable aspect ratio (`cropWidth` / `cropHeight` or `aspectRatio`)
27
38
  - Circular crop (`circularCrop`)
28
39
  - Crop overlays: dimmed layer + grid (`dimmedLayerColor`, `cropGridEnabled`)
29
40
  - Native crop controls (rotate/reset + aspect ratio picker) via `showNativeCropControls`
@@ -33,75 +44,38 @@ iOS/Android image picker + cropper with support for **camera**, **gallery**, opt
33
44
  - Icons: remote (http/https) + local (`file://` / Android `content://`) + base64 + bundled assets (`require(...)`)
34
45
  - Events: `onCropStart`, `onCropEnd`, `onProgress` (Android base64 progress)
35
46
 
36
- ## Roadmap (planned)
47
+ ## Roadmap / future features
37
48
 
38
- - **Rotation + flip parity**: add flip support, finer control over native toolbars
39
- - **Multiple aspect ratio presets**: configurable preset list (1:1, 4:3, 16:9, free) beyond the native defaults
40
- - **Full RN UI mode**: “JS chrome + native crop engine” component so every UI detail is styleable with real RN styles
41
- - **Richer error codes** and permission UX
42
- - **Multiple selection** (`multiple`, `maxFiles`)
49
+ - **Multiple selection**: `multiple`, `maxFiles`
50
+ - **Flip support** (to complement rotation)
51
+ - **More aspect ratio presets** (configurable preset list)
52
+ - **Richer errors + permission UX** (more granular error codes and clearer guidance)
43
53
 
44
54
  ## Demo
45
55
 
46
- **Android**
47
-
48
- </br></br>
49
- <p>
50
- <img src="https://github.com/amitkumarcoding/imagecroppicker/blob/main/images/1.png" alt="Android demo" width="320" />
51
- </p>
52
- </br>
53
- <p>
54
- <img src="https://github.com/amitkumarcoding/imagecroppicker/blob/main/images/2.png" alt="Android demo" width="320" />
55
- </p>
56
- </br>
57
- <p>
58
- <img src="https://github.com/amitkumarcoding/imagecroppicker/blob/main/images/3.png" alt="Android demo" width="320" />
59
- </p>
60
- </br>
61
- <p>
62
- <img src="https://github.com/amitkumarcoding/imagecroppicker/blob/main/images/4.png" alt="Android demo" width="320" />
63
- </p>
64
- </br>
65
- </br>
66
-
67
- **iOS**
68
-
69
- </br>
70
- </br>
71
- <p>
72
- <img src="https://github.com/amitkumarcoding/imagecroppicker/blob/main/images/5.png" alt="iOS demo" width="320" />
73
- </p>
74
- </br>
75
- <p>
76
- <img src="https://github.com/amitkumarcoding/imagecroppicker/blob/main/images/6.png" alt="iOS demo" width="320" />
77
- </p>
78
- </br>
79
- <p>
80
- <img src="https://github.com/amitkumarcoding/imagecroppicker/blob/main/images/7.png" alt="iOS demo" width="320" />
81
- </p>
82
- </br>
83
- <p>
84
- <img src="https://github.com/amitkumarcoding/imagecroppicker/blob/main/images/8.png" alt="iOS demo" width="320" />
85
- </p>
86
- </br>
87
- <p>
88
- <img src="https://github.com/amitkumarcoding/imagecroppicker/blob/main/images/9.png" alt="iOS demo" width="320" />
89
- </p>
90
- </br>
91
- </br>
92
-
93
-
94
- ## Important notes
95
-
96
- - **Camera permission**
97
- - **Android**: you must request `CAMERA` permission at runtime (helper included).
98
- - **iOS**: you must add `NSCameraUsageDescription` to `Info.plist`.
99
- - **iOS Simulator**: camera isn’t available on the simulator. Test camera on a real device.
100
-
101
- ## Getting started
56
+ <details>
57
+ <summary>Android screenshots</summary>
58
+ <br />
59
+ <img src="https://raw.githubusercontent.com/amitkumarcoding/imagecroppicker/main/images/1.png" width="240" />
60
+ <img src="https://raw.githubusercontent.com/amitkumarcoding/imagecroppicker/main/images/2.png" width="240" />
61
+ <img src="https://raw.githubusercontent.com/amitkumarcoding/imagecroppicker/main/images/3.png" width="240" />
62
+ <img src="https://raw.githubusercontent.com/amitkumarcoding/imagecroppicker/main/images/4.png" width="240" />
63
+ </details>
64
+
65
+ <details>
66
+ <summary>iOS screenshots</summary>
67
+ <br />
68
+ <img src="https://raw.githubusercontent.com/amitkumarcoding/imagecroppicker/main/images/5.png" width="240" />
69
+ <img src="https://raw.githubusercontent.com/amitkumarcoding/imagecroppicker/main/images/6.png" width="240" />
70
+ <img src="https://raw.githubusercontent.com/amitkumarcoding/imagecroppicker/main/images/7.png" width="240" />
71
+ <img src="https://raw.githubusercontent.com/amitkumarcoding/imagecroppicker/main/images/8.png" width="240" />
72
+ <img src="https://raw.githubusercontent.com/amitkumarcoding/imagecroppicker/main/images/9.png" width="240" />
73
+ </details>
74
+
75
+ ## Installation
102
76
 
103
77
  ```bash
104
- npm install react-native-customizable-image-crop-picker --save
78
+ npm install react-native-customizable-image-crop-picker
105
79
  ```
106
80
 
107
81
  or
@@ -113,85 +87,61 @@ yarn add react-native-customizable-image-crop-picker
113
87
  ### iOS
114
88
 
115
89
  ```bash
116
- cd ios
117
- pod install
118
- cd ..
90
+ cd ios && pod install && cd ..
119
91
  ```
120
92
 
121
- #### Permissions (Info.plist)
122
-
123
- Add:
124
-
125
- - `NSCameraUsageDescription`
126
- - `NSPhotoLibraryUsageDescription`
127
- - `NSPhotoLibraryAddUsageDescription` (only if saving to library)
128
-
129
93
  #### If CocoaPods fails: TOCropViewController modular headers
130
94
 
131
- If you see this error during `pod install`:
132
-
133
- - `The following Swift pods cannot yet be integrated as static libraries...`
134
- - `RNCustomizableImageCropPicker depends upon TOCropViewController, which does not define modules`
135
-
136
- Add this to your **app** `ios/Podfile` (inside your app target):
95
+ If `pod install` fails with a Swift modular headers error (TOCropViewController), add this to your **app** `ios/Podfile` (inside your app target):
137
96
 
138
97
  ```ruby
139
98
  pod 'TOCropViewController', :modular_headers => true
140
99
  ```
141
100
 
142
- Then run:
143
-
144
- ```bash
145
- cd ios
146
- pod install
147
- cd ..
148
- ```
101
+ Then run `pod install` again.
149
102
 
150
103
  #### If you see an rsync error about missing simulator slice (RN 0.84+ prebuilt pods)
151
104
 
152
105
  ```bash
153
106
  cd ios
154
107
  RCT_USE_PREBUILT_RNCORE=0 pod install
108
+ cd ..
155
109
  ```
156
110
 
111
+ ## Permissions
112
+
113
+ ### iOS (`Info.plist`)
114
+
115
+ Add:
116
+
117
+ - `NSCameraUsageDescription`
118
+ - `NSPhotoLibraryUsageDescription`
119
+ - `NSPhotoLibraryAddUsageDescription` (only if saving to library)
120
+
157
121
  ### Android
158
122
 
159
- Autolinking handles it. For camera flows, ensure this exists (manifest merge usually brings it from the library):
123
+ - Request `CAMERA` permission at runtime before opening `source: 'camera'`.
124
+ - Ensure the following is present (usually merged from the library):
160
125
 
161
126
  ```xml
162
127
  <uses-permission android:name="android.permission.CAMERA" />
163
128
  ```
164
129
 
165
- If you use **remote icons** (`http/https`) for buttons, your app must also have:
130
+ If you use **remote icons** (`http/https`) for buttons:
166
131
 
167
132
  ```xml
168
133
  <uses-permission android:name="android.permission.INTERNET" />
169
134
  ```
170
135
 
171
- ### SVG icons (Android native UI)
136
+ ### Notes
172
137
 
173
- On **Android**, button icon props like `uploadButtonIconUri` / `cancelButtonIconUri` can also be **SVG**:
174
-
175
- - Remote: `https://.../icon.svg`
176
- - Local: `file://.../icon.svg` or `content://.../icon.svg`
177
- - Data URI: `data:image/svg+xml;utf8,<svg ...>`
178
- - Base64: `data:image/svg+xml;base64,PHN2Zy4uLg==`
179
-
180
- On **iOS native UI**, SVG icons are not supported (use PNG/JPG/WebP), or use the JS UI (`ImageCropPickerModal`) with `react-native-svg`.
181
-
182
- ## Usage
138
+ - **iOS Simulator**: camera isn’t available on the simulator. Test camera on a real device.
183
139
 
184
- Import:
140
+ ## Quick start
185
141
 
186
142
  ```js
187
- import {
188
- openImageCropPicker,
189
- } from 'react-native-customizable-image-crop-picker';
190
- ```
191
-
192
- ### Select from gallery
143
+ import { openImageCropPicker } from 'react-native-customizable-image-crop-picker';
193
144
 
194
- ```js
195
145
  const result = await openImageCropPicker({
196
146
  source: 'gallery',
197
147
  cropWidth: 1,
@@ -201,7 +151,7 @@ const result = await openImageCropPicker({
201
151
  console.log(result.path);
202
152
  ```
203
153
 
204
- ### Select from camera
154
+ ### Camera
205
155
 
206
156
  ```js
207
157
  const result = await openImageCropPicker({
@@ -223,200 +173,28 @@ const result = await openImageCropPicker({
223
173
  });
224
174
  ```
225
175
 
226
- ## Optional: JS UI chrome (`ImageCropPickerModal`)
227
-
228
- This package also exports a **fully customizable React Native modal** (`ImageCropPickerModal`) that you can use as your own UI layer (custom header/footer/buttons). It’s independent from the native crop flow.
229
-
230
- ## Examples
176
+ ### Examples (recommended)
231
177
 
232
178
  - [Basic Example](https://github.com/amitkumarcoding/imagecroppicker/blob/main/App.js)
233
179
  - [Full Example](https://github.com/amitkumarcoding/imagecroppicker/blob/main/packages/react-native-customizable-image-crop-picker/example/App.js)
234
180
 
181
+ ## Icons (including SVG on Android)
235
182
 
236
- ### Usage
183
+ Button icon props like `uploadButtonIconUri` / `cancelButtonIconUri` accept:
237
184
 
238
- ```js
185
+ - Remote URI: `https://...`
186
+ - Local file: `file://...`
187
+ - Android content URI: `content://...`
188
+ - Bundled asset: `require('./icon.png')` (recommended)
239
189
 
240
- import React from 'react';
241
- import {
242
- View,
243
- Text,
244
- StyleSheet,
245
- StatusBar,
246
- TouchableOpacity,
247
- Alert,
248
- Platform,
249
- PermissionsAndroid,
250
- } from 'react-native';
251
- import { SafeAreaView } from 'react-native-safe-area-context';
252
- import { openImageCropPicker } from 'react-native-customizable-image-crop-picker';
190
+ ### SVG
253
191
 
254
- const App = () => {
255
- async function ensureCameraPermission() {
256
- if (Platform.OS !== 'android') return true;
257
- const res = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.CAMERA);
258
- return res === PermissionsAndroid.RESULTS.GRANTED;
259
- }
260
-
261
- const baseConfig = {
262
- cropWidth: 1,
263
- cropHeight: 1,
264
- circularCrop: true,
265
- cropGridEnabled: true,
266
- dimmedLayerColor: '#B3000000',
267
- compressQuality: 0.8,
268
- compressFormat: 'jpeg',
269
- headerTitle: 'Preview',
270
- headerAlignment: 'center',
271
- controlsPlacement: 'bottom',
272
- uploadText: 'Upload',
273
- cancelText: 'Cancel',
274
- uploadButtonContent: 'text',
275
- cancelButtonContent: 'text',
276
- };
277
-
278
- const openCamera = async () => {
279
- const ok = await ensureCameraPermission();
280
- if (!ok) return;
281
-
282
- try {
283
- const result = await openImageCropPicker({
284
- ...baseConfig,
285
- source: 'camera',
286
- });
287
- console.log('Camera Result:', result);
288
- } catch (error) {
289
- handleError(error);
290
- }
291
- };
292
-
293
- const openGallery = async () => {
294
- try {
295
- const result = await openImageCropPicker({
296
- ...baseConfig,
297
- source: 'gallery',
298
- });
299
-
300
- console.log('Gallery Result:', result);
301
- } catch (error) {
302
- handleError(error);
303
- }
304
- };
305
-
306
- const handleError = (error) => {
307
- if (error?.code === 'E_PERMISSION_MISSING') {
308
- Alert.alert('Permission Required', 'Please allow camera access');
309
- return;
310
- }
311
-
312
- if (error?.code === 'E_PICKER_CANCELLED') {
313
- console.log('User cancelled');
314
- return;
315
- }
316
-
317
- console.error('Unhandled Error:', error);
318
- };
319
-
320
- return (
321
- <SafeAreaView style={styles.safeArea}>
322
- <StatusBar barStyle="dark-content" />
323
-
324
- <View style={styles.container}>
325
- <TouchableOpacity
326
- style={styles.primaryButton}
327
- activeOpacity={0.8}
328
- onPress={openCamera}
329
- >
330
- <Text style={styles.primaryText}>Open Camera</Text>
331
- </TouchableOpacity>
332
-
333
- <TouchableOpacity
334
- style={styles.secondaryButton}
335
- activeOpacity={0.8}
336
- onPress={openGallery}
337
- >
338
- <Text style={styles.secondaryText}>Open Gallery</Text>
339
- </TouchableOpacity>
340
- </View>
341
- </SafeAreaView>
342
- );
343
- };
344
-
345
- export default App;
346
-
347
- const styles = StyleSheet.create({
348
- safeArea: {
349
- flex: 1,
350
- backgroundColor: '#F9FAFB',
351
- },
352
- container: {
353
- flex: 1,
354
- justifyContent: 'center',
355
- paddingHorizontal: 20,
356
- gap: 16,
357
- },
358
- primaryButton: {
359
- backgroundColor: '#111827',
360
- paddingVertical: 14,
361
- borderRadius: 12,
362
- alignItems: 'center',
363
- },
364
- primaryText: {
365
- color: '#FFFFFF',
366
- fontSize: 16,
367
- fontWeight: '600',
368
- },
369
- secondaryButton: {
370
- borderWidth: 1.5,
371
- borderColor: '#111827',
372
- paddingVertical: 14,
373
- borderRadius: 12,
374
- alignItems: 'center',
375
- },
376
- secondaryText: {
377
- color: '#111827',
378
- fontSize: 16,
379
- fontWeight: '600',
380
- },
381
- });
382
- ```
192
+ - **Android native UI** supports SVG for these icon URIs.
193
+ - **iOS native UI** does **not** support SVG (use PNG/JPG/WebP).
383
194
 
384
- ### Modal props
195
+ ## API: `openImageCropPicker(options)`
385
196
 
386
- | Prop | Type | Required | Default | Description |
387
- | --- | --- | --- | --- | --- |
388
- | visible | boolean | Yes | - | Show/hide the modal |
389
- | imageUri | string | No | - | Image to preview |
390
- | onCancel | `() => void` | Yes | - | Cancel callback |
391
- | onConfirm | `() => void` | Yes | - | Confirm callback |
392
- | safeAreaEnabled | boolean | No | `true` | Wrap modal in `SafeAreaView` |
393
- | backgroundColor | string | No | `#000` | Preview background |
394
- | showHeader | boolean | No | `true` | Show header |
395
- | showFooter | boolean | No | `true` | Show footer |
396
- | headerTitle | string | No | `Preview Image` | Header title |
397
- | headerAlignment | `'left' \| 'center' \| 'right'` | No | `'center'` | Title alignment |
398
- | leftIcon | `React.ReactNode` | No | - | Left icon element |
399
- | rightIcon | `React.ReactNode` | No | - | Right icon element |
400
- | showLeftIcon | boolean | No | `headerAlignment === 'center'` | Show/hide left icon |
401
- | showRightIcon | boolean | No | `headerAlignment === 'center'` | Show/hide right icon |
402
- | headerStyle | `{ containerStyle?, titleStyle?, leftIconContainerStyle?, rightIconContainerStyle? }` | No | - | Header styling |
403
- | cancelText | string | No | `Cancel` | Cancel label |
404
- | uploadText | string | No | `Upload` | Upload label |
405
- | cancelIcon | `React.ReactNode` | No | - | Cancel icon element (footer) |
406
- | uploadIcon | `React.ReactNode` | No | - | Upload icon element (footer) |
407
- | footerStyle | `{ containerStyle?, buttonRowStyle?, cancelButtonStyle?, uploadButtonStyle?, cancelTextStyle?, uploadTextStyle?, cancelIconContainerStyle?, uploadIconContainerStyle? }` | No | - | Footer styling |
408
- | overlayStyle | `{ containerStyle?, previewContainerStyle?, imageStyle?, cropOverlayStyle? }` | No | - | Preview + overlay styling |
409
-
410
- ### Render overrides
411
-
412
- | Prop | Type | Required | Default | Description |
413
- | --- | --- | --- | --- | --- |
414
- | renderHeader | `(ctx) => React.ReactNode` | No | - | Full custom header |
415
- | renderFooter | `(ctx) => React.ReactNode` | No | - | Full custom footer |
416
- | renderCancelButton | `(ctx) => React.ReactNode` | No | - | Custom cancel button |
417
- | renderUploadButton | `(ctx) => React.ReactNode` | No | - | Custom upload button |
418
-
419
- ## Props / Options (`openImageCropPicker(options)`)
197
+ > Backwards compatible alias: `open(options)`
420
198
 
421
199
  Defaults shown below are the current native defaults.
422
200
 
@@ -453,6 +231,7 @@ Defaults shown below are the current native defaults.
453
231
  | --- | --- | --- | --- | --- |
454
232
  | preferNativeUI | boolean | No | `true` | Prefer native full-screen UI (current implementation uses native UI) |
455
233
  | headerTitle | string | No | `Preview Image` | Native header title |
234
+ | headerAlignment | `'left' \| 'center' \| 'right'` | No | `'center'` | Header title alignment |
456
235
  | headerHeight | number | No | `84` | Header height |
457
236
  | headerPaddingHorizontal | number | No | `20` | Header padding |
458
237
  | headerPaddingTop | number | No | `20` | Header padding |
@@ -528,7 +307,7 @@ When `showNativeCropControls: true`, the native crop toolbar is visible.
528
307
  - To avoid the footer covering the native toolbar, `showNativeCropControls` works **only with** `controlsPlacement: 'top'`.
529
308
  - If you pass `controlsPlacement: 'bottom'`, the library will **auto-force it to `'top'`**.
530
309
 
531
- ## Platform-specific props / behavior
310
+ ### Platform-specific props / behavior
532
311
 
533
312
  - **Android only**
534
313
  - **`drawUnderStatusBar`**: edge-to-edge header under the status bar.
@@ -553,26 +332,7 @@ These are read from React Native styles and mapped into native values (subset on
553
332
  | headerStyle | `{ containerStyle?, titleStyle? }` | No | - | Supports `containerStyle.backgroundColor`, `titleStyle.color/fontSize/fontFamily` |
554
333
  | footerStyle | `{ containerStyle?, cancelButtonStyle?, uploadButtonStyle?, cancelTextStyle?, uploadTextStyle? }` | No | - | Supports background/border/textColor/fontSize/fontFamily/borderRadius subset |
555
334
 
556
- ### JS-only props (ignored by `openImageCropPicker()`)
557
-
558
- These exist in exported types to support the `ImageCropPickerModal` component. They are currently **not used** by the native `openImageCropPicker()` flow (or its alias `open()`).
559
-
560
- | Prop | Type | Required | Default | Description |
561
- | --- | --- | --- | --- | --- |
562
- | showHeader | boolean | No | - | `ImageCropPickerModal` only |
563
- | headerAlignment | `'left' \| 'center' \| 'right'` | No | - | `ImageCropPickerModal` only |
564
- | leftIcon | `React.ReactNode` | No | - | `ImageCropPickerModal` only |
565
- | rightIcon | `React.ReactNode` | No | - | `ImageCropPickerModal` only |
566
- | showLeftIcon | boolean | No | - | `ImageCropPickerModal` only |
567
- | showRightIcon | boolean | No | - | `ImageCropPickerModal` only |
568
- | showFooter | boolean | No | - | `ImageCropPickerModal` only |
569
- | cancelIcon | `React.ReactNode` | No | - | `ImageCropPickerModal` only |
570
- | uploadIcon | `React.ReactNode` | No | - | `ImageCropPickerModal` only |
571
- | overlayStyle | `CropperOverlayStyle` | No | - | `ImageCropPickerModal` only |
572
- | backgroundColor | string | No | - | `ImageCropPickerModal` only |
573
- | safeAreaEnabled | boolean | No | - | `ImageCropPickerModal` only |
574
-
575
- ## Response Object
335
+ ## Response object
576
336
 
577
337
  | Property | Type | Description |
578
338
  | --- | --- | --- |
@@ -603,7 +363,7 @@ The library throws `CropPickerError` with a `code`:
603
363
  - Multiple selection options exist in types but **native multiple picking is not implemented yet**.
604
364
  - iOS grid/frame color customization is limited (rectangle grid uses the native overlay; circular grid uses a custom overlay).
605
365
 
606
- ## Peer Dependencies
366
+ ## Peer dependencies
607
367
 
608
368
  | Package | Version |
609
369
  | --- | --- |
@@ -614,6 +374,11 @@ The library throws `CropPickerError` with a `code`:
614
374
 
615
375
  Contributions are welcome. Please open an issue with reproduction details or submit a PR with a clear description + test plan.
616
376
 
377
+ ## Support
378
+
379
+ - **Bug reports / feature requests**: open an issue with a minimal repro (device/OS, RN version, and logs).
380
+ - **Questions / help**: start a GitHub discussion or issue (whichever you prefer) with your use-case and desired UI.
381
+
617
382
  ## License
618
383
 
619
384
  MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-customizable-image-crop-picker",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "Fully customizable React Native image crop picker (JS UI + native performance).",
5
5
  "keywords": [
6
6
  "react-native",