Drag-and-Drop Libraries in the Plane UI: Inside the Pragmatic Drag-and-Drop Implementation
The Plane UI relies on Atlassian’s Pragmatic Drag-and-Drop ecosystem—specifically @atlaskit/pragmatic-drag-and-drop, @atlaskit/pragmatic-drag-and-drop-hitbox, and @atlaskit/pragmatic-drag-and-drop-auto-scroll —to power reordering in Kanban boards, lists, and sidebars.
The makeplane/plane repository manages complex project workflows where users constantly rearrange issues, labels, and project states. Understanding which drag-and-drop libraries in the Plane UI enable these interactions reveals why the interface remains responsive across large datasets. The codebase explicitly avoids heavy abstraction layers in favor of composable, low-level primitives that integrate directly with React refs and effects.
Core Atlassian Pragmatic Drag-and-Drop Packages
Plane’s implementation centers on three specific packages from Atlassian’s ecosystem, each pinned to precise versions in pnpm-workspace.yaml.
@atlaskit/pragmatic-drag-and-drop (Core)
Version 1.7.4 of this library provides the foundational primitives draggable, dropTargetForElements, and monitorForElements. According to the makeplane/plane source code, these functions appear throughout the shared UI package and web application:
- In
packages/ui/src/sortable/draggable.tsx, the code importscombineand element adapters to wrap components with drag behavior. - In
packages/ui/src/sortable/sortable.tsx,monitorForElementstracks drag events across multiple drop targets for complex sort operations. - Components in
apps/web, such asprojects-list-item.tsx, initiate drag operations using thedraggablefunction withgetInitialDatapayloads.
@atlaskit/pragmatic-drag-and-drop-hitbox
This utility library (version 1.1.0) supplies spatial detection logic that determines the closest edge of a drop target. This enables visual feedback—like insertion lines—when reordering items. The packages/ui/src/sortable/draggable.tsx file imports closest-edge helpers, while apps/web/core/components/project-states/state-item.tsx uses attachInstruction and extractInstruction to calculate whether a drop should place an item above, below, or inline with existing elements.
@atlaskit/pragmatic-drag-and-drop-auto-scroll
Listed at version 1.4.0 in the workspace configuration, this optional package automatically scrolls containers when dragged items approach viewport boundaries. You will find it integrated in long list views such as apps/web/core/components/issues/issue-layouts/list/default.tsx and various Kanban boards inside apps/web, improving usability for lengthy workflows without manual scrollbar interaction.
Implementation Patterns in the Codebase
The following snippets demonstrate how these drag-and-drop libraries in the Plane UI are wired into React components using hooks and refs.
Creating a Draggable Element
The draggable function from the element adapter attaches behavior to DOM nodes. As implemented in packages/ui/src/sortable/draggable.tsx:
import { draggable } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
function MyDraggableItem() {
const ref = useRef<HTMLDivElement | null>(null);
useEffect(() => {
const el = ref.current;
if (!el) return;
draggable({
element: el,
getInitialData: () => ({ id: "my-item-id" }),
});
}, []);
return <div ref={ref}>Drag me!</div>;
}
Detecting Drop Edges with Hitbox Utilities
To enable precise reordering, Plane uses the hitbox package to calculate insertion points. The pattern from apps/web/core/components/project-states/state-item.tsx looks like this:
import { dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
import {
attachInstruction,
extractInstruction,
} from "@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item";
function MyDropZone() {
const ref = useRef<HTMLDivElement | null>(null);
useEffect(() => {
const el = ref.current;
if (!el) return;
dropTargetForElements({
element: el,
canDrop: ({ source }) => source.id !== "my-item-id",
getData: ({ input }) => ({
...attachInstruction({ element: el, input }),
}),
onDrop: ({ source, location }) => {
const edge = extractInstruction(location);
console.log("Dropped on edge:", edge);
},
});
}, []);
return <div ref={ref}>Drop here</div>;
}
Enabling Auto-Scroll for Long Lists
For containers with overflow content, Plane registers auto-scroll behavior. This snippet reflects usage in list layouts like apps/web/core/components/issues/issue-layouts/list/default.tsx:
import { autoScrollForElements } from "@atlaskit/pragmatic-drag-and-drop-auto-scroll/element";
useEffect(() => {
const cleanup = autoScrollForElements({
element: scrollContainerRef.current!,
scrollMargin: 30,
});
return cleanup;
}, []);
Critical Source Files
Understanding where these libraries integrate helps when customizing or debugging the drag-and-drop libraries in the Plane UI:
-
packages/ui/src/sortable/draggable.tsx: Core wrapper that combinesdraggableprimitives with hitbox utilities to create reusable sortable items. -
packages/ui/src/sortable/sortable.tsx: Sets up global monitoring viamonitorForElementsto track items moving between different drop targets. -
apps/web/core/components/project-states/state-item.tsx: Concrete example of a drop target implementing edge detection for reordering project states. -
pnpm-workspace.yaml: Declares the exact versions of all three Pragmatic Drag-and-Drop packages (core1.7.4, hitbox1.1.0, auto-scroll1.4.0).
Summary
- Plane builds its drag-and-drop layer on Atlassian Pragmatic Drag-and-Drop, not legacy libraries like
react-beautiful-dnd. - The core library (
@atlaskit/pragmatic-drag-and-drop) provides thedraggableanddropTargetForElementsprimitives used acrosspackages/uiandapps/web. - Hitbox utilities enable precise edge detection for list reordering, implemented in components like
state-item.tsx. - Auto-scroll behavior improves UX for lengthy Kanban boards and issue lists.
- All dependencies are centrally managed in
pnpm-workspace.yamlwith pinned versions for consistency.
Frequently Asked Questions
Why did Plane choose Pragmatic Drag-and-Drop over alternatives like react-beautiful-dnd?
Atlassian’s library offers a lower-level, more composable API that works with modern React patterns while avoiding the bundle size and maintenance issues of larger abstraction libraries. As seen in packages/ui/src/sortable, Plane can mix draggable behaviors with custom hitbox logic rather than fighting a high-level component API.
How does Plane calculate drop positions between list items?
The codebase uses @atlaskit/pragmatic-drag-and-drop-hitbox functions like attachInstruction and extractInstruction to determine the closest edge (top, bottom, left, or right) of a target element. This allows components in apps/web/core/components to show insertion lines and compute final sort indices during the onDrop event.
Does the Plane UI support auto-scrolling during drag operations?
Yes. The apps/web directory shows integration of @atlaskit/pragmatic-drag-and-drop-auto-scroll in list and board layouts. By calling autoScrollForElements on container refs, the UI automatically scrolls when users drag items near viewport edges, eliminating the need for manual scroll handling.
Where are the drag-and-drop library versions defined in the Plane repository?
All versions are declared in the root pnpm-workspace.yaml file. Currently, Plane pins @atlaskit/pragmatic-drag-and-drop at 1.7.4, @atlaskit/pragmatic-drag-and-drop-hitbox at 1.1.0, and @atlaskit/pragmatic-drag-and-drop-auto-scroll at 1.4.0, ensuring consistent behavior across the monorepo's packages and applications.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →