Chat
kai-chat
A full-featured chat UI — thread, composer, and optional header — packaged as a single Shadow DOM web component for any framework.
- Shadow DOM
- 8 events
- Markdown + syntax highlighting
- Model switcher
- Slash-command palette
- Starter suggestions
Preview
Section titled “Preview”Set rich data (arrays, objects) in JavaScript; scalar props work as attributes or properties:
<kai-chat id="chat" style="display:block; height:100vh;"></kai-chat>
<script type="module"> import '@kitn.ai/ui/elements'; const chat = document.getElementById('chat');
chat.messages = [ { id: '1', role: 'user', content: 'How do I center a div?' }, { id: '2', role: 'assistant', content: 'Use `display: grid; place-items: center;`', actions: ['copy', 'like', 'dislike'] }, ];
chat.addEventListener('kai-submit', (e) => { console.log('user sent:', e.detail.value, 'attachments:', e.detail.attachments); }); chat.addEventListener('kai-message-action', (e) => { console.log(e.detail.messageId, e.detail.action); });</script>messages— each entry:id,role('user' | 'assistant'),content(markdown for assistant), plus optionalactions,attachments,reasoning,tools, andavatar.loading— flip totruewhile awaiting a reply; the input disables and a typing indicator appears.- Model switcher — set
models({ id, name, provider? }[]) andcurrentModel; listen forkai-model-change. - Context meter — set
context({ usedTokens, maxTokens, … }) to show a token-usage gauge in the header.
Examples
Section titled “Examples”Basic Thread
Section titled “Basic Thread”Loading State
Section titled “Loading State”Starter Suggestions
Section titled “Starter Suggestions”suggestions — clickable prompts above an empty thread; suggestion-mode="fill" populates the input instead of submitting.
Model Switcher and Header
Section titled “Model Switcher and Header”models + chat-title activates the header bar with a model-switcher dropdown.
Context Token Meter
Section titled “Context Token Meter”Add context to show a live token-usage gauge — yellow near the warning threshold, red near danger.
Slash Commands
Section titled “Slash Commands”slashCommands opens a palette on /; slash-compact uses single-line rows for dense layouts.
| Property | Type | Default | Notes |
|---|---|---|---|
| messages | | [] | The full message thread to render, newest last. Each entry carries its role, content, and optional reasoning/tools/attachments/actions. Set as a JS property (`el.messages = [...]`). |
| value | string | — | Controlled value of the input. When set, the host owns the input text and must update it on `kai-value-change`; leave unset for uncontrolled behavior. |
| placeholder | string | 'Send a message...' | Placeholder text shown in the empty input. |
| loading | boolean | false | When true, shows the loading/streaming state and disables submit (use while awaiting the assistant's reply). |
| suggestions | string[] | — | Starter prompts shown above the input when the thread is empty. Clicking one follows `suggestionMode`. Set as a JS property. |
| suggestionMode | "submit" | "fill" | 'submit' | What clicking a suggestion does: `'submit'` (default) sends it immediately as if typed and submitted; `'fill'` just places it in the input. |
| persistSuggestions | boolean | false | Keep suggestions visible after the conversation starts. By default suggestions are conversation starters and hide once `messages` is non-empty; set this to keep them always shown. Default false. |
| proseSize | "xs" | "sm" | "base" | "lg" | 'sm' | Body/prose font scale for rendered markdown (`'xs' | 'sm' | 'base' | 'lg'`). Defaults to `'sm'`. |
| codeTheme | string | 'github-dark-dimmed' | Shiki theme name for syntax-highlighted code blocks (e.g. `'github-dark-dimmed'`). |
| codeHighlight | boolean | true | Enable Shiki syntax highlighting in code blocks. Turn off to render plain `<pre>` blocks (lighter, no highlighter load). Default true. |
| chatTitle | string | — | Optional header title shown on the left of the header. |
| models | | — | Optional model list. When set (>1 model) a ModelSwitcher is shown in the header and a `kai-model-change` event fires on selection. |
| currentModel | string | — | The currently selected model id (pairs with `models`). |
| context | ContextData | — | Optional context-window token usage. When set, a Context token meter is shown in the header. |
| scrollButton | boolean | true | Show the scroll-to-bottom button inside the scroll area. Default true. |
| headerStart | boolean | — | Whether the host has `slot="header-start"` content (left of the title) — set by the `<kai-chat>` facade so a custom control forces the header open. |
| headerEnd | boolean | — | Whether the host has `slot="header-end"` content (right of the controls). |
| search | boolean | false | Show a Search (Globe) button in the input toolbar; fires a `search` event. |
| voice | boolean | false | Show a Voice (Mic) button in the input toolbar; fires a `voice` event. |
| slashCommands | SlashCommandItem[] | — | Slash commands — when set, typing `/` in the input opens the command palette and fires `kai-slash-select`. Set as a JS property. |
| slashActiveIds | string[] | — | Command ids to highlight as active in the palette. |
| slashCompact | boolean | false | Single-line palette rows. |
| actionsReveal | "always" | "hover" | 'always' | Whether each message's action bar is always visible (`'always'`, default) or only revealed on hover of that message row (`'hover'`). |
Events
Section titled “Events”| Event | Detail | Notes |
|---|---|---|
| kai-message-action | | An action button on a message was clicked. `action` is the built-in name or custom id. |
| kai-model-change | | The header model switcher changed. |
| kai-search | Record<string, never> | The Search button was clicked. |
| kai-slash-select | | A slash command was chosen from the palette. |
| kai-submit | | User submitted a message. |
| kai-suggestion-click | | A suggestion chip was clicked (only in `suggestion-mode="fill"`). |
| kai-value-change | | Fired on every input change. |
| kai-voice | Record<string, never> | The Mic / voice button was clicked. |
Composed from
Section titled “Composed from”This element wraps these SolidJS components — reach for them directly when you need finer control than the props expose.
ChatThread