Skip to content
Folio

Website

Conversation

Conversation threads, answers, citations, composers and floating chat surfaces.

Usage

When to reach for it

Compose a localized assistant interface while the host owns streaming, history and service calls.

Ships from@misoto22/design/website

TSX
import { ConversationLayout } from '@misoto22/design/website'

Notes

A reading-width conversation with a separate, sticky evidence rail.

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.

Examples

a local conversation

The host owns the questions and rendered answer nodes while the composition owns their reading order. This local example records questions without calling an assistant service.

Explore the library

Try a question to preview the conversation layout.

Start with

Parts

Composed at the call site rather than configured through props, so a layout this component did not anticipate is still expressible.

ConversationFacts

ConversationFacts props
PropTypeDefaultDescription
itemsrequiredDescriptionListItem[]

Also accepts everything in HTMLAttributes<HTMLDListElement>. Those are forwarded to the underlying element and are not listed row by row.

ConversationSuggestions

ConversationSuggestions props
PropTypeDefaultDescription
itemsrequiredConversationSuggestion[]
labelrequiredstring

Also accepts everything in HTMLAttributes<HTMLDivElement>. Those are forwarded to the underlying element and are not listed row by row.

ConversationThread

Host owns turns and folding; this composition owns their hierarchy and controls.

ConversationThread props
PropTypeDefaultDescription
composerrequiredReactNode
hasTurnsrequiredboolean
labelrequiredstring
controlsConversationControl[][]
intro{ title: ReactNode; description: ReactNode; suggestionsLabel: string; suggestions: ConversationSuggestion[] }
proposalReactNode
summaryReactNode

Also accepts everything in HTMLAttributes<HTMLElement>. Those are forwarded to the underlying element and are not listed row by row.

ConversationLog

ConversationLog props
PropTypeDefaultDescription
compactboolean

Also accepts everything in HTMLAttributes<HTMLDivElement>. Those are forwarded to the underlying element and are not listed row by row.

QuestionComposer

A controlled, labelled composer. Request limits and sending remain host concerns.

QuestionComposer props
PropTypeDefaultDescription
idrequiredstring
labelrequiredstring
onSubmitrequired() => void
onValueChangerequired(value: string) => void
submitLabelrequiredstring
valuerequiredstring
actionsReactNode
compactboolean
counterReactNode
disabledboolean
hideHintboolean
hideLabelboolean
hintReactNode
inputRefRef<HTMLInputElement>
maxLengthnumber
pendingboolean
placeholderstring
submitDisabledboolean

Also accepts everything in Omit<HTMLAttributes<HTMLFormElement>, 'onSubmit'>. Those are forwarded to the underlying element and are not listed row by row.

ConversationTurn

ConversationTurn props
PropTypeDefaultDescription
bodyIdrequiredstring
expandedrequiredboolean
onTogglerequired() => void
titlerequiredReactNode
metadataReactNode
previewReactNode

Also accepts everything in Omit<HTMLAttributes<HTMLElement>, 'title'>. Those are forwarded to the underlying element and are not listed row by row.

ConversationQuote

ConversationQuote props
PropTypeDefaultDescription
labelrequiredstring
compactboolean

Also accepts everything in HTMLAttributes<HTMLElement>. Those are forwarded to the underlying element and are not listed row by row.

ConversationAnswer

ConversationAnswer props
PropTypeDefaultDescription
questionrequiredReactNode
questionLabelrequiredstring
quoteReactNode

Also accepts everything in HTMLAttributes<HTMLDivElement>. Those are forwarded to the underlying element and are not listed row by row.

ConversationProse

Trusted React nodes from the host's sanitized answer parser, never raw model HTML.

Takes no props of its own.

ConversationAnswerHeading

Model-generated headings are prose labels, so they do not alter the page outline.

Takes no props of its own.

StreamingCaret

Takes no props of its own.

ConversationSources

ConversationSources props
PropTypeDefaultDescription
countrequiredReactNode
itemsrequiredConversationSource[]
labelrequiredstring

Also accepts everything in HTMLAttributes<HTMLDivElement>. Those are forwarded to the underlying element and are not listed row by row.

ActionProposal

ActionProposal props
PropTypeDefaultDescription
approveLabelrequiredstring
destinationrequiredReactNode
dismissLabelrequiredstring
labelrequiredstring
onApproverequired() => void
onDismissrequired() => void
approvalAttributesRecord<`data-${string}`, string>
detailReactNode

Also accepts everything in HTMLAttributes<HTMLDivElement>. Those are forwarded to the underlying element and are not listed row by row.

ConversationLauncher

ConversationLauncher props
PropTypeDefaultDescription
visiblerequiredboolean
buttonRefRef<HTMLButtonElement>

Also accepts everything in ButtonHTMLAttributes<HTMLButtonElement>. Those are forwarded to the underlying element and are not listed row by row.

ConversationDock

The host supplies placement, dismissal and stream state; the dock draws them.

ConversationDock props
PropTypeDefaultDescription
cardrequiredboolean
closeLabelrequiredstring
composerrequiredReactNode
cornerrequiredConversationDockCorner
labelrequiredstring
onCloserequired() => void
openrequiredboolean
roomLinkrequiredReactElement
draggingboolean
handlesReactNode
logRefRef<HTMLDivElement>
movingboolean
noticeReactNode
onHeaderPointerDown(event: PointerEvent<HTMLElement>) => void
panelRefRef<HTMLElement>
proposalReactNode

Also accepts everything in HTMLAttributes<HTMLElement>. Those are forwarded to the underlying element and are not listed row by row.

ConversationDockWelcome

ConversationDockWelcome props
PropTypeDefaultDescription
leadrequiredReactNode
suggestionsrequiredConversationSuggestion[]
suggestionsLabelrequiredstring

Also accepts everything in HTMLAttributes<HTMLDivElement>. Those are forwarded to the underlying element and are not listed row by row.

ConversationResizeHandle

Keyboard equivalents for the host's pointer resize controller.

ConversationResizeHandle props
PropTypeDefaultDescription
axisrequired'size-vertical' | 'size-horizontal'
draggingrequiredboolean
labelrequiredstring
onNudgerequired(axis: 'size-vertical' | 'size-horizontal', delta: number) => void
onStartrequired(axis: 'size-vertical' | 'size-horizontal', event: PointerEvent<HTMLElement>) => void
siderequired'top' | 'bottom' | 'left' | 'right'

SelectionToolbar

Selection actions with a real toolbar's single tab stop and arrow navigation.

SelectionToolbar props
PropTypeDefaultDescription
actionsrequiredSelectionToolbarAction[]
floatingrequiredboolean
labelrequiredstring
styleCSSProperties
toolbarRefRef<HTMLDivElement>

Also accepts everything in HTMLAttributes<HTMLDivElement>. Those are forwarded to the underlying element and are not listed row by row.

ConversationRoomLink

A router link keeps its own destination and behavior inside a standard action.

Takes no props of its own.

Types

TSX
export type ConversationDockCorner = 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right'