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

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions