Chat Shell — Composition Pattern

chat-shell cluster-namespaced

The canonical composition pattern for an LLM chat surface. Built from cluster-namespaced bespoke children — every structural part has its own custom element. The legacy raw-HTML form (raw <header> with data-chat-name / data-chat-status, <section data-chat-messages>, <empty-state-ui data-chat-empty>, <footer> wrapping <chat-input-ui>) was retired in v0.4.0 per ADR-0024; new code uses the bespoke shape exclusively per ADR-0023.

Canonical hierarchy

For the full live demo + state-as-attribute documentation, see /site/components/chat-shell. This page is the pattern hub.

<chat-shell provider="anthropic" model="claude-sonnet-4-7" proxy-url="/api/llm"> <!-- Header — name + status indicator --> <chat-header> <span slot="name">Claude</span> <chat-status slot="status">Connected</chat-status> </chat-header> <!-- Streaming message thread (with optional empty state) --> <chat-thread> <chat-empty> <empty-state-ui icon="chat-circle" heading="Hello!" description="Ask me anything."></empty-state-ui> </chat-empty> </chat-thread> <!-- Composer wraps the input primitive --> <chat-composer> <chat-input-ui placeholder="Message…"></chat-input-ui> </chat-composer> </chat-shell>

Part-by-part reference

PartRole
<chat-shell> Behavior-only host. Wires LLM streaming, markdown rendering, code-block upgrades, the proxy-url integration path.
<chat-header> Top band — slots: name, status, action.
<chat-thread> Streaming message list. Reflects [streaming].
<chat-empty> Empty-state hint inside <chat-thread> before the first message.
<chat-composer> Input area. Wraps <chat-input-ui>.
<chat-sidebar> Optional conversation-list / inspector rail (slot="leading" or slot="trailing").

With sidebar — conversation list

For a multi-conversation surface, add a <chat-sidebar slot="leading"> with a <nav-ui> of past chats.

<chat-shell> <chat-sidebar slot="leading"> <chat-topbar slot="header"> <span slot="heading">Conversations</span> <button-ui slot="action" text="+ New" variant="primary" size="sm"></button-ui> </chat-topbar> <nav-ui> <nav-item-ui text="Today's chat" selected></nav-item-ui> <nav-item-ui text="API design review"></nav-item-ui> <nav-item-ui text="Architecture proposal"></nav-item-ui> </nav-ui> </chat-sidebar> <chat-header>...</chat-header> <chat-thread>...</chat-thread> <chat-composer>...</chat-composer> </chat-shell>

Authoring rules

Where to next