ComponentsP3 본문

ReorderList

키보드와 포인터 드래그로 항목 순서를 바꾸는 제어형 리스트 — Alt/Ctrl+화살표, aria-live 공지, lifted drag, live gap, FLIP 스프링 정착을 제공합니다.

마지막 업데이트 2026-07-01

한눈에#

작업 우선순위, 즐겨찾기, 규칙 순서처럼 순서 자체가 데이터인 리스트에 쓰는 재정렬 컴포넌트입니다. 상태는 소비자가 소유하고, onReorder가 다음 items 배열과 이동 정보를 돌려줍니다.

Alt 또는 Ctrl과 위/아래 화살표로 순서를 변경합니다.

  • 긴급 이슈 분류P0 · 오늘
  • 디자인 검수 반영P1 · 내일
  • 릴리즈 노트 정리P2 · 이번 주
  • keyboard-first
  • aria-live
  • live gap
  • FLIP spring

핸들에 포커스한 뒤 Alt/Ctrl + ↑/↓로 이동하거나, 핸들을 드래그해 순서를 바꿉니다

사용 시점#

권장 — 이렇게 쓰세요

지양 — 이러지 마세요

Alt 또는 Ctrl과 위/아래 화살표로 순서를 변경합니다.

  • 긴급 이슈 분류
  • 디자인 검수 반영
  • 릴리즈 노트 정리

쓴다항목의 순서가 저장되는 설정·규칙·작업 목록

대신 Table단순 데이터 표시는 행 재정렬보다 읽기/비교가 중심일 때

대신 DataGrid컬럼 정렬·선택·편집이 중심인 고밀도 표

조작#

Alt 또는 Ctrl과 위/아래 화살표로 순서를 변경합니다.

  • 긴급 이슈 분류P0 · 오늘
  • 디자인 검수 반영P1 · 내일
  • 릴리즈 노트 정리P2 · 이번 주
키보드 · 포인터

핸들은 항목마다 제공되는 아이콘 버튼입니다. 키보드는 Alt 또는 Ctrl + ArrowUp/ArrowDown만 순서 변경으로 처리하므로 일반 화살표 탐색과 충돌하지 않습니다. 포인터 드래그는 같은 onReorder 계약을 사용합니다.

모션#

포인터로 잡은 항목은 raised surface로 살짝 떠오르고, 이동 범위의 형제 항목은 translate3d로 위/아래에 live insertion gap을 엽니다. 긴 목록에서는 포인터가 스크롤 컨테이너 가장자리로 가까워질 때 컨테이너를 조금씩 따라 스크롤하고, 그 스크롤량을 드래그 offset에도 반영해 항목이 포인터에서 미끄러져 보이지 않게 합니다.

순서가 바뀐 뒤 항목은 FLIP(First · Last · Invert · Play) 방식으로 이전 위치에서 새 위치로 정착합니다. 이전/이후 좌표 차이를 translate3d로 되감은 뒤 transform을 해제하므로 레이아웃 속성을 애니메이션하지 않습니다. 정착은 모션 SSOT의 spring.spatial.fast를 쓰고, prefers-reduced-motion: reduce에서는 transition을 끄고 새 순서를 즉시 표시합니다.

속성토큰/값
드래그 lift--wds-shadow-lg + scale(1.015)
live gap형제 항목 translate3d displacement
위치 정착--wds-spring-spatial-fast-duration + --wds-spring-spatial-fast
상태 색--wds-spring-effect-fast-duration + --wds-spring-effect-fast
reduced motiontransition 없음

Props#

Prop타입기본값설명
itemsreadonly T[]Ordered item data. The caller owns state and applies onReorder results.
getId(item: T, index: number) => stringStable item id. Index keys are unsafe because this component reorders.
renderItem(item: T, index: number) => ReactNodeRender item content. The drag handle is provided by ReorderList.
labelstringAccessible list name.
onReorder(change: ReorderListChange<T>) => voidCalled with the next ordered items after keyboard or pointer reorder.
getItemLabel(item: T, index: number) => stringAccessible item label for move announcements. Defaults to the item id.
disabledbooleanfalseDisable every handle.
itemDisabled(item: T, index: number) => booleanDisable individual item handles. Disabled items stay rendered but cannot be dragged.
refRef<HTMLDivElement>Root <div> ref (React 19 ref-as-prop).

접근성#

  • 리스트에는 label로 접근성 이름을 제공합니다
  • 각 핸들은 항목 라벨 기반의 aria-label을 갖습니다
  • 순서 변경 후 role="status" + aria-live="polite"로 새 위치를 공지합니다
  • 드래그만으로만 가능한 동작은 없습니다. 키보드 재정렬이 기본 계약입니다
  • 비활성 항목은 핸들을 disabled 처리해 순서 변경 대상에서 제외합니다