← Back to Home • Next: Secret — Styles →
How the Secret control behaves while it is running: keyboard, the mask character, the F2 reveal,
the order in which restrictions and validation apply, and the security rules that matter when you
handle passwords and keys.
Password: ####_ ← prompt + masked text + cursor
Min 8 chars with upper/lower/digit ← description (optional / dynamic)
Length: 4 ← ChangeDescription output (optional)
Password must have at least 8 chars ← error line, only when validation fails
Enter: confirm Esc: cancel F2: reveal ← tooltip (toggle with F1 / Ctrl+F1)
Every region can be recolored — see Styles. What the user typed appears as mask symbols, not the real characters, unless they reveal it with F2 (see below).
| Key | Action |
|---|---|
| Any printable character | Insert at the cursor, shown as the mask symbol (subject to AcceptInput and MaxLength) |
← / → |
Move one character |
Ctrl+← / Ctrl+→ |
Move one word |
Home / End |
Start / end of line |
Backspace |
Delete character before the cursor |
Delete |
Delete character at the cursor |
Ctrl+Backspace |
Delete the word to the left |
Ctrl+Delete |
Delete the word to the right |
| Key | Action |
|---|---|
Enter |
Confirm — runs validation, then returns the value |
Esc |
Abort (when the abort key is enabled) → IsAborted == true |
F2 |
Reveal / hide the plain text (when MaskSecret was left with enabledView: true) |
F1 |
Cycle tooltip content |
Ctrl+F1 |
Show / hide the tooltip |
When Emacs key bindings are enabled (
PromptPlus.Config.EmacsKeyBindings = true), the text also responds toCtrl+A/E/B/F/D/K/U/W/Y/Tand friends. See Keyboard Bindings for the full table.
Secret has no Tab autocomplete and no F3 history — those Input features are omitted by
design (a secret must not be suggested or persisted).
Every accepted character is drawn as a single mask symbol. The symbol is resolved in this order:
value passed to MaskSecret(char?, bool), when not null.PromptPlus.Config.SecretChar — the global default, '#'.PromptPlus.Config.SecretChar = '•'; // change the default for every Secret control
Calling MaskSecret('*') overrides the config for that one control. If you never call
MaskSecret, the control still masks input using Config.SecretChar and still allows F2 reveal.
MaskSecret(..., enabledView: true) (the default), pressing F2 toggles between the
masked view and the plain text so the user can verify what they typed. Pressing F2 again re-masks it.enabledView: false, F2 does nothing and the value can never be shown on screen.The reveal hotkey is configurable via PromptPlus.Config.HotKeyInputPasswordView (default F2).
⚠️ Disable reveal (
enabledView: false) when someone might be looking over the user’s shoulder or the session is being recorded — a PIN entry is a good candidate.
The restrictions apply in a fixed order, so it helps to picture the pipeline:
key pressed
│
├─ is it a control/navigation key? --→ handled (move, delete, F2, confirm, …)
│
└─ printable character
│
├─ AcceptInput(c) == false? --→ ignored
├─ length already == MaxLength? --→ ignored
├─ InputToCase applied (upper/lower)
└─ inserted at cursor, drawn as the mask symbol
Consequently:
AcceptInput and MaxLength are preventive — they stop bad input from ever appearing.InputToCase transforms accepted characters on the way in, so .Content is already cased..Content always holds the real characters.Pressing Enter runs this sequence:
PredicateValid /
PredicateValidAsync, if configured.ResultPrompt<string> with IsAborted == false.
Invalid → the control stays open, shows the error line, and waits for more input.⚠️ Validation only runs on confirm, never per keystroke. Use
AcceptInputfor per-keystroke rules andPredicateValidfor whole-value rules (length, complexity, match against a policy).
Because Secret has no DefaultIfEmpty, an empty field confirms as an empty string — add a
PredicateValid if an empty secret is not acceptable.
Set per instance via Options(...), or globally on
PromptPlus.Config:
| Option | Effect on Secret |
|---|---|
EnabledAbortKey(false) |
Removes Esc — the user must confirm |
HideAfterFinish(true) |
Erases the field after confirm — the whole control is erased, not just the interactive part |
HideOnAbort(true) |
Erases the field after Esc |
ShowTooltip(false) |
Hides the keyboard hint line |
Prompt(...) / Description(...) |
Overrides the prompt / description text |
Secret hides the value on screen, but it cannot secure what your application does with it after
Run() returns. Follow these rules:
.Content. Do not write it to the console, a log file, or telemetry.Secret has no EnableHistory on purpose;
do not route a secret through Input (which can) or through your own on-disk cache.Secret has no autocomplete for the same reason.enabledView: false for shoulder-surfing-prone contexts (recorded sessions, shared
screens)..Content always holds the full untruncated text..Content == "". .Content holds whatever partial text
the user had typed before pressing Esc — treat it as sensitive regardless of IsAborted, and
always branch on IsAborted before deciding whether to use the value at all.PredicateValidAsync.Options