# Conversation Conversation threads, answers, citations, composers and floating chat surfaces. - Group: Website - Import: `import { ConversationLayout } from '@misoto22/folio/website'` - Page: https://ui.misoto22.com/components/conversation/ ## When to reach for it Compose a localized assistant interface while the host owns streaming, history and service calls. ## Best practices ### Do - Supply localized labels, descriptive links and meaningful image alternatives. ### Don’t - Do not put service credentials, routing logic or backend models inside presentation components. ## ConversationLayout A reading-width conversation with a separate, sticky evidence rail. ### Props - `evidence` (required) — `ReactNode`. Also accepts: `HTMLAttributes`. ## ConversationFacts ### Props - `items` (required) — `DescriptionListItem[]`. Also accepts: `HTMLAttributes`. ## ConversationSuggestions ### Props - `label` (required) — `string`. - `items` (required) — `ConversationSuggestion[]`. Also accepts: `HTMLAttributes`. ## ConversationThread Host owns turns and folding; this composition owns their hierarchy and controls. ### Props - `label` (required) — `string`. - `intro` — `{ title: ReactNode; description: ReactNode; suggestionsLabel: string; suggestions: ConversationSuggestion[] }`. - `summary` — `ReactNode`. - `controls` — `ConversationControl[]` default `[]`. - `composer` (required) — `ReactNode`. - `proposal` — `ReactNode`. - `hasTurns` (required) — `boolean`. Also accepts: `HTMLAttributes`. ## ConversationLog ### Props - `compact` — `boolean`. Also accepts: `HTMLAttributes`. ## QuestionComposer A controlled, labelled composer. Request limits and sending remain host concerns. ### Props - `id` (required) — `string`. - `label` (required) — `string`. - `hideLabel` — `boolean`. - `value` (required) — `string`. - `onValueChange` (required) — `(value: string) => void`. - `onSubmit` (required) — `() => void`. - `inputRef` — `Ref`. - `placeholder` — `string`. - `maxLength` — `number`. - `disabled` — `boolean`. - `submitDisabled` — `boolean`. - `pending` — `boolean`. - `submitLabel` (required) — `string`. - `hint` — `ReactNode`. - `hideHint` — `boolean`. - `counter` — `ReactNode`. - `actions` — `ReactNode`. - `compact` — `boolean`. Also accepts: `Omit, 'onSubmit'>`. ## ConversationTurn ### Props - `title` (required) — `ReactNode`. - `metadata` — `ReactNode`. - `expanded` (required) — `boolean`. - `onToggle` (required) — `() => void`. - `bodyId` (required) — `string`. - `preview` — `ReactNode`. Also accepts: `Omit, 'title'>`. ## ConversationQuote ### Props - `label` (required) — `string`. - `compact` — `boolean`. Also accepts: `HTMLAttributes`. ## ConversationAnswer ### Props - `question` (required) — `ReactNode`. - `questionLabel` (required) — `string`. - `quote` — `ReactNode`. Also accepts: `HTMLAttributes`. ## ConversationProse Trusted React nodes from the host's sanitized answer parser, never raw model HTML. ## ConversationAnswerHeading Model-generated headings are prose labels, so they do not alter the page outline. ## StreamingCaret ## ConversationSources ### Props - `label` (required) — `string`. - `count` (required) — `ReactNode`. - `items` (required) — `ConversationSource[]`. Also accepts: `HTMLAttributes`. ## ActionProposal ### Props - `label` (required) — `string`. - `destination` (required) — `ReactNode`. - `detail` — `ReactNode`. - `approveLabel` (required) — `string`. - `dismissLabel` (required) — `string`. - `onApprove` (required) — `() => void`. - `onDismiss` (required) — `() => void`. - `approvalAttributes` — `Record<`data-${string}`, string>`. Also accepts: `HTMLAttributes`. ## ConversationLauncher ### Props - `visible` (required) — `boolean`. - `buttonRef` — `Ref`. Also accepts: `ButtonHTMLAttributes`. ## ConversationDock The host supplies placement, dismissal and stream state; the dock draws them. ### Props - `label` (required) — `string`. - `open` (required) — `boolean`. - `card` (required) — `boolean`. - `corner` (required) — `ConversationDockCorner`. - `dragging` — `boolean`. - `moving` — `boolean`. - `panelRef` — `Ref`. - `logRef` — `Ref`. - `roomLink` (required) — `ReactElement`. - `closeLabel` (required) — `string`. - `onClose` (required) — `() => void`. - `onHeaderPointerDown` — `(event: PointerEvent) => void`. - `handles` — `ReactNode`. - `proposal` — `ReactNode`. - `notice` — `ReactNode`. - `composer` (required) — `ReactNode`. Also accepts: `HTMLAttributes`. ## ConversationDockWelcome ### Props - `lead` (required) — `ReactNode`. - `suggestionsLabel` (required) — `string`. - `suggestions` (required) — `ConversationSuggestion[]`. Also accepts: `HTMLAttributes`. ## ConversationResizeHandle Keyboard equivalents for the host's pointer resize controller. ### Props - `axis` (required) — `'size-vertical' | 'size-horizontal'`. - `side` (required) — `'top' | 'bottom' | 'left' | 'right'`. - `label` (required) — `string`. - `dragging` (required) — `boolean`. - `onStart` (required) — `(axis: 'size-vertical' | 'size-horizontal', event: PointerEvent) => void`. - `onNudge` (required) — `(axis: 'size-vertical' | 'size-horizontal', delta: number) => void`. ## SelectionToolbar Selection actions with a real toolbar's single tab stop and arrow navigation. ### Props - `label` (required) — `string`. - `actions` (required) — `SelectionToolbarAction[]`. - `floating` (required) — `boolean`. - `toolbarRef` — `Ref`. - `style` — `CSSProperties`. Also accepts: `HTMLAttributes`. ## ConversationRoomLink A router link keeps its own destination and behavior inside a standard action. ## Example — a local conversation ```tsx import { ConversationAnswer, ConversationProse, ConversationThread, QuestionComposer } from '@misoto22/folio/website' 0} summary={`${questions.length} questions`} intro={questions.length ? undefined : { title: 'Explore the library', description: 'Try a question to preview the conversation layout.', suggestionsLabel: 'Start with', suggestions: [{ id: 'recent', label: 'What has been added recently?', onSelect: () => setQuestion('What has been added recently?') }], }} composer={ { if (question.trim()) { setQuestions((items) => [...items, question.trim()]); setQuestion('') } }} />}> {questions.map((item, index) =>

The question is now part of this local conversation. A connected application would supply its answer here.

)}
```