Dynamic add/remove
dnd-grid/dynamic-add-remove-exampleFreeComponent
Add and remove items at runtime.
Install it
npx shadcn@latest add https://dnd-grid.com/r/dynamic-add-remove-example.jsonSource
1"use client";23import { DndGrid, findEmptyPosition, type Layout } from "@dnd-grid/react";4import { type CSSProperties, useCallback, useState } from "react";56const removeButtonStyle: CSSProperties = {7 position: "absolute",8 top: 6,9 right: 6,10 width: 22,11 height: 22,12 borderRadius: 9999,13 border: "1px solid #e5e7eb",14 background: "white",15 color: "#0f172a",16 display: "inline-flex",17 alignItems: "center",18 justifyContent: "center",19 fontSize: 12,20 lineHeight: "1",21 cursor: "pointer",22 boxShadow: "0 1px 2px rgba(15, 23, 42, 0.08)",23};2425export function DynamicAddRemoveExample() {26 const [counter, setCounter] = useState(5);27 const [layout, setLayout] = useState<Layout>(28 [0, 1, 2, 3, 4].map((i) => ({29 id: i.toString(),30 x: (i * 2) % 12,31 y: 0,32 w: 2,33 h: 2,34 }))35 );3637 const addItem = useCallback(() => {38 setLayout((prev) => {39 const position = findEmptyPosition(prev, { w: 2, h: 2 }, 12);4041 return [42 ...prev,43 {44 id: `n${counter}`,45 ...position,46 w: 2,47 h: 2,48 },49 ];50 });51 setCounter((c) => c + 1);52 }, [counter]);5354 const removeItem = useCallback((id: string) => {55 setLayout((prev) => prev.filter((item) => item.id !== id));56 }, []);5758 const removeLastItem = useCallback(() => {59 setLayout((prev) => (prev.length > 0 ? prev.slice(0, -1) : prev));60 }, []);6162 return (63 <div>64 <div style={{ display: "flex", gap: 8, marginBottom: 12 }}>65 <button onClick={addItem} type="button">66 Add Item67 </button>68 <button69 disabled={layout.length === 0}70 onClick={removeLastItem}71 type="button"72 >73 Remove Last Item74 </button>75 </div>7677 <DndGrid78 cols={12}79 dragCancel=".grid-item-remove"80 layout={layout}81 onLayoutChange={setLayout}82 rowHeight={50}83 >84 {layout.map((item) => (85 <div className="grid-item" key={item.id}>86 <span>{item.id}</span>87 <button88 aria-label={`Remove ${item.id}`}89 className="grid-item-remove"90 onClick={() => removeItem(item.id)}91 style={removeButtonStyle}92 title="Remove"93 type="button"94 >95 x96 </button>97 </div>98 ))}99 </DndGrid>100 </div>101 );102}
What it pulls in
npm packages
Files it writes
More from dnd-grid
All 19 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Allow overlapallow-overlap-example | dnd-grid | Components | Free | 3 deps | |
| Aspect ratio constraintsaspect-ratio-constraints-example | dnd-grid | Components | Free | 3 deps | |
| Basic examplebasic-example | dnd-grid | Components | Free | 3 deps | |
| Boundedbounded-example | dnd-grid | Components | Free | 3 deps | |
| Compactor showcasecompactor-showcase-example | dnd-grid | Components | Free | 3 deps | |
| Compositioncomposition-example | dnd-grid | Components | Free | 3 deps | |
| Constraintsconstraints-example | dnd-grid | Components | Free | 3 deps | |
| Drag from outsidedrag-from-outside-example | dnd-grid | Components | Free | 3 deps |
