Glin UI
Primitive / Organismbeta

Prompt Input

Auto-growing chat composer with send and stop, IME-safe Enter handling, attachment slot and character hint.

Edit on GitHub
q3-report.pdf471 KB
metrics.csv94 KB
2 attachedPress Enter to send, Shift and Enter for a new line.

Installation

Install from
pnpm dlx @glinui/cli@latest add prompt-input

Prefer the package?

Usage

Variants

import { PromptInput } from "@glinui/ui"
export function Demo() {
return (
<div className="flex w-full max-w-xl flex-col gap-3">
<PromptInput variant="glinr" placeholder="glinr" showHint={false} />
<PromptInput variant="plain" placeholder="plain" showHint={false} />
<PromptInput variant="soft" placeholder="soft" showHint={false} />
<PromptInput variant="outline" placeholder="outline" showHint={false} />
</div>
)
}

Glass (opt-in)

Glass is opt-in and needs a backdrop behind it: pick Photo or Vivid in the stage backdrop switcher.

import { PromptInput } from "@glinui/ui"
export function Demo() {
return (
<PromptInput variant="glass" defaultValue="Summarize this thread" />
)
}

Accessibility

  • Native textarea with an aria-label and an aria-describedby hint for the send shortcut.
  • Enter during an IME composition (Japanese, Chinese, Korean) confirms the text and never sends.
  • While loading the field is read-only (focus is kept) and the stop button replaces send.
  • Send and stop buttons have explicit labels.

Keyboard Interactions

KeyAction
EnterSend (default mode).
Shift + EnterInsert a new line.
Cmd/Ctrl + EnterSend in mod-enter mode.

ARIA Attributes

  • `aria-label` on the textarea
  • `aria-describedby` hint
  • `aria-busy` while loading

Reduced Motion

Focus and button transitions are disabled under reduced motion.

Affected properties

border-colorbox-shadowopacity

API Reference

PropTypeRequiredDefaultDescription
value / defaultValuestring--Controlled or uncontrolled text.
onSubmit(value: string) => voidNo-Called with the trimmed text on send.
onStop() => voidNo-With loading, swaps the send button for a stop button.
loadingbooleanNofalseRead-only field, send blocked, aria-busy set.
submitOn"enter" | "mod-enter"NoenterEnter sends (Shift+Enter newline) or Cmd/Ctrl+Enter sends.
maxLengthnumberNo-Enables the character count hint.
variantControlVariantPropNoambient (glinr)Shell look. Omit to follow the ambient design style (glinr = raised shell). Glass is opt-in.
attachments / actionsReactNode--Slots above the textarea and in the footer.
labelstringNo"Message"Accessible name of the textarea.
actionsReact.ReactNodeNo-Rendered at the start of the footer, e.g. attach and model buttons.
attachmentsReact.ReactNodeNo-Rendered above the textarea, e.g. a row of `Attachment`.
defaultValuestringNo""Auto-generated from TypeScript source.
disabledbooleanNofalseAuto-generated from TypeScript source.
onValueChange(value: string) => voidNo-Auto-generated from TypeScript source.
placeholderstringNo"Ask anything"Auto-generated from TypeScript source.
rowsnumberNo1Auto-generated from TypeScript source.
sendLabelstringNo"Send message"Auto-generated from TypeScript source.
showHintbooleanNotrueShow the keyboard hint and character count.
stopLabelstringNo"Stop generating"Auto-generated from TypeScript source.
valuestringNo-Auto-generated from TypeScript source.

Source

Import directly from the package or browse the source on GitHub. Click any file to view it.

Import

import { PromptInput } from "@glinui/ui"

Source Files

Dependencies

@glinui/ui@phosphor-icons/reactclass-variance-authority

Generated API Snapshot

Beta

Auto-extracted from TypeScript source in packages/ui/src/components/prompt-input.tsx. This section is in beta and may lag behind hand-curated docs. Regenerate with pnpm --filter @glinui/docs api:generate.

Generated: 2026-10-08T01:41:21.546Z · Full index: /docs/api-metadata

Primary Props Type

PromptInputProps

PromptInputProps

PropTypeRequiredDefaultDescription
actionsReact.ReactNodeNo-Rendered at the start of the footer, e.g. attach and model buttons.
attachmentsReact.ReactNodeNo-Rendered above the textarea, e.g. a row of `Attachment`.
defaultValuestringNo""-
disabledbooleanNofalse-
labelstringNo"Message"Accessible name of the textarea.
loadingbooleanNofalseA response is streaming: input becomes read-only and send is blocked.
maxLengthnumberNo--
onStop() => voidNo-When set and `loading`, the send button becomes a stop button.
onSubmit(value: string) => voidNo-Called with the trimmed value when the user sends.
onValueChange(value: string) => voidNo--
placeholderstringNo"Ask anything"-
rowsnumberNo1-
sendLabelstringNo"Send message"-
showHintbooleanNotrueShow the keyboard hint and character count.
stopLabelstringNo"Stop generating"-
submitOn"enter" | "mod-enter"No"enter"`enter` sends on Enter (Shift+Enter newline). `mod-enter` sends on Cmd/Ctrl+Enter.
valuestringNo--
variantControlVariantPropNo-Shell look. Omit to follow the ambient design style (glinr = raised shell). Same vocabulary as Input.