Review Thread
A review conversation anchored to a line of code, with the line shown as context. Resolving is always a callback — a resolved thread is server truth other reviewers see.
src/components/ui/review-thread.tsxAbout
From the component's own source, where it was written.
A review conversation anchored to a line of code.
The anchor is rendered as context above the comments — a thread detached from the line it is about is unreadable, and re-finding that line is the main cost of reviewing in a browser.
Resolving is a callback, never local state. A resolved thread is server truth that other reviewers see; a component that hid it locally would show two people different threads on the same diff.
Install
npx astralyx-ui add review-thread
Usage
import { ReviewThread } from '@/components/ui/review-thread'
<ReviewThread
path="src/lib/styles.ts"
line={68}
snippet=" xs: 'h-7 gap-1.5 px-3.5 text-xs',"
comments={comments}
onReply={reply}
onResolve={resolve}
/>Composer
Change the props and the source below follows.
xs: 'h-7 gap-1.5 px-3.5 text-xs',- Grace HopperGrace Hopper2h agoShould this opt out of the squircle so it reads as a true pill?
- Ada LovelaceAda Lovelace1h agoPendingYes — a squircle at 50% looks like a rounded rectangle at this size.
<ReviewThread
path="src/lib/styles.ts"
line={68}
comments={comments}
resolved={false}
onResolve={resolve}
/>Examples
Thread
<ReviewThread path="src/lib/styles.ts" line={68} comments={comments} onReply={reply} onResolve={resolve} />API
Generated from the source, so it cannot fall behind the code. One table per exported component, then hooks, functions and types.
ReviewThread
Extends Omit<ComponentProps<'div'>, 'onSubmit'>.
| Prop | Type | Default | Description |
|---|---|---|---|
| path | string | — | The anchor. A thread detached from its line is unreadable, and re-finding that line is the main cost of reviewing in a browser. |
| line | number | — | The anchor. A thread detached from its line is unreadable, and re-finding that line is the main cost of reviewing in a browser. |
| snippet | string | — | The anchor. A thread detached from its line is unreadable, and re-finding that line is the main cost of reviewing in a browser. |
| comments | ReviewComment[] | required | { id, author, body, time?, pending? }. |
| resolved | boolean | false | Resolution is never local state — it is shared truth, so the component only reports the intent. |
| onResolve | () => void | — | Resolution is never local state — it is shared truth, so the component only reports the intent. |
| onReply | (body: string) => void | — | Adds the reply box. Omit it for a read-only thread. |
| resolvedLabel | ReactNode | 'Resolved' | — |
| pendingLabel | ReactNode | 'Pending' | Badge on a comment awaiting a reply. |
| replyLabel | ReactNode | 'Reply' | — |
| replyPlaceholder | string | 'Reply…' | — |
| replyFieldLabel | string | 'Reply to thread' | Accessible name for the reply field. |
| resolveLabel | ReactNode | 'Resolve' | — |
Types
ReviewComment
A review conversation anchored to a line of code.
| Field | Type | Description |
|---|---|---|
| id | string | — |
| author | string | — |
| body | ReactNode | — |
| time? | ReactNode | — |
| pending? | boolean | Marks the review that requested changes. |