Skip to content
Document DB v12 - Improved Interceptors with Soft Delete Integration, AI protections, & Admin UI with Aspire Integration! How!?

AI Prompt

A Siri-style full-screen AI entry overlay: a frosted/blurred backdrop, an animated multi-colour glow that runs around the screen edge, and a large prompt entry with microphone and submit buttons. Drop it in when you want a focused “Ask anything…” moment for AI input. Use it either as a declarative control (AiPromptOverlay) or invoke it from code via the IAiPromptService. Speech-to-text is optional and decoupled through IAiPromptSpeechProvider — the base control has no speech dependency.

  • NuGet downloads for Shiny.Maui.Controls
  • NuGet downloads for Shiny.Blazor.Controls
Frameworks
.NET MAUI
Blazor
  • Two usage modes — a declarative AiPromptOverlay control or a code-invoked IAiPromptService.PromptAsync(...)
  • Frosted backdrop — native blur behind the prompt (configurable BackdropBlurRadius)
  • Animated glow edge — a multi-colour glow that travels around the screen edge (default Siri-style violet → pink → blue → teal). On MAUI it’s a GraphicsView/IDrawable ring; on Blazor it’s an animated CSS conic-gradient border (@property --shiny-ai-angle) — no icon-font or image dependency
  • Theme-aware — colours follow the active Shiny theme tokens; only the glow palette is custom
  • Optional speech-to-text — decoupled via IAiPromptSpeechProvider; add it with the SpeechAddins packages. MAUI uses native speech (final transcript); Blazor uses the browser Web Speech API with live partial transcription
  • Busy stateIsBusy shows a working indicator while you call your AI backend
  • Dismiss control — backdrop tap (and Escape on Blazor), with optional dismiss-on-submit

Reach for the AI Prompt overlay when you want a dedicated, distraction-free surface for free-form AI input — an “Ask anything” entry point launched from a toolbar button, FAB, or wake word. If you need a full back-and-forth conversation UI with message bubbles, use ChatView instead; the AI Prompt is for capturing a single prompt and handing it off to your model.

IAiPromptService is registered automatically by UseShinyControls(). Inject it and await PromptAsync — the overlay auto-attaches over the current page.

public class MyViewModel(IAiPromptService aiPrompt)
{
public async Task AskAsync()
{
var result = await aiPrompt.PromptAsync(new AiPromptRequest
{
Title = "Ask AI",
Placeholder = "Ask anything…"
});
if (result.HasText)
await SendToAi(result.Text!);
}
}

AiPromptRequest lets you preset the Title, Subtitle, Placeholder (default "Ask anything…"), InitialText, ShowMicrophone (default true), a custom GlowColors palette, and the BackdropBlurRadius (default 30). PromptAsync returns an AiPromptResult with Text, WasCancelled, and HasText.

The AiPromptOverlay is a ContentView that fills its host. Place it as the last child of a Grid that also holds your page content so it overlays everything.

<ContentPage xmlns:shiny="http://shiny.net/maui/controls" ...>
<Grid>
<ScrollView>
<!-- page content -->
</ScrollView>
<shiny:AiPromptOverlay x:Name="Prompt"
Title="Ask AI"
Subtitle="What can I help you with?"
Submitted="OnSubmitted" />
</Grid>
</ContentPage>
void OpenPrompt() => this.Prompt.IsOpen = true;
void OnSubmitted(object? sender, AiPromptSubmittedEventArgs e)
=> SendToAi(e.Text);

Speech-to-text is opt-in. Reference Shiny.Maui.Controls.SpeechAddins and call .UseAiPromptSpeech() after .UseShinyControls() — this registers Shiny.Speech and an IAiPromptSpeechProvider.

builder
.UseShinyControls()
.UseAiPromptSpeech();

The service-based PromptAsync picks up the provider automatically. For the declarative control, assign the provider from DI yourself:

public MyPage(IAiPromptSpeechProvider speech)
{
InitializeComponent();
this.Prompt.SpeechProvider = speech;
}

Native speech returns a final transcript only (no live partials on MAUI).

Register the service and place a single <AiPromptHost /> in your layout (next to <DialogHost />):

builder.Services.AddShinyAiEntry();
// optional speech-to-text (browser Web Speech API)
builder.Services.AddAiPromptSpeech();
@* MainLayout.razor *@
<div class="page">
<main>@Body</main>
</div>
<DialogHost />
<AiPromptHost />
@inject IAiPromptService AiPrompt
<button @onclick="AskAsync">Ask AI</button>
@code {
async Task AskAsync()
{
var result = await AiPrompt.PromptAsync(new AiPromptRequest
{
Title = "Ask AI",
Placeholder = "Ask anything…"
});
if (result.HasText)
await SendToAi(result.Text!);
}
}
<AiPromptOverlay @bind-IsOpen="open"
Title="Ask AI"
OnSubmit="OnSubmit" />
@code {
bool open;
Task OnSubmit(string text) => SendToAi(text);
}

Enter submits, Shift+Enter inserts a newline, and Escape dismisses.

Add Shiny.Blazor.Controls.SpeechAddins and register it. It uses the browser Web Speech API with live partial transcription, so the entry updates as the user speaks.

builder.Services.AddAiPromptSpeech();
PropertyType (MAUI / Blazor)DefaultDescription
Titlestring?nullHeading above the prompt
Subtitlestring?nullSecondary line under the title
Placeholderstring?"Ask anything…"Entry placeholder
InitialTextstring?nullPre-filled prompt text
ShowMicrophonebooltrueShow the microphone (speech) button
GlowColorsIList<Color>? / IReadOnlyList<string>?Siri paletteCustom glow colours (CSS colours on Blazor)
BackdropBlurRadiusdouble30 (MAUI) / 24 (Blazor)Frosted backdrop blur radius
PropertyTypeDescription
Textstring?The entered prompt (null when cancelled)
WasCancelledbooltrue if dismissed without submitting
HasTextbooltrue when a non-empty prompt was submitted
PropertyTypeDefaultDescription
IsOpenboolfalseShow/hide the overlay (TwoWay)
Promptstring?nullThe prompt text (TwoWay)
Placeholderstring?"Ask anything…"Entry placeholder
Titlestring?nullHeading
Subtitlestring?nullSecondary line
ShowMicrophonebooltrueShow the microphone button
ShowSubmitButtonbooltrueShow the submit button
GlowColorsIList<Color>?Siri paletteCustom glow colours
GlowThicknessdouble6Glow ring thickness
BackdropBlurRadiusdouble30Frosted backdrop blur radius
AnimationDurationuint250Open/close animation in ms
IsBusyboolfalseWorking indicator while you call your AI
DismissOnSubmitbooltrueAuto-close after submit
DismissOnBackdropTapbooltrueClose when the backdrop is tapped
SubmitCommandICommand?nullCommand fired on submit
SpeechProviderIAiPromptSpeechProvider?nullSpeech-to-text provider (assign from DI)

Events: Submitted (AiPromptSubmittedEventArgs { Text }), SpeechRequested (AiPromptSpeechRequestedEventArgs { Handled }), Cancelled, Opened, Closed.

ParameterTypeDefaultDescription
IsOpenboolfalseShow/hide (@bind-IsOpen)
Promptstring?nullPrompt text (@bind-Prompt)
Placeholderstring?"Ask anything…"Entry placeholder
Titlestring?nullHeading
Subtitlestring?nullSecondary line
ShowMicrophonebooltrueShow the microphone button
ShowSubmitButtonbooltrueShow the submit button
GlowColorsIReadOnlyList<string>?Siri paletteCustom glow CSS colours
GlowThicknessdouble5Glow border thickness
BackdropBlurRadiusdouble24Frosted backdrop blur radius
GlowSpeedSecondsdouble6Seconds for one full glow rotation
IsBusyboolfalseWorking indicator while you call your AI
DismissOnBackdropTapbooltrueClose when the backdrop is tapped
SpeechProviderIAiPromptSpeechProvider?nullSpeech-to-text provider
OnSubmitEventCallback<string>Fired with the submitted text
OnCancelEventCallbackFired when dismissed
OnSpeechRequestedEventCallbackFired when the microphone is tapped

Speech is decoupled behind a small contract, so you can plug in any engine (cloud STT, on-device, etc.) without touching the control:

public interface IAiPromptSpeechProvider
{
bool IsSupported { get; }
Task<AiPromptSpeechResult> ListenAsync(IProgress<string>? partial, CancellationToken ct);
}

partial reports live interim transcription where the engine supports it (Blazor Web Speech API); MAUI’s native provider reports only the final transcript.

claude plugin marketplace add shinyorg/skills
claude plugin install controls@shiny
copilot plugin marketplace add https://github.com/shinyorg/skills
copilot plugin install controls@shiny
View controls Plugin