Composer
Try the composer’s selectors, attachment options, and recording control. Toggle Agent turn in progress to switch between a single Submit button and Stop with an icon-only split action/ellipsis control. Choose Queue or Steer from the menu; a check marks the current selection, which the primary button performs. Sending a message also starts the simulated turn; Stop or the toggle ends it without clearing your draft.
Messages and files stay in this example.
View code
import { useEffect, useRef, useState } from "react";import { Composer, type ComposerDraft } from "@stack/ui/composer";import { useAudioRecording } from "@stack/ui/use-audio-recording";import { useAttachmentCapabilities } from "@stack/ui/use-attachment-capabilities";import { Attachment } from "@stack/ui/attachment";import { Button } from "@/components/ui/button";import { DropdownMenuRadioGroup, DropdownMenuRadioItem,} from "@/components/ui/dropdown-menu";import { EllipsisIcon } from "lucide-react";
type LocalFile = { id: string; src: string; name: string; type: string };type Submission = { id: string; text: string; files: LocalFile[]; action: "Send" | "Queue" | "Steer"; model: string; effort: string;};
function FilePreview({ file, onRemove,}: { file: LocalFile; onRemove?: () => void;}) { return ( <Attachment.Root src={file.src} name={file.name} type={file.type} onRemove={onRemove} > <Attachment.PreviewTrigger /> <Attachment.Remove /> <Attachment.PreviewContent> <Attachment.Header> <Attachment.HeaderContent> <Attachment.Title /> <Attachment.Description /> </Attachment.HeaderContent> <Attachment.Actions> <Attachment.Download /> <Attachment.Close /> </Attachment.Actions> </Attachment.Header> <Attachment.Content /> </Attachment.PreviewContent> </Attachment.Root> );}
export default function Example() { const { narrowViewport } = useAttachmentCapabilities(); const [draft, setDraft] = useState<ComposerDraft | string>(""); const [files, setFiles] = useState<LocalFile[]>([]); const [submissions, setSubmissions] = useState<Submission[]>([]); const [model, setModel] = useState("General"); const [effort, setEffort] = useState("Medium"); const [working, setWorking] = useState(false); const [busyAction, setBusyAction] = useState<"Queue" | "Steer">("Queue"); const [loading, setLoading] = useState(false); const [disabled, setDisabled] = useState(false); const [notice, setNotice] = useState( "Messages and files stay in this example.", ); const [exampleError, setExampleError] = useState<string | null>(null); const urls = useRef(new Set<string>()); const text = typeof draft === "string" ? draft : draft.text; const voice = useAudioRecording({ scopeKey: "composer-docs", onRecording(recording) { attach([ new File([recording.blob], "recording.pcm", { type: "application/octet-stream", }), ]); setNotice( "Audio attached as raw PCM. No transcription or upload was performed.", ); }, }); const ready = !!(text.trim() || files.length) && !voice.busy && !disabled;
useEffect(() => { const created = urls.current; return () => { for (const url of created) URL.revokeObjectURL(url); created.clear(); }; }, []);
function attach(selected: File[]) { const added = selected.map((file) => { const src = URL.createObjectURL(file); urls.current.add(src); return { id: crypto.randomUUID(), src, name: file.name, type: file.type }; }); setFiles((current) => [...current, ...added]); }
function submit(action: Submission["action"] = "Send") { if (!ready) return; setSubmissions((current) => [ ...current, { id: crypto.randomUUID(), text, files, action, model, effort }, ]); setDraft(""); setFiles([]); if (action === "Send") setWorking(true); setNotice( action === "Queue" ? "Queued locally. Queue entries are not dispatched automatically." : action === "Steer" ? "Steered the simulated turn locally." : "Agent turn in progress. Try Stop, Queue, or Steer.", ); }
function stop() { setWorking(false); setNotice("Local response stopped. Your current draft is preserved."); }
return ( <div className="grid min-w-0 gap-4"> <div className="flex flex-wrap gap-2"> <Button role="switch" aria-label="Agent turn in progress" aria-checked={working} variant={working ? "secondary" : "outline"} size="sm" onClick={() => { setWorking((value) => !value); setNotice( working ? "Agent turn finished. Your current draft is preserved." : "Agent turn in progress. Try Stop or queue a message.", ); }} > Agent turn in progress: {working ? "On" : "Off"} </Button> <Button variant="outline" size="sm" onClick={() => setLoading((value) => !value)} > {loading ? "Finish loading selectors" : "Show selector loading"} </Button> <Button variant="outline" size="sm" onClick={() => setDisabled((value) => !value)} > {disabled ? "Enable composer" : "Disable composer"} </Button> <Button variant="outline" size="sm" onClick={() => setExampleError((value) => value ? null : "Example recording error. Clear this message to continue.", ) } > {exampleError ? "Clear recording error" : "Show recording error"} </Button> </div> <Composer.RecordingError error={voice.error ?? exampleError} /> {!!files.length && ( <div aria-label="Draft attachments" className="flex flex-wrap gap-2"> {files.map((file) => ( <FilePreview key={file.id} file={file} onRemove={ disabled ? undefined : () => setFiles((current) => current.filter((item) => item.id !== file.id), ) } /> ))} </div> )} <Composer.Root value={draft} onChange={setDraft} onFiles={attach} disabled={disabled} submitState={ready ? "ready" : "blocked"} onSubmit={() => submit(working ? busyAction : "Send")} > <Composer.Input id="docs-composer" aria-label="Message" placeholder="Message…" onInterrupt={() => { if (voice.busy) voice.cancel(); else stop(); }} /> <Composer.AttachMenu onFiles={attach}> {narrowViewport ? ( <> <Composer.AttachCamera capture="environment" /> <Composer.AttachPhotos /> <Composer.AttachFiles /> </> ) : ( <Composer.AttachPhotosAndFiles /> )} </Composer.AttachMenu> <Composer.Footer> <Composer.RecordAudio status={voice.status} level={voice.level} onStart={voice.start} onStop={voice.stop} /> {working ? ( <> <Composer.Stop onClick={stop} /> <Composer.SubmitGroup> <Composer.Submit label={`${busyAction} message`} /> <Composer.SubmitSeparator /> <Composer.SubmitMenu disabled={!ready}> <Composer.SubmitMenuTrigger> <EllipsisIcon aria-hidden="true" /> </Composer.SubmitMenuTrigger> <Composer.SubmitMenuContent> <DropdownMenuRadioGroup value={busyAction} onValueChange={setBusyAction} > <DropdownMenuRadioItem value="Queue" closeOnClick> Queue </DropdownMenuRadioItem> <DropdownMenuRadioItem value="Steer" closeOnClick> Steer </DropdownMenuRadioItem> </DropdownMenuRadioGroup> </Composer.SubmitMenuContent> </Composer.SubmitMenu> </Composer.SubmitGroup> </> ) : ( <Composer.Submit label="Send message" /> )} </Composer.Footer> </Composer.Root> <Composer.Toolbar> <Composer.ToolbarGroup> <Composer.Selector value={model} onValueChange={setModel} loading={loading} disabled={disabled} > <Composer.SelectorTrigger aria-label="Model"> {model} </Composer.SelectorTrigger> <Composer.SelectorContent> <Composer.SelectorGroup> <Composer.SelectorLabel>Model</Composer.SelectorLabel> {["General", "Fast", "Reasoning"].map((value) => ( <Composer.SelectorItem key={value} value={value}> {value} </Composer.SelectorItem> ))} </Composer.SelectorGroup> </Composer.SelectorContent> </Composer.Selector> <Composer.Selector value={effort} onValueChange={setEffort} loading={loading} disabled={disabled} > <Composer.SelectorTrigger aria-label="Reasoning effort"> {effort} </Composer.SelectorTrigger> <Composer.SelectorContent> <Composer.SelectorGroup> <Composer.SelectorLabel> Reasoning effort </Composer.SelectorLabel> {["Low", "Medium", "High"].map((value) => ( <Composer.SelectorItem key={value} value={value}> {value} </Composer.SelectorItem> ))} </Composer.SelectorGroup> </Composer.SelectorContent> </Composer.Selector> </Composer.ToolbarGroup> </Composer.Toolbar> <p role="status">{notice}</p> {!!submissions.length && ( <div aria-label="Local submissions" className="grid max-h-64 gap-4 overflow-auto" > {submissions.map((submission) => ( <div key={submission.id} className="grid gap-2"> <p> {submission.action} · {submission.model} · {submission.effort} </p> {submission.text && <p>{submission.text}</p>} <div className="flex flex-wrap gap-2"> {submission.files.map((file) => ( <FilePreview key={file.id} file={file} /> ))} </div> </div> ))} </div> )} </div> );}import { useState } from "react";import { Composer } from "@stack/ui/composer";The attachment menu shows Camera, Photos, and Files on narrow screens, and Photos & Files on desktop.
Messages, files, and queue entries stay in memory. Queue entries are not sent automatically. Camera and microphone access is requested only when their controls are clicked. Audio is attached as raw PCM without transcription. The controls above the composer let you try selector loading, the disabled state, and recording errors.
Reference
Section titled “Reference”Tables list component-specific props and inherited control options. Components that forward native props also accept the applicable React HTML attributes and event handlers, including data-* and aria-* attributes.
Composer.Root
Section titled “Composer.Root”Also accepts native element props.
| Prop | Type | Required | Description |
|---|---|---|---|
className |
string |
No | Additional CSS classes for the underlying element. |
children |
ReactNode |
No | Content rendered inside the component. |
onPasteCapture |
ClipboardEventHandler<HTMLDivElement> |
No | Handle paste events before the built-in attachment handler. |
onFocusCapture |
FocusEventHandler<HTMLDivElement> |
No | Handle focus entering the composer. |
onBlurCapture |
FocusEventHandler<HTMLDivElement> |
No | Handle focus leaving the composer. |
onDragOverCapture |
DragEventHandler<HTMLDivElement> |
No | Handle drag-over events before the built-in attachment handler. |
onDropCapture |
DragEventHandler<HTMLDivElement> |
No | Handle drop events before the built-in attachment handler. |
onFiles |
((files: File[]) => void) |
No | Receive files selected, pasted, or dropped into the component. |
value |
string | ComposerDraft |
Yes | Current controlled value. |
onChange |
(value: ComposerDraft) => void |
Yes | Called when the value changes. |
onSubmit |
() => void |
Yes | Handle submission. |
inputRef |
Ref<PromptInputHandle> |
No | Ref for the prompt editor’s imperative handle. |
newlineShortcut |
"enter" | "shift-enter" | "ctrl-enter" |
No | Keyboard shortcut that inserts a newline. Default: "shift-enter". |
submitShortcut |
"enter" | "shift-enter" | "ctrl-enter" |
No | Keyboard shortcut that submits the draft. Default: "enter". |
disabled |
boolean |
No | Disable interaction. Default: false. |
submitState |
"ready" | "blocked" | "pending" |
No | Control whether submission is ready, blocked, or pending. Default: "ready". |
Composer.Toolbar
Section titled “Composer.Toolbar”Also accepts native element props.
| Prop | Type | Required | Description |
|---|---|---|---|
className |
string |
No | Additional CSS classes for the underlying element. |
children |
ReactNode |
No | Content rendered inside the component. |
Composer.ToolbarGroup
Section titled “Composer.ToolbarGroup”Also accepts native element props.
| Prop | Type | Required | Description |
|---|---|---|---|
className |
string |
No | Additional CSS classes for the underlying element. |
children |
ReactNode |
No | Content rendered inside the component. |
Composer.Selector
Section titled “Composer.Selector”| Prop | Type | Required | Description |
|---|---|---|---|
defaultOpen |
boolean |
No | Whether the menu is initially open. |
loopFocus |
boolean |
No | Whether to loop keyboard focus back to the first item when the end of the list is reached while using the arrow keys. |
highlightItemOnHover |
boolean |
No | Whether moving the pointer over items should highlight them. |
modal |
boolean |
No | Determines if the menu enters a modal state when open. - true: user interaction is limited to the menu: document page scroll is locked and pointer interactions on outside elements are disabled. - false: user interaction with the rest of the document is allowed. |
onOpenChange |
((open: boolean, eventDetails: MenuRoot.ChangeEventDetails) => void) |
No | Event handler called when the menu is opened or closed. |
onOpenChangeComplete |
((open: boolean) => void) |
No | Event handler called after any animations complete when the menu is opened or closed. |
onItemHighlighted |
((highlightedItem: HTMLElement | undefined, eventDetails: MenuRoot.HighlightEventDetails) => void) |
No | Callback fired when an item is highlighted or unhighlighted. |
open |
boolean |
No | Controlled open state. |
orientation |
MenuRootOrientation |
No | Orientation of the component. |
disabled |
boolean |
No | Whether the component should ignore user interaction. Default: false. |
closeParentOnEsc |
boolean |
No | When in a submenu, determines whether pressing the Escape key closes the entire menu, or only the current child menu. |
actionsRef |
RefObject<MenuRootActions | null> |
No | A ref to imperative actions. - unmount: Ends the closing phase of the menu after an externally controlled closing animation finishes. |
triggerId |
string | null |
No | ID of the trigger that the menu is associated with. |
defaultTriggerId |
string | null |
No | ID of the trigger that the menu is associated with. |
handle |
Handle<unknown> |
No | A handle to associate the menu with a trigger. |
children |
ReactNode | PayloadChildRenderFunction<unknown> |
No | Content rendered inside the component. |
value |
string |
Yes | Current controlled value. |
onValueChange |
(value: string) => void |
Yes | Called when the selected value changes. |
loading |
boolean |
No | Whether data is loading. Default: false. |
Composer.SelectorTrigger
Section titled “Composer.SelectorTrigger”Also accepts native element props.
| Prop | Type | Required | Description |
|---|---|---|---|
children |
ReactNode |
No | Content rendered inside the component. |
disabled |
boolean |
No | Disable interaction. |
handle |
Handle<unknown> |
No | A handle to associate the trigger with a menu. |
payload |
unknown |
No | A payload to pass to the menu when it is opened. |
delay |
number |
No | How long to wait before the menu may be opened on hover. |
closeDelay |
number |
No | How long to wait before closing the menu that was opened on hover. |
openOnHover |
boolean |
No | Open the hint when the trigger is hovered. |
nativeButton |
boolean |
No | Whether the component renders a native <button> element when replacing it via the render prop. |
aria-label |
string |
Yes | Defines a string value that labels the current element. |
className |
string | ((state: MenuTriggerState) => string | undefined) |
No | Additional CSS classes for the underlying element. |
render |
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, MenuTriggerState> |
No | Replace the underlying element using render composition. |
style |
CSSProperties | ((state: MenuTriggerState) => CSSProperties | undefined) |
No | Inline styles for the underlying element. |
Composer.SelectorContent
Section titled “Composer.SelectorContent”Also accepts native element props.
| Prop | Type | Required | Description |
|---|---|---|---|
children |
ReactNode |
No | Content rendered inside the component. |
id |
string |
No | Element identifier. |
finalFocus |
boolean | RefObject<HTMLElement | null> | ((closeType: InteractionType) => boolean | HTMLElement | null | void) |
No | Determines the element to focus when the menu is closed. |
className |
string | ((state: ContextMenuPopupState) => string | undefined) |
No | Additional CSS classes for the underlying element. |
render |
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ContextMenuPopupState> |
No | Replace the underlying element using render composition. |
style |
CSSProperties | ((state: ContextMenuPopupState) => CSSProperties | undefined) |
No | Inline styles for the underlying element. |
align |
Align |
No | Alignment of the component. |
alignOffset |
number | OffsetFunction |
No | Additional offset along the alignment axis in pixels. |
side |
Side |
No | Side on which the popup or panel appears. |
sideOffset |
number | OffsetFunction |
No | Distance between the anchor and the popup in pixels. |
Composer.SelectorItem
Section titled “Composer.SelectorItem”Also accepts native element props.
| Prop | Type | Required | Description |
|---|---|---|---|
value |
any |
Yes | Current controlled value. |
onClick |
((event: BaseUIEvent<MouseEvent<HTMLDivElement, MouseEvent>>) => void) |
No | The click handler for the menu item. |
disabled |
boolean |
No | Disable interaction. |
label |
string |
No | Accessible or displayed label for the control. |
id |
string |
No | Element identifier. |
closeOnClick |
boolean |
No | Whether to close the menu when the item is clicked. |
nativeButton |
boolean |
No | Whether the component renders a native <button> element when replacing it via the render prop. |
children |
ReactNode |
No | Content rendered inside the component. |
className |
string | ((state: ContextMenuRadioItemState) => string | undefined) |
No | Additional CSS classes for the underlying element. |
render |
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ContextMenuRadioItemState> |
No | Replace the underlying element using render composition. |
style |
CSSProperties | ((state: ContextMenuRadioItemState) => CSSProperties | undefined) |
No | Inline styles for the underlying element. |
inset |
boolean |
No | Inset the menu item to align it with neighboring items. |
Composer.SelectorGroup
Section titled “Composer.SelectorGroup”Also accepts native element props.
| Prop | Type | Required | Description |
|---|---|---|---|
children |
ReactNode |
No | Content rendered inside the component. |
className |
string | ((state: ContextMenuGroupState) => string | undefined) |
No | Additional CSS classes for the underlying element. |
render |
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ContextMenuGroupState> |
No | Replace the underlying element using render composition. |
style |
CSSProperties | ((state: ContextMenuGroupState) => CSSProperties | undefined) |
No | Inline styles for the underlying element. |
Composer.SelectorLabel
Section titled “Composer.SelectorLabel”Also accepts native element props.
| Prop | Type | Required | Description |
|---|---|---|---|
children |
ReactNode |
No | Content rendered inside the component. |
className |
string | ((state: ContextMenuGroupLabelState) => string | undefined) |
No | Additional CSS classes for the underlying element. |
render |
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ContextMenuGroupLabelState> |
No | Replace the underlying element using render composition. |
style |
CSSProperties | ((state: ContextMenuGroupLabelState) => CSSProperties | undefined) |
No | Inline styles for the underlying element. |
inset |
boolean |
No | Inset the menu item to align it with neighboring items. |
Composer.Input
Section titled “Composer.Input”| Prop | Type | Required | Description |
|---|---|---|---|
id |
string |
Yes | Element identifier. |
aria-describedby |
string |
No | ID of the element supplying the accessible description. |
aria-invalid |
boolean |
No | Indicate that the input value is invalid. |
aria-label |
string |
No | Accessible name for the control. |
aria-labelledby |
string |
No | ID of the element supplying the accessible name. |
disabled |
boolean |
No | Disable interaction. |
required |
boolean |
No | Mark the input as required. |
compact |
boolean |
No | Use the compact input presentation. |
placeholder |
string |
Yes | Placeholder shown when the input is empty. |
onInterrupt |
(() => void | boolean) |
No | Handle an interruption request from the editor. |
onHistory |
((direction: "older" | "newer", editor: Editor) => boolean) |
No | Handle navigation through older or newer drafts. |
autocomplete |
ComposeAutocompleteProvider[] |
No | Autocomplete providers for the prompt editor. |
Composer.Footer
Section titled “Composer.Footer”Also accepts native element props.
| Prop | Type | Required | Description |
|---|---|---|---|
className |
string |
No | Additional CSS classes for the underlying element. |
children |
ReactNode |
No | Content rendered inside the component. |
align |
"inline-end" | "inline-start" | "block-start" | "block-end" | null |
No | Alignment of the component. |
Composer.Submit
Section titled “Composer.Submit”| Prop | Type | Required | Description |
|---|---|---|---|
className |
string |
No | Additional CSS classes for the underlying element. |
label |
string |
No | Accessible or displayed label for the control. Default: "Send message". |
children |
ReactNode |
No | Content rendered inside the component. |
Composer.SubmitGroup
Section titled “Composer.SubmitGroup”Also accepts native element props.
| Prop | Type | Required | Description |
|---|---|---|---|
className |
string |
No | Additional CSS classes for the underlying element. |
children |
ReactNode |
No | Content rendered inside the component. |
orientation |
"horizontal" | "vertical" | null |
No | Orientation of the component. |
Composer.SubmitSeparator
Section titled “Composer.SubmitSeparator”Also accepts native element props.
| Prop | Type | Required | Description |
|---|---|---|---|
orientation |
Orientation |
No | Orientation of the component. Default: "vertical". |
children |
ReactNode |
No | Content rendered inside the component. |
className |
string | ((state: SeparatorState) => string | undefined) |
No | Additional CSS classes for the underlying element. |
render |
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, SeparatorState> |
No | Replace the underlying element using render composition. |
style |
CSSProperties | ((state: SeparatorState) => CSSProperties | undefined) |
No | Inline styles for the underlying element. |
Composer.SubmitMenu
Section titled “Composer.SubmitMenu”| Prop | Type | Required | Description |
|---|---|---|---|
defaultOpen |
boolean |
No | Whether the menu is initially open. |
loopFocus |
boolean |
No | Whether to loop keyboard focus back to the first item when the end of the list is reached while using the arrow keys. |
highlightItemOnHover |
boolean |
No | Whether moving the pointer over items should highlight them. |
modal |
boolean |
No | Determines if the menu enters a modal state when open. - true: user interaction is limited to the menu: document page scroll is locked and pointer interactions on outside elements are disabled. - false: user interaction with the rest of the document is allowed. |
onOpenChange |
((open: boolean, eventDetails: MenuRoot.ChangeEventDetails) => void) |
No | Event handler called when the menu is opened or closed. |
onOpenChangeComplete |
((open: boolean) => void) |
No | Event handler called after any animations complete when the menu is opened or closed. |
onItemHighlighted |
((highlightedItem: HTMLElement | undefined, eventDetails: MenuRoot.HighlightEventDetails) => void) |
No | Callback fired when an item is highlighted or unhighlighted. |
open |
boolean |
No | Controlled open state. |
orientation |
MenuRootOrientation |
No | Orientation of the component. |
disabled |
boolean |
No | Whether the component should ignore user interaction. Default: false. |
closeParentOnEsc |
boolean |
No | When in a submenu, determines whether pressing the Escape key closes the entire menu, or only the current child menu. |
actionsRef |
RefObject<MenuRootActions | null> |
No | A ref to imperative actions. - unmount: Ends the closing phase of the menu after an externally controlled closing animation finishes. |
triggerId |
string | null |
No | ID of the trigger that the menu is associated with. |
defaultTriggerId |
string | null |
No | ID of the trigger that the menu is associated with. |
handle |
Handle<unknown> |
No | A handle to associate the menu with a trigger. |
children |
ReactNode | PayloadChildRenderFunction<unknown> |
No | Content rendered inside the component. |
Composer.SubmitMenuTrigger
Section titled “Composer.SubmitMenuTrigger”Also accepts native element props.
| Prop | Type | Required | Description |
|---|---|---|---|
children |
ReactNode |
No | Content rendered inside the component. |
disabled |
boolean |
No | Disable interaction. |
handle |
Handle<unknown> |
No | A handle to associate the trigger with a menu. |
payload |
unknown |
No | A payload to pass to the menu when it is opened. |
delay |
number |
No | How long to wait before the menu may be opened on hover. |
closeDelay |
number |
No | How long to wait before closing the menu that was opened on hover. |
openOnHover |
boolean |
No | Open the hint when the trigger is hovered. |
nativeButton |
boolean |
No | Whether the component renders a native <button> element when replacing it via the render prop. |
className |
string | ((state: MenuTriggerState) => string | undefined) |
No | Additional CSS classes for the underlying element. |
render |
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, MenuTriggerState> |
No | Replace the underlying element using render composition. |
style |
CSSProperties | ((state: MenuTriggerState) => CSSProperties | undefined) |
No | Inline styles for the underlying element. |
Composer.SubmitMenuContent
Section titled “Composer.SubmitMenuContent”Also accepts native element props.
| Prop | Type | Required | Description |
|---|---|---|---|
children |
ReactNode |
No | Content rendered inside the component. |
id |
string |
No | Element identifier. |
finalFocus |
boolean | RefObject<HTMLElement | null> | ((closeType: InteractionType) => boolean | HTMLElement | null | void) |
No | Determines the element to focus when the menu is closed. |
className |
string | ((state: ContextMenuPopupState) => string | undefined) |
No | Additional CSS classes for the underlying element. |
render |
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ContextMenuPopupState> |
No | Replace the underlying element using render composition. |
style |
CSSProperties | ((state: ContextMenuPopupState) => CSSProperties | undefined) |
No | Inline styles for the underlying element. |
align |
Align |
No | Alignment of the component. |
alignOffset |
number | OffsetFunction |
No | Additional offset along the alignment axis in pixels. |
side |
Side |
No | Side on which the popup or panel appears. |
sideOffset |
number | OffsetFunction |
No | Distance between the anchor and the popup in pixels. |
Composer.SubmitMenuItem
Section titled “Composer.SubmitMenuItem”Also accepts native element props.
| Prop | Type | Required | Description |
|---|---|---|---|
onClick |
((event: BaseUIEvent<MouseEvent<HTMLDivElement, MouseEvent>>) => void) |
No | The click handler for the menu item. |
disabled |
boolean |
No | Disable interaction. |
label |
string |
No | Accessible or displayed label for the control. |
id |
string |
No | Element identifier. |
closeOnClick |
boolean |
No | Whether to close the menu when the item is clicked. |
nativeButton |
boolean |
No | Whether the component renders a native <button> element when replacing it via the render prop. |
children |
ReactNode |
No | Content rendered inside the component. |
className |
string | ((state: ContextMenuItemState) => string | undefined) |
No | Additional CSS classes for the underlying element. |
render |
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ContextMenuItemState> |
No | Replace the underlying element using render composition. |
style |
CSSProperties | ((state: ContextMenuItemState) => CSSProperties | undefined) |
No | Inline styles for the underlying element. |
inset |
boolean |
No | Inset the menu item to align it with neighboring items. |
variant |
"default" | "destructive" |
No | Appearance variant. |
Composer.Stop
Section titled “Composer.Stop”Also accepts native element props.
| Prop | Type | Required | Description |
|---|---|---|---|
style |
CSSProperties | ((state: ButtonState) => CSSProperties | undefined) |
No | Inline styles for the underlying element. |
className |
string | ((state: ButtonState) => string | undefined) |
No | Additional CSS classes for the underlying element. |
variant |
"link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null |
No | Appearance variant. |
size |
"sm" | "xs" | "icon-xs" | "icon-sm" | null |
No | Size variant. |
render |
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ButtonState> |
No | Replace the underlying element using render composition. |
type |
"button" | "submit" | "reset" |
No | File MIME type. |
focusableWhenDisabled |
boolean |
No | Whether the button should be focusable when disabled. |
nativeButton |
boolean |
No | Whether the component renders a native <button> element when replacing it via the render prop. |
label |
string |
No | Accessible or displayed label for the control. Default: "Stop response". |
Composer.RecordAudio
Section titled “Composer.RecordAudio”| Prop | Type | Required | Description |
|---|---|---|---|
status |
AudioRecordingStatus |
Yes | Current operation status. |
level |
RefObject<number> |
No | Ref containing the current audio level. |
onStart |
() => void |
Yes | Start recording. |
onStop |
() => void |
Yes | Stop recording. |
disabled |
boolean |
No | Disable interaction. Default: false. |
processingLabel |
string |
No | Label shown while recorded audio is processing. Default: "Processing…". |
Composer.RecordingError
Section titled “Composer.RecordingError”| Prop | Type | Required | Description |
|---|---|---|---|
error |
string | null |
No | Error text to display. |
Composer.AttachMenu
Section titled “Composer.AttachMenu”| Prop | Type | Required | Description |
|---|---|---|---|
onFiles |
(files: File[]) => void |
Yes | Receive files selected, pasted, or dropped into the component. |
children |
ReactNode |
Yes | Content rendered inside the component. |
Composer.AttachCamera
Section titled “Composer.AttachCamera”| Prop | Type | Required | Description |
|---|---|---|---|
capture |
"user" | "environment" |
No | Request a front or rear camera from supported file pickers. |
Composer.AttachPhotos
Section titled “Composer.AttachPhotos”Also accepts native element props.
| Prop | Type | Required | Description |
|---|---|---|---|
label |
string |
No | Accessible or displayed label for the control. |
style |
CSSProperties | ((state: ContextMenuItemState) => CSSProperties | undefined) |
No | Inline styles for the underlying element. |
className |
string | ((state: ContextMenuItemState) => string | undefined) |
No | Additional CSS classes for the underlying element. |
variant |
"default" | "destructive" |
No | Appearance variant. |
id |
string |
No | Element identifier. |
render |
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ContextMenuItemState> |
No | Replace the underlying element using render composition. |
disabled |
boolean |
No | Disable interaction. |
nativeButton |
boolean |
No | Whether the component renders a native <button> element when replacing it via the render prop. |
closeOnClick |
boolean |
No | Whether to close the menu when the item is clicked. |
inset |
boolean |
No | Inset the menu item to align it with neighboring items. |
multiple |
boolean |
No | Allow selecting multiple files. |
Composer.AttachFiles
Section titled “Composer.AttachFiles”Also accepts native element props.
| Prop | Type | Required | Description |
|---|---|---|---|
label |
string |
No | Accessible or displayed label for the control. |
style |
CSSProperties | ((state: ContextMenuItemState) => CSSProperties | undefined) |
No | Inline styles for the underlying element. |
className |
string | ((state: ContextMenuItemState) => string | undefined) |
No | Additional CSS classes for the underlying element. |
variant |
"default" | "destructive" |
No | Appearance variant. |
id |
string |
No | Element identifier. |
render |
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ContextMenuItemState> |
No | Replace the underlying element using render composition. |
disabled |
boolean |
No | Disable interaction. |
nativeButton |
boolean |
No | Whether the component renders a native <button> element when replacing it via the render prop. |
closeOnClick |
boolean |
No | Whether to close the menu when the item is clicked. |
inset |
boolean |
No | Inset the menu item to align it with neighboring items. |
multiple |
boolean |
No | Allow selecting multiple files. |
Composer.AttachPhotosAndFiles
Section titled “Composer.AttachPhotosAndFiles”Also accepts native element props.
| Prop | Type | Required | Description |
|---|---|---|---|
label |
string |
No | Accessible or displayed label for the control. |
style |
CSSProperties | ((state: ContextMenuItemState) => CSSProperties | undefined) |
No | Inline styles for the underlying element. |
className |
string | ((state: ContextMenuItemState) => string | undefined) |
No | Additional CSS classes for the underlying element. |
variant |
"default" | "destructive" |
No | Appearance variant. |
id |
string |
No | Element identifier. |
render |
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ContextMenuItemState> |
No | Replace the underlying element using render composition. |
disabled |
boolean |
No | Disable interaction. |
nativeButton |
boolean |
No | Whether the component renders a native <button> element when replacing it via the render prop. |
closeOnClick |
boolean |
No | Whether to close the menu when the item is clicked. |
inset |
boolean |
No | Inset the menu item to align it with neighboring items. |
multiple |
boolean |
No | Allow selecting multiple files. |
Composer.AttachOption
Section titled “Composer.AttachOption”Also accepts native element props.
| Prop | Type | Required | Description |
|---|---|---|---|
label |
string |
No | Accessible or displayed label for the control. |
style |
CSSProperties | ((state: ContextMenuItemState) => CSSProperties | undefined) |
No | Inline styles for the underlying element. |
className |
string | ((state: ContextMenuItemState) => string | undefined) |
No | Additional CSS classes for the underlying element. |
variant |
"default" | "destructive" |
No | Appearance variant. |
id |
string |
No | Element identifier. |
children |
ReactNode |
No | Content rendered inside the component. |
render |
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ContextMenuItemState> |
No | Replace the underlying element using render composition. |
disabled |
boolean |
No | Disable interaction. Default: false. |
nativeButton |
boolean |
No | Whether the component renders a native <button> element when replacing it via the render prop. |
closeOnClick |
boolean |
No | Whether to close the menu when the item is clicked. |
inset |
boolean |
No | Inset the menu item to align it with neighboring items. |
accept |
string |
Yes | File-picker accept filter, such as image/* or .pdf. |
multiple |
boolean |
No | Allow selecting multiple files. Default: true. |
capture |
"user" | "environment" |
No | Request a front or rear camera from supported file pickers. |
Composer.AttachImages
Section titled “Composer.AttachImages”Also accepts native element props.
| Prop | Type | Required | Description |
|---|---|---|---|
label |
string |
No | Accessible or displayed label for the control. |
style |
CSSProperties | ((state: ContextMenuItemState) => CSSProperties | undefined) |
No | Inline styles for the underlying element. |
className |
string | ((state: ContextMenuItemState) => string | undefined) |
No | Additional CSS classes for the underlying element. |
variant |
"default" | "destructive" |
No | Appearance variant. |
id |
string |
No | Element identifier. |
render |
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ContextMenuItemState> |
No | Replace the underlying element using render composition. |
disabled |
boolean |
No | Disable interaction. |
nativeButton |
boolean |
No | Whether the component renders a native <button> element when replacing it via the render prop. |
closeOnClick |
boolean |
No | Whether to close the menu when the item is clicked. |
inset |
boolean |
No | Inset the menu item to align it with neighboring items. |
capture |
"user" | "environment" |
No | Request a front or rear camera from supported file pickers. |
multiple |
boolean |
No | Allow selecting multiple files. |
Composer.AttachPDF
Section titled “Composer.AttachPDF”Also accepts native element props.
| Prop | Type | Required | Description |
|---|---|---|---|
label |
string |
No | Accessible or displayed label for the control. |
style |
CSSProperties | ((state: ContextMenuItemState) => CSSProperties | undefined) |
No | Inline styles for the underlying element. |
className |
string | ((state: ContextMenuItemState) => string | undefined) |
No | Additional CSS classes for the underlying element. |
variant |
"default" | "destructive" |
No | Appearance variant. |
id |
string |
No | Element identifier. |
render |
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ContextMenuItemState> |
No | Replace the underlying element using render composition. |
disabled |
boolean |
No | Disable interaction. |
nativeButton |
boolean |
No | Whether the component renders a native <button> element when replacing it via the render prop. |
closeOnClick |
boolean |
No | Whether to close the menu when the item is clicked. |
inset |
boolean |
No | Inset the menu item to align it with neighboring items. |
capture |
"user" | "environment" |
No | Request a front or rear camera from supported file pickers. |
multiple |
boolean |
No | Allow selecting multiple files. |