Introduction
Customizable React component for seamless image upload, deletion, and preview.

The PictureSelector component is a highly customizable React component designed for seamless image upload, deletion, and preview functionality, ideal for profile pictures or general image management. Use it when you want to ship a polished upload experience without rebuilding drag & drop, preview modals, or API wiring from scratch.
π Feature Rich
Drag & drop, progress indicators, preview modals, and API integration
π¨ Highly Customizable
Colors, sizes, shapes, and full CSS class control
π§ͺ Test Mode
Simulate uploads and deletions without API dependencies
β‘ Performance Optimized
Smooth animations with requestAnimationFrame and abort controllers
Features
- Smooth Image Upload: Upload images with a progress ring (for profiles) or percentage display, powered by
requestAnimationFramefor smooth animations and low CPU usage. - Flexible Image Deletion: Delete images via API with customizable HTTP methods, headers, and request body, or simulated deletion in test mode.
- Progress Indicator: Displays a progress ring for circular profiles or a percentage-based indicator, with non-linear fallback for servers without
Content-Length. - Drag and Drop Support: Allows users to drag and drop images with visual feedback, with prevention of dragging selected photos for better UX.
- Image Preview: Clickable modal preview for uploaded images, supporting circular and rectangular formats.
- Full API Response Access: Provides the full API response body as an optional parameter in
onChangeImagefor advanced use cases. - Configurable Styling: Customize colors, sizes, shapes, and additional CSS classes for full control over appearance.
- Abort Controller: Cancel ongoing uploads using
AbortControllerfor better user control. - Event Callbacks: Support for
onUploadSuccess,onUploadError,onDeleteStart, andonDeleteSuccesscallbacks to handle upload and deletion events. - Test Mode: Simulate uploads and deletions with configurable delays, ideal for testing without API dependencies.
- Responsive Design: Supports RTL layouts, responsive sizing, and both circular (profile) and rectangular image types.
- Robust Error Handling: Displays clear error messages for failed operations, with proper cleanup to prevent resource leaks.
- Performance Optimizations: Prevents race conditions, ensures clean percentage displays, and optimizes resource usage using
useMemoanduseCallback.
Quick Start
import PictureSelector from "react-picture-selector";
const App = () => {
const handleImageChange = (imageUrl: string, responseData?: unknown) => {
console.log("New image URL:", imageUrl, responseData);
};
return (
<PictureSelector
imageUrl="https://example.com/avatar.jpg"
onChangeImage={handleImageChange}
type="profile"
title="Profile Picture"
size={180}
/>
);
};Core Concepts
Upload experience
- Drop zone and picker: Users can drag files onto the selector or open the OS picker. When an upload is running, the drop zone is visually disabled to prevent duplicate requests.
- Abortable progress: Uploads use
AbortController, so canceling, deleting, or navigating away halts the request and resets progress cleanly. - Accessible previews: The preview modal is keyboard navigable, traps focus, and adapts to both circular (βprofileβ) and rectangular image modes.
Test mode vs real mode
- Test mode simulates uploads and deletions locally. It is perfect for Storybook, design reviews, or rapid prototyping without a backend.
- Real mode sends HTTP requests described in
apiConfig. You receive the resulting URL and the raw API response viaonChangeImageso nothing is lost.
State management
PictureSelector is stateless; you control the imageUrl prop. Update your local or server state when onChangeImage fires to keep the UI in sync.
Props overview
| Prop | Type | Required | Description |
|---|---|---|---|
imageUrl | string | β | Current image shown in the selector or placeholder if empty |
title | string | β | Title rendered above the selector (and announced for accessibility) |
type | "profile" | "rectangle" | β | Controls layout, aspect ratio, and progress indicator style |
size | number | β | Base dimension in pixels for the component |
onChangeImage | (url: string, response?: unknown) => void | β | Fires after upload/delete so you can persist state |
apiConfig | ApiConfig | β | Enables real upload/delete requests with headers and callbacks |
testMode | boolean | β | Forces simulated uploads with configurable delays |
colors | ColorPalette | β | Overrides primary/error/progress/placeholder/text colors |
additionalClassNames | SelectorClassNames | β | Granular class overrides for title, buttons, or image shell |
showProgressRing | boolean | β | Toggles the radial indicator for profile images |
blurOnProgress | boolean | β | Blurs the current photo while uploads run to hint a change |
Testing scenarios
| Scenario | Recommendation |
|---|---|
| Designing UI states | Enable testMode, adjust delays, and preview empty vs filled selectors |
| Integrating with a backend | Start in test mode to wire callbacks, then add apiConfig and monitor network traffic |
| Handling errors | Force a rejection in test mode or point to a known failing endpoint to confirm the error UI |
| RTL layouts | Wrap the component in <div dir="rtl"> to verify spacing, focus, and animation direction |
Next steps
- Head to Installation for environment requirements and peer dependencies.
- Dive into API & Styling to configure uploads, callbacks, and themes.
- Ready to contribute? The root
READMEdocuments scripts, linting, and deployment commands.