ChatView | Input Bar & Tools
Overview
Section titled “Overview”The input bar sits at the bottom of the ChatView and provides the primary message composition interface:
┌─────────────────────────────────────────┐│ […] [+] Type a message... [Send] │└─────────────────────────────────────────┘ ↑ ↑ ↑ Tools Attach Send button button button- Tools button (left) — Opens a floating menu for camera, voice, etc. (MAUI only, shown when
ToolItemshas items) - Attach button — Shows when
AttachImageCommandis bound - Text entry — Placeholder text, Enter-to-send
- Send button — Fires
SendCommandwith trimmed text
Basic Configuration
Section titled “Basic Configuration”<shiny:ChatView Messages="{Binding Messages}" SendCommand="{Binding SendCommand}" PlaceholderText="Ask me anything..." SendButtonText="Send" SendButtonBackgroundColor="#007AFF" SendButtonTextColor="White" InputBarBackgroundColor="#F5F5F5" InputBarBorderColor="#E0E0E0" IsInputBarVisible="True" />| Property | Type | Default | Description |
|---|---|---|---|
PlaceholderText | string | "Type a message..." | Input field placeholder |
SendButtonText | string | "Send" | Send button label |
SendButtonBackgroundColor | Color | #007AFF | Send button background color (MAUI only) |
SendButtonTextColor | Color | White | Send button text color (MAUI only) |
InputBarBackgroundColor | Color | #F5F5F5 | Input bar background color (MAUI only) |
InputBarBorderColor | Color | #E0E0E0 | Input bar top separator/border color (MAUI only) |
IsInputBarVisible | bool | true | Show/hide the entire input bar |
EntryText | string | "" | Get/set current input text (MAUI only) |
Send Behavior
Section titled “Send Behavior”Messages are sent when:
- The user taps the Send button
- The user presses Enter/Return (MAUI) or Enter without Shift (Blazor)
The SendCommand receives the trimmed text string. Empty/whitespace-only text is ignored. The input field is automatically cleared after a successful send.
Blazor: Shift+Enter for Multiline
Section titled “Blazor: Shift+Enter for Multiline”On Blazor, Shift+Enter allows multiline input without triggering send. On MAUI, the entry is single-line by default.
Programmatic Send (MAUI only)
Section titled “Programmatic Send (MAUI only)”// Set text without sendingchatView.EntryText = "Pre-filled response";
// Programmatically trigger sendchatView.SubmitEntry();This is how tools like SpeechToTextTool inject transcribed text and optionally auto-send it.
Attach Button
Section titled “Attach Button”The attach button (”+”) appears automatically when AttachImageCommand is bound:
<shiny:ChatView SendCommand="{Binding SendCommand}" AttachImageCommand="{Binding AttachCommand}" />[RelayCommand]async Task Attach(){ var result = await MediaPicker.PickPhotoAsync(); if (result is not null) { Messages.Add(new ChatMessage { ImageUrl = result.FullPath, SenderId = "me", IsFromMe = true, Timestamp = DateTimeOffset.Now }); }}When AttachImageCommand is null or not bound, the button is hidden.
Tools FAB Menu (MAUI only)
Section titled “Tools FAB Menu (MAUI only)”Add a floating action button menu to the left of the input bar for multiple composition actions:
<shiny:ChatView Messages="{Binding Messages}" SendCommand="{Binding SendCommand}" ToolsIcon="tools.png" ToolsFabBackgroundColor="#007AFF"> <shiny:ChatView.ToolItems> <shiny:ChatEntryTool Text="Camera" Icon="camera.png" FabBackgroundColor="#4CAF50" Command="{Binding TakePhotoCommand}" /> <shiny:ChatEntryTool Text="Gallery" Icon="gallery.png" FabBackgroundColor="#FF9800" Command="{Binding PickImageCommand}" /> <shiny:ChatEntryTool Text="Location" Icon="location.png" FabBackgroundColor="#2196F3" Command="{Binding ShareLocationCommand}" /> </shiny:ChatView.ToolItems></shiny:ChatView>| Property | Type | Default | Description |
|---|---|---|---|
ToolItems | IList<ChatEntryTool> | null | Items shown in the tools FAB menu |
ToolsIcon | ImageSource | null | Icon on the main tools button |
ToolsText | string? | null | Text label for the tools button |
ToolsFabBackgroundColor | Color | #007AFF | Background color of the tools button |
When ToolItems is empty or null, the tools button is hidden.
FAB Animation
Section titled “FAB Animation”The tools menu expands upward with a staggered animation:
- 30ms stagger between each item appearing
- 200ms duration per item (fade + translate from below)
- Semi-transparent backdrop covers the chat area
- Tapping the backdrop or any item closes the menu
SpeechToTextTool (MAUI only)
Section titled “SpeechToTextTool (MAUI only)”A pre-built tool that records speech and inserts the transcription into the input field. Requires the Shiny.Maui.Controls.SpeechAddins package.
<shiny:ChatView.ToolItems> <shiny:SpeechToTextTool AutoSend="False" SilenceTimeout="00:00:03" Culture="en-US" /></shiny:ChatView.ToolItems>| Property | Type | Default | Description |
|---|---|---|---|
AutoSend | bool | false | Automatically submit text after speech completes |
SilenceTimeout | TimeSpan | 2 seconds | How long to wait for silence before stopping |
Culture | string? | null | BCP 47 language code (null = device default) |
PreferOnDevice | bool | false | Prefer on-device recognition over cloud |
ListeningIcon | ImageSource? | null | Icon shown while recording |
ListeningText | string | "Listening…" | Label shown while recording |
ListeningFabBackgroundColor | Color | #F44336 (red) | Button color while recording |
Behavior:
- First tap starts listening — icon/text/color change to indicate recording state
- Speech is transcribed in real-time and appended to
chatView.EntryText - Recording stops on: second tap, silence timeout, or error
- If
AutoSend = true,chatView.SubmitEntry()is called after recording stops
Requirements:
- Package:
Shiny.Maui.Controls.SpeechAddins - DI:
ISpeechToTextServicefromShiny.Speechmust be registered - Namespace:
Shiny.Maui.Controls.SpeechAddins.Chat
PhotoGalleryEntryTool (MAUI only)
Section titled “PhotoGalleryEntryTool (MAUI only)”A pre-built tool that opens the device photo gallery using MAUI MediaPicker and fires AttachImageCommand with the selected file path.
<shiny:ChatView.ToolItems> <shiny:PhotoGalleryEntryTool PickerTitle="Select a photo" /></shiny:ChatView.ToolItems>| Property | Type | Default | Description |
|---|---|---|---|
PickerTitle | string | "Select a photo" | Title displayed on the media picker dialog |
Behavior:
- Tap opens the device photo gallery via
MediaPicker.Default.PickPhotoAsync() - If the user selects a photo,
ChatView.AttachImageCommandis executed withFileResult.FullPath - If cancelled or permission denied, no action is taken
Requirements:
- Package:
Shiny.Maui.Controls - The
ChatView.AttachImageCommandmust be bound to handle the file path string
TakePhotoEntryTool (MAUI only)
Section titled “TakePhotoEntryTool (MAUI only)”A pre-built tool that opens the device camera using MAUI MediaPicker and fires AttachImageCommand with the captured photo path.
<shiny:ChatView.ToolItems> <shiny:TakePhotoEntryTool PickerTitle="Take a photo" /></shiny:ChatView.ToolItems>| Property | Type | Default | Description |
|---|---|---|---|
PickerTitle | string | "Take a photo" | Title displayed on the media picker dialog |
Behavior:
- Checks
MediaPicker.Default.IsCaptureSupported— if not supported, does nothing - Tap opens the device camera via
MediaPicker.Default.CapturePhotoAsync() - If the user captures a photo,
ChatView.AttachImageCommandis executed withFileResult.FullPath - If cancelled or permission denied, no action is taken
Requirements:
- Package:
Shiny.Maui.Controls - The
ChatView.AttachImageCommandmust be bound to handle the file path string - Device must support camera capture
ChatEntryTool Base Class
Section titled “ChatEntryTool Base Class”Tools that need access to the ChatView’s input system should inherit from ChatEntryTool. It can also be used directly in XAML with a Command binding for simple tools:
public class ChatEntryTool : FabMenuItem{ protected ChatView? ChatView { get; private set; } // Attach/Detach called automatically by ChatView}When ToolItems is set on a ChatView, each tool’s Attach() method is called automatically, giving it a reference to the parent ChatView.
This gives your tool access to:
ChatView.EntryText— Read/write the input fieldChatView.SubmitEntry()— Programmatically send- The full ChatView state (messages, participants, etc.)
Building a Custom Tool
Section titled “Building a Custom Tool”public class QuickReplyTool : ChatEntryTool{ public QuickReplyTool() { Text = "Quick Reply"; FabBackgroundColor = Colors.Purple; Clicked += OnClicked; }
void OnClicked(object? sender, EventArgs e) { if (ChatView is null) return; ChatView.EntryText = "Thanks, I'll get back to you shortly!"; ChatView.SubmitEntry(); }}<shiny:ChatView.ToolItems> <local:QuickReplyTool /></shiny:ChatView.ToolItems>More Complex Example: Template Picker
Section titled “More Complex Example: Template Picker”public class TemplateTool : ChatEntryTool{ readonly string[] templates = { "I'll look into this and get back to you.", "Thanks for reaching out!", "Let me connect you with the right team." };
public TemplateTool() { Text = "Templates"; FabBackgroundColor = Colors.Teal; Clicked += OnClicked; }
async void OnClicked(object? sender, EventArgs e) { if (ChatView is null) return;
var result = await Application.Current!.MainPage! .DisplayActionSheet("Pick a template", "Cancel", null, templates);
if (result != null && result != "Cancel") { ChatView.EntryText = result; // Don't auto-send — let user review/edit first } }}Hiding the Input Bar
Section titled “Hiding the Input Bar”Set IsInputBarVisible = false for read-only or externally-controlled scenarios:
<shiny:ChatView Messages="{Binding Messages}" IsInputBarVisible="False" />Use cases:
- Read-only chat history
- Chat controlled by external UI (buttons, cards)
- Bot conversations with only button-based interaction
- Review/audit views of past conversations