Thread List
An inbox of conversations. Unread is carried by weight and a count, not by colour alone, and the timestamp coarsens with age — a message from March does not need a clock time.
src/components/ui/thread-list.tsxAbout
From the component's own source, where it was written.
A conversation list — inbox, DMs, support threads.
Unread is carried by weight and a dot, never by colour alone. A list where unread rows are simply a shade darker is unreadable to a good share of people and invisible in bright sunlight, which is where phones are used.
The preview is the last message regardless of who sent it, prefixed with "You:" when it was yours. A list that only previews incoming messages leaves a thread you just replied to looking untouched.
Install
npx astralyx-ui add thread-list
Usage
import { ThreadList } from '@/components/ui/thread-list'
<ThreadList threads={threads} selected={id} onSelect={setId} />Composer
Change the props and the source below follows.
<ThreadList threads={threads} selected={id} onSelect={setId} />Examples
Selectable inbox
const [selected, setSelected] = useState('t1')
<ThreadList threads={threads} selected={selected} onSelect={setSelected} />API
Generated from the source, so it cannot fall behind the code. One table per exported component, then hooks, functions and types.
ThreadList
A conversation list — inbox, DMs, support threads.
Extends Omit<ComponentProps<'div'>, 'onSelect'>.
| Prop | Type | Default | Description |
|---|---|---|---|
| threads | Thread[] | required | { id, title, preview?, fromMe?, at?, unread?, participants?, attachments?, muted? }. |
| selected | string | — | — |
| onSelect | (id: string) => void | — | — |
| now | Date | — | — |
| locale | string | 'en-GB' | — |
| emptyLabel | ReactNode | 'No conversations' | — |
Types
Thread
| Field | Type | Description |
|---|---|---|
| id | string | — |
| title | ReactNode | — |
| preview? | ReactNode | Last message, whoever sent it. |
| fromMe? | boolean | Prefixes the preview with "You:", which is how you tell "they replied" from "you are waiting" at a glance. |
| at? | Date | — |
| unread? | number | A count, not a boolean. Two unread and forty unread are different situations, and the badge is what makes the row legible in monochrome. |
| participants? | string[] | — |
| avatar? | ReactNode | — |
| attachments? | number | — |
| badge? | ReactNode | — |
| muted? | boolean | Dims the row and suppresses the unread emphasis without hiding the count. |
Behaviour
| Topic | Detail | Description |
|---|---|---|
| timestamps | coarsening | Time today, weekday this week, date beyond that. Precision that stops being useful stops being shown. |