はじめに
こんにちは、エンジニアのkeitaMaxです。
こちらのライブラリを使用して、ドラッグ&ドロップで並び替えできるリストを作成しようと思います。
Next.jsとTailwindCSSを使用しています。
インストール
以下をインストールします。
npm install @dnd-kit/core @dnd-kit/sortable
実装
ファイル構成は以下のようにしました。
/
└─ src/views
└─ DragDropView
├─ index.ts
├─ index.stories.tsx
└─ components/SortableItem
└─ index.ts
DragDropView/index.tsx
import { DndContext, useSensor, useSensors } from '@dnd-kit/core'
import React, { useState } from 'react'
import { arrayMove, SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy } from '@dnd-kit/sortable'
import {
closestCenter,
KeyboardSensor,
PointerSensor,
} from "@dnd-kit/core"
import { SortableItem } from './components/SortableItem'
export const DragDropView = React.memo(function DragDropView() {
const [items, setItems] = useState(["Item 1", "Item 2", "Item 3", "Item 4"])
const sensors = useSensors(
useSensor(PointerSensor),
useSensor(KeyboardSensor, {
coordinateGetter: sortableKeyboardCoordinates,
})
)
const handleDragEnd = (event: any) => {
const { active, over } = event
if (active.id !== over.id) {
setItems((prevItems) => {
const oldIndex = prevItems.indexOf(active.id)
const newIndex = prevItems.indexOf(over.id)
return arrayMove(prevItems, oldIndex, newIndex)
})
}
}
return (
<DndContext
sensors={sensors}
collisionDetection={closestCenter}
onDragEnd={handleDragEnd}
>
<SortableContext items={items} strategy={verticalListSortingStrategy}>
<ul className="mx-auto max-w-md rounded bg-gray-100 p-4 shadow">
{items.map((item) => (
<SortableItem key={item} id={item} />
))}
</ul>
</SortableContext>
</DndContext>
)
})
export default DragDropView
DragDropView/index.stories.tsx
import { Meta, StoryObj } from '@storybook/react'
import { DragDropView } from '.'
const meta: Meta<typeof DragDropView> = {
component: DragDropView,
tags: ['autodocs'],
}
export default meta
type Story = StoryObj<typeof meta>
export const Default: Story = {}
SortableItem/index.tsx
import React from "react"
import { useSortable } from "@dnd-kit/sortable"
import { CSS } from "@dnd-kit/utilities"
interface SortableItemProps {
id: string;
}
export const SortableItem: React.FC<SortableItemProps> = ({ id }) => {
const { attributes, listeners, setNodeRef, transform, transition } =
useSortable({ id })
const style = {
transform: CSS.Transform.toString(transform),
transition,
}
return (
<li
ref={setNodeRef}
style={style}
{...attributes}
{...listeners}
className="mb-2 cursor-pointer rounded bg-white p-4 shadow hover:bg-gray-50"
>
{id}
</li>
)
}
これをnpm run storybookをして確認します。
挙動
こんな感じでドラッグ&ドロップで動かせるようなリストが完成しました!
おわりに
この記事での質問や、間違っている、もっといい方法があるといったご意見などありましたらご指摘していただけると幸いです。
最後まで読んでいただきありがとうございました!
参考