Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:TobikoData Sqlmesh FileExplorer DragLayer

From Leeroopedia


Knowledge Sources
Domains Web_UI, File_Explorer, Drag_and_Drop
Last Updated 2026-02-07 20:00 GMT

Overview

A React component that provides a custom drag preview layer for dragging files and directories in the file explorer.

Description

FileExplorer_DragLayer is a React component that implements a custom drag preview for file and directory drag operations using react-dnd's useDragLayer hook. Instead of using the browser's default drag preview, it creates a fixed-position overlay that follows the mouse cursor with styled previews of the items being dragged. The component handles multi-select dragging, showing all selected items when dragging from a selection, or just the single item when dragging an unselected item.

The drag layer creates visually appealing drag previews with drop shadows and themed backgrounds, displaying the appropriate icons and labels for each file or directory. It tracks the drag state (isDragging, currentOffset, artifact) and automatically shows/hides based on the drag operation. The component integrates with the project context to determine which items are in the active selection range.

Usage

Use this component as a global overlay in the file explorer to provide enhanced drag previews. It should be rendered once at the root level of the file explorer, not within individual draggable items.

Code Reference

Source Location

  • Repository: TobikoData_Sqlmesh
  • File: web/client/src/library/components/fileExplorer/DragLayer.tsx

Signature

export default function DragLayer(): JSX.Element

function getItemStyles(currentOffset: XYCoord | null): React.CSSProperties

Import

import DragLayer from '@components/fileExplorer/DragLayer'

I/O Contract

Inputs

Name Type Required Description
N/A N/A N/A Component reads drag state from react-dnd and project context

Outputs

Name Type Description
JSX.Element JSX.Element The rendered drag preview layer (empty when not dragging)

Drag Layer Hook

The component uses react-dnd's useDragLayer hook:

const { isDragging, currentOffset, artifact } = useDragLayer(monitor => ({
  artifact: monitor.getItem(),
  isDragging: monitor.isDragging(),
  currentOffset: monitor.getSourceClientOffset(),
}))

Monitored Values

Property Type Description
artifact ModelFile or ModelDirectory The item being dragged
isDragging boolean Whether a drag operation is in progress
currentOffset XYCoord or null Current mouse position relative to viewport

Multi-Select Logic

The component determines which items to show:

const artifacts = useMemo(
  () =>
    Array.from(
      inActiveRange(artifact) ? activeRange : new Set([artifact]),
    ).filter(Boolean),
  [activeRange, artifact],
)

Logic:

  • If dragged item is in active selection: Show all items in activeRange
  • Otherwise: Show only the dragged item
  • Filter out null/undefined values

Layer Styles

The drag layer uses fixed positioning:

const layerStyles: CSSProperties = {
  position: 'fixed',
  pointerEvents: 'none',
  zIndex: 100,
  left: 0,
  top: 0,
  width: '100%',
  height: '100%',
}

Style Properties

  • position: fixed: Overlay covers entire viewport
  • pointerEvents: none: Doesn't interfere with drop targets
  • zIndex: 100: Appears above file explorer content
  • Full viewport coverage: 100% width and height

Item Positioning

Each dragged item follows the cursor:

function getItemStyles(currentOffset: XYCoord | null): React.CSSProperties {
  if (currentOffset == null) {
    return {
      display: 'none',
    }
  }

  const { x, y } = currentOffset

  return {
    display: 'inline-block',
    transform: `translate(${x}px, ${y}px)`,
    filter: 'drop-shadow(0 2px 12px rgba(0,0,0,0.45))',
  }
}

Transform Translation

  • Uses CSS transform for smooth, GPU-accelerated movement
  • Directly follows mouse coordinates from react-dnd
  • Hidden when currentOffset is null

Visual Effects

  • Drop shadow: 2px offset, 12px blur, 45% opacity black
  • Rounded corners: Applied via className
  • Themed background: Uses 'bg-theme' class

Rendering Drag Items

Directory Preview

{artifact instanceof ModelDirectory && (
  <FileExplorer.Container
    key={artifact.path}
    artifact={artifact}
    className="bg-theme"
  >
    <Directory.Icons hasChevron={false} />
    <Directory.Display directory={artifact} />
  </FileExplorer.Container>
)}

Features:

  • No chevron icon (hasChevron={false})
  • Shows directory icon and name
  • Wrapped in FileExplorer.Container

File Preview

{artifact instanceof ModelFile && (
  <FileExplorer.Container
    key={artifact.path}
    artifact={artifact}
    className="bg-theme"
  >
    <File.Icons />
    <File.Display file={artifact} />
  </FileExplorer.Container>
)}

Features:

  • Shows file type icon
  • Shows file name
  • Wrapped in FileExplorer.Container

Component Structure

return (
  <>
    {isDragging && (
      <div style={layerStyles}>
        <div
          style={getItemStyles(currentOffset)}
          className="!cursor-grabbing !rounded-lg overflow-hidden"
        >
          {artifacts.map(artifact => (
            <span key={artifact.id}>
              {/* Directory or File preview */}
            </span>
          ))}
        </div>
      </div>
    )}
  </>
)

Conditional Rendering

  • Outer layer only renders when isDragging is true
  • Inner previews map over artifacts array
  • Each artifact keyed by unique ID

Cursor Style

  • cursor-grabbing: Shows closed hand cursor during drag
  • Uses !important override to ensure visibility

Performance Optimization

The component uses useMemo for artifacts calculation:

const artifacts = useMemo(
  () =>
    Array.from(
      inActiveRange(artifact) ? activeRange : new Set([artifact]),
    ).filter(Boolean),
  [activeRange, artifact],
)

This prevents unnecessary recalculation on every render.

Integration Points

The component integrates with:

  • react-dnd: Drag layer monitoring
  • Project context: Active range and selection state
  • FileExplorer.Container: Consistent item styling
  • Directory and File components: Icon and display rendering

Usage Example

import DragLayer from '@components/fileExplorer/DragLayer'
import { DndProvider } from 'react-dnd'
import { HTML5Backend } from 'react-dnd-html5-backend'

function FileExplorerApp() {
  return (
    <DndProvider backend={HTML5Backend}>
      <FileExplorer>
        {/* File tree content */}
      </FileExplorer>

      {/* Drag layer renders at root level */}
      <DragLayer />
    </DndProvider>
  )
}

Styling Classes

Applied classes:

  • !cursor-grabbing: Override cursor to grabbing
  • !rounded-lg: Large border radius (override)
  • overflow-hidden: Clip content to rounded corners
  • bg-theme: Themed background color

The ! prefix forces override of conflicting styles.

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment