` | Dialog | Dialog container. Focus trap, scroll lock, dismissal layers integrated. |
-| `Overlay` | `
` | Dialog | Backdrop. Click-outside does NOT close (forced by modal=true + alertdialog). |
-| `Title` | `
` | Dialog | Dialog heading. Linked via `aria-labelledby`. |
-| `Description` | `
` | Dialog | Supporting text. Linked via `aria-describedby`. |
-| `Action` | `
` | AlertDialog | Primary / destructive confirmation. Closes the dialog on click. |
-| `Cancel` | `` | AlertDialog | Safe escape button. Closes the dialog on click. |
+| Part | Element | Origin | Description |
+| ------------- | ---------- | ----------- | ---------------------------------------------------------------------------- |
+| `Provider` | none | AlertDialog | Root context. Forces `variant='alertdialog'` + `modal=true` on Dialog. |
+| `Trigger` | `` | Dialog | Opens the dialog on click. |
+| `Content` | `` | Dialog | Dialog container. Focus trap, scroll lock, dismissal layers integrated. |
+| `Overlay` | `
` | Dialog | Backdrop. Click-outside does NOT close (forced by modal=true + alertdialog). |
+| `Title` | `
` | Dialog | Dialog heading. Linked via `aria-labelledby`. |
+| `Description` | `
` | Dialog | Supporting text. Linked via `aria-describedby`. |
+| `Action` | `
` | AlertDialog | Primary / destructive confirmation. Closes the dialog on click. |
+| `Cancel` | `` | AlertDialog | Safe escape button. Closes the dialog on click. |
## Props
### `Provider`
-| Prop | Type | Default | Description |
-| ---------------------- | ----------------------------- | ------- | ---------------------------------------------------------- |
-| `id` | `string` | auto | DOM id for the root. |
-| `open` | `boolean` | `false` | Bindable open state. |
-| `onOpenChange` | `(v: boolean) => void` | — | Called when open state changes. |
-| `onOpenChangeComplete` | `(v: boolean) => void` | — | Called after the open/close animation settles. |
-| `disabled` | `boolean` | `false` | Disables the trigger (the dialog stays closed). |
+| Prop | Type | Default | Description |
+| ---------------------- | ---------------------- | ------- | ----------------------------------------------- |
+| `id` | `string` | auto | DOM id for the root. |
+| `open` | `boolean` | `false` | Bindable open state. |
+| `onOpenChange` | `(v: boolean) => void` | — | Called when open state changes. |
+| `onOpenChangeComplete` | `(v: boolean) => void` | — | Called after the open/close animation settles. |
+| `disabled` | `boolean` | `false` | Disables the trigger (the dialog stays closed). |
### `Action` / `Cancel`
Both accept every `` attribute plus:
-| Prop | Type | Default | Description |
-| ------------ | ---------- | ----------------------- | --------------------------------------------------- |
-| `id` | `string` | auto | DOM id. |
-| `aria-label` | `string` | `"Confirm"` / `"Cancel"` | Accessible name. Overrides the translated default. |
+| Prop | Type | Default | Description |
+| ------------ | -------- | ------------------------ | -------------------------------------------------- |
+| `id` | `string` | auto | DOM id. |
+| `aria-label` | `string` | `"Confirm"` / `"Cancel"` | Accessible name. Overrides the translated default. |
`Trigger`, `Content`, `Overlay`, `Title`, `Description` are re-exported from `Dialog` — see [Dialog's props](../dialog/README.md) for the complete list. Of particular interest:
@@ -71,49 +69,49 @@ Both accept every `` attribute plus:
## ARIA
-| Part | Attribute | Value |
-| ------- | ------------------- | ------------------------------------------- |
-| Trigger | `aria-haspopup` | `dialog` |
-| Trigger | `aria-expanded` | `true` \| `false` |
-| Trigger | `aria-controls` | ID of Content |
-| Content | `role` | `alertdialog` |
-| Content | `aria-modal` | `true` |
-| Content | `aria-labelledby` | ID of Title |
-| Content | `aria-describedby` | ID of Description |
-| Overlay | `aria-hidden` | `true` |
-| Title | `role` | `heading` |
-| Title | `aria-level` | Number (default `2`) |
-| Action | `aria-label` | Translated `'Confirm'` (override via prop) |
-| Cancel | `aria-label` | Translated `'Cancel'` (override via prop) |
+| Part | Attribute | Value |
+| ------- | ------------------ | ------------------------------------------ |
+| Trigger | `aria-haspopup` | `dialog` |
+| Trigger | `aria-expanded` | `true` \| `false` |
+| Trigger | `aria-controls` | ID of Content |
+| Content | `role` | `alertdialog` |
+| Content | `aria-modal` | `true` |
+| Content | `aria-labelledby` | ID of Title |
+| Content | `aria-describedby` | ID of Description |
+| Overlay | `aria-hidden` | `true` |
+| Title | `role` | `heading` |
+| Title | `aria-level` | Number (default `2`) |
+| Action | `aria-label` | Translated `'Confirm'` (override via prop) |
+| Cancel | `aria-label` | Translated `'Cancel'` (override via prop) |
## Data Attributes
-| Part | Attribute | Values |
-| -------- | ---------------------------- | ------------------------------------------------------ |
-| Trigger | `data-dialog-trigger` | Always present |
-| Trigger | `data-state` | `open` \| `closed` |
-| Content | `data-dialog-content` | Always present |
-| Content | `data-state` | `open` \| `closed` |
-| Content | `data-nested` | Present when nested |
-| Content | `data-nested-open` | Present when a child dialog is open |
-| Content | `data-starting-style` | Present during the open animation (one frame) |
-| Content | `data-ending-style` | Present during the close animation |
-| Overlay | `data-dialog-overlay` | Always present |
-| Overlay | `data-state` | `open` \| `closed` |
-| Action | `data-alert-dialog-action` | Always present |
-| Cancel | `data-alert-dialog-cancel` | Always present |
+| Part | Attribute | Values |
+| ------- | -------------------------- | --------------------------------------------- |
+| Trigger | `data-dialog-trigger` | Always present |
+| Trigger | `data-state` | `open` \| `closed` |
+| Content | `data-dialog-content` | Always present |
+| Content | `data-state` | `open` \| `closed` |
+| Content | `data-nested` | Present when nested |
+| Content | `data-nested-open` | Present when a child dialog is open |
+| Content | `data-starting-style` | Present during the open animation (one frame) |
+| Content | `data-ending-style` | Present during the close animation |
+| Overlay | `data-dialog-overlay` | Always present |
+| Overlay | `data-state` | `open` \| `closed` |
+| Action | `data-alert-dialog-action` | Always present |
+| Cancel | `data-alert-dialog-cancel` | Always present |
Because `AlertDialog` composes `Dialog`, the Trigger / Content / Overlay / Title / Description emit the `data-dialog-*` attributes inherited from that component. The two AlertDialog-specific parts (`Action`, `Cancel`) emit their own `data-alert-dialog-*` attributes so themes can style the primary vs secondary buttons independently.
## Keyboard
-| Key | Action |
-| ----------- | -------------------------------------------------------------------------------------- |
+| Key | Action |
+| ----------- | ------------------------------------------------------------------------------------------------------------------ |
| `Escape` | Closes (acts as Cancel). Default `escapeKeydownBehavior='close'`. Pass `'ignore'` to force explicit Action/Cancel. |
-| `Tab` | Cycle focus within the dialog (trapped). |
-| `Shift+Tab` | Cycle focus backwards. |
-| `Enter` | Fires `onclick` on the focused button. |
-| `Space` | Fires `onclick` on the focused button. |
+| `Tab` | Cycle focus within the dialog (trapped). |
+| `Shift+Tab` | Cycle focus backwards. |
+| `Enter` | Fires `onclick` on the focused button. |
+| `Space` | Fires `onclick` on the focused button. |
Focus lands on the first focusable child when the dialog opens (`Cancel` by DOM order convention). Focus returns to the trigger on close.
@@ -121,28 +119,28 @@ Focus lands on the first focusable child when the dialog opens (`Cancel` by DOM
Default button labels resolve through the UIX lang system. The component catalog is owned by `morfo.translations` under `components.alert-dialog`.
-| Key | English | Spanish |
-| -------- | --------- | ------------ |
-| `action` | `Confirm` | `Confirmar` |
-| `cancel` | `Cancel` | `Cancelar` |
+| Key | English | Spanish |
+| -------- | --------- | ----------- |
+| `action` | `Confirm` | `Confirmar` |
+| `cancel` | `Cancel` | `Cancelar` |
Consumers override per-instance via the `aria-label` prop on `Action` / `Cancel`, or the visible label via `children`.
## Comparison
-| Feature | Soma | Radix | Ark UI | bits-ui |
-| ---------------------------------------------- | :--: | :---: | :----: | :-----: |
-| `role="alertdialog"` emitted | ✅ | ✅ | ✅ | ✅ |
-| Always modal | ✅ | ✅ | ✅ | ✅ |
-| `Action` + `Cancel` as first-class parts | ✅ | ✅ | ✅ | ✅ |
-| Click-outside disabled | ✅ | ✅ | ✅ | ✅ |
-| Escape closes by default | ✅ | ✅ | ✅ | ✅ |
-| Translated default button labels | ✅ | ❌ | ⚠️² | ❌ |
-| Nested alert dialogs | ✅ | ✅ | ✅ | ✅ |
-| Portal-agnostic (consumer picks) | ✅ | ✅ | ✅ | ✅ |
-| `data-*` attribute contract | ✅ | ✅ | ✅ | ✅ |
-| Shared anatomy with plain Dialog | ✅ | ❌ | ✅ | ✅ |
-| Built-in Form integration (confirm on submit) | ✅³ | ❌ | ❌ | ❌ |
+| Feature | Soma | Radix | Ark UI | bits-ui |
+| --------------------------------------------- | :--: | :---: | :----: | :-----: |
+| `role="alertdialog"` emitted | ✅ | ✅ | ✅ | ✅ |
+| Always modal | ✅ | ✅ | ✅ | ✅ |
+| `Action` + `Cancel` as first-class parts | ✅ | ✅ | ✅ | ✅ |
+| Click-outside disabled | ✅ | ✅ | ✅ | ✅ |
+| Escape closes by default | ✅ | ✅ | ✅ | ✅ |
+| Translated default button labels | ✅ | ❌ | ⚠️² | ❌ |
+| Nested alert dialogs | ✅ | ✅ | ✅ | ✅ |
+| Portal-agnostic (consumer picks) | ✅ | ✅ | ✅ | ✅ |
+| `data-*` attribute contract | ✅ | ✅ | ✅ | ✅ |
+| Shared anatomy with plain Dialog | ✅ | ❌ | ✅ | ✅ |
+| Built-in Form integration (confirm on submit) | ✅³ | ❌ | ❌ | ❌ |
² Ark has a machine-level translator seam but no built-in English/Spanish strings.
³ Demonstrated on the test page: `onValidSubmit` returns a Promise gated on a confirmation dialog.
@@ -167,9 +165,7 @@ Consumers override per-instance via the `aria-label` prop on `Action` / `Cancel`
Delete account?
-
- All your data will be permanently removed.
-
+ All your data will be permanently removed.
Keep it
Delete
@@ -179,9 +175,7 @@ Consumers override per-instance via the `aria-label` prop on `Action` / `Cancel`
### Force explicit Action/Cancel (Escape ignored)
```svelte
-
- …
-
+…
```
### Gating a form submission
@@ -189,7 +183,7 @@ Consumers override per-instance via the `aria-label` prop on `Action` / `Cancel`
```svelte