API and Styling
Learn about the API and styling options of React Picture Selector.
The apiConfig prop allows you to specify endpoints, HTTP methods, headers, and callbacks for upload and delete operations.
API Configuration Interface
interface ApiConfig {
// Required URLs
deleteUrl: string; // Path for deleting images, combined with baseUrl
uploadUrl: string; // Path for uploading images, combined with baseUrl
baseUrl: string; // Base URL for API requests
// Optional Configuration
responsePath?: string; // Path to extract image URL from API response (default: "data.data")
formDataName?: string; // Name of the file field in FormData (default: "file")
additionalHeaders?: Record<string, string>; // Additional headers for API requests
// HTTP Methods
uploadMethod?: "POST" | "PUT" | "PATCH"; // HTTP method for upload requests
deleteMethod?: "POST" | "DELETE" | "PUT"; // HTTP method for delete requests
// Request Body
deleteBody?: Record<string, unknown> | ((imageUrl: string) => Record<string, unknown>);
// Event Callbacks
onUploadSuccess?: (url: string) => void;
onUploadError?: (error: any) => void;
onDeleteStart?: () => void;
onDeleteSuccess?: () => void;
}Lifecycle events
- User selects a file – the component builds
FormDatausingformDataNameand firesonDeleteStartif a delete needs to happen first. - Upload request – a
fetchpowered by Axios is sent tobaseUrl + uploadUrlwith your headers and method. - Progress + preview – live progress is emitted while bytes stream in; fallback animations kick in when
Content-Lengthis missing. - Success – the response body is parsed, the image URL is extracted via
responsePath, andonUploadSuccessplusonChangeImagefire. - Failure –
onUploadErrorruns and the UI resets the component so users can retry immediately.
Abort handling
Deletions follow the same pattern but call deleteUrl with deleteBody. If a user cancels mid-flight, the Axios request is aborted and cleanup callbacks still trigger.
Complete API Configuration Example
const apiConfig = {
baseUrl: "https://api.example.com",
uploadUrl: "/upload",
deleteUrl: "/images/remove",
formDataName: "profile_picture",
responsePath: "data.imageUrl",
additionalHeaders: {
"X-API-Key": "your-api-key",
"Client-Version": "1.0.0"
},
uploadMethod: "POST",
deleteMethod: "DELETE",
deleteBody: (imageUrl) => ({
imageId: imageUrl.split("/").pop(),
timestamp: Date.now()
}),
onUploadSuccess: (url) => console.log("Uploaded:", url),
onUploadError: (error) => console.error("Upload failed:", error),
onDeleteStart: () => console.log("Starting deletion..."),
onDeleteSuccess: () => console.log("Image deleted successfully")
};API Requirements
Your API should support:
- Upload: Accept
multipart/form-datawith the file attached - Delete: Accept requests with customizable method and body
- Response: Return the image URL in the specified
responsePath
Handling responses
responsePathuses lodash-style dot notation (default:data.data). Update it when your backend wraps URLs differently (e.g.,result.payload.url).deleteBodycan be a plain object or a callback that receives the previously storedimageUrl. This is handy when your API expects an image ID or signed key extracted from the URL itself.- Every successful upload triggers
onChangeImage(url, responseBody)so you can store extra metadata (S3 keys, CDN hashes, etc.) alongside the URL.
const apiConfig: ApiConfig = {
baseUrl: "https://api.example.com",
uploadUrl: "/media",
deleteUrl: "/media/delete",
responsePath: "result.assets[0].cdnUrl",
deleteBody: (imageUrl) => ({ assetId: new URL(imageUrl).searchParams.get("id") })
};Error visibility
Wrap network errors in logging/monitoring on your side via onUploadError so you know when a user cannot upload because of auth or quota issues.
Test mode behavior
- Set
testModetotruewhen you want the component to bypass HTTP calls and simulate uploads locally. - The component still fires
onChangeImage, letting the rest of your UI react as though a real upload completed. - Deletions resolve instantly in test mode, which is useful for unit tests or live demos where you do not have API credentials available.
Switching between modes
You can leave apiConfig defined while toggling testMode. When testMode is true, network calls are skipped; when it is false, the same component immediately starts using your backend.
Styling & Customization
Color Palette Configuration:
interface ColorPalette {
primary: string; // Edit button background color
error: string; // Delete button background color
progress: string; // Progress ring/percentage color
placeholder: string; // Placeholder SVG color
text: string; // Progress percentage text color
textDisabled: string; // Disabled button text/icon color
}Class name slots:
interface SelectorClassNames {
title?: string;
titleContainer?: string;
edit?: string;
delete?: string;
image?: string;
progressText?: string;
previewButton?: string;
}Use colors for token-level changes and additionalClassNames when you need to plug in utility classes, design-system tokens, or CSS modules.
Styling Examples
// Modern Blue Theme
const colors = {
primary: "#3B82F6",
error: "#EF4444",
progress: "#10B981",
placeholder: "#9CA3AF",
text: "#FFFFFF",
textDisabled: "#D1D5DB"
};
// Dark Theme
const darkColors = {
primary: "#8B5CF6",
error: "#F43F5E",
progress: "#06D6A0",
placeholder: "#6B7280",
text: "#1F2937",
textDisabled: "#4B5563"
};Styling tips
- Pair
sizewith CSS clamp/utility classes to adapt to small vs. large breakpoints. - Combine
additionalClassNames.imagewith aspect-ratio utilities when embedding into card layouts. - Keep brand colors accessible:
progressandtextshould pass WCAG AA against the button background. - Enable
blurOnProgresswhen replacing an existing avatar so users understand a change is in flight.
Component Types & Sizes
Profile Type
Circular image with ring progress indicator. Ideal for user avatars and profile pictures.
Rectangle Type
Rectangular image with percentage progress bar. Perfect for general image uploads.
// Profile (Circular)
<PictureSelector type="profile" size={150} />
// Rectangle
<PictureSelector type="rectangle" size={200} />Tailwind CSS Compatible