> ## Documentation Index
> Fetch the complete documentation index at: https://dnd-grid.blode.md/llms.txt
> Use this file to discover all available pages before exploring further.

# Drag from outside

<div className="not-prose my-6 rounded-lg border border-zinc-200/70 bg-white/70 shadow-sm dark:border-white/10 dark:bg-white/5">
  <iframe
    title="Drag from outside preview"
    src="https://dnd-grid.com/examples/drag-from-outside-example?embed=1"
    className="h-[640px] w-full"
    loading="lazy"
  />
</div>

[View source on GitHub](https://github.com/mblode/dnd-grid/blob/main/apps/web/examples/dnd-grid-drag-from-outside-example.tsx)

## Installation

<Tabs>
<Tab title="CLI">

```bash
npx shadcn@latest add https://dnd-grid.com/r/drag-from-outside-example.json
```

</Tab>
<Tab title="Manual">

```bash
npm install @dnd-grid/react
```

```css
@import "@dnd-grid/react/styles.css";
```

```tsx title="components/dnd-grid-drag-from-outside-example.tsx"
"use client";

import { DndGrid, type Layout, type LayoutItem } from "@dnd-grid/react";
import { useRef, useState } from "react";

type PaletteItem = {
  id: string;
  label: string;
  w: number;
  h: number;
};

const paletteItems: PaletteItem[] = [
  { id: "small", label: "Small (2x2)", w: 2, h: 2 },
  { id: "wide", label: "Wide (4x2)", w: 4, h: 2 },
  { id: "tall", label: "Tall (2x4)", w: 2, h: 4 },
];

const initialLayout: Layout = [
  { id: "a", x: 0, y: 0, w: 3, h: 2 },
  { id: "b", x: 3, y: 0, w: 3, h: 3 },
  { id: "c", x: 6, y: 0, w: 3, h: 2 },
  { id: "d", x: 9, y: 0, w: 3, h: 2 },
];

export function DragFromOutsideExample() {
  const [layout, setLayout] = useState<Layout>(initialLayout);
  const dragItemRef = useRef<PaletteItem | null>(null);
  const nextIdRef = useRef(1);

  const handleDropDragOver = () => {
    const active = dragItemRef.current;
    return active ? { w: active.w, h: active.h } : undefined;
  };

  const handleDrop = (_layout: Layout, item?: LayoutItem | null) => {
    if (!item) return;
    const nextId = `n${nextIdRef.current}`;
    nextIdRef.current += 1;
    setLayout((prev) => [
      ...prev,
      { id: nextId, x: item.x, y: item.y, w: item.w, h: item.h },
    ]);
  };

  return (
    <div>
      <div style={{ display: "flex", gap: 12, marginBottom: 12 }}>
        {paletteItems.map((palette) => (
          <button
            key={palette.id}
            type="button"
            draggable
            onDragStart={(event) => {
              dragItemRef.current = palette;
              event.dataTransfer.setData("text/plain", palette.id);
            }}
            style={{
              appearance: "none",
              background: "white",
              border: "1px solid #e5e7eb",
              padding: "6px 10px",
              borderRadius: "6px",
              fontSize: "12px",
              cursor: "grab",
            }}
          >
            {palette.label}
          </button>
        ))}
      </div>

      <DndGrid
        layout={layout}
        cols={12}
        rowHeight={50}
        onDrop={handleDrop}
        onDropDragOver={handleDropDragOver}
        onLayoutChange={setLayout}
      >
        {layout.map((item) => (
          <div key={item.id} className="grid-item">
            {item.id}
          </div>
        ))}
      </DndGrid>
    </div>
  );
}
```

</Tab>
</Tabs>

## Usage

```tsx
import { DragFromOutsideExample } from "@/components/dnd-grid-drag-from-outside-example";

export default function Page() {
  return <DragFromOutsideExample />;
}
```