Resizable split layout
Put a sidebar conversation list next to a chat pane and let the user resize both. Drag the divider to redistribute space, or flip the sidebar to the opposite side with the toggle above the demo.
How it works
Section titled “How it works”<kai-resizable> lays out its <kai-resizable-item> children along a horizontal (or vertical) axis and inserts a draggable divider between each pair. Set size, min, and max on each item to constrain the sidebar; the main pane flexes to fill the rest.
<kai-resizable orientation="horizontal" style="display:block;height:100%"> <!-- sidebar --> <kai-resizable-item size="25%" min="180px" max="340px"> <kai-conversations id="conv"></kai-conversations> </kai-resizable-item>
<!-- main chat --> <kai-resizable-item> <kai-chat id="chat"></kai-chat> </kai-resizable-item></kai-resizable>
<script type="module"> import '@kitn.ai/ui/elements';
const conv = document.getElementById('conv'); const chat = document.getElementById('chat');
// Assign arrays and objects in JavaScript — they can't be HTML attributes. conv.conversations = [ { id: 'c1', title: 'Web component architecture', scope: { type: 'document' }, messageCount: 12, lastMessageAt: new Date().toISOString(), updatedAt: new Date().toISOString(), }, ]; conv.activeId = 'c1';
chat.messages = [];
conv.addEventListener('kai-conversation-select', (e) => { // load the selected conversation's messages into chat console.log('selected', e.detail.id); });
chat.addEventListener('kai-submit', async (e) => { const prompt = e.detail.value; const aId = crypto.randomUUID(); chat.messages = [ ...chat.messages, { id: crypto.randomUUID(), role: 'user', content: prompt }, { id: aId, role: 'assistant', content: '' }, ]; chat.loading = true; // stream tokens into the assistant message for await (const token of streamFromYourModel(prompt)) { chat.messages = chat.messages.map((m) => m.id === aId ? { ...m, content: m.content + token } : m, ); } chat.loading = false; });</script>To put the sidebar on the right, reverse the child order — put <kai-resizable-item> (chat) first, then <kai-resizable-item> (conversations).
<kai-resizable> fires kai-change with { sizes: number[] } (percent) on each drag-end so you can persist or react to the panel sizes.
Next steps
Section titled “Next steps”kai-conversationsreference —groups,conversations,activeId, and thekai-conversation-selectevent.kai-chatreference — the full thread + input element, including models, context meter, and slash commands.- Drop-in chat — the streaming loop that drives the chat pane.
- Workspace app — the same sidebar + thread composed into a complete app.