Skip to content

feat: geometric shapes on the Atlas board (goal 0169 slice 5) - #398

Merged
alicoding merged 1 commit into
mainfrom
worktree-agent-ab0361dca1e5fd987
Aug 24, 2026
Merged

feat: geometric shapes on the Atlas board (goal 0169 slice 5)#398
alicoding merged 1 commit into
mainfrom
worktree-agent-ab0361dca1e5fd987

Conversation

@alicoding

Copy link
Copy Markdown
Owner

Summary

  • Rectangle, ellipse, and arrow join image/ink as a fourth board-local BoardObject Kind (shape), drawn via the existing drag-to-draw interaction (no new interaction shape needed).
  • Fill/stroke/strokeWidth stay live Payload data — never baked into a mirror file the way ink's pixels are — rendering straight from Payload + the already-generic Size field. First real use of SetBoardObjectSize outside a manual resize.
  • Zero Go files touched. CreateBoardObject/SetBoardObjectSize/PromoteBoardObject/DeleteBoardObject were already Kind-agnostic since goal 0179 S1 — confirmed by git diff --stat showing no .go files in this diff.
  • Fixed a structural bug in AtlasCreationTray.tsx: a single shared anchor ref reused across every mapped drag-to-draw button would have silently mispositioned one tool's own options popover the moment a second such tool (shape) existed. Replaced with a per-tool-id ref map; StylePicker resolution is now registry-driven off each tool's own descriptor field, not a hardcoded branch.
  • Shape's armed state/style store/placement door/drag hook are instantiated inside useAtlasDragTools.ts (Eraser/Laser's own precedent, not Area/Pencil's) to keep AtlasBoard.tsx under the 500-line cap.

Measurement against the 26 → 21 → 16 curve

20 files touched, +909/-68 lines, one PR. Roughly in line with the falling per-tool marginal cost the registry bet predicted (S2:26, S3:21, S4: ~8/tool for two tools). commands.ts and useKeymapDispatch needed zero changes (as with every slice since S2); AtlasCreationTray/useAtlasCreation/useAtlasDragTools took small additive edits plus one real structural fix the second drag-to-draw tool exposed.

Findings reported, not silently worked around

  1. A pre-existing, cosmetic bug: the .selected outline never visually renders on ANY board object (image/ink included, confirmed identical on an existing image object) — a clicked node also gains DOM focus, and React Flow's own .react-flow__node.selectable:focus { outline: none } wins at equal CSS specificity over Mill's .selected rule. Predates this slice (goal 0179 S1's own CSS), out of this slice's scope to fix. Selection state (multi-select, delete, undo) all work correctly — only the visual ring is invisible. Worth a follow-up.
  2. Tray width: 538px (8 tools) → 604px (9 tools) — still narrower than the original six-button labeled tray (628px). The eraser/laser slice's structural pointer-events fix holds; atlas-page.spec.ts passes unmodified.
  3. Caught my own e2e test bug via the goal-0184 class: a drag start point landing on the still-open style picker popover silently swallowed the gesture. Traced to root cause (not retried blind) and fixed by moving both drags into the board's clear top band.

Test plan

  • atlasTools.test.ts extended: shapeTool.commit for rectangle/ellipse/arrow, registry shape/StylePicker assertions.
  • New atlasShapeSvg.test.ts: pure geometry helpers (boxDimensions, arrowGeometry, shapePayload).
  • New frontend/e2e/atlas-shape-tool.spec.ts (shared pool): draw+delete, type switching, style-persistence-across-rearm + Promote to card. All green against the real built server, not mocked.
  • Regression sweep green: atlas-pencil-tool, atlas-eraser-laser, atlas-image-tool, atlas-page (14/14).
  • Full npm run test (92 files / 779 tests), npm run lint, npx tsc --noEmit, npm run boundaries, go build/go vet, and the full lefthook run pre-commit suite all green.
  • Screenshot taken (server mode + Playwright, deviceScaleFactor 2): image + a red-stroked, thick rectangle + an ink stroke drawn across it, shape selected (DOM-confirmed .selected, visual ring not visible per finding build(deps): Bump golang.org/x/oauth2 from 0.35.0 to 0.36.0 in the go-dependencies group #1 above).

🤖 Generated with Claude Code

https://claude.ai/code/session_01FW5GkkAG8du7tNdYLk2zSd

Rectangle, ellipse, and arrow join image/ink as a fourth board-local
BoardObject kind ('shape'), drawn via the existing drag-to-draw
interaction the pencil tool already proved. Fill/stroke/strokeWidth
live directly in Payload as editable data (never baked into a mirror
file the way ink's pixels are), rendering live from Payload + the
generic Size field -- the first real use of SetBoardObjectSize outside
a manual resize. Zero Go files touched: CreateBoardObject/
SetBoardObjectSize/PromoteBoardObject/DeleteBoardObject were already
Kind-agnostic since goal 0179 S1.

Fixes a structural bug in AtlasCreationTray.tsx surfaced by adding a
second 'drag-to-draw' tool: a single shared anchor ref reused across
every mapped drag-to-draw button would have silently mispositioned
one tool's own options popover. Replaced with a per-tool-id ref map,
and StylePicker resolution is now registry-driven (each tool names its
own options-bar component) rather than a hardcoded branch.

Shape's own armed state, style store, placement door, and drag hook
are instantiated inside useAtlasDragTools.ts (following Eraser/Laser's
own precedent, not Area/Pencil's, since Shape is introduced at this
split) to keep AtlasBoard.tsx under the 500-line cap.

Tray grows from 538px (8 tools) to 604px with the ninth icon-only
button -- still narrower than the original six-button labeled tray
(628px); the eraser/laser slice's pointer-events structural fix holds
(atlas-page.spec.ts passes unmodified).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FW5GkkAG8du7tNdYLk2zSd
@alicoding
alicoding merged commit 3b93a51 into main Aug 24, 2026
27 checks passed
@alicoding
alicoding deleted the worktree-agent-ab0361dca1e5fd987 branch August 24, 2026 08:20
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