Motion
Back to framer.com
DocumentationComponents
Reorder
Motion
Back to framer.com
Design and publish your first free site today.
Getting started
  • Introduction
  • Examples
Animation
  • Overview
  • Layout
  • Gestures
  • Scroll
  • Transition
Components
  • motion
  • AnimatePresence
  • LayoutGroup
  • LazyMotion
  • MotionConfig
  • Reorder
Motion values
  • Overview
  • useMotionValueEvent
  • useMotionTemplate
  • useScroll
  • useSpring
  • useTime
  • useTransform
  • useVelocity
  • useWillChange
Utilities
  • animate
  • transform
  • useAnimationControls
  • useAnimationFrame
  • useDragControls
  • useInView
  • useReducedMotion
3D
  • Introduction
  • LayoutCamera
  • LayoutOrthographicCamera
  • MotionCanvas
Guides
  • Accessibility
  • Reduce bundle size
  • Upgrade guides
Community
  • GitHub
  • Discord

Reorder

Create drag-to-reorder effects with a simple set of components.

The Reorder components can be used to create drag-to-reorder lists, like reorderable tabs or todo items.

import { Reorder } from "framer-motion"
import { useState } from "react"
function List() {
const [items, setItems] = useState([0, 1, 2, 3])
return (
<Reorder.Group axis="y" values={items} onReorder={setItems}>
{items.map((item) => (
<Reorder.Item key={item} value={item}>
{item}
</Reorder.Item>
))}
</Reorder.Group>
)
}

#Usage

Every reorderable list is wrapped in the Reorder.Group component.

import { Reorder } from "framer-motion"
function List() {
return (
<Reorder.Group>
</Reorder.Group>
)
}

By default, this is rendered as a <ul>, but this can be changed with the as prop.

<Reorder.Group as="ol">

Reorder.Group must be passed the array of values in your reorderable list via the values prop.

Additionally, a onReorder event will fire with the latest calculated order. For items to reorder, this must update the values state.

import { Reorder } from "framer-motion"
function List() {
const [items, setItems] = useState([0, 1, 2, 3])
return (
<Reorder.Group values={items} onReorder={setItems}>
</Reorder.Group>
)
}

To render each reorderable item, use Reorder.Item, passing it the value it represents via the value prop.

import { Reorder } from "framer-motion"
function List() {
const [items, setItems] = useState([0, 1, 2, 3])
return (
<Reorder.Group values={items} onReorder={setItems}>
{items.map(item => (
<Reorder.Item key={item} value={item}>
{item}
</Reorder.Item>
))}
</Reorder.Group>
)
}

Now, when items are dragged, onReorder will fire with a new order.

#Layout animations

Reorder.Item components are already configured to perform layout animations, so if new items are added or removed to the reorderable list, surrounding items will animate to their new position automatically.

#Exit animations

AnimatePresence can be used as normal to animate items as they enter/leave the React tree.

<AnimatePresence>
{items.map(item => (
<Reorder.Item
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
key={item}
/>
))
</AnimatePresence>

#Drag triggers

By default, all of a Reorder.Item will be draggable. useDragControls can be used to define a different component to act as a drag trigger

import { Reorder, useDragControls } from "framer-motion"
function Item({ value }) {
const controls = useDragControls()
return (
<Reorder.Item
value={value}
dragListener={false}
dragControls={controls}
>
<div
className="reorder-handle"
onPointerDown={(e) => controls.start(e)}
/>
</Reorder.Item>
)
}

#Scrollable lists

If Reorder.Item components are within a scrollable container, that container needs a layoutScroll prop so Framer Motion can correctly measure its scroll offset.

In this example, the scrollable container is the Reorder.Group:

<Reorder.Group
axis="y"
onReorder={setItems}
layoutScroll
style={{ overflowY: "scroll" }}
>
{items.map((item) => (
<Item key={item} item={item} />
))}
</Reorder.Group>

If the scrollable container is a normal HTML component it'll need to be converted to a motion component with layoutScroll.

#Reorder.Group props

#as: string

The underlying component for Reorder.Group to render.

Currently, this only accepts the name of a HTML element, but in the future will accept any HTML-rendering React component.

Defaults to "ul"

#axis: "x" | "y"

Required

The direction of reorder detection.

By default, all Reorder.Item components will be draggable only on this axis. To allow dragging on both axes, pass the drag prop to child Reorder.Item components.

#values: any[]

Required

The values array used as the source for the rendered Reorder.Item components.

#onReorder(newOrder): void

Required

A callback that will fire when items are detected to have reordered. The provided newOrder should be passed to a values state update function.

#Reorder.Item props

Reorder.Item components accept all motion component props in addition to the following:

#as: string

The underlying component for Reorder.Item to render.

Currently, this only accepts the name of a HTML element, but in the future will accept any HTML-rendering React component.

Defaults to "li"

#value: any

Required

When onReorder is called, this is the value that will be passed through in the newly ordered array.

PreviousMotionConfigNextMotion values overview
On this page
  • Usage
  • Layout animations
  • Exit animations
  • Drag triggers
  • Scrollable lists
  • Reorder.Group props
  • Reorder.Item props

Copyright © 2022 Framer B.V.

  • Security
  • Terms of Service
  • Privacy Statement