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.
- package/README.md +90 -325
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,24 +6,35 @@
|
|
|
6
6
|

|
|
7
7
|

|
|
8
8
|
|
|
9
|
-
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
|
47
|
+
## Roadmap / future features
|
|
37
48
|
|
|
38
|
-
- **
|
|
39
|
-
- **
|
|
40
|
-
- **
|
|
41
|
-
- **Richer error codes
|
|
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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
<
|
|
50
|
-
<img src="https://
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
</
|
|
57
|
-
<
|
|
58
|
-
<img src="https://
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
<
|
|
62
|
-
<img src="https://
|
|
63
|
-
</
|
|
64
|
-
|
|
65
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
###
|
|
136
|
+
### Notes
|
|
172
137
|
|
|
173
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
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
|
-
|
|
183
|
+
Button icon props like `uploadButtonIconUri` / `cancelButtonIconUri` accept:
|
|
237
184
|
|
|
238
|
-
|
|
185
|
+
- Remote URI: `https://...`
|
|
186
|
+
- Local file: `file://...`
|
|
187
|
+
- Android content URI: `content://...`
|
|
188
|
+
- Bundled asset: `require('./icon.png')` (recommended)
|
|
239
189
|
|
|
240
|
-
|
|
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
|
-
|
|
255
|
-
|
|
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
|
-
|
|
195
|
+
## API: `openImageCropPicker(options)`
|
|
385
196
|
|
|
386
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|