react-native-customizable-image-crop-picker 1.0.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.
Files changed (176) hide show
  1. package/LICENSE +44 -0
  2. package/README.md +479 -0
  3. package/RNCustomizableImageCropPicker.podspec +26 -0
  4. package/android/.gradle/8.9/checksums/checksums.lock +0 -0
  5. package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
  6. package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
  7. package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
  8. package/android/.gradle/8.9/gc.properties +0 -0
  9. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  10. package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
  11. package/android/.gradle/vcs-1/gc.properties +0 -0
  12. package/android/build/.transforms/a34a6297c7e9b65c987429ecd018e9a9/results.bin +1 -0
  13. package/android/build/.transforms/a34a6297c7e9b65c987429ecd018e9a9/transformed/classes/classes_dex/classes.dex +0 -0
  14. package/android/build/.transforms/d07257a7807cb64bf14f5adb0f98ee25/results.bin +1 -0
  15. package/android/build/.transforms/d07257a7807cb64bf14f5adb0f98ee25/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/rncustomizableimagecroppicker/BuildConfig.dex +0 -0
  16. package/android/build/.transforms/d07257a7807cb64bf14f5adb0f98ee25/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/rncustomizableimagecroppicker/NativeImageCropperActivity$Companion.dex +0 -0
  17. package/android/build/.transforms/d07257a7807cb64bf14f5adb0f98ee25/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/rncustomizableimagecroppicker/NativeImageCropperActivity.dex +0 -0
  18. package/android/build/.transforms/d07257a7807cb64bf14f5adb0f98ee25/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/rncustomizableimagecroppicker/NativeImageCropperModule$Companion.dex +0 -0
  19. package/android/build/.transforms/d07257a7807cb64bf14f5adb0f98ee25/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/rncustomizableimagecroppicker/NativeImageCropperModule.dex +0 -0
  20. package/android/build/.transforms/d07257a7807cb64bf14f5adb0f98ee25/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/rncustomizableimagecroppicker/NativeImageCropperPackage.dex +0 -0
  21. package/android/build/.transforms/d07257a7807cb64bf14f5adb0f98ee25/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/rncustomizableimagecroppicker/NativeImagePickerFileProvider.dex +0 -0
  22. package/android/build/.transforms/d07257a7807cb64bf14f5adb0f98ee25/transformed/bundleLibRuntimeToDirDebug/desugar_graph.bin +0 -0
  23. package/android/build/generated/source/buildConfig/debug/com/rncustomizableimagecroppicker/BuildConfig.java +10 -0
  24. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +26 -0
  25. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/output-metadata.json +18 -0
  26. package/android/build/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties +6 -0
  27. package/android/build/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json +1 -0
  28. package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  29. package/android/build/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar +0 -0
  30. package/android/build/intermediates/compile_symbol_list/debug/generateDebugRFile/R.txt +1 -0
  31. package/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/xml_nativeimagepicker_file_paths.xml.flat +0 -0
  32. package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +2 -0
  33. package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +2 -0
  34. package/android/build/intermediates/incremental/mergeDebugAssets/merger.xml +2 -0
  35. package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +2 -0
  36. package/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +2 -0
  37. package/android/build/intermediates/java_res/debug/processDebugJavaRes/out/META-INF/react-native-customizable-image-crop-picker_debug.kotlin_module +0 -0
  38. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/rncustomizableimagecroppicker/BuildConfig.class +0 -0
  39. package/android/build/intermediates/local_only_symbol_list/debug/parseDebugLocalResources/R-def.txt +3 -0
  40. package/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +41 -0
  41. package/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +26 -0
  42. package/android/build/intermediates/navigation_json/debug/extractDeepLinksDebug/navigation.json +1 -0
  43. package/android/build/intermediates/nested_resources_validation_report/debug/generateDebugResources/nestedResourcesValidationReport.txt +1 -0
  44. package/android/build/intermediates/packaged_res/debug/packageDebugResources/xml/nativeimagepicker_file_paths.xml +6 -0
  45. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/META-INF/react-native-customizable-image-crop-picker_debug.kotlin_module +0 -0
  46. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/rncustomizableimagecroppicker/BuildConfig.class +0 -0
  47. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/rncustomizableimagecroppicker/NativeImageCropperActivity$Companion.class +0 -0
  48. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/rncustomizableimagecroppicker/NativeImageCropperActivity.class +0 -0
  49. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/rncustomizableimagecroppicker/NativeImageCropperModule$Companion.class +0 -0
  50. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/rncustomizableimagecroppicker/NativeImageCropperModule.class +0 -0
  51. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/rncustomizableimagecroppicker/NativeImageCropperPackage.class +0 -0
  52. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/rncustomizableimagecroppicker/NativeImagePickerFileProvider.class +0 -0
  53. package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  54. package/android/build/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt +2 -0
  55. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab +0 -0
  56. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream +0 -0
  57. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len +0 -0
  58. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len +0 -0
  59. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at +0 -0
  60. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i +0 -0
  61. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len +0 -0
  62. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab +0 -0
  63. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream +0 -0
  64. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len +0 -0
  65. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len +0 -0
  66. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at +0 -0
  67. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i +0 -0
  68. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len +0 -0
  69. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab +0 -0
  70. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream +0 -0
  71. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len +0 -0
  72. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len +0 -0
  73. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at +0 -0
  74. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i +0 -0
  75. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len +0 -0
  76. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab +0 -0
  77. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream +0 -0
  78. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream.len +0 -0
  79. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.len +0 -0
  80. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.values +0 -0
  81. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.values.at +0 -0
  82. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.values.s +1 -0
  83. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i +0 -0
  84. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i.len +0 -0
  85. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab +0 -0
  86. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream +0 -0
  87. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len +0 -0
  88. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len +0 -0
  89. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at +0 -0
  90. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i +0 -0
  91. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len +0 -0
  92. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +0 -0
  93. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream +0 -0
  94. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len +0 -0
  95. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len +0 -0
  96. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values +0 -0
  97. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
  98. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.s +1 -0
  99. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i +0 -0
  100. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len +0 -0
  101. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab +0 -0
  102. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream +0 -0
  103. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len +0 -0
  104. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len +0 -0
  105. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at +0 -0
  106. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i +0 -0
  107. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len +0 -0
  108. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab +0 -0
  109. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream +0 -0
  110. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len +0 -0
  111. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len +0 -0
  112. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at +0 -0
  113. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i +0 -0
  114. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i.len +0 -0
  115. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab +0 -0
  116. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream +0 -0
  117. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len +0 -0
  118. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len +0 -0
  119. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at +0 -0
  120. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i +0 -0
  121. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i.len +0 -0
  122. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab +2 -0
  123. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab +0 -0
  124. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream +0 -0
  125. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len +0 -0
  126. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len +0 -0
  127. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at +0 -0
  128. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i +0 -0
  129. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len +0 -0
  130. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab +0 -0
  131. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream +0 -0
  132. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len +0 -0
  133. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len +0 -0
  134. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at +0 -0
  135. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i +0 -0
  136. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len +0 -0
  137. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
  138. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
  139. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +0 -0
  140. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +0 -0
  141. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values +0 -0
  142. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
  143. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.s +1 -0
  144. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
  145. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len +0 -0
  146. package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
  147. package/android/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin +0 -0
  148. package/android/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
  149. package/android/build/outputs/logs/manifest-merger-debug-report.txt +46 -0
  150. package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  151. package/android/build/tmp/kotlin-classes/debug/META-INF/react-native-customizable-image-crop-picker_debug.kotlin_module +0 -0
  152. package/android/build/tmp/kotlin-classes/debug/com/rncustomizableimagecroppicker/NativeImageCropperActivity$Companion.class +0 -0
  153. package/android/build/tmp/kotlin-classes/debug/com/rncustomizableimagecroppicker/NativeImageCropperActivity.class +0 -0
  154. package/android/build/tmp/kotlin-classes/debug/com/rncustomizableimagecroppicker/NativeImageCropperModule$Companion.class +0 -0
  155. package/android/build/tmp/kotlin-classes/debug/com/rncustomizableimagecroppicker/NativeImageCropperModule.class +0 -0
  156. package/android/build/tmp/kotlin-classes/debug/com/rncustomizableimagecroppicker/NativeImageCropperPackage.class +0 -0
  157. package/android/build/tmp/kotlin-classes/debug/com/rncustomizableimagecroppicker/NativeImagePickerFileProvider.class +0 -0
  158. package/android/build.gradle +49 -0
  159. package/android/consumer-rules.pro +3 -0
  160. package/android/src/main/AndroidManifest.xml +23 -0
  161. package/android/src/main/java/com/rncustomizableimagecroppicker/NativeImageCropperActivity.kt +1009 -0
  162. package/android/src/main/java/com/rncustomizableimagecroppicker/NativeImageCropperModule.kt +684 -0
  163. package/android/src/main/java/com/rncustomizableimagecroppicker/NativeImageCropperPackage.kt +17 -0
  164. package/android/src/main/java/com/rncustomizableimagecroppicker/NativeImagePickerFileProvider.kt +6 -0
  165. package/android/src/main/res/xml/nativeimagepicker_file_paths.xml +6 -0
  166. package/ios/NativeImageCropperModule.m +13 -0
  167. package/ios/NativeImageCropperModule.swift +1400 -0
  168. package/package.json +116 -0
  169. package/react-native.config.js +13 -0
  170. package/src/api.ts +41 -0
  171. package/src/errors.ts +39 -0
  172. package/src/index.ts +4 -0
  173. package/src/native/NativeImageCropperModule.ts +34 -0
  174. package/src/native/mapOptions.ts +164 -0
  175. package/src/types.ts +258 -0
  176. package/src/ui/ImageCropPickerModal.tsx +322 -0
package/package.json ADDED
@@ -0,0 +1,116 @@
1
+ {
2
+ "name": "react-native-customizable-image-crop-picker",
3
+ "version": "1.0.1",
4
+ "description": "Fully customizable React Native image crop picker (JS UI + native performance).",
5
+ "keywords": [
6
+ "react-native",
7
+ "image",
8
+ "picker",
9
+ "crop",
10
+ "cropper",
11
+ "camera",
12
+ "gallery",
13
+ "typescript"
14
+ ],
15
+ "homepage": "https://github.com/amitkumarcoding/imagecroppicker/blob/main/packages/react-native-customizable-image-crop-picker/README.md",
16
+ "bugs": {
17
+ "url": "https://github.com/amitkumarcoding/imagecroppicker/issues"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/amitkumarcoding/imagecroppicker.git#main"
22
+ },
23
+ "license": "MIT",
24
+ "author": "Amit Kumar",
25
+ "type": "commonjs",
26
+ "exports": {
27
+ ".": {
28
+ "react-native": "./src/index.ts",
29
+ "types": "./dist/types/index.d.ts",
30
+ "import": "./dist/module/index.js",
31
+ "require": "./dist/commonjs/index.js"
32
+ }
33
+ },
34
+ "main": "dist/commonjs/index.js",
35
+ "types": "dist/types/index.d.ts",
36
+ "directories": {
37
+ "example": "example"
38
+ },
39
+ "files": [
40
+ "android",
41
+ "assets",
42
+ "ios",
43
+ "src",
44
+ "dist",
45
+ "*.podspec",
46
+ "react-native.config.js",
47
+ "README.md",
48
+ "LICENSE"
49
+ ],
50
+ "scripts": {
51
+ "clean": "rimraf dist",
52
+ "build": "npm run clean && bob build",
53
+ "lint": "eslint .",
54
+ "typecheck": "tsc -p tsconfig.json --noEmit"
55
+ },
56
+ "dependencies": {
57
+ "balanced-match": "^4.0.3",
58
+ "brace-expansion": "^5.0.2",
59
+ "glob": "^13.0.6",
60
+ "minimatch": "^10.2.2"
61
+ },
62
+ "devDependencies": {
63
+ "@react-native/babel-preset": "^0.84.0",
64
+ "@react-native/eslint-config": "^0.84.0",
65
+ "@react-native/typescript-config": "^0.84.0",
66
+ "@types/react": "^19.2.0",
67
+ "eslint": "^8.57.0",
68
+ "prettier": "^3.3.3",
69
+ "react": "^19.2.0",
70
+ "react-native": "^0.84.0",
71
+ "react-native-builder-bob": "^0.40.1",
72
+ "rimraf": "^6.0.1",
73
+ "typescript": "^5.8.3"
74
+ },
75
+ "peerDependencies": {
76
+ "react": ">=18",
77
+ "react-native": ">=0.72"
78
+ },
79
+ "peerDependenciesMeta": {
80
+ "react-native-safe-area-context": {
81
+ "optional": true
82
+ },
83
+ "react-native-svg": {
84
+ "optional": true
85
+ }
86
+ },
87
+ "sideEffects": false,
88
+ "module": "dist/module/index.js",
89
+ "react-native": "src/index.ts",
90
+ "source": "src/index.ts",
91
+ "bob": {
92
+ "source": "src",
93
+ "output": "dist",
94
+ "targets": [
95
+ "commonjs",
96
+ "module",
97
+ [
98
+ "typescript",
99
+ {
100
+ "project": "tsconfig.json"
101
+ }
102
+ ]
103
+ ]
104
+ },
105
+ "eslintConfig": {
106
+ "root": true,
107
+ "extends": [
108
+ "@react-native",
109
+ "prettier"
110
+ ]
111
+ },
112
+ "prettier": {
113
+ "singleQuote": true,
114
+ "trailingComma": "all"
115
+ }
116
+ }
@@ -0,0 +1,13 @@
1
+ module.exports = {
2
+ dependency: {
3
+ platforms: {
4
+ android: {
5
+ sourceDir: './android',
6
+ packageImportPath:
7
+ 'import com.rncustomizableimagecroppicker.NativeImageCropperPackage;',
8
+ packageInstance: 'new NativeImageCropperPackage()',
9
+ },
10
+ },
11
+ },
12
+ };
13
+
package/src/api.ts ADDED
@@ -0,0 +1,41 @@
1
+ import { normalizeNativeError } from './errors';
2
+ import type { CropResult, OpenOptions } from './types';
3
+ import { NativeImageCropperModule } from './native/NativeImageCropperModule';
4
+ import { mapOpenOptionsToNative } from './native/mapOptions';
5
+ import { NativeEventEmitter, Platform } from 'react-native';
6
+
7
+ export async function openImageCropPicker(options: OpenOptions): Promise<CropResult> {
8
+ options.onCropStart?.();
9
+ options.onProgress?.(0);
10
+ const emitter =
11
+ Platform.OS === 'android' ? new NativeEventEmitter(NativeImageCropperModule as any) : null;
12
+ const sub =
13
+ options.onProgress && emitter
14
+ ? emitter.addListener('NativeImageCropperProgress', (evt: any) => {
15
+ const p = typeof evt?.progress === 'number' ? evt.progress : undefined;
16
+ if (typeof p === 'number') options.onProgress?.(Math.max(0, Math.min(1, p)));
17
+ })
18
+ : null;
19
+ try {
20
+ const nativeOptions = mapOpenOptionsToNative(options);
21
+ const result = await NativeImageCropperModule.openImagePreview(nativeOptions);
22
+ const path = result.path ?? '';
23
+ if (!path) {
24
+ throw new Error('Native cropper returned empty path');
25
+ }
26
+ const payload = { path, base64: options.includeBase64 ? result.base64 : undefined };
27
+ options.onProgress?.(1);
28
+ options.onCropEnd?.(payload, undefined);
29
+ return payload;
30
+ } catch (e) {
31
+ const err = normalizeNativeError(e);
32
+ options.onCropEnd?.(undefined, err);
33
+ throw err;
34
+ } finally {
35
+ sub?.remove();
36
+ }
37
+ }
38
+
39
+ // Backwards compatible alias.
40
+ export const open = openImageCropPicker;
41
+
package/src/errors.ts ADDED
@@ -0,0 +1,39 @@
1
+ export type CropPickerErrorCode =
2
+ | 'E_ACTIVITY_DOES_NOT_EXIST'
3
+ | 'E_PICKER_CANCELLED'
4
+ | 'E_NO_IMAGE_DATA_FOUND'
5
+ | 'E_MODULE_DESTROYED'
6
+ | 'E_PICKER_ERROR'
7
+ | 'E_PERMISSION_MISSING'
8
+ | 'E_NO_APP_AVAILABLE'
9
+ | 'E_UNAVAILABLE'
10
+ | 'E_INVALID_OPTIONS';
11
+
12
+ export class CropPickerError extends Error {
13
+ code: CropPickerErrorCode;
14
+ details?: unknown;
15
+
16
+ constructor(code: CropPickerErrorCode, message: string, details?: unknown) {
17
+ super(message);
18
+ this.name = 'CropPickerError';
19
+ this.code = code;
20
+ this.details = details;
21
+ }
22
+ }
23
+
24
+ export function normalizeNativeError(error: unknown): CropPickerError {
25
+ if (error instanceof CropPickerError) return error;
26
+
27
+ const anyErr = error as any;
28
+ const code =
29
+ (typeof anyErr?.code === 'string' ? anyErr.code : undefined) ??
30
+ (typeof anyErr?.nativeErrorCode === 'string' ? anyErr.nativeErrorCode : undefined) ??
31
+ 'E_PICKER_ERROR';
32
+
33
+ const message =
34
+ (typeof anyErr?.message === 'string' && anyErr.message) ||
35
+ 'Image picker failed';
36
+
37
+ return new CropPickerError(code as CropPickerErrorCode, message, error);
38
+ }
39
+
package/src/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ export * from './types';
2
+ export * from './errors';
3
+ export * from './api';
4
+ export { ImageCropPickerModal } from './ui/ImageCropPickerModal';
@@ -0,0 +1,34 @@
1
+ import { NativeModules, Platform } from 'react-native';
2
+
3
+ export type NativeOpenImagePreviewOptions = Record<string, unknown>;
4
+
5
+ export type NativeOpenImagePreviewResult = {
6
+ path?: string;
7
+ base64?: string;
8
+ };
9
+
10
+ type NativeModuleShape = {
11
+ openImagePreview(
12
+ options: NativeOpenImagePreviewOptions,
13
+ ): Promise<NativeOpenImagePreviewResult>;
14
+ };
15
+
16
+ const LINKING_ERROR =
17
+ `The package "react-native-customizable-image-crop-picker" doesn't seem to be linked. ` +
18
+ Platform.select({
19
+ ios: "Make sure you have run 'pod install'. ",
20
+ default: '',
21
+ }) +
22
+ 'Make sure you rebuilt the app after installing the package.';
23
+
24
+ export const NativeImageCropperModule: NativeModuleShape =
25
+ NativeModules.NativeImageCropperModule ??
26
+ new Proxy(
27
+ {},
28
+ {
29
+ get() {
30
+ throw new Error(LINKING_ERROR);
31
+ },
32
+ },
33
+ ) as NativeModuleShape;
34
+
@@ -0,0 +1,164 @@
1
+ import type { OpenOptions } from '../types';
2
+ import { Image, StyleSheet } from 'react-native';
3
+
4
+ export function mapOpenOptionsToNative(options: OpenOptions): Record<string, unknown> {
5
+ const cropWidth = options.cropWidth ?? options.aspectRatio?.width;
6
+ const cropHeight = options.cropHeight ?? options.aspectRatio?.height;
7
+
8
+ const headerTitle = options.headerTitle ?? 'Preview Image';
9
+ const cancelText = options.cancelText ?? 'Cancel';
10
+ const uploadText = options.uploadText ?? 'Upload';
11
+
12
+ const headerStyle = options.headerStyle;
13
+ const footerStyle = options.footerStyle;
14
+
15
+ const resolveIconUri = (
16
+ input: unknown,
17
+ ): string | undefined => {
18
+ if (typeof input === 'string') return input;
19
+ if (input == null) return undefined;
20
+ // Accept RN assets (require()) and resolve to a URI string.
21
+ const resolved = Image.resolveAssetSource(input as any);
22
+ return resolved?.uri;
23
+ };
24
+
25
+ const headerStylePayload: Record<string, unknown> = {};
26
+ if (headerStyle) {
27
+ headerStylePayload.backgroundColor = (headerStyle.containerStyle as any)?.backgroundColor;
28
+ headerStylePayload.color = (headerStyle.titleStyle as any)?.color;
29
+ headerStylePayload.fontSize = (headerStyle.titleStyle as any)?.fontSize;
30
+ headerStylePayload.fontFamily = (headerStyle.titleStyle as any)?.fontFamily;
31
+ }
32
+ if (options.headerHeight != null) headerStylePayload.height = options.headerHeight;
33
+ if (options.headerPaddingHorizontal != null)
34
+ headerStylePayload.paddingHorizontal = options.headerPaddingHorizontal;
35
+ if (options.headerPaddingTop != null) headerStylePayload.paddingTop = options.headerPaddingTop;
36
+ if (options.headerPaddingBottom != null)
37
+ headerStylePayload.paddingBottom = options.headerPaddingBottom;
38
+
39
+ const buttonContainerStylePayload: Record<string, unknown> = {};
40
+ if (footerStyle) {
41
+ const footerContainer = StyleSheet.flatten(footerStyle.containerStyle as any);
42
+ buttonContainerStylePayload.backgroundColor = footerContainer?.backgroundColor;
43
+ // Allow React Native-like spacing props on the native footer container.
44
+ if (typeof footerContainer?.paddingHorizontal === 'number')
45
+ buttonContainerStylePayload.paddingHorizontal = footerContainer.paddingHorizontal;
46
+ if (typeof footerContainer?.paddingTop === 'number')
47
+ buttonContainerStylePayload.paddingTop = footerContainer.paddingTop;
48
+ if (typeof footerContainer?.paddingBottom === 'number')
49
+ buttonContainerStylePayload.paddingBottom = footerContainer.paddingBottom;
50
+ if (typeof footerContainer?.gap === 'number') buttonContainerStylePayload.gap = footerContainer.gap;
51
+ }
52
+ if (options.footerPaddingHorizontal != null)
53
+ buttonContainerStylePayload.paddingHorizontal = options.footerPaddingHorizontal;
54
+ if (options.footerPaddingTop != null)
55
+ buttonContainerStylePayload.paddingTop = options.footerPaddingTop;
56
+ if (options.footerPaddingBottom != null)
57
+ buttonContainerStylePayload.paddingBottom = options.footerPaddingBottom;
58
+ if (options.footerButtonGap != null) buttonContainerStylePayload.gap = options.footerButtonGap;
59
+ if (options.footerButtonHeight != null)
60
+ buttonContainerStylePayload.buttonHeight = options.footerButtonHeight;
61
+ if (options.footerButtonLayout != null)
62
+ buttonContainerStylePayload.layout = options.footerButtonLayout;
63
+
64
+ const cancelButtonStylePayload: Record<string, unknown> = {};
65
+ if (footerStyle) {
66
+ cancelButtonStylePayload.backgroundColor = (footerStyle.cancelButtonStyle as any)?.backgroundColor;
67
+ cancelButtonStylePayload.borderColor = (footerStyle.cancelButtonStyle as any)?.borderColor;
68
+ cancelButtonStylePayload.borderWidth = (footerStyle.cancelButtonStyle as any)?.borderWidth;
69
+ cancelButtonStylePayload.fontFamily = (footerStyle.cancelTextStyle as any)?.fontFamily;
70
+ cancelButtonStylePayload.fontSize = (footerStyle.cancelTextStyle as any)?.fontSize;
71
+ cancelButtonStylePayload.textColor = (footerStyle.cancelTextStyle as any)?.color;
72
+ cancelButtonStylePayload.borderRadius = (footerStyle.cancelButtonStyle as any)?.borderRadius;
73
+ }
74
+ if (options.cancelButtonRadius != null && cancelButtonStylePayload.borderRadius == null) {
75
+ cancelButtonStylePayload.borderRadius = options.cancelButtonRadius;
76
+ }
77
+ if (options.cancelButtonContent != null) cancelButtonStylePayload.content = options.cancelButtonContent;
78
+ const cancelIconUri = resolveIconUri(options.cancelButtonIconUri);
79
+ if (cancelIconUri != null) cancelButtonStylePayload.iconUri = cancelIconUri;
80
+ if (options.cancelButtonIconBase64 != null) cancelButtonStylePayload.iconBase64 = options.cancelButtonIconBase64;
81
+ if (options.cancelButtonIconTintColor != null)
82
+ cancelButtonStylePayload.iconTintColor = options.cancelButtonIconTintColor;
83
+ if (options.cancelButtonIconSize != null) cancelButtonStylePayload.iconSize = options.cancelButtonIconSize;
84
+ if (options.buttonIconGap != null) cancelButtonStylePayload.iconGap = options.buttonIconGap;
85
+ const cancelPadH =
86
+ options.cancelButtonContentPaddingHorizontal ?? options.buttonContentPaddingHorizontal;
87
+ const cancelPadV =
88
+ options.cancelButtonContentPaddingVertical ?? options.buttonContentPaddingVertical;
89
+ if (cancelPadH != null) cancelButtonStylePayload.paddingHorizontal = cancelPadH;
90
+ if (cancelPadV != null) cancelButtonStylePayload.paddingVertical = cancelPadV;
91
+
92
+ const uploadButtonStylePayload: Record<string, unknown> = {};
93
+ if (footerStyle) {
94
+ uploadButtonStylePayload.backgroundColor = (footerStyle.uploadButtonStyle as any)?.backgroundColor;
95
+ uploadButtonStylePayload.borderColor = (footerStyle.uploadButtonStyle as any)?.borderColor;
96
+ uploadButtonStylePayload.borderWidth = (footerStyle.uploadButtonStyle as any)?.borderWidth;
97
+ uploadButtonStylePayload.fontFamily = (footerStyle.uploadTextStyle as any)?.fontFamily;
98
+ uploadButtonStylePayload.fontSize = (footerStyle.uploadTextStyle as any)?.fontSize;
99
+ uploadButtonStylePayload.textColor = (footerStyle.uploadTextStyle as any)?.color;
100
+ uploadButtonStylePayload.borderRadius = (footerStyle.uploadButtonStyle as any)?.borderRadius;
101
+ }
102
+ if (options.uploadButtonRadius != null && uploadButtonStylePayload.borderRadius == null) {
103
+ uploadButtonStylePayload.borderRadius = options.uploadButtonRadius;
104
+ }
105
+ if (options.uploadButtonContent != null) uploadButtonStylePayload.content = options.uploadButtonContent;
106
+ const uploadIconUri = resolveIconUri(options.uploadButtonIconUri);
107
+ if (uploadIconUri != null) uploadButtonStylePayload.iconUri = uploadIconUri;
108
+ if (options.uploadButtonIconBase64 != null) uploadButtonStylePayload.iconBase64 = options.uploadButtonIconBase64;
109
+ if (options.uploadButtonIconTintColor != null)
110
+ uploadButtonStylePayload.iconTintColor = options.uploadButtonIconTintColor;
111
+ if (options.uploadButtonIconSize != null) uploadButtonStylePayload.iconSize = options.uploadButtonIconSize;
112
+ if (options.buttonIconGap != null) uploadButtonStylePayload.iconGap = options.buttonIconGap;
113
+ const uploadPadH =
114
+ options.uploadButtonContentPaddingHorizontal ?? options.buttonContentPaddingHorizontal;
115
+ const uploadPadV =
116
+ options.uploadButtonContentPaddingVertical ?? options.buttonContentPaddingVertical;
117
+ if (uploadPadH != null) uploadButtonStylePayload.paddingHorizontal = uploadPadH;
118
+ if (uploadPadV != null) uploadButtonStylePayload.paddingVertical = uploadPadV;
119
+
120
+ return {
121
+ pickerSource: options.source,
122
+ width: typeof cropWidth === 'number' ? Math.round(cropWidth) : undefined,
123
+ height: typeof cropHeight === 'number' ? Math.round(cropHeight) : undefined,
124
+ freeStyleCropEnabled: options.freeStyleCropEnabled === true,
125
+ includeBase64: options.includeBase64 === true,
126
+ compressQuality:
127
+ typeof options.compressQuality === 'number' ? options.compressQuality : undefined,
128
+ compressFormat: options.compressFormat,
129
+ circularCrop: options.circularCrop === true,
130
+ rotationEnabled: options.rotationEnabled === true,
131
+ cropGridEnabled: options.cropGridEnabled === true,
132
+ cropFrameColor: options.cropFrameColor,
133
+ cropGridColor: options.cropGridColor,
134
+ showNativeCropControls: options.showNativeCropControls === true,
135
+ isDarkTheme: options.isDarkTheme === true,
136
+ drawUnderStatusBar: options.drawUnderStatusBar === true,
137
+ cropperStatusBarColor: options.statusBarColor,
138
+ cropperStatusBarStyle: options.statusBarStyle,
139
+ cropperDimmedLayerColor:
140
+ options.dimmedLayerColor ?? options.cropOverlayColor,
141
+
142
+ cropperToolbarTitle: headerTitle,
143
+ cropperCancelText: cancelText,
144
+ cropperChooseText: uploadText,
145
+ headerAlignment: options.headerAlignment,
146
+ controlsPlacement: options.controlsPlacement,
147
+ topLeftControl: options.topLeftControl,
148
+ topRightControl: options.topRightControl,
149
+ footerButtonOrder: options.footerButtonOrder,
150
+
151
+ // Best-effort mapping to existing native keys.
152
+ headerStyle: Object.keys(headerStylePayload).length ? headerStylePayload : undefined,
153
+ buttonContainerStyle: Object.keys(buttonContainerStylePayload).length
154
+ ? buttonContainerStylePayload
155
+ : undefined,
156
+ cancelButtonStyle: Object.keys(cancelButtonStylePayload).length
157
+ ? cancelButtonStylePayload
158
+ : undefined,
159
+ uploadButtonStyle: Object.keys(uploadButtonStylePayload).length
160
+ ? uploadButtonStylePayload
161
+ : undefined,
162
+ };
163
+ }
164
+
package/src/types.ts ADDED
@@ -0,0 +1,258 @@
1
+ import type * as React from 'react';
2
+ import type {
3
+ ImageSourcePropType,
4
+ ImageStyle,
5
+ StyleProp,
6
+ TextStyle,
7
+ ViewStyle,
8
+ } from 'react-native';
9
+
10
+ export type PickerSource = 'camera' | 'gallery';
11
+ export type HeaderAlignment = 'left' | 'center' | 'right';
12
+
13
+ export type CropCompressionFormat = 'jpeg' | 'png' | 'webp';
14
+
15
+ export type CropResult = {
16
+ path: string;
17
+ width?: number;
18
+ height?: number;
19
+ mime?: string;
20
+ size?: number;
21
+ base64?: string;
22
+ exif?: Record<string, unknown>;
23
+ };
24
+
25
+ export type PickedImage = {
26
+ path: string;
27
+ width?: number;
28
+ height?: number;
29
+ mime?: string;
30
+ size?: number;
31
+ };
32
+
33
+ export type IconElement = React.ReactNode;
34
+
35
+ export type HeaderStyle = {
36
+ containerStyle?: StyleProp<ViewStyle>;
37
+ titleStyle?: StyleProp<TextStyle>;
38
+ leftIconContainerStyle?: StyleProp<ViewStyle>;
39
+ rightIconContainerStyle?: StyleProp<ViewStyle>;
40
+ };
41
+
42
+ export type FooterStyle = {
43
+ containerStyle?: StyleProp<ViewStyle>;
44
+ buttonRowStyle?: StyleProp<ViewStyle>;
45
+ cancelButtonStyle?: StyleProp<ViewStyle>;
46
+ uploadButtonStyle?: StyleProp<ViewStyle>;
47
+ cancelTextStyle?: StyleProp<TextStyle>;
48
+ uploadTextStyle?: StyleProp<TextStyle>;
49
+ cancelIconContainerStyle?: StyleProp<ViewStyle>;
50
+ uploadIconContainerStyle?: StyleProp<ViewStyle>;
51
+ };
52
+
53
+ export type CropperOverlayStyle = {
54
+ containerStyle?: StyleProp<ViewStyle>;
55
+ previewContainerStyle?: StyleProp<ViewStyle>;
56
+ imageStyle?: StyleProp<ImageStyle>;
57
+ cropOverlayStyle?: StyleProp<ViewStyle>;
58
+ };
59
+
60
+ export type CropperUIProps = {
61
+ showHeader?: boolean;
62
+ headerTitle?: string;
63
+ headerAlignment?: HeaderAlignment;
64
+ leftIcon?: IconElement;
65
+ rightIcon?: IconElement;
66
+ showLeftIcon?: boolean;
67
+ showRightIcon?: boolean;
68
+ headerStyle?: HeaderStyle;
69
+ /**
70
+ * Native-only layout knobs (used by the native full-screen crop UI).
71
+ * For fully custom React components, use `ImageCropPickerModal`.
72
+ */
73
+ headerHeight?: number;
74
+ headerPaddingHorizontal?: number;
75
+ headerPaddingTop?: number;
76
+ headerPaddingBottom?: number;
77
+ /**
78
+ * Android native UI only:
79
+ * - false (default): header starts below the status bar (not "stuck" under it)
80
+ * - true: draw header under status bar (edge-to-edge)
81
+ */
82
+ drawUnderStatusBar?: boolean;
83
+
84
+ showFooter?: boolean;
85
+ cancelText?: string;
86
+ uploadText?: string;
87
+ cancelIcon?: IconElement;
88
+ uploadIcon?: IconElement;
89
+ footerStyle?: FooterStyle;
90
+ footerPaddingHorizontal?: number;
91
+ footerPaddingTop?: number;
92
+ footerPaddingBottom?: number;
93
+ footerButtonGap?: number;
94
+ footerButtonHeight?: number;
95
+ /**
96
+ * Native full-screen footer button layout.
97
+ * - vertical: Upload on top, Cancel below
98
+ * - horizontal: Cancel left, Upload right
99
+ */
100
+ footerButtonLayout?: 'vertical' | 'horizontal';
101
+ /**
102
+ * Native full-screen controls placement.
103
+ * - bottom: render actions in the footer (default)
104
+ * - top: render actions in the header (title stays centered)
105
+ */
106
+ controlsPlacement?: 'bottom' | 'top';
107
+ /**
108
+ * Only used when `controlsPlacement: 'top'`.
109
+ * Decide which control appears on the left/right side.
110
+ */
111
+ topLeftControl?: 'cancel' | 'upload' | 'none';
112
+ topRightControl?: 'cancel' | 'upload' | 'none';
113
+ /**
114
+ * Only used when `controlsPlacement: 'bottom'`.
115
+ * Controls ordering within the footer.
116
+ * - uploadFirst: Upload then Cancel (default)
117
+ * - cancelFirst: Cancel then Upload
118
+ */
119
+ footerButtonOrder?: 'uploadFirst' | 'cancelFirst';
120
+
121
+ /**
122
+ * Native full-screen: control content mode per button.
123
+ * - text: label only
124
+ * - icon: icon only
125
+ * - iconText | icon+text: icon then label
126
+ * - textIcon | TextIcon | text+icon: label then icon
127
+ */
128
+ cancelButtonContent?:
129
+ | 'text'
130
+ | 'icon'
131
+ | 'iconText'
132
+ | 'textIcon'
133
+ | 'TextIcon'
134
+ | 'icon+text'
135
+ | 'text+icon';
136
+ uploadButtonContent?:
137
+ | 'text'
138
+ | 'icon'
139
+ | 'iconText'
140
+ | 'textIcon'
141
+ | 'TextIcon'
142
+ | 'icon+text'
143
+ | 'text+icon';
144
+ cancelButtonIconUri?: string | ImageSourcePropType;
145
+ uploadButtonIconUri?: string | ImageSourcePropType;
146
+ cancelButtonIconBase64?: string;
147
+ uploadButtonIconBase64?: string;
148
+ cancelButtonIconTintColor?: string;
149
+ uploadButtonIconTintColor?: string;
150
+ cancelButtonIconSize?: number;
151
+ uploadButtonIconSize?: number;
152
+ buttonIconGap?: number;
153
+
154
+ /**
155
+ * Native full-screen: internal content padding for the action buttons.
156
+ * These apply to both buttons unless you override per-button.
157
+ */
158
+ buttonContentPaddingHorizontal?: number;
159
+ buttonContentPaddingVertical?: number;
160
+ cancelButtonContentPaddingHorizontal?: number;
161
+ cancelButtonContentPaddingVertical?: number;
162
+ uploadButtonContentPaddingHorizontal?: number;
163
+ uploadButtonContentPaddingVertical?: number;
164
+ cancelButtonRadius?: number;
165
+ uploadButtonRadius?: number;
166
+
167
+ overlayStyle?: CropperOverlayStyle;
168
+ backgroundColor?: string;
169
+ safeAreaEnabled?: boolean;
170
+
171
+ /**
172
+ * Native full-screen UI appearance.
173
+ */
174
+ isDarkTheme?: boolean;
175
+ statusBarColor?: string;
176
+ /**
177
+ * Android native UI only: status bar icon/text color.
178
+ * - dark: dark icons (for light backgrounds)
179
+ * - light: light icons (for dark backgrounds)
180
+ */
181
+ statusBarStyle?: 'dark' | 'light';
182
+ /**
183
+ * Native dimmed overlay color around the crop box (Android uses this directly).
184
+ * Example: "#CC0B1B3A"
185
+ */
186
+ dimmedLayerColor?: string;
187
+
188
+ /**
189
+ * Show native crop controls (rotation/aspect ratio toolbar).
190
+ * - Android: shows uCrop bottom controls and forces actions into the header.
191
+ * - iOS: shows TOCropViewController toolbar controls.
192
+ */
193
+ showNativeCropControls?: boolean;
194
+ };
195
+
196
+ export type CropOptions = {
197
+ cropWidth?: number;
198
+ cropHeight?: number;
199
+ aspectRatio?: { width: number; height: number };
200
+ freeStyleCropEnabled?: boolean;
201
+ circularCrop?: boolean;
202
+ rotationEnabled?: boolean;
203
+ cropGridEnabled?: boolean;
204
+ cropOverlayColor?: string;
205
+ cropFrameColor?: string;
206
+ cropGridColor?: string;
207
+
208
+ compressQuality?: number; // 0..1
209
+ compressFormat?: CropCompressionFormat;
210
+ includeBase64?: boolean;
211
+ };
212
+
213
+ export type PickerOptions = {
214
+ source: PickerSource;
215
+ multiple?: boolean;
216
+ maxFiles?: number;
217
+ mediaType?: 'photo';
218
+ };
219
+
220
+ export type OpenOptions = PickerOptions &
221
+ CropOptions &
222
+ CropperUIProps & {
223
+ /**
224
+ * If true, use the native full-screen UI flow (if your native layer supports it).
225
+ * If false, you can render JS chrome and use a native cropper *view* (future step).
226
+ */
227
+ preferNativeUI?: boolean;
228
+
229
+ /**
230
+ * JS callbacks (not passed to native).
231
+ */
232
+ onCropStart?: () => void;
233
+ onCropEnd?: (result?: CropResult, error?: unknown) => void;
234
+ /**
235
+ * Progress for slow work (currently best-effort; Android emits real base64 progress).
236
+ * 0..1
237
+ */
238
+ onProgress?: (progress: number) => void;
239
+ };
240
+
241
+ export type CropperRenderContext = {
242
+ title: string;
243
+ headerAlignment: HeaderAlignment;
244
+ onCancel: () => void;
245
+ onConfirm: () => void;
246
+ };
247
+
248
+ export type CropperRenderHeader = (ctx: CropperRenderContext) => React.ReactNode;
249
+ export type CropperRenderFooter = (ctx: CropperRenderContext) => React.ReactNode;
250
+ export type CropperRenderButton = (ctx: CropperRenderContext) => React.ReactNode;
251
+
252
+ export type CropperRenderOverrides = {
253
+ renderHeader?: CropperRenderHeader;
254
+ renderFooter?: CropperRenderFooter;
255
+ renderCancelButton?: CropperRenderButton;
256
+ renderUploadButton?: CropperRenderButton;
257
+ };
258
+