I9kChat โ
The shell of a scripted chat: a feature panel with a header (Nino, the bot name and actions), a scrolling live log of bubbles, and a sunken footer tray for the answer controls.
ts
import { I9kChat } from '@9klabs/design';Examples โ
A scripted conversation โ
๐ Hi! A few quick questions, then a ballpark price.
What are you looking to build?
You: AI automation
How many of your systems does it connect to?
vue
<I9kChat title="9k Labs" log-label="Conversation">
<template #actions><I9kButton size="sm" variant="link">โบ Start over</I9kButton></template>
<I9kChatBubble>๐ Hi! A few quick questions, then a ballpark price.</I9kChatBubble>
<I9kChatBubble>What are you looking to build?</I9kChatBubble>
<I9kChatBubble from="user" speaker-label="You">AI automation</I9kChatBubble>
<I9kChatBubble>How many of your systems does it connect to?</I9kChatBubble>
<template #footer>
<I9kChatOptions label="How many of your systems does it connect to?">
<I9kButton>0โ1</I9kButton>
<I9kButton>2โ3</I9kButton>
<I9kButton>4 or more</I9kButton>
</I9kChatOptions>
</template>
</I9kChat>Typing, with a free-text answer โ
Got it. And what's your name?
vue
<I9kChat title="Ismail" log-label="Conversation" expression="thinking">
<I9kChatBubble>Got it. And what's your name?</I9kChatBubble>
<I9kChatBubble typing typing-label="Typing" />
<template #footer>
<I9kChatComposer v-model="name" label="Your name" placeholder="Your name" />
</template>
</I9kChat>Watch out โ
- Presentation only: the conversation state, branching and validation stay in your page.
- Call the exposed scrollToEnd() after adding a bubble; the log scrolls inside the panel.
- Set
expandedonce a tall result is shown so it is not clipped by the log height cap. - The footer tray only renders when the footer slot has content.
API โ
Props โ
| Prop | Type | Default | Required |
|---|---|---|---|
logLabel | string | โ | yes |
title | string | '' | no |
expression | I9kNinoExpression | 'idle' | no |
expanded | boolean | false | no |
Slots โ
avataractionsdefaultfooter
Types โ
ts
export type I9kNinoExpression = (typeof I9K_NINO_EXPRESSIONS)[number];Agent prompt โ
Paste this into an agent to have it use the component correctly. It is self-contained.
text
Use I9kChat from @9klabs/design to render a guided, scripted conversation (an estimator, an intake form told as a chat). It is presentation only: your page owns the questions, answers, validation and analytics, and passes every string translated.
import { I9kChat, I9kChatBubble, I9kChatOptions, I9kChatComposer } from '@9klabs/design';
Props:
- logLabel: string (required) โ accessible name of the role="log" region.
- title?: string โ the bot name in the header.
- expression?: I9kNinoExpression (default 'idle') โ Nino's face, e.g. 'thinking' while the bot types, 'happy' when done.
- expanded?: boolean (default false) โ lifts the log's height cap (min(60vh, 34rem)) so a final result is never clipped.
Slots:
- default โ the I9kChatBubble list.
- avatar โ replaces Nino in the header.
- actions โ header end, e.g. a "Start over" link button.
- footer โ the answer tray (I9kChatOptions or I9kChatComposer). Leave it empty when nothing is being asked and the tray is not rendered.
Exposes: scrollToEnd() โ call it after you append a message; the log scrolls, not the page.
IMPORTANT: the log is aria-live="polite", so screen readers announce new bubbles. Do not add another live region around it.
IMPORTANT: no strings are built in. Pass logLabel and title translated, and translate the labels of the bubble, options and composer too.
Usage:
<I9kChat ref="chat" title="9k Labs" log-label="Conversation" :expression="typing ? 'thinking' : 'idle'">
<template #actions><I9kButton size="sm" variant="link" @click="restart">โบ Start over</I9kButton></template>
<I9kChatBubble>What are you looking to build?</I9kChatBubble>
<I9kChatBubble from="user" speaker-label="You">A website</I9kChatBubble>
<template #footer>
<I9kChatOptions label="What are you looking to build?">
<I9kButton @click="answer('website')">A website</I9kButton>
</I9kChatOptions>
</template>
</I9kChat>