ChatComposer

fun ChatComposer(onSendClick: (data: MessageData) -> Unit, onStopClick: () -> Unit, isGenerating: Boolean, modifier: Modifier = Modifier, messageData: MessageData = MessageData(), focusRequester: FocusRequester? = null)

Chat composer with attach, voice, and send buttons.

This composable provides full control over the message state and includes:

  • Text input field with placeholder

  • Add button for selecting images

  • Voice input button with speech-to-text

  • Send button (shown when text is not empty)

  • Stop button (shown during AI generating)

The rendered components are resolved through LocalChatAiComponentFactory, so each part can be overridden without replacing the whole composer. See CompoundChatAiComponentFactory.

The composer keeps the message being written itself. To own it instead, for example to fill in text from elsewhere or restore it after a refused send, use the overload that takes onMessageDataChange.

Parameters

onSendClick

Callback invoked when the send button is clicked with the composed message data.

onStopClick

Callback invoked when the stop button is clicked (during AI generation).

isGenerating

Whether the AI is currently generating a response.

modifier

The modifier to be applied to the composer.

messageData

The initial message data to be displayed in the input field.

focusRequester

Attached to the text field, so you can put the cursor in it with FocusRequester.requestFocus.


fun ChatComposer(messageData: MessageData, onMessageDataChange: (MessageData) -> Unit, onSendClick: (data: MessageData) -> Unit, onStopClick: () -> Unit, isGenerating: Boolean, modifier: Modifier = Modifier, focusRequester: FocusRequester? = null)

Chat composer with attach, voice, and send buttons, whose message the caller owns.

It renders exactly like the composer that keeps its own state, through the same LocalChatAiComponentFactory slots, but reads the message from messageData and reports every change through onMessageDataChange. Use it to put text in the composer from elsewhere (a suggestion, a restored draft) or to keep what was written when a send is refused.

var message by rememberSaveable(stateSaver = MessageData.Saver) { mutableStateOf(MessageData()) }
val focus = remember { FocusRequester() }

ChatComposer(
messageData = message,
onMessageDataChange = { message = it },
onSendClick = { sent -> if (!send(sent)) message = sent },
onStopClick = { stop() },
isGenerating = isGenerating,
focusRequester = focus,
)

Parameters

messageData

The message being written.

onMessageDataChange

Called with the new message whenever it changes: as the person types or dictates, picks or removes attachments, and with an empty message once it is sent.

onSendClick

Called with the message when the person sends it. The composer reports an empty message through onMessageDataChange just before; set the message back, here or later, to keep it.

onStopClick

Called when the stop button is clicked (during AI generation).

isGenerating

Whether the AI is currently generating a response.

modifier

The modifier to be applied to the composer.

focusRequester

Attached to the text field, so you can put the cursor in it with FocusRequester.requestFocus.