diff --git a/packages/editor/src/core/extensions/drag-and-drop/drag-handle-extension.ts b/packages/editor/src/core/extensions/drag-and-drop/drag-handle-extension.ts
new file mode 100644
index 00000000000..7cb427b717b
--- /dev/null
+++ b/packages/editor/src/core/extensions/drag-and-drop/drag-handle-extension.ts
@@ -0,0 +1,9 @@
+import { Extension } from "@tiptap/core";
+import { DragHandlePlugin } from "./drag-handle-plugin";
+
+export const DragAndDrop = Extension.create({
+  name: "DragAndDrop",
+  addProseMirrorPlugins() {
+    return [DragHandlePlugin()];
+  },
+});
diff --git a/packages/editor/src/core/extensions/drag-and-drop/drag-handle-plugin.tsx b/packages/editor/src/core/extensions/drag-and-drop/drag-handle-plugin.tsx
new file mode 100644
index 00000000000..6d45c553d1e
--- /dev/null
+++ b/packages/editor/src/core/extensions/drag-and-drop/drag-handle-plugin.tsx
@@ -0,0 +1,304 @@
+import { createRoot } from "react-dom/client";
+
+import { NodeType, ResolvedPos } from "@tiptap/pm/model";
+import { EditorState, NodeSelection, Plugin, PluginKey, TextSelection, Transaction } from "@tiptap/pm/state";
+import { Decoration, DecorationSet, EditorView } from "@tiptap/pm/view";
+import { findParentNodeOfTypeClosestToPos } from "prosemirror-utils";
+// ui
+import { DragHandle } from "@plane/ui";
+
+const PLUGIN_CONFIG = {
+  KEY: new PluginKey("dragHandlePlugin"),
+  SCROLL: {
+    UP_THRESHOLD: 200,
+    DOWN_THRESHOLD: 100,
+    MIN_SPEED: 1,
+    MAX_SPEED: 20,
+    BEHAVIOR: "auto" as const,
+  },
+  ALLOWED_NODE_TYPES: ["paragraph", "listItem", "table", "codeBlock", "blockquote", "image", "imageComponent"],
+} as const;
+
+interface ScrollableContainer extends HTMLElement {
+  scrollBy(options: ScrollToOptions): void;
+  scrollBy(x: number, y: number): void;
+}
+
+const DOMHelpers = {
+  isScrollable: (element: HTMLElement | SVGElement): boolean => {
+    if (!(element instanceof HTMLElement || element instanceof SVGElement)) return false;
+    const style = getComputedStyle(element);
+    return ["overflow", "overflow-y"].some((property) => ["auto", "scroll"].includes(style.getPropertyValue(property)));
+  },
+
+  findScrollableParent: (element: HTMLElement | SVGElement): ScrollableContainer => {
+    let parent = element.parentElement;
+    while (parent) {
+      if (DOMHelpers.isScrollable(parent)) return parent as ScrollableContainer;
+      parent = parent.parentElement;
+    }
+    return (document.scrollingElement || document.documentElement) as ScrollableContainer;
+  },
+};
+
+const SelectionHandler = {
+  selectTextBlock: (position: number, view: EditorView) => {
+    const docSize = view.state.doc.content.size;
+    const validPosition = Math.max(0, Math.min(position, docSize - 1));
+    const node = view.state.doc.nodeAt(validPosition);
+
+    const endPosition =
+      validPosition +
+      (node?.type.name === "codeBlock" ? node.nodeSize : view.state.doc.resolve(validPosition).parent.nodeSize - 1);
+
+    view.dispatch(view.state.tr.setSelection(TextSelection.create(view.state.doc, validPosition, endPosition)));
+  },
+
+  findClosestParentNode: (position: ResolvedPos, nodeTypes: NodeType[]) => {
+    const parents = nodeTypes
+      .map((type) => {
+        const parent = findParentNodeOfTypeClosestToPos(position, type);
+        return parent && { position: parent.pos, node: parent.node };
+      })
+      .filter(Boolean);
+
+    return parents[0];
+  },
+};
+
+// Scroll Handler Class
+class ScrollHandler {
+  private isDragging = false;
+  private lastClientY = 0;
+  private animationFrame: number | null = null;
+
+  constructor(private readonly handleElement: HTMLElement) {}
+
+  startDragging(clientY: number) {
+    this.isDragging = true;
+    this.lastClientY = clientY;
+    this.scroll();
+  }
+
+  stopDragging() {
+    this.isDragging = false;
+    if (this.animationFrame) {
+      cancelAnimationFrame(this.animationFrame);
+      this.animationFrame = null;
+    }
+  }
+
+  updatePosition(clientY: number) {
+    if (this.isDragging) {
+      this.lastClientY = clientY;
+    }
+  }
+
+  private scroll() {
+    if (!this.isDragging) return;
+
+    const scrollableParent = DOMHelpers.findScrollableParent(this.handleElement);
+    if (!scrollableParent) return;
+
+    const scrollAmount = this.calculateScrollAmount();
+
+    if (scrollAmount !== 0) {
+      scrollableParent.scrollBy({
+        top: scrollAmount,
+        behavior: PLUGIN_CONFIG.SCROLL.BEHAVIOR,
+      });
+    }
+
+    this.animationFrame = requestAnimationFrame(() => this.scroll());
+  }
+
+  private calculateScrollAmount(): number {
+    const scrollRegionUp = PLUGIN_CONFIG.SCROLL.UP_THRESHOLD;
+    const scrollRegionDown = window.innerHeight - PLUGIN_CONFIG.SCROLL.DOWN_THRESHOLD;
+
+    if (this.lastClientY < scrollRegionUp) {
+      const ratio = (scrollRegionUp - this.lastClientY) / PLUGIN_CONFIG.SCROLL.UP_THRESHOLD;
+      const easedRatio = Math.pow(ratio, 3);
+      return -1 * this.calculateDynamicSpeed(easedRatio);
+    }
+
+    if (this.lastClientY > scrollRegionDown) {
+      const ratio = (this.lastClientY - scrollRegionDown) / PLUGIN_CONFIG.SCROLL.DOWN_THRESHOLD;
+      const easedRatio = Math.pow(ratio, 3);
+      return this.calculateDynamicSpeed(easedRatio);
+    }
+
+    return 0;
+  }
+
+  private calculateDynamicSpeed(easedRatio: number): number {
+    const baseSpeed =
+      PLUGIN_CONFIG.SCROLL.MIN_SPEED + (PLUGIN_CONFIG.SCROLL.MAX_SPEED - PLUGIN_CONFIG.SCROLL.MIN_SPEED) * easedRatio;
+    return Math.sign(baseSpeed) * Math.pow(Math.abs(baseSpeed), 1.5);
+  }
+}
+
+// Main Plugin Factory
+function createDragHandlePlugin(isBlock = false, onMouseDown?: () => void, onMouseUp?: () => void) {
+  let dragHandleElement: HTMLElement | null = null;
+  let scrollHandler: ScrollHandler;
+  let currentCleanup: (() => void) | null = null;
+
+  const createDragHandle = (view: EditorView, getPosition: () => number) => {
+    // Clean up previous instance if it exists
+    if (currentCleanup) {
+      currentCleanup();
+      currentCleanup = null;
+    }
+
+    if (!dragHandleElement) {
+      dragHandleElement = document.createElement("div");
+      dragHandleElement.contentEditable = "false";
+
+      const root = createRoot(dragHandleElement);
+      root.render(<DragHandle className="absolute drag-handle-container" />);
+    }
+
+    scrollHandler = new ScrollHandler(dragHandleElement);
+
+    const handleMouseDown = (event: MouseEvent) => {
+      event.stopPropagation();
+      scrollHandler.startDragging(event.clientY);
+      onMouseDown?.();
+
+      const currentPosition = getPosition();
+      const { tr } = view.state;
+      tr.setSelection(NodeSelection.create(tr.doc, currentPosition - (isBlock ? 0 : 1)));
+      view.dispatch(tr);
+    };
+
+    const handleDragOver = (event: DragEvent) => {
+      event.preventDefault();
+      scrollHandler.updatePosition(event.clientY);
+    };
+
+    const cleanupDragHandle = () => {
+      scrollHandler.stopDragging();
+      onMouseUp?.();
+
+      if (view.dragging) {
+        SelectionHandler.selectTextBlock(getPosition(), view);
+      }
+    };
+
+    // Clean up old event listeners
+    const cleanup = () => {
+      dragHandleElement?.removeEventListener("mousedown", handleMouseDown);
+      document.removeEventListener("mouseup", cleanupDragHandle);
+      document.removeEventListener("drop", cleanupDragHandle);
+      document.removeEventListener("mouseenter", cleanupDragHandle);
+      document.removeEventListener("dragover", handleDragOver);
+      scrollHandler?.stopDragging();
+    };
+
+    // Add new event listeners
+    dragHandleElement.addEventListener("mousedown", handleMouseDown);
+    document.addEventListener("mouseup", cleanupDragHandle);
+    document.addEventListener("drop", cleanupDragHandle);
+    document.addEventListener("mouseenter", cleanupDragHandle);
+    document.addEventListener("dragover", handleDragOver);
+
+    currentCleanup = cleanup;
+
+    return dragHandleElement;
+  };
+
+  return createDragHandle;
+}
+
+function handleMouseMoveEvent(view: EditorView, event: MouseEvent) {
+  const position = view.posAtCoords({
+    left: event.clientX,
+    top: event.clientY,
+  });
+
+  if (!position) return;
+
+  const resolvedPos = view.state.doc.resolve(Math.min(position.inside + 1, view.state.doc.content.size - 1));
+  const allowedNodeTypes = PLUGIN_CONFIG.ALLOWED_NODE_TYPES.map((name) => view.state.schema.nodes[name]);
+
+  const closestParent = SelectionHandler.findClosestParentNode(resolvedPos, allowedNodeTypes);
+  const textBlockParent = resolvedPos.node(1);
+  const { tr } = view.state;
+  const { handlePos } = PLUGIN_CONFIG.KEY.getState(view.state);
+
+  if (position.inside === -1) return;
+
+  if (!textBlockParent || !closestParent?.node || handlePos === position.inside) {
+    if (handlePos !== position.inside && handlePos !== null) {
+      tr.setMeta("handle", "removeHandle");
+      view.dispatch(tr);
+    }
+    return;
+  }
+
+  const handleDecoration = Decoration.widget(position.inside + 1, createDragHandlePlugin(), {
+    containerId: textBlockParent.attrs.componentId,
+    pos: position.inside,
+    side: -1,
+  });
+
+  const decorationSet = DecorationSet.empty.add(view.state.doc, [handleDecoration]);
+
+  tr.setMeta("handle", {
+    set: decorationSet,
+    handlePos: position.inside,
+  });
+  view.dispatch(tr);
+}
+
+export const DragHandlePlugin = () =>
+  new Plugin({
+    key: PLUGIN_CONFIG.KEY,
+    state: {
+      init() {
+        return {
+          set: DecorationSet.empty,
+          handlePos: null,
+        };
+      },
+      apply(tr: Transaction, value) {
+        const pluginState = tr.getMeta("handle");
+
+        if (pluginState === "removeHandle" || !pluginState) {
+          if (tr.selection instanceof NodeSelection && value.handlePos && tr.getMeta("uiEvent") !== "drop") {
+            return value;
+          }
+          return {
+            set: DecorationSet.empty,
+            handlePos: null,
+          };
+        }
+
+        return {
+          set: pluginState.set,
+          handlePos: pluginState.handlePos,
+        };
+      },
+    },
+    props: {
+      decorations(state: EditorState) {
+        return this.getState(state).set;
+      },
+      handleDOMEvents: {
+        mousemove(view: EditorView, event: MouseEvent): boolean {
+          event.preventDefault();
+          if (!view.dragging) handleMouseMoveEvent(view, event);
+          return false;
+        },
+        mouseleave(view: EditorView, event: MouseEvent): boolean {
+          if ((event.target as Element).closest(".editor-container") === view.dom.closest(".editor-container")) {
+            const { tr } = view.state;
+            tr.setMeta("handle", "removeHandle");
+            view.dispatch(tr);
+          }
+          return false;
+        },
+      },
+    },
+  });
diff --git a/packages/editor/src/core/extensions/extensions.tsx b/packages/editor/src/core/extensions/extensions.tsx
index b8910a56c37..c3e2a92016d 100644
--- a/packages/editor/src/core/extensions/extensions.tsx
+++ b/packages/editor/src/core/extensions/extensions.tsx
@@ -36,6 +36,7 @@ import { isValidHttpUrl } from "@/helpers/common";
 import { IMentionHighlight, IMentionSuggestion, TExtensions, TFileHandler } from "@/types";
 // plane editor extensions
 import { CoreEditorAdditionalExtensions } from "@/plane-editor/extensions";
+import { DragAndDrop } from "./drag-and-drop/drag-handle-extension";
 
 type TArguments = {
   disabledExtensions: TExtensions[];
@@ -169,5 +170,6 @@ export const CoreEditorExtensions = (args: TArguments): Extensions => {
     ...CoreEditorAdditionalExtensions({
       disabledExtensions,
     }),
+    DragAndDrop,
   ];
 };
diff --git a/packages/editor/src/core/hooks/use-collaborative-editor.ts b/packages/editor/src/core/hooks/use-collaborative-editor.ts
index b3c7d6cfc2e..00a652e5619 100644
--- a/packages/editor/src/core/hooks/use-collaborative-editor.ts
+++ b/packages/editor/src/core/hooks/use-collaborative-editor.ts
@@ -80,10 +80,10 @@ export const useCollaborativeEditor = (props: TCollaborativeEditorProps) => {
     editorClassName,
     enableHistory: false,
     extensions: [
-      SideMenuExtension({
-        aiEnabled: !disabledExtensions?.includes("ai"),
-        dragDropEnabled: true,
-      }),
+      // SideMenuExtension({
+      //   aiEnabled: !disabledExtensions?.includes("ai"),
+      //   dragDropEnabled: true,
+      // }),
       HeadingListExtension,
       Collaboration.configure({
         document: provider.document,
diff --git a/packages/editor/src/index.ts b/packages/editor/src/index.ts
index ed7d9134698..ab6a04002a3 100644
--- a/packages/editor/src/index.ts
+++ b/packages/editor/src/index.ts
@@ -1,5 +1,4 @@
 // styles
-// import "./styles/tailwind.css";
 import "./styles/variables.css";
 import "./styles/editor.css";
 import "./styles/table.css";