@snapgridjs/react 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/index.cjs +69 -13
- package/dist/index.d.cts +22 -7
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +22 -7
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +44 -18
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -19,6 +19,7 @@ Draggable, resizable, responsive grid layouts for React — with pluggable packi
|
|
|
19
19
|
- **Pluggable packing** — `vertical` / `horizontal` / `none`, plus `masonry` / `gravity` / `shelf` from [`@snapgridjs/extras`](https://www.npmjs.com/package/@snapgridjs/extras), or your own `Compactor`.
|
|
20
20
|
- **Cross-grid dragging** — wrap grids in a `<SnapGridGroup>` and drag tiles between them.
|
|
21
21
|
- **Nested grids** — drop a grid inside a tile of another grid and drag tiles between levels; isolate a sub-grid with its own provider when you want it contained.
|
|
22
|
+
- **dnd-kit interop** — drag between a grid and a dnd-kit `useSortable` list or board (cards in, tiles out, both reorder) under one provider, via `snapMove`.
|
|
22
23
|
- **Responsive** — per-breakpoint layouts with `<ResponsiveGridLayout>`.
|
|
23
24
|
- **Keyboard accessible** — Enter/Space to pick up, arrow keys to move, Esc to cancel.
|
|
24
25
|
- **SSR-safe** and **TypeScript-first** (types included).
|
package/dist/index.cjs
CHANGED
|
@@ -143,7 +143,8 @@ function useGridContainer(opts) {
|
|
|
143
143
|
const srcEl = (0, _snapgridjs_dnd.domElement)(source);
|
|
144
144
|
if (srcEl && gridElRef.current && srcEl.contains(gridElRef.current)) return false;
|
|
145
145
|
if (source.type === "grid-item") return true;
|
|
146
|
-
|
|
146
|
+
if (source.data?.snapGridDrop != null) return true;
|
|
147
|
+
return opts.accept?.(source) ?? false;
|
|
147
148
|
},
|
|
148
149
|
collisionDetector: _snapgridjs_dnd.gridCollisionDetector
|
|
149
150
|
});
|
|
@@ -171,6 +172,7 @@ function useGridContainer(opts) {
|
|
|
171
172
|
}
|
|
172
173
|
const REFLOW_EASING = "ease";
|
|
173
174
|
const REFLOW_TRANSITION = `transform 150ms ${REFLOW_EASING}, width 150ms ${REFLOW_EASING}, height 150ms ${REFLOW_EASING}`;
|
|
175
|
+
const TILE_TRANSITION = `width 150ms ${REFLOW_EASING}, height 150ms ${REFLOW_EASING}`;
|
|
174
176
|
//#endregion
|
|
175
177
|
//#region src/hooks/useResolveController.ts
|
|
176
178
|
/**
|
|
@@ -191,6 +193,7 @@ const ITEM_FEEDBACK = [_dnd_kit_dom.Feedback.configure({
|
|
|
191
193
|
feedback: (_source, manager) => (0, _dnd_kit_dom_utilities.isKeyboardEvent)(manager.dragOperation.activatorEvent) ? "none" : "default",
|
|
192
194
|
dropAnimation: null
|
|
193
195
|
})];
|
|
196
|
+
const tileNeverTarget = () => null;
|
|
194
197
|
/**
|
|
195
198
|
* Headless hook for a single grid tile. The tile is a real `useSortable` (a
|
|
196
199
|
* draggable + droppable carrying `group`/`index`/`type`/`accept`), so it
|
|
@@ -201,10 +204,18 @@ const ITEM_FEEDBACK = [_dnd_kit_dom.Feedback.configure({
|
|
|
201
204
|
* element you render — you own the tag, className, content, and cosmetic styling.
|
|
202
205
|
*
|
|
203
206
|
* The dragged tile floats itself via dnd-kit's default feedback (no `<DragOverlay>`):
|
|
204
|
-
* the active tile renders at its committed origin
|
|
205
|
-
* reflow is animated on the compositor via the Web
|
|
206
|
-
* smooth in Safari, where the float's
|
|
207
|
-
* CSS-transition reflow.
|
|
207
|
+
* the active tile renders at its committed origin and dnd-kit's float follows the
|
|
208
|
+
* pointer from there, while reflow is animated on the compositor via the Web
|
|
209
|
+
* Animations API (a FLIP) — both so it stays smooth in Safari, where the float's
|
|
210
|
+
* popover top-layer repaint would jank a CSS-transition reflow.
|
|
211
|
+
*
|
|
212
|
+
* Tiles are positioned with `left`/`top` (not `transform`). dnd-kit's self-float
|
|
213
|
+
* measures the source element's rect ignoring transforms and re-applies its current
|
|
214
|
+
* transform each frame; a transform-positioned tile leans on that, but the
|
|
215
|
+
* compensation is lost the instant the dragged element is swapped for a foreign one
|
|
216
|
+
* mid-drag (grid → sortable interop — the tile becomes a flow card), which would
|
|
217
|
+
* make the float jump by the tile's grid offset. Plain left/top has nothing to lose
|
|
218
|
+
* on the swap, matching how dnd-kit's own flow-positioned sortables hand off cleanly.
|
|
208
219
|
*/
|
|
209
220
|
function useGridItem(id, group) {
|
|
210
221
|
const controller = useResolveController(group);
|
|
@@ -232,6 +243,7 @@ function useGridItem(id, group) {
|
|
|
232
243
|
group,
|
|
233
244
|
type: "grid-item",
|
|
234
245
|
accept: "grid-item",
|
|
246
|
+
collisionDetector: tileNeverTarget,
|
|
235
247
|
disabled: !config.isItemDraggable(id),
|
|
236
248
|
sensors: config.itemSensors,
|
|
237
249
|
modifiers: config.itemModifiers,
|
|
@@ -251,6 +263,7 @@ function useGridItem(id, group) {
|
|
|
251
263
|
const posTop = pos?.top;
|
|
252
264
|
const prev = (0, react.useRef)(null);
|
|
253
265
|
const reflowAnim = (0, react.useRef)(null);
|
|
266
|
+
const settleAnchor = (0, react.useRef)(null);
|
|
254
267
|
(0, react.useLayoutEffect)(() => {
|
|
255
268
|
const cur = posLeft != null && posTop != null ? {
|
|
256
269
|
left: posLeft,
|
|
@@ -259,17 +272,31 @@ function useGridItem(id, group) {
|
|
|
259
272
|
const before = prev.current;
|
|
260
273
|
prev.current = cur;
|
|
261
274
|
const el = elRef.current;
|
|
262
|
-
if (!el || !cur
|
|
275
|
+
if (!el || !cur) return;
|
|
276
|
+
if (active) {
|
|
277
|
+
settleAnchor.current = cur;
|
|
278
|
+
reflowAnim.current?.cancel();
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
if (dragging) settleAnchor.current = null;
|
|
282
|
+
else if (settleAnchor.current) {
|
|
283
|
+
const a = settleAnchor.current;
|
|
284
|
+
reflowAnim.current?.cancel();
|
|
285
|
+
if (cur.left !== a.left || cur.top !== a.top) settleAnchor.current = null;
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
if (!before || justDropped) return;
|
|
263
289
|
if (before.left === cur.left && before.top === cur.top) return;
|
|
290
|
+
if (typeof el.animate !== "function") return;
|
|
264
291
|
let fromX = before.left;
|
|
265
292
|
let fromY = before.top;
|
|
266
293
|
if (reflowAnim.current?.playState === "running") {
|
|
267
294
|
const m = new DOMMatrix(getComputedStyle(el).transform);
|
|
268
|
-
fromX = m.m41;
|
|
269
|
-
fromY = m.m42;
|
|
295
|
+
fromX = before.left + m.m41;
|
|
296
|
+
fromY = before.top + m.m42;
|
|
270
297
|
}
|
|
271
298
|
reflowAnim.current?.cancel();
|
|
272
|
-
reflowAnim.current = el.animate([{ transform: `translate(${fromX}px, ${fromY}px)` }, { transform:
|
|
299
|
+
reflowAnim.current = el.animate([{ transform: `translate(${fromX - cur.left}px, ${fromY - cur.top}px)` }, { transform: "translate(0px, 0px)" }], {
|
|
273
300
|
duration: 150,
|
|
274
301
|
easing: REFLOW_EASING
|
|
275
302
|
});
|
|
@@ -286,12 +313,11 @@ function useGridItem(id, group) {
|
|
|
286
313
|
handleRef,
|
|
287
314
|
style: pos ? {
|
|
288
315
|
position: "absolute",
|
|
289
|
-
left:
|
|
290
|
-
top:
|
|
316
|
+
left: pos.left,
|
|
317
|
+
top: pos.top,
|
|
291
318
|
width: pos.width,
|
|
292
319
|
height: pos.height,
|
|
293
|
-
|
|
294
|
-
transition: active || justDropped || dragging ? "none" : REFLOW_TRANSITION,
|
|
320
|
+
transition: justDropped || dragging ? "none" : TILE_TRANSITION,
|
|
295
321
|
touchAction: "none"
|
|
296
322
|
} : {
|
|
297
323
|
position: "absolute",
|
|
@@ -689,6 +715,12 @@ Object.defineProperty(exports, "PointerSensor", {
|
|
|
689
715
|
});
|
|
690
716
|
exports.ResponsiveGridLayout = ResponsiveGridLayout;
|
|
691
717
|
exports.SnapGridGroup = SnapGridGroup;
|
|
718
|
+
Object.defineProperty(exports, "defaultGridConfig", {
|
|
719
|
+
enumerable: true,
|
|
720
|
+
get: function() {
|
|
721
|
+
return _snapgridjs_core.defaultGridConfig;
|
|
722
|
+
}
|
|
723
|
+
});
|
|
692
724
|
Object.defineProperty(exports, "getCompactor", {
|
|
693
725
|
enumerable: true,
|
|
694
726
|
get: function() {
|
|
@@ -701,12 +733,36 @@ Object.defineProperty(exports, "horizontalCompactor", {
|
|
|
701
733
|
return _snapgridjs_core.horizontalCompactor;
|
|
702
734
|
}
|
|
703
735
|
});
|
|
736
|
+
Object.defineProperty(exports, "insertItemWithCompactor", {
|
|
737
|
+
enumerable: true,
|
|
738
|
+
get: function() {
|
|
739
|
+
return _snapgridjs_core.insertItemWithCompactor;
|
|
740
|
+
}
|
|
741
|
+
});
|
|
704
742
|
Object.defineProperty(exports, "noCompactor", {
|
|
705
743
|
enumerable: true,
|
|
706
744
|
get: function() {
|
|
707
745
|
return _snapgridjs_core.noCompactor;
|
|
708
746
|
}
|
|
709
747
|
});
|
|
748
|
+
Object.defineProperty(exports, "removeItemWithCompactor", {
|
|
749
|
+
enumerable: true,
|
|
750
|
+
get: function() {
|
|
751
|
+
return _snapgridjs_core.removeItemWithCompactor;
|
|
752
|
+
}
|
|
753
|
+
});
|
|
754
|
+
Object.defineProperty(exports, "snapMove", {
|
|
755
|
+
enumerable: true,
|
|
756
|
+
get: function() {
|
|
757
|
+
return _snapgridjs_dnd.snapMove;
|
|
758
|
+
}
|
|
759
|
+
});
|
|
760
|
+
Object.defineProperty(exports, "toPositionParams", {
|
|
761
|
+
enumerable: true,
|
|
762
|
+
get: function() {
|
|
763
|
+
return _snapgridjs_core.toPositionParams;
|
|
764
|
+
}
|
|
765
|
+
});
|
|
710
766
|
exports.useContainerWidth = useContainerWidth;
|
|
711
767
|
Object.defineProperty(exports, "useDraggable", {
|
|
712
768
|
enumerable: true,
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { DragConfig, DragConfig as DragConfig$1, DragSourceInfo, DropConfig, DropConfig as DropConfig$1, GridController, GridDropData, GridEventCallback, GridEventCallback as GridEventCallback$1, RESIZE_HANDLE_ATTR, ResizeConfig, ResizeConfig as ResizeConfig$1 } from "@snapgridjs/dnd";
|
|
1
|
+
import { DragConfig, DragConfig as DragConfig$1, DragSourceInfo, DragSourceInfo as DragSourceInfo$1, DropConfig, DropConfig as DropConfig$1, GridController, GridDropData, GridEventCallback, GridEventCallback as GridEventCallback$1, RESIZE_HANDLE_ATTR, ResizeConfig, ResizeConfig as ResizeConfig$1, SnapMoveContext, SnapMoveEvent, snapMove } from "@snapgridjs/dnd";
|
|
2
2
|
import { CSSProperties, ReactNode } from "react";
|
|
3
|
-
import { BreakpointCols, BreakpointCols as BreakpointCols$1, Breakpoints, Breakpoints as Breakpoints$1, CompactType, Compactor, Compactor as Compactor$1, GridConfig, GridConfig as GridConfig$1, Layout, Layout as Layout$1, LayoutItem, LayoutItem as LayoutItem$1, PositionParams, ResizeHandleAxis, ResizeHandleAxis as ResizeHandleAxis$1, ResponsiveLayouts, ResponsiveLayouts as ResponsiveLayouts$1, getCompactor, horizontalCompactor, noCompactor, verticalCompactor } from "@snapgridjs/core";
|
|
3
|
+
import { BreakpointCols, BreakpointCols as BreakpointCols$1, Breakpoints, Breakpoints as Breakpoints$1, CompactType, Compactor, Compactor as Compactor$1, GridConfig, GridConfig as GridConfig$1, Layout, Layout as Layout$1, LayoutItem, LayoutItem as LayoutItem$1, PositionParams, ResizeHandleAxis, ResizeHandleAxis as ResizeHandleAxis$1, ResponsiveLayouts, ResponsiveLayouts as ResponsiveLayouts$1, defaultGridConfig, getCompactor, horizontalCompactor, insertItemWithCompactor, noCompactor, removeItemWithCompactor, toPositionParams, verticalCompactor } from "@snapgridjs/core";
|
|
4
4
|
import { DragOverlay, useDraggable, useDroppable } from "@dnd-kit/react";
|
|
5
5
|
import { Feedback, KeyboardSensor, PointerSensor } from "@dnd-kit/dom";
|
|
6
6
|
|
|
@@ -18,6 +18,13 @@ interface UseGridControllerOptions {
|
|
|
18
18
|
dragConfig?: DragConfig$1;
|
|
19
19
|
resizeConfig?: ResizeConfig$1;
|
|
20
20
|
dropConfig?: DropConfig$1;
|
|
21
|
+
/**
|
|
22
|
+
* Accept additional (non-grid) dnd-kit draggables as drop targets — e.g. a
|
|
23
|
+
* `useSortable` card from a sibling list, for interop. Extends the built-in
|
|
24
|
+
* acceptance (grid tiles + `snapGridDrop` externals); the ancestry guard still
|
|
25
|
+
* applies. You drive the actual receive in your own `onDragOver` with `snapMove`.
|
|
26
|
+
*/
|
|
27
|
+
accept?: (source: DragSourceInfo$1) => boolean;
|
|
21
28
|
compactor?: Compactor$1;
|
|
22
29
|
isDraggable?: boolean;
|
|
23
30
|
isResizable?: boolean;
|
|
@@ -85,10 +92,18 @@ interface UseGridItemResult {
|
|
|
85
92
|
* element you render — you own the tag, className, content, and cosmetic styling.
|
|
86
93
|
*
|
|
87
94
|
* The dragged tile floats itself via dnd-kit's default feedback (no `<DragOverlay>`):
|
|
88
|
-
* the active tile renders at its committed origin
|
|
89
|
-
* reflow is animated on the compositor via the Web
|
|
90
|
-
* smooth in Safari, where the float's
|
|
91
|
-
* CSS-transition reflow.
|
|
95
|
+
* the active tile renders at its committed origin and dnd-kit's float follows the
|
|
96
|
+
* pointer from there, while reflow is animated on the compositor via the Web
|
|
97
|
+
* Animations API (a FLIP) — both so it stays smooth in Safari, where the float's
|
|
98
|
+
* popover top-layer repaint would jank a CSS-transition reflow.
|
|
99
|
+
*
|
|
100
|
+
* Tiles are positioned with `left`/`top` (not `transform`). dnd-kit's self-float
|
|
101
|
+
* measures the source element's rect ignoring transforms and re-applies its current
|
|
102
|
+
* transform each frame; a transform-positioned tile leans on that, but the
|
|
103
|
+
* compensation is lost the instant the dragged element is swapped for a foreign one
|
|
104
|
+
* mid-drag (grid → sortable interop — the tile becomes a flow card), which would
|
|
105
|
+
* make the float jump by the tile's grid offset. Plain left/top has nothing to lose
|
|
106
|
+
* on the swap, matching how dnd-kit's own flow-positioned sortables hand off cleanly.
|
|
92
107
|
*/
|
|
93
108
|
declare function useGridItem(id: string, group: string): UseGridItemResult;
|
|
94
109
|
//#endregion
|
|
@@ -299,5 +314,5 @@ interface UseContainerWidthResult {
|
|
|
299
314
|
*/
|
|
300
315
|
declare function useContainerWidth(options?: UseContainerWidthOptions): UseContainerWidthResult;
|
|
301
316
|
//#endregion
|
|
302
|
-
export { type BreakpointCols, type Breakpoints, type CompactType, type Compactor, DEFAULT_BREAKPOINTS, DEFAULT_BREAKPOINT_COLS, type DragConfig, DragOverlay, type DragSourceInfo, type DropConfig, Feedback, type GridConfig, type GridContainerProps, type GridDropData, type GridEventCallback, GridItem, type GridItemProps, GridLayout, type GridLayoutProps, GridPlaceholder, type GridPlaceholderInfo, type GridPlaceholderProps, KeyboardSensor, type Layout, type LayoutItem, PointerSensor, type PositionParams, type ResizeConfig, type ResizeHandleAxis, ResponsiveGridLayout, type ResponsiveGridLayoutProps, type ResponsiveLayouts, SnapGridGroup, type UseContainerWidthOptions, type UseContainerWidthResult, type UseGridContainerResult, type UseGridControllerOptions, type UseGridItemResult, type UseGridResizeHandleResult, type UseResponsiveLayoutOptions, type UseResponsiveLayoutResult, getCompactor, horizontalCompactor, noCompactor, useContainerWidth, useDraggable, useDroppable, useGridContainer, useGridItem, useGridPlaceholder, useGridResizeHandle, useResponsiveLayout, verticalCompactor };
|
|
317
|
+
export { type BreakpointCols, type Breakpoints, type CompactType, type Compactor, DEFAULT_BREAKPOINTS, DEFAULT_BREAKPOINT_COLS, type DragConfig, DragOverlay, type DragSourceInfo, type DropConfig, Feedback, type GridConfig, type GridContainerProps, type GridDropData, type GridEventCallback, GridItem, type GridItemProps, GridLayout, type GridLayoutProps, GridPlaceholder, type GridPlaceholderInfo, type GridPlaceholderProps, KeyboardSensor, type Layout, type LayoutItem, PointerSensor, type PositionParams, type ResizeConfig, type ResizeHandleAxis, ResponsiveGridLayout, type ResponsiveGridLayoutProps, type ResponsiveLayouts, SnapGridGroup, type SnapMoveContext, type SnapMoveEvent, type UseContainerWidthOptions, type UseContainerWidthResult, type UseGridContainerResult, type UseGridControllerOptions, type UseGridItemResult, type UseGridResizeHandleResult, type UseResponsiveLayoutOptions, type UseResponsiveLayoutResult, defaultGridConfig, getCompactor, horizontalCompactor, insertItemWithCompactor, noCompactor, removeItemWithCompactor, snapMove, toPositionParams, useContainerWidth, useDraggable, useDroppable, useGridContainer, useGridItem, useGridPlaceholder, useGridResizeHandle, useResponsiveLayout, verticalCompactor };
|
|
303
318
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/hooks/useGridController.ts","../src/hooks/useGridContainer.ts","../src/hooks/useGridItem.ts","../src/hooks/useGridPlaceholder.ts","../src/hooks/useGridResizeHandle.ts","../src/hooks/useResponsiveLayout.ts","../src/components/GridLayout.tsx","../src/components/ResponsiveGridLayout.tsx","../src/components/GridItem.tsx","../src/components/GridPlaceholder.tsx","../src/hooks/useContainerWidth.ts"],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/hooks/useGridController.ts","../src/hooks/useGridContainer.ts","../src/hooks/useGridItem.ts","../src/hooks/useGridPlaceholder.ts","../src/hooks/useGridResizeHandle.ts","../src/hooks/useResponsiveLayout.ts","../src/components/GridLayout.tsx","../src/components/ResponsiveGridLayout.tsx","../src/components/GridItem.tsx","../src/components/GridPlaceholder.tsx","../src/hooks/useContainerWidth.ts"],"mappings":"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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DragOverlay, useDraggable, useDroppable } from "@dnd-kit/react";
|
|
2
|
-
import { BreakpointCols, BreakpointCols as BreakpointCols$1, Breakpoints, Breakpoints as Breakpoints$1, CompactType, Compactor, Compactor as Compactor$1, GridConfig, GridConfig as GridConfig$1, Layout, Layout as Layout$1, LayoutItem, LayoutItem as LayoutItem$1, PositionParams, ResizeHandleAxis, ResizeHandleAxis as ResizeHandleAxis$1, ResponsiveLayouts, ResponsiveLayouts as ResponsiveLayouts$1, getCompactor, horizontalCompactor, noCompactor, verticalCompactor } from "@snapgridjs/core";
|
|
3
|
-
import { DragConfig, DragConfig as DragConfig$1, DragSourceInfo, DropConfig, DropConfig as DropConfig$1, GridController, GridDropData, GridEventCallback, GridEventCallback as GridEventCallback$1, RESIZE_HANDLE_ATTR, ResizeConfig, ResizeConfig as ResizeConfig$1 } from "@snapgridjs/dnd";
|
|
2
|
+
import { BreakpointCols, BreakpointCols as BreakpointCols$1, Breakpoints, Breakpoints as Breakpoints$1, CompactType, Compactor, Compactor as Compactor$1, GridConfig, GridConfig as GridConfig$1, Layout, Layout as Layout$1, LayoutItem, LayoutItem as LayoutItem$1, PositionParams, ResizeHandleAxis, ResizeHandleAxis as ResizeHandleAxis$1, ResponsiveLayouts, ResponsiveLayouts as ResponsiveLayouts$1, defaultGridConfig, getCompactor, horizontalCompactor, insertItemWithCompactor, noCompactor, removeItemWithCompactor, toPositionParams, verticalCompactor } from "@snapgridjs/core";
|
|
3
|
+
import { DragConfig, DragConfig as DragConfig$1, DragSourceInfo, DragSourceInfo as DragSourceInfo$1, DropConfig, DropConfig as DropConfig$1, GridController, GridDropData, GridEventCallback, GridEventCallback as GridEventCallback$1, RESIZE_HANDLE_ATTR, ResizeConfig, ResizeConfig as ResizeConfig$1, SnapMoveContext, SnapMoveEvent, snapMove } from "@snapgridjs/dnd";
|
|
4
4
|
import { CSSProperties, ReactNode } from "react";
|
|
5
5
|
import { Feedback, KeyboardSensor, PointerSensor } from "@dnd-kit/dom";
|
|
6
6
|
|
|
@@ -18,6 +18,13 @@ interface UseGridControllerOptions {
|
|
|
18
18
|
dragConfig?: DragConfig$1;
|
|
19
19
|
resizeConfig?: ResizeConfig$1;
|
|
20
20
|
dropConfig?: DropConfig$1;
|
|
21
|
+
/**
|
|
22
|
+
* Accept additional (non-grid) dnd-kit draggables as drop targets — e.g. a
|
|
23
|
+
* `useSortable` card from a sibling list, for interop. Extends the built-in
|
|
24
|
+
* acceptance (grid tiles + `snapGridDrop` externals); the ancestry guard still
|
|
25
|
+
* applies. You drive the actual receive in your own `onDragOver` with `snapMove`.
|
|
26
|
+
*/
|
|
27
|
+
accept?: (source: DragSourceInfo$1) => boolean;
|
|
21
28
|
compactor?: Compactor$1;
|
|
22
29
|
isDraggable?: boolean;
|
|
23
30
|
isResizable?: boolean;
|
|
@@ -85,10 +92,18 @@ interface UseGridItemResult {
|
|
|
85
92
|
* element you render — you own the tag, className, content, and cosmetic styling.
|
|
86
93
|
*
|
|
87
94
|
* The dragged tile floats itself via dnd-kit's default feedback (no `<DragOverlay>`):
|
|
88
|
-
* the active tile renders at its committed origin
|
|
89
|
-
* reflow is animated on the compositor via the Web
|
|
90
|
-
* smooth in Safari, where the float's
|
|
91
|
-
* CSS-transition reflow.
|
|
95
|
+
* the active tile renders at its committed origin and dnd-kit's float follows the
|
|
96
|
+
* pointer from there, while reflow is animated on the compositor via the Web
|
|
97
|
+
* Animations API (a FLIP) — both so it stays smooth in Safari, where the float's
|
|
98
|
+
* popover top-layer repaint would jank a CSS-transition reflow.
|
|
99
|
+
*
|
|
100
|
+
* Tiles are positioned with `left`/`top` (not `transform`). dnd-kit's self-float
|
|
101
|
+
* measures the source element's rect ignoring transforms and re-applies its current
|
|
102
|
+
* transform each frame; a transform-positioned tile leans on that, but the
|
|
103
|
+
* compensation is lost the instant the dragged element is swapped for a foreign one
|
|
104
|
+
* mid-drag (grid → sortable interop — the tile becomes a flow card), which would
|
|
105
|
+
* make the float jump by the tile's grid offset. Plain left/top has nothing to lose
|
|
106
|
+
* on the swap, matching how dnd-kit's own flow-positioned sortables hand off cleanly.
|
|
92
107
|
*/
|
|
93
108
|
declare function useGridItem(id: string, group: string): UseGridItemResult;
|
|
94
109
|
//#endregion
|
|
@@ -299,5 +314,5 @@ interface UseContainerWidthResult {
|
|
|
299
314
|
*/
|
|
300
315
|
declare function useContainerWidth(options?: UseContainerWidthOptions): UseContainerWidthResult;
|
|
301
316
|
//#endregion
|
|
302
|
-
export { type BreakpointCols, type Breakpoints, type CompactType, type Compactor, DEFAULT_BREAKPOINTS, DEFAULT_BREAKPOINT_COLS, type DragConfig, DragOverlay, type DragSourceInfo, type DropConfig, Feedback, type GridConfig, type GridContainerProps, type GridDropData, type GridEventCallback, GridItem, type GridItemProps, GridLayout, type GridLayoutProps, GridPlaceholder, type GridPlaceholderInfo, type GridPlaceholderProps, KeyboardSensor, type Layout, type LayoutItem, PointerSensor, type PositionParams, type ResizeConfig, type ResizeHandleAxis, ResponsiveGridLayout, type ResponsiveGridLayoutProps, type ResponsiveLayouts, SnapGridGroup, type UseContainerWidthOptions, type UseContainerWidthResult, type UseGridContainerResult, type UseGridControllerOptions, type UseGridItemResult, type UseGridResizeHandleResult, type UseResponsiveLayoutOptions, type UseResponsiveLayoutResult, getCompactor, horizontalCompactor, noCompactor, useContainerWidth, useDraggable, useDroppable, useGridContainer, useGridItem, useGridPlaceholder, useGridResizeHandle, useResponsiveLayout, verticalCompactor };
|
|
317
|
+
export { type BreakpointCols, type Breakpoints, type CompactType, type Compactor, DEFAULT_BREAKPOINTS, DEFAULT_BREAKPOINT_COLS, type DragConfig, DragOverlay, type DragSourceInfo, type DropConfig, Feedback, type GridConfig, type GridContainerProps, type GridDropData, type GridEventCallback, GridItem, type GridItemProps, GridLayout, type GridLayoutProps, GridPlaceholder, type GridPlaceholderInfo, type GridPlaceholderProps, KeyboardSensor, type Layout, type LayoutItem, PointerSensor, type PositionParams, type ResizeConfig, type ResizeHandleAxis, ResponsiveGridLayout, type ResponsiveGridLayoutProps, type ResponsiveLayouts, SnapGridGroup, type SnapMoveContext, type SnapMoveEvent, type UseContainerWidthOptions, type UseContainerWidthResult, type UseGridContainerResult, type UseGridControllerOptions, type UseGridItemResult, type UseGridResizeHandleResult, type UseResponsiveLayoutOptions, type UseResponsiveLayoutResult, defaultGridConfig, getCompactor, horizontalCompactor, insertItemWithCompactor, noCompactor, removeItemWithCompactor, snapMove, toPositionParams, useContainerWidth, useDraggable, useDroppable, useGridContainer, useGridItem, useGridPlaceholder, useGridResizeHandle, useResponsiveLayout, verticalCompactor };
|
|
303
318
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/hooks/useGridController.ts","../src/hooks/useGridContainer.ts","../src/hooks/useGridItem.ts","../src/hooks/useGridPlaceholder.ts","../src/hooks/useGridResizeHandle.ts","../src/hooks/useResponsiveLayout.ts","../src/components/GridLayout.tsx","../src/components/ResponsiveGridLayout.tsx","../src/components/GridItem.tsx","../src/components/GridPlaceholder.tsx","../src/hooks/useContainerWidth.ts"],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/hooks/useGridController.ts","../src/hooks/useGridContainer.ts","../src/hooks/useGridItem.ts","../src/hooks/useGridPlaceholder.ts","../src/hooks/useGridResizeHandle.ts","../src/hooks/useResponsiveLayout.ts","../src/components/GridLayout.tsx","../src/components/ResponsiveGridLayout.tsx","../src/components/GridItem.tsx","../src/components/GridPlaceholder.tsx","../src/hooks/useContainerWidth.ts"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DragDropProvider, DragOverlay, useDragDropManager, useDraggable, useDraggable as useDraggable$1, useDroppable, useDroppable as useDroppable$1, useInstance } from "@dnd-kit/react";
|
|
2
|
-
import { bottom, calcGridItemPosition, defaultGridConfig, findOrGenerateResponsiveLayout, getBreakpointFromWidth, getColsFromBreakpoint, getCompactor, horizontalCompactor, noCompactor, toPositionParams, verticalCompactor, verticalCompactor as verticalCompactor$1 } from "@snapgridjs/core";
|
|
3
|
-
import { GridController, NO_FEEDBACK, RESIZE_HANDLE_ATTR, SNAPGRID_GRID_ATTR, SnapToGrid, attachEngine, buildItemSensors, domElement, getController, gridCollisionDetector, registerController } from "@snapgridjs/dnd";
|
|
2
|
+
import { bottom, calcGridItemPosition, defaultGridConfig, defaultGridConfig as defaultGridConfig$1, findOrGenerateResponsiveLayout, getBreakpointFromWidth, getColsFromBreakpoint, getCompactor, horizontalCompactor, insertItemWithCompactor, noCompactor, removeItemWithCompactor, toPositionParams, toPositionParams as toPositionParams$1, verticalCompactor, verticalCompactor as verticalCompactor$1 } from "@snapgridjs/core";
|
|
3
|
+
import { GridController, NO_FEEDBACK, RESIZE_HANDLE_ATTR, SNAPGRID_GRID_ATTR, SnapToGrid, attachEngine, buildItemSensors, domElement, getController, gridCollisionDetector, registerController, snapMove } from "@snapgridjs/dnd";
|
|
4
4
|
import { Children, createContext, isValidElement, memo, useCallback, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
5
5
|
import { Feedback, Feedback as Feedback$1, KeyboardSensor, PointerSensor } from "@dnd-kit/dom";
|
|
6
6
|
import { isKeyboardEvent } from "@dnd-kit/dom/utilities";
|
|
@@ -27,10 +27,10 @@ function useGridController(opts) {
|
|
|
27
27
|
const autoId = useId();
|
|
28
28
|
const containerId = opts.id ?? autoId;
|
|
29
29
|
const gridConfig = useMemo(() => ({
|
|
30
|
-
...defaultGridConfig,
|
|
30
|
+
...defaultGridConfig$1,
|
|
31
31
|
...opts.gridConfig
|
|
32
32
|
}), [opts.gridConfig]);
|
|
33
|
-
const positionParams = useMemo(() => toPositionParams(gridConfig, opts.width), [gridConfig, opts.width]);
|
|
33
|
+
const positionParams = useMemo(() => toPositionParams$1(gridConfig, opts.width), [gridConfig, opts.width]);
|
|
34
34
|
const compactor = opts.compactor ?? verticalCompactor$1;
|
|
35
35
|
const manager = useDragDropManager();
|
|
36
36
|
const controller = useInstance((m) => new GridController(containerId, opts.layout, m ?? void 0));
|
|
@@ -142,7 +142,8 @@ function useGridContainer(opts) {
|
|
|
142
142
|
const srcEl = domElement(source);
|
|
143
143
|
if (srcEl && gridElRef.current && srcEl.contains(gridElRef.current)) return false;
|
|
144
144
|
if (source.type === "grid-item") return true;
|
|
145
|
-
|
|
145
|
+
if (source.data?.snapGridDrop != null) return true;
|
|
146
|
+
return opts.accept?.(source) ?? false;
|
|
146
147
|
},
|
|
147
148
|
collisionDetector: gridCollisionDetector
|
|
148
149
|
});
|
|
@@ -170,6 +171,7 @@ function useGridContainer(opts) {
|
|
|
170
171
|
}
|
|
171
172
|
const REFLOW_EASING = "ease";
|
|
172
173
|
const REFLOW_TRANSITION = `transform 150ms ${REFLOW_EASING}, width 150ms ${REFLOW_EASING}, height 150ms ${REFLOW_EASING}`;
|
|
174
|
+
const TILE_TRANSITION = `width 150ms ${REFLOW_EASING}, height 150ms ${REFLOW_EASING}`;
|
|
173
175
|
//#endregion
|
|
174
176
|
//#region src/hooks/useResolveController.ts
|
|
175
177
|
/**
|
|
@@ -190,6 +192,7 @@ const ITEM_FEEDBACK = [Feedback$1.configure({
|
|
|
190
192
|
feedback: (_source, manager) => isKeyboardEvent(manager.dragOperation.activatorEvent) ? "none" : "default",
|
|
191
193
|
dropAnimation: null
|
|
192
194
|
})];
|
|
195
|
+
const tileNeverTarget = () => null;
|
|
193
196
|
/**
|
|
194
197
|
* Headless hook for a single grid tile. The tile is a real `useSortable` (a
|
|
195
198
|
* draggable + droppable carrying `group`/`index`/`type`/`accept`), so it
|
|
@@ -200,10 +203,18 @@ const ITEM_FEEDBACK = [Feedback$1.configure({
|
|
|
200
203
|
* element you render — you own the tag, className, content, and cosmetic styling.
|
|
201
204
|
*
|
|
202
205
|
* The dragged tile floats itself via dnd-kit's default feedback (no `<DragOverlay>`):
|
|
203
|
-
* the active tile renders at its committed origin
|
|
204
|
-
* reflow is animated on the compositor via the Web
|
|
205
|
-
* smooth in Safari, where the float's
|
|
206
|
-
* CSS-transition reflow.
|
|
206
|
+
* the active tile renders at its committed origin and dnd-kit's float follows the
|
|
207
|
+
* pointer from there, while reflow is animated on the compositor via the Web
|
|
208
|
+
* Animations API (a FLIP) — both so it stays smooth in Safari, where the float's
|
|
209
|
+
* popover top-layer repaint would jank a CSS-transition reflow.
|
|
210
|
+
*
|
|
211
|
+
* Tiles are positioned with `left`/`top` (not `transform`). dnd-kit's self-float
|
|
212
|
+
* measures the source element's rect ignoring transforms and re-applies its current
|
|
213
|
+
* transform each frame; a transform-positioned tile leans on that, but the
|
|
214
|
+
* compensation is lost the instant the dragged element is swapped for a foreign one
|
|
215
|
+
* mid-drag (grid → sortable interop — the tile becomes a flow card), which would
|
|
216
|
+
* make the float jump by the tile's grid offset. Plain left/top has nothing to lose
|
|
217
|
+
* on the swap, matching how dnd-kit's own flow-positioned sortables hand off cleanly.
|
|
207
218
|
*/
|
|
208
219
|
function useGridItem(id, group) {
|
|
209
220
|
const controller = useResolveController(group);
|
|
@@ -231,6 +242,7 @@ function useGridItem(id, group) {
|
|
|
231
242
|
group,
|
|
232
243
|
type: "grid-item",
|
|
233
244
|
accept: "grid-item",
|
|
245
|
+
collisionDetector: tileNeverTarget,
|
|
234
246
|
disabled: !config.isItemDraggable(id),
|
|
235
247
|
sensors: config.itemSensors,
|
|
236
248
|
modifiers: config.itemModifiers,
|
|
@@ -250,6 +262,7 @@ function useGridItem(id, group) {
|
|
|
250
262
|
const posTop = pos?.top;
|
|
251
263
|
const prev = useRef(null);
|
|
252
264
|
const reflowAnim = useRef(null);
|
|
265
|
+
const settleAnchor = useRef(null);
|
|
253
266
|
useLayoutEffect(() => {
|
|
254
267
|
const cur = posLeft != null && posTop != null ? {
|
|
255
268
|
left: posLeft,
|
|
@@ -258,17 +271,31 @@ function useGridItem(id, group) {
|
|
|
258
271
|
const before = prev.current;
|
|
259
272
|
prev.current = cur;
|
|
260
273
|
const el = elRef.current;
|
|
261
|
-
if (!el || !cur
|
|
274
|
+
if (!el || !cur) return;
|
|
275
|
+
if (active) {
|
|
276
|
+
settleAnchor.current = cur;
|
|
277
|
+
reflowAnim.current?.cancel();
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
if (dragging) settleAnchor.current = null;
|
|
281
|
+
else if (settleAnchor.current) {
|
|
282
|
+
const a = settleAnchor.current;
|
|
283
|
+
reflowAnim.current?.cancel();
|
|
284
|
+
if (cur.left !== a.left || cur.top !== a.top) settleAnchor.current = null;
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
if (!before || justDropped) return;
|
|
262
288
|
if (before.left === cur.left && before.top === cur.top) return;
|
|
289
|
+
if (typeof el.animate !== "function") return;
|
|
263
290
|
let fromX = before.left;
|
|
264
291
|
let fromY = before.top;
|
|
265
292
|
if (reflowAnim.current?.playState === "running") {
|
|
266
293
|
const m = new DOMMatrix(getComputedStyle(el).transform);
|
|
267
|
-
fromX = m.m41;
|
|
268
|
-
fromY = m.m42;
|
|
294
|
+
fromX = before.left + m.m41;
|
|
295
|
+
fromY = before.top + m.m42;
|
|
269
296
|
}
|
|
270
297
|
reflowAnim.current?.cancel();
|
|
271
|
-
reflowAnim.current = el.animate([{ transform: `translate(${fromX}px, ${fromY}px)` }, { transform:
|
|
298
|
+
reflowAnim.current = el.animate([{ transform: `translate(${fromX - cur.left}px, ${fromY - cur.top}px)` }, { transform: "translate(0px, 0px)" }], {
|
|
272
299
|
duration: 150,
|
|
273
300
|
easing: REFLOW_EASING
|
|
274
301
|
});
|
|
@@ -285,12 +312,11 @@ function useGridItem(id, group) {
|
|
|
285
312
|
handleRef,
|
|
286
313
|
style: pos ? {
|
|
287
314
|
position: "absolute",
|
|
288
|
-
left:
|
|
289
|
-
top:
|
|
315
|
+
left: pos.left,
|
|
316
|
+
top: pos.top,
|
|
290
317
|
width: pos.width,
|
|
291
318
|
height: pos.height,
|
|
292
|
-
|
|
293
|
-
transition: active || justDropped || dragging ? "none" : REFLOW_TRANSITION,
|
|
319
|
+
transition: justDropped || dragging ? "none" : TILE_TRANSITION,
|
|
294
320
|
touchAction: "none"
|
|
295
321
|
} : {
|
|
296
322
|
position: "absolute",
|
|
@@ -657,6 +683,6 @@ function useContainerWidth(options = {}) {
|
|
|
657
683
|
};
|
|
658
684
|
}
|
|
659
685
|
//#endregion
|
|
660
|
-
export { DEFAULT_BREAKPOINTS, DEFAULT_BREAKPOINT_COLS, DragOverlay, Feedback, GridItem, GridLayout, GridPlaceholder, KeyboardSensor, PointerSensor, ResponsiveGridLayout, SnapGridGroup, getCompactor, horizontalCompactor, noCompactor, useContainerWidth, useDraggable, useDroppable, useGridContainer, useGridItem, useGridPlaceholder, useGridResizeHandle, useResponsiveLayout, verticalCompactor };
|
|
686
|
+
export { DEFAULT_BREAKPOINTS, DEFAULT_BREAKPOINT_COLS, DragOverlay, Feedback, GridItem, GridLayout, GridPlaceholder, KeyboardSensor, PointerSensor, ResponsiveGridLayout, SnapGridGroup, defaultGridConfig, getCompactor, horizontalCompactor, insertItemWithCompactor, noCompactor, removeItemWithCompactor, snapMove, toPositionParams, useContainerWidth, useDraggable, useDroppable, useGridContainer, useGridItem, useGridPlaceholder, useGridResizeHandle, useResponsiveLayout, verticalCompactor };
|
|
661
687
|
|
|
662
688
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["verticalCompactor","useDroppable","Feedback","useDraggable","verticalCompactor"],"sources":["../src/hooks/useGridController.ts","../src/hooks/useGridContainer.ts","../src/reflow.ts","../src/hooks/useResolveController.ts","../src/hooks/useGridItem.ts","../src/hooks/useGridPlaceholder.ts","../src/hooks/useGridResizeHandle.ts","../src/hooks/useResponsiveLayout.ts","../src/components/GridItem.tsx","../src/components/GridPlaceholder.tsx","../src/components/GridLayout.tsx","../src/components/ResponsiveGridLayout.tsx","../src/hooks/useContainerWidth.ts"],"sourcesContent":["import { useDragDropManager, useInstance } from \"@dnd-kit/react\";\nimport {\n type Compactor,\n type GridConfig,\n type Layout,\n type LayoutItem,\n type PositionParams,\n defaultGridConfig,\n toPositionParams,\n verticalCompactor,\n} from \"@snapgridjs/core\";\nimport {\n type DragConfig,\n type DropConfig,\n GridController,\n type GridEventCallback,\n type ResizeConfig,\n SnapToGrid,\n attachEngine,\n buildItemSensors,\n registerController,\n} from \"@snapgridjs/dnd\";\nimport { useCallback, useEffect, useId, useMemo, useRef } from \"react\";\n\nconst DEFAULT_HANDLES = [\"se\"] as const;\n\n// Per-item drag/resize gate. Mirrors RGL's engine rule: a `static` item is locked\n// unless its flag (`isDraggable`/`isResizable`) is explicitly `true` (\"pinned\");\n// a non-static item just follows the flag (default `true`).\nfunction itemGateOpen(flag: boolean | undefined, isStatic: boolean | undefined): boolean {\n return isStatic ? flag === true : (flag ?? true);\n}\n\n/** Options the grid host ({@link useGridContainer}) feeds the controller. */\nexport interface UseGridControllerOptions {\n /** Stable id for the grid's droppable surface (auto-generated if omitted). */\n id?: string;\n /** Container width in pixels (e.g. from {@link useContainerWidth}). */\n width: number;\n /** Controlled layout. Never mutated. */\n layout: Layout;\n onLayoutChange?: (layout: Layout) => void;\n gridConfig?: Partial<GridConfig>;\n dragConfig?: DragConfig;\n resizeConfig?: ResizeConfig;\n dropConfig?: DropConfig;\n compactor?: Compactor;\n isDraggable?: boolean;\n isResizable?: boolean;\n autoSize?: boolean;\n onDragStart?: GridEventCallback;\n onDrag?: GridEventCallback;\n onDragStop?: GridEventCallback;\n onResizeStart?: GridEventCallback;\n onResize?: GridEventCallback;\n onResizeStop?: GridEventCallback;\n onDrop?: (layout: Layout, item: LayoutItem, event: Event | null) => void;\n}\n\n/**\n * The grid's React seam: owns the {@link GridController} (an observable render\n * bridge), publishes per-grid config to it each render, registers it for id →\n * controller resolution, and attaches the manager-wide {@link SnapGridEngine}.\n *\n * The drag/resize *orchestration* lives in the engine (one per manager), not\n * here — this hook only wires the React-specific parts: the controller, the item\n * sensors/modifiers descriptors, the draggable/resizable gates, and the config\n * the engine reads. Created by {@link useGridContainer}; items resolve the same\n * controller by their `group` (= this grid's id). Consumes the ambient\n * `DragDropProvider` — it does not mint one.\n */\nexport function useGridController(opts: UseGridControllerOptions): GridController {\n const autoId = useId();\n const containerId = opts.id ?? autoId;\n\n const gridConfig: GridConfig = useMemo(\n () => ({ ...defaultGridConfig, ...opts.gridConfig }),\n [opts.gridConfig],\n );\n const positionParams: PositionParams = useMemo(\n () => toPositionParams(gridConfig, opts.width),\n [gridConfig, opts.width],\n );\n const compactor: Compactor = opts.compactor ?? verticalCompactor;\n\n const manager = useDragDropManager();\n const controller = useInstance<GridController>(\n (m) => new GridController(containerId, opts.layout, m ?? undefined),\n );\n controller.setCommitted(opts.layout);\n // useInstance creates the controller once, freezing its id to the first render's\n // value; re-point it if the controlled `id` prop changes so the group, the\n // droppable id, and the registry key (below) stay in sync. (Read during render,\n // before useGridContainer's droppable/group read controller.id.)\n if (controller.id !== containerId) controller.setId(containerId);\n\n // Live refs for the item sensor/modifier descriptors, which read config lazily\n // (they're built once but must see the latest dragConfig / positionParams).\n const optsRef = useRef(opts);\n optsRef.current = opts;\n const ppRef = useRef(positionParams);\n ppRef.current = positionParams;\n\n // Register the controller so items (and snapMove) resolve it by id, and so the\n // engine can find it as a drag's source/destination. During render so child\n // items resolve it on their first render (children render after the parent but\n // before any layout effect). The effect's cleanup unregisters on unmount / id\n // or manager change.\n registerController(manager, containerId, controller);\n useEffect(\n () => registerController(manager, containerId, controller),\n [manager, containerId, controller],\n );\n\n // Attach the manager-wide drag/resize engine (ref-counted; one per manager,\n // shared by every grid on it). Detaches when the last grid for this manager\n // unmounts. No-op without a manager (no provider above).\n useEffect(() => {\n if (!manager) return;\n return attachEngine(manager);\n }, [manager]);\n\n const committedById = useMemo(\n () => new Map<string, LayoutItem>(opts.layout.map((it) => [it.i, it])),\n [opts.layout],\n );\n\n const dragThreshold = opts.dragConfig?.threshold ?? 3;\n const itemSensors = useMemo(\n () => buildItemSensors(dragThreshold, () => optsRef.current.dragConfig),\n [dragThreshold],\n );\n\n // Snap-to-grid modifier (stable descriptor; reads live refs so it never goes\n // stale). A no-op unless `dragConfig.snapToGrid` is set.\n const itemModifiers = useMemo(\n () => [\n SnapToGrid.configure({\n getPositionParams: () => ppRef.current,\n isEnabled: () => optsRef.current.dragConfig?.snapToGrid ?? false,\n }),\n ],\n [],\n );\n\n const gridDraggable = opts.isDraggable ?? true;\n const dragEnabled = opts.dragConfig?.enabled ?? true;\n const isItemDraggable = useCallback(\n (id: string) => {\n const it = committedById.get(id);\n if (!it) return false;\n return gridDraggable && dragEnabled && itemGateOpen(it.isDraggable, it.static);\n },\n [committedById, gridDraggable, dragEnabled],\n );\n\n const gridResizable = opts.isResizable ?? true;\n const resizeEnabled = opts.resizeConfig?.enabled ?? true;\n const isItemResizable = useCallback(\n (id: string) => {\n const it = committedById.get(id);\n if (!it) return false;\n return gridResizable && resizeEnabled && itemGateOpen(it.isResizable, it.static);\n },\n [committedById, gridResizable, resizeEnabled],\n );\n const defaultHandles = opts.resizeConfig?.handles;\n const resizeHandlesFor = useCallback(\n (id: string) => committedById.get(id)?.resizeHandles ?? defaultHandles ?? DEFAULT_HANDLES,\n [committedById, defaultHandles],\n );\n\n // The per-grid callbacks the engine invokes, memoized so a stable consumer\n // doesn't reallocate the object every render (rebuilt only when one changes).\n const callbacks = useMemo(\n () => ({\n onDragStart: opts.onDragStart,\n onDrag: opts.onDrag,\n onDragStop: opts.onDragStop,\n onResizeStart: opts.onResizeStart,\n onResize: opts.onResize,\n onResizeStop: opts.onResizeStop,\n onLayoutChange: opts.onLayoutChange,\n onDrop: opts.onDrop,\n }),\n [\n opts.onDragStart,\n opts.onDrag,\n opts.onDragStop,\n opts.onResizeStart,\n opts.onResize,\n opts.onResizeStop,\n opts.onLayoutChange,\n opts.onDrop,\n ],\n );\n\n // Publish per-grid config to the controller so items (resolved by group) read\n // fresh geometry/predicates without a React context, and the engine reads this\n // grid's geometry, compaction, gates, and callbacks.\n controller.setConfig({\n positionParams,\n gridConfig,\n width: opts.width,\n autoSize: opts.autoSize ?? true,\n itemSensors,\n itemModifiers,\n isItemDraggable,\n isItemResizable,\n resizeHandlesFor,\n compactor,\n dragConfig: opts.dragConfig,\n dropConfig: opts.dropConfig,\n callbacks,\n });\n\n return controller;\n}\n","import { useDroppable } from \"@dnd-kit/react\";\nimport { type GridConfig, bottom } from \"@snapgridjs/core\";\nimport {\n type GridController,\n SNAPGRID_GRID_ATTR,\n domElement,\n gridCollisionDetector,\n} from \"@snapgridjs/dnd\";\nimport { type CSSProperties, useCallback, useRef, useSyncExternalStore } from \"react\";\nimport { type UseGridControllerOptions, useGridController } from \"./useGridController.js\";\n\nexport interface GridContainerProps {\n /** Attach to your container element. */\n ref: (element: Element | null) => void;\n /** Positioning style (relative + width + auto-sized height). Spread onto your element. */\n style: CSSProperties;\n /** Present while a compatible draggable is over the grid. */\n \"data-drop-target\"?: true;\n}\n\nexport interface UseGridContainerResult {\n /** Spread onto your container element. */\n containerProps: GridContainerProps;\n /** True while a compatible draggable is over the grid. */\n isDropTarget: boolean;\n /** This grid's id — pass as the `group` to {@link useGridItem} for its tiles. */\n group: string;\n /** The grid's controller (for advanced/headless composition). */\n controller: GridController;\n}\n\n/** Total container height in pixels for the given number of occupied rows. */\nfunction containerHeight(rows: number, grid: GridConfig): number {\n const padY = (grid.containerPadding ?? grid.margin)[1];\n if (rows <= 0) return padY * 2;\n return padY * 2 + rows * grid.rowHeight + (rows - 1) * grid.margin[1];\n}\n\n/**\n * The grid host: creates this grid's controller + drag monitor (see\n * {@link useGridController}), registers the droppable surface, and returns props\n * to spread onto your own container element. Render `useGridItem` tiles inside,\n * passing `group` (this grid's id) so they resolve this controller.\n */\nexport function useGridContainer(opts: UseGridControllerOptions): UseGridContainerResult {\n const controller = useGridController(opts);\n const config = controller.config;\n const { width, autoSize, gridConfig } = config!;\n const gridElRef = useRef<Element | null>(null);\n\n const { ref, isDropTarget } = useDroppable({\n id: controller.id,\n type: \"grid\",\n // Accept grid tiles plus external draggables carrying a `snapGridDrop`\n // payload. The latter have no type, so `accept: \"grid-item\"` would reject\n // them and they'd never resolve as a drop target. (The provider still\n // decides whether to actually receive an external source via dropConfig.)\n accept: (source) => {\n // Reject a source whose element CONTAINS this grid — an ancestor tile that\n // hosts this nested grid. Prevents dropping a host tile into the grid it\n // contains (a paradox) now that nested grids can share one manager.\n const srcEl = domElement(source);\n if (srcEl && gridElRef.current && srcEl.contains(gridElRef.current)) return false;\n if (source.type === \"grid-item\") return true;\n const data = source.data as { snapGridDrop?: unknown } | undefined;\n return data?.snapGridDrop != null;\n },\n collisionDetector: gridCollisionDetector,\n });\n\n // Merge dnd-kit's droppable ref with reporting the element to the controller\n // (the engine reads it to map the pointer to a cell when receiving a tile from\n // another grid), and mark the element so nested grids can measure their depth.\n const setRef = useCallback(\n (element: Element | null) => {\n ref(element);\n controller.element = element;\n gridElRef.current = element;\n if (element) element.setAttribute(SNAPGRID_GRID_ATTR, \"\");\n },\n [ref, controller],\n );\n\n // Subscribe to the rendered layout (drag preview while dragging, else\n // committed) so the surface auto-height tracks the content as it reflows.\n const renderedLayout = useSyncExternalStore(\n controller.subscribe,\n controller.renderedSnapshot,\n controller.renderedSnapshot,\n );\n const height = autoSize ? containerHeight(bottom(renderedLayout), gridConfig) : undefined;\n\n return {\n containerProps: {\n ref: setRef,\n style: { position: \"relative\", width, height },\n \"data-drop-target\": isDropTarget || undefined,\n },\n isDropTarget,\n group: controller.id,\n controller,\n };\n}\n","// Shared reflow timing for tiles and the placeholder, so they animate in lockstep\n// when a drag reflows the grid. Used by useGridItem (the tile's WAAPI reflow and\n// its out-of-drag CSS transition) and GridPlaceholder (its default look).\nexport const REFLOW_MS = 150;\nexport const REFLOW_EASING = \"ease\";\nexport const REFLOW_TRANSITION = `transform ${REFLOW_MS}ms ${REFLOW_EASING}, width ${REFLOW_MS}ms ${REFLOW_EASING}, height ${REFLOW_MS}ms ${REFLOW_EASING}`;\n","import { useDragDropManager } from \"@dnd-kit/react\";\nimport { type GridController, getController } from \"@snapgridjs/dnd\";\n\n/**\n * Resolve a grid's controller by its `group` (= the grid's id), scoped to the\n * ambient dnd-kit manager. Items declare `group` (mirroring useSortable); the\n * container registered the controller under that id. Throws a helpful error if\n * unresolved — almost always a missing `group` or a tile rendered outside any\n * grid / `DragDropProvider`.\n */\nexport function useResolveController(group: string): GridController {\n const manager = useDragDropManager();\n const controller = getController(manager, group);\n if (!controller) {\n throw new Error(\n `snapgrid: no grid found for group \"${group}\". A grid item must pass the group returned by its grid's useGridContainer, and render inside a <DragDropProvider> (or use <GridLayout>, which wires this for you).`,\n );\n }\n return controller;\n}\n","import { type Draggable, Feedback } from \"@dnd-kit/dom\";\nimport { isKeyboardEvent } from \"@dnd-kit/dom/utilities\";\nimport { useSortable } from \"@dnd-kit/react/sortable\";\nimport { type LayoutItem, calcGridItemPosition } from \"@snapgridjs/core\";\nimport {\n type CSSProperties,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useSyncExternalStore,\n} from \"react\";\nimport { REFLOW_EASING, REFLOW_MS, REFLOW_TRANSITION } from \"../reflow.js\";\nimport { useResolveController } from \"./useResolveController.js\";\n\n// A pointer drag floats the tile via dnd-kit's default feedback; a keyboard drag gets\n// `none` (no pointer — the tile steps in place via the session). The drop tween is\n// disabled so a pointer drop lands at the cell, not the float origin.\nconst ITEM_FEEDBACK = [\n Feedback.configure({\n feedback: (_source: Draggable, manager) =>\n isKeyboardEvent(manager.dragOperation.activatorEvent) ? \"none\" : \"default\",\n dropAnimation: null,\n }),\n];\n\nexport interface UseGridItemResult {\n /** Attach to the element that represents this grid item. */\n ref: (element: Element | null) => void;\n /**\n * Optional drag handle (dnd-kit's native handle). Attach to a child element to\n * restrict **pointer** drag activation to it; leave it unattached and the whole\n * tile drags. Keyboard pickup (Enter/Space on a focused tile) is unaffected.\n */\n handleRef: (element: Element | null) => void;\n /** Positioning style to spread onto your element. */\n style: CSSProperties;\n /** True while this item is the active drag source. */\n isDragging: boolean;\n /** The item's current (possibly reflowed) layout entry. */\n item: LayoutItem | undefined;\n}\n\n/**\n * Headless hook for a single grid tile. The tile is a real `useSortable` (a\n * draggable + droppable carrying `group`/`index`/`type`/`accept`), so it\n * interoperates with the dnd-kit sortable ecosystem, yet it is positioned by RGL\n * via the {@link GridController}. `group` is the owning grid's id (from its\n * {@link useGridContainer}), mirroring `useSortable`'s `group`. Spread the returned\n * `ref`, optional `handleRef`, positioning `style`, and drag state onto whatever\n * element you render — you own the tag, className, content, and cosmetic styling.\n *\n * The dragged tile floats itself via dnd-kit's default feedback (no `<DragOverlay>`):\n * the active tile renders at its committed origin so the float offset composes, and\n * reflow is animated on the compositor via the Web Animations API — both so it stays\n * smooth in Safari, where the float's popover top-layer repaint would jank a\n * CSS-transition reflow.\n */\nexport function useGridItem(id: string, group: string): UseGridItemResult {\n const controller = useResolveController(group);\n // Subscribe to just this item's slice → a drag elsewhere doesn't re-render it.\n const snap = useSyncExternalStore(\n controller.subscribe,\n () => controller.itemSnapshot(id),\n () => controller.itemSnapshot(id),\n );\n const item = snap.item;\n const active = snap.isDragging;\n // The controller's \"pointer move in progress\" signal (false for a keyboard drag).\n // We don't hide the tile (it floats itself) — we use it to decide whether to pin\n // the tile at its origin for the float.\n const hidden = snap.hidden;\n const config = controller.config!;\n\n // True on the single render where the tile goes active → settled (the drop frame):\n // snap to the landed cell instead of sliding there from the committed origin.\n const wasActive = useRef(false);\n const justDropped = wasActive.current && !active;\n wasActive.current = active;\n\n // Stable identity for the drag payload so dnd-kit doesn't churn on it every\n // render; it changes only when this tile's resolved entry does (a reflow).\n // `group` lets the engine resolve this tile's owning grid from the payload.\n const data = useMemo(\n () => ({ snapGrid: { kind: \"move\", itemId: id, item, group } }),\n [id, item, group],\n );\n\n const {\n ref: sortableRef,\n handleRef,\n isDragging,\n } = useSortable({\n id,\n index: controller.itemIndex(id),\n group,\n type: \"grid-item\",\n accept: \"grid-item\",\n disabled: !config.isItemDraggable(id),\n sensors: config.itemSensors,\n modifiers: config.itemModifiers,\n // Keep the sortable defaults (optimistic + keyboard, needed for interop); just\n // append the feedback config.\n plugins: (defaults) => [...defaults, ...ITEM_FEEDBACK],\n // Carry the full item so a receiving grid can render/insert it on a cross-grid drop.\n data,\n });\n\n // Capture the element to drive the WAAPI reflow, while still feeding the sortable's ref.\n const elRef = useRef<Element | null>(null);\n const setRef = useCallback(\n (element: Element | null) => {\n sortableRef(element);\n elRef.current = element;\n },\n [sortableRef],\n );\n\n const session = controller.getSession();\n const dragging = session != null;\n\n // During a POINTER drag the active tile renders at its committed origin so dnd-kit's\n // float offset tracks the pointer; a keyboard drag (and every other tile) renders at\n // the reflowed (preview) cell so it steps with the arrow keys.\n const posItem = item ? (active && hidden ? (session?.anchor.item ?? item) : item) : undefined;\n const pos = posItem\n ? calcGridItemPosition(config.positionParams, posItem.x, posItem.y, posItem.w, posItem.h)\n : undefined;\n const posLeft = pos?.left;\n const posTop = pos?.top;\n\n // While dragging, animate a reflowing tile to its new cell on the compositor (a\n // FLIP from its current visual position, so a mid-flight re-target stays smooth).\n // Compositor animations are immune to the float's popover repaint that janks a CSS\n // transition in Safari; outside a drag the CSS transition below handles changes.\n const prev = useRef<{ left: number; top: number } | null>(null);\n const reflowAnim = useRef<Animation | null>(null);\n useLayoutEffect(() => {\n const cur = posLeft != null && posTop != null ? { left: posLeft, top: posTop } : null;\n const before = prev.current;\n prev.current = cur;\n const el = elRef.current;\n if (!el || !cur || !before || active || justDropped || !dragging) return;\n if (before.left === cur.left && before.top === cur.top) return;\n let fromX = before.left;\n let fromY = before.top;\n if (reflowAnim.current?.playState === \"running\") {\n const m = new DOMMatrix(getComputedStyle(el).transform);\n fromX = m.m41;\n fromY = m.m42;\n }\n reflowAnim.current?.cancel();\n reflowAnim.current = el.animate(\n [\n { transform: `translate(${fromX}px, ${fromY}px)` },\n { transform: `translate(${cur.left}px, ${cur.top}px)` },\n ],\n { duration: REFLOW_MS, easing: REFLOW_EASING },\n );\n }, [posLeft, posTop, active, justDropped, dragging]);\n\n // Cancel any in-flight reflow animation when the tile unmounts (e.g. removed\n // mid-drag during a cross-grid move) so a running Animation can't outlive its node.\n useEffect(() => () => reflowAnim.current?.cancel(), []);\n\n const style: CSSProperties = pos\n ? {\n position: \"absolute\",\n left: 0,\n top: 0,\n width: pos.width,\n height: pos.height,\n transform: `translate(${pos.left}px, ${pos.top}px)`,\n // During a drag the WAAPI animation owns reflow motion; a CSS transition\n // would get janked (Safari) and double up. Outside a drag, keep it for\n // programmatic layout changes. The active/just-dropped tile never transitions.\n transition: active || justDropped || dragging ? \"none\" : REFLOW_TRANSITION,\n touchAction: \"none\",\n }\n : { position: \"absolute\", touchAction: \"none\" };\n\n return { ref: setRef, handleRef, style, isDragging, item };\n}\n","import { type LayoutItem, calcGridItemPosition } from \"@snapgridjs/core\";\nimport { type CSSProperties, useSyncExternalStore } from \"react\";\nimport { useResolveController } from \"./useResolveController.js\";\n\nexport interface GridPlaceholderInfo {\n /** The layout entry marking where the dragged item will land. */\n item: LayoutItem;\n /** Positioning style (left/top/size) to spread onto your placeholder element. */\n style: CSSProperties;\n}\n\n/**\n * Headless hook returning where the drag placeholder should be rendered, or\n * `null` when no drag is in progress. `group` is the owning grid's id (from its\n * {@link useGridContainer}). You render the element however you like.\n */\nexport function useGridPlaceholder(group: string): GridPlaceholderInfo | null {\n const controller = useResolveController(group);\n const placeholder = useSyncExternalStore(\n controller.subscribe,\n controller.placeholderSnapshot,\n controller.placeholderSnapshot,\n );\n if (!placeholder) return null;\n const pos = calcGridItemPosition(\n controller.config!.positionParams,\n placeholder.x,\n placeholder.y,\n placeholder.w,\n placeholder.h,\n );\n const style: CSSProperties = {\n position: \"absolute\",\n // Transform-positioned to match grid items (see useGridItem) — the\n // placeholder slides as a GPU transform, not an animated left/top.\n left: 0,\n top: 0,\n width: pos.width,\n height: pos.height,\n transform: `translate(${pos.left}px, ${pos.top}px)`,\n pointerEvents: \"none\",\n };\n return { item: placeholder, style };\n}\n","import { useDraggable } from \"@dnd-kit/react\";\nimport type { ResizeHandleAxis } from \"@snapgridjs/core\";\nimport { NO_FEEDBACK, RESIZE_HANDLE_ATTR } from \"@snapgridjs/dnd\";\nimport { useSyncExternalStore } from \"react\";\nimport { useResolveController } from \"./useResolveController.js\";\n\nexport interface UseGridResizeHandleResult {\n /** Attach to your resize-handle element. */\n ref: (element: Element | null) => void;\n /** Spread onto the handle element so item drags ignore pointer-downs on it. */\n handleProps: { [RESIZE_HANDLE_ATTR]: true };\n /** True while this item is actively being resized. */\n isResizing: boolean;\n}\n\n/**\n * Headless hook for a single resize handle. Model a handle as its own draggable;\n * dragging it resizes the item from the given edge/corner. `group` is the owning\n * grid's id (from its {@link useGridContainer}). Spread `ref` and `handleProps`\n * onto the handle element you position/style.\n */\nexport function useGridResizeHandle(\n itemId: string,\n handle: ResizeHandleAxis,\n group: string,\n): UseGridResizeHandleResult {\n const controller = useResolveController(group);\n const { ref } = useDraggable({\n id: `${itemId}::resize::${handle}`,\n disabled: !controller.config?.isItemResizable(itemId),\n plugins: NO_FEEDBACK,\n data: { snapGrid: { kind: \"resize\", itemId, handle, group } },\n });\n const { isResizing } = useSyncExternalStore(\n controller.subscribe,\n () => controller.resizeSnapshot(itemId),\n () => controller.resizeSnapshot(itemId),\n );\n return { ref, handleProps: { [RESIZE_HANDLE_ATTR]: true }, isResizing };\n}\n","import {\n type BreakpointCols,\n type Breakpoints,\n type Compactor,\n type Layout,\n type ResponsiveLayouts,\n findOrGenerateResponsiveLayout,\n getBreakpointFromWidth,\n getColsFromBreakpoint,\n verticalCompactor,\n} from \"@snapgridjs/core\";\nimport { useCallback, useEffect, useMemo, useRef } from \"react\";\n\n/** react-grid-layout's default breakpoints (px) and column counts. */\nexport const DEFAULT_BREAKPOINTS: Breakpoints = { lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 };\nexport const DEFAULT_BREAKPOINT_COLS: BreakpointCols = { lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 };\n\nexport interface UseResponsiveLayoutOptions {\n /** Current container width in pixels. */\n width: number;\n /** Controlled per-breakpoint layouts. Missing breakpoints are generated from the nearest one. */\n layouts: ResponsiveLayouts;\n /** Breakpoint → min width (px). @default lg/md/sm/xs/xxs */\n breakpoints?: Breakpoints;\n /** Breakpoint → column count. @default 12/10/6/4/2 */\n cols?: BreakpointCols;\n /** Compaction strategy used when generating a missing breakpoint's layout. */\n compactor?: Compactor;\n /** Called when a layout commits: the active layout and the updated map. */\n onLayoutChange?: (layout: Layout, layouts: ResponsiveLayouts) => void;\n /** Called when the active breakpoint changes. */\n onBreakpointChange?: (breakpoint: string, cols: number) => void;\n}\n\nexport interface UseResponsiveLayoutResult {\n /** The active breakpoint name. */\n breakpoint: string;\n /** Column count for the active breakpoint. */\n cols: number;\n /** The resolved layout for the active breakpoint (generated if absent). */\n layout: Layout;\n /** Pass to the grid's `onLayoutChange`; updates the active breakpoint's layout. */\n onLayoutChange: (layout: Layout) => void;\n}\n\n/**\n * Headless responsive layout engine: resolves the active breakpoint and its\n * column count/layout from the container width, generating a layout for the\n * active breakpoint from the nearest one when missing.\n */\nexport function useResponsiveLayout(\n options: UseResponsiveLayoutOptions,\n): UseResponsiveLayoutResult {\n const {\n width,\n layouts,\n breakpoints = DEFAULT_BREAKPOINTS,\n cols = DEFAULT_BREAKPOINT_COLS,\n compactor = verticalCompactor,\n onLayoutChange,\n onBreakpointChange,\n } = options;\n\n const breakpoint = getBreakpointFromWidth(breakpoints, width);\n const colCount = getColsFromBreakpoint(breakpoint, cols);\n\n // Memoized so the clone + compact over every item only runs when an input\n // actually changes (not on every render/width tick). The fallback source for\n // generating a missing breakpoint — used by findOrGenerateResponsiveLayout\n // only when no provided breakpoint sits at/above the target — is the widest\n // provided layout. Derived purely from inputs (no ref mutated in an effect),\n // so generation is a pure function of render inputs (StrictMode/concurrent\n // safe) and no longer depends on the order breakpoints were visited.\n const layout = useMemo(() => {\n let source = breakpoint;\n let sourceWidth = Number.NEGATIVE_INFINITY;\n for (const [bp, minWidth] of Object.entries(breakpoints)) {\n if (layouts[bp] && minWidth > sourceWidth) {\n sourceWidth = minWidth;\n source = bp;\n }\n }\n return findOrGenerateResponsiveLayout(\n layouts,\n breakpoints,\n breakpoint,\n source,\n colCount,\n compactor,\n );\n }, [layouts, breakpoints, breakpoint, colCount, compactor]);\n\n // Fire onBreakpointChange when the active breakpoint actually changes. This ref\n // is written only inside the effect (never read during render), so render stays pure.\n const onBreakpointChangeRef = useRef(onBreakpointChange);\n onBreakpointChangeRef.current = onBreakpointChange;\n const firedBreakpointRef = useRef(breakpoint);\n useEffect(() => {\n if (firedBreakpointRef.current !== breakpoint) {\n firedBreakpointRef.current = breakpoint;\n onBreakpointChangeRef.current?.(breakpoint, colCount);\n }\n }, [breakpoint, colCount]);\n\n const handleLayoutChange = useCallback(\n (next: Layout) => {\n onLayoutChange?.(next, { ...layouts, [breakpoint]: next });\n },\n [onLayoutChange, layouts, breakpoint],\n );\n\n return { breakpoint, cols: colCount, layout, onLayoutChange: handleLayoutChange };\n}\n","import type { ResizeHandleAxis } from \"@snapgridjs/core\";\nimport { type CSSProperties, type ReactNode, memo } from \"react\";\nimport { useGridItem } from \"../hooks/useGridItem.js\";\nimport { useGridResizeHandle } from \"../hooks/useGridResizeHandle.js\";\nimport { useResolveController } from \"../hooks/useResolveController.js\";\n\nexport interface GridItemProps {\n /** Matches the layout item's `i`. */\n id: string;\n /** The owning grid's id (from its useGridContainer). */\n group: string;\n children: ReactNode;\n /** Appended to the default `snapgrid-item` class. */\n className?: string;\n /** Merged over (and able to override) the positioning style. */\n style?: CSSProperties;\n}\n\nconst HANDLE_CURSOR: Record<ResizeHandleAxis, string> = {\n n: \"ns-resize\",\n s: \"ns-resize\",\n e: \"ew-resize\",\n w: \"ew-resize\",\n se: \"nwse-resize\",\n nw: \"nwse-resize\",\n ne: \"nesw-resize\",\n sw: \"nesw-resize\",\n};\n\nconst SIDE = 14;\nfunction handleStyle(handle: ResizeHandleAxis): CSSProperties {\n const s: CSSProperties = {\n position: \"absolute\",\n width: SIDE,\n height: SIDE,\n cursor: HANDLE_CURSOR[handle],\n touchAction: \"none\",\n zIndex: 4,\n };\n if (handle.includes(\"n\")) s.top = -SIDE / 2;\n if (handle.includes(\"s\")) s.bottom = -SIDE / 2;\n if (handle.includes(\"e\")) s.right = -SIDE / 2;\n if (handle.includes(\"w\")) s.left = -SIDE / 2;\n if (handle === \"n\" || handle === \"s\") {\n s.left = `calc(50% - ${SIDE / 2}px)`;\n }\n if (handle === \"e\" || handle === \"w\") {\n s.top = `calc(50% - ${SIDE / 2}px)`;\n }\n return s;\n}\n\nfunction DefaultResizeHandle({\n itemId,\n handle,\n group,\n}: { itemId: string; handle: ResizeHandleAxis; group: string }) {\n const { ref, handleProps } = useGridResizeHandle(itemId, handle, group);\n return (\n <span\n ref={ref}\n {...handleProps}\n className={`snapgrid-resize-handle snapgrid-resize-handle--${handle}`}\n style={handleStyle(handle)}\n />\n );\n}\n\n/**\n * Convenience wrapper over {@link useGridItem}: an absolutely-positioned `<div>`\n * with stable hooks (`.snapgrid-item`, `data-grid-id`, `data-dragging`) and the\n * configured resize handles. `group` is the owning grid's id. For full control,\n * use the hooks directly.\n *\n * Memoized so re-rendering the surface (e.g. its auto-height tracking the drag)\n * doesn't re-render every tile — a tile re-renders only when its own slice\n * changes (via useGridItem's subscription). Keeps a drag's React work scoped to\n * the moved tile (see renderScope.test).\n */\nfunction GridItemImpl({ id, group, children, className, style }: GridItemProps) {\n const controller = useResolveController(group);\n const { ref, style: positionStyle, isDragging } = useGridItem(id, group);\n const config = controller.config;\n const handles = config?.isItemResizable(id) ? config.resizeHandlesFor(id) : [];\n return (\n <div\n ref={ref}\n data-grid-id={id}\n data-dragging={isDragging || undefined}\n className={className ? `snapgrid-item ${className}` : \"snapgrid-item\"}\n style={style ? { ...positionStyle, ...style } : positionStyle}\n >\n {children}\n {handles.map((handle) => (\n <DefaultResizeHandle key={handle} itemId={id} handle={handle} group={group} />\n ))}\n </div>\n );\n}\n\nexport const GridItem = memo(GridItemImpl);\n","import type { CSSProperties } from \"react\";\nimport { useGridPlaceholder } from \"../hooks/useGridPlaceholder.js\";\nimport { REFLOW_TRANSITION } from \"../reflow.js\";\n\nexport interface GridPlaceholderProps {\n /** The owning grid's id (from its useGridContainer). */\n group: string;\n /** Appended to the default `snapgrid-placeholder` class. */\n className?: string;\n /** Merged over (and able to override) the default look. */\n style?: CSSProperties;\n}\n\nconst DEFAULT_LOOK: CSSProperties = {\n background: \"rgba(99, 102, 241, 0.2)\",\n border: \"1px dashed rgba(99, 102, 241, 0.6)\",\n borderRadius: 4,\n boxSizing: \"border-box\",\n zIndex: 2,\n transition: REFLOW_TRANSITION,\n};\n\n/**\n * Convenience placeholder rendered from {@link useGridPlaceholder}. Renders\n * nothing when no drag is active. For a custom placeholder, call the hook\n * directly and render your own element with the returned `style`.\n */\nexport function GridPlaceholder({ group, className, style }: GridPlaceholderProps) {\n const placeholder = useGridPlaceholder(group);\n if (!placeholder) return null;\n return (\n <div\n aria-hidden=\"true\"\n className={className ? `snapgrid-placeholder ${className}` : \"snapgrid-placeholder\"}\n style={{ ...placeholder.style, ...DEFAULT_LOOK, ...style }}\n />\n );\n}\n","import { DragDropProvider } from \"@dnd-kit/react\";\nimport {\n type CSSProperties,\n Children,\n type ReactNode,\n createContext,\n isValidElement,\n useContext,\n} from \"react\";\nimport { useGridContainer } from \"../hooks/useGridContainer.js\";\nimport type { UseGridControllerOptions } from \"../hooks/useGridController.js\";\nimport { GridItem } from \"./GridItem.js\";\nimport { GridPlaceholder } from \"./GridPlaceholder.js\";\n\nexport interface GridLayoutProps extends UseGridControllerOptions {\n children: ReactNode;\n /** Appended to the default `snapgrid` class on the surface. */\n className?: string;\n /** Merged over (and able to override) the surface's positioning style. */\n style?: CSSProperties;\n}\n\n// Marks that a snapgrid-managed <DragDropProvider> already exists above, so a\n// nested GridLayout (or sibling sharing one) doesn't mint a second manager.\nconst InProvider = createContext(false);\n\n/** Strip the namespacing prefix React applies to keys inside `Children.map`. */\nfunction keyToId(key: string): string {\n return key.startsWith(\".$\") ? key.slice(2) : key;\n}\n\n/** The default surface: positioned container + mapped items + placeholder. */\nfunction GridSurface({ className, style, children, ...opts }: GridLayoutProps) {\n const { containerProps, group } = useGridContainer(opts);\n return (\n <div\n {...containerProps}\n className={className ? `snapgrid ${className}` : \"snapgrid\"}\n style={style ? { ...containerProps.style, ...style } : containerProps.style}\n >\n {Children.map(children, (child) => {\n if (!isValidElement(child) || child.key == null) return child;\n return (\n <GridItem key={child.key} id={keyToId(String(child.key))} group={group}>\n {child}\n </GridItem>\n );\n })}\n <GridPlaceholder group={group} />\n </div>\n );\n}\n\n/**\n * Drop-in grid component: a controlled, react-grid-layout v2-compatible layout\n * backed by dnd-kit. A thin shell over {@link useGridContainer} and the headless\n * hooks — children are keyed by their layout item's `i`. For full control over\n * markup/styling, use the hooks directly.\n *\n * Supplies the dnd-kit `DragDropProvider` for the turnkey case so consumers\n * don't manage one. Nest multiple `GridLayout`s and they share one provider\n * (the seam for cross-grid drags); a consumer's own provider is also honored.\n */\nexport function GridLayout(props: GridLayoutProps): React.JSX.Element {\n const inProvider = useContext(InProvider);\n const surface = <GridSurface {...props} />;\n if (inProvider) return surface;\n return (\n <DragDropProvider>\n <InProvider.Provider value={true}>{surface}</InProvider.Provider>\n </DragDropProvider>\n );\n}\n\n/**\n * Share one dnd-kit `DragDropProvider` across several sibling grids so tiles can\n * be dragged between them. (Nested `GridLayout`s already share a provider; this\n * is for siblings.) A thin wrapper over `DragDropProvider` — the cross-grid seam\n * is the shared manager + collision target.\n */\nexport function SnapGridGroup({ children }: { children: ReactNode }): React.JSX.Element {\n const inProvider = useContext(InProvider);\n if (inProvider) return <>{children}</>;\n return (\n <DragDropProvider>\n <InProvider.Provider value={true}>{children}</InProvider.Provider>\n </DragDropProvider>\n );\n}\n","import type {\n BreakpointCols,\n Breakpoints,\n Compactor,\n Layout,\n ResponsiveLayouts,\n} from \"@snapgridjs/core\";\nimport type { DragConfig, ResizeConfig } from \"@snapgridjs/dnd\";\nimport { type CSSProperties, type ReactNode, useMemo } from \"react\";\nimport { useResponsiveLayout } from \"../hooks/useResponsiveLayout.js\";\nimport { GridLayout } from \"./GridLayout.js\";\n\nexport interface ResponsiveGridLayoutProps {\n /** Container width in pixels (e.g. from {@link useContainerWidth}). */\n width: number;\n /** Controlled per-breakpoint layouts. Children are keyed by item `i`. */\n layouts: ResponsiveLayouts;\n /** Called when a layout commits: the active layout and the updated map. */\n onLayoutChange?: (layout: Layout, layouts: ResponsiveLayouts) => void;\n /** Called when the active breakpoint changes. */\n onBreakpointChange?: (breakpoint: string, cols: number) => void;\n /** Breakpoint → min width (px). @default lg/md/sm/xs/xxs */\n breakpoints?: Breakpoints;\n /** Breakpoint → column count. @default 12/10/6/4/2 */\n cols?: BreakpointCols;\n rowHeight?: number;\n margin?: [number, number];\n containerPadding?: [number, number] | null;\n compactor?: Compactor;\n dragConfig?: DragConfig;\n resizeConfig?: ResizeConfig;\n isDraggable?: boolean;\n isResizable?: boolean;\n autoSize?: boolean;\n className?: string;\n style?: CSSProperties;\n children: ReactNode;\n}\n\n/**\n * A responsive grid: switches column count and layout by breakpoint as `width`\n * changes, generating a breakpoint's layout from the nearest one when absent.\n * A thin wrapper over {@link useResponsiveLayout} + {@link GridLayout}; mirrors\n * react-grid-layout v2's `ResponsiveGridLayout`.\n */\nexport function ResponsiveGridLayout(props: ResponsiveGridLayoutProps): React.JSX.Element {\n const { cols, layout, onLayoutChange } = useResponsiveLayout({\n width: props.width,\n layouts: props.layouts,\n breakpoints: props.breakpoints,\n cols: props.cols,\n compactor: props.compactor,\n onLayoutChange: props.onLayoutChange,\n onBreakpointChange: props.onBreakpointChange,\n });\n\n // Stable object identity so the grid host's gridConfig/positionParams memos\n // aren't busted on every render (e.g. each width tick).\n const gridConfig = useMemo(\n () => ({\n cols,\n rowHeight: props.rowHeight ?? 150,\n margin: props.margin ?? ([10, 10] as [number, number]),\n containerPadding: props.containerPadding ?? null,\n }),\n [cols, props.rowHeight, props.margin, props.containerPadding],\n );\n\n return (\n // No explicit `id`: useGridContainer mints a stable per-instance id (useId),\n // which avoids droppable/registry identity churn when the breakpoint changes and\n // keeps two responsive grids in a group from colliding on the same id.\n <GridLayout\n layout={layout}\n width={props.width}\n onLayoutChange={onLayoutChange}\n gridConfig={gridConfig}\n compactor={props.compactor}\n dragConfig={props.dragConfig}\n resizeConfig={props.resizeConfig}\n isDraggable={props.isDraggable}\n isResizable={props.isResizable}\n autoSize={props.autoSize}\n className={props.className}\n style={props.style}\n >\n {props.children}\n </GridLayout>\n );\n}\n","import { useCallback, useEffect, useLayoutEffect, useState } from \"react\";\n\n// useLayoutEffect warns when run on the server; fall back to useEffect there so\n// the hook is SSR-safe (Next.js / Remix). The initial `width` is `initialWidth`\n// on both server and client, so the first render matches and there's no\n// hydration mismatch — the measured width is applied right after mount.\nconst useIsomorphicLayoutEffect = typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\nexport interface UseContainerWidthOptions {\n /** Width to use until the element has been measured. @default 1280 */\n initialWidth?: number;\n}\n\nexport interface UseContainerWidthResult {\n /** Measured container width in pixels (or `initialWidth` before mount). */\n width: number;\n /** Whether the element has been measured at least once. */\n mounted: boolean;\n /** Attach to the element whose width should drive the grid. */\n containerRef: (element: HTMLElement | null) => void;\n}\n\n/**\n * Measure a container's width with a `ResizeObserver`. Replaces react-grid-layout's\n * `WidthProvider` HOC with a hook, mirroring RGL v2's `useContainerWidth`.\n */\nexport function useContainerWidth(options: UseContainerWidthOptions = {}): UseContainerWidthResult {\n const { initialWidth = 1280 } = options;\n const [width, setWidth] = useState(initialWidth);\n const [mounted, setMounted] = useState(false);\n // Track the element in state so the observer effect re-runs when it changes;\n // this is StrictMode-safe (the effect's cleanup disconnects the observer).\n const [element, setElement] = useState<HTMLElement | null>(null);\n const containerRef = useCallback((node: HTMLElement | null) => setElement(node), []);\n\n useIsomorphicLayoutEffect(() => {\n if (!element || typeof ResizeObserver === \"undefined\") return;\n const measure = () => {\n const next = element.getBoundingClientRect().width;\n if (next > 0) {\n setWidth(next);\n setMounted(true);\n }\n };\n measure();\n const observer = new ResizeObserver(measure);\n observer.observe(element);\n return () => observer.disconnect();\n }, [element]);\n\n return { width, mounted, containerRef };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["defaultGridConfig","toPositionParams","verticalCompactor","useDroppable","Feedback","useDraggable","verticalCompactor"],"sources":["../src/hooks/useGridController.ts","../src/hooks/useGridContainer.ts","../src/reflow.ts","../src/hooks/useResolveController.ts","../src/hooks/useGridItem.ts","../src/hooks/useGridPlaceholder.ts","../src/hooks/useGridResizeHandle.ts","../src/hooks/useResponsiveLayout.ts","../src/components/GridItem.tsx","../src/components/GridPlaceholder.tsx","../src/components/GridLayout.tsx","../src/components/ResponsiveGridLayout.tsx","../src/hooks/useContainerWidth.ts"],"sourcesContent":["import { useDragDropManager, useInstance } from \"@dnd-kit/react\";\nimport {\n type Compactor,\n type GridConfig,\n type Layout,\n type LayoutItem,\n type PositionParams,\n defaultGridConfig,\n toPositionParams,\n verticalCompactor,\n} from \"@snapgridjs/core\";\nimport {\n type DragConfig,\n type DragSourceInfo,\n type DropConfig,\n GridController,\n type GridEventCallback,\n type ResizeConfig,\n SnapToGrid,\n attachEngine,\n buildItemSensors,\n registerController,\n} from \"@snapgridjs/dnd\";\nimport { useCallback, useEffect, useId, useMemo, useRef } from \"react\";\n\nconst DEFAULT_HANDLES = [\"se\"] as const;\n\n// Per-item drag/resize gate. Mirrors RGL's engine rule: a `static` item is locked\n// unless its flag (`isDraggable`/`isResizable`) is explicitly `true` (\"pinned\");\n// a non-static item just follows the flag (default `true`).\nfunction itemGateOpen(flag: boolean | undefined, isStatic: boolean | undefined): boolean {\n return isStatic ? flag === true : (flag ?? true);\n}\n\n/** Options the grid host ({@link useGridContainer}) feeds the controller. */\nexport interface UseGridControllerOptions {\n /** Stable id for the grid's droppable surface (auto-generated if omitted). */\n id?: string;\n /** Container width in pixels (e.g. from {@link useContainerWidth}). */\n width: number;\n /** Controlled layout. Never mutated. */\n layout: Layout;\n onLayoutChange?: (layout: Layout) => void;\n gridConfig?: Partial<GridConfig>;\n dragConfig?: DragConfig;\n resizeConfig?: ResizeConfig;\n dropConfig?: DropConfig;\n /**\n * Accept additional (non-grid) dnd-kit draggables as drop targets — e.g. a\n * `useSortable` card from a sibling list, for interop. Extends the built-in\n * acceptance (grid tiles + `snapGridDrop` externals); the ancestry guard still\n * applies. You drive the actual receive in your own `onDragOver` with `snapMove`.\n */\n accept?: (source: DragSourceInfo) => boolean;\n compactor?: Compactor;\n isDraggable?: boolean;\n isResizable?: boolean;\n autoSize?: boolean;\n onDragStart?: GridEventCallback;\n onDrag?: GridEventCallback;\n onDragStop?: GridEventCallback;\n onResizeStart?: GridEventCallback;\n onResize?: GridEventCallback;\n onResizeStop?: GridEventCallback;\n onDrop?: (layout: Layout, item: LayoutItem, event: Event | null) => void;\n}\n\n/**\n * The grid's React seam: owns the {@link GridController} (an observable render\n * bridge), publishes per-grid config to it each render, registers it for id →\n * controller resolution, and attaches the manager-wide {@link SnapGridEngine}.\n *\n * The drag/resize *orchestration* lives in the engine (one per manager), not\n * here — this hook only wires the React-specific parts: the controller, the item\n * sensors/modifiers descriptors, the draggable/resizable gates, and the config\n * the engine reads. Created by {@link useGridContainer}; items resolve the same\n * controller by their `group` (= this grid's id). Consumes the ambient\n * `DragDropProvider` — it does not mint one.\n */\nexport function useGridController(opts: UseGridControllerOptions): GridController {\n const autoId = useId();\n const containerId = opts.id ?? autoId;\n\n const gridConfig: GridConfig = useMemo(\n () => ({ ...defaultGridConfig, ...opts.gridConfig }),\n [opts.gridConfig],\n );\n const positionParams: PositionParams = useMemo(\n () => toPositionParams(gridConfig, opts.width),\n [gridConfig, opts.width],\n );\n const compactor: Compactor = opts.compactor ?? verticalCompactor;\n\n const manager = useDragDropManager();\n const controller = useInstance<GridController>(\n (m) => new GridController(containerId, opts.layout, m ?? undefined),\n );\n controller.setCommitted(opts.layout);\n // useInstance creates the controller once, freezing its id to the first render's\n // value; re-point it if the controlled `id` prop changes so the group, the\n // droppable id, and the registry key (below) stay in sync. (Read during render,\n // before useGridContainer's droppable/group read controller.id.)\n if (controller.id !== containerId) controller.setId(containerId);\n\n // Live refs for the item sensor/modifier descriptors, which read config lazily\n // (they're built once but must see the latest dragConfig / positionParams).\n const optsRef = useRef(opts);\n optsRef.current = opts;\n const ppRef = useRef(positionParams);\n ppRef.current = positionParams;\n\n // Register the controller so items (and snapMove) resolve it by id, and so the\n // engine can find it as a drag's source/destination. During render so child\n // items resolve it on their first render (children render after the parent but\n // before any layout effect). The effect's cleanup unregisters on unmount / id\n // or manager change.\n registerController(manager, containerId, controller);\n useEffect(\n () => registerController(manager, containerId, controller),\n [manager, containerId, controller],\n );\n\n // Attach the manager-wide drag/resize engine (ref-counted; one per manager,\n // shared by every grid on it). Detaches when the last grid for this manager\n // unmounts. No-op without a manager (no provider above).\n useEffect(() => {\n if (!manager) return;\n return attachEngine(manager);\n }, [manager]);\n\n const committedById = useMemo(\n () => new Map<string, LayoutItem>(opts.layout.map((it) => [it.i, it])),\n [opts.layout],\n );\n\n const dragThreshold = opts.dragConfig?.threshold ?? 3;\n const itemSensors = useMemo(\n () => buildItemSensors(dragThreshold, () => optsRef.current.dragConfig),\n [dragThreshold],\n );\n\n // Snap-to-grid modifier (stable descriptor; reads live refs so it never goes\n // stale). A no-op unless `dragConfig.snapToGrid` is set.\n const itemModifiers = useMemo(\n () => [\n SnapToGrid.configure({\n getPositionParams: () => ppRef.current,\n isEnabled: () => optsRef.current.dragConfig?.snapToGrid ?? false,\n }),\n ],\n [],\n );\n\n const gridDraggable = opts.isDraggable ?? true;\n const dragEnabled = opts.dragConfig?.enabled ?? true;\n const isItemDraggable = useCallback(\n (id: string) => {\n const it = committedById.get(id);\n if (!it) return false;\n return gridDraggable && dragEnabled && itemGateOpen(it.isDraggable, it.static);\n },\n [committedById, gridDraggable, dragEnabled],\n );\n\n const gridResizable = opts.isResizable ?? true;\n const resizeEnabled = opts.resizeConfig?.enabled ?? true;\n const isItemResizable = useCallback(\n (id: string) => {\n const it = committedById.get(id);\n if (!it) return false;\n return gridResizable && resizeEnabled && itemGateOpen(it.isResizable, it.static);\n },\n [committedById, gridResizable, resizeEnabled],\n );\n const defaultHandles = opts.resizeConfig?.handles;\n const resizeHandlesFor = useCallback(\n (id: string) => committedById.get(id)?.resizeHandles ?? defaultHandles ?? DEFAULT_HANDLES,\n [committedById, defaultHandles],\n );\n\n // The per-grid callbacks the engine invokes, memoized so a stable consumer\n // doesn't reallocate the object every render (rebuilt only when one changes).\n const callbacks = useMemo(\n () => ({\n onDragStart: opts.onDragStart,\n onDrag: opts.onDrag,\n onDragStop: opts.onDragStop,\n onResizeStart: opts.onResizeStart,\n onResize: opts.onResize,\n onResizeStop: opts.onResizeStop,\n onLayoutChange: opts.onLayoutChange,\n onDrop: opts.onDrop,\n }),\n [\n opts.onDragStart,\n opts.onDrag,\n opts.onDragStop,\n opts.onResizeStart,\n opts.onResize,\n opts.onResizeStop,\n opts.onLayoutChange,\n opts.onDrop,\n ],\n );\n\n // Publish per-grid config to the controller so items (resolved by group) read\n // fresh geometry/predicates without a React context, and the engine reads this\n // grid's geometry, compaction, gates, and callbacks.\n controller.setConfig({\n positionParams,\n gridConfig,\n width: opts.width,\n autoSize: opts.autoSize ?? true,\n itemSensors,\n itemModifiers,\n isItemDraggable,\n isItemResizable,\n resizeHandlesFor,\n compactor,\n dragConfig: opts.dragConfig,\n dropConfig: opts.dropConfig,\n callbacks,\n });\n\n return controller;\n}\n","import { useDroppable } from \"@dnd-kit/react\";\nimport { type GridConfig, bottom } from \"@snapgridjs/core\";\nimport {\n type GridController,\n SNAPGRID_GRID_ATTR,\n domElement,\n gridCollisionDetector,\n} from \"@snapgridjs/dnd\";\nimport { type CSSProperties, useCallback, useRef, useSyncExternalStore } from \"react\";\nimport { type UseGridControllerOptions, useGridController } from \"./useGridController.js\";\n\nexport interface GridContainerProps {\n /** Attach to your container element. */\n ref: (element: Element | null) => void;\n /** Positioning style (relative + width + auto-sized height). Spread onto your element. */\n style: CSSProperties;\n /** Present while a compatible draggable is over the grid. */\n \"data-drop-target\"?: true;\n}\n\nexport interface UseGridContainerResult {\n /** Spread onto your container element. */\n containerProps: GridContainerProps;\n /** True while a compatible draggable is over the grid. */\n isDropTarget: boolean;\n /** This grid's id — pass as the `group` to {@link useGridItem} for its tiles. */\n group: string;\n /** The grid's controller (for advanced/headless composition). */\n controller: GridController;\n}\n\n/** Total container height in pixels for the given number of occupied rows. */\nfunction containerHeight(rows: number, grid: GridConfig): number {\n const padY = (grid.containerPadding ?? grid.margin)[1];\n if (rows <= 0) return padY * 2;\n return padY * 2 + rows * grid.rowHeight + (rows - 1) * grid.margin[1];\n}\n\n/**\n * The grid host: creates this grid's controller + drag monitor (see\n * {@link useGridController}), registers the droppable surface, and returns props\n * to spread onto your own container element. Render `useGridItem` tiles inside,\n * passing `group` (this grid's id) so they resolve this controller.\n */\nexport function useGridContainer(opts: UseGridControllerOptions): UseGridContainerResult {\n const controller = useGridController(opts);\n const config = controller.config;\n const { width, autoSize, gridConfig } = config!;\n const gridElRef = useRef<Element | null>(null);\n\n const { ref, isDropTarget } = useDroppable({\n id: controller.id,\n type: \"grid\",\n // Accept grid tiles plus external draggables carrying a `snapGridDrop`\n // payload. The latter have no type, so `accept: \"grid-item\"` would reject\n // them and they'd never resolve as a drop target. (The provider still\n // decides whether to actually receive an external source via dropConfig.)\n accept: (source) => {\n // Reject a source whose element CONTAINS this grid — an ancestor tile that\n // hosts this nested grid. Prevents dropping a host tile into the grid it\n // contains (a paradox) now that nested grids can share one manager.\n const srcEl = domElement(source);\n if (srcEl && gridElRef.current && srcEl.contains(gridElRef.current)) return false;\n if (source.type === \"grid-item\") return true;\n const data = source.data as { snapGridDrop?: unknown } | undefined;\n if (data?.snapGridDrop != null) return true;\n // Consumer extension: accept foreign dnd-kit draggables (e.g. a sortable\n // card) as drop targets for interop; the receive is driven via snapMove.\n return opts.accept?.(source) ?? false;\n },\n collisionDetector: gridCollisionDetector,\n });\n\n // Merge dnd-kit's droppable ref with reporting the element to the controller\n // (the engine reads it to map the pointer to a cell when receiving a tile from\n // another grid), and mark the element so nested grids can measure their depth.\n const setRef = useCallback(\n (element: Element | null) => {\n ref(element);\n controller.element = element;\n gridElRef.current = element;\n if (element) element.setAttribute(SNAPGRID_GRID_ATTR, \"\");\n },\n [ref, controller],\n );\n\n // Subscribe to the rendered layout (drag preview while dragging, else\n // committed) so the surface auto-height tracks the content as it reflows.\n const renderedLayout = useSyncExternalStore(\n controller.subscribe,\n controller.renderedSnapshot,\n controller.renderedSnapshot,\n );\n const height = autoSize ? containerHeight(bottom(renderedLayout), gridConfig) : undefined;\n\n return {\n containerProps: {\n ref: setRef,\n style: { position: \"relative\", width, height },\n \"data-drop-target\": isDropTarget || undefined,\n },\n isDropTarget,\n group: controller.id,\n controller,\n };\n}\n","// Shared reflow timing for tiles and the placeholder, so they animate in lockstep\n// when a drag reflows the grid. Used by useGridItem (the tile's WAAPI reflow FLIP\n// and its out-of-drag CSS transition) and GridPlaceholder (its default look).\nexport const REFLOW_MS = 150;\nexport const REFLOW_EASING = \"ease\";\n// The placeholder is transform-positioned; this transitions its motion.\nexport const REFLOW_TRANSITION = `transform ${REFLOW_MS}ms ${REFLOW_EASING}, width ${REFLOW_MS}ms ${REFLOW_EASING}, height ${REFLOW_MS}ms ${REFLOW_EASING}`;\n// Tiles rest on left/top and animate POSITION via the compositor FLIP in useGridItem,\n// so their CSS transition covers SIZE only: a left/top transition would be copied onto\n// dnd-kit's float clone and fly it in from (0,0) at lift.\nexport const TILE_TRANSITION = `width ${REFLOW_MS}ms ${REFLOW_EASING}, height ${REFLOW_MS}ms ${REFLOW_EASING}`;\n","import { useDragDropManager } from \"@dnd-kit/react\";\nimport { type GridController, getController } from \"@snapgridjs/dnd\";\n\n/**\n * Resolve a grid's controller by its `group` (= the grid's id), scoped to the\n * ambient dnd-kit manager. Items declare `group` (mirroring useSortable); the\n * container registered the controller under that id. Throws a helpful error if\n * unresolved — almost always a missing `group` or a tile rendered outside any\n * grid / `DragDropProvider`.\n */\nexport function useResolveController(group: string): GridController {\n const manager = useDragDropManager();\n const controller = getController(manager, group);\n if (!controller) {\n throw new Error(\n `snapgrid: no grid found for group \"${group}\". A grid item must pass the group returned by its grid's useGridContainer, and render inside a <DragDropProvider> (or use <GridLayout>, which wires this for you).`,\n );\n }\n return controller;\n}\n","import { type Draggable, Feedback } from \"@dnd-kit/dom\";\nimport { isKeyboardEvent } from \"@dnd-kit/dom/utilities\";\nimport { useSortable } from \"@dnd-kit/react/sortable\";\nimport { type LayoutItem, calcGridItemPosition } from \"@snapgridjs/core\";\nimport {\n type CSSProperties,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useSyncExternalStore,\n} from \"react\";\nimport { REFLOW_EASING, REFLOW_MS, TILE_TRANSITION } from \"../reflow.js\";\nimport { useResolveController } from \"./useResolveController.js\";\n\n// A pointer drag floats the tile via dnd-kit's default feedback; a keyboard drag gets\n// `none` (no pointer — the tile steps in place via the session). The drop tween is\n// disabled so a pointer drop lands at the cell, not the float origin.\nconst ITEM_FEEDBACK = [\n Feedback.configure({\n feedback: (_source: Draggable, manager) =>\n isKeyboardEvent(manager.dragOperation.activatorEvent) ? \"none\" : \"default\",\n dropAnimation: null,\n }),\n];\n\n// A grid tile is never itself a drop target — the grid CONTAINER (a separate,\n// higher-priority droppable) is what a drag resolves onto. Keeping tiles out of the\n// target pool also stops dnd-kit's OptimisticSortingPlugin from reparenting a tile's\n// DOM node mid-drag (it acts only when source AND target are sortables) and then\n// fighting React's commit (`removeChild`).\nconst tileNeverTarget = () => null;\n\nexport interface UseGridItemResult {\n /** Attach to the element that represents this grid item. */\n ref: (element: Element | null) => void;\n /**\n * Optional drag handle (dnd-kit's native handle). Attach to a child element to\n * restrict **pointer** drag activation to it; leave it unattached and the whole\n * tile drags. Keyboard pickup (Enter/Space on a focused tile) is unaffected.\n */\n handleRef: (element: Element | null) => void;\n /** Positioning style to spread onto your element. */\n style: CSSProperties;\n /** True while this item is the active drag source. */\n isDragging: boolean;\n /** The item's current (possibly reflowed) layout entry. */\n item: LayoutItem | undefined;\n}\n\n/**\n * Headless hook for a single grid tile. The tile is a real `useSortable` (a\n * draggable + droppable carrying `group`/`index`/`type`/`accept`), so it\n * interoperates with the dnd-kit sortable ecosystem, yet it is positioned by RGL\n * via the {@link GridController}. `group` is the owning grid's id (from its\n * {@link useGridContainer}), mirroring `useSortable`'s `group`. Spread the returned\n * `ref`, optional `handleRef`, positioning `style`, and drag state onto whatever\n * element you render — you own the tag, className, content, and cosmetic styling.\n *\n * The dragged tile floats itself via dnd-kit's default feedback (no `<DragOverlay>`):\n * the active tile renders at its committed origin and dnd-kit's float follows the\n * pointer from there, while reflow is animated on the compositor via the Web\n * Animations API (a FLIP) — both so it stays smooth in Safari, where the float's\n * popover top-layer repaint would jank a CSS-transition reflow.\n *\n * Tiles are positioned with `left`/`top` (not `transform`). dnd-kit's self-float\n * measures the source element's rect ignoring transforms and re-applies its current\n * transform each frame; a transform-positioned tile leans on that, but the\n * compensation is lost the instant the dragged element is swapped for a foreign one\n * mid-drag (grid → sortable interop — the tile becomes a flow card), which would\n * make the float jump by the tile's grid offset. Plain left/top has nothing to lose\n * on the swap, matching how dnd-kit's own flow-positioned sortables hand off cleanly.\n */\nexport function useGridItem(id: string, group: string): UseGridItemResult {\n const controller = useResolveController(group);\n // Subscribe to just this item's slice → a drag elsewhere doesn't re-render it.\n const snap = useSyncExternalStore(\n controller.subscribe,\n () => controller.itemSnapshot(id),\n () => controller.itemSnapshot(id),\n );\n const item = snap.item;\n const active = snap.isDragging;\n // The controller's \"pointer move in progress\" signal (false for a keyboard drag).\n // We don't hide the tile (it floats itself) — we use it to decide whether to pin\n // the tile at its origin for the float.\n const hidden = snap.hidden;\n const config = controller.config!;\n\n // True on the single render where the tile goes active → settled (the drop frame):\n // snap to the landed cell instead of sliding there from the committed origin.\n const wasActive = useRef(false);\n const justDropped = wasActive.current && !active;\n wasActive.current = active;\n\n // Stable identity for the drag payload so dnd-kit doesn't churn on it every\n // render; it changes only when this tile's resolved entry does (a reflow).\n // `group` lets the engine resolve this tile's owning grid from the payload.\n const data = useMemo(\n () => ({ snapGrid: { kind: \"move\", itemId: id, item, group } }),\n [id, item, group],\n );\n\n const {\n ref: sortableRef,\n handleRef,\n isDragging,\n } = useSortable({\n id,\n index: controller.itemIndex(id),\n group,\n type: \"grid-item\",\n accept: \"grid-item\",\n // The tile is a sortable (so it interops + carries group/index), but never a\n // drop target — the grid container is. See {@link tileNeverTarget}.\n collisionDetector: tileNeverTarget,\n disabled: !config.isItemDraggable(id),\n sensors: config.itemSensors,\n modifiers: config.itemModifiers,\n // Keep the sortable defaults (optimistic + keyboard, needed for interop); just\n // append the feedback config.\n plugins: (defaults) => [...defaults, ...ITEM_FEEDBACK],\n // Carry the full item so a receiving grid can render/insert it on a cross-grid drop.\n data,\n });\n\n // Capture the element to drive the WAAPI reflow, while still feeding the sortable's ref.\n const elRef = useRef<Element | null>(null);\n const setRef = useCallback(\n (element: Element | null) => {\n sortableRef(element);\n elRef.current = element;\n },\n [sortableRef],\n );\n\n const session = controller.getSession();\n const dragging = session != null;\n\n // During a POINTER drag the active tile renders at its committed origin so dnd-kit's\n // float offset tracks the pointer; a keyboard drag (and every other tile) renders at\n // the reflowed (preview) cell so it steps with the arrow keys.\n const posItem = item ? (active && hidden ? (session?.anchor.item ?? item) : item) : undefined;\n const pos = posItem\n ? calcGridItemPosition(config.positionParams, posItem.x, posItem.y, posItem.w, posItem.h)\n : undefined;\n const posLeft = pos?.left;\n const posTop = pos?.top;\n\n // Reflow a tile to its new cell via a compositor FLIP: the resting left/top has\n // already jumped this render, so animate a `transform` delta from the tile's previous\n // visual position back to 0. Drives in-drag reflow AND out-of-drag (responsive /\n // programmatic) changes, and dodges the float's popover repaint that janks a CSS\n // transition in Safari. The drag source settling after a drop is the exception (see\n // the `settleAnchor` branch below).\n const prev = useRef<{ left: number; top: number } | null>(null);\n const reflowAnim = useRef<Animation | null>(null);\n const settleAnchor = useRef<{ left: number; top: number } | null>(null);\n useLayoutEffect(() => {\n const cur = posLeft != null && posTop != null ? { left: posLeft, top: posTop } : null;\n const before = prev.current;\n prev.current = cur;\n const el = elRef.current;\n if (!el || !cur) return;\n\n // Active: dnd-kit owns this tile's motion. Remember the cell it floats from so the\n // post-drop settle can snap instead of FLIP.\n if (active) {\n settleAnchor.current = cur;\n reflowAnim.current?.cancel();\n return;\n }\n // A drag of ANOTHER tile in this grid: this tile reflows normally; drop any stale\n // settle anchor so it FLIPs (it was never floated).\n if (dragging) settleAnchor.current = null;\n // Post-drop settle of the formerly-active source: it was floated, so `before` is the\n // committed origin, not where it visually was — snap (no FLIP) until the committed\n // move lands (cell leaves the anchor). Clearing earlier is unsafe: the drop's commit\n // can arrive a render after `active` clears, and on that frame a pending real move\n // and a no-op drop both read `cur === anchor`. The cost: a true no-op drop leaves the\n // anchor set until the next drag clears it (tiny, accepted — beats reopening the slide).\n else if (settleAnchor.current) {\n const a = settleAnchor.current;\n reflowAnim.current?.cancel();\n if (cur.left !== a.left || cur.top !== a.top) settleAnchor.current = null;\n return;\n }\n\n if (!before || justDropped) return;\n if (before.left === cur.left && before.top === cur.top) return;\n // Web Animations API may be absent (jsdom / SSR / very old browsers): degrade to\n // an instant move (the left/top below already places the tile) rather than throw.\n if (typeof el.animate !== \"function\") return;\n // Previous visual position = the prior resting cell plus any in-flight transform.\n let fromX = before.left;\n let fromY = before.top;\n if (reflowAnim.current?.playState === \"running\") {\n const m = new DOMMatrix(getComputedStyle(el).transform);\n fromX = before.left + m.m41;\n fromY = before.top + m.m42;\n }\n reflowAnim.current?.cancel();\n reflowAnim.current = el.animate(\n [\n { transform: `translate(${fromX - cur.left}px, ${fromY - cur.top}px)` },\n { transform: \"translate(0px, 0px)\" },\n ],\n { duration: REFLOW_MS, easing: REFLOW_EASING },\n );\n }, [posLeft, posTop, active, justDropped, dragging]);\n\n // Cancel any in-flight reflow animation when the tile unmounts (e.g. removed\n // mid-drag during a cross-grid move) so a running Animation can't outlive its node.\n useEffect(() => () => reflowAnim.current?.cancel(), []);\n\n // Tiles rest on left/top (see the hook doc above); position animates via the FLIP\n // above, so the transition is SIZE-only (TILE_TRANSITION) — and \"none\" while dragging\n // (FLIP owns motion) or just-dropped (it snaps). The active tile (⊂ dragging) hits \"none\".\n const style: CSSProperties = pos\n ? {\n position: \"absolute\",\n left: pos.left,\n top: pos.top,\n width: pos.width,\n height: pos.height,\n transition: justDropped || dragging ? \"none\" : TILE_TRANSITION,\n touchAction: \"none\",\n }\n : { position: \"absolute\", touchAction: \"none\" };\n\n return { ref: setRef, handleRef, style, isDragging, item };\n}\n","import { type LayoutItem, calcGridItemPosition } from \"@snapgridjs/core\";\nimport { type CSSProperties, useSyncExternalStore } from \"react\";\nimport { useResolveController } from \"./useResolveController.js\";\n\nexport interface GridPlaceholderInfo {\n /** The layout entry marking where the dragged item will land. */\n item: LayoutItem;\n /** Positioning style (left/top/size) to spread onto your placeholder element. */\n style: CSSProperties;\n}\n\n/**\n * Headless hook returning where the drag placeholder should be rendered, or\n * `null` when no drag is in progress. `group` is the owning grid's id (from its\n * {@link useGridContainer}). You render the element however you like.\n */\nexport function useGridPlaceholder(group: string): GridPlaceholderInfo | null {\n const controller = useResolveController(group);\n const placeholder = useSyncExternalStore(\n controller.subscribe,\n controller.placeholderSnapshot,\n controller.placeholderSnapshot,\n );\n if (!placeholder) return null;\n const pos = calcGridItemPosition(\n controller.config!.positionParams,\n placeholder.x,\n placeholder.y,\n placeholder.w,\n placeholder.h,\n );\n const style: CSSProperties = {\n position: \"absolute\",\n // Transform-positioned to match grid items (see useGridItem) — the\n // placeholder slides as a GPU transform, not an animated left/top.\n left: 0,\n top: 0,\n width: pos.width,\n height: pos.height,\n transform: `translate(${pos.left}px, ${pos.top}px)`,\n pointerEvents: \"none\",\n };\n return { item: placeholder, style };\n}\n","import { useDraggable } from \"@dnd-kit/react\";\nimport type { ResizeHandleAxis } from \"@snapgridjs/core\";\nimport { NO_FEEDBACK, RESIZE_HANDLE_ATTR } from \"@snapgridjs/dnd\";\nimport { useSyncExternalStore } from \"react\";\nimport { useResolveController } from \"./useResolveController.js\";\n\nexport interface UseGridResizeHandleResult {\n /** Attach to your resize-handle element. */\n ref: (element: Element | null) => void;\n /** Spread onto the handle element so item drags ignore pointer-downs on it. */\n handleProps: { [RESIZE_HANDLE_ATTR]: true };\n /** True while this item is actively being resized. */\n isResizing: boolean;\n}\n\n/**\n * Headless hook for a single resize handle. Model a handle as its own draggable;\n * dragging it resizes the item from the given edge/corner. `group` is the owning\n * grid's id (from its {@link useGridContainer}). Spread `ref` and `handleProps`\n * onto the handle element you position/style.\n */\nexport function useGridResizeHandle(\n itemId: string,\n handle: ResizeHandleAxis,\n group: string,\n): UseGridResizeHandleResult {\n const controller = useResolveController(group);\n const { ref } = useDraggable({\n id: `${itemId}::resize::${handle}`,\n disabled: !controller.config?.isItemResizable(itemId),\n plugins: NO_FEEDBACK,\n data: { snapGrid: { kind: \"resize\", itemId, handle, group } },\n });\n const { isResizing } = useSyncExternalStore(\n controller.subscribe,\n () => controller.resizeSnapshot(itemId),\n () => controller.resizeSnapshot(itemId),\n );\n return { ref, handleProps: { [RESIZE_HANDLE_ATTR]: true }, isResizing };\n}\n","import {\n type BreakpointCols,\n type Breakpoints,\n type Compactor,\n type Layout,\n type ResponsiveLayouts,\n findOrGenerateResponsiveLayout,\n getBreakpointFromWidth,\n getColsFromBreakpoint,\n verticalCompactor,\n} from \"@snapgridjs/core\";\nimport { useCallback, useEffect, useMemo, useRef } from \"react\";\n\n/** react-grid-layout's default breakpoints (px) and column counts. */\nexport const DEFAULT_BREAKPOINTS: Breakpoints = { lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 };\nexport const DEFAULT_BREAKPOINT_COLS: BreakpointCols = { lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 };\n\nexport interface UseResponsiveLayoutOptions {\n /** Current container width in pixels. */\n width: number;\n /** Controlled per-breakpoint layouts. Missing breakpoints are generated from the nearest one. */\n layouts: ResponsiveLayouts;\n /** Breakpoint → min width (px). @default lg/md/sm/xs/xxs */\n breakpoints?: Breakpoints;\n /** Breakpoint → column count. @default 12/10/6/4/2 */\n cols?: BreakpointCols;\n /** Compaction strategy used when generating a missing breakpoint's layout. */\n compactor?: Compactor;\n /** Called when a layout commits: the active layout and the updated map. */\n onLayoutChange?: (layout: Layout, layouts: ResponsiveLayouts) => void;\n /** Called when the active breakpoint changes. */\n onBreakpointChange?: (breakpoint: string, cols: number) => void;\n}\n\nexport interface UseResponsiveLayoutResult {\n /** The active breakpoint name. */\n breakpoint: string;\n /** Column count for the active breakpoint. */\n cols: number;\n /** The resolved layout for the active breakpoint (generated if absent). */\n layout: Layout;\n /** Pass to the grid's `onLayoutChange`; updates the active breakpoint's layout. */\n onLayoutChange: (layout: Layout) => void;\n}\n\n/**\n * Headless responsive layout engine: resolves the active breakpoint and its\n * column count/layout from the container width, generating a layout for the\n * active breakpoint from the nearest one when missing.\n */\nexport function useResponsiveLayout(\n options: UseResponsiveLayoutOptions,\n): UseResponsiveLayoutResult {\n const {\n width,\n layouts,\n breakpoints = DEFAULT_BREAKPOINTS,\n cols = DEFAULT_BREAKPOINT_COLS,\n compactor = verticalCompactor,\n onLayoutChange,\n onBreakpointChange,\n } = options;\n\n const breakpoint = getBreakpointFromWidth(breakpoints, width);\n const colCount = getColsFromBreakpoint(breakpoint, cols);\n\n // Memoized so the clone + compact over every item only runs when an input\n // actually changes (not on every render/width tick). The fallback source for\n // generating a missing breakpoint — used by findOrGenerateResponsiveLayout\n // only when no provided breakpoint sits at/above the target — is the widest\n // provided layout. Derived purely from inputs (no ref mutated in an effect),\n // so generation is a pure function of render inputs (StrictMode/concurrent\n // safe) and no longer depends on the order breakpoints were visited.\n const layout = useMemo(() => {\n let source = breakpoint;\n let sourceWidth = Number.NEGATIVE_INFINITY;\n for (const [bp, minWidth] of Object.entries(breakpoints)) {\n if (layouts[bp] && minWidth > sourceWidth) {\n sourceWidth = minWidth;\n source = bp;\n }\n }\n return findOrGenerateResponsiveLayout(\n layouts,\n breakpoints,\n breakpoint,\n source,\n colCount,\n compactor,\n );\n }, [layouts, breakpoints, breakpoint, colCount, compactor]);\n\n // Fire onBreakpointChange when the active breakpoint actually changes. This ref\n // is written only inside the effect (never read during render), so render stays pure.\n const onBreakpointChangeRef = useRef(onBreakpointChange);\n onBreakpointChangeRef.current = onBreakpointChange;\n const firedBreakpointRef = useRef(breakpoint);\n useEffect(() => {\n if (firedBreakpointRef.current !== breakpoint) {\n firedBreakpointRef.current = breakpoint;\n onBreakpointChangeRef.current?.(breakpoint, colCount);\n }\n }, [breakpoint, colCount]);\n\n const handleLayoutChange = useCallback(\n (next: Layout) => {\n onLayoutChange?.(next, { ...layouts, [breakpoint]: next });\n },\n [onLayoutChange, layouts, breakpoint],\n );\n\n return { breakpoint, cols: colCount, layout, onLayoutChange: handleLayoutChange };\n}\n","import type { ResizeHandleAxis } from \"@snapgridjs/core\";\nimport { type CSSProperties, type ReactNode, memo } from \"react\";\nimport { useGridItem } from \"../hooks/useGridItem.js\";\nimport { useGridResizeHandle } from \"../hooks/useGridResizeHandle.js\";\nimport { useResolveController } from \"../hooks/useResolveController.js\";\n\nexport interface GridItemProps {\n /** Matches the layout item's `i`. */\n id: string;\n /** The owning grid's id (from its useGridContainer). */\n group: string;\n children: ReactNode;\n /** Appended to the default `snapgrid-item` class. */\n className?: string;\n /** Merged over (and able to override) the positioning style. */\n style?: CSSProperties;\n}\n\nconst HANDLE_CURSOR: Record<ResizeHandleAxis, string> = {\n n: \"ns-resize\",\n s: \"ns-resize\",\n e: \"ew-resize\",\n w: \"ew-resize\",\n se: \"nwse-resize\",\n nw: \"nwse-resize\",\n ne: \"nesw-resize\",\n sw: \"nesw-resize\",\n};\n\nconst SIDE = 14;\nfunction handleStyle(handle: ResizeHandleAxis): CSSProperties {\n const s: CSSProperties = {\n position: \"absolute\",\n width: SIDE,\n height: SIDE,\n cursor: HANDLE_CURSOR[handle],\n touchAction: \"none\",\n zIndex: 4,\n };\n if (handle.includes(\"n\")) s.top = -SIDE / 2;\n if (handle.includes(\"s\")) s.bottom = -SIDE / 2;\n if (handle.includes(\"e\")) s.right = -SIDE / 2;\n if (handle.includes(\"w\")) s.left = -SIDE / 2;\n if (handle === \"n\" || handle === \"s\") {\n s.left = `calc(50% - ${SIDE / 2}px)`;\n }\n if (handle === \"e\" || handle === \"w\") {\n s.top = `calc(50% - ${SIDE / 2}px)`;\n }\n return s;\n}\n\nfunction DefaultResizeHandle({\n itemId,\n handle,\n group,\n}: { itemId: string; handle: ResizeHandleAxis; group: string }) {\n const { ref, handleProps } = useGridResizeHandle(itemId, handle, group);\n return (\n <span\n ref={ref}\n {...handleProps}\n className={`snapgrid-resize-handle snapgrid-resize-handle--${handle}`}\n style={handleStyle(handle)}\n />\n );\n}\n\n/**\n * Convenience wrapper over {@link useGridItem}: an absolutely-positioned `<div>`\n * with stable hooks (`.snapgrid-item`, `data-grid-id`, `data-dragging`) and the\n * configured resize handles. `group` is the owning grid's id. For full control,\n * use the hooks directly.\n *\n * Memoized so re-rendering the surface (e.g. its auto-height tracking the drag)\n * doesn't re-render every tile — a tile re-renders only when its own slice\n * changes (via useGridItem's subscription). Keeps a drag's React work scoped to\n * the moved tile (see renderScope.test).\n */\nfunction GridItemImpl({ id, group, children, className, style }: GridItemProps) {\n const controller = useResolveController(group);\n const { ref, style: positionStyle, isDragging } = useGridItem(id, group);\n const config = controller.config;\n const handles = config?.isItemResizable(id) ? config.resizeHandlesFor(id) : [];\n return (\n <div\n ref={ref}\n data-grid-id={id}\n data-dragging={isDragging || undefined}\n className={className ? `snapgrid-item ${className}` : \"snapgrid-item\"}\n style={style ? { ...positionStyle, ...style } : positionStyle}\n >\n {children}\n {handles.map((handle) => (\n <DefaultResizeHandle key={handle} itemId={id} handle={handle} group={group} />\n ))}\n </div>\n );\n}\n\nexport const GridItem = memo(GridItemImpl);\n","import type { CSSProperties } from \"react\";\nimport { useGridPlaceholder } from \"../hooks/useGridPlaceholder.js\";\nimport { REFLOW_TRANSITION } from \"../reflow.js\";\n\nexport interface GridPlaceholderProps {\n /** The owning grid's id (from its useGridContainer). */\n group: string;\n /** Appended to the default `snapgrid-placeholder` class. */\n className?: string;\n /** Merged over (and able to override) the default look. */\n style?: CSSProperties;\n}\n\nconst DEFAULT_LOOK: CSSProperties = {\n background: \"rgba(99, 102, 241, 0.2)\",\n border: \"1px dashed rgba(99, 102, 241, 0.6)\",\n borderRadius: 4,\n boxSizing: \"border-box\",\n zIndex: 2,\n transition: REFLOW_TRANSITION,\n};\n\n/**\n * Convenience placeholder rendered from {@link useGridPlaceholder}. Renders\n * nothing when no drag is active. For a custom placeholder, call the hook\n * directly and render your own element with the returned `style`.\n */\nexport function GridPlaceholder({ group, className, style }: GridPlaceholderProps) {\n const placeholder = useGridPlaceholder(group);\n if (!placeholder) return null;\n return (\n <div\n aria-hidden=\"true\"\n className={className ? `snapgrid-placeholder ${className}` : \"snapgrid-placeholder\"}\n style={{ ...placeholder.style, ...DEFAULT_LOOK, ...style }}\n />\n );\n}\n","import { DragDropProvider } from \"@dnd-kit/react\";\nimport {\n type CSSProperties,\n Children,\n type ReactNode,\n createContext,\n isValidElement,\n useContext,\n} from \"react\";\nimport { useGridContainer } from \"../hooks/useGridContainer.js\";\nimport type { UseGridControllerOptions } from \"../hooks/useGridController.js\";\nimport { GridItem } from \"./GridItem.js\";\nimport { GridPlaceholder } from \"./GridPlaceholder.js\";\n\nexport interface GridLayoutProps extends UseGridControllerOptions {\n children: ReactNode;\n /** Appended to the default `snapgrid` class on the surface. */\n className?: string;\n /** Merged over (and able to override) the surface's positioning style. */\n style?: CSSProperties;\n}\n\n// Marks that a snapgrid-managed <DragDropProvider> already exists above, so a\n// nested GridLayout (or sibling sharing one) doesn't mint a second manager.\nconst InProvider = createContext(false);\n\n/** Strip the namespacing prefix React applies to keys inside `Children.map`. */\nfunction keyToId(key: string): string {\n return key.startsWith(\".$\") ? key.slice(2) : key;\n}\n\n/** The default surface: positioned container + mapped items + placeholder. */\nfunction GridSurface({ className, style, children, ...opts }: GridLayoutProps) {\n const { containerProps, group } = useGridContainer(opts);\n return (\n <div\n {...containerProps}\n className={className ? `snapgrid ${className}` : \"snapgrid\"}\n style={style ? { ...containerProps.style, ...style } : containerProps.style}\n >\n {Children.map(children, (child) => {\n if (!isValidElement(child) || child.key == null) return child;\n return (\n <GridItem key={child.key} id={keyToId(String(child.key))} group={group}>\n {child}\n </GridItem>\n );\n })}\n <GridPlaceholder group={group} />\n </div>\n );\n}\n\n/**\n * Drop-in grid component: a controlled, react-grid-layout v2-compatible layout\n * backed by dnd-kit. A thin shell over {@link useGridContainer} and the headless\n * hooks — children are keyed by their layout item's `i`. For full control over\n * markup/styling, use the hooks directly.\n *\n * Supplies the dnd-kit `DragDropProvider` for the turnkey case so consumers\n * don't manage one. Nest multiple `GridLayout`s and they share one provider\n * (the seam for cross-grid drags); a consumer's own provider is also honored.\n */\nexport function GridLayout(props: GridLayoutProps): React.JSX.Element {\n const inProvider = useContext(InProvider);\n const surface = <GridSurface {...props} />;\n if (inProvider) return surface;\n return (\n <DragDropProvider>\n <InProvider.Provider value={true}>{surface}</InProvider.Provider>\n </DragDropProvider>\n );\n}\n\n/**\n * Share one dnd-kit `DragDropProvider` across several sibling grids so tiles can\n * be dragged between them. (Nested `GridLayout`s already share a provider; this\n * is for siblings.) A thin wrapper over `DragDropProvider` — the cross-grid seam\n * is the shared manager + collision target.\n */\nexport function SnapGridGroup({ children }: { children: ReactNode }): React.JSX.Element {\n const inProvider = useContext(InProvider);\n if (inProvider) return <>{children}</>;\n return (\n <DragDropProvider>\n <InProvider.Provider value={true}>{children}</InProvider.Provider>\n </DragDropProvider>\n );\n}\n","import type {\n BreakpointCols,\n Breakpoints,\n Compactor,\n Layout,\n ResponsiveLayouts,\n} from \"@snapgridjs/core\";\nimport type { DragConfig, ResizeConfig } from \"@snapgridjs/dnd\";\nimport { type CSSProperties, type ReactNode, useMemo } from \"react\";\nimport { useResponsiveLayout } from \"../hooks/useResponsiveLayout.js\";\nimport { GridLayout } from \"./GridLayout.js\";\n\nexport interface ResponsiveGridLayoutProps {\n /** Container width in pixels (e.g. from {@link useContainerWidth}). */\n width: number;\n /** Controlled per-breakpoint layouts. Children are keyed by item `i`. */\n layouts: ResponsiveLayouts;\n /** Called when a layout commits: the active layout and the updated map. */\n onLayoutChange?: (layout: Layout, layouts: ResponsiveLayouts) => void;\n /** Called when the active breakpoint changes. */\n onBreakpointChange?: (breakpoint: string, cols: number) => void;\n /** Breakpoint → min width (px). @default lg/md/sm/xs/xxs */\n breakpoints?: Breakpoints;\n /** Breakpoint → column count. @default 12/10/6/4/2 */\n cols?: BreakpointCols;\n rowHeight?: number;\n margin?: [number, number];\n containerPadding?: [number, number] | null;\n compactor?: Compactor;\n dragConfig?: DragConfig;\n resizeConfig?: ResizeConfig;\n isDraggable?: boolean;\n isResizable?: boolean;\n autoSize?: boolean;\n className?: string;\n style?: CSSProperties;\n children: ReactNode;\n}\n\n/**\n * A responsive grid: switches column count and layout by breakpoint as `width`\n * changes, generating a breakpoint's layout from the nearest one when absent.\n * A thin wrapper over {@link useResponsiveLayout} + {@link GridLayout}; mirrors\n * react-grid-layout v2's `ResponsiveGridLayout`.\n */\nexport function ResponsiveGridLayout(props: ResponsiveGridLayoutProps): React.JSX.Element {\n const { cols, layout, onLayoutChange } = useResponsiveLayout({\n width: props.width,\n layouts: props.layouts,\n breakpoints: props.breakpoints,\n cols: props.cols,\n compactor: props.compactor,\n onLayoutChange: props.onLayoutChange,\n onBreakpointChange: props.onBreakpointChange,\n });\n\n // Stable object identity so the grid host's gridConfig/positionParams memos\n // aren't busted on every render (e.g. each width tick).\n const gridConfig = useMemo(\n () => ({\n cols,\n rowHeight: props.rowHeight ?? 150,\n margin: props.margin ?? ([10, 10] as [number, number]),\n containerPadding: props.containerPadding ?? null,\n }),\n [cols, props.rowHeight, props.margin, props.containerPadding],\n );\n\n return (\n // No explicit `id`: useGridContainer mints a stable per-instance id (useId),\n // which avoids droppable/registry identity churn when the breakpoint changes and\n // keeps two responsive grids in a group from colliding on the same id.\n <GridLayout\n layout={layout}\n width={props.width}\n onLayoutChange={onLayoutChange}\n gridConfig={gridConfig}\n compactor={props.compactor}\n dragConfig={props.dragConfig}\n resizeConfig={props.resizeConfig}\n isDraggable={props.isDraggable}\n isResizable={props.isResizable}\n autoSize={props.autoSize}\n className={props.className}\n style={props.style}\n >\n {props.children}\n </GridLayout>\n );\n}\n","import { useCallback, useEffect, useLayoutEffect, useState } from \"react\";\n\n// useLayoutEffect warns when run on the server; fall back to useEffect there so\n// the hook is SSR-safe (Next.js / Remix). The initial `width` is `initialWidth`\n// on both server and client, so the first render matches and there's no\n// hydration mismatch — the measured width is applied right after mount.\nconst useIsomorphicLayoutEffect = typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\nexport interface UseContainerWidthOptions {\n /** Width to use until the element has been measured. @default 1280 */\n initialWidth?: number;\n}\n\nexport interface UseContainerWidthResult {\n /** Measured container width in pixels (or `initialWidth` before mount). */\n width: number;\n /** Whether the element has been measured at least once. */\n mounted: boolean;\n /** Attach to the element whose width should drive the grid. */\n containerRef: (element: HTMLElement | null) => void;\n}\n\n/**\n * Measure a container's width with a `ResizeObserver`. Replaces react-grid-layout's\n * `WidthProvider` HOC with a hook, mirroring RGL v2's `useContainerWidth`.\n */\nexport function useContainerWidth(options: UseContainerWidthOptions = {}): UseContainerWidthResult {\n const { initialWidth = 1280 } = options;\n const [width, setWidth] = useState(initialWidth);\n const [mounted, setMounted] = useState(false);\n // Track the element in state so the observer effect re-runs when it changes;\n // this is StrictMode-safe (the effect's cleanup disconnects the observer).\n const [element, setElement] = useState<HTMLElement | null>(null);\n const containerRef = useCallback((node: HTMLElement | null) => setElement(node), []);\n\n useIsomorphicLayoutEffect(() => {\n if (!element || typeof ResizeObserver === \"undefined\") return;\n const measure = () => {\n const next = element.getBoundingClientRect().width;\n if (next > 0) {\n setWidth(next);\n setMounted(true);\n }\n };\n measure();\n const observer = new ResizeObserver(measure);\n observer.observe(element);\n return () => observer.disconnect();\n }, [element]);\n\n return { width, mounted, containerRef };\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@snapgridjs/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "React grid-layout components built on dnd-kit — a react-grid-layout v2 alternative.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Edmond Leung",
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
"module": "./dist/index.mjs",
|
|
52
52
|
"types": "./dist/index.d.mts",
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@snapgridjs/core": "0.
|
|
55
|
-
"@snapgridjs/dnd": "0.
|
|
54
|
+
"@snapgridjs/core": "0.6.0",
|
|
55
|
+
"@snapgridjs/dnd": "0.6.0"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
58
|
"react": ">=18",
|