A responsive image cropping tool for React with no dependencies.
—
TypeScript interfaces and type definitions for crop coordinates, dimensions, and drag handle ordinates used throughout the react-image-crop library.
Basic interfaces defining crop coordinates and dimensions in both pixel and percentage units.
/**
* Base crop interface defining position, size, and coordinate units
*/
interface Crop {
/** X coordinate of crop's top-left corner */
x: number;
/** Y coordinate of crop's top-left corner */
y: number;
/** Width of the crop selection */
width: number;
/** Height of the crop selection */
height: number;
/** Coordinate unit system: pixels or percentage */
unit: 'px' | '%';
}
/**
* Crop with pixel-based coordinates
* Used for precise positioning and sizing
*/
interface PixelCrop extends Crop {
unit: 'px';
}
/**
* Crop with percentage-based coordinates
* Used for responsive layouts and relative positioning
*/
interface PercentCrop extends Crop {
unit: '%';
}Usage Examples:
import { Crop, PixelCrop, PercentCrop } from "react-image-crop";
// Pixel-based crop (absolute positioning)
const pixelCrop: PixelCrop = {
unit: 'px',
x: 100,
y: 50,
width: 200,
height: 150,
};
// Percentage-based crop (relative positioning)
const percentCrop: PercentCrop = {
unit: '%',
x: 25, // 25% from left
y: 12.5, // 12.5% from top
width: 50, // 50% of container width
height: 37.5, // 37.5% of container height
};
// Generic crop (can be either unit type)
const genericCrop: Crop = {
unit: '%',
x: 10,
y: 10,
width: 80,
height: 80,
};Type definitions for drag handle positions used in crop manipulation and keyboard navigation.
/**
* X-axis drag handle positions (east/west)
*/
type XOrds = 'e' | 'w';
/**
* Y-axis drag handle positions (north/south)
*/
type YOrds = 'n' | 's';
/**
* Corner drag handle positions (diagonal)
*/
type XYOrds = 'nw' | 'ne' | 'se' | 'sw';
/**
* All possible drag handle positions
* Used for resize operations and keyboard navigation
*/
type Ords = XOrds | YOrds | XYOrds;Ordinate Meanings:
'n' - North (top edge)'s' - South (bottom edge)'e' - East (right edge)'w' - West (left edge)'nw' - Northwest (top-left corner)'ne' - Northeast (top-right corner)'se' - Southeast (bottom-right corner)'sw' - Southwest (bottom-left corner)Usage in Drag Operations:
import { Ords } from "react-image-crop";
// Handle type is automatically inferred based on which drag handle is used
function handleDragStart(ord: Ords) {
switch (ord) {
case 'nw':
console.log('Dragging top-left corner');
break;
case 'n':
console.log('Dragging top edge');
break;
case 'ne':
console.log('Dragging top-right corner');
break;
// ... other cases
}
}Helper functions for working with crop types and ensuring type safety.
/**
* Default pixel crop with zero dimensions
* Useful as a starting point for new crops
*/
const defaultCrop: PixelCrop;
/**
* Utility function to compare crop objects for equality
* Handles partial crop objects safely
*/
function areCropsEqual(cropA: Partial<Crop>, cropB: Partial<Crop>): boolean;Type Guard Usage:
import { Crop, PixelCrop, PercentCrop, defaultCrop, areCropsEqual } from "react-image-crop";
// Type checking
function isPixelCrop(crop: Crop): crop is PixelCrop {
return crop.unit === 'px';
}
function isPercentCrop(crop: Crop): crop is PercentCrop {
return crop.unit === '%';
}
// Using default crop
const newCrop: PixelCrop = { ...defaultCrop, width: 100, height: 100 };
// Comparing crops
const crop1: Crop = { unit: 'px', x: 10, y: 10, width: 50, height: 50 };
const crop2: Crop = { unit: 'px', x: 10, y: 10, width: 50, height: 50 };
if (areCropsEqual(crop1, crop2)) {
console.log('Crops are identical');
}Interfaces defining the internal state of the ReactCrop component.
/**
* Internal state interface for ReactCrop component
* Tracks current interaction state
*/
interface ReactCropState {
/** Whether crop is currently being manipulated (dragging/resizing) */
cropIsActive: boolean;
/** Whether user is in the process of drawing a new crop selection */
newCropIsBeingDrawn: boolean;
}
/**
* Accessibility labels interface for screen readers
* Provides custom labels for crop area and drag handles
*/
interface AriaLabels {
/** Label for the main crop selection area */
cropArea: string;
/** Label for northwest (top-left) drag handle */
nwDragHandle: string;
/** Label for north (top) drag handle */
nDragHandle: string;
/** Label for northeast (top-right) drag handle */
neDragHandle: string;
/** Label for east (right) drag handle */
eDragHandle: string;
/** Label for southeast (bottom-right) drag handle */
seDragHandle: string;
/** Label for south (bottom) drag handle */
sDragHandle: string;
/** Label for southwest (bottom-left) drag handle */
swDragHandle: string;
/** Label for west (left) drag handle */
wDragHandle: string;
}Common patterns for working with crop types in TypeScript applications.
Partial Crops:
import { Crop, PixelCrop } from "react-image-crop";
// Partial crop for initialization
const partialCrop: Partial<Crop> = {
unit: '%',
width: 50,
height: 50,
// x and y will be calculated by utility functions
};
// Creating crops with required and optional properties
function createCrop(required: Pick<Crop, 'unit'>, optional?: Partial<Omit<Crop, 'unit'>>): Crop {
return {
x: 0,
y: 0,
width: 0,
height: 0,
...optional,
unit: required.unit,
};
}Generic Crop Functions:
import { Crop, PixelCrop, PercentCrop } from "react-image-crop";
// Function that preserves crop unit type
function scaleCrop<T extends Crop>(crop: T, scaleFactor: number): T {
return {
...crop,
x: crop.x * scaleFactor,
y: crop.y * scaleFactor,
width: crop.width * scaleFactor,
height: crop.height * scaleFactor,
};
}
// Usage maintains type safety
const pixelCrop: PixelCrop = { unit: 'px', x: 10, y: 10, width: 100, height: 100 };
const scaledPixelCrop: PixelCrop = scaleCrop(pixelCrop, 2); // Still PixelCrop
const percentCrop: PercentCrop = { unit: '%', x: 10, y: 10, width: 50, height: 50 };
const scaledPercentCrop: PercentCrop = scaleCrop(percentCrop, 1.5); // Still PercentCropInstall with Tessl CLI
npx tessl i tessl/npm-react-image-crop