# Conversations

A sidebar conversation list with grouping, active highlighting, and a "New chat" button — the building block for any chat history panel.

<p class="kai-tag-sub">kai-conversations</p>

A self-contained sidebar that renders a grouped, scrollable conversation list with a "New chat" button and collapse toggle — drop it into any framework and wire up three events.

## Preview

> **tip:** 
Use `<kai-conversations>` for a conversation switcher outside SolidJS — React, Vue, Svelte, or plain HTML. Shadow DOM keeps styles isolated in both directions. In SolidJS with fine-grained layout needs, compose the `ConversationList` primitive directly.

## Usage

Set the data in JavaScript (it's arrays and objects) and listen for CustomEvents:

```html
<kai-conversations id="sidebar" style="display:block; width:300px; height:100vh;"></kai-conversations>

<script type="module">

  await customElements.whenDefined('kai-conversations');

  const el = document.getElementById('sidebar');

  el.conversations = [
    {
      id: 'c-1', title: 'Web component architecture',
      scope: { type: 'collection' }, messageCount: 12,
      lastMessageAt: '2026-06-16T10:00:00.000Z',
      updatedAt: '2026-06-16T10:00:00.000Z',
    },
  ];
  el.activeId = 'c-1';

  el.addEventListener('kai-conversation-select', (e) => {
    el.activeId = e.detail.id; // keep the active highlight in sync
  });
  el.addEventListener('kai-new-chat', () => console.log('new chat'));
  el.addEventListener('kai-toggle-sidebar', () => console.log('toggled'));
</script>
```

**Two data approaches:**

- **In JavaScript** — `el.conversations` is the rows; `el.groups` is the section headers. They work together, not as alternatives: each row lands in the group whose `id` matches its `groupId`, and anything with no match falls into a single **Ungrouped** section. Leave `groups` empty and the whole list renders as one Ungrouped section.
- **Declarative children** — nest `<kai-conversation>` tags directly; each carries its `id` as an attribute and title as text content. The element reads them on mount and watches via MutationObserver — works in plain HTML, SSR, or any framework that sets innerHTML.

## Examples

### Default List

A flat `conversations` array with no `groups` — every row renders in one Ungrouped section.

### Active Conversation Highlighted

`activeId` highlights the matching row and scrolls it into view.

### Pre-bucketed Groups

Supply `groups` for the section headers and give each conversation a matching `groupId`; anything unmatched falls to the "Ungrouped" section.

### Empty State

An empty `conversations` array renders the built-in empty state.

### Declarative Children

Nested `<kai-conversation>` elements — no JavaScript wiring needed.

## Slots

Replace the title bar or the empty state, or add a footer row (account, settings, usage). The slot names mirror `<kai-chat>`, so the two compose with one vocabulary.

## Props

## Events

## Methods

## Composed from
