# ReviewThread

> A conversation anchored to lines of a change: comment cards, a suggested change drawn as a small diff, a reply box and Resolve, all plain POST forms that reload the thread's own frame.

```ts
import { ReviewThread } from "@sdxc/ui/app";
```

Open, it shows the excerpt, comments, suggestion and forms; resolved or outdated, it folds into
a closed `<details>` behind one line. Every form is a plain POST, so it works without script and
needs no island; with the page's runtime, `frame` reloads only the thread in place.

## Examples

```tsx
<Frame name={`thread-${thread.id}`} src={`/threads/${thread.id}`}>
	<ReviewThread id={`thread-${thread.id}`} frame={`thread-${thread.id}`} comments={comments}
		replyAction={`/threads/${thread.id}/replies`} resolveAction={`/threads/${thread.id}/resolve`} labels={labels} />
</Frame>
```

```tsx
<ReviewThread resolved resolvedSummary={t("thread.resolvedBy", { name: "ana" })} comments={comments} labels={labels} />
```

## Props

| Prop | Type | Description |
| --- | --- | --- |
| `comments` | `readonly Comment[]` | The thread's comments, oldest first. |
| `resolved?` | `boolean` | The thread is resolved, which folds it to `resolvedSummary`. |
| `resolvedSummary?` | `RemixNode` | The folded line of a resolved thread, such as "ana marked this conversation as resolved". |
| `outdated?` | `boolean` | The lines the thread cites have changed since, which folds it and labels it. |
| `excerpt?` | `Lines` | The code the thread is about, drawn above the comments: on the timeline, and for an outdated thread, whose original lines no longer show in the diff. |
| `suggestion?` | `Suggestion` | A change the reviewer proposes, drawn as a small diff under the comments. |
| `replyAction?` | `string` | Where a reply posts its text (as `body`); omitted, the thread draws no reply box. |
| `resolveAction?` | `string` | Where Resolve and Unresolve post `resolved=true\|false`; omitted, no button. |
| `frame?` | `string` | The named frame the thread renders in, which every form reloads in place. |
| `fields?` | `RemixNode` | Hidden inputs every form carries, such as a CSRF token. |
| `labels` | `Labels` | Every string the thread shows or announces, so it reads in any language. |

Also accepts everything in `Omit<TagProps<"div">, "children">`.

