Skip to content
ComposerSend buttonMenu

Send button

Send that becomes Stop in the same footprint: the arrow lifts and blurs out while the kit's square mark settles in.

The full cycle in one footprint: empty, ready, sending, streaming.

Installation

$ pnpm dlx shadcn@latest add https://chatcn.dev/r/send-button.json

Usage

tsx
import { SendButton } from "@/components/ui/chatcn/send-button"

<SendButton status={status} empty={!text.trim()} onStop={stop} />

Inside a PromptInput, use PromptInputSubmit, which wires all of this for you. Outside one, it is a submit button while idle and a plain button that calls onStop while streaming.

Examples

Shapes and sizes

Round and square at 28, 32 and 36 px, in every state.

Props

PropTypeNotes
status"idle" | "submitting" | "streaming"Arrow, spinner or stop square
emptybooleanThe only reason Send is inactive. Stays focusable
onStop() => voidCalled on click while streaming
shape"round" | "square"Default round
size"sm" | "md" | "lg"28, 32 or 36 px. 44 px hit area on touch
labels{ send?, stop?, submitting? }Accessible names for your language

Accessibility

  • Empty is aria-disabled, not disabled: after Stop the input is often empty, and a disabled button would drop focus onto the page.
  • aria-keyshortcuts advertises Enter while idle and Escape while streaming.
  • The name changes with the state, so a screen reader hears Stop generating the moment it applies.

Motion

  • Each glyph is its own layer. Changes crossfade over 150 ms with a 2 px blur: the arrow lifts 4 px and shrinks to 0.9, the square grows from 0.5.
  • Same footprint in every state, so nothing around it moves.
  • Press scales to 0.94. Reduced motion keeps the crossfade and drops the blur, lift and scale.