I-007 Interaction medium

How to create a drag drop list ドラッグ&ドロップリストの作り方

Sortable list interface using drag and drop interactions. 項目の並べ替えが可能なドラッグ&ドロップリスト。

ライブデモ Live Demo

  • Item 1: Research
  • Item 2: Design
  • Item 3: Development
  • Item 4: Testing

概要・用途・特徴Overview, Usage & Features

何ができるかWhat it does

Sortable list interface using drag and drop interactions.

項目の並べ替えが可能なドラッグ&ドロップリスト。

どこで使うかWhere to use

user engagement, data entry, content management, settings panel

タスク管理、カンバンボード、プレイリスト並び替え、ダッシュボードウィジェット配置

特徴Key features

Native HTML5 drag-and-drop API for reordering list items. Smooth CSS transition animates list reflow on drop. No external DnD library needed. Touch support via Pointer Events fallback. Visual drag ghost and drop target indicators.

リストアイテムの並び替えにネイティブHTML5ドラッグ&ドロップAPIを使用。ドロップ時のリストリフローをスムーズなCSSトランジションでアニメーション。外部DnDライブラリ不要。Pointer Eventsフォールバックでタッチサポート。ドラッグゴーストとドロップターゲットインジケーターを表示。

調整可能パラメータ Adjustable Parameters

Parameter Default Description
--item-paddingItem padding
--drag-highlightDrag highlight color

実装コード Implementation Code

<ul id="list">
  <li draggable="true">Item 1</li>
  <li draggable="true">Item 2</li>
</ul>



<script>
// Drag and Drop logic
</script>
/* react/I-007.css */
/* I-007: React styles */
.draggable-list {
  max-width: 400px;
  margin: 0 auto;
  padding: 0;
  list-style: none;
}

.draggable-item {
  background: #fff;
  border: 1px solid #e0e4f0;
  border-radius: 8px;
  padding: 16px;
  margin-bottom: 12px;
  display: flex;
  align-items: center;
  gap: 12px;
  cursor: grab;
  transition: transform 0.2s, box-shadow 0.2s;
}

.draggable-item:active {
  cursor: grabbing;
}

.draggable-item.dragging {
  opacity: 0.5;
  border: 2px dashed #5c6ac4;
}

.drag-handle {
  color: #5c6184;
  cursor: grab;
  padding: 4px;
}

.drag-content {
  flex: 1;
  font-weight: 500;
  color: #1d2242;
}
import { useState, useRef } from 'react';
import './I-007.css';

export default function DraggableList({ initialItems = [] }) {
  const [items, setItems] = useState(initialItems);
  const dragItem = useRef();
  const dragOverItem = useRef();

  const dragStart = (e, position) => {
    dragItem.current = position;
    e.target.classList.add('dragging');
  };

  const dragEnter = (e, position) => {
    dragOverItem.current = position;
  };

  const drop = (e) => {
    const copyListItems = [...items];
    const dragItemContent = copyListItems[dragItem.current];
    copyListItems.splice(dragItem.current, 1);
    copyListItems.splice(dragOverItem.current, 0, dragItemContent);
    dragItem.current = null;
    dragOverItem.current = null;
    setItems(copyListItems);
    e.target.classList.remove('dragging'); // In real app, might need more robust class cleanup
  };

  return (
    <ul className="draggable-list">
      {items.map((item, index) => (
        <li
          key={index}
          className="draggable-item"
          draggable
          onDragStart={(e) => dragStart(e, index)}
          onDragEnter={(e) => dragEnter(e, index)}
          onDragEnd={drop}
        >
          <span className="drag-handle">☰</span>
          <span className="drag-content">{item}</span>
        </li>
      ))}
    </ul>
  );
}
/* I-007: React styles */
.draggable-list {
  max-width: 400px;
  margin: 0 auto;
  padding: 0;
  list-style: none;
}

.draggable-item {
  background: #fff;
  border: 1px solid #e0e4f0;
  border-radius: 8px;
  padding: 16px;
  margin-bottom: 12px;
  display: flex;
  align-items: center;
  gap: 12px;
  cursor: grab;
  transition: transform 0.2s, box-shadow 0.2s;
}

.draggable-item:active {
  cursor: grabbing;
}

.draggable-item.dragging {
  opacity: 0.5;
  border: 2px dashed #5c6ac4;
}

.drag-handle {
  color: #5c6184;
  cursor: grab;
  padding: 4px;
}

.drag-content {
  flex: 1;
  font-weight: 500;
  color: #1d2242;
}

仕組みとカスタマイズHow It Works & Customization

仕組みHow it works

Each list item has draggable="true". dragstart stores the dragged element reference. On dragover of other items, insertBefore or insertAfter repositions the element in the DOM to reflect the new order visually. dragend commits the final order. CSS transition on the list container animates the sibling items flowing to fill the gap.

各リストアイテムはdraggable="true"を持ちます。dragstartがドラッグ中の要素参照を格納。他のアイテムのdragover時、insertBeforeまたはinsertAfterが新しい順序を反映してDOM内の要素を移動。dragendが最終順序を確定。リストコンテナのCSSトランジションが隙間を埋めるよう兄弟アイテムをアニメーション。

カスタマイズ方法Customization

Add handle elements (drag-grip icons) so only dragging from the handle activates DnD. Highlight the drop zone with a dashed border using the dragover class. Emit a custom orderChanged event so parent components can persist the new order to an API.

ハンドル要素(ドラッググリップアイコン)を追加してハンドルからのドラッグのみDnDを発効。dragoverクラスでドロップゾーンに点線ボーダーをハイライト。orderChangedカスタムイベントを発行して親コンポーネントが新しい順序をAPIに保存できるようにする。

注意点Caveats

Native drag-and-drop has limited touch support — add touchstart/touchmove/touchend event handlers or use a polyfill for mobile users. Provide a keyboard-accessible alternative (up/down arrow buttons) to reorder items for accessibility.

ネイティブドラッグ&ドロップはタッチサポートが限定的です。モバイルユーザー向けにtouchstart/touchmove/touchendイベントハンドラを追加するかポリフィルを使用してください。アクセシビリティのためにキーボードアクセシブルな代替手段(上下矢印ボタン)を提供してください。

よくある質問 Frequently Asked Questions

How to customize the drag & drop list? Drag & Drop Listをカスタマイズするには?

Modify the CSS custom properties and class styles defined in the code section. Key adjustable values include colors, sizes, durations, and spacing. See the Adjustable Parameters section for specific variables.

コードセクションで定義されているCSSカスタムプロパティとクラススタイルを変更してください。色、サイズ、時間、間隔が主な調整可能値です。具体的な変数は調整可能パラメータセクションを参照してください。

How to use the drag & drop list in React? ReactでDrag & Drop Listを使うには?

Import the provided React component and its CSS file. The component accepts props for customization. Check the React code section for the full implementation and available props.

提供されているReactコンポーネントとCSSファイルをインポートしてください。コンポーネントのpropsでカスタマイズできます。完全な実装と利用可能なpropsはReactコードセクションを参照してください。

What are the performance implications of drag & drop list? Drag & Drop Listのパフォーマンスへの影響は?

This implementation uses CSS transforms and opacity for animations, which are GPU-accelerated. It's lightweight and doesn't cause layout thrashing. Consider using prefers-reduced-motion for accessibility.

この実装はCSSのtransformとopacityを使用しており、GPUアクセラレーションされます。軽量でレイアウトスラッシングを引き起こしません。アクセシビリティのためにprefers-reduced-motionの使用を検討してください。

AIへの指示テンプレート AI Prompt Template

以下をAIに貼り付けると実装を依頼できます。 Paste the following into your AI assistant to request implementation.