Terminal box
A terminal window for the 'here is the command to run' block on a landing page or an installation guide. It is presentation, not an emulator - nothing is executed, and the typing animation plays over text that is already on the page.
One command
The common shape is one line long, so Command is a shorthand for a single child line. The copy button takes the command without the prompt - a prompt is decoration, and pasting one into a shell is an error.
Terminal
<VetoTerminalBox Command="dotnet add package Veto" />Typing
Typed reveals the command a character at a time. It is a width animation stepped once per character, over text that is already in the DOM - nothing is inserted as it plays, so the text stays selectable and a screen reader is given the whole command at once rather than watching it arrive. Looping suits a landing page, a page the reader is working through wants it to settle, which is what Loop=false does.
Looping
Types once, then stays
Wide characters
@* Types in, holds, clears, repeats. *@
<VetoTerminalBox Command="npx create-veto-app@latest" Typed="true" />
@* Types once and stays put. *@
<VetoTerminalBox Command="dotnet new blazorwasm -o MyApp"
Typed="true" Loop="false" TypingDuration="3s" />A long session
MaxHeight caps the window's body; the lines scroll inside it rather than stretching the page.
build
<VetoTerminalBox Title="build" MaxHeight="10rem">
@foreach (var line in _log)
{
<VetoTerminalLine Prompt="@null" Output="@line" />
}
</VetoTerminalBox>A session
Child lines for anything longer than one command. Output is drawn muted and is deliberately left out of what the copy button collects, nobody wants a program's own chatter pasted back into their shell. A line that is only output belongs to the program, so give it no prompt.
bash
<VetoTerminalBox Title="bash">
<VetoTerminalLine Command="dotnet add package Veto" />
<VetoTerminalLine Prompt="@null" Output="info : Adding PackageReference for 'Veto' into project." />
<VetoTerminalLine Command="dotnet run" />
<VetoTerminalLine Prompt="@null" Output="Now listening on: http://localhost:5000" />
</VetoTerminalBox>The window itself
Title and Icon name the window - a shell, a container, a remote host. ShowHeader=false takes the bar away entirely, for a page that has already said what it is, and the body then carries the rounding.
deploy@veto-prod
<VetoTerminalBox Title="deploy@veto-prod" Icon="@VetoIcons.Server"
Command="systemctl restart veto" />
<VetoTerminalBox ShowHeader="false"
Command="git clone https://github.com/G-HK/Veto.git" />The prompt sign
Prompt is any string, so the sign is whatever the shell you are showing actually uses. PromptContent replaces it with content - an icon, a coloured host name - and unlike a bare $, content put there deliberately is read out rather than hidden, because it is presumably saying something. PromptEditable lets the reader type over it, which is what makes @bind-Prompt worth having: the prompt becomes a small input of its own.
zsh
pwsh
With an icon
Type over the prompt
@* Any sign the shell you are showing actually uses. *@
<VetoTerminalBox Prompt="›" Command="veto build" />
<VetoTerminalBox Prompt="PS>" Command="dotnet test" />
@* Content instead of a sign. *@
<VetoTerminalLine Command="git push origin main">
<PromptContent>
<VetoIcon Icon="@VetoIcons.GitHub" Size="VetoIconSize.Small" />
</PromptContent>
</VetoTerminalLine>
@* Editable, and bound back to the page. *@
<VetoTerminalBox PromptEditable="true" @bind-Prompt="_prompt" Command="whoami" />What copy takes
By default the commands in the window, one per line, gathered from what is actually rendered. CopyText overrides that outright - for a window showing an abbreviated command where the real one is longer, or where the thing worth copying was never on screen.
Copies more than it shows
No copy button
@* Copies the full command, not the short one on screen. *@
<VetoTerminalBox Command="docker compose up"
CopyText="docker compose --profile full --env-file .env.production up --build --detach" />
<VetoTerminalBox Command="rm -rf ./bin ./obj" Copyable="false" />