InputPopupController is a UIViewComponent that renders a single-line text prompt — rename dialogs, save names, seed entry, chat handles. It is the text-input sibling of the Confirmation Popup and drives the same two ways:

  • As a navigation destination (recommended) — register one popup prefab in your nav graph and push it from anywhere with per-call InputPopupArgs. The push is awaitable: PushAsync<string> resolves with the confirmed text.
  • Embedded in a host view (legacy) — a node-less InputPopupController on the same GameObject as its caller, driven through the Value / Validate properties and OnConfirm + Fade.FadeIn().

As a navigation destination

One prefab in a global navigation graph serves every text prompt in the game. Register the popup prefab on a NavNode (typically dismissMode: Pop with a Dim backdrop, hidden until pushed), then push it with args:

csharp
async void OnRenameClicked() { var result = await LunaNavigation.PushAsync<string>(_inputDest, new InputPopupArgs { Header = "Rename Hero", InitialValue = _hero.Name, Placeholder = "Enter a name", Validate = v => !string.IsNullOrWhiteSpace(v) && v.Trim().Length >= 3, }); if (!result.IsDismissed) { _hero.Name = result.Value.Trim(); } }
  • InputPopupArgs fields are optional — a null Header, Body, or Placeholder keeps the value serialized on the prefab, so a generic prompt works with new InputPopupArgs { InitialValue = current }. The text field itself is reset on every open: InitialValue when provided, empty otherwise — a previous caller's text never leaks into the next open.
  • Validate gates Confirm. While the predicate returns false, the Confirm button is disabled (SetEnabled, style it via :disabled) and Enter does nothing. null means "require non-blank input"; pass v => true to allow anything, including empty.
  • Enter confirms. A Return/KeypadEnter press in the focused field is equivalent to clicking Confirm (and respects Validate).
  • Dismissal is a cancel. Escape, the Cancel button, a Close button, or a backdrop click pops the node without a result — result.IsDismissed is true and no text is delivered.
  • The field receives focus on open, with the initial text preselected (UI Toolkit's select-all-on-focus default), so typing immediately replaces it.

The Showcase sample's Rename Player modal is this controller under a skinned UXML — ProfileScreen pushes it with InitialValue + a 3-character Validate and writes the awaited result back into the profile header.

Embedded in a host view (legacy)

An InputPopupController without a nav node is driven manually through its properties. On load it forces itself start-hidden (like the confirmation popup), and confirming just fades it back out instead of popping:

csharp
[SerializeField] InputPopupController _popup; void OnRenameClicked() { _popup.Value = _hero.Name; _popup.Validate = v => v.Trim().Length >= 3; _popup.OnConfirm += OnRenameConfirmed; _popup.UIView.Fade.FadeIn(); } void OnRenameConfirmed(string text) { _hero.Name = text.Trim(); _popup.OnConfirm -= OnRenameConfirmed; }

Prefer the nav-destination mode for new work — the embedded mode duplicates a popup per host view and can't be awaited.

Setup

1. UXML

The popup queries these named elements in the UXML hosted by the view's PanelRenderer:

ElementNameRequired
LabelHeaderoptional
LabelBodyoptional
TextFieldFieldyes
ButtonConfirmyes
ButtonCanceloptional — wired to dismiss
ButtonCloseoptional — wired to dismiss
VisualElementBackdropoptional — direct clicks dismiss

The Essentials sample ships a themed starting point at UXML/Components/InputPopup.uxml (+ .uss) — a clay panel matching the confirmation popup, with a slate text field and lime/slate buttons.

2. Add component + configure

Add InputPopupController to the GameObject. In the inspector:

  • _textHeader / _textBody — default labels (used when a push passes no override).
  • _placeholder — ghost text shown while the field is empty.

For the nav-destination mode, also register the prefab on a NavNode in your graph and reference that destination key from callers.

API

csharp
namespace CupkekGames.Luna; public class InputPopupController : UIViewComponent

Properties

PropertyTypeDescription
ValuestringRead/write the field text (write skips change notification, then re-evaluates validation).
ValidateFunc<string, bool>The active validation predicate. Assigning re-evaluates the Confirm button.
TextHeaderstringRead/write the header label.
TextBodystringRead/write the body label.

Events

csharp
public event Action<string> OnConfirm;

Fires with the confirmed text (in both modes, before the popup resolves). After a confirm the buttons are disabled, then the popup pops (nav mode) or fades out (embedded mode).

Subclassing hooks

VirtualCalledOverride to
ApplyArgs(InputPopupArgs)On fade-in, when the push carried argsApply extra fields from an InputPopupArgs subclass.
IsInputValid(string)On every field change, Enter, and Confirm clickReplace the validation policy entirely.
ResolveInput(string)After a confirmDelay or decorate the resolution (default: Pop(value) with a node, FadeOut() without).

InputPopupArgs

csharp
public class InputPopupArgs { public string Header; public string Body; public string InitialValue; public string Placeholder; public Func<string, bool> Validate; }

Passed as the push args; read on fade-in via GetArgs<InputPopupArgs>(). Subclass it to carry extra data for an InputPopupController subclass.

Default behaviour

  • Escape: closes the popup — in nav mode the node's dismiss pops it (an awaiting PushAsync sees IsDismissed); a UIViewActionEscape(Fade.FadeOut) covers the embedded mode.
  • Initial focus: the text field, with existing text preselected.
  • Reset on open (nav mode): header, body, placeholder, and validation return to the serialized defaults before per-push args apply — one global destination never shows a previous caller's overrides.

See also

  • Confirmation Popup — the N-button sibling; same args/await pattern with a choice index
  • Navigation — destinations, PushAsync<T> / Pop<T>, dismiss modes

Settings

Theme

Light

Contrast

Material

Dark

Dim

Material Dark

System

Sidebar(Light & Contrast only)

Light
Dark

Font Family

DM Sans

Wix

Inclusive Sans

AR One Sans

Direction

LTR
RTL