ChatInput

ChatInput is a multi-part textarea component built for AI chat interfaces — auto-resizing input, send/stop button, and loading state managed as a single unit.

2
Variants
3
Sizes
3
Parts
Pure
React

Playground

Preview
outlinedefaultdefault
ChatInput
Variant
Color
Layout
Size
Radius
State
Options
Submit
Radius
<ChatInput onSubmit={(value) => console.log(value)}>
  <ChatInputField placeholder="Ask me anything..." />
  <ChatInputSubmit />
</ChatInput>

Variants

Outline
Default bordered style — clean and versatile for most backgrounds.
Default
Filled
Filled background style — blends into chat UI surfaces with minimal contrast.
Emphasis

Sizes

sm
Button28px
Font14px
Padding10px / 12px
default
Button32px
Font14px
Padding12px / 16px
lg
Button36px
Font16px
Padding16px / 20px

Features

Auto Resize

The textarea grows with content and shrinks when lines are removed — bound by maxRows.

<ChatInput onSubmit={(value) => console.log(value)}>
  <ChatInputField
    placeholder="Type multiple lines (Shift+Enter for newline)..."
    maxRows={5}
  />
  <ChatInputSubmit />
</ChatInput>

Character Count

Combine showCount with maxLength to display a live character counter in the bottom-right corner.

<ChatInput onSubmit={(value) => console.log(value)}>
  <ChatInputField
    placeholder="Ask me anything..."
    showCount
    maxLength={500}
  />
  <ChatInputSubmit />
</ChatInput>

Loading State

Set loading=true to switch the button to a stop icon — button stays enabled so users can abort.

<ChatInput onSubmit={(value) => console.log(value)}>
  <ChatInputField placeholder="Response generating..." />
  <ChatInputSubmit loading onStop={() => console.log('stopped')} />
</ChatInput>

Filled Variant

variant="filled" uses a muted background with no border, ideal for chat surfaces where the input should recede.

<ChatInput variant="filled" onSubmit={(value) => console.log(value)}>
  <ChatInputField placeholder="Ask me anything..." />
  <ChatInputSubmit />
</ChatInput>

Disabled

disabled disables both input and submit together — communicated visually with reduced opacity.

<ChatInput disabled onSubmit={(value) => console.log(value)}>
  <ChatInputField placeholder="Currently unavailable..." />
  <ChatInputSubmit />
</ChatInput>

Customization

Replace the default send icon via the children prop on ChatInputSubmit.

Custom Icon

<ChatInputSubmit> <ArrowUp className="icon-xs" /> </ChatInputSubmit>

Voice Input Style

<ChatInputSubmit> <Mic className="icon-xs" /> </ChatInputSubmit>

API

Component Structure

ChatInput— Compound · Pure React
ChatInputContext provider + container
ChatInputFieldAuto-resizing textarea
ChatInputSubmitSend / stop button

Multi-part component — ChatInput (root), ChatInputField (textarea), ChatInputSubmit (send button).

Props

ChatInput

variant"outline"
"outline" | "filled"

Visual style — outline (bordered) or filled (muted background)

size"default"
"sm" | "default" | "lg"

Size scale — sm, default, or lg

radius"xl"
"sm" | "md" | "lg" | "xl" | "2xl" | "full"

Container corner radius

color"default"
"default" | "primary"

Submit button color — default (dark) or primary (brand)

layout"default"
"default" | "inline"

Layout direction — default (stacked) or inline (field + button side by side)

disabledfalse
boolean

Disable both input and submit together

onSubmitundefined
(value: string) => void

Submit callback — receives the current text value

classNameundefined
string

Additional CSS classes

ChatInputField

maxRows8
number

Maximum visible rows before the field scrolls

showCountfalse
boolean

Show character counter — requires maxLength

maxLengthundefined
number

Maximum character count

placeholderundefined
string

Placeholder text shown when empty

classNameundefined
string

Additional CSS classes

ChatInputSubmit

loadingfalse
boolean

Switch to stop icon — button stays enabled

onStopundefined
() => void

Called when clicked in loading state

buttonRadiusundefined
"sm" | "md" | "lg" | "xl" | "2xl" | "full"

Override button corner radius — auto-calculated from container radius when omitted

childrenundefined
ReactNode

Custom icon — defaults to send icon

classNameundefined
string

Additional CSS classes

Anatomy

1
2
3
4
0 / 500
5
1
ChatInput
Container — context provider
2
ChatInputField
Textarea (auto-resizes)
3
ChatInputSubmit
Submit row — counter + button
4
Counter
Optional character counter
5
Send Button
Send / stop icon button

Best Practices

Recommended

  • Manage loading state in onSubmit for async sends
  • Set maxRows to prevent unbounded growth
  • Use a clear placeholder to indicate purpose

Don't

  • Don't mutate field value outside onSubmit in uncontrolled mode
  • Don't combine loading and disabled — they conflict
  • Don't use for general-purpose forms — use Textarea instead

Accessibility

Keyboard

EnterSubmit the message
Shift + EnterInsert a line break
TabMove focus to the submit button

ARIA / WCAG

  • textarea element — screen readers announce correctly
  • Submit button has automatic aria-label (Send / Stop)
  • Disabled state is visually and semantically distinct