Skip to content

Approval content

In review
Live · web

View (a config of the slots) · context (the host follows it, per the ratified wiring)

Approve shell command

This command modifies the working tree

rm -rf build/ dist/

~/dizyx/projects/nockerl-design · destructive

Deletes 2 directories permanently. There is no undo, and regenerating requires a full rebuild.

Decide with the CTA row: outline confirm, ghost cancel, destructive = outline-red. The host follows the context (desktop → panel, compact → sheet, the ratified wiring); the anatomy never changes.

The one shared approval shape for the agent console: every moment an agent stops and asks (a tool call, a plan, an AskUserQuestion) renders this same anatomy, top-down:

  1. Title row (optional). Only for hosts without their own header (inline panels).
  2. Preview slot. What is being approved: a ToolCallCard, Markdown plan content, a diff, a mono command in a sunken Well.
  3. Options slot. Choice rows: the real RadioGroup, Checkbox, TextField.
  4. Risk-note slot. Caveats in the ratified Banner / Callout alert grammar (recessed status disc + whisper intent border on a solid surface, never a wash, never a rail).
  5. Actions. NockerlApprovalActions, the ratified CTA grammar (Dialog r5 canon): outline confirm (tertiary cyan) · ghost cancel · destructive confirm = outline-red, never a filled primary on a lifted surface. Confirm can hold confirmDisabled until the options slot is satisfied.

NockerlApprovalContent is pure content: no overlay, no scrim, no chrome. The title and the actions migrate to whatever chrome the host owns:

Host Title Actions
BottomSheet the sheet header (title / subtitle) pinned in the sheet’s footer slot (never scroll away)
Dialog the dialog header the dialog’s own CTA row (same grammar)
Inline panel the content’s own title prop the actions slot, inline at the end
Ratified (2026-07-05): one anatomy, platform-idiomatic hosts

The host wiring is settled: web desktop/pointer presents approvals in inline panels (the Panel/Dialog grammar, never a desktop bottom sheet); compact/touch web widths are sheet-idiomatic and host the same anatomy in the shipped BottomSheet; Android rides NockerlBottomSheet (the ApprovalSheet shell). The HOST is interaction idiom (law §9); the ANATOMY is the drift-guard (§12) and never changes across hosts. The demo above derives the host from the context switch exactly per this rule.

The approval views are configs, not components

Section titled “The approval views are configs, not components”

Per the component-vs-view rule, the three console approval moments are pure slot configurations of this one anatomy. They introduce no new components:

View preview options riskNote Confirm
Tool approval ToolCallCard (or a mono command Well) n/a Banner on destructive/write commands Approve · destructive commands flip tone="destructive"
Plan approval Markdown plan body n/a n/a Approve plan / cancel Keep planning
AskUserQuestion optional context RadioGroup (+ Checkbox multi-select, TextField “other”) n/a Submit, confirmDisabled until answered
import { NockerlApprovalActions, NockerlApprovalContent, NockerlBottomSheet } from '@dizyx/nockerl-react';
// SHEET host: title on the sheet, actions PINNED in the footer slot.
<NockerlBottomSheet
open={open}
onDismiss={deny}
stage={stage}
title="Approve shell command"
subtitle="This command modifies the working tree"
footer={<NockerlApprovalActions tone="destructive" confirmLabel="Run anyway" onConfirm={approve} onCancel={deny} />}
>
<NockerlApprovalContent preview={<CommandWell cmd="rm -rf build/" />} riskNote={<RiskBanner />} />
</NockerlBottomSheet>
// INLINE PANEL host: the content carries its own title row + inline actions.
<NockerlApprovalContent
title="Release timing"
subtitle="The agent needs a decision to continue"
options={<NockerlRadioGroup label="How should this ship?" options={choices} value={choice} onChange={setChoice} />}
actions={<NockerlApprovalActions confirmLabel="Submit" confirmDisabled={!choice} onConfirm={submit} onCancel={cancel} />}
/>
Android

The Compose mirror (NockerlApprovalContent hosted in the canonical NockerlBottomSheet, matching ToolApprovalSheet) is the Compose lane. Same anatomy, same slot names.

PropTypeDefaultDescription
titlestringOptional title row for hosts WITHOUT their own header (panels). Sheet/Dialog hosts carry the title themselves and omit this.
subtitlestringOptional supporting line under the title.
previewReactNodeThe PREVIEW slot: what is being approved (ToolCallCard · Markdown · diff…).
optionsReactNodeThe OPTIONS slot: choice rows (RadioGroup / Checkbox / TextField).
riskNoteReactNodeThe RISK-NOTE slot: a Banner / Callout carrying caveats.
actionsReactNodeOptional INLINE actions (panel hosts). Sheet hosts pin NockerlApprovalActions in the sheet footer instead and omit this.
classNamestringExtra class.
PropTypeDefaultDescription
confirmLabelstring'Approve'Confirm label (e.g. "Approve", "Run tool", "Submit").
cancelLabelstring | null'Deny'Cancel label. null hides cancel (rare: a single-action acknowledge).
tone'primary' | 'destructive''primary'Emphasis of the confirm: outline cyan (default) or destructive outline-red.
onConfirm *() => void
onCancel(() => void) | undefined
confirmDisabledbooleanfalseDisable confirm (e.g. an unsatisfied option row).