Prompt composer
Free · MITReact Native · ExpoThe input for AI apps: a field that grows with the text on a spring, chips that add phrases to the prompt, and a send button that morphs into a stop square while a job runs.
Installation
$ npx shadcn@latest add https://goodui.dev/native/r/prompt-composer.jsonThen run npx expo install --fix so react-native-reanimated, react-native-svg match your Expo SDK. Files land in components/goodui-native/prompt-composer.
Usage
import { useState } from "react";
import { PromptComposer } from "@/components/goodui-native/prompt-composer/prompt-composer";
const [prompt, setPrompt] = useState("");
<PromptComposer
value={prompt}
onChangeText={setPrompt}
onSubmit={(text) => generate(text)}
busy={running}
onStop={cancel}
chips={[{ id: "studio", label: "Studio light" }, { id: "film", label: "Film grain" }]}
/>When to use
- Describing what to generate, with optional suggested phrases.
- A chat reply bar that needs a stop button while the answer streams.
- Search: use search-bar.
- Person-to-person chat: chat-screen has its own composer.
API reference
| Prop | Type | Default |
|---|---|---|
| value* | string | — |
| onChangeText* | (text: string) => void | — |
| onSubmit* Send was pressed with text in the field. | (text: string) => void | — |
| busy A job is running: send morphs into a stop square. | boolean | false |
| onStop | () => void | — |
| chips Tappable phrases above the field; a tap appends and the chip fills. | PromptChip[] | — |
| leading A button left of the field: attach, camera. | ReactNode | — |
| emptyAction Empty-field action in place of send, usually the voice button. | ReactNode | — |
| footer Sits under the text, inside the box: a live cost. | ReactNode | — |
| maxLines | number | 6 |
| inputRef | Ref<ComponentRef<typeof TextInput>> | — |
| labels | Partial<PromptComposerLabels> | — |
| style Style for the outer container. | StyleProp<ViewStyle> | — |
| testID Identifier for end-to-end tests. | string | — |
Motion and haptics
- The field height springs as lines are added, up to maxLines.
- The arrow morphs into a stop square on the morph spring.
- Reduced motion: height and morph changes happen at once.
- Haptic: select on chips, send on submit, warning on stop.
- The field height and button morph run on the UI thread.
Accessibility
- The field uses the placeholder as its label, so keep it descriptive.
- The send button's label switches to Stop while busy, and it is disabled with no text.
- Chips expose their selected state.
Notes for AI
- It is controlled: pass value and onChangeText. Clear the value yourself in onSubmit if you want it cleared.
- `footer` renders under the text inside the box, a good place for CreditsCost.
- `emptyAction` replaces send while the field is empty, usually a voice button.
- Chip text is appended with a comma. A chip is on while its phrase is in the text, so editing the text updates it.
- Keep it above the keyboard in your own layout; it does not handle the keyboard itself.
Related
A balance pill for an app bar whose digits roll when the balance changes and which turns warning colored when low, plus CreditsCost, a live price line that says what a job costs and what is left after it.
Text that arrives word by word: new words fade up and a caret pulses at the end, and when streaming stops it becomes one plain text block.
A sphere of drifting color lobes for voice modes: idle, listening, thinking and speaking each move differently, it swells with the audio level, and a halo pulses behind it.
Cards for long AI jobs: each one shows its status, a fill and a light sweep while running, a rolling percentage, and cancel, retry and open actions.