Repository navigation
feat(ui): redesign phase 2 — layer panel with depth ruler - #27
Conversation
HANDOFF.md §12 step 2: - LayerPanel: always-visible layer list, nearest first, with thumbnail, name, GROUND badge and a depth chip that edits depth in place (without selecting). Click selects/deselects; Delete on the focused list deletes the selected slice. Copy / Paste / Delete move to its header. - DepthRuler: 255 (near) to 0 (far) axis with a handle per slice linked to its row (ground green, selected blue); drag or arrow keys preview locally and commit setSliceDepth on release. - SelectedSliceHeader at the top of the Inspector: the selected slice with Download and Replace image. - The slice strip and its Copy/Paste/Delete are gone from the Segmentation panel; the Inspector narrows to 360px. - e2e: slices are addressed by index (sliceImage(i)), undo/redo use the header for the selected slice, download/replace select the slice first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The new in-place depth editing in LayerPanel can commit out-of-range depths (negative/>255), which can break ruler mapping and produce unexpected backend state.
Review effort: Lite
Findings: 1
Open (1)
What changed in this PR
Implements phase 2 of the Svelte UI redesign by introducing an always-visible LayerPanel (with a DepthRuler) and moving selected-slice affordances into a new SelectedSliceHeader, while removing the legacy slice thumbnail strip from the Segmentation tab. This aligns slice selection, depth editing, undo/redo, download, and replace-image flows with the redesign handoff.
Changes:
- Add
LayerPanel+DepthRulerfor nearest-first slice listing and depth editing (drag + keyboard), and adjust app layout columns. - Add
SelectedSliceHeaderin the Inspector to centralize per-slice download/replace actions. - Update unit tests and Playwright E2E driver/specs to use the new UI structure and slice addressing.
| File | Description |
|---|---|
| frontend/src/setupTests.ts | Adds a jsdom ResizeObserver stub for components using bind:clientHeight. |
| frontend/src/lib/components/shell/Inspector.svelte | Renders SelectedSliceHeader above Inspector sections (non-Configuration tabs). |
| frontend/src/lib/components/shell/AppShell.svelte | Adds LayerPanel to the main grid and adjusts column widths/breakpoints. |
| frontend/src/lib/components/segmentation/SegmentationTab.test.ts | Removes/updates tests tied to the removed slice strip and relocated actions. |
| frontend/src/lib/components/segmentation/SegmentationTab.svelte | Removes the slice thumbnail strip UI and related handlers/styles; simplifies layout. |
| frontend/src/lib/components/layers/SelectedSliceHeader.test.ts | Adds unit coverage for selected-slice header rendering, download, and replace flow. |
| frontend/src/lib/components/layers/SelectedSliceHeader.svelte | Implements the Inspector header for the selected slice (thumb, depth, ground, download/replace). |
| frontend/src/lib/components/layers/LayerPanel.test.ts | Adds unit coverage for ordering, empty state, selection toggle, depth chip edit, header actions, delete key, and ruler interactions. |
| frontend/src/lib/components/layers/LayerPanel.svelte | Implements the new layer list UI, selection semantics, in-place depth editing, and wiring to DepthRuler. |
| frontend/src/lib/components/layers/DepthRuler.svelte | Adds the vertical 255→0 ruler with draggable/keyboard-adjustable handles and commit-on-release behavior. |
| e2e/slice-editing.spec.ts | Switches slice thumbnail targeting to ui.sliceImage(i) under nearest-first display order. |
| e2e/parallax-maker.spec.ts | Updates slice thumbnail access to the new sliceImage(i) helper while preserving count checks. |
| e2e/drivers/types.ts | Extends UiDriver with sliceImage(index) and clarifies semantics around undo/redo targeting. |
| e2e/drivers/svelte.ts | Implements sliceImage(index), updates selection logic for the new panel, and routes undo/redo/download/replace via the selected-slice header. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| function commitDepth(index: number): void { | ||
| if (editingIndex !== index) return; | ||
| editingIndex = null; | ||
| // Blank or non-integer input does not commit (it must not become 0). | ||
| const draft = depthDraft.trim(); | ||
| if (!/^-?\d+$/.test(draft)) return; | ||
| void workflow.setSliceDepth(index, Number.parseInt(draft, 10)); | ||
| } |
There was a problem hiding this comment.
Fixed: typed depths are now clamped to 0–255 before setSliceDepth (blank and non-integer input still don't commit). Added tests for 300 → 255 and -5 → 0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Phase 2 of the UI redesign (docs/redesign/HANDOFF.md, §12 step 2). The slice thumbnail strip is replaced by an always-visible layer panel.
What changes
LayerPanel(left column, 300px):DepthRuler:setSliceDepthon release.SelectedSliceHeaderat the top of the Inspector shows the selected slice, with Download and Replace image…. Per the design, these replace the per-thumbnail download link and drop target.Tests
LayerPanel.test.ts(19 tests), ported from the old strip tests plus new ones: nearest-first order, empty state, Delete key, ruler keyboard nudge and pointer drag.SelectedSliceHeader.test.ts(5 tests).SegmentationTab.test.tstrimmed accordingly.ResizeObserverstub for jsdom.UiDriver.sliceImage(i), since display order is now nearest first. Undo/redo use the header's buttons for the selected slice, and download and replace select the slice first.Next: phase 3, canvas view modes and tools.
🤖 Generated with Claude Code