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

# Toolbox

<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="Toolbox preview"
    src="https://dnd-grid.com/examples/toolbox-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-toolbox-example.tsx)

## Installation

<Tabs>
<Tab title="CLI">

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

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

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

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

```tsx title="components/dnd-grid-toolbox-example.tsx"
"use client";

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

interface ToolboxItem {
  id: string;
  x: number;
  y: number;
  w: number;
  h: number;
  visible: boolean;
}

const initialItems: ToolboxItem[] = [
  { id: "a", x: 0, y: 0, w: 2, h: 2, visible: true },
  { id: "b", x: 2, y: 0, w: 2, h: 2, visible: true },
  { id: "c", x: 4, y: 0, w: 2, h: 2, visible: false },
  { id: "d", x: 6, y: 0, w: 2, h: 2, visible: false },
];

const removeButtonStyle: CSSProperties = {
  position: "absolute",
  top: 6,
  right: 6,
  width: 22,
  height: 22,
  borderRadius: 9999,
  border: "1px solid #e5e7eb",
  background: "white",
  color: "#0f172a",
  display: "inline-flex",
  alignItems: "center",
  justifyContent: "center",
  fontSize: 12,
  lineHeight: "1",
  cursor: "pointer",
  boxShadow: "0 1px 2px rgba(15, 23, 42, 0.08)",
};

export function ToolboxExample() {
  const [items, setItems] = useState<ToolboxItem[]>(initialItems);

  const toggleItem = (id: string) => {
    setItems((prev) =>
      prev.map((item) =>
        item.id === id ? { ...item, visible: !item.visible } : item,
      ),
    );
  };

  const visibleItems = items.filter((item) => item.visible);
  const hiddenItems = items.filter((item) => !item.visible);
  const visibleLayout: Layout = visibleItems.map(
    ({ visible, ...item }) => item,
  );

  const handleLayoutChange = (newLayout: Layout) => {
    setItems((prev) =>
      prev.map((item) => {
        const updated = newLayout.find((l) => l.id === item.id);
        return updated ? { ...item, ...updated } : item;
      }),
    );
  };

  return (
    <div>
      <div className="toolbox">
        <div>Toolbox (click to add)</div>
        {hiddenItems.map((item) => (
          <button
            key={item.id}
            type="button"
            onClick={() => toggleItem(item.id)}
          >
            {item.id}
          </button>
        ))}
      </div>

      <DndGrid
        layout={visibleLayout}
        cols={12}
        rowHeight={50}
        onLayoutChange={handleLayoutChange}
      >
        {visibleItems.map((item) => (
          <div key={item.id} className="grid-item">
            <span>{item.id}</span>
            <button
              type="button"
              onClick={() => toggleItem(item.id)}
              style={removeButtonStyle}
              aria-label={`Remove ${item.id}`}
              title="Remove"
            >
              x
            </button>
          </div>
        ))}
      </DndGrid>
    </div>
  );
}
```

</Tab>
</Tabs>

## Usage

```tsx
import { ToolboxExample } from "@/components/dnd-grid-toolbox-example";

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