Composer
Chat composer card with optional context, attachments, editor content, and actions.
Installation
import {
Composer,
useComposerEditorSubmit,
} from "@o/pipeline/experimental/components/composer";
Usage
Editor
Composers pair with Editor: Editor.Root wraps the composer — outside Composer.Root, so drafts survive content swaps — and Editor.Content plus Editor.Bubble render inside Composer.EditorBody. The external Editor component and Composer.Editor are intentionally adjacent: Composer.Editor is the composer’s elevated card, while Editor.Root is the editor state owner.
useComposerEditorSubmit adds submission behavior to Composer editors without changing the generic Editor.Root: Enter and ⌘↵ submit when there is content, while Shift+Enter inserts a new paragraph. When the editor is empty or submission is disabled, the keymap yields so the editor handles the key normally. Set preventEmptySubmit when a parent composition has its own Enter behavior that should not run for an empty editor. Use the hook’s submit/canSubmit values to wire Composer.EditorSubmit; the keymap is removed when the calling component unmounts.
const { submit, canSubmit } = useComposerEditorSubmit({ onSubmit, disabled });
Header
Context
Resume
Attachments
Dynamic content
Dynamic content swaps happen directly under Composer.Root, as keyed siblings of the persistent Composer.Header. Composer.Editor is the editor card and contains the EditorAttachments/EditorBody/EditorFooter arrangement. Non-editor views bring their own card surface and padding; there is no generic body slot by design. Use Questionnaire for question views. Composer.Action is generic and can be used in the header, editor footer, or a custom view. Keep dismissal in state too: Esc or a dismiss action simply switches back.
Click the button on the bottom right
Composition
Editor.Root
└── Composer.Root
├── Composer.Header
│ ├── Glyph
│ ├── Composer.HeaderTitle
│ ├── Composer.HeaderDescription
│ └── Composer.Action
└── Composer.Editor
├── Composer.EditorAttachments
│ └── Attachment.Root
├── Composer.EditorBody
│ ├── Editor.Content
│ └── Editor.Bubble
└── Composer.EditorFooter
├── Composer.EditorActions
│ └── Composer.Action
└── Composer.EditorSubmit