Skip to Content
DocumentationComponentMotionDnDGrid

MotionDnDGrid

MotionDnDGrid 컴포넌트는 드래그 앤 드롭으로 그리드 아이템을 재정렬할 수 있는 리스트를 만들 때 사용해요.

import { MotionDnDGrid } from '@simple-motion-dnd/grid'; import { useState } from 'react'; const [items, setItems] = useState([ { id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }, { id: 6 }, ]); return ( <MotionDnDGrid.Group items={items} onSorted={setItems} cols={3} gap={10}> {items.map((item) => ( <MotionDnDGrid.Item key={item.id} itemId={item.id}> <div>{item.id}</div> </MotionDnDGrid.Item> ))} </MotionDnDGrid.Group> );

참고: MotionDnDGrid가볍고 직관적인 그리드 기반 DnD 구현을 목표로 설계되었어요. 다중 행 간 드래그, 영역 간 이동, 복잡한 트리 구조 같은 고급 기능은 지원하지 않아요. 이런 기능이 필요하다면 DnD Kit 같은 고급 라이브러리를 추천해요.


사용법

모든 재정렬 가능한 그리드는 MotionDnDGrid.Group 컴포넌트로 감싸야 해요.
이 컴포넌트는 드래그 가능한 아이템들의 위치와 정렬 상태를 관리해요.

import { MotionDnDGrid } from '@simple-motion-dnd/grid'; function Grid() { return <MotionDnDGrid.Group></MotionDnDGrid.Group>; }

기본적으로 <ul> 요소로 렌더링되지만, as prop으로 변경할 수 있어요.

<MotionDnDGrid.Group as="div">

MotionDnDGrid.Group에는 반드시 items prop으로 아이템 리스트를 전달해야 해요.
또한 아이템 순서가 변경되면 onSorted 이벤트가 새 순서와 함께 호출돼요.

const [items, setItems] = useState([{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }]); <MotionDnDGrid.Group items={items} onSorted={setItems} cols={2} gap={10} />;

각 재정렬 가능한 아이템을 렌더링하려면 MotionDnDGrid.Item을 사용하고, itemId prop으로 해당 아이템의 고유 ID를 전달해요.

<MotionDnDGrid.Group items={items} onSorted={setItems} cols={2} gap={10}> {items.map((item) => ( <MotionDnDGrid.Item key={item.id} itemId={item.id}> <div>{item.id}</div> </MotionDnDGrid.Item> ))} </MotionDnDGrid.Group>

이제 아이템을 드래그하면 onSorted가 새로운 순서와 함께 호출돼요.

스크롤 가능한 그리드

MotionDnDGrid.Group을 스크롤 가능한 컨테이너에서 사용한다면,
Framer Motion이 올바르게 레이아웃을 측정할 수 있도록 layoutScroll prop을 추가해야 해요.

<MotionDnDGrid.Group layoutScroll items={items} onSorted={setItems} cols={3} gap={10} style={{ overflowY: 'auto', height: '400px' }}> {items.map((item) => ( <MotionDnDGrid.Item key={item.id} itemId={item.id}> <div>{item.id}</div> </MotionDnDGrid.Item> ))} </MotionDnDGrid.Group>

드래그 트리거

기본적으로 MotionDnDGrid.Item전체 영역이 드래그 가능해요.
특정 영역만 드래그 가능하게 하려면 useDragControls를 사용하면 돼요.

import { MotionDnDGrid, useDragControls } from '@simple-motion-dnd/grid'; function Item({ itemId }) { const controls = useDragControls(); return ( <MotionDnDGrid.Item itemId={itemId} dragListener={false} dragControls={controls}> <div className="drag-handle cursor-grab" onPointerDown={(e) => controls.start(e)}> 드래그 핸들 </div> <div className="content">아이템 내용</div> </MotionDnDGrid.Item> ); }


z-index

MotionDnDGrid.Item은 드래그 중인 아이템이 다른 아이템 위로 표시되도록
자동으로 z-index 스타일을 적용해요. 내부적으로 position: relative로 설정되어 있어,
드래그 중에도 자연스럽게 위로 떠오르는 효과를 볼 수 있어요.


API Reference

MotionDnDGrid.Group

Prop타입기본값설명
askeyof HTMLElementTagNameMap'ul'렌더링할 HTML 태그를 지정해요.
itemsT[]재정렬될 아이템 배열이에요. 각 아이템은 id 속성을 포함해야 해요.
onSorted(newOrder: T[]) => void순서가 변경될 때 호출돼요.
colsnumber한 줄에 표시할 열의 개수예요.
gapnumber아이템 간의 간격(px 단위)이에요.
layoutScrollbooleanfalse스크롤 가능한 컨테이너에서 사용 시 true로 설정해요.

MotionDnDGrid.Item

Prop타입기본값설명
askeyof HTMLElementTagNameMap'li'렌더링할 HTML 태그를 지정해요.
itemIdstring | number아이템의 고유 ID예요.
onDragStart(event, info) => void드래그 시작 시 호출돼요.
onDrag(event, info) => void드래그 중 호출돼요.
onDragEnd(event, info) => void드래그 종료 시 호출돼요.

Motion Props 지원

MotionDnDGrid.GroupMotionDnDGrid.ItemMotion의 motion 컴포넌트 위에 구축되어 있어서,
모든 motion 관련 props(layout, transition, drag, whileHover 등)를 그대로 사용할 수 있어요.


요약

  • MotionDnDGrid.Group으로 리스트를 감싸고, 내부에 MotionDnDGrid.Item을 배치하면 드래그 앤 드롭 정렬이 가능해요.
  • onSorted를 통해 변경된 배열을 상위 상태로 전달해요.
  • 스크롤, 터치, 마우스 모두 지원하고, 네이티브 DOM 기반의 충돌 감지로 빠르게 동작해요.
Last updated on