DocsChatComponentsChatInputComponent

ChatInputComponent

ChatInputComponent is the text input primitive for sending messages to a LangGraph agent. It provides a textarea with auto-sizing, a send button, keyboard handling, and automatic disabling while the agent is loading.

Selector: chat-input

Import:

import { ChatInputComponent, submitMessage } from '@ngaf/chat';

Basic Usage

<chat-input
  [agent]="chatRef"
  [submitOnEnter]="true"
  placeholder="Type a message..."
  (submitted)="onMessageSent($event)"
/>

API

Inputs

InputTypeDefaultDescription
agentAgentRequiredThe agent to submit messages to
submitOnEnterbooleantrueWhen true, pressing Enter submits the message. Shift+Enter inserts a newline. When false, Enter always inserts a newline.
placeholderstring''Placeholder text shown when the input is empty

Outputs

OutputTypeDescription
submittedstringEmits the trimmed message text after successful submission

Behavior

Submit Flow

When the user submits (via Enter key or clicking the send button):

  1. The message text is trimmed
  2. If empty after trimming, nothing happens
  3. agent.submit() is called with { message: trimmed }
  4. The submitted output emits the trimmed text
  5. The input is cleared
  6. Focus is returned to the textarea

Disabled State

The input is automatically disabled when agent.isLoading() returns true. This prevents sending messages while the agent is processing. Both the textarea and the send button reflect the disabled state.

Auto-Sizing

The textarea uses field-sizing: content CSS, which allows it to grow with its content up to a maximum height of 120px. After that, the textarea scrolls internally.

Keyboard Handling

KeysubmitOnEnter: truesubmitOnEnter: false
EnterSubmits the messageInserts a newline
Shift+EnterInserts a newlineInserts a newline

submitMessage() Helper

The submitMessage() function is exported as a standalone utility for programmatic message submission:

import { submitMessage } from '@ngaf/chat';
import type { Agent } from '@ngaf/chat';
 
function sendGreeting(agent: Agent) {
  const result = submitMessage(agent, 'Hello!');
  // result is 'Hello!' or null if the text was empty
}

Signature:

function submitMessage(
  agent: Agent,
  text: string
): string | null
ParameterTypeDescription
agentAgentThe agent to submit to
textstringThe message text to send

Returns: The trimmed message string if submitted, or null if the trimmed text was empty.

The function calls agent.submit({ message: trimmed }) under the hood.

Slots

[chatInputModelSelect]

Projects content into the controls row of the input pill, between [chatInputTrailing] and the send button. Designed for <chat-select> (a model picker), but accepts any element.

<chat-input [agent]="agent">
  <chat-select chatInputModelSelect [options]="opts" [(value)]="selected" />
</chat-input>

Styling

The component renders a <form> containing a <textarea> and a <button>. It uses the following CSS custom properties from the chat theme:

VariableApplied To
--ngaf-chat-surface-altForm background
--ngaf-chat-separatorForm border (unfocused)
--ngaf-chat-mutedForm border (focused)
--ngaf-chat-radius-inputForm border radius
--ngaf-chat-textTextarea text color
--ngaf-chat-font-familyTextarea font
--ngaf-chat-primarySend button background
--ngaf-chat-on-primarySend button icon color

ARIA

The component includes accessibility attributes:

  • The form has role="search" and aria-label="Message input"
  • The textarea has aria-label="Type a message"
  • The send button has aria-label="Send message"

Full Example

import { Component, signal, ChangeDetectionStrategy } from '@angular/core';
import { agent } from '@ngaf/langgraph';
import { ChatInputComponent } from '@ngaf/chat';
 
@Component({
  selector: 'app-input-demo',
  standalone: true,
  imports: [ChatInputComponent],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <div class="border rounded-lg p-4">
      <chat-input
        [agent]="chatRef"
        [submitOnEnter]="true"
        placeholder="Ask a question..."
        (submitted)="lastMessage.set($event)"
      />
      @if (lastMessage()) {
        <p class="text-sm mt-2 text-gray-500">
          Last sent: {{ lastMessage() }}
        </p>
      }
    </div>
  `,
})
export class InputDemoComponent {
  chatRef = agent({
    assistantId: 'chat_agent',
    threadId: signal(null),
  });
 
  lastMessage = signal('');
}