Learn · 05 of 09
Presentations.
TerminalUI ships four presentation modifiers. Each takes a state
binding (typically a Bool, optional, or
Identifiable) and renders a content closure when the
state says "show":
.alert(...) — small, focused, OK/Cancel-shaped. .confirmationDialog(...) — multi-choice, primary
action often .destructive. .sheet(...) — full-overlay modal with arbitrary
content. .toast(...) — transient, non-blocking, no
dismissal required.
Each conforms to ActionScope, so commands declared on
a presentation modifier are active only while the presentation
is on screen — exactly the semantics you want for "Cancel"
and "Deploy" inside a confirmation dialog.
Why presentations live at the root
All four modifiers are root-hoisted. The
runtime collects presentation declarations during ordinary
resolve, then composes overlay roots after the
base tree has resolved. The base view tree never reflows when an
overlay opens; opening or dismissing a presentation is transparent
to the underlying selection / scroll / focus state unless the
action itself mutates that state.
Practical consequence: state owned inside a presentation
body is ephemeral — it lives only while the overlay is on screen.
Hoist editor state above the presentation if it must survive
dismissal. See
Runtime for the full
ordering rules.
Binding shapes
Each modifier accepts a state binding:
-
isPresented: Binding<Bool> — the simplest case,
used by all four modifiers.
-
item: Binding<Identifiable?> — the variant most
useful for "show detail for the selected row." The framework
re-presents when the identity changes, not just when the binding
toggles.
-
presenting: T? — used by .alert for
optional payloads (e.g. an error model). The presence of the
value drives presentation; the closure receives the unwrapped
value.
Dismissal
Three ways to dismiss:
- Set the state binding to false / nil. The
canonical path. Mutating the source of truth is what closes the
overlay.
- Read
@Environment(\.dismiss) inside the
presentation body. Calling it does the binding mutation
for you. Useful for "Close" buttons that don't need to know
which Boolean drives them.
- The framework dismisses on Escape for alert,
confirmationDialog, and sheet. Toasts dismiss themselves when
their state binding clears (or when the surrounding style's
timeout fires).
Scoped commands on presentations
Because each presentation modifier conforms to
ActionScope, you can attach
.keyCommand / .paletteCommand /
.toolbar directly to one. The bindings are active
while the overlay is on the focus chain — i.e. while it's on
screen — and silently inactive otherwise. Same shallowest-wins
semantics as elsewhere; see
Tutorial 03.
Where to go next