Overview
TheDraggableImageItem component is part of an image gallery system that allows users to manage property images with drag-and-drop reordering, rotation, main image selection, and deletion marking.
Import
Props
The image object containing metadata. See PropertyImageMeta Type below.
Callback function triggered when the delete button is clicked. Receives the image ID.
Callback function triggered when setting an image as main. Receives the image ID.
Callback function triggered when the rotate button is clicked. Receives the image ID.
Whether the image is marked for deletion (affects button styling).
Current rotation angle in degrees (0, 90, 180, 270).
Function that returns CSS classes for image fitting based on rotation count.
PropertyImageMeta Type
Unique identifier for the image
URL of the image
Position in the gallery (0-based)
Whether this is the main/featured image
Rotation state (0-3, representing 90° increments)
Features
Drag and Drop
Powered by@dnd-kit/sortable:
- Drag images to reorder them
- Visual feedback during drag (opacity, scale, shadow)
- Cursor changes to
grabandgrabbing - Smooth transitions
Image Operations
Delete/Undelete
- Click the X button to mark for deletion
- Click again to unmark
- Visual feedback: Red background when marked
- Actual deletion happens on form submit
Set as Main
- Click the star button to set as main image
- Yellow badge when image is main
- Automatically moves to position 1
- Disabled when already main
Rotate
- Click rotate button to rotate 90° clockwise
- Smooth rotation transition (0.3s ease)
- Image fit classes adjust based on rotation
- Supports 0°, 90°, 180°, 270° rotations
Visual Indicators
Order Index Badge
- Top-left corner badge showing position
- Dark background with white text
- 1-based numbering for user clarity
Drag Handle
- Top-right corner grip icon
- Appears on hover (opacity transition)
- Visual indicator that item is draggable
Usage Examples
Button Controls
Delete Button (Top-Right)
States:- Default: White background, gray text
- Marked: Red background, white text
Main Image Button (Bottom-Left)
States:- Not main: White background, gray star outline
- Main: Yellow background, filled yellow star, disabled
Rotate Button (Bottom-Right)
Style: Blue background, white icon Icon: RotateCw from lucide-reactDrag Handle (Top-Right)
Style: Gray background, appears on hover Icon: GripVertical from lucide-reactStyling
Container
- Height:
h-32 - Relative positioning for absolute button placement
- Group hover effects
- Dragging states (opacity 0.5, scale 1.05, shadow-lg)
Image Container
- Width: 80% of parent
- Height: 80% of parent
- Border and rounded corners
- Centered using flex
- Transform origin center for rotation
- Smooth rotation transition (0.3s ease)
Image Fit Classes
ThegetImageFitClassForRotation function should return:
object-coverfor 0° and 180° (even rotations)object-containfor 90° and 270° (odd rotations)
Drag & Drop Setup
This component requires@dnd-kit setup:
Keyboard Accessibility
All buttons support keyboard interaction:Enterkey to activateSpacekey to activatetabIndex={0}on all buttons- Descriptive
aria-labelattributes
Aria Labels
- Delete: “Marcar para eliminar” / “Desmarcar para eliminar”
- Main: “Imagen principal (posición 1)” / “Mover a posición 1 (imagen principal)”
- Rotate: “Rotar imagen”
Image URL Normalization
UsesnormalizeImageUrl utility from ../utils to handle:
- Relative URLs
- Absolute URLs
- CDN URLs
- Local development URLs
Dependencies
@dnd-kit/sortable- Drag and drop functionality@dnd-kit/utilities- CSS transform utilitieslucide-react- Icons (X, Star, RotateCw, GripVertical)../utils- Image URL normalization
Integration Notes
With Form State
The component is stateless and relies on parent state management:- Parent manages order
- Parent tracks deletions
- Parent stores rotations
- Parent handles main image selection
With Backend
Typical workflow:- Load images from API with metadata
- User makes changes (reorder, rotate, delete, set main)
- Track changes in parent state
- On submit, send updated metadata to API
- API processes deletions, rotations, and new order
Source Code
View the full implementation atsrc/components/DraggableImageItem.tsx:1