1const [data, setData] = useState([
2 {
3 id: "1",
4 title: "Item 1",
5 description: "Item 1 description",
6 }, {/* ... */}
7]);
8
9<SortableComp.Root
10 value={data}
11 onValueChange={setData}
12 getItemValue={(item) => item.id}
13 orientation="mixed"
14>
15 <SortableComp.Content className="grid auto-rows-fr grid-cols-3 gap-2.5">
16 {data.map((item) => (
17 <SortableComp.Item key={item.id} value={item.id} asChild asHandle>
18 <div className="flex items-center gap-x-2 size-full rounded-md border shadow-sm bg-zinc-100 dark:bg-zinc-900 px-2 py-2 md:py-4">
19 <GripVertical className="size-3 md:size-6" />
20 <div className="flex flex-col gap-1 text-foreground">
21 <div className="font-medium text-sm leading-tight md:text-base">
22 {item.title}
23 </div>
24 <span className="line-clamp-2 hidden text-muted-foreground text-sm md:inline-block">
25 {item.description}
26 </span>
27 </div>
28 </div>
29 </SortableComp.Item>
30 ))}
31 </SortableComp.Content>
32 <SortableComp.Overlay>
33 <div className="size-full rounded-md bg-primary/5" />
34 </SortableComp.Overlay>
35</SortableComp.Root>