Corpora UI
Blocks

Chat

The chat surface end to end: the chrome-less AiPanel rail (scoped selections, generated answers, recommendation cards) and the Bubble-atom messages that carry attachments and AI content. The panel is the main example; the examples below show message exchanges, attachments and an AI reply.

Preview and props

Expand Props below the centered preview to change the component’s properties.

Examples

Explore message exchanges, attachments and generated replies.

Usage

import { AiPanel, GeneratedBlock, RecommendationCard } from "@exegia/corpora-ui"

;<AiPanel
  scope={{ kind: "passage", label: "a.1", range: "¶1–¶2" }}
  thread={
    <>
      <GeneratedBlock content="The boundary is valid." />
      <RecommendationCard
        title="Fix the label mismatch"
        description="Change label from paragraph to p on"
        entity={{ name: "p-17" }}
        onAccept={applyFix}
      />
    </>
  }
  composerProps={{
    onSubmit: askContextFabric,
    models: [
      { id: "auto", label: "Auto" },
      { id: "reasoning", label: "Reasoning" },
    ],
    onModelChange: setModel,
    sources: [
      {
        id: "corpus",
        label: "Corpus",
        description: "Manuscripts and annotations",
      },
    ],
    commands: [
      {
        id: "validate",
        label: "/validate",
        description: "Check the selected passage",
      },
    ],
  }}
/>

API notes

PropTypeDefaultDescription
AiPanelscope / thread / composerProps / callbacks—Full-height rail with no surface chrome or close affordance of its own — host it inside a container such as the shell's right panel. Keep data fetching, streaming and writes in the host application; the panel provides the stable focus order and layout.
SelectionPopover"word" | "node"—One shell for word and node selections. Word details are preserved and both variants append exactly one Add to chat action (⌘J).
ScopePickerword | passage | articulus | quaestio | corpus—Keyboard-operable listbox for the five corpus scope levels.
GeneratedBlock / RecommendationCardcontent and recommendation props—Thread blocks with persistent generated labeling, polite live-region streaming, and direct human-in-the-loop recommendation cards with Reject/Accept actions.
Bubblevariant="sender" | "recipient", Header, Message—The message atom: sender hugs the right edge, recipient carries attachments inline. Render Bubble.Header on the first message of a run and mark follow-ups continued.

Prompt Bar composer

The composer follows Beautiful UI's Prompt Bar: a compact rounded row with attachments, message input, model selection, dictation, and send. Long drafts move above the controls and grow to a bounded height. Use composerProps.shape="pill" for the pill shape or expanded to keep the text above the controls.

Type @ to find configured sources or / to find commands. Arrow keys move through matches; Enter or Tab inserts a selection; Escape dismisses the menu. Enter sends, Shift+Enter inserts a new line, and ⌘/Ctrl+Enter still sends. While streaming, Send becomes Stop.

onSubmit(value, mode, attachments) retains the existing contract. Local file attachments include a file object; the consuming app owns uploads. model / onModelChange support controlled model selection. Dictation starts only from the microphone button and uses the browser's speech recognition; unsupported browsers disable the control. Set dictation={false} to hide it.

Files are classified as images, video, audio, or documents when selected. Keep the complete attachment object when rendering it in the thread: <Attachment {...attachment} variant="default" removable={false} /> preserves its file, source URL, and preview metadata. Sent messages use the compact attachment chip with a hover/focus preview. The preview variant displays expanded content without a hover card. Wrap sent attachments in <Bubble.Message unstyled> to remove the surrounding bubble surface. Text and attachments can occupy separate message surfaces in the same Bubble.

Last updated on

On this page