# Thread event

A quiet, centred line in a thread for something that happened rather than something said: "Sam joined", "Switched to the staging environment", "Run stopped by a guardrail". System messages are drawn with it too, so app events and system lines look the same. Text here is the app's own, never model output.

- Registry name: `thread-event` (`@candor/thread-event`)
- Tier: Free (MIT). No licence key needed.
- Docs: https://candor.themethodic.com/docs/thread-event

## Install

```bash
npx candor-ui add thread-event
```

Run `npx candor-ui@latest init` once first (https://candor.themethodic.com/get-started.md). Without the CLI: `npx shadcn@latest add @candor/thread-event`.
It brings in: locale, relative-time, utils.
npm packages: lucide-react@^1.67.0.

## Example

```tsx
"use client"

import { GitBranch, ShieldAlert, UserPlus } from "lucide-react"
import { ThreadEvent } from "@/components/thread-event"

const minutesAgo = (m: number) => new Date(Date.now() - m * 60_000).toISOString()

export default function Example() {
  return (
    <div className="flex max-w-xl flex-col gap-2">
      <ThreadEvent icon={UserPlus} at={minutesAgo(12)}>
        Sam Lee joined the conversation
      </ThreadEvent>
      <ThreadEvent icon={GitBranch}>Switched to the staging environment</ThreadEvent>
      <ThreadEvent icon={ShieldAlert} tone="attention">
        Run stopped: deletes in production need a second person’s sign-off
      </ThreadEvent>
    </div>
  )
}
```

## <ThreadEvent>

Props:

- `icon?: LucideIcon | null | undefined` (default `Info`): The glyph before the text; `null` for none. Default: an info mark.
- `tone?: "quiet" | "attention" | undefined` (default `"quiet"`): "quiet" (the default) or "attention", for an event a reader shouldn't miss.
- `at?: string | undefined`: When it happened, shown after the text as a relative time.
- `timeFormat?: "relative" | DateStyle | undefined`: "relative" (the default) or an absolute "time", "date" or "datetime" in the locale.
- `align?: "center" | "start" | undefined` (default `"center"`): "center" (the default), or "start": a left-aligned line (right-aligned in RTL) with the time at its end.
- `children: React.ReactNode`: What happened, in a short line.
- `className?: string | undefined`

Also takes the props of `Omit<React.ComponentProps<"div">, "children">`.

## Rules for using Candor UI

- Components take plain typed data. Never pass model output as HTML or render it as a link; messages are typed blocks.
- A control that can't be used says why: wrap it in `<Locked reason="…">`, don't just disable it.
- Don't show a value you don't have: leave it out (it renders as —) rather than guess. An estimate is labelled as one.
- Nothing is pre-selected in a decision a person makes, and the agent is named from your app's data, never from model output.
- Your app's words go in `LocaleProvider` (fixed strings) and `TermsProvider` (nouns); entity kinds and agent roles in `EntityKindsProvider` and `AgentRolesProvider`.
