Skip to content

Distribute — even out gaps in a multi-selection#182

Open
lklyne wants to merge 1 commit into
mainfrom
claude/issue-180
Open

Distribute — even out gaps in a multi-selection#182
lklyne wants to merge 1 commit into
mainfrom
claude/issue-180

Conversation

@lklyne
Copy link
Copy Markdown
Owner

@lklyne lklyne commented May 31, 2026

Closes #180

Adds a Distribute action (ADR 0015 D7) that evens edge-to-edge gaps in a loose 3+ entity selection along the dominant axis, keeping the first and last items fixed. The output is reorder-eligible by construction — distribute is the on-ramp to a reorderable row.

What's in this PR

Phase A — Pure kernel

  • src/shared/reorder-row.ts: extract and export dominantAxis so the distribute kernel and reorder detector share one axis definition (no copy-pasted predicate)
  • src/shared/distribute-row.ts: pure distributeRowPositions kernel — sort by leading edge, compute even gap, pack middle items, return only changed positions; null when <3 items or already even
  • tests/unit/distribute-row.test.ts: 11 unit tests including the round-trip that proves output passes detectReorderableRow

Phase B — Commit path + CLI + HTTP

  • src/main/runtime/document-commands.ts: distributeSelection(entityIds) mutator — reads live geometry, calls distributeRowPositions, writes changed positions via writeReorderedPosition inside one beginBatch/endBatch + markUndoBoundary. Position-only, no entityOrder, no managedLayout.
  • src/main/routes/workspace.ts: POST /selection/distribute (defaults to current selection)
  • src/main/cli-commands.ts: specular distribute <ids>
  • src/main/routes/test.ts: POST /test/canvas-distribute-selection/commit
  • tests/smoke/app-client.ts: distributeSelection helper
  • tests/smoke/distribute-selection.test.ts: smoke tests — one transaction, one undo step, endpoints fixed, gaps equal, output reorder-eligible, no-op for already-even and <3 items

Phase C — Selection popup

  • src/shared/types.ts: distributeSelection() on CanvasBgElectronAPI
  • src/preload/canvas-bg.ts + src/main/ipc/register-canvas-entity-ipc.ts: IPC wiring
  • src/renderer/above-view/DistributePopup.tsx: popup button (AlignJustify icon) shown for 3+ loose entities
  • src/renderer/above-view/App.tsx: mount DistributePopup when ≥3 entities selected with no managed-row group

Phase C acceptance (in-app visual) requires human /verify: with 3+ unevenly-spaced items selected the Distribute button appears; clicking evens the gaps; reorder dots then appear on the result; one undo restores.

https://claude.ai/code/session_01QdaCmAuAZfcKYFGeesiNBP


Generated by Claude Code

#180)

Adds a Distribute action (ADR 0015 D7) that evens edge-to-edge gaps in a
loose 3+ entity selection along the dominant axis, keeping endpoints fixed
and making the result reorder-eligible by construction.

- src/shared/reorder-row.ts: extract and export `dominantAxis` so the
  distribute kernel and the reorder detector share one axis definition
- src/shared/distribute-row.ts: pure `distributeRowPositions` kernel
- src/main/runtime/document-commands.ts: `distributeSelection` mutator —
  position-only, one Y.Doc transaction, one undo step, no managed-layout
- src/main/routes/workspace.ts: POST /selection/distribute
- src/main/cli-commands.ts: `specular distribute <ids>`
- src/main/routes/test.ts: POST /test/canvas-distribute-selection/commit
- tests/smoke/app-client.ts: distributeSelection helper
- tests/smoke/distribute-selection.test.ts: smoke coverage
- tests/unit/distribute-row.test.ts: unit coverage incl. round-trip
- src/shared/types.ts: distributeSelection on CanvasBgElectronAPI
- src/preload/canvas-bg.ts + src/main/ipc/register-canvas-entity-ipc.ts:
  IPC wiring
- src/renderer/above-view/DistributePopup.tsx: selection popup button
- src/renderer/above-view/App.tsx: mount DistributePopup for 3+ loose entities
- CONTEXT.md: Distribute glossary entry

https://claude.ai/code/session_01QdaCmAuAZfcKYFGeesiNBP
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.

Distribute — even out the gaps in a multi-selection

2 participants