AlertDialog
A modal alert dialog for urgent messages that require acknowledgement
Import
import { AlertDialog } from '@videojs/react';import '@videojs/html/ui/alert-dialog';Anatomy
<AlertDialog.Root>
<AlertDialog.Backdrop />
<AlertDialog.Popup>
<AlertDialog.Title />
<AlertDialog.Description />
<AlertDialog.Close />
</AlertDialog.Popup>
</AlertDialog.Root><media-alert-dialog>
<media-dialog-backdrop></media-dialog-backdrop>
<media-dialog-popup>
<media-dialog-title></media-dialog-title>
<media-dialog-description></media-dialog-description>
<media-dialog-close></media-dialog-close>
</media-dialog-popup>
</media-alert-dialog>Behavior
Use an alert dialog for an urgent message that interrupts the user and requires acknowledgement. Your application controls when it opens and supplies its content. AlertDialog.Root adds alert semantics, while the other AlertDialog parts are re-exported from Dialog. For general modal content, including a player opened from a thumbnail, use Dialog.Root instead.
Use open with onOpenChange for controlled state, or defaultOpen for uncontrolled state. Root provides state without rendering an element, while Popup renders only while the dialog is open.
Set the root’s open property to show the dialog. The root supplies alert state while the shared media-dialog-backdrop and media-dialog-popup siblings render the visual surfaces and semantics. The root updates the property and dispatches open-change when the dialog closes.
The close part and Escape close the dialog. The dialog stays rendered during a closing transition, then restores focus to the element that was focused before it opened.
Styling
Use the open and transition data attributes to style visibility and animations:
| Attribute | Description |
|---|---|
data-open |
Present while the dialog is open, including its closing transition |
data-starting-style |
Present at the start of the opening transition |
data-ending-style |
Present during the closing transition |
media-dialog-backdrop:not([data-open]),
media-dialog-popup:not([data-open]) {
display: none;
}
media-dialog-backdrop[data-starting-style],
media-dialog-backdrop[data-ending-style],
media-dialog-popup[data-starting-style],
media-dialog-popup[data-ending-style] {
opacity: 0;
}React renders separate backdrop and popup elements. Add a className to each part and style them independently:
.alert-dialog-backdrop[data-starting-style],
.alert-dialog-backdrop[data-ending-style],
.alert-dialog-popup[data-starting-style],
.alert-dialog-popup[data-ending-style] {
opacity: 0;
}Accessibility
The dialog uses role="alertdialog" and aria-modal="true". The title and description receive generated IDs that are connected with aria-labelledby and aria-describedby. Focus moves into the dialog when it opens, stays within it while open, and returns to the previously focused element when it closes. Content outside the dialog is inert while it is open. Pressing Escape closes the dialog.
Examples
Basic usage
import { AlertDialog } from '@videojs/react';
import { useState } from 'react';
export default function BasicUsage() {
const [open, setOpen] = useState(false);
return (
<div className="react-alert-dialog-basic">
<button className="react-alert-dialog-basic__trigger" type="button" onClick={() => setOpen(true)}>
Open alert dialog
</button>
<AlertDialog.Root open={open} onOpenChange={setOpen}>
<AlertDialog.Backdrop className="react-alert-dialog-basic__backdrop" />
<AlertDialog.Popup className="react-alert-dialog-basic__dialog">
<AlertDialog.Title className="react-alert-dialog-basic__title">Stop playback?</AlertDialog.Title>
<AlertDialog.Description className="react-alert-dialog-basic__description">
Your current playback position will be lost.
</AlertDialog.Description>
<AlertDialog.Close className="react-alert-dialog-basic__close">Continue</AlertDialog.Close>
</AlertDialog.Popup>
</AlertDialog.Root>
</div>
);
}
.react-alert-dialog-basic {
position: relative;
display: grid;
place-items: center;
min-height: 240px;
overflow: hidden;
background: #111827;
border-radius: 12px;
}
.react-alert-dialog-basic__trigger,
.react-alert-dialog-basic__close {
padding: 8px 16px;
color: #111827;
cursor: pointer;
background: #fff;
border: 0;
border-radius: 9999px;
}
.react-alert-dialog-basic__backdrop {
position: absolute;
inset: 0;
background: rgb(3 7 18 / 92%);
transition: opacity 150ms ease;
}
.react-alert-dialog-basic__dialog {
position: absolute;
inset: 0;
z-index: 1;
display: grid;
gap: 12px;
place-content: center;
padding: 32px;
color: #fff;
text-align: center;
transition: opacity 150ms ease;
}
.react-alert-dialog-basic__backdrop[data-starting-style],
.react-alert-dialog-basic__backdrop[data-ending-style],
.react-alert-dialog-basic__dialog[data-starting-style],
.react-alert-dialog-basic__dialog[data-ending-style] {
opacity: 0;
}
.react-alert-dialog-basic__title {
font-size: 20px;
font-weight: 600;
}
.react-alert-dialog-basic__description {
color: #d1d5db;
}
.react-alert-dialog-basic__close {
justify-self: center;
}
<div class="html-alert-dialog-basic">
<button class="html-alert-dialog-basic__trigger" type="button">Open alert dialog</button>
<media-alert-dialog>
<media-dialog-backdrop class="html-alert-dialog-basic__backdrop"></media-dialog-backdrop>
<media-dialog-popup class="html-alert-dialog-basic__dialog">
<media-dialog-title class="html-alert-dialog-basic__title">Stop playback?</media-dialog-title>
<media-dialog-description class="html-alert-dialog-basic__description">
Your current playback position will be lost.
</media-dialog-description>
<media-dialog-close class="html-alert-dialog-basic__close">Continue</media-dialog-close>
</media-dialog-popup>
</media-alert-dialog>
</div>
.html-alert-dialog-basic {
position: relative;
display: grid;
place-items: center;
min-height: 240px;
overflow: hidden;
background: #111827;
border-radius: 12px;
}
.html-alert-dialog-basic__trigger,
.html-alert-dialog-basic__close {
padding: 8px 16px;
color: #111827;
cursor: pointer;
background: #fff;
border: 0;
border-radius: 9999px;
}
.html-alert-dialog-basic__backdrop {
position: absolute;
inset: 0;
background: rgb(3 7 18 / 92%);
transition: opacity 150ms ease;
}
.html-alert-dialog-basic__dialog {
position: absolute;
inset: 0;
z-index: 1;
display: grid;
gap: 12px;
place-content: center;
padding: 32px;
color: #fff;
text-align: center;
transition: opacity 150ms ease;
}
.html-alert-dialog-basic__backdrop:not([data-open]),
.html-alert-dialog-basic__dialog:not([data-open]) {
display: none;
}
.html-alert-dialog-basic__backdrop[data-starting-style],
.html-alert-dialog-basic__backdrop[data-ending-style],
.html-alert-dialog-basic__dialog[data-starting-style],
.html-alert-dialog-basic__dialog[data-ending-style] {
opacity: 0;
}
.html-alert-dialog-basic__title,
.html-alert-dialog-basic__description {
display: block;
}
.html-alert-dialog-basic__title {
font-size: 20px;
font-weight: 600;
}
.html-alert-dialog-basic__description {
color: #d1d5db;
}
.html-alert-dialog-basic__close {
justify-self: center;
}
import '@videojs/html/ui/alert-dialog';
document.querySelectorAll<HTMLElement>('.html-alert-dialog-basic').forEach((demo) => {
const trigger = demo.querySelector<HTMLButtonElement>('.html-alert-dialog-basic__trigger');
const dialog = demo.querySelector('media-alert-dialog');
trigger?.addEventListener('click', () => {
if (dialog) dialog.open = true;
});
});
API Reference
Rootmedia-alert-dialog
Manages alert dialog state and provides it to the shared dialog parts.
Props
| Prop | Type | Default | Details |
|---|---|---|---|
closeOnEscape | boolean | — | |
| |||
defaultOpen | boolean | — | |
| |||
open | boolean | — | |
| |||
State
render, className, and style props.| Property | Type | Details |
|---|---|---|
transitionStarting | boolean | |
| ||
transitionEnding | boolean | |
| ||
open | boolean | |
| ||
status | 'idle' | 'starting' | 'ending' | |
| ||
titleId | string | undefined | |
| ||
descriptionId | string | undefined | |
| ||
Events
| Event | Description |
|---|---|
open-change | Fired when the dialog's open state changes. |
open-change-complete |
Backdropmedia-dialog-backdrop
Presentational layer behind a dialog while it is rendered, including its exit transition.
Props
| Prop | Type | Default | Details |
|---|---|---|---|
className | string | ((state: DialogCore.State) => string | undefined) | — | |
| |||
render | ReactElement | ((props: HTMLProps, state: DialogCore.State) => ReactElement | null) | — | |
| |||
style | CSSProperties | ((state: DialogCore.State) => CSSProperties | undefined) | — | |
| |||
Data attributes
| Attribute | Type | Details |
|---|---|---|
data-open | ||
| ||
data-starting-style | ||
| ||
data-ending-style | ||
| ||
Closemedia-dialog-close
Renders a button that closes the dialog.
Props
| Prop | Type | Default | Details |
|---|---|---|---|
className | string | ((state: DialogCore.State) => string | undefined) | — | |
| |||
render | ReactElement | ((props: HTMLProps, state: DialogCore.State) => ReactElement | null) | — | |
| |||
style | CSSProperties | ((state: DialogCore.State) => CSSProperties | undefined) | — | |
| |||
Data attributes
| Attribute | Type | Details |
|---|---|---|
data-open | ||
| ||
data-starting-style | ||
| ||
data-ending-style | ||
| ||
Descriptionmedia-dialog-description
Renders the description announced with the dialog.
Props
| Prop | Type | Default | Details |
|---|---|---|---|
className | string | ((state: DialogCore.State) => string | undefined) | — | |
| |||
render | ReactElement | ((props: HTMLProps, state: DialogCore.State) => ReactElement | null) | — | |
| |||
style | CSSProperties | ((state: DialogCore.State) => CSSProperties | undefined) | — | |
| |||
Popupmedia-dialog-popup
Renders the modal dialog while it is open.
Props
| Prop | Type | Default | Details |
|---|---|---|---|
className | string | ((state: DialogCore.State) => string | undefined) | — | |
| |||
render | ReactElement | ((props: HTMLProps, state: DialogCore.State) => ReactElement | null) | — | |
| |||
style | CSSProperties | ((state: DialogCore.State) => CSSProperties | undefined) | — | |
| |||
Data attributes
| Attribute | Type | Details |
|---|---|---|
data-open | ||
| ||
data-starting-style | ||
| ||
data-ending-style | ||
| ||
Titlemedia-dialog-title
Renders the heading that labels the dialog.
Props
| Prop | Type | Default | Details |
|---|---|---|---|
className | string | ((state: DialogCore.State) => string | undefined) | — | |
| |||
render | ReactElement | ((props: HTMLProps, state: DialogCore.State) => ReactElement | null) | — | |
| |||
style | CSSProperties | ((state: DialogCore.State) => CSSProperties | undefined) | — | |
| |||