Overview
Reusable, resolution-aware comments panel for a DiffReviewState session (COR-509 / DR-6). Shows every saved comment by default (including resolved and outdated ones), with an explicit "Unresolved only" filter, plus the session's review note. Standalone-usable next to a bare DiffViewer/SourceDiffViewer, or composed inside the aggregate DiffReview shell.
Props
| Prop | Type | Description |
|---|---|---|
state |
DiffReviewState |
Controlled session state (@lostgradient/editor/diff-review-state). Never mutated directly. |
onStateChange |
(next: DiffReviewState) => void |
Called after every successful edit/delete/resolve/reopen/review-note action. |
readonly |
boolean |
Disables every mutating control; viewing and filtering remain available. Default false. |
defaultFilter |
'all' | 'unresolved' |
Initial filter. Uncontrolled after mount. Default 'all'. |
onNavigate |
(comment: DiffReviewComment) => void |
Called when a person activates a CURRENT comment's "Go to" action — never for an outdated or removed one. The host wires this to whichever diff viewer it owns, calling that viewer's own public focusAnchor/focusFile. Optional; when omitted, "Go to" on a current comment is a no-op. |
class |
string |
Additional class merged onto the root <section>. |
Behavior
- Delete requires confirmation (
ConfirmDialog) and is irreversible once confirmed — it removes the comment from state and from every subsequent export. - Edit/resolve/reopen/delete/review-note dispatch through
reduceDiffReviewState(via the shareddispatchDiffReviewActionhelper); a rejected action never callsonStateChangeand leaves the panel's state untouched. - Outdated comments render an
Outdatedbadge but are never hidden — they remain fully visible and editable/resolvable/deletable like any other comment. A comment whose target has been removed entirely (not merely changed) rendersRemovedinstead. - Every comment has a "Go to" action. For a
currentcomment this callsonNavigate; this component classifies status itself (diff-review-anchor-status.ts, shared withDiffReview) so a standalone host never has to. For anoutdated/removedcomment, "Go to" instead moves DOM focus to that comment's own captured-detail text (its originally captured target label and path) and never callsonNavigate— the diff is never focused for a stale or gone anchor.
Why onStateChange, not onstatechange
The ratified cross-package diff-review contract names this callback onstatechange. This repository's check-prop-conventions gate structurally bans a non-native-passthrough lowercase on* prop (a lowercase on* name must resolve to a real DOM-event handler). @lostgradient/cinder's SourceDiffViewer already established the precedent (onFilesChange, onAnnotationSelectionChange) of keeping the field name and payload exactly as specified while translating only the casing to this repository's house style.
Related
diff-review, review-editor.
When to use
- Building a standalone comment panel next to a `DiffViewer` or `SourceDiffViewer` instance.
- Composing the aggregate `DiffReview` shell, which renders this panel internally.
- Reviewing ProseMirror document threads with author identity — use ReviewEditor's own comment UI instead.
Examples
Read-only review
In read-only mode the filter and review note remain viewable but every mutating control is disabled.
Standalone comments panel
DiffReviewComments next to a DiffViewer, sharing one controlled DiffReviewState.
Reviewing only open feedback
Toggling to the unresolved-only filter hides resolved comments without discarding them.
Props
Name | Type | Default | Description |
|---|---|---|---|
state required | DiffReviewState | Controlled diff-review session state. Never mutated directly. | |
onStateChange required | (next: DiffReviewState) => void | Called whenever a comment/review-note action succeeds. Named onStateChange
(camelCase) rather than the cross-package contract's lowercase
onstatechange: this repository's check-prop-conventions gate
structurally bans a non-native-passthrough lowercase on* prop (see
@lostgradient/cinder's SourceDiffViewer.onFilesChange for the same,
earlier translation) — the field name and payload are otherwise exactly
the contract's. | |
readonly | boolean | false | Disables create/edit/delete/resolve/reopen and review-note editing. Viewing and filtering remain available. |
defaultFilter | 'all' | 'unresolved' | 'all' | Initial comment filter. Uncontrolled after mount — the person can change it locally. |
onNavigate | (comment: DiffReviewComment) => void | Called when a person activates a CURRENT comment's "Go to" action --
never for an outdated or removed one, which instead moves focus to that
comment's own captured-detail text in place. The host uses this to
focus the comment's anchor in whichever diff viewer it owns (through
that viewer's own public focusAnchor/focusFile, e.g.
DiffReview's internal DiffReviewRenderer, or a standalone viewer's
own ref in a host that composes this panel next to one directly). |
No comments yet.