diff --git a/apps/desktop/src/components/dnd/dnd-provider.tsx b/apps/desktop/src/components/dnd/dnd-provider.tsx
index 9b4ec9c7..b38352b7 100644
--- a/apps/desktop/src/components/dnd/dnd-provider.tsx
+++ b/apps/desktop/src/components/dnd/dnd-provider.tsx
@@ -66,6 +66,7 @@ function renderDragOverlay(source: DragOverlaySource) {
)
}
diff --git a/apps/desktop/src/components/dnd/explorer-drag-overlay.test.tsx b/apps/desktop/src/components/dnd/explorer-drag-overlay.test.tsx
index 6cdf6700..0cadefac 100644
--- a/apps/desktop/src/components/dnd/explorer-drag-overlay.test.tsx
+++ b/apps/desktop/src/components/dnd/explorer-drag-overlay.test.tsx
@@ -1,5 +1,8 @@
import { describe, expect, it } from "vitest"
-import { getExplorerDragOverlayName } from "./explorer-drag-overlay"
+import {
+ getExplorerDragOverlayName,
+ getExplorerDragOverlayStyle,
+} from "./explorer-drag-overlay"
describe("getExplorerDragOverlayName", () => {
it("prefers the display name when present", () => {
@@ -21,3 +24,38 @@ describe("getExplorerDragOverlayName", () => {
).toBe("folder")
})
})
+
+describe("getExplorerDragOverlayStyle", () => {
+ it("returns undefined when no source element is available", () => {
+ expect(getExplorerDragOverlayStyle()).toBeUndefined()
+ })
+
+ it("preserves the source row width and padding", () => {
+ const sourceElement = {
+ getBoundingClientRect: () =>
+ ({
+ width: 240,
+ }) as DOMRect,
+ ownerDocument: {
+ defaultView: {
+ getComputedStyle: () => ({
+ boxSizing: "border-box",
+ paddingTop: "2px",
+ paddingRight: "8px",
+ paddingBottom: "2px",
+ paddingLeft: "36px",
+ }),
+ },
+ },
+ } as unknown as Element
+
+ expect(getExplorerDragOverlayStyle(sourceElement)).toEqual({
+ boxSizing: "border-box",
+ paddingTop: "2px",
+ paddingRight: "8px",
+ paddingBottom: "2px",
+ paddingLeft: "36px",
+ width: "240px",
+ })
+ })
+})
diff --git a/apps/desktop/src/components/dnd/explorer-drag-overlay.tsx b/apps/desktop/src/components/dnd/explorer-drag-overlay.tsx
index 04b52ec9..f4c9a06d 100644
--- a/apps/desktop/src/components/dnd/explorer-drag-overlay.tsx
+++ b/apps/desktop/src/components/dnd/explorer-drag-overlay.tsx
@@ -1,19 +1,47 @@
import { cn } from "@mdit/ui/lib/utils"
import { ChevronRight } from "lucide-react"
+import { type CSSProperties, useMemo } from "react"
import type { FileEntryDragData } from "./dnd-types"
type ExplorerDragOverlayProps = {
name: string
isDirectory: boolean
+ sourceElement?: Element | null
}
export function getExplorerDragOverlayName(data: FileEntryDragData): string {
return data.displayName ?? data.name ?? ""
}
+export function getExplorerDragOverlayStyle(
+ sourceElement?: Element | null,
+): CSSProperties | undefined {
+ if (!sourceElement || !("getBoundingClientRect" in sourceElement)) {
+ return undefined
+ }
+
+ const ownerWindow = sourceElement.ownerDocument?.defaultView
+ if (!ownerWindow?.getComputedStyle) {
+ return undefined
+ }
+
+ const rect = sourceElement.getBoundingClientRect()
+ const computedStyle = ownerWindow.getComputedStyle(sourceElement)
+
+ return {
+ boxSizing:
+ (computedStyle.boxSizing as CSSProperties["boxSizing"]) || "border-box",
+ paddingTop: computedStyle.paddingTop,
+ paddingRight: computedStyle.paddingRight,
+ paddingBottom: computedStyle.paddingBottom,
+ paddingLeft: computedStyle.paddingLeft,
+ width: rect.width > 0 ? `${rect.width}px` : undefined,
+ }
+}
+
function getExplorerDragOverlayClassName(isDirectory: boolean) {
return cn(
- "pointer-events-none flex min-w-0 max-w-80 items-center gap-1 rounded-sm bg-transparent px-0 py-0 text-sm text-accent-foreground/95 shadow-none ring-0 outline-none border-0",
+ "pointer-events-none flex min-w-0 max-w-none items-center gap-1 rounded-sm bg-transparent px-0 py-0 text-sm text-accent-foreground/95 shadow-none ring-0 outline-none border-0",
isDirectory ? "pr-2" : "pr-1",
)
}
@@ -21,9 +49,15 @@ function getExplorerDragOverlayClassName(isDirectory: boolean) {
export function ExplorerDragOverlay({
name,
isDirectory,
+ sourceElement,
}: ExplorerDragOverlayProps) {
+ const style = useMemo(
+ () => getExplorerDragOverlayStyle(sourceElement),
+ [sourceElement],
+ )
+
return (
-