feat: geometric shapes on the Atlas board (goal 0169 slice 5) - #398
Merged
Conversation
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
BoardObjectKind (shape), drawn via the existingdrag-to-drawinteraction (no new interaction shape needed).Payloaddata — never baked into a mirror file the way ink's pixels are — rendering straight from Payload + the already-genericSizefield. First real use ofSetBoardObjectSizeoutside a manual resize.CreateBoardObject/SetBoardObjectSize/PromoteBoardObject/DeleteBoardObjectwere already Kind-agnostic since goal 0179 S1 — confirmed bygit diff --statshowing no.gofiles in this diff.AtlasCreationTray.tsx: a single shared anchorrefreused across every mappeddrag-to-drawbutton 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;StylePickerresolution is now registry-driven off each tool's own descriptor field, not a hardcoded branch.useAtlasDragTools.ts(Eraser/Laser's own precedent, not Area/Pencil's) to keepAtlasBoard.tsxunder 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.tsanduseKeymapDispatchneeded zero changes (as with every slice since S2);AtlasCreationTray/useAtlasCreation/useAtlasDragToolstook small additive edits plus one real structural fix the second drag-to-draw tool exposed.Findings reported, not silently worked around
.selectedoutline 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.selectedrule. 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.pointer-eventsfix holds;atlas-page.spec.tspasses unmodified.Test plan
atlasTools.test.tsextended:shapeTool.commitfor rectangle/ellipse/arrow, registry shape/StylePicker assertions.atlasShapeSvg.test.ts: pure geometry helpers (boxDimensions,arrowGeometry,shapePayload).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.atlas-pencil-tool,atlas-eraser-laser,atlas-image-tool,atlas-page(14/14).npm run test(92 files / 779 tests),npm run lint,npx tsc --noEmit,npm run boundaries,go build/go vet, and the fulllefthook run pre-commitsuite all green..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