react-grid-layout
Version:
A draggable and resizable grid layout with responsive breakpoints, for React.
359 lines (349 loc) • 12.8 kB
text/typescript
import React__default, { ReactElement, CSSProperties, RefObject } from 'react';
import { k as PositionStrategy, D as DroppingPosition, d as ResizeHandleAxis, f as LayoutConstraint, a as LayoutItem, L as Layout, G as GridDragEvent, e as GridResizeEvent, c as Compactor, B as Breakpoint, b as Breakpoints, R as ResponsiveLayouts } from './types-BiXsdXr7.mjs';
export { C as CompactType, P as Position } from './types-BiXsdXr7.mjs';
export { E as EventCallback, G as GridLayout, a as GridLayoutProps, R as ResponsiveGridLayout, b as ResponsiveGridLayoutProps } from './ResponsiveGridLayout-DqK__izz.mjs';
export { b as bottom, c as cloneLayout, a as cloneLayoutItem, d as getCompactor, g as getLayoutItem, h as horizontalCompactor, n as noCompactor, f as setTopLeft, s as setTransform, e as verticalCompactor } from './position-CetgOHhD.mjs';
export { c as calcGridItemPosition, b as calcWH, a as calcXY } from './calculate-FbCWy8x1.mjs';
/**
* GridItem component
*
* An individual item within a grid layout. Handles dragging and resizing.
*/
type GridItemCallback<Data extends GridDragEvent | GridResizeEvent> = (i: string, w: number, h: number, data: Data) => void;
type ResizeHandle = ReactElement | ((resizeHandleAxis: ResizeHandleAxis, ref: React__default.Ref<HTMLElement>) => ReactElement);
interface GridItemProps {
/** Child element to render */
children: ReactElement;
/** Number of columns in the grid */
cols: number;
/** Width of the container in pixels */
containerWidth: number;
/** Margin between items [x, y] */
margin: readonly [number, number];
/** Padding inside the container [x, y] */
containerPadding: readonly [number, number];
/** Height of each row in pixels */
rowHeight: number;
/** Maximum number of rows */
maxRows: number;
/** Whether the item can be dragged */
isDraggable: boolean;
/** Whether the item can be resized */
isResizable: boolean;
/** Whether the item is bounded within the container */
isBounded: boolean;
/** Whether the item is static (can't be moved/resized) */
static?: boolean;
/** Use CSS transforms instead of top/left */
useCSSTransforms?: boolean;
/** Use percentage widths for server rendering */
usePercentages?: boolean;
/** Scale factor for transforms */
transformScale?: number;
/** Position strategy for custom positioning (#2217) */
positionStrategy?: PositionStrategy;
/** Drag threshold in pixels before drag starts (#2217) */
dragThreshold?: number;
/** Current position of a dropping element */
droppingPosition?: DroppingPosition;
/** Additional class name */
className?: string;
/** Additional styles */
style?: CSSProperties;
/** CSS selector for draggable handle */
handle?: string;
/** CSS selector for cancel handle */
cancel?: string;
/** X position in grid units */
x: number;
/** Y position in grid units */
y: number;
/** Width in grid units */
w: number;
/** Height in grid units */
h: number;
/** Minimum width in grid units */
minW?: number;
/** Maximum width in grid units */
maxW?: number;
/** Minimum height in grid units */
minH?: number;
/** Maximum height in grid units */
maxH?: number;
/** Unique identifier */
i: string;
/** Which resize handles to show */
resizeHandles?: ResizeHandleAxis[];
/** Custom resize handle */
resizeHandle?: ResizeHandle;
/** Layout constraints for position/size limiting */
constraints?: LayoutConstraint[];
/** The layout item data (for per-item constraints) */
layoutItem?: LayoutItem;
/** Current layout (for constraint context) */
layout?: Layout;
/** Called when drag starts */
onDragStart?: GridItemCallback<GridDragEvent>;
/** Called during drag */
onDrag?: GridItemCallback<GridDragEvent>;
/** Called when drag stops */
onDragStop?: GridItemCallback<GridDragEvent>;
/** Called when resize starts */
onResizeStart?: GridItemCallback<GridResizeEvent>;
/** Called during resize */
onResize?: GridItemCallback<GridResizeEvent>;
/** Called when resize stops */
onResizeStop?: GridItemCallback<GridResizeEvent>;
}
/**
* GridItem - An individual item within a grid layout.
*
* Wraps a child element with drag and resize functionality.
*/
declare function GridItem(props: GridItemProps): ReactElement;
/**
* useContainerWidth hook
*
* Observes container width using ResizeObserver and provides
* reactive width updates for responsive layouts.
*/
interface UseContainerWidthOptions {
/**
* If true, delays initial render until width is measured.
* Useful for SSR or when you need accurate initial measurements.
*/
measureBeforeMount?: boolean;
/**
* Initial width to use before measurement.
* Defaults to 1280.
*/
initialWidth?: number;
}
interface UseContainerWidthResult {
/**
* Current container width in pixels.
*/
width: number;
/**
* Whether the container has been measured at least once.
*/
mounted: boolean;
/**
* Ref to attach to the container element.
*/
containerRef: RefObject<HTMLDivElement | null>;
/**
* Manually trigger a width measurement.
* Useful when the container size might change without a resize event.
*/
measureWidth: () => void;
}
/**
* Hook to observe and track container width.
*
* Replaces the WidthProvider HOC with a more composable approach.
*
* @example
* ```tsx
* function MyGrid() {
* const { width, containerRef, mounted } = useContainerWidth();
*
* return (
* <div ref={containerRef}>
* {mounted && <GridLayout width={width} {...props} />}
* </div>
* );
* }
* ```
*/
declare function useContainerWidth(options?: UseContainerWidthOptions): UseContainerWidthResult;
/**
* useGridLayout hook
*
* Core hook for managing grid layout state, including drag, resize, and drop operations.
* This extracts the state management logic from ReactGridLayout into a reusable hook.
*/
interface DragState {
/** Currently dragging item placeholder */
activeDrag: LayoutItem | null;
/** Original item before drag started */
oldDragItem: LayoutItem | null;
/** Layout before drag started */
oldLayout: Layout | null;
}
interface ResizeState {
/** Whether a resize is in progress */
resizing: boolean;
/** Original item before resize started */
oldResizeItem: LayoutItem | null;
/** Layout before resize started */
oldLayout: Layout | null;
}
interface DropState {
/** DOM node for the dropping placeholder */
droppingDOMNode: React.ReactElement | null;
/** Current drop position */
droppingPosition: DroppingPosition | null;
}
interface UseGridLayoutOptions {
/** Initial layout */
layout: Layout;
/** Number of columns */
cols: number;
/** Prevent collisions when moving items */
preventCollision?: boolean;
/** Called when layout changes */
onLayoutChange?: (layout: Layout) => void;
/** Compactor for layout compaction (default: verticalCompactor) */
compactor?: Compactor;
}
interface UseGridLayoutResult {
/** Current layout */
layout: Layout;
/** Set layout directly */
setLayout: (layout: Layout) => void;
/** Drag state */
dragState: DragState;
/** Resize state */
resizeState: ResizeState;
/** Drop state */
dropState: DropState;
/** Start dragging an item */
onDragStart: (itemId: string, x: number, y: number) => LayoutItem | null;
/** Update drag position */
onDrag: (itemId: string, x: number, y: number) => void;
/** Stop dragging */
onDragStop: (itemId: string, x: number, y: number) => void;
/** Start resizing an item */
onResizeStart: (itemId: string) => LayoutItem | null;
/** Update resize dimensions */
onResize: (itemId: string, w: number, h: number, x?: number, y?: number) => void;
/** Stop resizing */
onResizeStop: (itemId: string, w: number, h: number) => void;
/** Start dropping (external drag-in) */
onDropDragOver: (droppingItem: LayoutItem, position: DroppingPosition) => void;
/** Update drop position */
onDropDragLeave: () => void;
/** Complete drop */
onDrop: (droppingItem: LayoutItem) => void;
/** Container height in rows */
containerHeight: number;
/** Whether any drag/resize is active */
isInteracting: boolean;
/** Get the compactor being used */
compactor: Compactor;
}
/**
* Hook for managing grid layout state.
*
* Handles all layout state including drag, resize, and drop operations.
* Uses immutable updates and provides callbacks for all interactions.
*
* @example
* ```tsx
* function MyGrid() {
* const {
* layout,
* onDragStart,
* onDrag,
* onDragStop,
* containerHeight
* } = useGridLayout({
* layout: initialLayout,
* cols: 12
* });
*
* return (
* <div style={{ height: containerHeight }}>
* {layout.map(item => (
* <GridItem
* key={item.i}
* {...item}
* onDragStart={() => onDragStart(item.i, item.x, item.y)}
* />
* ))}
* </div>
* );
* }
* ```
*/
declare function useGridLayout(options: UseGridLayoutOptions): UseGridLayoutResult;
/**
* useResponsiveLayout hook
*
* Manages responsive breakpoints and layout generation for different screen sizes.
* Extracts state management from ResponsiveReactGridLayout into a reusable hook.
*/
/** Default breakpoint names */
type DefaultBreakpoints = "lg" | "md" | "sm" | "xs" | "xxs";
/** Default breakpoint widths */
declare const DEFAULT_BREAKPOINTS: Breakpoints<DefaultBreakpoints>;
/** Default column counts per breakpoint */
declare const DEFAULT_COLS: Breakpoints<DefaultBreakpoints>;
interface UseResponsiveLayoutOptions<B extends Breakpoint = DefaultBreakpoints> {
/** Current container width */
width: number;
/** Breakpoint definitions (name → min-width) */
breakpoints?: Breakpoints<B>;
/** Column counts per breakpoint */
cols?: Breakpoints<B>;
/** Layouts for each breakpoint */
layouts?: ResponsiveLayouts<B>;
/** Compactor for layout compaction (default: verticalCompactor) */
compactor?: Compactor;
/** Called when breakpoint changes */
onBreakpointChange?: (newBreakpoint: B, cols: number) => void;
/** Called when layout changes */
onLayoutChange?: (layout: Layout, layouts: ResponsiveLayouts<B>) => void;
/** Called when width changes */
onWidthChange?: (width: number, margin: readonly [number, number], cols: number, containerPadding: readonly [number, number] | null) => void;
}
interface UseResponsiveLayoutResult<B extends Breakpoint = DefaultBreakpoints> {
/** Current layout for the active breakpoint */
layout: Layout;
/** All layouts by breakpoint */
layouts: ResponsiveLayouts<B>;
/** Current active breakpoint */
breakpoint: B;
/** Column count for the current breakpoint */
cols: number;
/** Update layouts for a specific breakpoint */
setLayoutForBreakpoint: (breakpoint: B, layout: Layout) => void;
/** Update all layouts */
setLayouts: (layouts: ResponsiveLayouts<B>) => void;
/** Sorted array of breakpoint names (smallest to largest) */
sortedBreakpoints: B[];
}
/**
* Hook for managing responsive grid layouts.
*
* Automatically selects the appropriate layout based on container width
* and generates layouts for new breakpoints from existing ones.
*
* @example
* ```tsx
* function MyResponsiveGrid() {
* const { width, containerRef } = useContainerWidth();
* const { layout, breakpoint, cols } = useResponsiveLayout({
* width,
* layouts: {
* lg: [...],
* md: [...],
* sm: [...]
* }
* });
*
* return (
* <div ref={containerRef}>
* <GridLayout
* width={width}
* cols={cols}
* layout={layout}
* />
* </div>
* );
* }
* ```
*/
declare function useResponsiveLayout<B extends Breakpoint = DefaultBreakpoints>(options: UseResponsiveLayoutOptions<B>): UseResponsiveLayoutResult<B>;
export { Breakpoint, Breakpoints, Compactor, DEFAULT_BREAKPOINTS, DEFAULT_COLS, type DefaultBreakpoints, type DragState, type DropState, DroppingPosition, GridDragEvent, GridItem, type GridItemCallback, type GridItemProps, GridResizeEvent, Layout, LayoutItem, type ResizeHandle, ResizeHandleAxis, type ResizeState, ResponsiveLayouts, type UseContainerWidthOptions, type UseContainerWidthResult, type UseGridLayoutOptions, type UseGridLayoutResult, type UseResponsiveLayoutOptions, type UseResponsiveLayoutResult, useContainerWidth, useGridLayout, useResponsiveLayout };