Composer

A chat-style prompt input that grows with content, paired with a toolbar and a submit button.

Anatomy

A root holds the empty and focus state. The input is a styled textarea that registers a submit handler with the root, so the same submit button drives whichever input is mounted. The toolbar sits below the input as a separate strip.

TSX

Keyboard

  • Enter submits when the input is non-empty.
  • Shift+Enter inserts a newline.
  • Tab moves focus out of the input as expected.

API

Reference for each part of the component, including its available props and behavior.

Composer

The root. Owns the empty and focus state, the disabled flag, and the registration channel for inputs. Renders a relative flex column so the toolbar sits below the input and any future floating UI can anchor to the root.

The root is engine-agnostic. It tracks empty and focus state and exposes a registration hook that any input can hand its submit handler to. The default ComposerInput registers a textarea-based handler. For mentions, commands, and chips, drop in ComposerRichInput from composer-rich instead.

Prop

ComposerInput

A styled textarea that registers a submit handler with the root. Autosizes between one row and maxRows lines. Sends on Enter without Shift, ignores Enter during IME composition so input methods can commit without firing submit.

The input runs in either mode. Leave value unset and the component manages its own state, optionally seeded by defaultValue, and clears itself after submit. Pass value together with onValueChange to hand state ownership to the parent. In that mode the parent decides when to clear, typically by setting value to an empty string after onSubmit.

Prop

ComposerToolbar

The bottom strip below the input. A flex row with a top divider. Drop in any buttons or menus. Keep ComposerToolbarSpacer near the end to push the trailing controls to the right.

Prop

ComposerToolbarSpacer

A flex group with ml-auto. Wraps the trailing controls so they cluster to the right edge of the toolbar.

Prop

ComposerSubmit

A headless trigger wired to the registered input's submit action. Renders a plain <button> by default and exposes a render prop so the consumer supplies the real button. The submit applies disabled whenever the input is empty or the root is disabled, and surfaces data-empty for fine-grained styling. Children pass through to the rendered element so the icon stays outside the styling concern.

TSX
Prop

useComposer

Hook for reading root state and triggering submit from a custom part. Returns { isEmpty, isFocused, disabled, submit }. Use it when building a custom submit button or a status indicator.

TSX