UNPKG

react-profile-crop

Version:

A flexible, customizable React component for cropping profile pictures with real-time preview.

249 lines (200 loc) 8.86 kB
# React Profile Cropper A flexible, customizable React component for cropping profile pictures with real-time preview. <!-- [![npm version](https://img.shields.io/npm/v/react-profile-cropper.svg)](https://www.npmjs.com/package/react-profile-cropper) --> <!-- [![License](https://img.shields.io/npm/l/react-profile-cropper.svg)](https://github.com/yourusername/react-profile-cropper/blob/main/LICENSE) --> ## Features - 🖼️ Circular, square, or rectangular crop shapes - 🔄 Real-time preview - 📱 Responsive and mobile-friendly with touch support - 🎚️ Zoom and drag controls - 🎨 Fully customizable theming - 📤 Multiple output formats (PNG, JPEG, WebP) - ⚙️ Configurable aspect ratio - 🔍 Error handling for file types and size ## Installation ```bash npm install react-profile-cropper # or yarn add react-profile-cropper ``` ## Basic Usage ```jsx import React from "react"; import { ProfileCropper } from "react-profile-cropper"; function App() { return ( <div className="app"> <ProfileCropper onSave={(imageData) => { console.log("Cropped image:", imageData); // Save to server or state }} /> </div> ); } export default App; ``` ## Advanced Usage ```jsx import React, { useState } from "react"; import { ProfileCropper } from "react-profile-cropper"; function ProfileEditor() { const [profileImage, setProfileImage] = useState(null); const [showCropper, setShowCropper] = useState(false); const handleSave = (imageData) => { setProfileImage(imageData); setShowCropper(false); // Upload to server }; return ( <div className="profile-editor"> {profileImage ? ( <div className="current-profile"> <img src={profileImage} alt="Profile" className="profile-image" /> <button onClick={() => setShowCropper(true)}>Change Picture</button> </div> ) : ( <button onClick={() => setShowCropper(true)}> Add Profile Picture </button> )} {showCropper && ( <div className="cropper-modal"> <ProfileCropper initialImage={profileImage} onSave={handleSave} onCancel={() => setShowCropper(false)} cropShape="circle" outputFormat="png" maxFileSizeMB={2} theme={{ accentColor: "#4a90e2", buttonBackgroundColor: "#4a90e2", }} /> </div> )} </div> ); } export default ProfileEditor; ``` ## Custom Theming ```jsx import { ProfileCropper } from "react-profile-cropper"; const customTheme = { backgroundColor: "#ffffff", overlayColor: "rgba(0, 0, 0, 0.7)", borderColor: "#cccccc", accentColor: "#ff5722", textColor: "#333333", buttonBackgroundColor: "#ff5722", buttonTextColor: "white", }; function App() { return ( <ProfileCropper theme={customTheme} // other props... /> ); } ``` ## Props ### Core Functionality | Prop | Type | Default | Description | | --------------- | ------------------------------------- | ----------- | ---------------------------------------- | | `initialImage` | `string` | `undefined` | Base64 or URL of initial image to crop | | `onSave` | `(imageData: string) => void` | `undefined` | Callback when save button is clicked | | `onCancel` | `() => void` | `undefined` | Callback when cancel button is clicked | | `cropShape` | `'circle' \| 'square' \| 'rectangle'` | `'circle'` | Shape of the crop area | | `aspectRatio` | `number` | `undefined` | Aspect ratio of crop area (width/height) | | `outputFormat` | `'png' \| 'jpeg' \| 'webp'` | `'png'` | Output image format | | `outputQuality` | `number` | `0.9` | Output image quality (0-1) | ### Style and Appearance | Prop | Type | Default | Description | | ----------------- | --------------------- | --------- | ------------------------------------ | | `theme` | `ThemeOptions` | See below | Theme customization object | | `size` | `number` | `250` | Size of the crop area (width in px) | | `className` | `string` | `''` | Class name for the container element | | `style` | `React.CSSProperties` | `{}` | Inline styles for the container | | `containerHeight` | `number` | `350` | Height of the container (px) | ### Controls and Features | Prop | Type | Default | Description | | ------------------ | --------- | ------- | ----------------------------- | | `maxZoom` | `number` | `4` | Maximum zoom level | | `minZoom` | `number` | `0` | Minimum zoom level | | `zoomStep` | `number` | `0.1` | Step size for zoom controls | | `allowZoom` | `boolean` | `true` | Enable zoom controls | | `allowDrag` | `boolean` | `true` | Enable image dragging | | `showPreview` | `boolean` | `true` | Show preview of cropped image | | `previewSize` | `number` | `120` | Size of preview image (px) | | `showZoomControls` | `boolean` | `true` | Show zoom slider | | `showChangeButton` | `boolean` | `true` | Show button to change image | ### Text Customization | Prop | Type | Default | Description | | ------------------ | -------- | ----------------------------- | ------------------------ | | `headerText` | `string` | `'Profile Picture Cropper'` | Header text | | `previewText` | `string` | `'Preview'` | Text below preview image | | `saveButtonText` | `string` | `'Save Profile Picture'` | Save button text | | `cancelButtonText` | `string` | `'Cancel'` | Cancel button text | | `loadingText` | `string` | `'Saving...'` | Text shown when saving | | `uploadText` | `string` | `'Click to upload image'` | Upload area main text | | `uploadSubtext` | `string` | `'JPG, PNG or GIF. Max 5MB.'` | Upload area subtext | | `zoomLabel` | `string` | `'Zoom:'` | Label for zoom control | | `changeButtonText` | `string` | `'Change Image'` | Change image button text | ### Image Constraints | Prop | Type | Default | Description | | ------------------- | -------- | ----------- | ------------------------------ | | `acceptedFileTypes` | `string` | `'image/*'` | Accepted file types for upload | | `maxFileSizeMB` | `number` | `5` | Maximum file size in MB | ### CSS Class Names | Prop | Type | Default | Description | | --------------------------- | -------- | ------- | ----------------------------- | | `containerClassName` | `string` | `''` | Class for the outer container | | `headerClassName` | `string` | `''` | Class for the header text | | `previewContainerClassName` | `string` | `''` | Class for preview container | | `buttonContainerClassName` | `string` | `''` | Class for button container | | `saveButtonClassName` | `string` | `''` | Class for save button | | `cancelButtonClassName` | `string` | `''` | Class for cancel button | | `errorContainerClassname` | `string` | `''` | Class for error container | | `errorTextClassname` | `string` | `''` | Class for error text | ### Error Handling | Prop | Type | Default | Description | | --------- | ------------------------- | ----------- | ----------------------------- | | `onError` | `(error: string) => void` | `undefined` | Callback when an error occurs | ## Default Theme ```javascript { backgroundColor: "#f3f2ef", overlayColor: "rgba(0, 0, 0, 0.6)", borderColor: "#e0e0e0", accentColor: "#0077B5", textColor: "#333333", buttonBackgroundColor: "#0077B5", buttonTextColor: "white" } ``` ## TypeScript Support The package includes TypeScript definitions. You can import the types: ```typescript import { ProfileCropperProps, CropArea, ThemeOptions, CropShape, OutputImageType, } from "react-profile-cropper"; ``` ## Development ### Building the package ```bash npm run build ``` ### Running tests ```bash npm test ``` ## License MIT © ydixit007(https://github.com/ydixit007)