Skip to content

feat(M5): selection transform, inspector, z-order & per-object lock (pillars 2 & 3, v0)#9

Merged
pedrobritx merged 2 commits into
mainfrom
claude/intelligent-albattani-xExxa
May 29, 2026
Merged

feat(M5): selection transform, inspector, z-order & per-object lock (pillars 2 & 3, v0)#9
pedrobritx merged 2 commits into
mainfrom
claude/intelligent-albattani-xExxa

Conversation

@pedrobritx
Copy link
Copy Markdown
Owner

Milestone 5 — Pillars 2 & 3 (v0)

Makes the selection a first-class object: you can now resize/rotate, restyle, restack, and lock shapes. The M5 scope line is "highlighter / eraser / shapes / text / select + per-object lock"; the tools shipped in M2/M3, so this PR covers the select and per-object lock halves, grouped into two pillars.

Note: the detailed "pillar" breakdown lives in the external planning doc (the notuux-whiteboard-brainstorm branch description), which isn't in the repo. This v0 was scoped from that M5 line + the current code; the four capability areas were confirmed with the requester.

Pillar 2 — Select & Style

  • Selection transform — a Konva Transformer (new TransformLayer) adds resize + rotate handles for box kinds (rect/ellipse/text/asset), mounted only under the select tool. To pivot correctly around each shape's own origin, the box renderers now draw in local coords with the ShapesLayer Group carrying x/y/rotation; the live transform is baked back to the model on transformend (one undo entry for multi-select). A pointer-down on a handle is guarded so it doesn't also start a drag.
  • Selection inspector — a Liquid-Glass panel (right dock, mirrors ToolPalette) with stroke color, fill, opacity, and font-size controls, showing shared values or "Mixed" across a multi-selection.

Pillar 3 — Arrange & Lock

  • Z-orderbringToFront / sendToBack / bringForward / sendBackward on the shape store; listShapes sorts by a new optional z (insertion-order fallback, so existing boards are unchanged). Inspector buttons + Cmd/Ctrl+]/[ (Shift = front/back).
  • Per-object lock — wires the existing-but-unused locked field across select-drag, transform, delete, eraser, marquee, and double-click-edit. Lock/Unlock in the inspector, Cmd/Ctrl+Shift+L, and an amber selection box. A locked shape is still single-click-selectable so Unlock stays reachable.

Model / plumbing

  • New optional YShapeBase fields z?, opacity? (+ rot? on YText); both optional ⇒ no migration, old shapes deserialize fine.
  • Opacity is now applied once on the ShapesLayer Group (highlighter keeps its 0.35 default unless overridden); removed from StrokeRenderer.
  • All writes go through updateShape / transact, so they ride the Yjs UndoManager and will sync over M4 realtime once that merges.

Verification

  • pnpm typecheck (all 5 workspaces)
  • pnpm build
  • ⏳ Manual browser smoke (recommended): resize/rotate a rect & persist on reload; multi-select transform → single undo reverts both; inspector color/fill/opacity/font + "Mixed"; z-order via buttons + shortcuts; lock blocks drag/resize/delete/erase/marquee/edit but stays selectable; anchors don't double-drag.

Deferred past v0

Stroke resize/rotate; line/arrow endpoint handles; rotated-bounds-aware marquee/overlay; fractional z-indexing; flip via negative scale; text aspect-lock; dedicated lock-glyph badge.

https://claude.ai/code/session_019jiFzJWnoACbYVEURirwxL


Generated by Claude Code

claude added 2 commits May 29, 2026 02:46
Milestone 5, pillars 2 & 3 (v0) — make the selection a first-class,
editable, arrangeable, lockable object.

Pillar 2 — Select & Style:
- Konva Transformer (new TransformLayer) gives resize + rotate handles
  for box kinds (rect/ellipse/text/asset), gated on the select tool.
  Renderers now draw in local coords with the ShapesLayer Group carrying
  x/y/rotation so the transform pivots around the shape's own origin; the
  transform is baked back to the model on transformend (one undo entry).
- SelectionInspector: a Liquid-Glass panel (right dock) with stroke color,
  fill, opacity, and font-size controls, computing shared/"mixed" values
  across a multi-selection.

Pillar 3 — Arrange & Lock:
- Z-order: bringToFront/sendToBack/bringForward/sendBackward on the store;
  listShapes sorts by z (insertion-order fallback). Buttons + Cmd/Ctrl+]/[
  (Shift = front/back). New shapeBase z field.
- Per-object lock: wires the existing locked field across select-drag,
  transform, delete, eraser, marquee, and double-click-edit; lock toggle in
  the inspector, Cmd/Ctrl+Shift+L, and an amber selection box.

New optional shape fields z/opacity (+ rot on text); opacity now applied
once on the ShapesLayer Group. All mutations flow through updateShape/
transact so they ride Yjs undo and future realtime.

typecheck + build pass across all workspaces.

https://claude.ai/code/session_019jiFzJWnoACbYVEURirwxL
It ran `npm ci` / `npm test` with `cache: npm` in a pnpm monorepo that has
no package-lock.json and no test script, so its build (18.x/20.x/22.x) jobs
failed on every PR and push. The real typecheck + build gate is ci.yml
(pnpm-based), which fully covers this; node.js.yml was redundant.

https://claude.ai/code/session_019jiFzJWnoACbYVEURirwxL
@pedrobritx pedrobritx marked this pull request as ready for review May 29, 2026 04:19
@pedrobritx pedrobritx merged commit 5d6eed7 into main May 29, 2026
4 checks passed
@pedrobritx pedrobritx deleted the claude/intelligent-albattani-xExxa branch May 29, 2026 04:19
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.

2 participants