Modal Dialog with role='alertdialog', forced
modal=true and click-outside disabled. The user MUST
choose Action or Cancel (Escape still
cancels). The morfo declares only 3 parts (Provider + Action +
Cancel) — every other part (Trigger / Portal / Overlay / Content /
Title / Description / Header / Footer) is delegated to Dialog's
runtime via variant='alertdialog', including all 6
semantic events. Auto-coloring on intent='risk' | 'threat'
cascades the destructive tint to the Action button.
trace
{#if trace.length === 0}
open the dialog, click Cancel/Action to see Dialog events
{:else}
{#each trace.slice(0, 3) as entry}
{entry.event} · {entry.family}{entry.intent ? ' · ' + entry.intent : ''}{fmtTime(entry.at)}
{/each}
{/if}
open {String(open)}
{#if lastChoice}
last {lastChoice}
{/if}
{#if tab === 'live'}
Controls
intent is the key knob — switching to
risk / threat auto-colors the Action
button (red / amber) via an eidos cascade, and primes the sema
layer for a destructive-confirmation perceptual signature.
soma Provider props
eidos Content props
· forwarded to Dialog
Composition
· toggle structural wrappers in / out
Demo content
· literal text rendered into the dialog
eidos Action
· visual props forwarded to <Button>; intent inherits from the dialog
eidos Cancel
· variant narrowed to ControlVariant; always neutral palette
eidosvisual · full composition with Portal/Overlay/Header/Footersvelte
{eidosSnippet}
{/if}
{#if tab === 'api'}
API reference
AlertDialog declares 3 parts of its own (Provider + Action +
Cancel). Trigger / Portal / Overlay / Content / Title /
Description / Header / Footer come from Dialog via
soma's runtime delegation. Below are the alert-dialog-specific
props; for the inherited props see the Dialog demo.
AlertDialog (Provider)
Prop
Type
Default
Description
id
string
auto
Stable identifier.
open bindable
boolean
false
Whether the dialog is open.
onOpenChange / onOpenChangeComplete
(open: boolean) => void
—
Fire on every transition start / animation settle.
disabled
boolean
false
Disable the Trigger; dialog stays closed.
intent
'neutral' | 'risk' | 'threat'
'neutral'
Doctrinal intent. Narrowed from Dialog's full set — alert dialogs gate destructive actions. Drives the auto-color cascade on Action.
Escape does cancel by convention (overrides Dialog's 'defer' default).
interactOutsideBehavior
same as above
'ignore'
Forced — click outside cannot dismiss. The user MUST choose Action or Cancel.
…inherited
DialogContentProps
—
trapFocus, loop, preventScroll, forceMount, onOpenAutoFocus, onCloseAutoFocus, onEscapeKeydown, etc.
AlertDialog.Action
Prop
Type
Default
Description
aria-label
string
"Confirm"
Overrides the default accessible name.
onclick
(e: MouseEvent) => void
—
Business handler. The default close runs LAST — consumer logic gets first chance to gate.
variant eidos
SelectionVariant: 'solid' | 'outline' | 'ghost'
'solid'
Forwarded to the inner <Button>. Narrowed from ButtonVariant per DEMO_AUTHORING_GUIDE §12.7 — 3-value SelectionVariant keeps 'solid' as the CTA default while staying in the canonical chip rhythm.
When omitted, reads the parent AlertDialog.intent (neutral · risk · threat) so a flagged dialog paints a matching Action automatically.
color · rounded · iconOnly · icon · endIcon eidos
Button props
—
Standard Button visual knobs forwarded through.
child
{`Snippet<[{ props; intent }]>`}
—
Opt out of <Button> entirely. The dialog's resolved intent is passed alongside props.
…native button attrs
PrimitiveButtonAttributes
—
Renders a native <button type='button'>.
AlertDialog.Cancel
Prop
Type
Default
Description
aria-label
string
"Cancel"
Overrides the default accessible name.
onclick
(e: MouseEvent) => void
—
Business handler. Default close runs last.
variant eidos
ControlVariant: 'surface' | 'outline' | 'ghost'
'outline'
Forwarded to <Button>. Narrowed from ButtonVariant per DEMO_AUTHORING_GUIDE §12.7 (form-control surface).
size eidos
'xs' | 'sm' | 'md' | 'lg' | 'xl'
'md'
Button size scale.
intent eidos
ButtonIntent
'neutral'
Stays neutral by default so it contrasts with the (potentially destructive) Action.
color eidos
ColorRole
'neutral'
Forced to neutral so the outline reads as gray regardless of Button's default primary.
rounded · iconOnly · icon · endIcon eidos
Button props
—
Standard Button visual knobs.
…native button attrs
PrimitiveButtonAttributes
—
By convention, receives initial focus — render BEFORE Action in DOM order.
Inherited from Dialog
Same surface as Dialog. Listed
for at-a-glance reference; the prop tables live in the Dialog
demo.
Part
Notes
Trigger
Renders a native <button> with aria-haspopup='dialog' + aria-expanded.
Portal
Portal to document.body (no props).
Overlay
Backdrop. Optional via composition (toggle in / out).
Title
Wired to Content's aria-labelledby.
Description
Wired to Content's aria-describedby.
Header / Footer
Structural wrappers — pure layout.
Reference parity
Feature
Radix
bits-ui
ark-ui
Eidos (this)
Forced modal=true
✓
✓
✓
✓
role='alertdialog'
✓
✓
✓
✓
Click-outside ignored
✓
✓
✓
✓
Escape cancels (overrides Dialog)
✓
✓
✓
✓
Dedicated Action / Cancel parts
✓
✓
✓
✓
intent prop (risk/threat auto-color)
—
—
—
✓
Runtime delegation to Dialog
—
—
—
✓
Sema event inheritance (6 events)
—
—
—
✓
{/if}
{#if tab === 'morfo'}
morfo
· declarative contract
The alert-dialog morfo declares only the Action + Cancel button
parts (Provider is virtual). Trigger / Content / Overlay / Title
/ Description / Header / Footer come from the
Dialog morfo via soma's
runtime delegation
(variant='alertdialog' on the Dialog provider) —
which also brings the full Dialog event vocabulary. Source:
src/uix/morfo/components/alert-dialog.ts.
The runtime stamps these events on the Content / Action / Cancel
targets when the dialog opens / closes / commits. AlertDialog
does NOT declare its own events array — the perceptual surface
is identical to Dialog's. The Sema tab plays them.
name
family
verb
sequence
intent
target
{#each dialogEvents as action (action.name)}
{@const sem = action.semantic}
{@const intentDecl = 'intent' in sem ? sem.intent : undefined}
{@const intentStr = typeof intentDecl === 'string' ? intentDecl : intentDecl ? `fromProp:${(intentDecl as { fromProp?: string }).fromProp ?? '?'}` : '—'}
{action.name}
{sem.family}
{sem.verb ?? '—'}
{sem.sequence ?? 'pre'}
{intentStr}
{action.target}
{/each}
{/if}
{#if tab === 'sema'}
sema
· events + perceptual signature
0 events declared by alert-dialog morfo;
perceptual surface inherited from Dialog (6 events). The
intent prop on the Provider drives intent for the
commit-* family on the Action button — risk /
threat gets the destructive-confirmation signature (sharper
timbre + saturated motion).
Source: src/uix/eidos/components/alert-dialog/alert-dialog.css.
Only the Action + Cancel buttons get bespoke selectors — the
chrome (overlay, content panel, header, footer, title,
description) is inherited from dialog.css because
the soma runtime emits the same data-dialog-*
markers under variant='alertdialog'.
Selector
Source
Concern
[data-alert-dialog-action]
morfo
Solid primary button (neutral intent).
[data-alert-dialog-cancel]
morfo
Outline secondary button. Stays neutral regardless of intent.
Follows the APG alertdialog pattern.
Content emits role='alertdialog' (vs Dialog's
role='dialog') so screen readers announce with
alert semantics. Cancel receives initial focus by
convention (render it BEFORE Action in DOM order)
— the safe choice becomes the default when the user just
presses Enter.