[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-3696":3},{"id":4,"name":5,"fullName":6,"owner":5,"repo":5,"description":7,"homepage":8,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":15,"forks30d":15,"starsTrendScore":19,"compositeScore":20,"rankGlobal":9,"rankLanguage":9,"license":21,"archived":22,"fork":22,"defaultBranch":23,"hasWiki":24,"hasPages":24,"topics":25,"createdAt":9,"pushedAt":9,"updatedAt":32,"readmeContent":33,"aiSummary":34,"trendingCount":15,"starSnapshotCount":15,"syncStatus":35,"lastSyncTime":36,"discoverSource":37},3696,"react-grid-layout","react-grid-layout\u002Freact-grid-layout","A draggable and resizable grid layout with responsive breakpoints, for React.","https:\u002F\u002Freact-grid-layout.github.io\u002Freact-grid-layout\u002Fexamples\u002F00-showcase.html",null,"TypeScript",22307,2710,227,51,0,1,19,67,9,45,"MIT License",false,"master",true,[26,27,28,29,30,31],"drag-and-drop","es2015","grid","javascript","react","resize","2026-06-12 02:00:52","# React-Grid-Layout\n\n[![npm package](https:\u002F\u002Fimg.shields.io\u002Fnpm\u002Fv\u002Freact-grid-layout.svg?style=flat-square)](https:\u002F\u002Fwww.npmjs.org\u002Fpackage\u002Freact-grid-layout)\n[![npm downloads](https:\u002F\u002Fimg.shields.io\u002Fnpm\u002Fdt\u002Freact-grid-layout.svg?maxAge=2592000)]()\n\nReact-Grid-Layout is a grid layout system much like [Packery](http:\u002F\u002Fpackery.metafizzy.co\u002F) or\n[Gridster](http:\u002F\u002Fdsmorse.github.io\u002Fgridster.js\u002F), for React.\n\nUnlike those systems, it is responsive and supports breakpoints. Breakpoint layouts can be provided by the user\nor autogenerated.\n\nRGL is React-only and does not require jQuery.\n\n![BitMEX UI](http:\u002F\u002Fi.imgur.com\u002Foo1NT6c.gif)\n\n> GIF from production usage on [BitMEX.com](https:\u002F\u002Fwww.bitmex.com)\n\n[**[Demo](https:\u002F\u002Freact-grid-layout.github.io\u002Freact-grid-layout\u002F) | [Changelog](\u002FCHANGELOG.md) | [CodeSandbox Editable demo](https:\u002F\u002Fcodesandbox.io\u002Fp\u002Fsandbox\u002F5ywf7c)**]\n\n## Table of Contents\n\n- [What's New in v2](#whats-new-in-v2)\n- [Migrating from v1](#migrating-from-v1)\n- [Demos](#demos)\n- [Features](#features)\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Responsive Usage](#responsive-usage)\n- [Providing Grid Width](#providing-grid-width)\n- [Hooks API](#hooks-api)\n- [API Reference](#api-reference)\n- [Extending: Custom Compactors & Position Strategies](#extending-custom-compactors--position-strategies)\n- [Extras](#extras)\n- [Performance](#performance)\n- [Contribute](#contribute)\n\n## What's New in v2\n\nVersion 2 is a complete TypeScript rewrite with a modernized API:\n\n- **Full TypeScript support** - First-class types, no more `@types\u002Freact-grid-layout`\n- **React Hooks** - New `useContainerWidth`, `useGridLayout`, and `useResponsiveLayout` hooks\n- **Composable Configuration** - Group related props into focused interfaces:\n  - `gridConfig` - cols, rowHeight, margin, padding\n  - `dragConfig` - enable, handle, cancel, bounded\n  - `resizeConfig` - enable, handles\n  - `positionStrategy` - transform vs absolute positioning\n  - `compactor` - vertical, horizontal, or custom algorithms\n- **Modular architecture** - Import only what you need:\n  - `react-grid-layout` - React components and hooks (v2 API)\n  - `react-grid-layout\u002Fcore` - Pure layout algorithms (framework-agnostic)\n  - `react-grid-layout\u002Flegacy` - v1 flat props API for migration\n  - `react-grid-layout\u002Fextras` - Optional components like `GridBackground`\n- **Smaller bundle** - Tree-shakeable ESM and CJS builds\n\n### Breaking Changes\n\nSee the [RFC](.\u002Frfcs\u002F0001-v2-typescript-rewrite.md#breaking-changes-in-v2) for detailed migration examples.\n\n| Change                                                                                                               | Description                                                                                            |\n| -------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |\n| [`width` prop required](.\u002Frfcs\u002F0001-v2-typescript-rewrite.md#breaking-changes-in-v2)                                 | Use `useContainerWidth` hook or provide your own measurement                                           |\n| [`onDragStart` threshold](.\u002Frfcs\u002F0001-v2-typescript-rewrite.md#1-ondragstart-no-longer-fires-on-click-only-events)   | Now fires after 3px movement, not on mousedown. Use `onMouseDown` for immediate response               |\n| [Immutable callbacks](.\u002Frfcs\u002F0001-v2-typescript-rewrite.md#2-immutable-callback-parameters)                          | Callback parameters are read-only. Use `onLayoutChange` or constraints instead of mutation             |\n| [`data-grid` in legacy only](.\u002Frfcs\u002F0001-v2-typescript-rewrite.md#3-data-grid-prop-only-available-in-legacy-wrapper) | v2 requires explicit `layout` prop. Use legacy wrapper for `data-grid`                                 |\n| [Pluggable compaction](.\u002Frfcs\u002F0001-v2-typescript-rewrite.md#4-pluggable-compaction-algorithms)                       | Compaction is now pluggable via `Compactor` interface. Optional fast O(n log n) algorithm in `\u002Fextras` |\n| UMD bundle removed                                                                                                   | Use a bundler (Vite, webpack, esbuild)                                                                 |\n| `verticalCompact` removed                                                                                            | Use `compactType={null}` or `compactor={noCompactor}`                                                  |\n\n## Migrating from v1\n\n**Quick migration** - change your import to use the legacy wrapper:\n\n```diff\n- import GridLayout, { Responsive, WidthProvider } from 'react-grid-layout';\n+ import GridLayout, { Responsive, WidthProvider } from 'react-grid-layout\u002Flegacy';\n```\n\nThis provides **100% runtime API compatibility** with v1.\n\n**TypeScript users**: If you were using `@types\u002Freact-grid-layout`, note that v2 includes its own types with some naming changes:\n\n| Old (`@types\u002Freact-grid-layout`) | New (v2)            | Notes                   |\n| -------------------------------- | ------------------- | ----------------------- |\n| `RGL.Layout`                     | `LayoutItem`        | Single grid item        |\n| `RGL.Layout[]`                   | `Layout`            | Array of items          |\n| `RGL.Layouts`                    | `ResponsiveLayouts` | Breakpoint → layout map |\n\n```diff\n- import RGL from 'react-grid-layout';\n- const item: RGL.Layout = { i: 'a', x: 0, y: 0, w: 1, h: 1 };\n- const layouts: RGL.Layouts = { lg: [item] };\n+ import { LayoutItem, ResponsiveLayouts } from 'react-grid-layout\u002Flegacy';\n+ const item: LayoutItem = { i: 'a', x: 0, y: 0, w: 1, h: 1 };\n+ const layouts: ResponsiveLayouts = { lg: [item] };\n```\n\n**Full migration** - adopt the v2 API for new features and better tree-shaking:\n\n```typescript\nimport ReactGridLayout, { useContainerWidth, verticalCompactor } from 'react-grid-layout';\n\nfunction MyGrid() {\n  const { width, containerRef, mounted } = useContainerWidth();\n\n  return (\n    \u003Cdiv ref={containerRef}>\n      {mounted && (\n        \u003CReactGridLayout\n          width={width}\n          layout={layout}\n          gridConfig={{ cols: 12, rowHeight: 30 }}\n          dragConfig={{ enabled: true, handle: '.handle' }}\n          compactor={verticalCompactor}\n        >\n          {children}\n        \u003C\u002FReactGridLayout>\n      )}\n    \u003C\u002Fdiv>\n  );\n}\n```\n\n| Use Case             | Recommendation                     |\n| -------------------- | ---------------------------------- |\n| Existing v1 codebase | `react-grid-layout\u002Flegacy`         |\n| New project          | v2 API with hooks                  |\n| Custom compaction    | v2 with custom `Compactor`         |\n| SSR                  | v2 with `measureBeforeMount: true` |\n\n## Demos\n\n1. [Showcase](https:\u002F\u002Freact-grid-layout.github.io\u002Freact-grid-layout\u002Fexamples\u002F00-showcase.html)\n1. [Basic](https:\u002F\u002Freact-grid-layout.github.io\u002Freact-grid-layout\u002Fexamples\u002F01-basic.html)\n1. [No Dragging\u002FResizing (Layout Only)](https:\u002F\u002Freact-grid-layout.github.io\u002Freact-grid-layout\u002Fexamples\u002F02-no-dragging.html)\n1. [Messy Layout Autocorrect](https:\u002F\u002Freact-grid-layout.github.io\u002Freact-grid-layout\u002Fexamples\u002F03-messy.html)\n1. [Layout Defined on Children](https:\u002F\u002Freact-grid-layout.github.io\u002Freact-grid-layout\u002Fexamples\u002F04-grid-property.html)\n1. [Static Elements](https:\u002F\u002Freact-grid-layout.github.io\u002Freact-grid-layout\u002Fexamples\u002F05-static-elements.html)\n1. [Adding\u002FRemoving Elements](https:\u002F\u002Freact-grid-layout.github.io\u002Freact-grid-layout\u002Fexamples\u002F06-dynamic-add-remove.html)\n1. [Saving Layout to LocalStorage](https:\u002F\u002Freact-grid-layout.github.io\u002Freact-grid-layout\u002Fexamples\u002F07-localstorage.html)\n1. [Saving a Responsive Layout to LocalStorage](https:\u002F\u002Freact-grid-layout.github.io\u002Freact-grid-layout\u002Fexamples\u002F08-localstorage-responsive.html)\n1. [Minimum and Maximum Width\u002FHeight](https:\u002F\u002Freact-grid-layout.github.io\u002Freact-grid-layout\u002Fexamples\u002F09-min-max-wh.html)\n1. [Dynamic Minimum and Maximum Width\u002FHeight](https:\u002F\u002Freact-grid-layout.github.io\u002Freact-grid-layout\u002Fexamples\u002F10-dynamic-min-max-wh.html)\n1. [Toolbox](https:\u002F\u002Freact-grid-layout.github.io\u002Freact-grid-layout\u002Fexamples\u002F11-toolbox.html)\n1. [Drag From Outside](https:\u002F\u002Freact-grid-layout.github.io\u002Freact-grid-layout\u002Fexamples\u002F12-drag-from-outside.html)\n1. [Bounded Layout](https:\u002F\u002Freact-grid-layout.github.io\u002Freact-grid-layout\u002Fexamples\u002F13-bounded.html)\n1. [Responsive Bootstrap-style Layout](https:\u002F\u002Freact-grid-layout.github.io\u002Freact-grid-layout\u002Fexamples\u002F14-responsive-bootstrap-style.html)\n1. [Scaled Containers](https:\u002F\u002Freact-grid-layout.github.io\u002Freact-grid-layout\u002Fexamples\u002F15-scale.html)\n1. [Allow Overlap](https:\u002F\u002Freact-grid-layout.github.io\u002Freact-grid-layout\u002Fexamples\u002F16-allow-overlap.html)\n1. [All Resizable Handles](https:\u002F\u002Freact-grid-layout.github.io\u002Freact-grid-layout\u002Fexamples\u002F17-resizable-handles.html)\n1. [Compactor Showcase](https:\u002F\u002Freact-grid-layout.github.io\u002Freact-grid-layout\u002Fexamples\u002F18-compactors.html)\n1. [Pluggable Constraints](https:\u002F\u002Freact-grid-layout.github.io\u002Freact-grid-layout\u002Fexamples\u002F19-constraints.html)\n1. [Aspect Ratio Constraints](https:\u002F\u002Freact-grid-layout.github.io\u002Freact-grid-layout\u002Fexamples\u002F20-aspect-ratio.html)\n1. [Custom Constraints](https:\u002F\u002Freact-grid-layout.github.io\u002Freact-grid-layout\u002Fexamples\u002F21-custom-constraints.html)\n\n#### Projects Using React-Grid-Layout\n\n- [Basedash](https:\u002F\u002Fwww.basedash.com)\n- [BitMEX](https:\u002F\u002Fwww.bitmex.com\u002F)\n- [AWS CloudFront Dashboards](https:\u002F\u002Faws.amazon.com\u002Fblogs\u002Faws\u002Fcloudwatch-dashboards-create-use-customized-metrics-views\u002F)\n- [Grafana](https:\u002F\u002Fgrafana.com\u002F)\n- [Metabase](http:\u002F\u002Fwww.metabase.com\u002F)\n- [HubSpot](http:\u002F\u002Fwww.hubspot.com)\n- [Kibana](https:\u002F\u002Fwww.elastic.co\u002Fproducts\u002Fkibana)\n- [Monday](https:\u002F\u002Fsupport.monday.com\u002Fhc\u002Fen-us\u002Farticles\u002F360002187819-What-are-the-Dashboards-)\n\n_Know of others? Create a PR to let me know!_\n\n## Features\n\n- 100% React - no jQuery\n- Full TypeScript support\n- Compatible with server-rendered apps\n- Draggable widgets\n- Resizable widgets\n- Static widgets\n- Configurable packing: horizontal, vertical, or off\n- Bounds checking for dragging and resizing\n- Widgets may be added or removed without rebuilding grid\n- Layout can be serialized and restored\n- Responsive breakpoints\n- Separate layouts per responsive breakpoint\n- Grid Items placed using CSS Transforms\n- Compatibility with `\u003CReact.StrictMode>`\n\n| Version   | Compatibility         |\n| --------- | --------------------- |\n| >= 2.0.0  | React 18+, TypeScript |\n| >= 0.17.0 | React 16 & 17         |\n\n## Installation\n\n```bash\nnpm install react-grid-layout\n```\n\nInclude the stylesheets in your application:\n\n```js\nimport \"react-grid-layout\u002Fcss\u002Fstyles.css\";\nimport \"react-resizable\u002Fcss\u002Fstyles.css\";\n```\n\nOr link them directly:\n\n```html\n\u003Clink rel=\"stylesheet\" href=\"\u002Fnode_modules\u002Freact-grid-layout\u002Fcss\u002Fstyles.css\" \u002F>\n\u003Clink rel=\"stylesheet\" href=\"\u002Fnode_modules\u002Freact-resizable\u002Fcss\u002Fstyles.css\" \u002F>\n```\n\n## Quick Start\n\n```tsx\nimport ReactGridLayout, { useContainerWidth } from \"react-grid-layout\";\nimport \"react-grid-layout\u002Fcss\u002Fstyles.css\";\nimport \"react-resizable\u002Fcss\u002Fstyles.css\";\n\nfunction MyGrid() {\n  const { width, containerRef, mounted } = useContainerWidth();\n\n  const layout = [\n    { i: \"a\", x: 0, y: 0, w: 1, h: 2, static: true },\n    { i: \"b\", x: 1, y: 0, w: 3, h: 2, minW: 2, maxW: 4 },\n    { i: \"c\", x: 4, y: 0, w: 1, h: 2 }\n  ];\n\n  return (\n    \u003Cdiv ref={containerRef}>\n      {mounted && (\n        \u003CReactGridLayout\n          layout={layout}\n          width={width}\n          gridConfig={{ cols: 12, rowHeight: 30 }}\n        >\n          \u003Cdiv key=\"a\">a\u003C\u002Fdiv>\n          \u003Cdiv key=\"b\">b\u003C\u002Fdiv>\n          \u003Cdiv key=\"c\">c\u003C\u002Fdiv>\n        \u003C\u002FReactGridLayout>\n      )}\n    \u003C\u002Fdiv>\n  );\n}\n```\n\nYou can also define layout on children using `data-grid`:\n\n```tsx\n\u003CReactGridLayout width={width} gridConfig={{ cols: 12, rowHeight: 30 }}>\n  \u003Cdiv key=\"a\" data-grid={{ x: 0, y: 0, w: 1, h: 2, static: true }}>\n    a\n  \u003C\u002Fdiv>\n  \u003Cdiv key=\"b\" data-grid={{ x: 1, y: 0, w: 3, h: 2 }}>\n    b\n  \u003C\u002Fdiv>\n  \u003Cdiv key=\"c\" data-grid={{ x: 4, y: 0, w: 1, h: 2 }}>\n    c\n  \u003C\u002Fdiv>\n\u003C\u002FReactGridLayout>\n```\n\n## Responsive Usage\n\nUse `Responsive` for automatic breakpoint handling:\n\n```tsx\nimport { Responsive, useContainerWidth } from \"react-grid-layout\";\n\nfunction MyResponsiveGrid() {\n  const { width, containerRef, mounted } = useContainerWidth();\n\n  const layouts = {\n    lg: [{ i: \"1\", x: 0, y: 0, w: 2, h: 2 }],\n    md: [{ i: \"1\", x: 0, y: 0, w: 2, h: 2 }]\n  };\n\n  return (\n    \u003Cdiv ref={containerRef}>\n      {mounted && (\n        \u003CResponsive\n          layouts={layouts}\n          breakpoints={{ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }}\n          cols={{ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }}\n          width={width}\n        >\n          \u003Cdiv key=\"1\">1\u003C\u002Fdiv>\n          \u003Cdiv key=\"2\">2\u003C\u002Fdiv>\n          \u003Cdiv key=\"3\">3\u003C\u002Fdiv>\n        \u003C\u002FResponsive>\n      )}\n    \u003C\u002Fdiv>\n  );\n}\n```\n\n## Providing Grid Width\n\nThe `width` prop is required. You have several options:\n\n### Option 1: useContainerWidth Hook (Recommended)\n\n```tsx\nimport ReactGridLayout, { useContainerWidth } from \"react-grid-layout\";\n\nfunction MyGrid() {\n  const { width, containerRef, mounted } = useContainerWidth();\n\n  return (\n    \u003Cdiv ref={containerRef}>\n      {mounted && \u003CReactGridLayout width={width}>...\u003C\u002FReactGridLayout>}\n    \u003C\u002Fdiv>\n  );\n}\n```\n\n### Option 2: Fixed Width\n\n```tsx\n\u003CReactGridLayout width={1200}>...\u003C\u002FReactGridLayout>\n```\n\n### Option 3: CSS Container Queries or ResizeObserver\n\nUse any width measurement library like [react-sizeme](https:\u002F\u002Fgithub.com\u002Fctrlplusb\u002Freact-sizeme) or your own ResizeObserver implementation.\n\n### Option 4: Legacy WidthProvider HOC\n\nFor backwards compatibility, you can still use `WidthProvider`:\n\n```tsx\nimport ReactGridLayout, { WidthProvider } from \"react-grid-layout\u002Flegacy\";\n\nconst GridLayoutWithWidth = WidthProvider(ReactGridLayout);\n\nfunction MyGrid() {\n  return \u003CGridLayoutWithWidth>...\u003C\u002FGridLayoutWithWidth>;\n}\n```\n\n## Hooks API\n\nThe v2 API provides three hooks for different use cases. Choose based on your needs:\n\n| Hook                  | Use When                                                             |\n| --------------------- | -------------------------------------------------------------------- |\n| `useContainerWidth`   | You need responsive width measurement (most common)                  |\n| `useGridLayout`       | You're building a custom grid component or need direct state control |\n| `useResponsiveLayout` | You're building a custom responsive grid with breakpoint logic       |\n\n### useContainerWidth\n\nObserves container width using ResizeObserver and provides reactive width updates. This is the recommended way to provide width to the grid.\n\n**Why use it instead of WidthProvider?**\n\n- Hooks are more composable and easier to test\n- No HOC wrapper means simpler component tree\n- Explicit control over when to render (via `mounted`)\n- Works better with SSR\n\n```tsx\nimport { useContainerWidth } from \"react-grid-layout\";\n\nfunction MyGrid() {\n  const { width, containerRef, mounted, measureWidth } = useContainerWidth({\n    measureBeforeMount: false, \u002F\u002F Set true for SSR\n    initialWidth: 1280 \u002F\u002F Width before first measurement\n  });\n\n  return (\n    \u003Cdiv ref={containerRef}>{mounted && \u003CReactGridLayout width={width} \u002F>}\u003C\u002Fdiv>\n  );\n}\n```\n\n**Type Definitions:**\n\n```ts\ninterface UseContainerWidthOptions {\n  \u002F** Delay render until width is measured. Useful for SSR. Default: false *\u002F\n  measureBeforeMount?: boolean;\n  \u002F** Initial width before measurement. Default: 1280 *\u002F\n  initialWidth?: number;\n}\n\ninterface UseContainerWidthResult {\n  \u002F** Current container width in pixels *\u002F\n  width: number;\n  \u002F** Whether the container has been measured at least once *\u002F\n  mounted: boolean;\n  \u002F** Ref to attach to the container element *\u002F\n  containerRef: RefObject\u003CHTMLDivElement | null>;\n  \u002F** Manually trigger a width measurement *\u002F\n  measureWidth: () => void;\n}\n```\n\n### useGridLayout\n\nCore layout state management hook. Use this when you need direct control over drag\u002Fresize\u002Fdrop state, or when building a custom grid component.\n\n**Why use it instead of the component?**\n\n- Full control over layout state and updates\n- Access to drag\u002Fresize\u002Fdrop state for custom UIs\n- Can integrate with external state management\n- Build headless grid implementations\n\n```tsx\nimport { useGridLayout, horizontalCompactor } from \"react-grid-layout\";\n\nfunction CustomGrid({ initialLayout }) {\n  const {\n    layout,\n    setLayout,\n    dragState,\n    resizeState,\n    onDragStart,\n    onDrag,\n    onDragStop,\n    onResizeStart,\n    onResize,\n    onResizeStop,\n    containerHeight,\n    isInteracting,\n    compactor\n  } = useGridLayout({\n    layout: initialLayout,\n    cols: 12,\n    compactor: horizontalCompactor, \u002F\u002F default is verticalCompactor\n    onLayoutChange: newLayout => console.log(\"Layout changed:\", newLayout)\n  });\n\n  \u002F\u002F Access drag state for custom placeholder rendering\n  const placeholder = dragState.activeDrag;\n\n  \u002F\u002F Check if any interaction is happening\n  if (isInteracting) {\n    \u002F\u002F Disable other UI during drag\u002Fresize\n  }\n\n  return (\n    \u003Cdiv style={{ height: containerHeight * rowHeight }}>\n      {layout.map(item => (\n        \u003Cdiv\n          key={item.i}\n          onMouseDown={() => onDragStart(item.i, item.x, item.y)}\n        >\n          {item.i}\n        \u003C\u002Fdiv>\n      ))}\n      {placeholder && \u003Cdiv className=\"placeholder\" \u002F>}\n    \u003C\u002Fdiv>\n  );\n}\n```\n\n**Type Definitions:**\n\n```ts\ninterface UseGridLayoutOptions {\n  \u002F** Initial layout *\u002F\n  layout: Layout;\n  \u002F** Number of columns *\u002F\n  cols: number;\n  \u002F** Block movement into occupied space instead of pushing items *\u002F\n  preventCollision?: boolean;\n  \u002F** Called when layout changes *\u002F\n  onLayoutChange?: (layout: Layout) => void;\n  \u002F** Compactor for layout compaction (default: verticalCompactor) *\u002F\n  compactor?: Compactor;\n}\n\ninterface UseGridLayoutResult {\n  \u002F** Current layout *\u002F\n  layout: Layout;\n  \u002F** Set layout directly *\u002F\n  setLayout: (layout: Layout) => void;\n  \u002F** Current drag state (activeDrag, oldDragItem, oldLayout) *\u002F\n  dragState: DragState;\n  \u002F** Current resize state (resizing, oldResizeItem, oldLayout) *\u002F\n  resizeState: ResizeState;\n  \u002F** Current drop state (droppingDOMNode, droppingPosition) *\u002F\n  dropState: DropState;\n  \u002F** Start dragging an item *\u002F\n  onDragStart: (itemId: string, x: number, y: number) => LayoutItem | null;\n  \u002F** Update drag position *\u002F\n  onDrag: (itemId: string, x: number, y: number) => void;\n  \u002F** Stop dragging *\u002F\n  onDragStop: (itemId: string, x: number, y: number) => void;\n  \u002F** Start resizing an item *\u002F\n  onResizeStart: (itemId: string) => LayoutItem | null;\n  \u002F** Update resize dimensions *\u002F\n  onResize: (\n    itemId: string,\n    w: number,\n    h: number,\n    x?: number,\n    y?: number\n  ) => void;\n  \u002F** Stop resizing *\u002F\n  onResizeStop: (itemId: string, w: number, h: number) => void;\n  \u002F** Handle external drag over *\u002F\n  onDropDragOver: (\n    droppingItem: LayoutItem,\n    position: DroppingPosition\n  ) => void;\n  \u002F** Handle external drag leave *\u002F\n  onDropDragLeave: () => void;\n  \u002F** Complete external drop *\u002F\n  onDrop: (droppingItem: LayoutItem) => void;\n  \u002F** Container height in grid rows *\u002F\n  containerHeight: number;\n  \u002F** Whether any drag\u002Fresize\u002Fdrop is active *\u002F\n  isInteracting: boolean;\n  \u002F** The compactor being used *\u002F\n  compactor: Compactor;\n}\n```\n\n### useResponsiveLayout\n\nManages responsive breakpoints and generates layouts for different screen sizes. Use this when building a custom responsive grid.\n\n**Why use it instead of the Responsive component?**\n\n- Direct access to current breakpoint\n- Control over layout generation for new breakpoints\n- Can update layouts for specific breakpoints\n- Build custom breakpoint UIs\n\n```tsx\nimport { useContainerWidth, useResponsiveLayout } from \"react-grid-layout\";\n\nfunction CustomResponsiveGrid() {\n  const { width, containerRef, mounted } = useContainerWidth();\n\n  const {\n    layout, \u002F\u002F Current layout for active breakpoint\n    layouts, \u002F\u002F All layouts by breakpoint\n    breakpoint, \u002F\u002F Current active breakpoint ('lg', 'md', etc.)\n    cols, \u002F\u002F Column count for current breakpoint\n    setLayoutForBreakpoint,\n    setLayouts,\n    sortedBreakpoints\n  } = useResponsiveLayout({\n    width,\n    breakpoints: { lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 },\n    cols: { lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 },\n    layouts: {\n      lg: [{ i: \"1\", x: 0, y: 0, w: 2, h: 2 }],\n      md: [{ i: \"1\", x: 0, y: 0, w: 3, h: 2 }]\n    },\n    \u002F\u002F compactor: verticalCompactor (default)\n    onBreakpointChange: (bp, cols) =>\n      console.log(`Now at ${bp} (${cols} cols)`),\n    onLayoutChange: (layout, allLayouts) => saveToServer(allLayouts)\n  });\n\n  \u002F\u002F Show current breakpoint in UI\n  return (\n    \u003Cdiv ref={containerRef}>\n      \u003Cdiv>\n        Current breakpoint: {breakpoint} ({cols} columns)\n      \u003C\u002Fdiv>\n      {mounted && (\n        \u003CGridLayout width={width} cols={cols} layout={layout}>\n          {\u002F* children *\u002F}\n        \u003C\u002FGridLayout>\n      )}\n    \u003C\u002Fdiv>\n  );\n}\n```\n\n**Type Definitions:**\n\n```ts\ninterface UseResponsiveLayoutOptions\u003CB extends string = DefaultBreakpoints> {\n  \u002F** Current container width *\u002F\n  width: number;\n  \u002F** Breakpoint definitions (name → min-width). Default: {lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0} *\u002F\n  breakpoints?: Record\u003CB, number>;\n  \u002F** Column counts per breakpoint. Default: {lg: 12, md: 10, sm: 6, xs: 4, xxs: 2} *\u002F\n  cols?: Record\u003CB, number>;\n  \u002F** Layouts for each breakpoint *\u002F\n  layouts?: Partial\u003CRecord\u003CB, Layout>>;\n  \u002F** Compactor for layout compaction (default: verticalCompactor) *\u002F\n  compactor?: Compactor;\n  \u002F** Called when breakpoint changes *\u002F\n  onBreakpointChange?: (newBreakpoint: B, cols: number) => void;\n  \u002F** Called when layout changes *\u002F\n  onLayoutChange?: (layout: Layout, layouts: Record\u003CB, Layout>) => void;\n  \u002F** Called when width changes *\u002F\n  onWidthChange?: (\n    width: number,\n    margin: [number, number],\n    cols: number,\n    padding: [number, number] | null\n  ) => void;\n}\n\ninterface UseResponsiveLayoutResult\u003CB extends string = DefaultBreakpoints> {\n  \u002F** Current layout for the active breakpoint *\u002F\n  layout: Layout;\n  \u002F** All layouts by breakpoint *\u002F\n  layouts: Partial\u003CRecord\u003CB, Layout>>;\n  \u002F** Current active breakpoint *\u002F\n  breakpoint: B;\n  \u002F** Column count for the current breakpoint *\u002F\n  cols: number;\n  \u002F** Update layout for a specific breakpoint *\u002F\n  setLayoutForBreakpoint: (breakpoint: B, layout: Layout) => void;\n  \u002F** Update all layouts *\u002F\n  setLayouts: (layouts: Partial\u003CRecord\u003CB, Layout>>) => void;\n  \u002F** Sorted array of breakpoint names (smallest to largest) *\u002F\n  sortedBreakpoints: B[];\n}\n\ntype DefaultBreakpoints = \"lg\" | \"md\" | \"sm\" | \"xs\" | \"xxs\";\n```\n\n## API Reference\n\n### ReactGridLayout Props\n\nThe v2 API uses composable configuration interfaces for cleaner prop organization:\n\n```ts\ninterface ReactGridLayoutProps {\n  \u002F\u002F Required\n  children: React.ReactNode;\n  width: number; \u002F\u002F Container width in pixels\n\n  \u002F\u002F Configuration interfaces (see below for details)\n  gridConfig?: Partial\u003CGridConfig>; \u002F\u002F Grid measurement settings\n  dragConfig?: Partial\u003CDragConfig>; \u002F\u002F Drag behavior settings\n  resizeConfig?: Partial\u003CResizeConfig>; \u002F\u002F Resize behavior settings\n  dropConfig?: Partial\u003CDropConfig>; \u002F\u002F External drop settings\n  positionStrategy?: PositionStrategy; \u002F\u002F CSS positioning strategy\n  compactor?: Compactor; \u002F\u002F Layout compaction strategy\n\n  \u002F\u002F Layout data\n  layout?: Layout; \u002F\u002F Layout definition\n  droppingItem?: LayoutItem; \u002F\u002F Item configuration when dropping from outside\n\n  \u002F\u002F Container\n  autoSize?: boolean; \u002F\u002F Auto-size container height (default: true)\n  className?: string;\n  style?: React.CSSProperties;\n  innerRef?: React.Ref\u003CHTMLDivElement>;\n\n  \u002F\u002F Callbacks\n  onLayoutChange?: (layout: Layout) => void;\n  onDragStart?: EventCallback;\n  onDrag?: EventCallback;\n  onDragStop?: EventCallback;\n  onResizeStart?: EventCallback;\n  onResize?: EventCallback;\n  onResizeStop?: EventCallback;\n  onDrop?: (layout: Layout, item: LayoutItem | undefined, e: Event) => void;\n  onDropDragOver?: (e: DragEvent) => { w?: number; h?: number } | false | void;\n}\n```\n\n### GridConfig\n\nGrid measurement configuration:\n\n```ts\ninterface GridConfig {\n  cols: number; \u002F\u002F Number of columns (default: 12)\n  rowHeight: number; \u002F\u002F Row height in pixels (default: 150)\n  margin: [number, number]; \u002F\u002F [x, y] margin between items (default: [10, 10])\n  containerPadding: [number, number] | null; \u002F\u002F Container padding (default: null, uses margin)\n  maxRows: number; \u002F\u002F Maximum rows (default: Infinity)\n}\n```\n\n### DragConfig\n\nDrag behavior configuration:\n\n```ts\ninterface DragConfig {\n  enabled: boolean; \u002F\u002F Enable dragging (default: true)\n  bounded: boolean; \u002F\u002F Keep items within container (default: false)\n  handle?: string; \u002F\u002F CSS selector for drag handle\n  cancel?: string; \u002F\u002F CSS selector to cancel dragging\n  threshold: number; \u002F\u002F Pixels to move before drag starts (default: 3)\n}\n```\n\n### ResizeConfig\n\nResize behavior configuration:\n\n```ts\ninterface ResizeConfig {\n  enabled: boolean; \u002F\u002F Enable resizing (default: true)\n  handles: ResizeHandleAxis[]; \u002F\u002F Handle positions (default: ['se'])\n  handleComponent?: React.ReactNode | ((axis, ref) => React.ReactNode);\n}\n```\n\n### DropConfig\n\nExternal drop configuration:\n\n```ts\ninterface DropConfig {\n  enabled: boolean; \u002F\u002F Allow external drops (default: false)\n  defaultItem: { w: number; h: number }; \u002F\u002F Default size (default: { w: 1, h: 1 })\n  onDragOver?: (e: DragEvent) => { w?: number; h?: number } | false | void;\n}\n```\n\n### PositionStrategy\n\nCSS positioning strategy. Built-in options:\n\n```ts\nimport {\n  transformStrategy, \u002F\u002F Default: use CSS transforms\n  absoluteStrategy, \u002F\u002F Use top\u002Fleft positioning\n  createScaledStrategy \u002F\u002F For scaled containers\n} from \"react-grid-layout\u002Fcore\";\n\n\u002F\u002F Example: scaled container\n\u003Cdiv style={{ transform: 'scale(0.5)' }}>\n  \u003CReactGridLayout positionStrategy={createScaledStrategy(0.5)} ... \u002F>\n\u003C\u002Fdiv>\n```\n\n### Compactor\n\nLayout compaction strategy. Built-in options:\n\n```ts\nimport {\n  verticalCompactor, \u002F\u002F Default: compact items upward\n  horizontalCompactor, \u002F\u002F Compact items leftward\n  noCompactor, \u002F\u002F No compaction (free positioning)\n  getCompactor \u002F\u002F Factory: getCompactor('vertical', allowOverlap, preventCollision)\n} from \"react-grid-layout\u002Fcore\";\n```\n\n### ResponsiveGridLayout Props\n\nExtends `GridLayoutProps` with responsive-specific props:\n\n```ts\ninterface ResponsiveGridLayoutProps\u003CB extends string = string> {\n  \u002F\u002F Responsive configuration\n  breakpoint?: B; \u002F\u002F Current breakpoint (auto-detected)\n  breakpoints?: Record\u003CB, number>; \u002F\u002F Breakpoint definitions (default: {lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0})\n  cols?: Record\u003CB, number>; \u002F\u002F Columns per breakpoint (default: {lg: 12, md: 10, sm: 6, xs: 4, xxs: 2})\n  layouts?: Record\u003CB, Layout>; \u002F\u002F Layouts per breakpoint\n\n  \u002F\u002F Can be fixed or per-breakpoint\n  margin?: [number, number] | Partial\u003CRecord\u003CB, [number, number]>>;\n  containerPadding?:\n    | [number, number]\n    | Partial\u003CRecord\u003CB, [number, number] | null>>\n    | null;\n\n  \u002F\u002F Callbacks\n  onBreakpointChange?: (newBreakpoint: B, cols: number) => void;\n  onLayoutChange?: (layout: Layout, layouts: Record\u003CB, Layout>) => void;\n  onWidthChange?: (\n    width: number,\n    margin: [number, number],\n    cols: number,\n    padding: [number, number] | null\n  ) => void;\n}\n```\n\n### Layout Item\n\n```ts\ninterface LayoutItem {\n  i: string; \u002F\u002F Unique identifier (must match child key)\n  x: number; \u002F\u002F X position in grid units\n  y: number; \u002F\u002F Y position in grid units\n  w: number; \u002F\u002F Width in grid units\n  h: number; \u002F\u002F Height in grid units\n  minW?: number; \u002F\u002F Minimum width (default: 0)\n  maxW?: number; \u002F\u002F Maximum width (default: Infinity)\n  minH?: number; \u002F\u002F Minimum height (default: 0)\n  maxH?: number; \u002F\u002F Maximum height (default: Infinity)\n  static?: boolean; \u002F\u002F If true, not draggable or resizable\n  isDraggable?: boolean; \u002F\u002F Override grid isDraggable\n  isResizable?: boolean; \u002F\u002F Override grid isResizable\n  isBounded?: boolean; \u002F\u002F Override grid isBounded\n  resizeHandles?: Array\u003C\"s\" | \"w\" | \"e\" | \"n\" | \"sw\" | \"nw\" | \"se\" | \"ne\">;\n}\n```\n\n### Core Utilities\n\nImport pure layout functions from `react-grid-layout\u002Fcore`:\n\n```ts\nimport {\n  verticalCompactor,\n  horizontalCompactor,\n  noCompactor,\n  getCompactor,\n  moveElement,\n  collides,\n  getFirstCollision,\n  validateLayout\n  \u002F\u002F ... and more\n} from \"react-grid-layout\u002Fcore\";\n```\n\n> **Note**: The `compact()` function is not exported. Use compactors instead: `verticalCompactor.compact(layout, cols)` or get one via `getCompactor('vertical')`.\n\n## Extending: Custom Compactors & Position Strategies\n\n### Creating a Custom Compactor\n\nCompactors control how items are arranged after drag\u002Fresize. Create your own for custom layouts like masonry, gravity, or shelf-packing.\n\n**The Compactor Interface:**\n\n```ts\ninterface Compactor {\n  \u002F** Identifies the compaction type *\u002F\n  type: \"vertical\" | \"horizontal\" | null | string;\n\n  \u002F**\n   * Whether items can overlap each other.\n   *\n   * When true:\n   * - Items can be placed on top of other items\n   * - Dragging into another item does NOT push it away\n   * - Compaction is skipped after drag\u002Fresize\n   *\n   * Use for: layered dashboards, free-form layouts\n   *\u002F\n  allowOverlap: boolean;\n\n  \u002F**\n   * Whether to block movement that would cause collision.\n   *\n   * When true (and allowOverlap is false):\n   * - Dragging into another item is blocked (item snaps back)\n   * - Other items are NOT pushed away\n   * - Only affects movement, not compaction\n   *\n   * Use with noCompactor for: fixed grids, slot-based layouts\n   *\n   * Note: Has no effect when allowOverlap is true.\n   *\u002F\n  preventCollision?: boolean;\n\n  \u002F**\n   * Compact the entire layout.\n   * Called after any layout change to fill gaps.\n   *\n   * @param layout - Array of layout items (clone before mutating!)\n   * @param cols - Number of grid columns\n   * @returns New compacted layout\n   *\u002F\n  compact(layout: Layout, cols: number): Layout;\n}\n```\n\n**Example: Gravity Compactor (items fall to bottom)**\n\n```ts\nimport { cloneLayout, cloneLayoutItem, getStatics, bottom } from \"react-grid-layout\u002Fcore\";\n\nconst gravityCompactor: Compactor = {\n  type: \"gravity\",\n  allowOverlap: false,\n\n  compact(layout, cols) {\n    const statics = getStatics(layout);\n    const maxY = 100; \u002F\u002F arbitrary max height\n    const out = [];\n\n    \u002F\u002F Sort by Y descending (process bottom items first)\n    const sorted = [...layout].sort((a, b) => b.y - a.y);\n\n    for (const item of sorted) {\n      const l = cloneLayoutItem(item);\n\n      if (!l.static) {\n        \u002F\u002F Move down as far as possible\n        while (l.y \u003C maxY && !collides(l, statics)) {\n          l.y++;\n        }\n        l.y--; \u002F\u002F Back up one\n      }\n\n      out.push(l);\n    }\n\n    return out;\n  }\n};\n\n\u002F\u002F Usage\n\u003CGridLayout compactor={gravityCompactor} \u002F>\n```\n\n**Example: Single Row Compactor (horizontal shelf)**\n\n```ts\nconst singleRowCompactor: Compactor = {\n  type: \"shelf\",\n  allowOverlap: false,\n\n  compact(layout, cols) {\n    let x = 0;\n    const out = [];\n\n    \u002F\u002F Sort by original X position\n    const sorted = [...layout].sort((a, b) => a.x - b.x);\n\n    for (const item of sorted) {\n      const l = cloneLayoutItem(item);\n      if (!l.static) {\n        l.x = x;\n        l.y = 0; \u002F\u002F All items on row 0\n        x += l.w;\n\n        \u002F\u002F Wrap to next row if overflow\n        if (x > cols) {\n          l.x = 0;\n          x = l.w;\n        }\n      }\n      out.push(l);\n    }\n\n    return out;\n  }\n};\n```\n\n**Using Helper Functions:**\n\nThe core module exports helpers for building compactors:\n\n```ts\nimport {\n  resolveCompactionCollision, \u002F\u002F Move items to resolve overlaps\n  compactItemVertical, \u002F\u002F Compact one item upward\n  compactItemHorizontal, \u002F\u002F Compact one item leftward\n  getFirstCollision, \u002F\u002F Find first collision\n  collides, \u002F\u002F Check if two items collide\n  getStatics, \u002F\u002F Get static items from layout\n  cloneLayout, \u002F\u002F Clone layout array\n  cloneLayoutItem \u002F\u002F Clone single item\n} from \"react-grid-layout\u002Fcore\";\n```\n\n### Creating a Custom Position Strategy\n\nPosition strategies control how items are positioned via CSS. Create custom strategies for special transform handling.\n\n**The PositionStrategy Interface:**\n\n```ts\ninterface PositionStrategy {\n  \u002F** Type identifier *\u002F\n  type: \"transform\" | \"absolute\" | string;\n\n  \u002F** Scale factor for coordinate calculations *\u002F\n  scale: number;\n\n  \u002F**\n   * Generate CSS styles for positioning an item.\n   *\n   * @param pos - Position with top, left, width, height in pixels\n   * @returns CSS properties object\n   *\u002F\n  calcStyle(pos: Position): React.CSSProperties;\n\n  \u002F**\n   * Calculate drag position from mouse coordinates.\n   * Used during drag to convert screen coords to grid coords.\n   *\n   * @param clientX - Mouse X position\n   * @param clientY - Mouse Y position\n   * @param offsetX - Offset from item left edge\n   * @param offsetY - Offset from item top edge\n   * @returns Calculated left\u002Ftop position\n   *\u002F\n  calcDragPosition(\n    clientX: number,\n    clientY: number,\n    offsetX: number,\n    offsetY: number\n  ): { left: number; top: number };\n}\n```\n\n**Example: Rotated Container Strategy**\n\n```ts\nconst createRotatedStrategy = (angleDegrees: number): PositionStrategy => {\n  const angleRad = (angleDegrees * Math.PI) \u002F 180;\n  const cos = Math.cos(angleRad);\n  const sin = Math.sin(angleRad);\n\n  return {\n    type: \"rotated\",\n    scale: 1,\n\n    calcStyle(pos) {\n      \u002F\u002F Apply rotation to position\n      const rotatedX = pos.left * cos - pos.top * sin;\n      const rotatedY = pos.left * sin + pos.top * cos;\n\n      return {\n        transform: `translate(${rotatedX}px, ${rotatedY}px)`,\n        width: `${pos.width}px`,\n        height: `${pos.height}px`,\n        position: \"absolute\"\n      };\n    },\n\n    calcDragPosition(clientX, clientY, offsetX, offsetY) {\n      \u002F\u002F Reverse the rotation for drag calculations\n      const x = clientX - offsetX;\n      const y = clientY - offsetY;\n\n      return {\n        left: x * cos + y * sin,\n        top: -x * sin + y * cos\n      };\n    }\n  };\n};\n\n\u002F\u002F Usage: grid inside a rotated container\n\u003Cdiv style={{ transform: 'rotate(45deg)' }}>\n  \u003CGridLayout positionStrategy={createRotatedStrategy(45)} \u002F>\n\u003C\u002Fdiv>\n```\n\n**Example: 3D Perspective Strategy**\n\n```ts\nconst create3DStrategy = (\n  perspective: number,\n  rotateX: number\n): PositionStrategy => ({\n  type: \"3d\",\n  scale: 1,\n\n  calcStyle(pos) {\n    return {\n      transform: `\n        perspective(${perspective}px)\n        rotateX(${rotateX}deg)\n        translate3d(${pos.left}px, ${pos.top}px, 0)\n      `,\n      width: `${pos.width}px`,\n      height: `${pos.height}px`,\n      position: \"absolute\",\n      transformStyle: \"preserve-3d\"\n    };\n  },\n\n  calcDragPosition(clientX, clientY, offsetX, offsetY) {\n    \u002F\u002F Adjust for perspective foreshortening\n    const perspectiveFactor = 1 + clientY \u002F perspective;\n    return {\n      left: (clientX - offsetX) \u002F perspectiveFactor,\n      top: (clientY - offsetY) \u002F perspectiveFactor\n    };\n  }\n});\n```\n\n## Extras\n\nThe `react-grid-layout\u002Fextras` entry point provides optional components that extend react-grid-layout. These are tree-shakeable and won't be included in your bundle unless explicitly imported.\n\n### GridBackground\n\nRenders an SVG grid background that aligns with GridLayout cells. Use this to visualize the grid structure behind your layout.\n\n> Based on [PR #2175](https:\u002F\u002Fgithub.com\u002Freact-grid-layout\u002Freact-grid-layout\u002Fpull\u002F2175) by [@dmj900501](https:\u002F\u002Fgithub.com\u002Fdmj900501).\n\n```tsx\nimport { GridBackground } from \"react-grid-layout\u002Fextras\";\nimport ReactGridLayout, { useContainerWidth } from \"react-grid-layout\";\n\nfunction MyGrid() {\n  const { width, containerRef, mounted } = useContainerWidth();\n\n  return (\n    \u003Cdiv ref={containerRef} style={{ position: \"relative\" }}>\n      {mounted && (\n        \u003C>\n          \u003CGridBackground\n            width={width}\n            cols={12}\n            rowHeight={30}\n            margin={[10, 10]}\n            rows={10}\n            color=\"#f0f0f0\"\n            borderRadius={4}\n          \u002F>\n          \u003CReactGridLayout\n            width={width}\n            gridConfig={{ cols: 12, rowHeight: 30, margin: [10, 10] }}\n          >\n            {children}\n          \u003C\u002FReactGridLayout>\n        \u003C\u002F>\n      )}\n    \u003C\u002Fdiv>\n  );\n}\n```\n\n**Props:**\n\n```ts\ninterface GridBackgroundProps {\n  \u002F\u002F Required - must match your GridLayout config\n  width: number; \u002F\u002F Container width\n  cols: number; \u002F\u002F Number of columns\n  rowHeight: number; \u002F\u002F Row height in pixels\n\n  \u002F\u002F Optional\n  margin?: [number, number]; \u002F\u002F Gap between cells (default: [10, 10])\n  containerPadding?: [number, number] | null; \u002F\u002F Container padding (default: uses margin)\n  rows?: number | \"auto\"; \u002F\u002F Number of rows to display (default: 10)\n  height?: number; \u002F\u002F Used when rows=\"auto\" to calculate row count\n  color?: string; \u002F\u002F Cell background color (default: \"#e0e0e0\")\n  borderRadius?: number; \u002F\u002F Cell border radius (default: 4)\n  className?: string; \u002F\u002F Additional CSS class\n  style?: React.CSSProperties; \u002F\u002F Additional inline styles\n}\n```\n\n### Fast Compactors\n\nFor large layouts (200+ items), the standard compactors can become slow due to O(n²) collision resolution. The fast compactors use optimized algorithms with O(n log n) complexity.\n\n> Based on the \"rising tide\" algorithm from [PR #2152](https:\u002F\u002Fgithub.com\u002Freact-grid-layout\u002Freact-grid-layout\u002Fpull\u002F2152) by [@morris](https:\u002F\u002Fgithub.com\u002Fmorris).\n\n```tsx\nimport {\n  fastVerticalCompactor,\n  fastHorizontalCompactor,\n  fastVerticalOverlapCompactor,\n  fastHorizontalOverlapCompactor\n} from \"react-grid-layout\u002Fextras\";\n\n\u003CReactGridLayout\n  compactor={fastVerticalCompactor}\n  \u002F\u002F or compactor={fastHorizontalCompactor}\n  layout={layout}\n  width={width}\n\u002F>;\n```\n\n**Performance Benchmarks:**\n\n| Items | Standard Vertical | Fast Vertical | Speedup |\n| ----- | ----------------- | ------------- | ------- |\n| 50    | 112 µs            | 19 µs         | **6x**  |\n| 100   | 203 µs            | 36 µs         | **6x**  |\n| 200   | 821 µs            | 51 µs         | **16x** |\n| 500   | 5.7 ms            | 129 µs        | **45x** |\n\n| Items | Standard Horizontal | Fast Horizontal | Speedup |\n| ----- | ------------------- | --------------- | ------- |\n| 50    | 164 µs              | 12 µs           | **14x** |\n| 100   | 477 µs              | 25 µs           | **19x** |\n| 200   | 1.1 ms              | 42 µs           | **26x** |\n| 500   | 9.5 ms              | 128 µs          | **74x** |\n\n**Correctness:**\n\nThe fast compactors produce layouts identical to the standard compactors:\n\n- **Vertical**: 0% height difference on deterministic 100-item layouts\n- **Horizontal**: 0% width difference on deterministic 100-item layouts\n- Both pass all correctness tests: no overlaps, idempotent, static item handling\n\n**When to use:**\n\n- Use fast compactors for dashboards with 200+ widgets\n- For smaller layouts (\u003C100 items), standard compactors work equally well\n- Both standard and fast compactors produce valid, non-overlapping layouts\n\n### calcGridCellDimensions (Core Utility)\n\nFor building custom grid overlays or backgrounds, use the `calcGridCellDimensions` utility from `react-grid-layout\u002Fcore`:\n\n```ts\nimport { calcGridCellDimensions } from \"react-grid-layout\u002Fcore\";\n\nconst dims = calcGridCellDimensions({\n  width: 1200,\n  cols: 12,\n  rowHeight: 30,\n  margin: [10, 10],\n  containerPadding: [20, 20]\n});\n\n\u002F\u002F dims = {\n\u002F\u002F   cellWidth: 88.33,  \u002F\u002F Width of each cell\n\u002F\u002F   cellHeight: 30,     \u002F\u002F Height of each cell (= rowHeight)\n\u002F\u002F   offsetX: 20,        \u002F\u002F Left padding\n\u002F\u002F   offsetY: 20,        \u002F\u002F Top padding\n\u002F\u002F   gapX: 10,           \u002F\u002F Horizontal gap between cells\n\u002F\u002F   gapY: 10,           \u002F\u002F Vertical gap between cells\n\u002F\u002F   cols: 12,           \u002F\u002F Column count\n\u002F\u002F   containerWidth: 1200\n\u002F\u002F }\n```\n\nThis is useful for building custom visualizations, snap-to-grid functionality, or integrating with canvas\u002FWebGL renderers.\n\n## Performance\n\n### Memoize Children\n\nThe grid compares children by reference. Memoize them for better performance:\n\n```tsx\nfunction MyGrid({ count, width }) {\n  const children = useMemo(() => {\n    return Array.from({ length: count }, (_, i) => (\n      \u003Cdiv\n        key={i}\n        data-grid={{ x: i % 12, y: Math.floor(i \u002F 12), w: 1, h: 1 }}\n      \u002F>\n    ));\n  }, [count]);\n\n  return (\n    \u003CReactGridLayout width={width} gridConfig={{ cols: 12 }}>\n      {children}\n    \u003C\u002FReactGridLayout>\n  );\n}\n```\n\n### Avoid Creating Components in Render (Legacy WidthProvider)\n\nIf using the legacy WidthProvider HOC, don't create the component during render:\n\n```tsx\nimport ReactGridLayout, { WidthProvider } from \"react-grid-layout\u002Flegacy\";\n\n\u002F\u002F Bad - creates new component every render\nfunction MyGrid() {\n  const GridLayoutWithWidth = WidthProvider(ReactGridLayout);\n  return \u003CGridLayoutWithWidth>...\u003C\u002FGridLayoutWithWidth>;\n}\n\n\u002F\u002F Good - create once outside or with useMemo\nconst GridLayoutWithWidth = WidthProvider(ReactGridLayout);\n\nfunction MyGrid() {\n  return \u003CGridLayoutWithWidth>...\u003C\u002FGridLayoutWithWidth>;\n}\n```\n\nWith the v2 API, use `useContainerWidth` hook instead to avoid this issue entirely.\n\n## Custom Child Components\n\nGrid children must forward refs and certain props:\n\n```tsx\nconst CustomItem = forwardRef\u003CHTMLDivElement, CustomItemProps>(\n  (\n    {\n      style,\n      className,\n      onMouseDown,\n      onMouseUp,\n      onTouchEnd,\n      children,\n      ...props\n    },\n    ref\n  ) => {\n    return (\n      \u003Cdiv\n        ref={ref}\n        style={style}\n        className={className}\n        onMouseDown={onMouseDown}\n        onMouseUp={onMouseUp}\n        onTouchEnd={onTouchEnd}\n      >\n        {children}\n      \u003C\u002Fdiv>\n    );\n  }\n);\n```\n\n## Contribute\n\nIf you have a feature request, please add it as an issue or make a pull request.\n\nIf you have a bug to report, please reproduce the bug in [CodeSandbox](https:\u002F\u002Fcodesandbox.io\u002Fp\u002Fsandbox\u002F5ywf7c) to help\nus easily isolate it.\n","React-Grid-Layout 是一个适用于 React 的可拖拽和可调整大小的网格布局系统。它支持响应式断点，用户可以自定义或自动生成断点布局，这使得它非常适合需要灵活布局的应用场景。该项目使用 TypeScript 重写，提供了完整的 TypeScript 支持，并引入了 React Hooks 来增强功能性和可组合性配置。其模块化架构允许开发者仅导入所需的部分，从而减小最终打包体积。此外，它不需要 jQuery，完全基于 React 构建。对于需要在不同屏幕尺寸下保持良好用户体验的仪表盘、控制台界面等场景尤其适用。",2,"2026-06-11 02:55:38","top_language"]