Skip to content
kerfjsGitHub

CommentThread

A run of comments with a reply field and Resolve.

SourcePackage @kerf-js/veneer

Preview

tsx
import { state } from '@kerf-js/core'import { CommentThread } from '@kerf-js/veneer'import type {  Peer,  CommentThreadData} from '@kerf-js/veneer'export function Reply() {  const thread = state(COMMENT_TIMEOUTS)  const reply = (text: string) =>    (thread.value = {      ...thread.value,      comments: [        ...thread.value.comments,        newComment(text),      ],    })  return (    <CommentThread      thread={thread}      onReply={reply}    />  )}const PEOPLE = [  {    id: 'mara',    name: 'Mara Lindqvist',    email: 'mara@kerf.dev',    role: 'Owner',    team: 'Platform',    initials: 'ML',  },  {    id: 'jun',    name: 'Jun Tanaka',    email: 'jun@kerf.dev',    role: 'Admin',    team: 'Platform',    initials: 'JT',  },  {    id: 'priya',    name: 'Priya Raman',    email: 'priya@kerf.dev',    role: 'Member',    team: 'Web',    initials: 'PR',  },  {    id: 'tomas',    name: 'Tomás Oliveira',    email: 'tomas@kerf.dev',    role: 'Member',    team: 'Web',    initials: 'TO',  },  {    id: 'lena',    name: 'Lena Fischer',    email: 'lena@kerf.dev',    role: 'Member',    team: 'Data',    initials: 'LF',  },  {    id: 'noor',    name: 'Noor Haddad',    email: 'noor@kerf.dev',    role: 'Viewer',    team: 'Data',    initials: 'NH',  },  {    id: 'sam',    name: 'Sam Okafor',    email: 'sam@kerf.dev',    role: 'Member',    team: 'Mobile',    initials: 'SO',  },  {    id: 'ines',    name: 'Inés Vidal',    email: 'ines@kerf.dev',    role: 'Viewer',    team: 'Mobile',    initials: 'IV',  },]const PEERS: Peer[] = PEOPLE.map((p, i) => ({  id: p.id,  name: p.name,  color: i + 1,}))const [  MARA,  JUN,  PRIYA,  TOMAS,  LENA,  NOOR,  SAM,  INES,] = PEERS as [  Peer,  Peer,  Peer,  Peer,  Peer,  Peer,  Peer,  Peer,]const COMMENT_TIMEOUTS: CommentThreadData = {  id: 'c-timeouts',  comments: [    {      id: 'a',      author: LENA,      time: '10:12',      text:        'Should this say 30 seconds? ' +        'The stale window changed on ' +        'Friday.',    },    {      id: 'b',      author: JUN,      time: '10:20',      text:        'Yes. d-4817 lowered it, I ' +        'will update the number.',    },  ],}const newComment = (text: string) => ({  id: text,  author: MARA,  time: 'Now',  text,})

Installation

npm install @kerf-js/veneer

Usage

tsx
import { CommentThread } from '@kerf-js/veneer'

Resolved

It folds to one line with Reopen.

tsx
import { CommentThread } from '@kerf-js/veneer'import type {  Peer,  CommentThreadData} from '@kerf-js/veneer'export function Resolved() {  return (  <CommentThread thread={RESOLVED} />  )}const PEOPLE = [  {    id: 'mara',    name: 'Mara Lindqvist',    email: 'mara@kerf.dev',    role: 'Owner',    team: 'Platform',    initials: 'ML',  },  {    id: 'jun',    name: 'Jun Tanaka',    email: 'jun@kerf.dev',    role: 'Admin',    team: 'Platform',    initials: 'JT',  },  {    id: 'priya',    name: 'Priya Raman',    email: 'priya@kerf.dev',    role: 'Member',    team: 'Web',    initials: 'PR',  },  {    id: 'tomas',    name: 'Tomás Oliveira',    email: 'tomas@kerf.dev',    role: 'Member',    team: 'Web',    initials: 'TO',  },  {    id: 'lena',    name: 'Lena Fischer',    email: 'lena@kerf.dev',    role: 'Member',    team: 'Data',    initials: 'LF',  },  {    id: 'noor',    name: 'Noor Haddad',    email: 'noor@kerf.dev',    role: 'Viewer',    team: 'Data',    initials: 'NH',  },  {    id: 'sam',    name: 'Sam Okafor',    email: 'sam@kerf.dev',    role: 'Member',    team: 'Mobile',    initials: 'SO',  },  {    id: 'ines',    name: 'Inés Vidal',    email: 'ines@kerf.dev',    role: 'Viewer',    team: 'Mobile',    initials: 'IV',  },]const PEERS: Peer[] = PEOPLE.map((p, i) => ({  id: p.id,  name: p.name,  color: i + 1,}))const [  MARA,  JUN,  PRIYA,  TOMAS,  LENA,  NOOR,  SAM,  INES,] = PEERS as [  Peer,  Peer,  Peer,  Peer,  Peer,  Peer,  Peer,  Peer,]const COMMENT_OWNER: CommentThreadData = {  id: 'c-owner',  comments: [    {      id: 'c',      author: PRIYA,      time: 'Mon',      text:        'Who signs off on the rollback ' +        'rule, Mara or the on-call ' +        'person?',    },  ],}const RESOLVED = {  ...COMMENT_OWNER,  resolved: true,}

Accessibility

Enter
Sends the reply

API Reference

PropTypeDefaultDescription
threadLive<CommentThreadData>—The thread.
activebooleanfalseRaises it.
EventTypeDefaultDescription
onReply((text: string) => void)—Called with the text.
onResolve((resolved: boolean) => void)—Called when it is resolved or reopened.

Parts

Every element carries a stable name, so you can style it from your own CSS: [data-scope="comment-thread"] [data-part="reply"]

replycommentsr-only

RelatedComment railComment anchor