import type { Meta, StoryObj } from 'storybook-solidjs-vite'; import { For } from 'solid-js'; import { ChatContainerRoot, ChatContainerContent, ChatContainerScrollAnchor } from './chat-container'; import { Message, MessageAvatar, MessageContent } from './message'; import { componentDescription } from '../stories/docs/element-controls'; const sampleMessages = [ { role: 'user', content: 'What is SolidJS?' }, { role: 'assistant', content: '**SolidJS** is a declarative, efficient, and flexible JavaScript library for building user interfaces. Unlike React, it uses fine-grained reactivity with no Virtual DOM, resulting in excellent performance.' }, { role: 'user', content: 'How does reactivity work in SolidJS?' }, { role: 'assistant', content: `SolidJS uses **signals** as its core reactive primitive. Here's how it works: 1. **Signals** -- Store reactive values that track their dependencies 2. **Effects** -- Side effects that re-run when their signal dependencies change 3. **Memos** -- Derived values that cache their results Unlike React's useState, SolidJS signals are getter/setter pairs that update only the specific DOM nodes that depend on them.` }, { role: 'user', content: 'Can you show me an example?' }, { role: 'assistant', content: `Here's a simple counter example: \`\`\`typescript import { createSignal } from 'solid-js'; function Counter() { const [count, setCount] = createSignal(0); return ( ); } \`\`\` Notice that \`count\` is called as a function -- this is how SolidJS tracks which parts of the UI depend on which signals.` }, ]; const meta = { title: 'Solid (Advanced)/Elements/ChatContainer', component: ChatContainerRoot, tags: ['autodocs'], parameters: { layout: 'padded', docs: { description: componentDescription([ 'A scrollable message viewport that automatically sticks to the bottom as new content streams in. Composed of `ChatContainerRoot` (the scroll region), `ChatContainerContent` (the message stack), and `ChatContainerScrollAnchor` (the stick-to-bottom target).', '**When to use:** as the conversation transcript region of a chat UI, where messages append over time and the view should follow the latest output unless the user scrolls up.', '**How to use:** wrap your message list in `ChatContainerRoot`, place messages inside `ChatContainerContent`, and end with `ChatContainerScrollAnchor`. Give the root a fixed height so it can scroll.', '**Placement:** the central pane of a chat layout, between the header and the prompt input.', ]), controls: { exclude: ['use:eventListener'] }, }, }, argTypes: { children: { control: false, description: 'The container content — typically `ChatContainerContent` with messages.', }, class: { control: 'text', description: 'Extra classes for the scroll region (set a height so it can scroll).', }, }, args: { class: 'h-full flex-col p-4', }, render: (args) => (