Voice UI Kit

Text Input

Text input component for sending text messages to the bot

The TextInput component provides a user interface for entering and sending textual messages to the bot. It includes both a headless variant for full control and a connected variant that automatically integrates with the Pipecat Client SDK.

import { TextInputComponent } from "@pipecat-ai/voice-ui-kit";

<TextInputComponent
  placeholder="Type your message..."
  onSend={(message) => console.log("Sending:", message)}
  classNames={{
    container: "w-full",
  }}
/>

Component Variants

TextInput

The TextInput component is the connected variant that automatically integrates with the Pipecat Client SDK. It must be used within a PipecatClientProvider context.

import { TextInput } from "@pipecat-ai/voice-ui-kit";

<TextInput placeholder="Ask me anything..." />
PropTypeDefault
debounceTime?
number
300
disabled?
boolean
false
sendTextOptions?
SendTextOptions
undefined
noInject?
boolean
false
noConnectedPlaceholder?
string
"Connect to send"
onSend?
(message: string) => Promise<void> | void
undefined
multiline?
boolean
false
buttonLabel?
React.ReactNode
undefined
buttonIcon?
React.ReactNode
<SendIcon />
buttonProps?
ButtonProps
undefined
classNames?
{ container?: string; input?: string; button?: string; }
undefined
placeholder?
string
"Type message..."
size?
"sm" | "md" | "lg" | "xl"
"md"

SendTextOptions

The sendTextOptions prop accepts an object with the following properties:

PropTypeDefault
run_immediately?
boolean
true
audio_response?
boolean
true

TextInputComponent

The TextInputComponent is the headless variant that accepts all callbacks and state as props. This allows you to use it with any framework or state management solution.

import { TextInputComponent } from "@pipecat-ai/voice-ui-kit";

function Demo() {
  const handleSend = async (message: string) => {
    console.log("Sending message:", message);
    // Simulate API call
    await new Promise(resolve => setTimeout(resolve, 1000));
  };

  return (
    <TextInputComponent
      placeholder="Type your message..."
      onSend={handleSend}
      buttonLabel="Send Message"
    />
  );
}

render(<Demo />);
PropTypeDefault
debounceTime?
number
300
onSend?
(message: string) => Promise<void> | void
undefined
disabled?
boolean
false
multiline?
boolean
false
buttonLabel?
React.ReactNode
undefined
buttonIcon?
React.ReactNode
<SendIcon />
buttonProps?
ButtonProps
undefined
classNames?
{ container?: string; input?: string; button?: string; }
undefined
placeholder?
string
"Type message..."
size?
"sm" | "md" | "lg" | "xl"
"md"

Usage Examples

Custom Button Label

You can customize the send button with a custom label.

import { TextInputComponent } from "@pipecat-ai/voice-ui-kit";

function Demo() {
  return (
    <TextInputComponent
      placeholder="Ask a question..."
      buttonLabel="Ask Bot"
      onSend={(message) => console.log("Asking:", message)}
    />
  );
}

render(<Demo />);

Custom Button Icon

You can use a custom icon for the send button.

import { TextInputComponent } from "@pipecat-ai/voice-ui-kit";
import { MessageCircle } from "lucide-react";

function Demo() {
  return (
    <TextInputComponent
      placeholder="Send a message..."
      buttonIcon={<CircleIcon size={16} />}
      onSend={(message) => console.log("Sending:", message)}
    />
  );
}

render(<Demo />);

Multiline Input

Enable multiline input for longer messages.

import { TextInputComponent } from "@pipecat-ai/voice-ui-kit";

function Demo() {
  return (
    <TextInputComponent
      placeholder="Type a longer message..."
      multiline={true}
      onSend={(message) => console.log("Sending:", message)}
    />
  );
}

render(<Demo />);

Custom Styling

Apply custom CSS classes to different parts of the component.

import { TextInputComponent } from "@pipecat-ai/voice-ui-kit";

function Demo() {
  return (
    <TextInputComponent
      placeholder="Styled input..."
      classNames={{
        container: "border-2 border-primary rounded-lg p-2",
        input: "bg-gray-50 border-none focus:ring-2 focus:ring-primary",
        button: "bg-primary text-white hover:bg-primary/90",
      }}
      onSend={(message) => console.log("Sending:", message)}
    />
  );
}

render(<Demo />);

Disabled State

The component can be disabled and shows appropriate visual feedback.

import { TextInputComponent } from "@pipecat-ai/voice-ui-kit";

function Demo() {
  return (
    <TextInputComponent
      placeholder="This input is disabled..."
      disabled={true}
      onSend={(message) => console.log("Sending:", message)}
    />
  );
}

render(<Demo />);

Size

You can use different sizes for the input and button components.

import { TextInputComponent } from "@pipecat-ai/voice-ui-kit";

function Demo() {
  return (
    <TextInputComponent
      placeholder="Type your message..."
      size="lg"
      onSend={(message) => console.log("Sending:", message)}
    />
  );
}

render(<Demo />);

SendTextOptions

You can customize how the bot handles text messages using the sendTextOptions prop.

import { TextInput } from "@pipecat-ai/voice-ui-kit";

<TextInput
  placeholder="Send a text-only message..."
  sendTextOptions={{
    run_immediately: true,
    audio_response: false, // Bot will respond with text only, no TTS
  }}
/>

Disable Message Injection

By default, messages sent via TextInput are automatically injected into the conversation store. You can disable this behavior with the noInject prop if you want to handle message injection manually.

import { TextInput } from "@pipecat-ai/voice-ui-kit";

<TextInput
  placeholder="Send without auto-injecting..."
  noInject={true}
  onSend={(message) => {
    console.log("Message sent:", message);
    // Handle message injection manually if needed
  }}
/>

Multiline Input

The component can be configured for multiline or single-line input. When multiline={false}, it uses a single-line input field that prevents line breaks.

import { TextInputComponent } from "@pipecat-ai/voice-ui-kit";

<TextInputComponent
  placeholder="Press shift+enter to add a new line..."
  multiline={true}
  classNames={{
    container: "w-full",
  }}
/>

Multiline Behavior

The component dynamically switches between input types based on the multiline prop:

  • multiline={true}: Uses a Textarea component that allows multiple lines and supports Shift+Enter for new lines
  • multiline={false}: Uses a single-line Input component that prevents line breaks and only allows Enter to send the message