LearnNewsExamplesServices
Frontmatter
id17870
titleSplit previews paint the resulting region, not just the insertion line
stateClosed
labels
enhancementdesignai
assigneesneo-fable
createdAtAug 30, 2026, 12:24 AM
updatedAtAug 30, 2026, 8:43 AM
githubUrlhttps://github.com/neomjs/neo/issues/17870
authorneo-fable
commentsCount1
parentIssue13158
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtAug 30, 2026, 8:43 AM

Split previews paint the resulting region, not just the insertion line

Closed v13.2.0/archive-v13-2-0-chunk-17 enhancementdesignai
neo-fable
neo-fable commented on Aug 30, 2026, 12:24 AM

Context

Operator comparison study (2026-08-30): webdock — a compact dock prototype (~4.5k LOC) built by a single Opus 5 agent in under two hours — feels like it offers "more drop spots" and a smarter drag UX (light-blue regions instead of hunting icons). Both codebases were read and the engine was probed live before this ticket; the finding is sharper than the premise.

Live latest-open sweep: checked latest 15 open issues at 2026-08-30T00:20Z; no equivalent found. A2A claim sweep over the herd window: no competing claim (Euclid's PR #17869 owns #17865 — disjoint surface).

The Problem

The hit models are already equivalent. Probed with a held synthetic gesture on the workstation at merged dev:

  • Our PreviewProducer#resolvePlacementKind IS webdock's zoneOf: nearest-edge bands (edgeBandRatio: 0.24 vs their EDGE_FRACTION = 0.25), tab-into center, the tab-header carve-out, indicator override on top, release-truth commit through the same payload path — one producer feeds preview AND commit in both codebases. A drop 25px inside a pane body (no icon anywhere near) commits the inferred split today; region drops are not missing.
  • At a pane center, our preview already paints the full-zone translucent fill (rgba(94, 234, 212, 0.2) at the probed 414×543 zone) — exactly webdock's region language.

The one real gap is the split-placement preview geometry. In the edge bands, our affordance collapses to a 6px solid insertion line at the zone edge (measured live: w: 6, h: 543) — the "green bars" of the report — while webdock's edgePreview() paints the half-pane region the new pane would occupy (width * 0.5 along the direction). A thin line at the far edge of a pane is easy to miss and reads as "only the icons are interactive"; a half-pane fill is unmistakable and shows the outcome, not the cut. The perceived "must hit the icons exactly" is an affordance-legibility problem, not a hit-model problem — users gravitate to the icons because the icons are the only legible target, even though every pane pixel already works.

Secondary gap — root-edge reachability: webdock resolves the container's outer edges as hover bands (containerEdgeSize px along the full border) in addition to its edge markers; our root edges are reachable only through the 26px chips (chipSize). A band along the whole container border is a dramatically larger Fitts target for "dock across the full surface".

Also observed (not this ticket's scope): examples/dashboard/dock composes no affordance tier at all — a held drag over it paints nothing (no preview element, no indicators) while the drop still commits via inference. Silent-but-working; whether the minimal example should stay minimal is a separate call.

The Architectural Reality

  • src/dashboard/dock/interaction/Preview.mjs — the renderer that maps a dockPreview.v1 placement onto the affordance rect; the split/edge kinds currently resolve to the insertion-line geometry.
  • src/dashboard/dock/interaction/PreviewProducer.mjs — placement vocabulary (split-before/after, edge-*, tab-into); produce() is the pointer-inference tier; root chips come from produceCandidates only (no root band inference).
  • resources/scss/src/dashboard/Container.scss — the --dock-preview-*/accept tokens; the region fill exists for tab-into and needs a split-region sibling.
  • webdock reference points (read in full): src/interaction/drop-resolver.js (zoneOf, containerEdge, edgePreview), src/interaction/drop-overlay.js (wd-drop-preview region + active-dot highlight).

The Fix

  1. Region previews for split placements (the adoption): the Preview renderer maps split-before/after and edge-* to the RESULT region — the half of the target zone (or root) the new pane would occupy along the placement axis — painted with the translucent fill, keeping the current insertion line as the region's leading-edge accent (region communicates the outcome; the line still marks the exact cut). Tokenized fill/line so themes tune both.
  2. Optionality: a reactive config on the Preview renderer (proposed: resultRegionPreviews_: true) with the current line-only presentation as the false branch — the operator floated the knob, and the pre-region look stays one config away. Default ON: at the pane center we already paint regions, so region-for-splits is consistency, not a new mode.
  3. Root-edge band inference (the secondary adoption): produce() gains the container-edge fall-through — a pointer within a band (proposed: the chip inset geometry generalized, e.g. 24px) of the root rect's border resolves the edge-* root placement even between chips, mirroring webdock's containerEdge tier order (after indicator override, before zone inference at the border strip).
  4. Witnesses: unit tier for the renderer's kind→rect mapping and the root-band inference (mutation-checked); the rendered component tier extends the live-preview spec with one region-visibility case (affordance rect ≈ half-zone for a band hover).

Acceptance Criteria

  • Hovering a pane's edge band (no indicator) paints the half-zone result region with the insertion line as its leading edge; the pane center keeps the full-zone fill.
  • resultRegionPreviews: false restores the line-only presentation (both states witnessed).
  • Hovering within the root-edge band between chips resolves and previews the root edge-* placement; the chips continue to work unchanged.
  • No commit-semantics change: previewToOperation payloads are byte-identical for every placement kind (the change is presentation + one added inference tier, witnessed by unchanged unit expectations on produced payloads).
  • Tokens documented in the theme block; the workstation renders sanely with engine defaults. The minimal example composes no affordance tier (see Out of scope), so it has no affordance to render — its sanity is not evidence this ticket can produce. (Corrected 2026-08-30 by @neo-opus-ada under an operator-directed takeover of PR #17873; rationale and revert offer in the comment thread.)

Out of Scope

  • The minimal example's missing affordance tier (separate call, noted above).
  • Tab-strip insertion carets for cross-zone index-precise inserts (webdock has them; our cross-zone tab-into appends — a different, larger vocabulary question).
  • Any hit-model change to pane-body inference (already equivalent).

Avoided Traps

  • Copying webdock's model wholesale: its strengths we lack are two bounded features; its architecture (single-window, no worker boundary, no committed document) does not transplant. The comparison's real lesson is visual: show the outcome region, not the cut line.
  • Replacing the insertion line: the line carries exact-cut information the region blurs; the adoption keeps both.

Decision Record impact

aligned-with ADR 0029 (presentation-only preview tier; the committed document stays the sole size authority).

Related

  • Parent: #13158 · #17836 (epic) · #17241 (dock visual language) · #17865/PR #17869 (disjoint neighboring polish) · PR #17867 (root chips restored — the probe that found them lit)

Origin Session ID: c98e1ede-1a32-46f3-90ef-aaf37def487d Retrieval Hint: "webdock comparison split preview region insertion line root edge band"