Use a workspace
<kai-workspace> is a layout shell: five slots (header, start, main, end, footer), resize handles between the columns, per-aside collapse, a collapse breakpoint, and a mobile drawer mode. It knows nothing about chat. You slot <kai-conversations> and <kai-chat> into it, and you drive those parts directly.
<kai-workspace collapse-below="720" drawer-below="640" style="display:block; height:100dvh;"> <kai-conversations slot="start"></kai-conversations> <kai-chat></kai-chat></kai-workspace>
<script type="module"> import '@kitn.ai/ui/elements';
const rail = document.querySelector('kai-conversations'); const chat = document.querySelector('kai-chat');
// Arrays are JS properties, never attributes; reassign a NEW array to re-render. rail.conversations = await api.listConversations(); chat.messages = [];
rail.addEventListener('kai-conversation-select', async (e) => { rail.activeId = e.detail.id; chat.messages = await api.loadThread(e.detail.id); });
chat.addEventListener('kai-submit', (e) => send(e.detail.value));</script>Unnamed children land in the main region; slot="main" works too. The end aside is for an inspector, notes, or a preview pane, and the header/footer bands span the full shell width. Every region renders only when you project content into it.
Layout behavior
Section titled “Layout behavior”- Resize. A drag handle sits beside each aside. Widths are CSS custom properties, not props:
--kai-workspace-start-width(280px),--kai-workspace-start-min-width(200px),--kai-workspace-start-max-width(480px), and the--kai-workspace-end-*trio (320px / 200px / 480px). Each resize fireskai-aside-resizewith{ side, width }. - Collapse.
startCollapsed/endCollapsedare controlled props (JS properties);default-start-collapsed/default-end-collapsedseed the uncontrolled state from HTML.collapse-belowauto-collapses both asides when the shell narrows past it. Every change fireskai-aside-togglewith{ side, collapsed }. - Drawer. Below
drawer-below, an expanded aside paints as an overlay drawer above the main region. Escape inside it closes it and returns focus to the opener. - Methods.
toggleAside(side),collapseAside(side),expandAside(side), withsidebeing'start'or'end'.
start and end are logical: on an RTL page, start is the right column.
BREAKING: migrating from the chat preset
Section titled “BREAKING: migrating from the chat preset”Before the 2026-08-20 re-cast, <kai-workspace> was a chat preset that took messages, conversations, and 30 other props. That surface is gone; there is no back-compat alias. The fastest migration is to regenerate the composition: the kai MCP scaffold tool’s workspace archetype emits the shell with the parts wired. To migrate by hand, move each prop to the part that owns it now:
Old <kai-workspace> prop | Where it lives now |
|---|---|
conversations, activeId, groups, noConversations | your own <kai-conversations slot="start"> |
messages, loading, proseSize, codeTheme, codeHighlight, chatTitle, scrollButton, cardTypes, cardSchemas | your own <kai-chat> in the main region |
value, placeholder, suggestions, suggestionMode, voice, triggers, kindIcons, search (renamed webSearch) | the composer surface on <kai-chat> or <kai-prompt-input> |
models, currentModel, context | header chrome you slot (a model picker is a part in a slot, not three orchestrator props) |
sidebarWidth, sidebarMinWidth, sidebarMaxWidth | the --kai-workspace-start-* custom properties |
sidebarCollapsed, defaultSidebarCollapsed | startCollapsed / defaultStartCollapsed (the end aside has its own pair) |
collapseBelow | kept, now collapsing both asides |
compact | kept as a reflected density hint; the rail’s row density is <kai-conversations>’ own compact |
theme | unchanged, as on every element |
Events moved with their owners: listen for kai-conversation-select and kai-new-chat on <kai-conversations>, for kai-submit, kai-message-action, kai-model-change, kai-value-change, kai-suggestion-click, kai-voice, and kai-web-search (was kai-search) on <kai-chat>. The shell itself fires only kai-aside-toggle (was kai-sidebar-toggle, now with a side) and kai-aside-resize. The old sidebar methods toggleSidebar() / collapseSidebar() / expandSidebar() are toggleAside(side) / collapseAside(side) / expandAside(side), and the thread methods (focus(), clear(), send(), scrollToBottom()) live on your <kai-chat>.
What’s next
Section titled “What’s next”- Compose your own shell for a layout the shell’s five regions cannot express, built from the same parts.
kai-workspacereference for every slot, part, prop, and event.