chat-window
Orchestrating shell that wires chat-thread, chat-input, participant data, and model selection into a composed chat interface.
Overview
The orchestrating shell for chat UIs. chat-window wires together <chat-thread>, <chat-input>, participant data, and an optional model selector into a complete chat interface.
Light DOM, no Shadow DOM. Uses CSS grid with grid-template-rows: auto 1fr auto for header/thread/input layout. The consumer sizes the container; chat-window fills it.
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
endpoint |
URL | - | API endpoint for chat requests |
model |
string | - | Active model; synced with [data-model-select] |
empty-message |
string | Send a message to start. |
Text shown when thread is empty |
AI Chat with Model Selector
The full compose: header with title and model selector, empty thread, and input area. The [data-model-select] dropdown syncs bidirectionally with model.
Support Chat with SSR Messages
Server-rendered messages hydrate on connect. chat-window resolves data-from IDs against the participant map and writes data-from-label for CSS rendering.
Participant Data
Declared via a <script type="application/json" data-participants> block inside chat-window, or set programmatically via the participants setter. Keys are participant IDs used in data-from attributes.
Orchestration Flow
When chat-input:send fires:
- Builds
chat-message[data-role="user"]and appends to thread - Builds
chat-message[data-role="agent"][data-status="typing"]with animated dots - Disables
chat-inputduring fetch - Awaits response from
endpoint - Populates the typing message with real content; removes
data-status - Re-enables
chat-inputand restores focus
The typing indicator and the final response share the same DOM node — no element swap, no flicker.
DOM Structure
Public API
| Member | Type | Description |
|---|---|---|
model |
string (get/set) | Current model; syncs with select |
participants |
Map (get/set) | Participant registry |
clearThread() |
method | Remove all messages |
appendMessage(role, html, from?) |
method | Programmatic message append |
Events
| Event | Detail | Description |
|---|---|---|
chat-window:send |
{ message, typingElement } |
Dispatched when a message is sent and no endpoint is set. Use this for custom transport (WebSocket, worker, etc.). Populate the typing element's chat-bubble with the response. |
chat-window:error |
{ error, status } |
Dispatched when the built-in fetch transport fails. |
chat-window:model-change |
{ model } |
Dispatched when the model selector value changes. |
Participant Identity
The data-participants JSON map uses arbitrary string IDs as keys. User messages are created with data-from="user", and the agent is resolved as the first participant whose role is "agent". Match these conventions in your participant map.
Model Property
The model attribute is synced with the <select data-model-select> at connect time. After connect, use the .model property setter for updates — attribute mutations are not observed.
CSS Variables
| Variable | Default | Description |
|---|---|---|
--chat-window-header-bg |
var(--color-surface) |
Header background |
--chat-window-header-border |
var(--border-width-thin) solid var(--color-border) |
Header bottom border |
Related
<chat-thread>— Scrollable message container<chat-message>— Individual message turns<chat-bubble>— Content bubble wrapper<chat-input>— Form-associated input- Chat Patterns — Launcher, sidebar, and full-page compositions