EditorRightPanel: ~170 lines of dead Sequence/Underlay branches + 4 smaller dead/broken controls #91

Closed
opened 2026-09-14 17:27:43 +00:00 by Mark · 0 comments
Owner

Where: src/components/editor/EditorRightPanel.tsx.

Bug: Walking the right panel turned up one large dead-section pair and four smaller issues. Same orphan-decorative-UI family as the Editor's Settings placeholder (#71, since fixed), parseDesignFile.ts (#72), and the Settings page reference (#76).

Bug 1 — mode === 'sequence' (L257-335, ~80 lines) and mode === 'underlay' (L336-427, ~90 lines) branches are unreachable. ~170 lines of dead UI.

The panel renders a different content per mode (string). Of the four reachable toolbar modes (select_nodes, add_node, delete_node, convert_node, draw_path, scissors, smooth, zoom — TOOL_MODES in src/components/editor/constants.ts:28-37), only isNodeMode (the 6 listed node modes share one panel), draw_path, and zoom produce content. sequence and underlay produce no content because:

  1. EditorToolMode (src/components/editor/types.ts:38-46) does not include 'sequence' or 'underlay' — it enumerates exactly the 8 modes in TOOL_MODES.
  2. useState<EditorToolMode>('select_nodes') initializes mode (Editor.tsx:164); handleModeChange (Editor.tsx:204) only ever passes values from the toolbar (EditorToolbar.tsx:58-105 mapping TOOL_MODES.map(tool => onModeChange(tool.id))) or from the keyboard shortcut toolMap (useKeyboardShortcuts.ts:89-104, keys n a d c p s m z → the 8 TOOL_MODES). Neither path can produce 'sequence' or 'underlay'.
  3. EditorRightPanel.tsx:9 types mode as string (relaxed from EditorToolMode) so the comparison compiles. That relaxation is the only thing keeping the dead branches from being a TypeScript error.

So the Sequence Controls panel (Play/Pause, Optimize Sequence button, drag-reorder list at L313-332) and the Underlay Settings panel (Main/Underlay toggle, disabled select + read-only inputs + disabled sliders at L373-422) never render in the running app. Grep:

$ grep -rn "'sequence'|'underlay'" src/
src/components/editor/EditorCanvas.tsx:292: if (mode === 'underlay') {
src/components/editor/EditorCanvas.tsx:314: } else if (mode === 'sequence') {
src/components/editor/EditorCanvas.tsx:325: } else if (mode === 'underlay') {
src/components/editor/EditorRightPanel.tsx:257: ) : mode === 'sequence' ? (
src/components/editor/EditorRightPanel.tsx:336: ) : mode === 'underlay' ? (
src/pages/Editor.tsx:173: const [underlayEditMode, setUnderlayEditMode] = useState<'main' | 'underlay'>('main');

All references are consumer-side: nothing ever sets mode to 'sequence' or 'underlay'. The EditorCanvas branches (lines 292, 314, 325) are also unreachable for the same reason.

Bug 2 — "Convert" button (L181) is mislabeled. onClick={() => onUpdateNodeType('smooth')} — always sets node type to smooth. There's no conversion logic; the label promises "Convert" but the action is "force-smooth". The Node Type segmented control directly above (L147-160) already exposes corner/smooth/symmetric via onUpdateNodeType(t), making this button redundant with the smooth segment.

Bug 3 — draw_path Path Properties controls (L235-255) are uncontrolled dead-end inputs.

<select defaultValue="satin" ...>…</select>
<Slider defaultValue={[0.4]} min={0.1} max={1.0} step={0.05} />

Stitch Type and Density render with no value and no onChange — defaultValue only. The user picks a different stitch type from the dropdown or moves the slider; the underlying selectedPath.stitchType and selectedPath.density are never updated. The export pipeline (pathsToStitchObjects, Editor.tsx:105-138) reads p.stitchType / p.density directly from the path, so these controls visually change but have zero effect on the output.

Bug 4 — Sequence Order list (L313-332) renders drag handles with no drag wiring. GripVertical icon at L319 with cursor: 'grab'. No draggable attribute, no onDragStart/onDragOver/onDragEnd handlers. The list is display-only. (Moot because the whole sequence mode branch is unreachable — Bug 1 — but if the mode were wired up, the drag handles would silently fail.)

Bug 5 — EditorToolbar Settings button (EditorToolbar.tsx:149-163) is decorative-without-disabled. No onClick, no disabled prop. Hover changes background and color (onMouseEnter/onMouseLeave lines 152-160) — so the button looks interactive — but clicks do nothing. Same family as the EditorHeader Settings button (#71), but that one was fixed to disabled + cursor: not-allowed. EditorToolbar wasn't.

Fix consistent with existing patterns:

  1. Bugs 1 + 4 — delete or wire up. Two paths:

    • Delete (cheaper, matches the deferred path for #88): drop the 'sequence' and 'underlay' branches from EditorRightPanel.tsx (~170 lines). Drop the if (mode === 'underlay') / else if (mode === 'sequence') / else if (mode === 'underlay') branches from EditorCanvas.tsx:289-340 (~50 more lines). Re-tighten mode: EditorToolMode in EditorRightPanelProps. Then the underlayEditMode state in Editor.tsx:173 becomes dead state (no UI ever flips it) — drop that too. Total ~250 lines of dead code removed.
    • Wire up: add 'sequence' and 'underlay' to EditorToolMode + TOOL_MODES, expose them in the toolbar, give the keyboard shortcuts bindings. That's a feature request, not a bug fix — track separately under the open #6/#7/#8/#9/#10 Phase D issues or file a new "Editor needs explicit sequence/underlay tools" feature.

    Recommended: Delete. The actual sequence optimization happens server-side at export time; the per-path reorder would be a UX nicety at best.

  2. Bug 2 — remove "Convert" button (L180-186) or make it round-robin. Three Node Type buttons already cover corner/smooth/symmetric. The button is redundant. If round-robin is desired, the handler is onUpdateNodeType(nextType) where nextType = current === 'corner' ? 'smooth' : current === 'smooth' ? 'symmetric' : 'corner'.

  3. Bug 3 — wire Stitch Type and Density to selectedPath. Either:

    • Add onStitchTypeChange / onDensityChange props to EditorRightPanelProps, lift the handlers to Editor.tsx, and call setPaths(prev => prev.map(p => p.id === selectedPathId ? { ...p, stitchType, density } : p)) — push history too.
    • Or, since the panel can't actually edit per-path properties meaningfully (they get rewritten by the export pipeline), remove the Path Properties section entirely until a real edit story exists.
  4. Bug 5 — disable the EditorToolbar Settings button (L149-163). Mirror the EditorHeader fix from #71:

    <button disabled ... title="Settings — coming soon">…</button>
    

    With disabled:opacity-30 disabled:cursor-not-allowed styling to match the disabled Undo/Redo buttons above.

Cross-references: #71 (EditorHeader Export/Settings no-op, since fixed), #76 (FAQ reference to non-existent Settings page, since fixed), #88 (orphan region-classifier, deferred+deleted this turn). Same orphan-UI pattern.

Severity: medium for Bug 1 (170 LOC of misleading UI + relaxed type), low for Bugs 2-5 (cosmetic / dead controls).

**Where:** `src/components/editor/EditorRightPanel.tsx`. **Bug:** Walking the right panel turned up one large dead-section pair and four smaller issues. Same orphan-decorative-UI family as the Editor's Settings placeholder (#71, since fixed), `parseDesignFile.ts` (#72), and the Settings page reference (#76). **Bug 1 — `mode === 'sequence'` (L257-335, ~80 lines) and `mode === 'underlay'` (L336-427, ~90 lines) branches are unreachable. ~170 lines of dead UI.** The panel renders a different content per `mode` (string). Of the four reachable toolbar modes (`select_nodes`, `add_node`, `delete_node`, `convert_node`, `draw_path`, `scissors`, `smooth`, `zoom` — `TOOL_MODES` in `src/components/editor/constants.ts:28-37`), only `isNodeMode` (the 6 listed node modes share one panel), `draw_path`, and `zoom` produce content. `sequence` and `underlay` produce no content because: 1. `EditorToolMode` (`src/components/editor/types.ts:38-46`) does not include `'sequence'` or `'underlay'` — it enumerates exactly the 8 modes in `TOOL_MODES`. 2. `useState<EditorToolMode>('select_nodes')` initializes `mode` (`Editor.tsx:164`); `handleModeChange` (Editor.tsx:204) only ever passes values from the toolbar (`EditorToolbar.tsx:58-105` mapping `TOOL_MODES.map(tool => onModeChange(tool.id))`) or from the keyboard shortcut toolMap (`useKeyboardShortcuts.ts:89-104`, keys `n a d c p s m z` → the 8 `TOOL_MODES`). Neither path can produce `'sequence'` or `'underlay'`. 3. `EditorRightPanel.tsx:9` types `mode` as `string` (relaxed from `EditorToolMode`) so the comparison compiles. That relaxation is the only thing keeping the dead branches from being a TypeScript error. So the Sequence Controls panel (Play/Pause, Optimize Sequence button, drag-reorder list at L313-332) and the Underlay Settings panel (Main/Underlay toggle, disabled select + read-only inputs + disabled sliders at L373-422) never render in the running app. Grep: ``` $ grep -rn "'sequence'|'underlay'" src/ src/components/editor/EditorCanvas.tsx:292: if (mode === 'underlay') { src/components/editor/EditorCanvas.tsx:314: } else if (mode === 'sequence') { src/components/editor/EditorCanvas.tsx:325: } else if (mode === 'underlay') { src/components/editor/EditorRightPanel.tsx:257: ) : mode === 'sequence' ? ( src/components/editor/EditorRightPanel.tsx:336: ) : mode === 'underlay' ? ( src/pages/Editor.tsx:173: const [underlayEditMode, setUnderlayEditMode] = useState<'main' | 'underlay'>('main'); ``` All references are **consumer-side**: nothing ever sets `mode` to `'sequence'` or `'underlay'`. The EditorCanvas branches (lines 292, 314, 325) are also unreachable for the same reason. **Bug 2 — "Convert" button (L181) is mislabeled.** `onClick={() => onUpdateNodeType('smooth')}` — always sets node type to smooth. There's no conversion logic; the label promises "Convert" but the action is "force-smooth". The Node Type segmented control directly above (L147-160) already exposes corner/smooth/symmetric via `onUpdateNodeType(t)`, making this button redundant with the smooth segment. **Bug 3 — `draw_path` Path Properties controls (L235-255) are uncontrolled dead-end inputs.** ```tsx <select defaultValue="satin" ...>…</select> <Slider defaultValue={[0.4]} min={0.1} max={1.0} step={0.05} /> ``` Stitch Type and Density render with no `value` and no `onChange` — `defaultValue` only. The user picks a different stitch type from the dropdown or moves the slider; the underlying `selectedPath.stitchType` and `selectedPath.density` are never updated. The export pipeline (`pathsToStitchObjects`, Editor.tsx:105-138) reads `p.stitchType` / `p.density` directly from the path, so these controls visually change but have zero effect on the output. **Bug 4 — Sequence Order list (L313-332) renders drag handles with no drag wiring.** `GripVertical` icon at L319 with `cursor: 'grab'`. No `draggable` attribute, no `onDragStart`/`onDragOver`/`onDragEnd` handlers. The list is display-only. (Moot because the whole `sequence` mode branch is unreachable — Bug 1 — but if the mode were wired up, the drag handles would silently fail.) **Bug 5 — EditorToolbar Settings button (EditorToolbar.tsx:149-163) is decorative-without-disabled.** No `onClick`, no `disabled` prop. Hover changes background and color (`onMouseEnter`/`onMouseLeave` lines 152-160) — so the button looks interactive — but clicks do nothing. Same family as the EditorHeader Settings button (#71), but that one was fixed to `disabled` + `cursor: not-allowed`. EditorToolbar wasn't. **Fix consistent with existing patterns:** 1. **Bugs 1 + 4 — delete or wire up.** Two paths: - **Delete** (cheaper, matches the deferred path for #88): drop the `'sequence'` and `'underlay'` branches from `EditorRightPanel.tsx` (~170 lines). Drop the `if (mode === 'underlay')` / `else if (mode === 'sequence')` / `else if (mode === 'underlay')` branches from `EditorCanvas.tsx:289-340` (~50 more lines). Re-tighten `mode: EditorToolMode` in `EditorRightPanelProps`. Then the `underlayEditMode` state in Editor.tsx:173 becomes dead state (no UI ever flips it) — drop that too. Total ~250 lines of dead code removed. - **Wire up**: add `'sequence'` and `'underlay'` to `EditorToolMode` + `TOOL_MODES`, expose them in the toolbar, give the keyboard shortcuts bindings. That's a feature request, not a bug fix — track separately under the open #6/#7/#8/#9/#10 Phase D issues or file a new "Editor needs explicit sequence/underlay tools" feature. **Recommended:** Delete. The actual sequence optimization happens server-side at export time; the per-path reorder would be a UX nicety at best. 2. **Bug 2 — remove "Convert" button (L180-186) or make it round-robin.** Three Node Type buttons already cover corner/smooth/symmetric. The button is redundant. If round-robin is desired, the handler is `onUpdateNodeType(nextType)` where `nextType = current === 'corner' ? 'smooth' : current === 'smooth' ? 'symmetric' : 'corner'`. 3. **Bug 3 — wire Stitch Type and Density to `selectedPath`.** Either: - Add `onStitchTypeChange` / `onDensityChange` props to `EditorRightPanelProps`, lift the handlers to `Editor.tsx`, and call `setPaths(prev => prev.map(p => p.id === selectedPathId ? { ...p, stitchType, density } : p))` — push history too. - Or, since the panel can't actually edit per-path properties meaningfully (they get rewritten by the export pipeline), remove the Path Properties section entirely until a real edit story exists. 4. **Bug 5 — disable the EditorToolbar Settings button (L149-163).** Mirror the EditorHeader fix from #71: ```tsx <button disabled ... title="Settings — coming soon">…</button> ``` With `disabled:opacity-30 disabled:cursor-not-allowed` styling to match the disabled Undo/Redo buttons above. **Cross-references:** #71 (EditorHeader Export/Settings no-op, since fixed), #76 (FAQ reference to non-existent Settings page, since fixed), #88 (orphan region-classifier, deferred+deleted this turn). Same orphan-UI pattern. **Severity:** medium for Bug 1 (170 LOC of misleading UI + relaxed type), low for Bugs 2-5 (cosmetic / dead controls).
Mark 2026-09-14 17:27:43 +00:00
Sign in to join this conversation.
No description provided.