> ## Documentation Index
> Fetch the complete documentation index at: https://dndkit.com/llms.txt
> Use this file to discover all available pages before exploring further.

# useSortable

> Use the `useSortable` hook to reorder elements in a list or across multiple lists.

export const sortableStyles = `
body {
  padding: 1em;
  font-size: 20px;
  font-family: system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  line-height: 1.5;
}

.list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  padding: 0;
  margin: 0;
  list-style: none;
}

.item {
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  padding: 10px 20px;
  border: none;
  gap: 10px;
  background-color: rgb(255, 255, 255);
  border-radius: 6px;
  font-size: 14px !important;
  color: #555;
  outline: none;
  min-height: 50px;
  box-shadow: inset 0 0 1px rgba(0,0,0,0.4), 0 0 0 1px rgba(63, 63, 68, 0.05), 0 1px 2px 0 rgba(34, 33, 81, 0.05);
  font-family: var(--font-family);
  width: calc(25% - 10px);
  min-width: 150px;
  max-width: 300px;
  white-space: nowrap;
  transition: transform 0.3s ease, box-shadow 0.3s ease;
  cursor: grab;
}

.item[aria-grabbed="true"] {
  transform: scale(1.025);
  box-shadow: inset 0px 0px 1px rgba(0,0,0,0.5), -1px 0 15px 0 rgba(34, 33, 81, 0.01), 0px 15px 15px 0 rgba(34, 33, 81, 0.25)
}
`.trim();

export const CodeSandbox = ({files, height, hero, previewHeight, showTabs, template}) => {
  const [Editor, setEditor] = useState(null);
  useEffect(() => {
    import('@components/CodeSandbox').then(mod => {
      setEditor(() => mod.CodeSandbox);
    });
  }, []);
  if (!Editor) return null;
  return <div className={`not-prose${hero ? ' hero' : ''}`} style={previewHeight ? {
    '--preview-height': `${previewHeight}px`
  } : undefined}>
      <Editor files={files} height={height} showTabs={showTabs} template={template} />
    </div>;
};

export const Story = ({id, framework = "react", width = "100%", height = "250", hero = false}) => {
  const BRANCH = 'experimental';
  const STORYBOOKS = {
    react: {
      localPort: 6006,
      productionHost: '5fc05e08a4a65d0021ae0bf2'
    },
    vue: {
      localPort: 6008,
      productionHost: '6989440ed560d70abcd6bcc7'
    },
    vanilla: {
      localPort: 6007,
      productionHost: '69892d294eb9040f0d29aa81'
    },
    solid: {
      localPort: 6009,
      productionHost: '698944444eb9040f0d2a0217'
    },
    svelte: {
      localPort: 6010,
      productionHost: '69910d2a631cb57638616dcd'
    }
  };
  const config = STORYBOOKS[framework] ?? STORYBOOKS.react;
  const isDev = import.meta.env.DEV;
  const host = isDev ? `//localhost:${config.localPort}` : `https://${BRANCH}--${config.productionHost}.chromatic.com`;
  return <Frame>
      <iframe src={`${host}/iframe.html?args=&id=${id}&viewMode=story&hero=${hero}`} width={width} height={height} />
    </Frame>;
};

<Story id="react-sortable--example" height="320" hero />

## Usage

The `useSortable` hook requires an `id` and an `index`. It accepts all the same options as the `Sortable` class. Refer to the [Input](#input) section below for more information.

export const code = `
import {useSortable} from '@dnd-kit/react/sortable';

function Sortable({id, index}) {
  const {ref} = useSortable({id, index});

  return (
    <li ref={ref} className="item">Item {id}</li>
  );
}

export default function App() {
  const items = [1, 2, 3, 4];

  return (
    <ul className="list">
      {items.map((id, index) =>
        <Sortable key={id} id={id} index={index} />
      )}
    </ul>
  );
}
`.trim();

<CodeSandbox
  files={{
'App.js': {code, active: true},
'styles.css': {code: sortableStyles, hidden: true},
}}
  height={455}
  previewHeight={180}
/>

## API Reference

<Note>
  The `useSortable` hook is a thin wrapper around the [Sortable](/concepts/sortable) class that makes it easier to create sortable elements in React. It therefore accepts all of the same input arguments.
</Note>

### Input

The `useSortable` hook accepts all of the same arguments as the [useDraggable](/react/hooks/use-draggable) hook and [useDroppable](/react/hooks/use-droppable) hooks, as well as additional arguments that are specific to sortable elements.

<ParamField path="id" type="string | number" required>
  The identifier of the sortable element. Should be unique within the same [drag and drop context provider](/react/components/drag-drop-provider).
</ParamField>

<ParamField path="index" type="number" required>
  The index of the sortable element. This is used to determine the position of the element in the list.
</ParamField>

<ParamField path="transition" type="{duration?: number; easing?: string: idle: boolean} | null">
  Optionally supply a transition to animate the sortable element when it is being sorted.

  <Expandable>
    <ParamField path="duration" type="number">
      The duration of the transition in milliseconds.
    </ParamField>

    <ParamField path="easing" type="string">
      The easing function to use for the transition.
    </ParamField>

    <ParamField path="idle" type="boolean">
      Whether the sortable item should transition to its new position when its index changes, but there is no drag operation in progress.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField path="element" type="Element | Ref<Element>">
  If you already have a reference to the element, you can pass it to the `element` option instead of using the `ref` that is returned by the `useSortable` hook to connect the sortable element.
</ParamField>

<ParamField path="handle" type="Element | Ref<Element>">
  If you already have a reference to the drag handle element, you can pass it to the `handle` option instead of using the `handleRef` that is returned by the `useSortable` hook to connect the sortable handle element.
</ParamField>

<ParamField path="modifiers" type="Modifier[]">
  An array of [modifiers](/extend/modifiers) that can be used to modify or restrict the behavior of the sortable element.
</ParamField>

<ParamField path="sensors" type="Sensors[]">
  An array of [sensors](/extend/sensors) that can be bound to the sortable element to detect drag interactions.
</ParamField>

<ParamField path="target" type="Element | Ref<Element>">
  If you already have a reference to the element you want to use as the droppable target for this sortable element, you can pass it to the `target` option instead of using the `targetRef` that is returned by the `useSortable` hook.
</ParamField>

<ParamField path="accept" type="Type | Type[] | ((source: Draggable) => boolean)">
  Restrict which draggables can be dropped on this sortable item. Pass a single [`type`](#param-type), an array of types, or a predicate that receives the draggable and returns `true` to accept it. If omitted, every draggable is accepted.
</ParamField>

<ParamField path="type" type="string | number | Symbol">
  An identifier for this item that other sortables' or droppables' `accept` rules check when **this item is dragged** — it determines where this item can be dropped. Whether this item can act as a drop target for other draggables is governed by its own [`accept`](#param-accept) rule.
</ParamField>

<ParamField path="group" type="string | number | Symbol">
  An optional identifier for grouping sortable items. Items with the same `group` can be sorted within the same list — useful for [multi-list sortable layouts](/react/guides/multiple-sortable-lists). Items without a `group` are treated as belonging to the same implicit group.
</ParamField>

<ParamField path="collisionDetector" type="(input: CollisionDetectorInput) => Collision | null">
  Optionally supply a [collision detector](/concepts/droppable#detecting-collisions) function can be used to detect collisions between the droppable element and draggable elements.
</ParamField>

<ParamField path="collisionPriority" type="number">
  Optionally supply a number to set the collision priority of the droppable target of this sortable element. The higher the number, the higher the priority when detecting collisions. This can be useful if there are multiple droppable elements that overlap.
</ParamField>

<ParamField path="disabled" type="boolean | {draggable?: boolean; droppable?: boolean}">
  Set to `true` to prevent the sortable element from being dragged or used as a drop target. Pass an object to disable dragging and dropping independently:

  ```ts theme={null}
  // Disable dragging only — other items can still be dropped on this one
  disabled: {draggable: true}

  // Disable dropping only — this item can still be dragged
  disabled: {droppable: true}
  ```
</ParamField>

<ParamField path="plugins" type="PluginDescriptor[]">
  An array of plugin descriptors for per-entity plugin configuration. Use `Plugin.configure()` to create descriptors. For example, `Feedback.configure({ feedback: 'clone' })`.
</ParamField>

<ParamField path="data" type="{[key: string]: any}">
  The data argument is for advanced use-cases where you may need access to additional data about the sortable element in event handlers, modifiers, sensors or custom plugins.
</ParamField>

<ParamField path="effects" type="() => Effect[]">
  <Info>This is an advanced feature and should not need to be used by most consumers.</Info>
  You can supply a function that returns an array of reactive effects that can be set up and automatically cleaned up when the component invoking the `useSortable` hook element is unmounted.
</ParamField>

### Output

The `useSortable` hook returns an object containing the following properties:

<ParamField path="ref" type="Ref<Element>">
  A React ref that can be assigned to the element you want to connect as the draggable element and droppable target for this sortable instance.
</ParamField>

<ParamField path="targetRef" type="Ref<Element>">
  A React ref that can be assigned to the element you want to use as the droppable target for this sortable element.
</ParamField>

<ParamField path="sourceRef" type="Ref<Element>">
  A React ref that can be assigned to the element you want to use as the draggable source element for this sortable element.
</ParamField>

<ParamField path="handleRef" type="Ref<Element>">
  A React ref that can be assigned to the element you want to use as the drag handle element for this sortable element.
</ParamField>

<ParamField path="isDropTarget" type="boolean">
  A boolean value that indicates whether the sortable element is currently a drop target.
</ParamField>

<ParamField path="isDragSource" type="boolean">
  A boolean value that indicates whether the sortable is the source of the drag operation that is in progress.
</ParamField>

<ResponseField name="isDragging" type="boolean">
  A boolean value that indicates whether the sortable is currently being dragged.
</ResponseField>

<ResponseField name="isDropping" type="boolean">
  A boolean value that indicates whether the sortable is being dropped. This can be used to style the sortable element differently during the drop animation.
</ResponseField>
