Skip to content

Circuit-Editor Multi-Target Gate Support#3426

Draft
ScottCarda-MS wants to merge 3 commits into
sccarda/ce-foundationfrom
sccarda/ce-multitarget
Draft

Circuit-Editor Multi-Target Gate Support#3426
ScottCarda-MS wants to merge 3 commits into
sccarda/ce-foundationfrom
sccarda/ce-multitarget

Conversation

@ScottCarda-MS

@ScottCarda-MS ScottCarda-MS commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Circuit Editor: multi-target / group drag-editing

Reviewer TL;DR. This adds the multi-target / group drag-editing layer
to the circuit-vis circuit editor: moving multi-target gates and groups as
rigid units, cloning them as a unit (Ctrl-drag), and shift-to-extend a group
onto new wires. No public API changes. The diff is small and
self-contained — 8 files — and the behavior is purely additive on top of the
existing single-target editing paths.


At a glance

Scope 8 files — 4 source, 4 test — all under source/npm/qsharp/
Size +1,439 / −23
Language TypeScript (frontend) + .mjs tests. No Rust, no VS Code host.
Public API Unchanged
Tests +26 tests, all green
Behavioral risk Additive — only the multi-leg editing paths are new

What this PR adds

The multi-target / group drag-editing behavior, layered onto the
single-target editing foundation:

  1. Rigid unit-move. Dragging a multi-target gate or a group shifts the
    gate's own .targets and recursively remaps every register reference in
    its child grid by the same delta, so the box and its contents stay aligned.
    Classical controls anchor correctly:

    • an external measurement's classical reg stays put → the moved gate's
      classical control anchors on the original wire;
    • an internal measurement (inside the moved subtree) moves with it → the
      consumer's classical control shifts in lockstep, and numResults
      bookkeeping follows the measurement.
    • Bounds-checked: a unit-shift that would push any wire below 0 is refused
      without mutating the model.
  2. Clone-as-unit (Ctrl-drag). Ctrl-dragging a multi-target gate / group
    leaves the source in place and drops a full copy at the target, with the same
    child-register remap as a unit-move.

  3. Shift-to-extend. Holding Shift while dragging a child out of an expanded
    group offers dropzones on wires outside the group's span (skipping wires
    blocked by ancestor-column siblings) and paints a ghost border showing the
    extended bounds — extending the group onto new wires.


Files changed

Source (4):

File What it adds
actions/circuit-actions/move.ts moveAsUnit, shiftAllRegisters, subtree wire-swap helpers; the unit-shift branch of moveY; group-body target handling.
actions/circuitActions.ts moveOperation unit-shift wire-growth; addOperation clone-as-unit + sourceWire param.
editor/controllers/dragController.ts Shift-extend lifecycle (setupShiftExtend / spawn / paintGhostBorder / tearDown) + the per-op multi-leg dropzone loop.
editor/draggable.ts makeShiftExtendGhost geometry helper.

Tests (4):

File Tests added
test/circuit-editor/circuit-actions/groupClone.test.mjs 7 clone-as-unit tests (whole file).
test/circuit-editor/circuit-actions/groupMove.test.mjs 7 rigid unit-move / bounds tests.
test/circuit-editor/dragController.test.mjs 8 shift-extend lifecycle tests.
test/circuit-editor/draggable.test.mjs 4 makeShiftExtendGhost geometry tests.

Testing

  • +26 circuit-editor tests across the 4 test files above, all passing.

  • Run locally from source/npm/qsharp/:

    # build the UX bundle
    npm run build:ux
    # run the circuit-editor suite
    node --test "test/circuit-editor/**/*.test.mjs"

@ScottCarda-MS ScottCarda-MS changed the title multi-target gate support Circuit-Editor Multi-Target Gate Support Jul 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant