KQ-1736 · RANGE/REMARKS
Range Remarks
A code review diff where comments cover spans of lines. Pressing in the comment gutter and dragging grows a bracket across the lines you mean — its live end under the pointer 1:1, the lines tinting as it passes them — and on release the end settles onto the last line's edge on springs.snap with the throw's velocity, then a comment box unfolds under the range, its measured height opening on springs.glide as it swings down from its top edge. Existing threads sit after their last line with their bracket in the gutter, brighten with their lines on hover or focus, carry suggested changes as mini diffs, and fold to a one-line summary on glide when resolved or outdated. The diff is a role="grid" with one roving line: Up and Down move, Shift with an arrow grows the same bracket a line at a time, Enter or C opens the box and Escape clears; long lines wrap below a 30rem container.
fieldline/uploader/src/retry/backoff.ts
+6−3· 2 openUp and Down move between lines. Shift with an arrow selects a range. Enter or C comments on it, Escape clears it. In a comment box, Control or Command with Enter posts.
no lines selected · 2 open threads
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/range-remarks
Props
- diff
- RangeDiff
- default defaultRangeDiff
- The file: { path, lines: { kind: "context" | "add" | "del", text, old?, new? }[] }; missing line numbers are counted from the top.
- threads / defaultThreads
- RangeThread[]
- default — / defaultRangeThreads
- Threads as { id, start, end (line indexes), comments, resolved?, outdated?, suggestion? }, controlled or initial.
- onThreadsChange
- (threads) => void
- default —
- Fires with every thread after a comment, a reply or a resolve.
- selection / defaultSelection / onSelectionChange
- { start, end } | null
- default — / null
- The selected range of lines, controlled or initial, and the callback from the drag or key that changed it.
- onComment
- (range, text, threadId?) => void
- default —
- A comment was posted on a range — a new thread, or a reply when `threadId` is given.
- onSuggest
- (range, suggestion, text) => void
- default —
- A suggested change was posted on a range, with its replacement text and optional comment.
- onResolve
- (threadId, resolved) => void
- default —
- A thread was resolved (true) or reopened (false).
- bracketStyle
- "bracket" | "bar" | "brace"
- default "bracket"
- A square bracket with caps, a solid rounded bar, or a curly brace whose nose points at the range's middle.
- density
- "compact" | "regular" | "roomy"
- default "regular"
- Line height (18/20/24px) and code type size.
- editorTheme
- "plain" | "paper" | "night"
- default "plain"
- The page's own surfaces, a warm paper tint, or a dark editor in either page theme (the accent's hue at fixed lightness).
- wrap
- "auto" | "always" | "never"
- default "auto"
- Wrap long lines below a 30rem container, always, or never (the diff scrolls sideways instead).
- author
- string
- default "Noor Haddad"
- The name new comments are posted under.
- now
- number | Date
- default defaultRangeNow
- The moment relative times count from, so server and browser render the same text.
- status
- "ready" | "loading" | "error"
- default "ready"
- Loading shows skeleton lines; error shows Try again.
- onRetry
- () => void
- default —
- Try again was pressed after the diff failed to load.
- height
- number
- default 540
- The surface's height in px; the diff scrolls inside it.
- disabled
- boolean
- default false
- Read only: threads can be read and expanded, nothing posted or resolved.
- className
- string
- default —
- Classes for the surface.
| Prop | Type | Default | Description |
|---|---|---|---|
| diff | RangeDiff | defaultRangeDiff | The file: { path, lines: { kind: "context" | "add" | "del", text, old?, new? }[] }; missing line numbers are counted from the top. |
| threads / defaultThreads | RangeThread[] | — / defaultRangeThreads | Threads as { id, start, end (line indexes), comments, resolved?, outdated?, suggestion? }, controlled or initial. |
| onThreadsChange | (threads) => void | — | Fires with every thread after a comment, a reply or a resolve. |
| selection / defaultSelection / onSelectionChange | { start, end } | null | — / null | The selected range of lines, controlled or initial, and the callback from the drag or key that changed it. |
| onComment | (range, text, threadId?) => void | — | A comment was posted on a range — a new thread, or a reply when `threadId` is given. |
| onSuggest | (range, suggestion, text) => void | — | A suggested change was posted on a range, with its replacement text and optional comment. |
| onResolve | (threadId, resolved) => void | — | A thread was resolved (true) or reopened (false). |
| bracketStyle | "bracket" | "bar" | "brace" | "bracket" | A square bracket with caps, a solid rounded bar, or a curly brace whose nose points at the range's middle. |
| density | "compact" | "regular" | "roomy" | "regular" | Line height (18/20/24px) and code type size. |
| editorTheme | "plain" | "paper" | "night" | "plain" | The page's own surfaces, a warm paper tint, or a dark editor in either page theme (the accent's hue at fixed lightness). |
| wrap | "auto" | "always" | "never" | "auto" | Wrap long lines below a 30rem container, always, or never (the diff scrolls sideways instead). |
| author | string | "Noor Haddad" | The name new comments are posted under. |
| now | number | Date | defaultRangeNow | The moment relative times count from, so server and browser render the same text. |
| status | "ready" | "loading" | "error" | "ready" | Loading shows skeleton lines; error shows Try again. |
| onRetry | () => void | — | Try again was pressed after the diff failed to load. |
| height | number | 540 | The surface's height in px; the diff scrolls inside it. |
| disabled | boolean | false | Read only: threads can be read and expanded, nothing posted or resolved. |
| className | string | — | Classes for the surface. |