Wizard / process steps
In reviewLive · web
Create session · Basics
- 1Basics
- 2Model
- 3Review
Basics
Name the session and choose its harness. The harness is immutable after creation.
Shown on the session chip and in the switcher.
Harness
On step 1 of 3 (Basics). The island is live.
// Web: React, consuming @dizyx/nockerl-tokens. (Web is the laggard platform. Spec + live demo,// not yet exported from @dizyx/nockerl-react; promotion is tracked.)// The Wizard is the FLOW: it renders a NockerlStepper indicator + the active step's// content + the Back/Next/Finish footer, and gates advance on each step's// `isValid`. The shipped "Create session" flow (SessionCreationForm) is the// content this models.
export function CreateSessionWizard({ onFinish }: { onFinish: (v: SessionValues) => void }) { return ( <Wizard label="Create session" onFinish={onFinish} // fired from the last step's Finish steps={[ { label: 'Basics', isValid: (v) => v.name.trim().length > 0, // gates Next render: (v, set) => ( <> <NockerlTextField label="Session name" required value={v.name} onChange={(name) => set({ name })} /> <NockerlRadioGroup label="Harness" value={v.engine} onChange={(engine) => set({ engine })} options={[{ value: 'cloud-agent', label: 'Cloud Agent' }, { value: 'api-server', label: 'Local Engine' }]} /> </> ), }, { label: 'Model', isValid: (v) => v.provider.length > 0, render: (v, set) => ( <> <Select label="Provider" required value={v.provider} onChange={(provider) => set({ provider })} /> <Select label="Model" value={v.model} onChange={(model) => set({ model })} /> </> ), }, { label: 'Review', render: (v) => <ReviewSummary values={v} /> }, // final step → Finish ]} /> );}// Android: Jetpack Compose. INTENDED API (com.nockerl.app.core.ui.NockerlWizard):// no formal wizard ships yet; the real "Create session" flow renders as a single// SessionCreationSheet (one scroll, not paged). This generalizes those fields into// a guided flow that OWNS a NockerlStepper + the step body + the Back/Next/Finish bar.import com.nockerl.app.core.ui.NockerlWizardimport com.nockerl.app.core.ui.NockerlWizardStep
NockerlWizard( label = "Create session", onFinish = viewModel::createSession, // invoked from the last step's Finish steps = listOf( NockerlWizardStep( label = "Basics", isValid = { it.name.isNotBlank() }, // gates Next; footer Next disabled until true content = { values, set -> NockerlTextField("Session name", values.name, onValueChange = { set(values.copy(name = it)) }) NockerlEngineRadios(values.engine, onSelect = { set(values.copy(engine = it)) }) }, ), NockerlWizardStep( label = "Model", isValid = { it.provider.isNotEmpty() }, content = { values, set -> NockerlProviderDropdown(values.provider, onSelect = { set(values.copy(provider = it)) }) NockerlModelDropdown(values.model, onSelect = { set(values.copy(model = it)) }) }, ), NockerlWizardStep(label = "Review", content = { values, _ -> NockerlReviewSummary(values) }), ), modifier = Modifier.fillMaxWidth(),)// macOS: SwiftUI. INTENDED API (NockerlVoice/UI/NockerlWizard.swift): no formal// wizard ships yet. The closest precedent is OnboardingView (a status checklist,// not a paged Back/Next flow); this generalizes it into a guided container that// pairs a NockerlStepper with the active step's content and a Back/Next/Finish bar.NockerlWizard(label: "Create session", values: $session, onFinish: createSession) { NockerlWizardStep("Basics", isValid: { !$0.name.isEmpty }) { values in // gates Next NockerlTextField("Session name", text: values.name) NockerlEngineRadios(selection: values.engine) // Cloud Agent / Local Engine } NockerlWizardStep("Model", isValid: { !$0.provider.isEmpty }) { values in NockerlProviderPicker(selection: values.provider) NockerlModelPicker(selection: values.model) // optional → "Provider default" } NockerlWizardStep("Review") { values in NockerlReviewSummary(values) // last step → Finish }}Parameters
Section titled “Parameters”| Prop | Type | Default | Description |
|---|---|---|---|
steps * | WizardStep[] | Ordered steps. Each is { label, render, isValid? }. render(values, set) draws the step body; isValid(values) gates Next (omit for an always-passable step like Review). | |
onFinish * | (values: T) => void | Fired when Finish is pressed on the last step. Receives the accumulated values. | |
label | string | Accessible name for the flow region (e.g. 'Create session'); also drives the header eyebrow. | |
current | number | Controlled active step index. Omit to let the Wizard own its step state internally. | |
onStepChange | (index: number) => void | Notified on every Back / Next / indicator-jump. Pair with current for a controlled flow. | |
allowJumpBack | boolean | true | When true, completed discs in the indicator are clickable to jump back. Forward jumps are never allowed (gating). |
finishing | boolean | false | Holds the Finish button with a spinner + aria-busy while the create call is in flight. |
| Parameter | Type | Default | Description |
|---|---|---|---|
steps * | List<NockerlWizardStep> | NockerlWizardStep(label, content, isValid = { true }). content is a @Composable (values, set) -> Unit body; isValid gates the footer Next. | |
onFinish * | (T) -> Unit | Invoked from the last step’s Finish with the accumulated values. | |
label | String | "" | Content description for the flow + the header eyebrow text. |
current | Int? | null | Controlled active step. Null = the wizard hoists its own rememberSaveable step state. |
onStepChange | ((Int) -> Unit)? | null | Called on Back / Next / jump-back. Pair with current to control the flow. |
allowJumpBack | Boolean | true | Completed stepper discs become clickable (ripple) to return to an earlier step. |
finishing | Boolean | false | Shows a spinner in Finish and blocks re-press while the create call runs. |
modifier | Modifier | Modifier | Outer modifier. Pass Modifier.fillMaxWidth() for a full-width flow card. |
SwiftUI exposes the flow as a NockerlWizard view built from a @ViewBuilder of
NockerlWizardSteps; the active index is internal unless bound. State styling
reads from NockerlTheme (accent, success, surface highlight, divider).
| Style | Type | Default | Description |
|---|---|---|---|
steps (builder) * | @WizardBuilder | NockerlWizardStep(_:isValid:content:): a label, an optional isValid predicate that gates Next, and the step’s content view. | |
onFinish * | (T) -> Void | Closure fired from the last step’s Finish with the bound values. | |
values * | Binding<T> | The accumulated flow values; each step reads/writes through this binding. | |
label | String | "" | Accessibility label for the flow + the header eyebrow. |
current | Binding<Int>? | nil | Optional binding to control the active step; nil = internal @State. |
allowJumpBack | Bool | true | Completed stops in the indicator become tappable to step back. |
finishing | Bool | false | Drives the Finish spinner + disabled state while creating. |