Image Cropper
An image cropper provides a headless container for cropping and resizing an image to a selected region, typically using mouse, touch, or stylus input to move and resize a crop rectangle. Commonly used in avatar and profile-photo editors, media upload workflows, document scanning, and content management systems, the image cropper brings the familiar drag-to-frame experience to digital interfaces.
The component serves as a semantic container that consumers populate with their preferred cropping implementation, whether an HTML image with an overlay, a canvas, SVG resize handles, or a third-party cropping library. It uses role="application" to support complex pointer interactions, along with an accessible label describing the cropping purpose.
Implementation Notes
- Renders a
<div>withrole="application"to indicate complex widget behavior requiring pointer interaction - Requires an
aria-labeldescribing the cropping purpose for accessibility - Consumers provide the actual image and crop overlay UI (image, canvas, SVG handles, etc.) as children
- Spreads
restPropsonto the container for consumer customization
Props
label: string (required) -- accessible description of the image cropper viaaria-labelchildren: slot (required) -- the image and crop overlay surface (image, canvas, SVG, or cropping-library output)
Usage
Basic image cropper with an image and overlay:
<ImageCropper label="Crop your profile photo">
<img src="/uploads/photo.jpg" alt="Photo to crop" />
</ImageCropper>
Image cropper in an avatar upload flow:
<Form label="Update profile photo" onsubmit={handleUpload}>
<Field label="Profile photo" required>
<ImageCropper label="Crop your profile photo to a square">
<img src={previewUrl} alt="Selected photo to crop" id="avatar-crop" />
</ImageCropper>
</Field>
<div class="actions">
<Button type="button" onclick={resetCrop}>Reset</Button>
<Button type="submit">Save photo</Button>
</div>
</Form>
Image cropper for a document scan:
<ImageCropper label="Adjust the crop region around the document">
<canvas width="600" height="800" id="scan-crop"></canvas>
</ImageCropper>
<p>Drag the corners to frame the document before saving.</p>
Keyboard Interactions
None are baked in -- this component is a passive container. Pointer- and keyboard-based crop interactions are handled by the consumer-provided overlay surface.
ARIA
role="application"-- indicates a complex widget with custom pointer interactions, informing assistive technologies to pass keyboard events through to the applicationaria-label-- provides an accessible description of the image cropper purpose
When to Use
- Use when a user must frame, crop, or resize an image before saving or uploading it, such as avatar editors and media workflows.
- Use when a fixed aspect ratio or focal region needs to be selected from a larger image.
- Use in content management and document-scanning flows where a region of an image must be isolated.
- Use when a drag-to-frame experience is more intuitive than numeric crop inputs.
When Not to Use
- Do not use for simply selecting and previewing a file -- use ImageFileInput.
- Do not use for capturing a handwritten signature -- use SignaturePad.
- Do not use for displaying an image without editing -- use Image.
- Do not use for picking a colour from an image -- use ColorPicker.
Headless
This headless component provides a semantic container with role="application" and aria-label for complex pointer interactions. The consumer provides the actual image, crop overlay, resize handles, and cropping logic (HTML/canvas/SVG or a third-party library) as children, along with all visual styling, gesture handling, and the resulting cropped-image output.
Styles
The consumer provides all CSS styling. The component renders with an .image-cropper class for targeting. No default styles are included — this is a fully headless component.
Testing
- Verify the component renders a
<div>element with classimage-cropper - Verify
role="application"is present - Verify the
aria-labelattribute reflects thelabelprop - Verify pass-through attributes are applied to the root
Advice
- Designers: Show a clear crop boundary, dimmed overlay outside the selection, and visible resize handles. Communicate any fixed aspect ratio and provide reset and zoom controls alongside the cropper.
- Developers: Emit the cropped result as a canvas, blob, or data URL. Offer keyboard-accessible controls for moving and resizing the crop region, and respect the source image's intrinsic dimensions when exporting.
Related components
image-file-input— an input for selecting image files with previewimage— an image element with alt textsignature-pad— a drawing area for capturing a handwritten signaturefield— a form field wrapper with label, input, and error message
References
- WAI-ARIA application Role: https://www.w3.org/TR/wai-aria-1.2/#application
- Origin UI Angular — Cropper: https://www.originui-ng.com/
- MDN Canvas API: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API