Skip to content

Sub-grid elements are not draggable/resizable when added dynamically inside a nested GridStack layout (React) #3084

@alphacode-rajinthank

Description

@alphacode-rajinthank

Hi GridStack team 👋,

First of all, thanks for maintaining this amazing library — it's super powerful!

I'm currently using GridStack.js inside a Next.js + TypeScript project to build a fully customizable screen layout editor with support for nested components. My goal is to allow drag/drop + resize in both parent and child layouts.

The issue I'm facing is:

When dynamically adding a new item inside a nested (child) GridStack, the new item is rendered but cannot be dragged or resized.

I've been stuck on this for several days — I’ve tried many things and looked through the docs and GitHub issues, but I still can’t solve it. If anyone can help, I’d really appreciate it 🙏

✅ What works

  • The parent GridStack initializes and behaves correctly.
  • The initial children inside the nested GridStack also render and behave correctly.
  • However, dynamically added items inside the nested grid are not draggable or resizable.

🧪 What I’m trying to build

  • Nested GridStack layout with parent and child grids.
  • Both parent and child initialized with GridStack.init(...) in useEffect.
  • New items are added dynamically via React state.
  • Expectation: new items inside subgrid should behave like others.

❌ What’s going wrong

  • New elements inside a nested child grid:
    • Render visually
    • But can’t be dragged or resized
  • DOM contains correct .grid-stack-item wrappers.
  • Tried subGridDynamic: true – didn’t help.

Environment

{
  "next": "^15.2.3",
  "react": "^18.x",
  "typescript": "^5.8.2",
  "typescript-eslint": "^8.27.0",
  "gridstack": "^8.3.0"
}

Code Snippets
Parent Grid

const dropRef = useRef<HTMLDivElement>(null);
const gridRef = useRef<any>(null);

useEffect(() => {
  if (!dropRef.current) return;

  if (gridRef.current) {
    gridRef.current.destroy(false); // Clean up
  }

  const grid = GridStack.init(
    {
      draggable: { handle: ".drag-handle" },
      cellHeight: "20px",
      column: COLUMN.MAX,
      float: true,
      margin: 0,
    },
    dropRef.current
  );

  gridRef.current = grid;

  dropRef.current.addEventListener("change", (event: any) => {
    const items = event.detail;
    items.forEach((item: any) => {
      const { x, y, w, h, el } = item;
      const id = el.getAttribute("id");
      if (id) {
        updatePosition(String(x), String(y), String(w), String(h), id);
      }
    });
  });
}, [children?.length, forceRender, updatePosition]);

Child Grid (nested, works only for initial children)

useEffect(() => {
  const el = dropRef.current as (HTMLDivElement & { gridstack?: GridStack }) | null;
  if (!el) return;

  if (!el.gridstack) {
    const grid = GridStack.init(
      {
        draggable: { handle: ".drag-handle" },
        cellHeight: "20px",
        column: COLUMN.MAX,
        margin: 0,
        float: true,
        // subGridDynamic: true, // Tried this too
      },
      el
    );

    el.gridstack = grid;

    dropRef.current?.addEventListener("change", (event: any) => {
      const items = event.detail;
      items.forEach((item: any) => {
        const { x, y, w, h, el } = item;
        const id = el.getAttribute("id");
        if (id) {
          updatePosition(String(x), String(y), String(w), String(h), id);
        }
      });
    });
  }
}, [updatePosition, children?.length, forceRender]);

Tried but didn't work

  • Adding subGridDynamic: true
  • Using setTimeout() to delay init
  • Destroying and re-initializing child grid on update
  • Forcing re-render with state toggles
  • Manually triggering DOM events

Am I missing something to make GridStack work properly when I add new items inside a nested grid?
Is there a workaround or something I should do after adding a new .grid-stack-item?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions