Skip to content

Feature: VS Code–style drop guide "compass" (aim-at-cell docking) #1377

Description

@KDONG1224

👋 First, thanks for dockview. We use it as the layout engine for an internal monitoring app (dockable panels — tables, charts, an inspector, a map), and it's been a great base to build on.

As we built on it, we kept wanting a more discoverable and precise way to choose where a dragged panel lands. We added it in our fork and it's worked well for us — so rather than keep it private, we'd like to contribute it back. Below is the idea + our implementation; happy to reshape it to whatever fits the project.

Summary

Add an opt-in compass-style drop guide (like VS Code's editor drag overlay): while dragging a panel, show a fixed cross of cells over the hovered group, and the user aims at a cell to choose the drop direction — instead of relying on the cursor's quadrant.

Demo

Image

Note: in the clip the side panels keep their size (the content area fills the rest). That fixed-size behaviour is a separate proposed feature (LayoutPriority.Fill, see #1378 ) — not a bug and not part of this compass feature.

Motivation

Today the drop position is decided by which quadrant of the target the cursor is in. That's fast but:

  • It's not very discoverable (no visible affordance for where a drop will land).
  • Precise edge/center targeting is fiddly on large groups.

A compass widget makes the available drops explicit and easy to hit. It's a familiar pattern (VS Code, Visual Studio, many IDEs).

Proposed behaviour

  • Opt-in via a new option; default off → existing cursor-quadrant behaviour unchanged (fully backward compatible).
  • When on, dragging over a group shows a centered cross:
    • inner cells (top/bottom/left/right/center) → split/merge that group (same semantics as today's quadrants),
    • optional outer cells (top/bottom/left/right) → dock against the whole layout edge (the root/orthogonal drop).
  • Cells that can't accept the drag are hidden (e.g. a panel from another dockview over a group that doesn't accept it), so the compass only shows where a drop is actually possible.
  • Optional preview of the whole-layout edge target when aiming an outer cell.

Proposed API (open to naming)

dndGuide?: boolean | {
  zones?: Position[];   // restrict which inner cells appear (e.g. ['center'] = reorder-only)
  edges?: boolean;      // include the outer whole-layout-edge cells (default true)
};
// + optional resolver for the edge-dock size:
dndEdgeDockSize?: number | { width?: number; height?: number }
                 | ((position: Position, panelId?: string) => number | undefined);

Implementation status

I have a working implementation in a fork (v7-based), covering:

  • Both DnD backends (HTML5 + pointer) via a single shared widget.
  • Per-cell gating, layout-edge docking + preview, theming via CSS variables.

I'm happy to open a PR. Before I do, a few questions:

  1. Is this a direction you'd accept into core, or would you prefer it as a separate module / example?
  2. Naming/shape of the option (dndGuide?), and whether the whole-layout-edge ("outer") cells belong in the same feature or a follow-up.
  3. Any constraints on adding new SVG glyphs vs CSS-only cells.

I can also split out a small related core bug fix I found while building this: tree-restructuring helpers in gridview (cloneNode / flipNode / removeView's branch-spread path) don't preserve a child view's hidden (setVisible(false)) state, so a hidden group can reappear after a layout restructure. Happy to file that separately with a repro.

Metadata

Metadata

Assignees

No one assigned

    Labels

    improvementImprovement or new feature requesttriagedProcessed by the triage agent

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions