/v1.0

ImageCropField

ImageCropField shows a file dropzone that accepts PNG, JPEG, and SVG images. After the user selects a file the component opens ImageCropModal (full-screen) to let the user crop the image to the desired aspect ratio. Once the crop is confirmed the cropped image is uploaded via POST to uploadPath and onChange is called with the server-returned file path. A preview of the current image is shown with a remove button.

Props

| Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | value | string | Yes | — | Current image path (relative path returned by the server). | | onChange | (imagePath: string) => void | Yes | — | Called with the new image path after a successful upload, or with '' when cleared. | | apiBaseUrl | string | Yes | — | Base URL of the API used for the upload request. | | uploadPath | string | Yes | — | API path for the upload endpoint (e.g. /v1/files/upload). | | targetDir | string | Yes | — | Target directory on the server where the file will be stored. | | label | string | No | — | Label rendered above the field. | | description | string | No | — | Helper text rendered below the field. | | filesBaseUrl | string | No | urls.filesBase | Base URL prepended to the path when constructing the preview URL. | | useAuthToken | boolean | No | true | Whether to attach the auth token to the upload request. | | isPublic | boolean | No | true | Passed to the server to mark the file as publicly accessible. | | fileName | string | No | — | Override the filename sent in the upload form data. | | aspectRatio | number | No | 1 | Crop aspect ratio (e.g. 1 for square, 16/9 for widescreen). | | maxFileSize | number | No | — | Maximum accepted file size in MB. | | dropzoneLabel | string | No | — | Label shown inside the dropzone. | | dropzoneIcon | string | No | — | Icon name shown inside the dropzone. | | modalZIndex | number | No | 99999 | z-index applied to the crop modal. | | containerStyle | React.CSSProperties | No | — | Styles applied to the outer FieldContainer. | | headerStyle | React.CSSProperties | No | — | Styles applied to the field header area. | | bodyStyle | React.CSSProperties | No | — | Styles applied to the field body area. | | labelStyle | React.CSSProperties | No | — | Styles applied to the label element. | | descriptionStyle | React.CSSProperties | No | — | Styles applied to the description paragraph. | | className | string | No | — | CSS class name applied to the outer container. |

Usage

Basic square avatar

import React, { useState } from 'react';
import ImageCropField from '@/components/fields/ImageCropField';

export default function Example() {
  const [imagePath, setImagePath] = useState('');

  return (
    <ImageCropField
      label="Profile photo"
      value={imagePath}
      onChange={setImagePath}
      apiBaseUrl="https://api.example.com"
      uploadPath="/v1/files/upload"
      targetDir="avatars"
      aspectRatio={1}
    />
  );
}

16:9 banner image

<ImageCropField
  label="Banner"
  value={bannerPath}
  onChange={setBannerPath}
  apiBaseUrl="https://api.example.com"
  uploadPath="/v1/files/upload"
  targetDir="banners"
  aspectRatio={16 / 9}
  maxFileSize={5}
  dropzoneLabel="Drop a banner image here"
/>