Cropper
An image cropper built on react-easy-crop. Drag to reposition, pinch /
scroll / slider to zoom — the image always covers the crop area. Call
getCroppedImage() through a ref to render the crop to a JPEG data URL via
canvas (same-origin / CORS images only).
As a dialog
CropperDialog is the full two-step photo flow: a drop zone to pick or drop a
photo, then the crop step with the zoom slider, Save and Choose another
photo. File state lives inside the dialog — the parent receives the cropped
data URL via onSave and closes the dialog when its own work is done. Pass
error (+ onClearError) to surface a validation alert on the crop step, and
onRemove to offer removing the current photo. All copy is overridable via
labels (the avatar flow passes translations through
@repo/features/users/components/avatar-photo-dialog).
Cropper props
| Prop | Type | Default | Description |
|---|---|---|---|
src | string | — | URL or object URL of the image. |
aspect | number | 1 | Crop aspect ratio. |
shape | "round" | "rect" | "round" | Crop mask shape. |
outputSize | number | 512 | Width (px) of the output; height follows the aspect. |
ref | Ref<CropperHandle> | — | Exposes getCroppedImage() (async) and reset(). |
CropperDialog props
| Prop | Type | Default | Description |
|---|---|---|---|
onSave | (dataUrl: string) => void | — | Receives the cropped JPEG data URL. |
saving | boolean | false | Disables actions and shows the saving label. |
error | string | null | — | External validation error shown on the crop step. |
onRemove | () => void | — | Adds a remove action for the current photo. |
maxSizeMb | number | 10 | Max accepted file size. |
labels | Partial<CropperDialogLabels> | — | Override any copy (title, hints, buttons). |