Dialog / modal
In reviewLive · web
Variant: pick one, then open the dialog
Last outcome: none yet. Esc, Cancel, the scrim, or the close button dismisses; Enter / the default action resolves. The island is live.
// Web: React, consuming @dizyx/nockerl-tokens. (Web is the laggard platform;// this is the canonical API the published @dizyx/nockerl-react package exposes.)// NockerlDialog composes the shipped NockerlOverlay primitive (scrim + focus-trap + Esc);// it supplies the centered card, the scale-in motion, and the Enter=confirm shortcut.import { NockerlDialog } from '@dizyx/nockerl-react';
export function DeleteSessionDialog({ open, name, stage, onCancel, onDelete }: Props) { return ( <NockerlDialog open={open} stage={stage} title="Delete session?" tone="destructive" icon="warning" confirmLabel="Delete" onConfirm={onDelete} onDismiss={onCancel} > <p>“{name}” will be permanently removed.</p> <p className="muted">Chat history is preserved on the server.</p> </NockerlDialog> );}// Android: Jetpack Compose (canonical). Material 3 AlertDialog with the title /// text / confirmButton / dismissButton slots, filled by NockerlButton.// chat/ui/SessionChipsDialogs.kt → DeleteSubSessionDialog.import androidx.compose.material3.AlertDialogimport androidx.compose.material3.Textimport com.nockerl.app.core.ui.NockerlButtonimport com.nockerl.app.core.ui.NockerlButtonVariant
AlertDialog( onDismissRequest = onDismiss, title = { Text("Delete session?") }, text = { Text("\"${session.name}\" will be permanently removed.") }, confirmButton = { NockerlButton( text = "Delete", onClick = { onConfirm(session.slug) }, variant = NockerlButtonVariant.DESTRUCTIVE, ) }, dismissButton = { NockerlButton("Cancel", onClick = onDismiss, variant = NockerlButtonVariant.GHOST) },)// macOS: SwiftUI (canonical). Voice uses the STOCK presenters: .alert for a// message + actions, .confirmationDialog for a destructive choice (role-driven).// NockerlVoice/UI/HistoryView.swift → "Clear All".Button("Clear All") { confirmClear = true } .buttonStyle(.nockerlDestructive) .confirmationDialog( "Delete all \(records.count) transcriptions? This can't be undone.", isPresented: $confirmClear, titleVisibility: .visible ) { Button("Delete All", role: .destructive) { HistoryStore.shared.deleteAll() } Button("Cancel", role: .cancel) {} }
// A non-destructive prompt uses .alert with the same role-tagged buttons..alert("Rename session", isPresented: $showRename) { TextField("Name", text: $name) Button("Rename") { rename(name) } Button("Cancel", role: .cancel) {}} message: { Text("Enter a new name for this session.")}Parameters
Section titled “Parameters”| Prop | Type | Default | Description |
|---|---|---|---|
open * | boolean | Whether the dialog is presented. | |
onDismiss * | () => void | Dismiss handler: scrim tap, Esc, Cancel, or the close (X) button. | |
onConfirm * | () => void | Default-action handler: the confirm button + Enter. | |
title * | string | Accessible title; carries the dialog name (aria-labelledby). | |
confirmLabel | string | 'Confirm' | Confirm-button label. |
cancelLabel | string | null | 'Cancel' | Cancel-button label. null hides Cancel (a single-action alert). |
tone | 'primary' | 'destructive' | 'primary' | Emphasis of the default action: primary cyan or destructive red. |
icon | 'warning' | 'fork' | Optional leading header glyph key (warning for destructive, fork for branch). | |
confirmDisabled | boolean | false | Disable the confirm action (e.g. an unsatisfied form). |
stage * | HTMLElement | null | The contained stage element, which gates rendering so the dialog never escapes it. | |
children * | React.ReactNode | Body: supporting text and/or a form field. |
| Parameter | Type | Default | Description |
|---|---|---|---|
onDismissRequest * | () -> Unit | Invoked on scrim tap, the system back gesture, or Esc. Wire to the same handler as the Cancel button. | |
confirmButton * | @Composable -> Unit | The default action slot. Fill with a NockerlButton (PRIMARY, or DESTRUCTIVE for a delete). | |
dismissButton | @Composable (() -> Unit)? | null | The secondary action slot, typically a GHOST NockerlButton labelled "Cancel". Omit for a single-action alert. |
title | @Composable (() -> Unit)? | null | Heading slot. A Row with an Icon + Text gives the icon-header variant. |
text | @Composable (() -> Unit)? | null | Body slot: supporting Text (and a Column with an OutlinedTextField for a form dialog). |
properties | DialogProperties | DialogProperties() | Platform dialog behavior, such as dismiss-on-back and dismiss-on-outside. |
SwiftUI presents dialogs as view modifiers bound to a Bool, not a component
with parameters. Voice uses the stock presenters; buttons carry semantics via
role.
| Style | Type | Default | Description |
|---|---|---|---|
.alert(_:isPresented:actions:message:) | modifier | A titled message with action buttons + an optional message. May contain a TextField for a short prompt. | |
.confirmationDialog(_:isPresented:titleVisibility:actions:) | modifier | A choice sheet for a destructive/irreversible action. titleVisibility: .visible shows the prompt as the title. | |
isPresented | Binding<Bool> | Drives presentation; set false from any action to dismiss. There is no explicit scrim/elevation parameter, since the system supplies them. | |
Button(role:) | .destructive | .cancel | Action emphasis. .destructive tints the confirm red; .cancel is the dismiss. The platform orders the buttons. |