@snapgridjs/react 0.3.0 → 0.4.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 CHANGED
@@ -18,7 +18,7 @@ Draggable, resizable, responsive grid layouts for React — with pluggable packi
18
18
  - **Headless-first** — compose `useGridContainer` + hooks under a dnd-kit `DragDropProvider` for full control of your markup — or drop in the turnkey [`<GridLayout>`](https://snapgrid.dev/docs/guides/component-layer) (react-grid-layout-style) when you don't need that. Ships **no CSS**.
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
- - **Nested grids** — drop a grid inside a tile of another grid; each level keeps its own isolated drag session.
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
22
  - **Responsive** — per-breakpoint layouts with `<ResponsiveGridLayout>`.
23
23
  - **Keyboard accessible** — Enter/Space to pick up, arrow keys to move, Esc to cancel.
24
24
  - **SSR-safe** and **TypeScript-first** (types included).
package/dist/index.cjs CHANGED
@@ -2,11 +2,61 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  let _dnd_kit_react = require("@dnd-kit/react");
3
3
  let _snapgridjs_core = require("@snapgridjs/core");
4
4
  let react = require("react");
5
+ let _dnd_kit_collision = require("@dnd-kit/collision");
5
6
  let _dnd_kit_abstract = require("@dnd-kit/abstract");
6
7
  let _dnd_kit_dom = require("@dnd-kit/dom");
7
8
  let _dnd_kit_dom_utilities = require("@dnd-kit/dom/utilities");
8
9
  let _dnd_kit_react_sortable = require("@dnd-kit/react/sortable");
9
10
  let react_jsx_runtime = require("react/jsx-runtime");
11
+ //#region src/dnd/entity.ts
12
+ /**
13
+ * The DOM element of a dnd-kit entity (a draggable, droppable, or drag source).
14
+ * dnd-kit's abstract types don't expose `element`, but the DOM layer snapgrid
15
+ * runs on always sets it — this centralizes that one assumption (and the cast)
16
+ * in a single place instead of scattering it across the drag code.
17
+ */
18
+ function domElement(entity) {
19
+ return entity?.element ?? null;
20
+ }
21
+ //#endregion
22
+ //#region src/dnd/collision.ts
23
+ /**
24
+ * Marker attribute set on every grid container element. Used by {@link gridDepth}
25
+ * to measure how deeply a grid is nested, purely from the DOM.
26
+ */
27
+ const SNAPGRID_GRID_ATTR = "data-snapgrid-grid";
28
+ const GRID_COLLISION_PRIORITY = 10;
29
+ /**
30
+ * How deeply `el`'s grid is nested: the number of ancestor grid containers above
31
+ * it. A top-level grid is 0; a grid rendered inside another grid's tile is 1; and
32
+ * so on. DOM containment is the ground truth, so this is correct regardless of the
33
+ * React tree shape or how priorities are assigned elsewhere.
34
+ */
35
+ function gridDepth(el) {
36
+ let depth = 0;
37
+ let node = el?.parentElement ?? null;
38
+ while (node) {
39
+ if (node.hasAttribute("data-snapgrid-grid")) depth++;
40
+ node = node.parentElement;
41
+ }
42
+ return depth;
43
+ }
44
+ /**
45
+ * Collision detector for grid droppables. Runs dnd-kit's default detector, then —
46
+ * when nested grid rects overlap (the pointer is over both an inner grid and its
47
+ * outer one) — ranks the **innermost** grid highest by boosting priority with the
48
+ * grid's nesting depth. Without this, overlapping grids tie on priority and the
49
+ * winner is arbitrary. For non-nested grids depth is 0, so priority is unchanged.
50
+ */
51
+ const gridCollisionDetector = (input) => {
52
+ const collision = (0, _dnd_kit_collision.defaultCollisionDetection)(input);
53
+ if (!collision) return null;
54
+ return {
55
+ ...collision,
56
+ priority: GRID_COLLISION_PRIORITY + gridDepth(domElement(input.droppable))
57
+ };
58
+ };
59
+ //#endregion
10
60
  //#region src/controller/GridController.ts
11
61
  function sameItem(a, b) {
12
62
  if (a === b) return true;
@@ -441,7 +491,7 @@ function useGridController(opts) {
441
491
  top: rect.top,
442
492
  pointer
443
493
  }));
444
- const cr = (event.operation.source?.element)?.getBoundingClientRect();
494
+ const cr = domElement(event.operation.source)?.getBoundingClientRect();
445
495
  if (cr) setGrabOffset(managerRef.current, {
446
496
  x: pointer.x - cr.left,
447
497
  y: pointer.y - cr.top
@@ -650,7 +700,6 @@ function useGridController(opts) {
650
700
  }
651
701
  //#endregion
652
702
  //#region src/hooks/useGridContainer.ts
653
- const GRID_COLLISION_PRIORITY = 10;
654
703
  /** Total container height in pixels for the given number of occupied rows. */
655
704
  function containerHeight(rows, grid) {
656
705
  const padY = (grid.containerPadding ?? grid.margin)[1];
@@ -666,18 +715,23 @@ function containerHeight(rows, grid) {
666
715
  function useGridContainer(opts) {
667
716
  const controller = useGridController(opts);
668
717
  const { width, autoSize, gridConfig, setContainerElement } = controller.config;
718
+ const gridElRef = (0, react.useRef)(null);
669
719
  const { ref, isDropTarget } = (0, _dnd_kit_react.useDroppable)({
670
720
  id: controller.id,
671
721
  type: "grid",
672
722
  accept: (source) => {
723
+ const srcEl = domElement(source);
724
+ if (srcEl && gridElRef.current && srcEl.contains(gridElRef.current)) return false;
673
725
  if (source.type === "grid-item") return true;
674
726
  return source.data?.snapGridDrop != null;
675
727
  },
676
- collisionPriority: GRID_COLLISION_PRIORITY
728
+ collisionDetector: gridCollisionDetector
677
729
  });
678
730
  const setRef = (0, react.useCallback)((element) => {
679
731
  ref(element);
680
732
  setContainerElement(element);
733
+ gridElRef.current = element;
734
+ if (element) element.setAttribute(SNAPGRID_GRID_ATTR, "");
681
735
  }, [ref, setContainerElement]);
682
736
  const renderedLayout = (0, react.useSyncExternalStore)(controller.subscribe, controller.renderedSnapshot, controller.renderedSnapshot);
683
737
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/controller/GridController.ts","../src/types.ts","../src/hooks/useGridController.ts","../src/hooks/useGridContainer.ts","../src/hooks/useGridItem.ts","../src/hooks/useGridPlaceholder.ts","../src/hooks/dndShared.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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"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/controller/GridController.ts","../src/types.ts","../src/hooks/useGridController.ts","../src/hooks/useGridContainer.ts","../src/hooks/useGridItem.ts","../src/hooks/useGridPlaceholder.ts","../src/hooks/dndShared.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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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/controller/GridController.ts","../src/types.ts","../src/hooks/useGridController.ts","../src/hooks/useGridContainer.ts","../src/hooks/useGridItem.ts","../src/hooks/useGridPlaceholder.ts","../src/hooks/dndShared.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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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/controller/GridController.ts","../src/types.ts","../src/hooks/useGridController.ts","../src/hooks/useGridContainer.ts","../src/hooks/useGridItem.ts","../src/hooks/useGridPlaceholder.ts","../src/hooks/dndShared.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,11 +1,61 @@
1
1
  import { DragDropProvider, DragOverlay, useDragDropManager, useDragDropMonitor, useDraggable, useDraggable as useDraggable$1, useDroppable, useDroppable as useDroppable$1, useInstance } from "@dnd-kit/react";
2
2
  import { beginDrag, beginReceive, beginResize, bottom, calcGridColWidth, calcGridItemPosition, calcXY, commitLayout, defaultGridConfig, dragResize, dragTo, findOrGenerateResponsiveLayout, getBreakpointFromWidth, getColsFromBreakpoint, getCompactor, horizontalCompactor, noCompactor, nudge, removeItemWithCompactor, toPositionParams, verticalCompactor, verticalCompactor as verticalCompactor$1 } from "@snapgridjs/core";
3
3
  import { Children, createContext, isValidElement, memo, useCallback, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
4
+ import { defaultCollisionDetection } from "@dnd-kit/collision";
4
5
  import { Modifier } from "@dnd-kit/abstract";
5
6
  import { Feedback, Feedback as Feedback$1, KeyboardSensor, KeyboardSensor as KeyboardSensor$1, PointerActivationConstraints, PointerSensor, PointerSensor as PointerSensor$1 } from "@dnd-kit/dom";
6
7
  import { isKeyboardEvent } from "@dnd-kit/dom/utilities";
7
8
  import { useSortable } from "@dnd-kit/react/sortable";
8
9
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
+ //#region src/dnd/entity.ts
11
+ /**
12
+ * The DOM element of a dnd-kit entity (a draggable, droppable, or drag source).
13
+ * dnd-kit's abstract types don't expose `element`, but the DOM layer snapgrid
14
+ * runs on always sets it — this centralizes that one assumption (and the cast)
15
+ * in a single place instead of scattering it across the drag code.
16
+ */
17
+ function domElement(entity) {
18
+ return entity?.element ?? null;
19
+ }
20
+ //#endregion
21
+ //#region src/dnd/collision.ts
22
+ /**
23
+ * Marker attribute set on every grid container element. Used by {@link gridDepth}
24
+ * to measure how deeply a grid is nested, purely from the DOM.
25
+ */
26
+ const SNAPGRID_GRID_ATTR = "data-snapgrid-grid";
27
+ const GRID_COLLISION_PRIORITY = 10;
28
+ /**
29
+ * How deeply `el`'s grid is nested: the number of ancestor grid containers above
30
+ * it. A top-level grid is 0; a grid rendered inside another grid's tile is 1; and
31
+ * so on. DOM containment is the ground truth, so this is correct regardless of the
32
+ * React tree shape or how priorities are assigned elsewhere.
33
+ */
34
+ function gridDepth(el) {
35
+ let depth = 0;
36
+ let node = el?.parentElement ?? null;
37
+ while (node) {
38
+ if (node.hasAttribute("data-snapgrid-grid")) depth++;
39
+ node = node.parentElement;
40
+ }
41
+ return depth;
42
+ }
43
+ /**
44
+ * Collision detector for grid droppables. Runs dnd-kit's default detector, then —
45
+ * when nested grid rects overlap (the pointer is over both an inner grid and its
46
+ * outer one) — ranks the **innermost** grid highest by boosting priority with the
47
+ * grid's nesting depth. Without this, overlapping grids tie on priority and the
48
+ * winner is arbitrary. For non-nested grids depth is 0, so priority is unchanged.
49
+ */
50
+ const gridCollisionDetector = (input) => {
51
+ const collision = defaultCollisionDetection(input);
52
+ if (!collision) return null;
53
+ return {
54
+ ...collision,
55
+ priority: GRID_COLLISION_PRIORITY + gridDepth(domElement(input.droppable))
56
+ };
57
+ };
58
+ //#endregion
9
59
  //#region src/controller/GridController.ts
10
60
  function sameItem(a, b) {
11
61
  if (a === b) return true;
@@ -440,7 +490,7 @@ function useGridController(opts) {
440
490
  top: rect.top,
441
491
  pointer
442
492
  }));
443
- const cr = (event.operation.source?.element)?.getBoundingClientRect();
493
+ const cr = domElement(event.operation.source)?.getBoundingClientRect();
444
494
  if (cr) setGrabOffset(managerRef.current, {
445
495
  x: pointer.x - cr.left,
446
496
  y: pointer.y - cr.top
@@ -649,7 +699,6 @@ function useGridController(opts) {
649
699
  }
650
700
  //#endregion
651
701
  //#region src/hooks/useGridContainer.ts
652
- const GRID_COLLISION_PRIORITY = 10;
653
702
  /** Total container height in pixels for the given number of occupied rows. */
654
703
  function containerHeight(rows, grid) {
655
704
  const padY = (grid.containerPadding ?? grid.margin)[1];
@@ -665,18 +714,23 @@ function containerHeight(rows, grid) {
665
714
  function useGridContainer(opts) {
666
715
  const controller = useGridController(opts);
667
716
  const { width, autoSize, gridConfig, setContainerElement } = controller.config;
717
+ const gridElRef = useRef(null);
668
718
  const { ref, isDropTarget } = useDroppable$1({
669
719
  id: controller.id,
670
720
  type: "grid",
671
721
  accept: (source) => {
722
+ const srcEl = domElement(source);
723
+ if (srcEl && gridElRef.current && srcEl.contains(gridElRef.current)) return false;
672
724
  if (source.type === "grid-item") return true;
673
725
  return source.data?.snapGridDrop != null;
674
726
  },
675
- collisionPriority: GRID_COLLISION_PRIORITY
727
+ collisionDetector: gridCollisionDetector
676
728
  });
677
729
  const setRef = useCallback((element) => {
678
730
  ref(element);
679
731
  setContainerElement(element);
732
+ gridElRef.current = element;
733
+ if (element) element.setAttribute(SNAPGRID_GRID_ATTR, "");
680
734
  }, [ref, setContainerElement]);
681
735
  const renderedLayout = useSyncExternalStore(controller.subscribe, controller.renderedSnapshot, controller.renderedSnapshot);
682
736
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["#committed","#listeners","#session","#rendered","#renderedMapSource","#renderedMap","#indexById","#itemCache","#resizeCache","#emit","#keyboard","#renderedById","#placeholderCache","#nextIndex","Feedback","PointerSensor","KeyboardSensor","verticalCompactor","useDroppable","Feedback","useDraggable","verticalCompactor"],"sources":["../src/controller/GridController.ts","../src/controller/registry.ts","../src/dnd/dragFlow.ts","../src/dnd/snapToGrid.ts","../src/hooks/dndShared.ts","../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 type { Modifiers, Sensors } from \"@dnd-kit/abstract\";\nimport type { DragDropManager } from \"@dnd-kit/dom\";\nimport type {\n DragSession,\n GridConfig,\n Layout,\n LayoutItem,\n PositionParams,\n ResizeHandleAxis,\n} from \"@snapgridjs/core\";\n\n/**\n * Per-grid configuration the container host writes to the controller each render\n * (during render, so items that resolve this controller by `group` read fresh\n * config on the same pass). Replaces the fields the old GridContext exposed.\n */\nexport interface GridControllerConfig {\n positionParams: PositionParams;\n gridConfig: GridConfig;\n width: number;\n autoSize: boolean;\n itemSensors: Sensors;\n itemModifiers: Modifiers;\n isItemDraggable: (id: string) => boolean;\n isItemResizable: (id: string) => boolean;\n resizeHandlesFor: (id: string) => readonly ResizeHandleAxis[];\n /** Report the container element (used to map a pointer to a cell on receive). */\n setContainerElement: (element: Element | null) => void;\n}\n\nexport interface ItemSnapshot {\n item: LayoutItem | undefined;\n isDragging: boolean;\n // True only for a *pointer* drag of this tile. There's no overlay — the tile\n // floats itself — so the host renders it at its committed origin and dnd-kit's\n // float offset composes on top. A keyboard drag has no float, so the tile steps\n // in place instead (hence false here).\n hidden: boolean;\n}\n\nexport interface ResizeSnapshot {\n isResizing: boolean;\n}\n\nfunction sameItem(a: LayoutItem | undefined, b: LayoutItem | undefined): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n // Only the fields that affect what a tile renders/positions. Layout items are\n // immutable, so the compactor may hand back a fresh object for an *unmoved*\n // tile each frame — comparing by value (not identity) is what keeps that tile\n // from re-rendering during someone else's drag.\n return a.i === b.i && a.x === b.x && a.y === b.y && a.w === b.w && a.h === b.h;\n}\n\n/**\n * Live per-grid drag/resize state as a plain observable: the provider writes\n * (`setSession`/`setKeyboard`/`setCommitted`), hooks subscribe to just their own\n * slice via `useSyncExternalStore`. Value-cached snapshots mean a drag re-renders\n * only the tiles whose slice changed, not the whole subtree (the old\n * context-value model re-rendered every tile every frame).\n */\nexport class GridController {\n id: string;\n #committed: Layout;\n #session: DragSession | null = null;\n // True while the active drag was started by the keyboard (no floating overlay\n // → the in-grid tile must stay visible and move in place).\n #keyboard = false;\n #listeners = new Set<() => void>();\n // Per-grid config, written by the container host each render (see setConfig).\n // Non-null once mounted; items only read it after resolving a registered grid.\n config: GridControllerConfig | null = null;\n\n // getSnapshot must return a stable reference while the slice is unchanged\n // (useSyncExternalStore contract, and the basis of the fine-grained re-render).\n #itemCache = new Map<string, ItemSnapshot>();\n #resizeCache = new Map<string, ResizeSnapshot>();\n #placeholderCache: LayoutItem | null = null;\n\n // Rebuilt only when the rendered layout reference changes.\n #renderedMap: Map<string, LayoutItem> | null = null;\n #renderedMapSource: Layout | null = null;\n\n // Stable per-id index for the sortable contract (useGridItem). Assigned on first\n // sight; reclaimed when an item leaves the committed layout (see setCommitted), so\n // the index space stays bounded under item churn. While an item is present its\n // index is stable — the sortable FLIP it would otherwise drive never fires (RGL\n // owns motion).\n #indexById = new Map<string, number>();\n #nextIndex = 0;\n\n /** The dnd-kit manager this grid is registered with (set by useInstance). */\n manager: DragDropManager | undefined;\n\n constructor(id: string, committed: Layout = [], manager?: DragDropManager) {\n this.id = id;\n this.#committed = committed;\n this.manager = manager;\n }\n\n /** Replace the per-grid config (called by the container host during render). */\n setConfig(config: GridControllerConfig): void {\n this.config = config;\n }\n\n /**\n * Re-point this grid's id. The container host syncs it (during render, before\n * the droppable/group read it) when the controlled `id` prop changes, so the\n * returned `group`, the droppable id, and the registry key never drift apart.\n */\n setId(id: string): void {\n this.id = id;\n }\n\n // Satisfies dnd-kit's `Instance` interface (useInstance calls this in a layout\n // effect). Registry registration is handled by the host hook (it must happen\n // during render so child items resolve this controller on their first render),\n // so there's nothing to do here.\n register = (): void => {};\n\n subscribe = (listener: () => void): (() => void) => {\n this.#listeners.add(listener);\n return () => {\n this.#listeners.delete(listener);\n };\n };\n\n #emit(): void {\n for (const listener of this.#listeners) listener();\n }\n\n /** The layout currently shown: the drag preview while dragging, else committed. */\n #rendered(): Layout {\n return this.#session ? (this.#session.preview as Layout) : this.#committed;\n }\n\n #renderedById(): Map<string, LayoutItem> {\n const rendered = this.#rendered();\n if (this.#renderedMapSource !== rendered) {\n this.#renderedMap = new Map(rendered.map((it) => [it.i, it]));\n this.#renderedMapSource = rendered;\n }\n return this.#renderedMap!;\n }\n\n /**\n * Sync the committed layout from the controlled `layout` prop. Called during\n * the provider's render, so it must NOT notify — emitting here would update\n * subscribed GridItems mid-render (a React \"setState while rendering\" error).\n * No notify is needed: a `layout` prop change already re-renders the whole\n * provider subtree, so every GridItem re-reads its snapshot on that pass.\n */\n setCommitted(layout: Layout): void {\n if (this.#committed === layout) return;\n this.#committed = layout;\n // Reclaim cached slices/indices for items no longer in the layout, so a\n // long-lived grid whose items churn doesn't grow these maps without bound.\n const present = new Set(layout.map((it) => it.i));\n for (const id of this.#indexById.keys()) if (!present.has(id)) this.#indexById.delete(id);\n for (const id of this.#itemCache.keys()) if (!present.has(id)) this.#itemCache.delete(id);\n for (const id of this.#resizeCache.keys()) if (!present.has(id)) this.#resizeCache.delete(id);\n }\n\n setSession(next: DragSession | null): void {\n this.#session = next;\n this.#emit();\n }\n\n getSession(): DragSession | null {\n return this.#session;\n }\n\n /** Record whether the active drag is keyboard-driven (drives `hidden`). */\n setKeyboard(value: boolean): void {\n if (this.#keyboard === value) return;\n this.#keyboard = value;\n this.#emit();\n }\n\n itemSnapshot = (id: string): ItemSnapshot => {\n const item = this.#renderedById().get(id);\n const isDragging = this.#session?.activeId === id;\n const hidden = isDragging && this.#session?.kind === \"move\" && !this.#keyboard;\n const prev = this.#itemCache.get(id);\n if (\n prev &&\n prev.isDragging === isDragging &&\n prev.hidden === hidden &&\n sameItem(prev.item, item)\n ) {\n return prev;\n }\n const snap: ItemSnapshot = { item, isDragging, hidden };\n this.#itemCache.set(id, snap);\n return snap;\n };\n\n placeholderSnapshot = (): LayoutItem | null => {\n const next = this.#session?.placeholder ?? null;\n if (sameItem(this.#placeholderCache ?? undefined, next ?? undefined)) {\n return this.#placeholderCache;\n }\n this.#placeholderCache = next;\n return next;\n };\n\n resizeSnapshot = (itemId: string): ResizeSnapshot => {\n const isResizing = this.#session?.kind === \"resize\" && this.#session.activeId === itemId;\n const prev = this.#resizeCache.get(itemId);\n if (prev && prev.isResizing === isResizing) return prev;\n const snap: ResizeSnapshot = { isResizing };\n this.#resizeCache.set(itemId, snap);\n return snap;\n };\n\n renderedSnapshot = (): Layout => this.#rendered();\n\n /** A stable index for `id` (see {@link GridController.#indexById}). */\n itemIndex(id: string): number {\n let i = this.#indexById.get(id);\n if (i === undefined) {\n i = this.#nextIndex++;\n this.#indexById.set(id, i);\n }\n return i;\n }\n}\n","import type { GridController } from \"./GridController.js\";\n\n/**\n * Resolves a grid's {@link GridController} by its id, scoped to the dnd-kit\n * manager the grid is registered with. A container registers its controller\n * here (during render, so child items resolve it on their first render); items\n * look it up by their `group` (= the grid id). Replaces the old geometry\n * `GridRegistry` — which grid the pointer is over now comes from the collision\n * target, so the registry's only job is id → controller resolution.\n *\n * Keyed by manager so two apps (or two providers) never collide, and grids in\n * one provider share a map (the cross-grid seam).\n */\nconst byManager = new WeakMap<object, Map<string, GridController>>();\n// Used when there is no manager yet (no <DragDropProvider> above) — degenerate\n// but keeps lookups total instead of throwing.\nconst noManager = new Map<string, GridController>();\n\nfunction mapFor(manager: object | null | undefined): Map<string, GridController> {\n if (!manager) return noManager;\n let map = byManager.get(manager);\n if (!map) {\n map = new Map();\n byManager.set(manager, map);\n }\n return map;\n}\n\n/** Register a controller under `id` for `manager`. Returns an unregister fn. */\nexport function registerController(\n manager: object | null | undefined,\n id: string,\n controller: GridController,\n): () => void {\n const map = mapFor(manager);\n map.set(id, controller);\n return () => {\n if (map.get(id) === controller) map.delete(id);\n };\n}\n\n/** The controller registered under `id` for `manager`, or undefined. */\nexport function getController(\n manager: object | null | undefined,\n id: string,\n): GridController | undefined {\n return mapFor(manager).get(id);\n}\n\n// The active drag's grab offset (pointer position within the dragged tile),\n// shared across grids on the same manager so a *receiving* grid maps the pointer\n// to the cell under the grabbed point, not the tile's corner. One drag at a time\n// per manager, so a single slot keyed by manager suffices.\nconst grabOffsets = new WeakMap<object, { x: number; y: number }>();\nconst noManagerGrab = { current: null as { x: number; y: number } | null };\n\nexport function setGrabOffset(\n manager: object | null | undefined,\n offset: { x: number; y: number } | null,\n): void {\n if (!manager) {\n noManagerGrab.current = offset;\n return;\n }\n if (offset) grabOffsets.set(manager, offset);\n else grabOffsets.delete(manager);\n}\n\nexport function getGrabOffset(manager: object | null | undefined): { x: number; y: number } {\n const offset = manager ? grabOffsets.get(manager) : noManagerGrab.current;\n return offset ?? { x: 0, y: 0 };\n}\n","import { type PositionParams, calcXY } from \"@snapgridjs/core\";\nimport type { DropConfig, GridDropData } from \"../types.js\";\nimport type { SnapGridDragData } from \"./dragData.js\";\n\n/**\n * Pure decision helpers for the drag interaction so the tricky bits — grab-offset\n * cell mapping, the cross-grid drop lifecycle, and external-drop acceptance — are\n * unit-testable without a DOM or dnd-kit.\n */\n\n/** Read snapgrid's payload off a dnd-kit drag source. */\nexport function dragData(event: {\n operation: { source?: { data?: unknown } | null };\n}): SnapGridDragData | undefined {\n const data = event.operation.source?.data as { snapGrid?: SnapGridDragData } | undefined;\n return data?.snapGrid;\n}\n\n/** Size/id spec for an external (non-grid) draggable the grid may accept, or null. */\nexport function externalDropSpec(\n source: { id: string | number; type?: unknown; data?: unknown } | null | undefined,\n dropConfig: DropConfig | undefined,\n): { i?: string; w: number; h: number } | null {\n if (!dropConfig?.enabled || !source) return null;\n const data = source.data as { snapGrid?: unknown; snapGridDrop?: GridDropData } | undefined;\n if (data?.snapGrid) return null; // a grid item, not external\n if (dropConfig.accept && !dropConfig.accept(source)) return null;\n const spec = data?.snapGridDrop;\n return {\n i: spec?.i,\n // Fall back to react-grid-layout's `defaultDropConfig.defaultItem` (1×1) for parity.\n w: spec?.w ?? dropConfig.defaultItem?.w ?? 1,\n h: spec?.h ?? dropConfig.defaultItem?.h ?? 1,\n };\n}\n\n/**\n * Map a client-space pointer to a grid cell, accounting for where *within* the\n * dragged tile the pointer grabbed it. Subtracting the grab offset means the\n * tile's top-left (not the cursor) maps to the cell, so a received tile's\n * placeholder aligns with the floating overlay instead of jumping its corner to\n * the cursor. External drops pass `{ x: 0, y: 0 }` (no meaningful grab point).\n */\nexport function receiveCell(\n pointer: { x: number; y: number },\n gridRect: { left: number; top: number },\n grabOffset: { x: number; y: number },\n w: number,\n h: number,\n pp: PositionParams,\n): { x: number; y: number } {\n return calcXY(\n pp,\n pointer.y - grabOffset.y - gridRect.top,\n pointer.x - grabOffset.x - gridRect.left,\n w,\n h,\n );\n}\n\n/**\n * Map a keyboard event key to a one-cell grid step while a keyboard drag is\n * active, or null for keys snapgrid doesn't own — Enter/Space (drop) and Escape\n * (cancel) fall through to dnd-kit's KeyboardSensor.\n */\nexport function arrowStep(key: string): [number, number] | null {\n switch (key) {\n case \"ArrowLeft\":\n return [-1, 0];\n case \"ArrowRight\":\n return [1, 0];\n case \"ArrowUp\":\n return [0, -1];\n case \"ArrowDown\":\n return [0, 1];\n default:\n return null;\n }\n}\n\n/**\n * Which grid a drop commits to, as fed to {@link classifyDrop} as `dest`. A\n * keyboard drag has no pointer, so it can only ever land in its own grid; a\n * pointer drag lands in whichever grid the collision observer resolved (or none).\n */\nexport function dropDestination(opts: {\n keyboard: boolean;\n targetId: string | number | null | undefined;\n myId: string;\n}): string | null {\n if (opts.keyboard) return opts.myId;\n return opts.targetId != null ? String(opts.targetId) : null;\n}\n\n/** State gathered by the drag-end handler, fed to {@link classifyDrop}. */\nexport interface DropState {\n /** Kind of the in-progress session, or null if there is none. */\n kind: \"move\" | \"resize\" | null;\n /** Whether the drag was canceled (Esc / abort). */\n canceled: boolean;\n /** Does THIS grid own the dragged item (i.e. it is the source)? */\n ownsItem: boolean;\n /** Is the drag source a grid item (vs. an external draggable)? */\n hasData: boolean;\n /** Id of the grid under the drop pointer, or null if none. */\n dest: string | null;\n /** This grid's id. */\n myId: string;\n}\n\n/**\n * What the drag-end handler should do. Each action implies a specific set of\n * callbacks — encoded here so the cross-grid lifecycle contract is explicit and\n * testable:\n * - `commit-in-grid` / `remove-source` / `revert` all fire `onDragStop` (the\n * SOURCE grid owns the drag's start/stop pair);\n * - `commit-dest` fires only `onLayoutChange` — the destination grid never\n * fired `onDragStart`, so emitting `onDragStop` there would be unbalanced.\n */\nexport type DropAction =\n | \"cancel-resize\"\n | \"cancel-move\"\n | \"commit-resize\"\n | \"commit-in-grid\"\n | \"remove-source\"\n | \"revert\"\n | \"commit-dest\"\n | \"external-drop\"\n | \"noop\";\n\n/** Pure classification of a drag end. See {@link DropAction}. */\nexport function classifyDrop(s: DropState): DropAction {\n if (s.canceled) {\n if (s.kind === \"resize\") return \"cancel-resize\";\n if (s.ownsItem) return \"cancel-move\";\n return \"noop\";\n }\n if (s.kind === \"resize\") return \"commit-resize\";\n\n if (s.ownsItem && s.hasData) {\n if (s.dest === s.myId && s.kind === \"move\") return \"commit-in-grid\";\n if (s.dest) return \"remove-source\";\n return \"revert\";\n }\n\n // Not the owner: we can only be a receiving grid, and only with a session.\n if (s.dest === s.myId && s.kind === \"move\") {\n return s.hasData ? \"commit-dest\" : \"external-drop\";\n }\n return \"noop\";\n}\n","import { Modifier } from \"@dnd-kit/abstract\";\nimport type { DragDropManager } from \"@dnd-kit/dom\";\nimport { type PositionParams, calcGridColWidth } from \"@snapgridjs/core\";\n\nexport interface SnapToGridOptions {\n /** Current geometry (changes with container width). Read fresh each apply(). */\n getPositionParams: () => PositionParams;\n /** Whether snapping is currently enabled (dragConfig.snapToGrid). */\n isEnabled: () => boolean;\n}\n\n/**\n * Quantizes the dragged item's transform to whole grid cells, so the floating\n * <DragOverlay> clone jumps cell-to-cell in lockstep with the (always-snapped)\n * placeholder instead of tracking the pointer smoothly. Applied on the item\n * draggable; a no-op unless `dragConfig.snapToGrid` is set.\n */\nexport class SnapToGrid extends Modifier<DragDropManager, SnapToGridOptions> {\n override apply({ transform }: DragDropManager[\"dragOperation\"]) {\n const opts = this.options;\n if (!opts?.isEnabled()) return transform;\n const pp = opts.getPositionParams();\n // A cell step is the column/row size plus the gap to the next cell.\n const colStep = calcGridColWidth(pp) + pp.margin[0];\n const rowStep = pp.rowHeight + pp.margin[1];\n if (colStep <= 0 || rowStep <= 0) return transform; // guard degenerate geometry\n return {\n x: Math.round(transform.x / colStep) * colStep,\n y: Math.round(transform.y / rowStep) * rowStep,\n };\n }\n}\n","import {\n Feedback,\n KeyboardSensor,\n PointerActivationConstraints,\n PointerSensor,\n type Sensors,\n} from \"@dnd-kit/dom\";\nimport type { DragConfig } from \"../types.js\";\n\n/** Marker attribute placed on resize-handle elements. */\nexport const RESIZE_HANDLE_ATTR = \"data-snapgrid-resize-handle\";\n\n// Resize handles are draggables too, but resizing isn't a move — there's no tile\n// to float — so they suppress dnd-kit's visual feedback entirely.\nexport const NO_FEEDBACK = [Feedback.configure({ feedback: \"none\" })];\n\n/**\n * Whether a pointer-down on `target` should NOT start an item move. Pure and\n * exported for testing. Honors three rules, in order:\n * - never start a move from a resize handle;\n * - never start from a region matching `dragConfig.cancel`;\n * - if `dragConfig.handle` is set, only start from within it.\n */\nexport function shouldPreventItemDrag(\n target: EventTarget | null,\n cfg: DragConfig | undefined,\n): boolean {\n if (!(target instanceof Element)) return false;\n if (target.closest(`[${RESIZE_HANDLE_ATTR}]`)) return true;\n if (cfg?.cancel && target.closest(cfg.cancel)) return true;\n if (cfg?.handle && !target.closest(cfg.handle)) return true;\n return false;\n}\n\n/**\n * Sensors for item (move) draggables, built from the drag config: a distance\n * activation threshold (so clicks don't start drags) plus handle/cancel/resize\n * gating, with the keyboard sensor kept for accessibility.\n */\nexport function buildItemSensors(\n threshold: number,\n getDragConfig: () => DragConfig | undefined,\n): Sensors {\n return [\n PointerSensor.configure({\n activationConstraints: () =>\n threshold > 0\n ? [new PointerActivationConstraints.Distance({ value: threshold })]\n : undefined,\n preventActivation: (event: PointerEvent) =>\n shouldPreventItemDrag(event.target, getDragConfig()),\n }),\n KeyboardSensor,\n ];\n}\n","import { useDragDropManager, useDragDropMonitor, useInstance } from \"@dnd-kit/react\";\nimport type { DragEndEvent, DragMoveEvent, DragStartEvent } from \"@dnd-kit/react\";\nimport {\n type Compactor,\n type DragSession,\n type GridConfig,\n type Layout,\n type LayoutItem,\n type PositionParams,\n beginDrag,\n beginReceive,\n beginResize,\n calcGridItemPosition,\n commitLayout,\n defaultGridConfig,\n dragResize,\n dragTo,\n nudge,\n removeItemWithCompactor,\n toPositionParams,\n verticalCompactor,\n} from \"@snapgridjs/core\";\nimport { useCallback, useEffect, useId, useMemo, useRef } from \"react\";\nimport { GridController } from \"../controller/GridController.js\";\nimport { getGrabOffset, registerController, setGrabOffset } from \"../controller/registry.js\";\nimport {\n arrowStep,\n classifyDrop,\n dragData,\n dropDestination,\n externalDropSpec,\n receiveCell,\n} from \"../dnd/dragFlow.js\";\nimport { SnapToGrid } from \"../dnd/snapToGrid.js\";\nimport type { DragConfig, DropConfig, GridEventCallback, ResizeConfig } from \"../types.js\";\nimport { buildItemSensors } from \"./dndShared.js\";\n\nconst DEFAULT_HANDLES = [\"se\"] as const;\n\ntype Point = { x: number; y: number };\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 brain: owns the {@link GridController}, runs the dnd-kit drag/resize\n * monitor for this grid, and writes per-grid config to the controller each render.\n * Created by {@link useGridContainer}; items resolve the same controller by their\n * `group` (= this grid's id) from the per-manager registry. 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 // Refs read inside the stable monitor handlers so they never see stale values.\n const optsRef = useRef(opts);\n optsRef.current = opts;\n const ppRef = useRef(positionParams);\n ppRef.current = positionParams;\n const gridRef = useRef(gridConfig);\n gridRef.current = gridConfig;\n const compactorRef = useRef(compactor);\n compactorRef.current = compactor;\n const containerIdRef = useRef(containerId);\n containerIdRef.current = containerId;\n const managerRef = useRef(manager);\n managerRef.current = manager;\n const sessionRef = useRef<DragSession | null>(null);\n const containerElRef = useRef<Element | null>(null);\n // True while the active move was started by the keyboard (Enter/Space on a\n // focused tile) rather than a pointer — drives the arrow-key drag path.\n const keyboardRef = useRef(false);\n // External-drop bookkeeping: a stable synthesized item id + size for the\n // in-flight external draggable this grid may receive.\n const dropSpecRef = useRef<{ i: string; w: number; h: number } | null>(null);\n const dropCounterRef = useRef(0);\n\n // Register the controller so items (and snapMove) resolve it by id. During\n // render so child items resolve it on their first render (children render\n // after the parent but before any layout effect). The effect's cleanup\n // unregisters on unmount / id or manager change.\n registerController(manager, containerId, controller);\n useEffect(\n () => registerController(manager, containerId, controller),\n [manager, containerId, controller],\n );\n\n const committedById = useMemo(\n () => new Map<string, LayoutItem>(opts.layout.map((it) => [it.i, it])),\n [opts.layout],\n );\n const committedByIdRef = useRef(committedById);\n committedByIdRef.current = committedById;\n\n const setSessionBoth = useCallback(\n (next: DragSession | null) => {\n sessionRef.current = next;\n controller.setSession(next);\n },\n [controller],\n );\n\n // Write the keyboard-drag flag to both the synchronous ref (read in the event\n // handlers) and the controller (drives the reactive `hidden` snapshot).\n const setKeyboard = useCallback(\n (value: boolean) => {\n keyboardRef.current = value;\n controller.setKeyboard(value);\n },\n [controller],\n );\n\n const setContainerElement = useCallback((element: Element | null) => {\n containerElRef.current = element;\n }, []);\n\n /**\n * Is THIS grid the drop target dnd-kit's collision observer resolved? Both the\n * move-phase preview and the drop-phase commit read `operation.target`, so they\n * always agree on which grid wins (one oracle), including when grids overlap.\n */\n const overMe = useCallback(\n (target: { id: string | number } | null | undefined) => target?.id === containerIdRef.current,\n [],\n );\n\n /** Map a client-space pointer to a grid cell within THIS grid (see {@link receiveCell}). */\n const cellFromPointer = useCallback((p: Point, item: LayoutItem) => {\n const el = containerElRef.current;\n if (!el) return null;\n const rect = el.getBoundingClientRect();\n return receiveCell(p, rect, getGrabOffset(managerRef.current), item.w, item.h, ppRef.current);\n }, []);\n\n const ctx = useCallback(\n () => ({\n positionParams: ppRef.current,\n compactor: compactorRef.current,\n cols: gridRef.current.cols,\n }),\n [],\n );\n\n const handleDragStart = useCallback(\n (event: DragStartEvent) => {\n // Reset on every start (incl. the external/resize early-returns below) so a\n // keyboard flag can never leak from a prior drag into an unrelated one.\n setKeyboard(false);\n const data = dragData(event);\n if (!data) {\n // An external (non-grid) draggable: if we accept it, reserve a stable\n // synthesized id/size for the item this grid may receive on drop.\n const spec = externalDropSpec(event.operation.source, optsRef.current.dropConfig);\n if (spec) {\n dropCounterRef.current += 1;\n dropSpecRef.current = {\n // Prefix with this grid's id so two drop-enabled grids in a group\n // don't both mint `dropped-1` (colliding item ids).\n i: spec.i ?? `${containerIdRef.current}-dropped-${dropCounterRef.current}`,\n w: spec.w,\n h: spec.h,\n };\n } else {\n dropSpecRef.current = null;\n }\n return;\n }\n dropSpecRef.current = null;\n const layout = optsRef.current.layout;\n const item = layout.find((it) => it.i === data.itemId);\n const p = event.operation.position.current;\n const pointer = { x: p.x, y: p.y };\n if (data.kind === \"resize\") {\n if (!item) return; // resize only applies to the owning grid\n const rect = calcGridItemPosition(ppRef.current, item.x, item.y, item.w, item.h);\n setSessionBoth(beginResize(layout, { item, rect, pointer }, data.handle));\n optsRef.current.onResizeStart?.(\n layout,\n item,\n item,\n item,\n event.operation.activatorEvent,\n null,\n );\n return;\n }\n if (item) {\n // We own the item — this is the source grid.\n const isKeyboard = event.operation.activatorEvent instanceof KeyboardEvent;\n setKeyboard(isKeyboard);\n const rect = calcGridItemPosition(ppRef.current, item.x, item.y, item.w, item.h);\n setSessionBoth(beginDrag(layout, { item, left: rect.left, top: rect.top, pointer }));\n // Share the grab offset (pointer position within the tile) so a receiving\n // grid maps the pointer to the cell under the same point the user grabbed,\n // not the tile's corner.\n const el = (event.operation.source as { element?: Element } | null)?.element;\n const cr = el?.getBoundingClientRect();\n if (cr) {\n setGrabOffset(managerRef.current, { x: pointer.x - cr.left, y: pointer.y - cr.top });\n }\n optsRef.current.onDragStart?.(\n layout,\n item,\n item,\n item,\n event.operation.activatorEvent,\n null,\n );\n }\n // Otherwise the item belongs to another grid; we may receive it on move.\n },\n [setSessionBoth, setKeyboard],\n );\n\n const handleDragMove = useCallback(\n (event: DragMoveEvent) => {\n // Keyboard moves are driven entirely by the arrow-key handler below; ignore\n // dnd-kit's (pointerless, therefore no-op) move events so they can't revert\n // a nudge back to the static activator cell.\n if (keyboardRef.current) return;\n const p = event.operation.position.current;\n const pointer = { x: p.x, y: p.y };\n const current = sessionRef.current;\n\n if (current?.kind === \"resize\") {\n const next = dragResize(current, pointer, ctx());\n setSessionBoth(next);\n optsRef.current.onResize?.(\n next.preview,\n next.anchor.item,\n next.placeholder,\n next.placeholder,\n event.operation.activatorEvent,\n null,\n );\n return;\n }\n\n const target = event.operation.target;\n const data = dragData(event);\n if (!data) {\n // External (non-grid) draggable: preview where it would land over us.\n const spec = dropSpecRef.current;\n if (spec && overMe(target)) {\n const foreign: LayoutItem = { i: spec.i, x: 0, y: 0, w: spec.w, h: spec.h };\n const committed = optsRef.current.layout;\n const cell = cellFromPointer(pointer, foreign) ?? { x: 0, y: 0 };\n setSessionBoth(beginReceive(committed, foreign, cell.x, cell.y, pointer, ctx()));\n } else if (sessionRef.current) {\n setSessionBoth(null);\n }\n return;\n }\n if (data.kind !== \"move\") return;\n const here = overMe(target);\n const ownsItem = committedByIdRef.current.has(data.itemId);\n\n if (ownsItem) {\n const source = current?.kind === \"move\" ? current : null;\n if (!source) return;\n let next: DragSession;\n if (here) {\n next = dragTo(source, pointer, ctx());\n } else {\n // Leaving this grid: keep the item in place and hide the placeholder\n // here; the dragged tile floats itself across grids (no overlay).\n next = {\n ...source,\n preview: source.committed as LayoutItem[],\n placeholder: null,\n };\n }\n setSessionBoth(next);\n optsRef.current.onDrag?.(\n next.preview,\n next.anchor.item,\n next.placeholder,\n next.placeholder,\n event.operation.activatorEvent,\n null,\n );\n return;\n }\n\n // We don't own the item — maybe receive it.\n if (here) {\n const foreign = data.item;\n const committed = optsRef.current.layout;\n const cell = cellFromPointer(pointer, foreign) ?? { x: 0, y: 0 };\n setSessionBoth(beginReceive(committed, foreign, cell.x, cell.y, pointer, ctx()));\n } else if (sessionRef.current) {\n setSessionBoth(null); // pointer left; we're no longer receiving\n }\n },\n [setSessionBoth, overMe, cellFromPointer, ctx],\n );\n\n const handleDragEnd = useCallback(\n (event: DragEndEvent) => {\n const current = sessionRef.current;\n const data = dragData(event);\n const myId = containerIdRef.current;\n // A keyboard drop always commits in-grid; a pointer drop uses the collision\n // target (see dropDestination).\n const dest = dropDestination({\n keyboard: keyboardRef.current,\n targetId: event.operation.target?.id,\n myId,\n });\n const ownsItem = data ? committedByIdRef.current.has(data.itemId) : false;\n setGrabOffset(managerRef.current, null);\n\n const native = event.nativeEvent ?? null;\n const o = optsRef.current;\n // Pure classification of what this drop means for THIS grid; the switch\n // below maps each action to its callbacks (see dragFlow.ts for the contract).\n const action = classifyDrop({\n kind: current?.kind ?? null,\n canceled: event.canceled,\n ownsItem,\n hasData: !!data,\n dest,\n myId,\n });\n\n switch (action) {\n case \"cancel-resize\":\n o.onResizeStop?.(o.layout, current?.anchor.item ?? null, null, null, native, null);\n break;\n case \"cancel-move\":\n o.onDragStop?.(o.layout, current?.anchor.item ?? null, null, null, native, null);\n break;\n case \"commit-resize\":\n if (current) {\n o.onLayoutChange?.(commitLayout(current));\n o.onResizeStop?.(\n current.preview,\n current.anchor.item,\n current.placeholder,\n current.placeholder,\n native,\n null,\n );\n }\n break;\n case \"commit-in-grid\":\n case \"remove-source\":\n case \"revert\": {\n // Source grid finishing its drag: all fire onDragStop, differing only in layout.\n if (action === \"commit-in-grid\" && current) {\n o.onLayoutChange?.(commitLayout(current));\n } else if (action === \"remove-source\" && data) {\n const { compactor: c, cols } = ctx();\n o.onLayoutChange?.(\n removeItemWithCompactor(o.layout, data.itemId, { compactor: c, cols }),\n );\n } // \"revert\" → dropped outside any grid → no layout change.\n o.onDragStop?.(\n current?.preview ?? o.layout,\n current?.anchor.item ?? null,\n current?.placeholder ?? null,\n current?.placeholder ?? null,\n native,\n null,\n );\n break;\n }\n case \"commit-dest\":\n if (current) o.onLayoutChange?.(commitLayout(current));\n break;\n case \"external-drop\":\n // Hand the synthesized item to onDrop so the consumer can add it.\n if (current) {\n const committed = commitLayout(current);\n const dropped = committed.find((it) => it.i === current.activeId);\n if (dropped) o.onDrop?.(committed, dropped, native);\n }\n break;\n // \"noop\" → nothing to do.\n }\n dropSpecRef.current = null;\n setKeyboard(false);\n setSessionBoth(null);\n },\n [setSessionBoth, setKeyboard, ctx],\n );\n\n // Keyboard dragging: while a keyboard-initiated move is active, arrow keys step\n // the tile one cell at a time (it moves in place via the session preview — no\n // overlay). Enter / Space (drop) and Escape (cancel) fall through to dnd-kit's\n // KeyboardSensor.\n useEffect(() => {\n const onKeyDown = (e: KeyboardEvent) => {\n if (!keyboardRef.current) return;\n const session = sessionRef.current;\n if (!session || session.kind !== \"move\") return;\n const step = arrowStep(e.key);\n if (!step) return; // Enter/Space/Escape → dnd-kit handles drop/cancel\n e.preventDefault();\n // Own the arrow: stop dnd-kit's KeyboardSensor (a document capture-phase\n // listener) from also moving — otherwise its internal operation position\n // drifts every keystroke. We run in capture on window, ahead of it.\n e.stopImmediatePropagation();\n setSessionBoth(nudge(session, step[0], step[1], ctx()));\n };\n window.addEventListener(\"keydown\", onKeyDown, true);\n return () => window.removeEventListener(\"keydown\", onKeyDown, true);\n }, [ctx, setSessionBoth]);\n\n // Stable handlers object: dnd-kit's monitor effect keys on the handlers\n // identity, so a fresh literal each render would tear down and re-add all\n // listeners on every render (i.e. every pointer move, for every grid).\n const monitorHandlers = useMemo(\n () => ({\n onDragStart: handleDragStart,\n onDragMove: handleDragMove,\n onDragEnd: handleDragEnd,\n }),\n [handleDragStart, handleDragMove, handleDragEnd],\n );\n useDragDropMonitor(monitorHandlers);\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 // Publish per-grid config to the controller so items (resolved by group) read\n // fresh geometry/predicates without a React context.\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 setContainerElement,\n });\n\n return controller;\n}\n","import { useDroppable } from \"@dnd-kit/react\";\nimport { type GridConfig, bottom } from \"@snapgridjs/core\";\nimport { type CSSProperties, useCallback, useSyncExternalStore } from \"react\";\nimport type { GridController } from \"../controller/GridController.js\";\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// Outranks a dragged tile/card's own sortable droppable, so collision inside the\n// grid resolves to the container (not a tile). That keeps dnd-kit's sortable\n// reorder out of the grid (RGL drives the move) and lets a foreign sortable\n// resolve the grid as its drop target for cell mapping.\nconst GRID_COLLISION_PRIORITY = 10;\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, setContainerElement } = config!;\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 if (source.type === \"grid-item\") return true;\n const data = source.data as { snapGridDrop?: unknown } | undefined;\n return data?.snapGridDrop != null;\n },\n collisionPriority: GRID_COLLISION_PRIORITY,\n });\n\n // Merge dnd-kit's droppable ref with reporting the element to the controller\n // (used to map the pointer to a cell when receiving a tile from another grid).\n const setRef = useCallback(\n (element: Element | null) => {\n ref(element);\n setContainerElement(element);\n },\n [ref, setContainerElement],\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 } from \"../controller/GridController.js\";\nimport { getController } from \"../controller/registry.js\";\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 const data = useMemo(() => ({ snapGrid: { kind: \"move\", itemId: id, item } }), [id, item]);\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 { useSyncExternalStore } from \"react\";\nimport { NO_FEEDBACK, RESIZE_HANDLE_ATTR } from \"./dndShared.js\";\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 } },\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 CSSProperties, type ReactNode, useMemo } from \"react\";\nimport { useResponsiveLayout } from \"../hooks/useResponsiveLayout.js\";\nimport type { DragConfig, ResizeConfig } from \"../types.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":["#committed","#listeners","#session","#rendered","#renderedMapSource","#renderedMap","#indexById","#itemCache","#resizeCache","#emit","#keyboard","#renderedById","#placeholderCache","#nextIndex","Feedback","PointerSensor","KeyboardSensor","verticalCompactor","useDroppable","Feedback","useDraggable","verticalCompactor"],"sources":["../src/dnd/entity.ts","../src/dnd/collision.ts","../src/controller/GridController.ts","../src/controller/registry.ts","../src/dnd/dragFlow.ts","../src/dnd/snapToGrid.ts","../src/hooks/dndShared.ts","../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":["/**\n * The DOM element of a dnd-kit entity (a draggable, droppable, or drag source).\n * dnd-kit's abstract types don't expose `element`, but the DOM layer snapgrid\n * runs on always sets it — this centralizes that one assumption (and the cast)\n * in a single place instead of scattering it across the drag code.\n */\nexport function domElement(entity: object | null | undefined): Element | null {\n return (entity as { element?: Element | null } | null | undefined)?.element ?? null;\n}\n","import { type CollisionDetector, defaultCollisionDetection } from \"@dnd-kit/collision\";\nimport { domElement } from \"./entity.js\";\n\n/**\n * Marker attribute set on every grid container element. Used by {@link gridDepth}\n * to measure how deeply a grid is nested, purely from the DOM.\n */\nexport const SNAPGRID_GRID_ATTR = \"data-snapgrid-grid\";\n\n// Base priority for a grid droppable. Outranks a dragged tile's own sortable\n// droppable so collision inside a grid resolves to the container (RGL drives the\n// move, not dnd-kit's sortable reorder), and lets a foreign sortable resolve the\n// grid as its drop target. `gridDepth` adds to this so an inner grid outranks its\n// outer one when their rects overlap.\nconst GRID_COLLISION_PRIORITY = 10;\n\n/**\n * How deeply `el`'s grid is nested: the number of ancestor grid containers above\n * it. A top-level grid is 0; a grid rendered inside another grid's tile is 1; and\n * so on. DOM containment is the ground truth, so this is correct regardless of the\n * React tree shape or how priorities are assigned elsewhere.\n */\nexport function gridDepth(el: Element | null | undefined): number {\n let depth = 0;\n let node = el?.parentElement ?? null;\n while (node) {\n if (node.hasAttribute(SNAPGRID_GRID_ATTR)) depth++;\n node = node.parentElement;\n }\n return depth;\n}\n\n/**\n * Collision detector for grid droppables. Runs dnd-kit's default detector, then —\n * when nested grid rects overlap (the pointer is over both an inner grid and its\n * outer one) — ranks the **innermost** grid highest by boosting priority with the\n * grid's nesting depth. Without this, overlapping grids tie on priority and the\n * winner is arbitrary. For non-nested grids depth is 0, so priority is unchanged.\n */\nexport const gridCollisionDetector: CollisionDetector = (input) => {\n const collision = defaultCollisionDetection(input);\n if (!collision) return null;\n return {\n ...collision,\n priority: GRID_COLLISION_PRIORITY + gridDepth(domElement(input.droppable)),\n };\n};\n","import type { Modifiers, Sensors } from \"@dnd-kit/abstract\";\nimport type { DragDropManager } from \"@dnd-kit/dom\";\nimport type {\n DragSession,\n GridConfig,\n Layout,\n LayoutItem,\n PositionParams,\n ResizeHandleAxis,\n} from \"@snapgridjs/core\";\n\n/**\n * Per-grid configuration the container host writes to the controller each render\n * (during render, so items that resolve this controller by `group` read fresh\n * config on the same pass). Replaces the fields the old GridContext exposed.\n */\nexport interface GridControllerConfig {\n positionParams: PositionParams;\n gridConfig: GridConfig;\n width: number;\n autoSize: boolean;\n itemSensors: Sensors;\n itemModifiers: Modifiers;\n isItemDraggable: (id: string) => boolean;\n isItemResizable: (id: string) => boolean;\n resizeHandlesFor: (id: string) => readonly ResizeHandleAxis[];\n /** Report the container element (used to map a pointer to a cell on receive). */\n setContainerElement: (element: Element | null) => void;\n}\n\nexport interface ItemSnapshot {\n item: LayoutItem | undefined;\n isDragging: boolean;\n // True only for a *pointer* drag of this tile. There's no overlay — the tile\n // floats itself — so the host renders it at its committed origin and dnd-kit's\n // float offset composes on top. A keyboard drag has no float, so the tile steps\n // in place instead (hence false here).\n hidden: boolean;\n}\n\nexport interface ResizeSnapshot {\n isResizing: boolean;\n}\n\nfunction sameItem(a: LayoutItem | undefined, b: LayoutItem | undefined): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n // Only the fields that affect what a tile renders/positions. Layout items are\n // immutable, so the compactor may hand back a fresh object for an *unmoved*\n // tile each frame — comparing by value (not identity) is what keeps that tile\n // from re-rendering during someone else's drag.\n return a.i === b.i && a.x === b.x && a.y === b.y && a.w === b.w && a.h === b.h;\n}\n\n/**\n * Live per-grid drag/resize state as a plain observable: the provider writes\n * (`setSession`/`setKeyboard`/`setCommitted`), hooks subscribe to just their own\n * slice via `useSyncExternalStore`. Value-cached snapshots mean a drag re-renders\n * only the tiles whose slice changed, not the whole subtree (the old\n * context-value model re-rendered every tile every frame).\n */\nexport class GridController {\n id: string;\n #committed: Layout;\n #session: DragSession | null = null;\n // True while the active drag was started by the keyboard (no floating overlay\n // → the in-grid tile must stay visible and move in place).\n #keyboard = false;\n #listeners = new Set<() => void>();\n // Per-grid config, written by the container host each render (see setConfig).\n // Non-null once mounted; items only read it after resolving a registered grid.\n config: GridControllerConfig | null = null;\n\n // getSnapshot must return a stable reference while the slice is unchanged\n // (useSyncExternalStore contract, and the basis of the fine-grained re-render).\n #itemCache = new Map<string, ItemSnapshot>();\n #resizeCache = new Map<string, ResizeSnapshot>();\n #placeholderCache: LayoutItem | null = null;\n\n // Rebuilt only when the rendered layout reference changes.\n #renderedMap: Map<string, LayoutItem> | null = null;\n #renderedMapSource: Layout | null = null;\n\n // Stable per-id index for the sortable contract (useGridItem). Assigned on first\n // sight; reclaimed when an item leaves the committed layout (see setCommitted), so\n // the index space stays bounded under item churn. While an item is present its\n // index is stable — the sortable FLIP it would otherwise drive never fires (RGL\n // owns motion).\n #indexById = new Map<string, number>();\n #nextIndex = 0;\n\n /** The dnd-kit manager this grid is registered with (set by useInstance). */\n manager: DragDropManager | undefined;\n\n constructor(id: string, committed: Layout = [], manager?: DragDropManager) {\n this.id = id;\n this.#committed = committed;\n this.manager = manager;\n }\n\n /** Replace the per-grid config (called by the container host during render). */\n setConfig(config: GridControllerConfig): void {\n this.config = config;\n }\n\n /**\n * Re-point this grid's id. The container host syncs it (during render, before\n * the droppable/group read it) when the controlled `id` prop changes, so the\n * returned `group`, the droppable id, and the registry key never drift apart.\n */\n setId(id: string): void {\n this.id = id;\n }\n\n // Satisfies dnd-kit's `Instance` interface (useInstance calls this in a layout\n // effect). Registry registration is handled by the host hook (it must happen\n // during render so child items resolve this controller on their first render),\n // so there's nothing to do here.\n register = (): void => {};\n\n subscribe = (listener: () => void): (() => void) => {\n this.#listeners.add(listener);\n return () => {\n this.#listeners.delete(listener);\n };\n };\n\n #emit(): void {\n for (const listener of this.#listeners) listener();\n }\n\n /** The layout currently shown: the drag preview while dragging, else committed. */\n #rendered(): Layout {\n return this.#session ? (this.#session.preview as Layout) : this.#committed;\n }\n\n #renderedById(): Map<string, LayoutItem> {\n const rendered = this.#rendered();\n if (this.#renderedMapSource !== rendered) {\n this.#renderedMap = new Map(rendered.map((it) => [it.i, it]));\n this.#renderedMapSource = rendered;\n }\n return this.#renderedMap!;\n }\n\n /**\n * Sync the committed layout from the controlled `layout` prop. Called during\n * the provider's render, so it must NOT notify — emitting here would update\n * subscribed GridItems mid-render (a React \"setState while rendering\" error).\n * No notify is needed: a `layout` prop change already re-renders the whole\n * provider subtree, so every GridItem re-reads its snapshot on that pass.\n */\n setCommitted(layout: Layout): void {\n if (this.#committed === layout) return;\n this.#committed = layout;\n // Reclaim cached slices/indices for items no longer in the layout, so a\n // long-lived grid whose items churn doesn't grow these maps without bound.\n const present = new Set(layout.map((it) => it.i));\n for (const id of this.#indexById.keys()) if (!present.has(id)) this.#indexById.delete(id);\n for (const id of this.#itemCache.keys()) if (!present.has(id)) this.#itemCache.delete(id);\n for (const id of this.#resizeCache.keys()) if (!present.has(id)) this.#resizeCache.delete(id);\n }\n\n setSession(next: DragSession | null): void {\n this.#session = next;\n this.#emit();\n }\n\n getSession(): DragSession | null {\n return this.#session;\n }\n\n /** Record whether the active drag is keyboard-driven (drives `hidden`). */\n setKeyboard(value: boolean): void {\n if (this.#keyboard === value) return;\n this.#keyboard = value;\n this.#emit();\n }\n\n itemSnapshot = (id: string): ItemSnapshot => {\n const item = this.#renderedById().get(id);\n const isDragging = this.#session?.activeId === id;\n const hidden = isDragging && this.#session?.kind === \"move\" && !this.#keyboard;\n const prev = this.#itemCache.get(id);\n if (\n prev &&\n prev.isDragging === isDragging &&\n prev.hidden === hidden &&\n sameItem(prev.item, item)\n ) {\n return prev;\n }\n const snap: ItemSnapshot = { item, isDragging, hidden };\n this.#itemCache.set(id, snap);\n return snap;\n };\n\n placeholderSnapshot = (): LayoutItem | null => {\n const next = this.#session?.placeholder ?? null;\n if (sameItem(this.#placeholderCache ?? undefined, next ?? undefined)) {\n return this.#placeholderCache;\n }\n this.#placeholderCache = next;\n return next;\n };\n\n resizeSnapshot = (itemId: string): ResizeSnapshot => {\n const isResizing = this.#session?.kind === \"resize\" && this.#session.activeId === itemId;\n const prev = this.#resizeCache.get(itemId);\n if (prev && prev.isResizing === isResizing) return prev;\n const snap: ResizeSnapshot = { isResizing };\n this.#resizeCache.set(itemId, snap);\n return snap;\n };\n\n renderedSnapshot = (): Layout => this.#rendered();\n\n /** A stable index for `id` (see {@link GridController.#indexById}). */\n itemIndex(id: string): number {\n let i = this.#indexById.get(id);\n if (i === undefined) {\n i = this.#nextIndex++;\n this.#indexById.set(id, i);\n }\n return i;\n }\n}\n","import type { GridController } from \"./GridController.js\";\n\n/**\n * Resolves a grid's {@link GridController} by its id, scoped to the dnd-kit\n * manager the grid is registered with. A container registers its controller\n * here (during render, so child items resolve it on their first render); items\n * look it up by their `group` (= the grid id). Replaces the old geometry\n * `GridRegistry` — which grid the pointer is over now comes from the collision\n * target, so the registry's only job is id → controller resolution.\n *\n * Keyed by manager so two apps (or two providers) never collide, and grids in\n * one provider share a map (the cross-grid seam).\n */\nconst byManager = new WeakMap<object, Map<string, GridController>>();\n// Used when there is no manager yet (no <DragDropProvider> above) — degenerate\n// but keeps lookups total instead of throwing.\nconst noManager = new Map<string, GridController>();\n\nfunction mapFor(manager: object | null | undefined): Map<string, GridController> {\n if (!manager) return noManager;\n let map = byManager.get(manager);\n if (!map) {\n map = new Map();\n byManager.set(manager, map);\n }\n return map;\n}\n\n/** Register a controller under `id` for `manager`. Returns an unregister fn. */\nexport function registerController(\n manager: object | null | undefined,\n id: string,\n controller: GridController,\n): () => void {\n const map = mapFor(manager);\n map.set(id, controller);\n return () => {\n if (map.get(id) === controller) map.delete(id);\n };\n}\n\n/** The controller registered under `id` for `manager`, or undefined. */\nexport function getController(\n manager: object | null | undefined,\n id: string,\n): GridController | undefined {\n return mapFor(manager).get(id);\n}\n\n// The active drag's grab offset (pointer position within the dragged tile),\n// shared across grids on the same manager so a *receiving* grid maps the pointer\n// to the cell under the grabbed point, not the tile's corner. One drag at a time\n// per manager, so a single slot keyed by manager suffices.\nconst grabOffsets = new WeakMap<object, { x: number; y: number }>();\nconst noManagerGrab = { current: null as { x: number; y: number } | null };\n\nexport function setGrabOffset(\n manager: object | null | undefined,\n offset: { x: number; y: number } | null,\n): void {\n if (!manager) {\n noManagerGrab.current = offset;\n return;\n }\n if (offset) grabOffsets.set(manager, offset);\n else grabOffsets.delete(manager);\n}\n\nexport function getGrabOffset(manager: object | null | undefined): { x: number; y: number } {\n const offset = manager ? grabOffsets.get(manager) : noManagerGrab.current;\n return offset ?? { x: 0, y: 0 };\n}\n","import { type PositionParams, calcXY } from \"@snapgridjs/core\";\nimport type { DropConfig, GridDropData } from \"../types.js\";\nimport type { SnapGridDragData } from \"./dragData.js\";\n\n/**\n * Pure decision helpers for the drag interaction so the tricky bits — grab-offset\n * cell mapping, the cross-grid drop lifecycle, and external-drop acceptance — are\n * unit-testable without a DOM or dnd-kit.\n */\n\n/** Read snapgrid's payload off a dnd-kit drag source. */\nexport function dragData(event: {\n operation: { source?: { data?: unknown } | null };\n}): SnapGridDragData | undefined {\n const data = event.operation.source?.data as { snapGrid?: SnapGridDragData } | undefined;\n return data?.snapGrid;\n}\n\n/** Size/id spec for an external (non-grid) draggable the grid may accept, or null. */\nexport function externalDropSpec(\n source: { id: string | number; type?: unknown; data?: unknown } | null | undefined,\n dropConfig: DropConfig | undefined,\n): { i?: string; w: number; h: number } | null {\n if (!dropConfig?.enabled || !source) return null;\n const data = source.data as { snapGrid?: unknown; snapGridDrop?: GridDropData } | undefined;\n if (data?.snapGrid) return null; // a grid item, not external\n if (dropConfig.accept && !dropConfig.accept(source)) return null;\n const spec = data?.snapGridDrop;\n return {\n i: spec?.i,\n // Fall back to react-grid-layout's `defaultDropConfig.defaultItem` (1×1) for parity.\n w: spec?.w ?? dropConfig.defaultItem?.w ?? 1,\n h: spec?.h ?? dropConfig.defaultItem?.h ?? 1,\n };\n}\n\n/**\n * Map a client-space pointer to a grid cell, accounting for where *within* the\n * dragged tile the pointer grabbed it. Subtracting the grab offset means the\n * tile's top-left (not the cursor) maps to the cell, so a received tile's\n * placeholder aligns with the floating overlay instead of jumping its corner to\n * the cursor. External drops pass `{ x: 0, y: 0 }` (no meaningful grab point).\n */\nexport function receiveCell(\n pointer: { x: number; y: number },\n gridRect: { left: number; top: number },\n grabOffset: { x: number; y: number },\n w: number,\n h: number,\n pp: PositionParams,\n): { x: number; y: number } {\n return calcXY(\n pp,\n pointer.y - grabOffset.y - gridRect.top,\n pointer.x - grabOffset.x - gridRect.left,\n w,\n h,\n );\n}\n\n/**\n * Map a keyboard event key to a one-cell grid step while a keyboard drag is\n * active, or null for keys snapgrid doesn't own — Enter/Space (drop) and Escape\n * (cancel) fall through to dnd-kit's KeyboardSensor.\n */\nexport function arrowStep(key: string): [number, number] | null {\n switch (key) {\n case \"ArrowLeft\":\n return [-1, 0];\n case \"ArrowRight\":\n return [1, 0];\n case \"ArrowUp\":\n return [0, -1];\n case \"ArrowDown\":\n return [0, 1];\n default:\n return null;\n }\n}\n\n/**\n * Which grid a drop commits to, as fed to {@link classifyDrop} as `dest`. A\n * keyboard drag has no pointer, so it can only ever land in its own grid; a\n * pointer drag lands in whichever grid the collision observer resolved (or none).\n */\nexport function dropDestination(opts: {\n keyboard: boolean;\n targetId: string | number | null | undefined;\n myId: string;\n}): string | null {\n if (opts.keyboard) return opts.myId;\n return opts.targetId != null ? String(opts.targetId) : null;\n}\n\n/** State gathered by the drag-end handler, fed to {@link classifyDrop}. */\nexport interface DropState {\n /** Kind of the in-progress session, or null if there is none. */\n kind: \"move\" | \"resize\" | null;\n /** Whether the drag was canceled (Esc / abort). */\n canceled: boolean;\n /** Does THIS grid own the dragged item (i.e. it is the source)? */\n ownsItem: boolean;\n /** Is the drag source a grid item (vs. an external draggable)? */\n hasData: boolean;\n /** Id of the grid under the drop pointer, or null if none. */\n dest: string | null;\n /** This grid's id. */\n myId: string;\n}\n\n/**\n * What the drag-end handler should do. Each action implies a specific set of\n * callbacks — encoded here so the cross-grid lifecycle contract is explicit and\n * testable:\n * - `commit-in-grid` / `remove-source` / `revert` all fire `onDragStop` (the\n * SOURCE grid owns the drag's start/stop pair);\n * - `commit-dest` fires only `onLayoutChange` — the destination grid never\n * fired `onDragStart`, so emitting `onDragStop` there would be unbalanced.\n */\nexport type DropAction =\n | \"cancel-resize\"\n | \"cancel-move\"\n | \"commit-resize\"\n | \"commit-in-grid\"\n | \"remove-source\"\n | \"revert\"\n | \"commit-dest\"\n | \"external-drop\"\n | \"noop\";\n\n/** Pure classification of a drag end. See {@link DropAction}. */\nexport function classifyDrop(s: DropState): DropAction {\n if (s.canceled) {\n if (s.kind === \"resize\") return \"cancel-resize\";\n if (s.ownsItem) return \"cancel-move\";\n return \"noop\";\n }\n if (s.kind === \"resize\") return \"commit-resize\";\n\n if (s.ownsItem && s.hasData) {\n if (s.dest === s.myId && s.kind === \"move\") return \"commit-in-grid\";\n if (s.dest) return \"remove-source\";\n return \"revert\";\n }\n\n // Not the owner: we can only be a receiving grid, and only with a session.\n if (s.dest === s.myId && s.kind === \"move\") {\n return s.hasData ? \"commit-dest\" : \"external-drop\";\n }\n return \"noop\";\n}\n","import { Modifier } from \"@dnd-kit/abstract\";\nimport type { DragDropManager } from \"@dnd-kit/dom\";\nimport { type PositionParams, calcGridColWidth } from \"@snapgridjs/core\";\n\nexport interface SnapToGridOptions {\n /** Current geometry (changes with container width). Read fresh each apply(). */\n getPositionParams: () => PositionParams;\n /** Whether snapping is currently enabled (dragConfig.snapToGrid). */\n isEnabled: () => boolean;\n}\n\n/**\n * Quantizes the dragged item's transform to whole grid cells, so the floating\n * <DragOverlay> clone jumps cell-to-cell in lockstep with the (always-snapped)\n * placeholder instead of tracking the pointer smoothly. Applied on the item\n * draggable; a no-op unless `dragConfig.snapToGrid` is set.\n */\nexport class SnapToGrid extends Modifier<DragDropManager, SnapToGridOptions> {\n override apply({ transform }: DragDropManager[\"dragOperation\"]) {\n const opts = this.options;\n if (!opts?.isEnabled()) return transform;\n const pp = opts.getPositionParams();\n // A cell step is the column/row size plus the gap to the next cell.\n const colStep = calcGridColWidth(pp) + pp.margin[0];\n const rowStep = pp.rowHeight + pp.margin[1];\n if (colStep <= 0 || rowStep <= 0) return transform; // guard degenerate geometry\n return {\n x: Math.round(transform.x / colStep) * colStep,\n y: Math.round(transform.y / rowStep) * rowStep,\n };\n }\n}\n","import {\n Feedback,\n KeyboardSensor,\n PointerActivationConstraints,\n PointerSensor,\n type Sensors,\n} from \"@dnd-kit/dom\";\nimport type { DragConfig } from \"../types.js\";\n\n/** Marker attribute placed on resize-handle elements. */\nexport const RESIZE_HANDLE_ATTR = \"data-snapgrid-resize-handle\";\n\n// Resize handles are draggables too, but resizing isn't a move — there's no tile\n// to float — so they suppress dnd-kit's visual feedback entirely.\nexport const NO_FEEDBACK = [Feedback.configure({ feedback: \"none\" })];\n\n/**\n * Whether a pointer-down on `target` should NOT start an item move. Pure and\n * exported for testing. Honors three rules, in order:\n * - never start a move from a resize handle;\n * - never start from a region matching `dragConfig.cancel`;\n * - if `dragConfig.handle` is set, only start from within it.\n */\nexport function shouldPreventItemDrag(\n target: EventTarget | null,\n cfg: DragConfig | undefined,\n): boolean {\n if (!(target instanceof Element)) return false;\n if (target.closest(`[${RESIZE_HANDLE_ATTR}]`)) return true;\n if (cfg?.cancel && target.closest(cfg.cancel)) return true;\n if (cfg?.handle && !target.closest(cfg.handle)) return true;\n return false;\n}\n\n/**\n * Sensors for item (move) draggables, built from the drag config: a distance\n * activation threshold (so clicks don't start drags) plus handle/cancel/resize\n * gating, with the keyboard sensor kept for accessibility.\n */\nexport function buildItemSensors(\n threshold: number,\n getDragConfig: () => DragConfig | undefined,\n): Sensors {\n return [\n PointerSensor.configure({\n activationConstraints: () =>\n threshold > 0\n ? [new PointerActivationConstraints.Distance({ value: threshold })]\n : undefined,\n preventActivation: (event: PointerEvent) =>\n shouldPreventItemDrag(event.target, getDragConfig()),\n }),\n KeyboardSensor,\n ];\n}\n","import { useDragDropManager, useDragDropMonitor, useInstance } from \"@dnd-kit/react\";\nimport type { DragEndEvent, DragMoveEvent, DragStartEvent } from \"@dnd-kit/react\";\nimport {\n type Compactor,\n type DragSession,\n type GridConfig,\n type Layout,\n type LayoutItem,\n type PositionParams,\n beginDrag,\n beginReceive,\n beginResize,\n calcGridItemPosition,\n commitLayout,\n defaultGridConfig,\n dragResize,\n dragTo,\n nudge,\n removeItemWithCompactor,\n toPositionParams,\n verticalCompactor,\n} from \"@snapgridjs/core\";\nimport { useCallback, useEffect, useId, useMemo, useRef } from \"react\";\nimport { GridController } from \"../controller/GridController.js\";\nimport { getGrabOffset, registerController, setGrabOffset } from \"../controller/registry.js\";\nimport {\n arrowStep,\n classifyDrop,\n dragData,\n dropDestination,\n externalDropSpec,\n receiveCell,\n} from \"../dnd/dragFlow.js\";\nimport { domElement } from \"../dnd/entity.js\";\nimport { SnapToGrid } from \"../dnd/snapToGrid.js\";\nimport type { DragConfig, DropConfig, GridEventCallback, ResizeConfig } from \"../types.js\";\nimport { buildItemSensors } from \"./dndShared.js\";\n\nconst DEFAULT_HANDLES = [\"se\"] as const;\n\ntype Point = { x: number; y: number };\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 brain: owns the {@link GridController}, runs the dnd-kit drag/resize\n * monitor for this grid, and writes per-grid config to the controller each render.\n * Created by {@link useGridContainer}; items resolve the same controller by their\n * `group` (= this grid's id) from the per-manager registry. 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 // Refs read inside the stable monitor handlers so they never see stale values.\n const optsRef = useRef(opts);\n optsRef.current = opts;\n const ppRef = useRef(positionParams);\n ppRef.current = positionParams;\n const gridRef = useRef(gridConfig);\n gridRef.current = gridConfig;\n const compactorRef = useRef(compactor);\n compactorRef.current = compactor;\n const containerIdRef = useRef(containerId);\n containerIdRef.current = containerId;\n const managerRef = useRef(manager);\n managerRef.current = manager;\n const sessionRef = useRef<DragSession | null>(null);\n const containerElRef = useRef<Element | null>(null);\n // True while the active move was started by the keyboard (Enter/Space on a\n // focused tile) rather than a pointer — drives the arrow-key drag path.\n const keyboardRef = useRef(false);\n // External-drop bookkeeping: a stable synthesized item id + size for the\n // in-flight external draggable this grid may receive.\n const dropSpecRef = useRef<{ i: string; w: number; h: number } | null>(null);\n const dropCounterRef = useRef(0);\n\n // Register the controller so items (and snapMove) resolve it by id. During\n // render so child items resolve it on their first render (children render\n // after the parent but before any layout effect). The effect's cleanup\n // unregisters on unmount / id or manager change.\n registerController(manager, containerId, controller);\n useEffect(\n () => registerController(manager, containerId, controller),\n [manager, containerId, controller],\n );\n\n const committedById = useMemo(\n () => new Map<string, LayoutItem>(opts.layout.map((it) => [it.i, it])),\n [opts.layout],\n );\n const committedByIdRef = useRef(committedById);\n committedByIdRef.current = committedById;\n\n const setSessionBoth = useCallback(\n (next: DragSession | null) => {\n sessionRef.current = next;\n controller.setSession(next);\n },\n [controller],\n );\n\n // Write the keyboard-drag flag to both the synchronous ref (read in the event\n // handlers) and the controller (drives the reactive `hidden` snapshot).\n const setKeyboard = useCallback(\n (value: boolean) => {\n keyboardRef.current = value;\n controller.setKeyboard(value);\n },\n [controller],\n );\n\n const setContainerElement = useCallback((element: Element | null) => {\n containerElRef.current = element;\n }, []);\n\n /**\n * Is THIS grid the drop target dnd-kit's collision observer resolved? Both the\n * move-phase preview and the drop-phase commit read `operation.target`, so they\n * always agree on which grid wins (one oracle), including when grids overlap.\n */\n const overMe = useCallback(\n (target: { id: string | number } | null | undefined) => target?.id === containerIdRef.current,\n [],\n );\n\n /** Map a client-space pointer to a grid cell within THIS grid (see {@link receiveCell}). */\n const cellFromPointer = useCallback((p: Point, item: LayoutItem) => {\n const el = containerElRef.current;\n if (!el) return null;\n const rect = el.getBoundingClientRect();\n return receiveCell(p, rect, getGrabOffset(managerRef.current), item.w, item.h, ppRef.current);\n }, []);\n\n const ctx = useCallback(\n () => ({\n positionParams: ppRef.current,\n compactor: compactorRef.current,\n cols: gridRef.current.cols,\n }),\n [],\n );\n\n const handleDragStart = useCallback(\n (event: DragStartEvent) => {\n // Reset on every start (incl. the external/resize early-returns below) so a\n // keyboard flag can never leak from a prior drag into an unrelated one.\n setKeyboard(false);\n const data = dragData(event);\n if (!data) {\n // An external (non-grid) draggable: if we accept it, reserve a stable\n // synthesized id/size for the item this grid may receive on drop.\n const spec = externalDropSpec(event.operation.source, optsRef.current.dropConfig);\n if (spec) {\n dropCounterRef.current += 1;\n dropSpecRef.current = {\n // Prefix with this grid's id so two drop-enabled grids in a group\n // don't both mint `dropped-1` (colliding item ids).\n i: spec.i ?? `${containerIdRef.current}-dropped-${dropCounterRef.current}`,\n w: spec.w,\n h: spec.h,\n };\n } else {\n dropSpecRef.current = null;\n }\n return;\n }\n dropSpecRef.current = null;\n const layout = optsRef.current.layout;\n const item = layout.find((it) => it.i === data.itemId);\n const p = event.operation.position.current;\n const pointer = { x: p.x, y: p.y };\n if (data.kind === \"resize\") {\n if (!item) return; // resize only applies to the owning grid\n const rect = calcGridItemPosition(ppRef.current, item.x, item.y, item.w, item.h);\n setSessionBoth(beginResize(layout, { item, rect, pointer }, data.handle));\n optsRef.current.onResizeStart?.(\n layout,\n item,\n item,\n item,\n event.operation.activatorEvent,\n null,\n );\n return;\n }\n if (item) {\n // We own the item — this is the source grid.\n const isKeyboard = event.operation.activatorEvent instanceof KeyboardEvent;\n setKeyboard(isKeyboard);\n const rect = calcGridItemPosition(ppRef.current, item.x, item.y, item.w, item.h);\n setSessionBoth(beginDrag(layout, { item, left: rect.left, top: rect.top, pointer }));\n // Share the grab offset (pointer position within the tile) so a receiving\n // grid maps the pointer to the cell under the same point the user grabbed,\n // not the tile's corner.\n const el = domElement(event.operation.source);\n const cr = el?.getBoundingClientRect();\n if (cr) {\n setGrabOffset(managerRef.current, { x: pointer.x - cr.left, y: pointer.y - cr.top });\n }\n optsRef.current.onDragStart?.(\n layout,\n item,\n item,\n item,\n event.operation.activatorEvent,\n null,\n );\n }\n // Otherwise the item belongs to another grid; we may receive it on move.\n },\n [setSessionBoth, setKeyboard],\n );\n\n const handleDragMove = useCallback(\n (event: DragMoveEvent) => {\n // Keyboard moves are driven entirely by the arrow-key handler below; ignore\n // dnd-kit's (pointerless, therefore no-op) move events so they can't revert\n // a nudge back to the static activator cell.\n if (keyboardRef.current) return;\n const p = event.operation.position.current;\n const pointer = { x: p.x, y: p.y };\n const current = sessionRef.current;\n\n if (current?.kind === \"resize\") {\n const next = dragResize(current, pointer, ctx());\n setSessionBoth(next);\n optsRef.current.onResize?.(\n next.preview,\n next.anchor.item,\n next.placeholder,\n next.placeholder,\n event.operation.activatorEvent,\n null,\n );\n return;\n }\n\n const target = event.operation.target;\n const data = dragData(event);\n if (!data) {\n // External (non-grid) draggable: preview where it would land over us.\n const spec = dropSpecRef.current;\n if (spec && overMe(target)) {\n const foreign: LayoutItem = { i: spec.i, x: 0, y: 0, w: spec.w, h: spec.h };\n const committed = optsRef.current.layout;\n const cell = cellFromPointer(pointer, foreign) ?? { x: 0, y: 0 };\n setSessionBoth(beginReceive(committed, foreign, cell.x, cell.y, pointer, ctx()));\n } else if (sessionRef.current) {\n setSessionBoth(null);\n }\n return;\n }\n if (data.kind !== \"move\") return;\n const here = overMe(target);\n const ownsItem = committedByIdRef.current.has(data.itemId);\n\n if (ownsItem) {\n const source = current?.kind === \"move\" ? current : null;\n if (!source) return;\n let next: DragSession;\n if (here) {\n next = dragTo(source, pointer, ctx());\n } else {\n // Leaving this grid: keep the item in place and hide the placeholder\n // here; the dragged tile floats itself across grids (no overlay).\n next = {\n ...source,\n preview: source.committed as LayoutItem[],\n placeholder: null,\n };\n }\n setSessionBoth(next);\n optsRef.current.onDrag?.(\n next.preview,\n next.anchor.item,\n next.placeholder,\n next.placeholder,\n event.operation.activatorEvent,\n null,\n );\n return;\n }\n\n // We don't own the item — maybe receive it.\n if (here) {\n const foreign = data.item;\n const committed = optsRef.current.layout;\n const cell = cellFromPointer(pointer, foreign) ?? { x: 0, y: 0 };\n setSessionBoth(beginReceive(committed, foreign, cell.x, cell.y, pointer, ctx()));\n } else if (sessionRef.current) {\n setSessionBoth(null); // pointer left; we're no longer receiving\n }\n },\n [setSessionBoth, overMe, cellFromPointer, ctx],\n );\n\n const handleDragEnd = useCallback(\n (event: DragEndEvent) => {\n const current = sessionRef.current;\n const data = dragData(event);\n const myId = containerIdRef.current;\n // A keyboard drop always commits in-grid; a pointer drop uses the collision\n // target (see dropDestination).\n const dest = dropDestination({\n keyboard: keyboardRef.current,\n targetId: event.operation.target?.id,\n myId,\n });\n const ownsItem = data ? committedByIdRef.current.has(data.itemId) : false;\n setGrabOffset(managerRef.current, null);\n\n const native = event.nativeEvent ?? null;\n const o = optsRef.current;\n // Pure classification of what this drop means for THIS grid; the switch\n // below maps each action to its callbacks (see dragFlow.ts for the contract).\n const action = classifyDrop({\n kind: current?.kind ?? null,\n canceled: event.canceled,\n ownsItem,\n hasData: !!data,\n dest,\n myId,\n });\n\n switch (action) {\n case \"cancel-resize\":\n o.onResizeStop?.(o.layout, current?.anchor.item ?? null, null, null, native, null);\n break;\n case \"cancel-move\":\n o.onDragStop?.(o.layout, current?.anchor.item ?? null, null, null, native, null);\n break;\n case \"commit-resize\":\n if (current) {\n o.onLayoutChange?.(commitLayout(current));\n o.onResizeStop?.(\n current.preview,\n current.anchor.item,\n current.placeholder,\n current.placeholder,\n native,\n null,\n );\n }\n break;\n case \"commit-in-grid\":\n case \"remove-source\":\n case \"revert\": {\n // Source grid finishing its drag: all fire onDragStop, differing only in layout.\n if (action === \"commit-in-grid\" && current) {\n o.onLayoutChange?.(commitLayout(current));\n } else if (action === \"remove-source\" && data) {\n const { compactor: c, cols } = ctx();\n o.onLayoutChange?.(\n removeItemWithCompactor(o.layout, data.itemId, { compactor: c, cols }),\n );\n } // \"revert\" → dropped outside any grid → no layout change.\n o.onDragStop?.(\n current?.preview ?? o.layout,\n current?.anchor.item ?? null,\n current?.placeholder ?? null,\n current?.placeholder ?? null,\n native,\n null,\n );\n break;\n }\n case \"commit-dest\":\n if (current) o.onLayoutChange?.(commitLayout(current));\n break;\n case \"external-drop\":\n // Hand the synthesized item to onDrop so the consumer can add it.\n if (current) {\n const committed = commitLayout(current);\n const dropped = committed.find((it) => it.i === current.activeId);\n if (dropped) o.onDrop?.(committed, dropped, native);\n }\n break;\n // \"noop\" → nothing to do.\n }\n dropSpecRef.current = null;\n setKeyboard(false);\n setSessionBoth(null);\n },\n [setSessionBoth, setKeyboard, ctx],\n );\n\n // Keyboard dragging: while a keyboard-initiated move is active, arrow keys step\n // the tile one cell at a time (it moves in place via the session preview — no\n // overlay). Enter / Space (drop) and Escape (cancel) fall through to dnd-kit's\n // KeyboardSensor.\n useEffect(() => {\n const onKeyDown = (e: KeyboardEvent) => {\n if (!keyboardRef.current) return;\n const session = sessionRef.current;\n if (!session || session.kind !== \"move\") return;\n const step = arrowStep(e.key);\n if (!step) return; // Enter/Space/Escape → dnd-kit handles drop/cancel\n e.preventDefault();\n // Own the arrow: stop dnd-kit's KeyboardSensor (a document capture-phase\n // listener) from also moving — otherwise its internal operation position\n // drifts every keystroke. We run in capture on window, ahead of it.\n e.stopImmediatePropagation();\n setSessionBoth(nudge(session, step[0], step[1], ctx()));\n };\n window.addEventListener(\"keydown\", onKeyDown, true);\n return () => window.removeEventListener(\"keydown\", onKeyDown, true);\n }, [ctx, setSessionBoth]);\n\n // Stable handlers object: dnd-kit's monitor effect keys on the handlers\n // identity, so a fresh literal each render would tear down and re-add all\n // listeners on every render (i.e. every pointer move, for every grid).\n const monitorHandlers = useMemo(\n () => ({\n onDragStart: handleDragStart,\n onDragMove: handleDragMove,\n onDragEnd: handleDragEnd,\n }),\n [handleDragStart, handleDragMove, handleDragEnd],\n );\n useDragDropMonitor(monitorHandlers);\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 // Publish per-grid config to the controller so items (resolved by group) read\n // fresh geometry/predicates without a React context.\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 setContainerElement,\n });\n\n return controller;\n}\n","import { useDroppable } from \"@dnd-kit/react\";\nimport { type GridConfig, bottom } from \"@snapgridjs/core\";\nimport { type CSSProperties, useCallback, useRef, useSyncExternalStore } from \"react\";\nimport type { GridController } from \"../controller/GridController.js\";\nimport { SNAPGRID_GRID_ATTR, gridCollisionDetector } from \"../dnd/collision.js\";\nimport { domElement } from \"../dnd/entity.js\";\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, setContainerElement } = 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 // (used to map the pointer to a cell when receiving a tile from another grid),\n // and mark the element so nested grids can measure their depth (gridDepth).\n const setRef = useCallback(\n (element: Element | null) => {\n ref(element);\n setContainerElement(element);\n gridElRef.current = element;\n if (element) element.setAttribute(SNAPGRID_GRID_ATTR, \"\");\n },\n [ref, setContainerElement],\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 } from \"../controller/GridController.js\";\nimport { getController } from \"../controller/registry.js\";\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 const data = useMemo(() => ({ snapGrid: { kind: \"move\", itemId: id, item } }), [id, item]);\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 { useSyncExternalStore } from \"react\";\nimport { NO_FEEDBACK, RESIZE_HANDLE_ATTR } from \"./dndShared.js\";\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 } },\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 CSSProperties, type ReactNode, useMemo } from \"react\";\nimport { useResponsiveLayout } from \"../hooks/useResponsiveLayout.js\";\nimport type { DragConfig, ResizeConfig } from \"../types.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.0",
3
+ "version": "0.4.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,7 +51,7 @@
51
51
  "module": "./dist/index.mjs",
52
52
  "types": "./dist/index.d.mts",
53
53
  "dependencies": {
54
- "@snapgridjs/core": "0.1.0"
54
+ "@snapgridjs/core": "0.4.0"
55
55
  },
56
56
  "peerDependencies": {
57
57
  "react": ">=18",