diff --git a/codev/plans/1107-preview-inline-comment-composer.md b/codev/plans/1107-preview-inline-comment-composer.md new file mode 100644 index 000000000..c01929534 --- /dev/null +++ b/codev/plans/1107-preview-inline-comment-composer.md @@ -0,0 +1,222 @@ +# Plan — #1107: Inline composer for preview-pane review comments + +> PIR plan. The GitHub issue (#1107) is the implicit spec. This document is the +> **plan-approval** artifact: how the change is built, where it lands, the risks, +> and the test plan. Reviewed before any code is written. + +## Understanding + +Adding a review comment from the Codev Markdown Preview +(`codev.openMarkdownPreview`) currently collects the comment body with +`vscode.window.showInputBox` — rendered in VS Code's center-top Quick Pick +chrome, physically far from the block the user clicked `+` on. The cognitive +distance between the block being commented on and the input box is the friction +the issue targets. The issue recommends **Option A**: render an inline composer +in the webview/canvas itself, co-located with the block, so the visual anchor is +preserved end-to-end while typing. + +What the codebase already gives us: + +- `packages/artifact-canvas/src/components/ArtifactCanvas.tsx` is the shared React + canvas. It renders a React overlay with the `CommentAffordance` (`+`) button + anchored at the active block's vertical center (`overlayTop`); the `+` calls + `onAddComment(line)` — the intent-only seam (spec 945 D6). The host then runs the + text input and write-back. +- The **read-only comment cards** (existing comments) are injected imperatively as + **in-flow DOM siblings directly below the block** (`.codev-canvas-marker-cards`, + built in `buildMarkerCards` and inserted via `el.after(...)` in the `[html, + markers]` effect). They sit in normal flow and push following content down. +- **Decision (reviewer, 2026-06-30): the composer renders in the same in-flow + location as those read-only cards** — directly below the block, where the comment + will live after submit — rather than in the left-gutter overlay. This keeps the + add flow visually consistent with the existing card pattern and sets the precedent + #1055 (edit mode) will reuse. To stay React-owned (clean state / focus / Esc) while + living in the innerHTML-managed body, the composer mounts via **`ReactDOM.createPortal` + into an in-flow placeholder element** injected below the block — the standard + React-into-imperative-DOM pattern. +- `packages/core/src/review-markers.ts` `serializeReviewMarker` **already + normalizes the body to a single line** (`body.replace(/\s+/g, ' ').trim()`). So + a multi-line composer is purely an input ergonomics improvement; the on-disk + marker form is unchanged. **No marker-format change is in scope** — #1055 owns + the v2 format. Newlines typed in the composer collapse to spaces on write, + matching today's single-line `` convention. + +So the work is: move the text input from the host's Quick Pick into a +React composer in the canvas overlay, and widen the comment-intent seam to carry +the collected text. + +## Proposed change + +### 1. New composer component (artifact-canvas package) + +Add `packages/artifact-canvas/src/overlays/CommentComposer.tsx`: a small +React component — a `