Skip to content
kitn AI/UI

Confirm

kai-confirm

A structured approval card that pairs a body message with labelled action buttons — use it when the model needs an explicit go-ahead before a consequential operation runs.

  • Shadow DOM
  • Single kai-card event
  • Resolves on action (no double-fire)
  • 3 action styles
  • Optional dismiss affordance

Set data in JavaScript (it’s an object) and listen for the kai-card CustomEvent:

<kai-confirm heading="Run database migration?"></kai-confirm>
<script type="module">
import '@kitn.ai/ui/elements';
await customElements.whenDefined('kai-confirm');
const el = document.querySelector('kai-confirm');
el.data = {
body: 'This will apply 3 pending migrations to production. This cannot be undone.',
tone: 'warning',
actions: [
{ id: 'approve', label: 'Run migration', style: 'primary', default: true },
{ id: 'reject', label: 'Cancel' },
],
};
el.addEventListener('kai-card', (e) => {
const ev = e.detail; // { kind: 'action', cardId, action, payload? }
if (ev.kind === 'action') console.log('chose', ev.action);
});
</script>
  • data — shape: ConfirmCardData from @kitn.ai/ui. Malformed payloads render an inline error.
  • Action styles'primary' | 'default' | 'destructive'. Mark one default: true to make it the keyboard default; combine with autofocus to focus it on mount.
  • Restore resolved state via el.resolution = { kind: 'action', action: 'approve' } — useful when replaying past conversations.

The canonical two-action pattern: warning tone, primary confirm, plain cancel.

tone: 'danger' with style: 'destructive' — colour and icon both signal severity.

More than two actions work naturally — each becomes a button.

dismissible: true adds a close (×) affordance that fires { kind: 'dismiss', cardId } — the card stays in the DOM.

Set the resolution property to render the chromed read-only view for a replayed conversation.

An empty actions array renders the inline error view and fires { kind: 'error', cardId, message }.

PropertyTypeDefaultNotes
theme'auto'Color mode (`auto` follows prefers-color-scheme).
dataThe confirm definition (the CardEnvelope.data). Set as a JS PROPERTY: `el.data = { body, tone, actions:[…] }`. Import `ConfirmCardData` from `@kitn.ai/ui` for the full shape.
cardIdStable card id correlating every emitted CardEvent. Attribute: `card-id`.
headingHeading rendered in the card chrome (= CardEnvelope.title). Attribute: `heading`.
autofocusfalseFocus the default action on mount (off by default, so nothing steals focus). Attribute: `autofocus`.
resolutionSet when the user resolved this card; renders the read-only view. Property: `el.resolution = { kind:'action', action:'…' }`.
MethodSignatureNotes
(options?: FocusOptions): voidFocus the default action button (or the first action if none is default). The same target `autofocus` focuses on mount, but on demand.
(actionId?: string): voidActivate an action by id: emits the `action` verb on kai-card and resolves the card (single-shot). With no id, invokes the default action.
(): voidTrigger the dismiss path: emits `dismiss` on kai-card and optimistically collapses the card to its re-openable stub.
(): voidRe-open a dismissed card from its stub: emits `reopen` on kai-card.

This element wraps these SolidJS components — reach for them directly when you need finer control than the props expose.

ConfirmCard