Orbeez kit
Conversation

Chat timeline

<ChatTimeline />
A rail down the side of a long conversation: a bead rolls to the turn being read, and each mark jumps to its turn.
Sketch the data model for a reading list app.
Done. Here is what changed, with a note on anything worth a second look before it ships. It kept the old names where it could, so nothing that calls into this has to change yet.
Add tags, and let a book have more than one.
Done. Here is what changed, with a note on anything worth a second look before it ships. It kept the old names where it could, so nothing that calls into this has to change yet.
Write the API routes for books and tags.
Done. Here is what changed, with a note on anything worth a second look before it ships. It kept the old names where it could, so nothing that calls into this has to change yet.
Add search by title, author and tag.
Done. Here is what changed, with a note on anything worth a second look before it ships. It kept the old names where it could, so nothing that calls into this has to change yet.
Write tests for the search.
Done. Here is what changed, with a note on anything worth a second look before it ships. It kept the old names where it could, so nothing that calls into this has to change yet.
Make a first pass at the list page.
Done. Here is what changed, with a note on anything worth a second look before it ships. It kept the old names where it could, so nothing that calls into this has to change yet.

Install

bash
npx shadcn@latest add https://orbeez-kit.vercel.app/r/chat-timeline.json

Usage

tsx
<ChatContainer>
  <ChatContainerContent>
    {turns.map((t) => (
      <Message key={t.id} from="user" data-timeline={t.id}>…</Message>
    ))}
  </ChatContainerContent>
  <ChatTimeline items={turns.map((t) => ({ id: t.id, label: t.prompt, mood: t.mood }))} />
</ChatContainer>

Good to know

  • Moods. The bead on the rail wears the mood of the turn you're reading: working while it runs, sad if it was stopped.
  • Mark each turn with data-timeline={id}; the rail finds them inside its ChatContainer.
  • Hover or focus a mark to see what was asked there. A jump lets go of the bottom, as scrolling up would.
  • It floats over the column and moves only by transform. With more turns than fit, the marks close up rather than the rail growing.
  • Leave room on the right of the column for it, or hide it on narrow screens.