registry:ui · NativeHTML
system dialog — the deliberate destructive
The confirmation dialog as a composed family (shadcn-shaped on the native <dialog>): Root (bind:open/onconfirm) + Trigger / Content / Title / Description / Actions / Action(variant: fill with the destructive pair injected by default | tonal | outline) / Cancel — focus lands on Cancel (the safe default), Escape cancels, confirm runs then closes. No Overlay/Portal parts (the dialog element IS the overlay) — recorded divergence.
$npx jixoai-ui add system-dialog
https://ui.jixoai.com/r/system-dialog.json
overview
Overview
The destructive-decision surface, composed shadcn-shape on the popover base: Root carries the state, Trigger carries the anchor, Content is a manual popover that rises beside its trigger, and the Action parts close the decision through one seam.
system-dialog is the family that takes window.confirm seriously. The composition is
shadcn-shaped but the base is the popover engine: Content is a popover="manual" panel — top layer and ::backdrop
scrim from the platform — that rises BESIDE the button which asked
the question (CSS Anchor Positioning: the Trigger publishes the
anchor-name, the panel resolves position-anchor/area/try, and the
native try-fallbacks flip it at the viewport edge). Manual means
alert gravity: no light dismiss — an outside click never silently
answers a destructive question — and Escape is the component's own
cancel, scoped to the panel. Title and Description are parts, not
props: the ARIA wiring (role=alertdialog, labelledby/describedby
over deterministic derived ids) is Content's job.
The delivery shape is the fleet's self-carried portal (the
carriers stamp the popover panel, which the platform promotes) —
with two twists worth naming. The parts resolve their axes
through Svelte CONTEXT, which follows the component tree, never
the top-layer promotion. And the family has a SECOND face: the
imperative trio — alert(), confirm(), prompt() — mounts its own
hosts at viewport center (pose="center": a system question has no
trigger to rise beside), resolves EXACTLY ONCE (an action
resolves its value; any close without one resolves the cancel
value), and unmounts after the exit window.
The anchored rise, measured: the Trigger publishes the
anchor-name and the panel resolves position-anchor with position-area: block-end — the panel opens BELOW the
trigger, centered on it, with the --jx-gap breathing
room (12px). Near a viewport edge the try chain (flip-block,
flip-inline, and the combined flip) re-buckets the panel instead
of clipping it, and anchors-visible hides it if the
trigger scrolls away. The system trio's pose="center" drops the chain and lets the UA's own
popover centering own the panel (measured dead-center). One
measured defect rides the family ledger rather than this page's
claims: the anchored panel's authored width cap
(min(24rem, 100vw − 2rem)) does not reach the
served panel (544.5px at max-width none; no served stylesheet
rule sets the cap — W-next #8's second family repro,
mechanism-agnostic: the anchor itself is proven correct).
system dialog
Open it: the alert rises BESIDE the button that asked — position-area: block-end, centered on the trigger with the --jx-gap breathing room (near a viewport edge the try-fallbacks flip it to the other side). Focus lands on Cancel (Tab straight to Delete). Escape cancels through the component's own handler — manual popover, no light dismiss on a destructive question. Confirm runs the root's onconfirm seam; hiding the popover restores focus to the invoker.
delete the pipeline?
this removes 12 checks and their history. there is no undo.
the checks being removed: lint, typecheck, size-budget, a11y-audit…
Rename the pipeline?
The new slug applies to every check's history — references update with it.
<script lang="ts">
import SystemDialog, {
SystemDialogTrigger, SystemDialogContent, SystemDialogTitle,
SystemDialogDescription, SystemDialogActions, SystemDialogAction,
SystemDialogCancel,
} from '@ui/system-dialog/index';
</script>
<SystemDialog bind:open onconfirm={() => (deleted = true)}>
<SystemDialogTrigger>delete pipeline…</SystemDialogTrigger>
<SystemDialogContent>
<SystemDialogTitle>Delete the pipeline?</SystemDialogTitle>
<SystemDialogDescription>
This removes 12 checks and their history. There is no undo.
</SystemDialogDescription>
<SystemDialogActions>
<SystemDialogCancel>cancel</SystemDialogCancel>
<SystemDialogAction>delete pipeline</SystemDialogAction>
</SystemDialogActions>
</SystemDialogContent>
</SystemDialog>system
System dialogs — alert · confirm · prompt
The imperative trio carries window.alert / window.confirm / window.prompt on the family's one engine, with TWO deliberate postures: the composed family above ANCHORS beside its trigger (the question rises at the button that asked — near the page top when the trigger lives there), while the trio always rises at the exact VIEWPORT CENTER (pose=center: a system question has no trigger to anchor beside; the UA popover centering owns the geometry). The carved split strip centers its labels and never wraps while space suffices. Every call resolves exactly once — an action resolves its value, any close without one resolves the cancel value.
— not asked yet —
import { alert, confirm, prompt } from '@ui/system-dialog/index';
await alert('the key rotated');
// → void (a single affirmative action)
const ok = await confirm('rotate the key?');
// → boolean (the action → true; Cancel/Escape → false)
const name = await prompt({ title: 'rename', inputLabel: 'name' });
// → string | null (Enter submits, Escape cancels → null)law
The anchored alert
Alert gravity on the popover base: no light dismiss, the safe landing, the non-modal page, one confirm seam with exactly-once resolution — measured, not asserted.
| Property | Type | Default | Description |
|---|---|---|---|
| the parts contract | Root · Trigger · Content · Title · Description · Actions · Action · Cancel | Root is the STATE CONTEXT only — bind:open + the onconfirm seam, rendered as a fragment (no element, no rest: consumer attributes have no landing). Title and Description are PARTS, never props — the ARIA wiring (labelledby/describedby over deterministic derived ids) is Content's job; an alert without words is caller error | announces: seven real elements over one invisible state holder |
| alert gravity | popover="manual" | NO light dismiss — an outside click must not silently answer a destructive question. Escape is the component's own cancel, SCOPED to the panel (the keydown lives on the popover: it cancels while focus is inside; a user who tabbed back to the page has left the question) | announces: measured: an outside click leaves the panel open |
| the anchored rise | CSS Anchor Positioning | the panel rises BESIDE the trigger that asked — anchor-name on the Trigger, position-anchor/area/try on the panel, symmetric margin so a flip finds the same gap, try-fallbacks flipping at the viewport edge, anchors-visible hiding it when the trigger scrolls away. pose="center" (the system trio) drops the chain for the UA's popover centering | announces: a question at its button, not a mode takeover |
| the safe landing | focusLanding="cancel" | focus lands on the CANCEL action on open (the APG safe-landing law — the destructive path must be a deliberate move), falling back to the action when no cancel exists; hiding the popover returns focus to the invoker — only when focus was ours; a REMOVED invoker deliberately leaves focus on the body (a dead panel must not steer it) | announces: the safe exit is one keypress away |
| non-modal by design | Tab | NO focus trap, no scroll lock — Tab is free: a user who tabs back to the page has left the question (the anchored alert is a popover-base surface, not a dialog() takeover). The top layer and ::backdrop scrim still come from the platform | announces: the page stays reachable; the question stays answered |
| the confirm seam | SystemDialogAction | the Action runs the Root's onconfirm, then the family)s single animated close; the fill rung ships the DESTRUCTIVE pair injected (the loud path is opt-out). The imperative trio resolves EXACTLY ONCE — an action resolves its value, any close without one resolves the cancel value (false / null); never hangs | announces: one decision, one resolution |
types
Types
The surface paint and the confirm tone are the two variant axes; everything else is the fixed alertdialog contract.
Content variant
variant="auto" (default) picks acrylic unless the environment asks for reduced transparency; "solid" and "acrylic" force one.
Action variant
variant="fill" (default) ships with the destructive pair injected — the loud path is opt-OUT; "tonal" is the brand-tinted positive confirm; "outline" stays quiet.
Composed family
Seven parts: Root (state context), Trigger, Content (the manual popover), Title, Description, Actions, Action, Cancel — each a real element, no slots.
usage
Usage
Root owns bind:open + the onconfirm seam; Title and Description are parts — an alert without words is not an alert.
<script lang="ts">
import SystemDialog, {
SystemDialogTrigger, SystemDialogContent, SystemDialogTitle,
SystemDialogDescription, SystemDialogActions, SystemDialogAction,
SystemDialogCancel,
} from '@ui/system-dialog/index';
</script>
<SystemDialog bind:open onconfirm={() => (deleted = true)}>
<SystemDialogTrigger>delete pipeline…</SystemDialogTrigger>
<SystemDialogContent>
<SystemDialogTitle>Delete the pipeline?</SystemDialogTitle>
<SystemDialogDescription>
This removes 12 checks and their history. There is no undo.
</SystemDialogDescription>
<SystemDialogActions>
<SystemDialogCancel>cancel</SystemDialogCancel>
<SystemDialogAction>delete pipeline</SystemDialogAction>
</SystemDialogActions>
</SystemDialogContent>
</SystemDialog>a11y
Accessibility
APG alertdialog law on the popover base: focus lands on Cancel on open, Escape cancels through the component-owned handler (keydown lives on the panel — Escape cancels while focus is inside it; a user who tabbed back to the page has left the question), hiding the popover restores focus to the invoker (a removed invoker deliberately leaves focus on the body — focus is never steered into dead markup); Tab is free — the anchored alert is non-modal by the popover-engine ruling.
Keyboard
| Key | Action |
|---|---|
| Escape | Cancels — SCOPED to the panel: the keydown handler lives on the popover itself, so it fires while focus is inside the panel; the component-owned keydown is prevented and runs through the state close (manual popover — no light dismiss) |
| Tab | Free — the anchored alert is non-modal (popover base: no focus trap); hiding the popover restores focus to the invoker, or to the body if the invoker was removed while open |
| Enter / Space | Activates the focused button — Cancel (focused on open) or Action |
ARIA
| Attribute | Value | Description |
|---|---|---|
| role | alertdialog | On Content (the popover panel div). |
| aria-labelledby | {uid}-title | Points at the deterministic id Title renders; derived from the root uid. |
| aria-describedby | {uid}-desc | Points at the deterministic id Description renders. |
| aria-haspopup | dialog | On the Trigger button. |
| aria-expanded | true/false | On the Trigger; mirrors the open state. |
api
API — the parts
The family's parts, each with its own props; all button/element parts forward their native HTML attributes.
SystemDialog (root)
| Property | Type | Default | Description |
|---|---|---|---|
open bind | boolean | false | Controlled open state (bind:open); the root renders no element. |
| onconfirm | () => void | — | The confirm seam: runs on SystemDialogAction, then the dialog closes. |
| children | Snippet | — | The family parts. |
Universal props
| Property | Type | Default | Description |
|---|---|---|---|
| size | 'small' | 'medium' | 'large' | 'auto' | number | 'auto' · ambient scope | the base scale — root font-size; parts size in em |
| shape | 'round' | 'scoop' | 'bevel' | 'notch' | 'square' | 'squircle' | 'auto' | 'auto' · ambient scope | corner geometry (CSS corner-shape; §14 degrade table) |
| radius | 'small' | 'medium' | 'large' | 'auto' | number | 'auto' · ambient scope | corner size; auto = the concentric broadcast (§3) |
| density | 'small' | 'medium' | 'large' | 'auto' | number | 'auto' · ambient scope | spacing/leading scale over the kernel channels (§4) |
| color | 'primary' | 'secondary' | 'error' | 'warn' | 'success' | 'info' | 'auto' | number | string | 'auto' · ambient scope | the hue axis of the fixed oklch primary system (§5) |
| theme | 'light' | 'dark' | 'system' | 'auto' | 'auto' · ambient scope | light/dark profile; system = the JS-mutable global (§6) |
| elevation | 'level-1' | 'level0' | 'level1' | 'level2' | 'level3' | 'level4' | 'level5' | 'auto' | number | 'auto' · ambient scope | official M3 levels over the surface ladder (§7) |
| motion | 'reduced' | 'subtle' | 'normal' | 'expressive' | 'auto' | number | 'auto' · ambient scope | intensity across the motion kernels (§8) |
SystemDialogTrigger
| Property | Type | Default | Description |
|---|---|---|---|
| child | Snippet<[{ props }]> | — | Replacement-element escape: spread {...props} on your own button. |
| children | Snippet | — | Trigger label; spreads HTMLButtonAttributes. |
SystemDialogContent
| Property | Type | Default | Description |
|---|---|---|---|
| variant | 'solid' | 'acrylic' | 'auto' | 'auto' · Own default, not ambient | Floating-surface paint; auto falls back to solid under reduced transparency. Defaults: literal slot — own ’auto’, ambient when an axis opens. |
| pose | 'anchored' | 'center' | 'anchored' | The panel’s posture: anchored rides CSS Anchor Positioning against the trigger; center (the system trio) drops the anchor chain and lets the UA popover centering own the panel — the window.confirm posture. |
| focusLanding | 'cancel' | 'none' | 'cancel' | Where focus lands on open: cancel (the APG safe-landing law, falling back to the action when no cancel exists) or none (the caller owns the landing — the prompt form focuses its input). |
| children | Snippet | — | Title, Description, free body, and the Actions row; spreads HTMLAttributes (a popover panel div). |
SystemDialogAction / Cancel / Title / Description / Actions
| Property | Type | Default | Description |
|---|---|---|---|
| variant | 'fill' | 'tonal' | 'outline' | 'fill' · Own default, not ambient | Action only: the confirm paint on the ladder — fill ships with the destructive pair injected (the opt-out loud path); flip the injection to the brand pair or switch to tonal for positive confirmations. Own default, not ambient (the action ladder is outside the paint zone’s frozen availability table). |
| children | Snippet | — | Shared by all five parts; each spreads its native element attributes. |
| id (Title/Description) | string | {uid}-title / -desc | Deterministic derived ids Content’s aria wiring points at. |
axes
The eight axes on system-dialog
Self-carried across the promotion: the carriers stamp the popover panel, the parts resolve through Svelte context (which follows the component tree, never the promotion), and the panel PUBLISHES its consumed corner so flush inhabitants pair concentrically. Owns: variant (auto), actionVariant (fill), tone (destructive), elevation (level3).
| Property | Type | Default | Description |
|---|---|---|---|
| density | 'small' | 'medium' | 'large' | 'auto' | number (+ the five legacy spellings) | 'auto' | STAMP-ONLY, RUNG — the resolved lane stamps the §4 legacy rung on the panel (measured: density="small" → data-density="sm"). The parts resolve against the supply through Svelte CONTEXT, which follows the COMPONENT tree — never the top-layer promotion. Number unit: coefficient. |
| size | 'small' | 'medium' | 'large' | 'auto' | number | 'auto' | STAMP-ONLY, VOICE — the §11 pair lands on the panel root (measured 18px computed on the size demo); the title's eyebrow voice and the description's 13px reading voice are the panel's own, the body text inherits the root. Number unit: px. |
| shape | 'round' | 'scoop' | 'bevel' | 'notch' | 'square' | 'squircle' | 'auto' | 'auto' | CONSUMED, PUBLISHED — corner-shape rides the §14 alias ladder on the panel, and the consumed corner is PUBLISHED as --jx-corner: the carved strip's end cells pair concentrically with the panel's curve instead of clipping past it (the corner-context law). Number unit: none. |
| radius | 'small' | 'medium' | 'large' | 'auto' | number | 'auto' | CONSUMED, THE CONCENTRIC ANCHOR — an explicit lane stamps --jx-radius-effective on the promoted panel (self-carried across the top-layer promotion) and the consumed calc paints the silhouette AND publishes --jx-corner (measured 12px → both). 'auto' consumes against the panel's OWN ancestors. Number unit: px. |
| color | 'primary' | 'secondary' | 'error' | 'warn' | 'success' | 'info' | 'auto' | number | string | 'auto' | SUPPLY-ONLY — --jx-color-effective lands on the panel; the alert's ink is popover-foreground (the platform element paints nothing — the surface body owns fill), so the lane's work is the scope the parts read. Number unit: hue degrees. |
| theme | 'light' | 'dark' | 'system' | 'auto' | 'auto' | BRIDGE — class:dark lands on the promoted panel (measured) and re-voices the surface body + scrim through the token scope. No number lane. |
| elevation | 'level-1' | 'level0' | 'level1' | 'level2' | 'level3' | 'level4' | 'level5' | 'auto' | number | 'level3' · the family's declared own | OWN, level3 — the system alert's historic z-feel (6dp: one rung under the modal dialog — it rises BESIDE its trigger, not over the page). The §7 consumption pair stamps the shadow recipe + the paired ladder-rung surface on the panel (measured in the style attr). Number unit: dp. |
| motion | 'reduced' | 'subtle' | 'normal' | 'expressive' | 'auto' | number | 'auto' | SUPPLIED, READ BY THE KERNEL — the panel rides the shared WAAPI surface-motion kernel (--jx-p drives every formula; hidePopover fires IMMEDIATELY on the falling edge and the exit rides the kernel's discrete window). Reduced motion degades to the state alone. Number unit: coefficient. |
| Token | Default | Source |
|---|---|---|
| --jx-corner | the published corner | component |
| --scrim | ::backdrop | color |
| --jx-p | the kernel timeline | structural |
| the split strip | flex over the group grid | component |
| the viewport measure | min(24rem, 100vw − 2rem) — AUTHORED, NOT SERVED | structural |
SystemDialog · universal props
Rotate every key?
All sessions re-authenticate. The own elevation is level3 — 6dp, one rung under the modal dialog.
<SystemDialog bind:open onconfirm={run}>
<SystemDialogTrigger>rotate keys…</SystemDialogTrigger>
<SystemDialogContent elevation="level4">…</SystemDialogContent>
</SystemDialog>The stamps land on the PROMOTED panel: the rung, the dark bridge, and the 12px consumed radius (published as --jx-corner for the strip's end cells) — while the own elevation level3 rides the style attr even with no lane named.