React Picture Selector

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

  1. User selects a file – the component builds FormData using formDataName and fires onDeleteStart if a delete needs to happen first.
  2. Upload request – a fetch powered by Axios is sent to baseUrl + uploadUrl with your headers and method.
  3. Progress + preview – live progress is emitted while bytes stream in; fallback animations kick in when Content-Length is missing.
  4. Success – the response body is parsed, the image URL is extracted via responsePath, and onUploadSuccess plus onChangeImage fire.
  5. FailureonUploadError runs 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-data with the file attached
  • Delete: Accept requests with customizable method and body
  • Response: Return the image URL in the specified responsePath

Handling responses

  • responsePath uses lodash-style dot notation (default: data.data). Update it when your backend wraps URLs differently (e.g., result.payload.url).
  • deleteBody can be a plain object or a callback that receives the previously stored imageUrl. 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 testMode to true when 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 size with CSS clamp/utility classes to adapt to small vs. large breakpoints.
  • Combine additionalClassNames.image with aspect-ratio utilities when embedding into card layouts.
  • Keep brand colors accessible: progress and text should pass WCAG AA against the button background.
  • Enable blurOnProgress when 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

The component uses Tailwind CSS classes by default, but you can override any style using the color palette and additionalClassNames props.