UNPKG

react-native-gallery-picker-pro

Version:

A comprehensive React Native media gallery picker with smooth animations, multi-select, single-select, crop functionality, and native iOS/Android support

236 lines (184 loc) 6.85 kB
# MotorInc Media Picker A comprehensive React Native media gallery picker with smooth animations, multi-select/single-select modes, crop functionality, and native iOS/Android support. ## Features - 🖼️ **Modern UI** - Smooth scrolling with layered animations - 📱 **Native Performance** - Built with native iOS and Android modules - ✨ **Multi/Single Select** - Flexible selection modes - ✂️ **Crop Functionality** - Built-in image cropping with aspect ratio controls - 🎬 **Video Support** - Handle both images and videos - 🎯 **Gesture Controls** - Intuitive touch gestures and animations - 📐 **Aspect Ratios** - Support for multiple aspect ratios (0.8, 16:9, 1:1) - 🔄 **Permission Handling** - Smart permission management - 📤 **Export Options** - Base64, URI, and file data support ## Installation ```bash npm install motorinc-media-picker ``` ### iOS Setup 1. Add to your `Podfile`: ```ruby pod 'MotorincMediaPicker', :path => '../node_modules/motorinc-media-picker' ``` 2. Run: ```bash cd ios && pod install ``` ### Android Setup The Android module is automatically linked with React Native 0.60+. ## Dependencies Make sure you have these peer dependencies installed: ```bash npm install react-native-gesture-handler react-native-reanimated react-native-view-shot ``` Follow the setup instructions for: - [react-native-gesture-handler](https://docs.swmansion.com/react-native-gesture-handler/docs/installation) - [react-native-reanimated](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started) ## Usage ### Basic Usage ```jsx import React from 'react'; import { View } from 'react-native'; import { MainPhotoGallery } from 'motorinc-media-picker'; export default function App() { const handleAssetSelected = (asset) => { console.log('Selected asset:', asset); }; const handleSelectedAssetsChange = (assets) => { console.log('Selected assets:', assets); }; return ( <View style={{ flex: 1 }}> <MainPhotoGallery mediaType="all" multiSelect={true} maxSelectionLimit={10} onAssetSelected={handleAssetSelected} onSelectedAssetsChange={handleSelectedAssetsChange} /> </View> ); } ``` ### Advanced Usage with Crop ```jsx import React, { useRef, useState } from 'react'; import { View, Button } from 'react-native'; import { MainPhotoGallery } from 'motorinc-media-picker'; export default function App() { const galleryRef = useRef(null); const [selectedAssets, setSelectedAssets] = useState([]); const [cropParams, setCropParams] = useState(new Map()); const handleCroppedImagesReady = (croppedImages) => { console.log('Cropped images:', croppedImages); }; const handleCropCapture = async () => { if (galleryRef.current) { await galleryRef.current.triggerCropCapture(); } }; return ( <View style={{ flex: 1 }}> <MainPhotoGallery ref={galleryRef} mediaType="image" multiSelect={true} selectedAssets={selectedAssets} onSelectedAssetsChange={setSelectedAssets} showSelectedAssetsHeader={true} onCropParamsChange={(assetId, params) => { setCropParams(prev => new Map(prev.set(assetId, params))); }} existingCropParams={cropParams} onCroppedImagesReady={handleCroppedImagesReady} onAspectRatioChange={(ratio) => console.log('Aspect ratio:', ratio)} /> <Button title="Capture Cropped Images" onPress={handleCropCapture} /> </View> ); } ``` ## Props ### MainPhotoGallery Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `mediaType` | `'image' \| 'video' \| 'all'` | `'all'` | Type of media to display | | `multiSelect` | `boolean` | `false` | Enable multi-selection mode | | `maxSelectionLimit` | `number` | `10` | Maximum number of assets that can be selected | | `selectedAssets` | `PhotoAsset[]` | `[]` | Currently selected assets | | `onAssetSelected` | `(asset: PhotoAsset) => void` | - | Callback when a single asset is selected | | `onSelectedAssetsChange` | `(assets: PhotoAsset[]) => void` | - | Callback when selected assets change | | `showSelectedAssetsHeader` | `boolean` | `false` | Show cropping header for selected assets | | `hideSelectionHeader` | `boolean` | `false` | Hide the selection mode header | | `onCropParamsChange` | `(assetId: string, params: CropParams \| null) => void` | - | Callback for crop parameter changes | | `existingCropParams` | `Map<string, CropParams>` | - | Existing crop parameters | | `onAspectRatioChange` | `(ratio: number) => void` | - | Callback for aspect ratio changes | | `onCroppedImagesReady` | `(images: Array<{assetId: string, dataUri: string}>) => void` | - | Callback when cropped images are ready | | `onCancel` | `() => void` | - | Cancel button callback | | `onNext` | `(assets: PhotoAsset[]) => void` | - | Next button callback | | `renderPermissionDeniedState` | `(onRequest?: () => void) => React.ReactNode` | - | Custom permission denied state | ## Types ### PhotoAsset ```typescript interface PhotoAsset { id: string; uri: string; filename: string; width: number; height: number; creationDate: number; mediaType: 'image' | 'video'; duration?: number; // For videos } ``` ### CropParams ```typescript interface CropParams { x: number; y: number; width: number; height: number; scale: number; aspectRatio: number; } ``` ### SelectedImage ```typescript interface SelectedImage { uri: string; fileName: string; fileSize: number; width: number; height: number; type: string; id: string; base64: string; } ``` ## Layered Scroll Behavior The gallery implements smooth layered scroll behavior: - **Scroll Up**: First hides the header section, then allows grid scrolling - **Scroll Down**: Grid scrolls down immediately, regardless of header position - **Header Drag**: Can always drag header up/down to show/hide sections - **Smooth Animations**: Cubic easing for natural feel ## Permissions ### iOS Add to your `Info.plist`: ```xml <key>NSPhotoLibraryUsageDescription</key> <string>This app needs access to photo library to select images</string> <key>NSPhotoLibraryAddUsageDescription</key> <string>This app needs access to save images to photo library</string> ``` ### Android Add to your `AndroidManifest.xml`: ```xml <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> ``` ## Contributing Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. ## License MIT ## Support If you like this project, please consider giving it a ⭐ on GitHub!