UNPKG

@kitn.ai/chat

Version:

Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. Authored in SolidJS.

174 lines (137 loc) 6.68 kB
import { Meta } from '@storybook/addon-docs/blocks'; <Meta title="Docs/Frameworks/Solid" /> # Solid The kit is **authored in SolidJS** — the `<kc-*>` web components are compiled from these very components. So Solid devs get the richest path of any framework, with **two ways to build** that you can freely mix: 1. **Native SolidJS components** (`@kitn.ai/chat`) — `ChatContainer`, `Message`, `PromptInput`, and the rest, composed in your own JSX. Full compositional control and the smallest output for a Solid app. **This is the recommended Solid path.** 2. The same framework-agnostic **`<kc-*>` web components** (`@kitn.ai/chat/elements`) — the drop-in shells (`<kc-chat>`, ) when you just want batteries included. Both work in the same app; reach for whichever fits the surface you're building. ## Install & setup ```bash npm i @kitn.ai/chat ``` `solid-js` is a peer dependency — install it if you haven't already: ```bash npm i solid-js ``` Import the design tokens **once**, near your app entry: ```ts import '@kitn.ai/chat/theme.css'; ``` The `@kitn.ai/chat` entry ships as **source** (TSX), so your bundler compiles and tree-shakes it alongside your own Solid code — you only pay for what you import. ## Quick start — native components Compose the native components directly in your JSX. Drive the prompt input with a `createSignal`, and let the components fill their container — size them with flex / `class="h-full"` rather than a hard-coded `height: 100vh`. ```tsx import { ChatConfig, ChatContainer, ChatContainerContent, Message, MessageContent, PromptInput, PromptInputTextarea, PromptInputActions, } from '@kitn.ai/chat'; import '@kitn.ai/chat/theme.css'; import { createSignal } from 'solid-js'; function Chat() { const [input, setInput] = createSignal(''); // The components fill their box — give them a flex parent and let // ChatContainer grow with `h-full`/flex rather than a fixed viewport height. return ( <div class="flex flex-col h-full"> <ChatConfig proseSize="sm"> <ChatContainer class="h-full"> <ChatContainerContent class="space-y-4 p-4"> <Message> <MessageContent markdown>{`Ask me anything.`}</MessageContent> </Message> </ChatContainerContent> </ChatContainer> <PromptInput value={input()} onValueChange={setInput} onSubmit={() => setInput('')}> <PromptInputTextarea placeholder="Ask anything..." /> <PromptInputActions>{/* your buttons */}</PromptInputActions> </PromptInput> </ChatConfig> </div> ); } ``` `<ChatContainer>` is **transport-agnostic**: it owns the conversation UI, you own the request. Render your message list inside `<ChatContainerContent>` (a `<For>` over your signal of messages), and append the user turn — then stream the assistant reply — in `onSubmit`. ## Go further — compose & the web components ### The native components *are* the granular composition There's no separate "advanced" component set — the pieces above (`ChatContainer`, `Message`, `PromptInput`) plus the feature components (`Markdown`, `CodeBlock`, `Reasoning`, `Tool`, `Conversations`, `ModelSwitcher`, ) **are** the building blocks. Assemble them into any layout you like: a sidebar next to a thread, a split view, a custom composer — it's all just Solid JSX. For a resizable layout, use the native `Resizable` convenience component with one `ResizablePanel` per pane (handles are auto-inserted between visible panels). Each panel takes `defaultSize` (px or `%`) plus optional `minSize`/`maxSize`; listen for `onChange` (an array of percent sizes) to persist the layout. ```tsx import { Resizable, ResizablePanel } from '@kitn.ai/chat'; function Workspace() { return ( <div class="flex flex-col h-full"> <Resizable orientation="horizontal" withHandle onChange={(sizes) => persist(sizes)}> <ResizablePanel defaultSize="25%" minSize="200px"> {/* your conversation sidebar */} </ResizablePanel> <ResizablePanel> {/* the message thread + prompt input */} </ResizablePanel> </Resizable> </div> ); } ``` > **Full reference:** the **[Solid (Advanced)](?path=/docs/solid-advanced-overview--docs)** sidebar > tier documents every native building block — the composed **Elements** (message, tool, reasoning, > ) and the low-level **Primitives** (button, tooltip, dropdown, ) they're built on. ### Prefer the drop-in shell? Use the web component When you just want a whole chat in one tag, register the `<kc-*>` elements and use `<kc-chat>`. Solid sets rich data as DOM **properties** on custom elements (so arrays/objects pass through without stringifying), and you listen for CustomEvents with Solid's `on:` namespace: ```tsx import '@kitn.ai/chat/elements'; // registers the <kc-*> elements once import { createSignal } from 'solid-js'; function Shell() { const [messages, setMessages] = createSignal([ { id: '1', role: 'assistant', content: 'Hello! How can I help?' }, ]); const onSubmit = (e: CustomEvent<{ value: string }>) => { setMessages((prev) => [ ...prev, { id: crypto.randomUUID(), role: 'user', content: e.detail.value }, ]); // ...call your model, then append an assistant message }; return ( <div class="flex flex-col h-full"> <kc-chat // `prop:` forces a property assignment (not an attribute) for rich data. prop:messages={messages()} on:kc-submit={onSubmit} style={{ flex: 1, 'min-height': 0 }} /> </div> ); } ``` For a resizable web-component layout, use `<kc-resizable>` the same way (set properties, listen with `on:`) — though in a Solid app the native `Resizable` above gives you tighter control. > **See it all assembled:** **[Examples Full Chat App](?path=/story/examples-full-chat-app--default)** > wires a sidebar, threaded markdown, reasoning, a tool call, a model switcher, a context meter, and > a rich prompt input into one screen — a working reference to crib from. ## When to use which - **Native components** (`@kitn.ai/chat`) — full compositional control and the **smallest output** for a Solid app, since they compile and tree-shake with your own code. The recommended path when you're building in Solid. - **Web components** (`@kitn.ai/chat/elements`) — the **fastest drop-in** and fully framework-agnostic. Reach for `<kc-chat>` (or any `<kc-*>` shell) when you want batteries included or you're sharing UI across frameworks. Mix freely: a native composed thread on one screen, a drop-in `<kc-chat>` on another.