
Security News
Deno 2.2 Improves Dependency Management and Expands Node.js Compatibility
Deno 2.2 enhances Node.js compatibility, improves dependency management, adds OpenTelemetry support, and expands linting and task automation for developers.
@material/dialog
Advanced tools
The MDC Dialog component is a spec-aligned dialog component adhering to the Material Design dialog pattern. It implements a modal dialog window. You may notice that full screen components outlined in the dialog spec do not appear in MDC Dialog. This is because they have been deemed to be outside of the scope of what a dialog should be.
npm install --save @material/dialog
Dialogs inform users about a specific task and may contain critical information or require decisions.
<aside id="my-mdc-dialog"
style="visibility:hidden"
class="mdc-dialog"
role="alertdialog"
aria-labelledby="my-mdc-dialog-label"
aria-describedby="my-mdc-dialog-description">
<div class="mdc-dialog__surface">
<header class="mdc-dialog__header">
<h2 id="my-mdc-dialog-label" class="mdc-dialog__header__title">
Use Google's location service?
</h2>
</header>
<section id="my-mdc-dialog-description" class="mdc-dialog__body">
Let Google help apps determine location. This means sending anonymous location data to Google, even when no apps are running.
</section>
<footer class="mdc-dialog__footer">
<button type="button" class="mdc-button mdc-dialog__footer__button mdc-dialog__footer__button--cancel">Decline</button>
<button type="button" class="mdc-button mdc-dialog__footer__button mdc-dialog__footer__button--accept">Accept</button>
</footer>
</div>
<div class="mdc-dialog__backdrop"></div>
</aside>
In the example above, we've created a dialog box in an aside
element. Note that you can place content inside
the dialog. There are two types: dialog & dialogs with scrollable content. These are declared using CSS classes.
Some dialogs will not be tall enough to accomodate everything you would like to display in them. For this there is a
mdc-dialog__body--scrollable
modifier to allow scrolling in the dialog.
<aside id="mdc-dialog-with-list"
style="visibility:hidden"
class="mdc-dialog"
role="alertdialog"
aria-labelledby="mdc-dialog-with-list-label"
aria-describedby="mdc-dialog-with-list-description">
<div class="mdc-dialog__surface">
<header class="mdc-dialog__header">
<h2 id="mdc-dialog-with-list-label" class="mdc-dialog__header__title">
Choose a Ringtone
</h2>
</header>
<section id="mdc-dialog-with-list-description" class="mdc-dialog__body mdc-dialog__body--scrollable">
<ul class="mdc-list">
<li class="mdc-list-item">None</li>
<li class="mdc-list-item">Callisto</li>
<li class="mdc-list-item">Ganymede</li>
<li class="mdc-list-item">Luna</li>
<li class="mdc-list-item">Marimba</li>
<li class="mdc-list-item">Schwifty</li>
<li class="mdc-list-item">Callisto</li>
<li class="mdc-list-item">Ganymede</li>
<li class="mdc-list-item">Luna</li>
<li class="mdc-list-item">Marimba</li>
<li class="mdc-list-item">Schwifty</li>
</ul>
</section>
<footer class="mdc-dialog__footer">
<button type="button" class="mdc-button mdc-dialog__footer__button mdc-dialog__footer__button--cancel">Decline</button>
<button type="button" class="mdc-button mdc-dialog__footer__button mdc-dialog__footer__button--accept">Accept</button>
</footer>
</div>
<div class="mdc-dialog__backdrop"></div>
</aside>
Note that unlike the css classnames, the specific ID names used do not have to be exactly the same as listed above. They only need to match the values set for their corresponding aria attributes.
MDC Dialog ships with a Component / Foundation combo which allows for frameworks to richly integrate the correct dialog behaviors into idiomatic components.
import {MDCDialog, MDCDialogFoundation, util} from 'mdc-dialog';
const mdcDialog = require('mdc-dialog');
const MDCDialog = mdcDialog.MDCDialog;
const MDCDialogFoundation = mdcDialog.MDCDialogFoundation;
const util = mdcDialog.util;
require(['path/to/mdc-dialog'], mdcDialog => {
const MDCDialog = mdcDrawer.MDCDialog;
const MDCDialogFoundation = mdcDialog.MDCDialogFoundation;
const util = mdcDialog.util;
});
const MDCDialog = mdc.dialog.MDCDialog;
const MDCDialogFoundation = mdc.dialog.MDCDialogFoundation;
const util = mdc.dialog.util;
If you do not care about retaining the component instance for the temporary drawer, simply call attachTo()
and pass it a DOM element. This however, is only useful if you do not need to pass a callback to the dialog
when the user selects Accept or Cancel.
mdc.dialog.MDCDialog.attachTo(document.querySelector('#my-mdc-dialog'));
Dialogs can easily be initialized using their default constructors as well, similar to attachTo
.
import {MDCDialog} from 'mdc-dialog';
const dialog = new MDCDialog(document.querySelector('#my-mdc-dialog'));
var dialog = new mdc.dialog.MDCDialog(document.querySelector('#mdc-dialog-default'));
dialog.listen('MDCDialog:accept', function() {
console.log('accepted');
})
dialog.listen('MDCDialog:cancel', function() {
console.log('canceled');
})
document.querySelector('#default-dialog-activation').addEventListener('click', function (evt) {
dialog.lastFocusedTarget = evt.target;
dialog.show();
})
Boolean. True when the dialog is shown, false otherwise.
Shows the dialog
Closes the dialog
Broadcast when a user actions on the .mdc-dialog__footer__button--accept
element.
Broadcast when a user actions on the .mdc-dialog__footer__button--cancel
element.
MDC Dialog ships with an MDCDialogFoundation
class that external frameworks and libraries can
use to integrate the component. As with all foundation classes, an adapter object must be provided.
NOTE: Components themselves must manage adding ripples to dialog buttons, should they choose to do so. We provide instructions on how to add ripples to buttons within the mdc-button README.
Method Signature | Description |
---|---|
addClass(className: string) => void | Adds a class to the root element. |
removeClass(className: string) => void | Removes a class from the root element. |
setStyle(propertyName: string, value: string) => void | Sets a style property propertyName on the root element to the value specified |
addBodyClass(className: string) => void | Adds a class to the body. |
removeBodyClass(className: string) => void | Removes a class from the body. |
eventTargetHasClass(target: EventTarget, className: string) => boolean | Returns true if target has className, false otherwise. |
registerInteractionHandler(evt: string, handler: EventListener) => void | Adds an event listener to the root element, for the specified event name. |
deregisterInteractionHandler(evt: string, handler: EventListener) => void | Removes an event listener from the root element, for the specified event name. |
registerSurfaceInteractionHandler(evt: string, handler: EventListener) => void | Registers an event handler on the dialog surface element. |
deregisterSurfaceInteractionHandler(evt: string, handler: EventListener) => void | Deregisters an event handler from the dialog surface element. |
registerDocumentKeydownHandler(handler: EventListener) => void | Registers an event handler on the document object for a keydown event. |
deregisterDocumentKeydownHandler(handler: EventListener) => void | Deregisters an event handler on the document object for a keydown event. |
notifyAccept() => {} | Broadcasts an event denoting that the user has accepted the dialog. |
notifyCancel() => {} | Broadcasts an event denoting that the user has cancelled the dialog. |
trapFocusOnSurface() => {} | Sets up the DOM which the dialog is contained in such that focusability is restricted to the elements on the dialog surface (see Handling Focus Trapping below for more details). |
untrapFocusOnSurface() => {} | Removes any affects of focus trapping on the dialog surface from the DOM (see Handling Focus Trapping below for more details). |
In order for dialogs to be fully accessible, they must conform to the guidelines outlined in https://www.w3.org/TR/wai-aria-practices/#dialog_modal. The main implication of these guidelines is that the only focusable elements are those contained within a dialog surface.
Trapping focus correctly for a modal dialog requires a complex set of events and interaction patterns that we feel is best not duplicated within the logic of this component. Furthermore, frameworks and libraries may have their own ways of trapping focus that framework authors may want to make use of. For this reason, we have two methods on the adapter that should be used to handle focus trapping:
In our MDCDialog
component, we use the focus-trap
package to handle this. You can use util.createFocusTrapInstance to easily
create a focus trapping solution for your component code.
Opens the dialog, registers appropriate event listeners, sets aria attributes, focuses elements.
Closes the dialog, deregisters appropriate event listeners, resets aria attributes, focuses elements.
Closes the dialog. If notifyChange
is true, calls the adapter's notifyAccept()
method.
Closes the dialog. If notifyChange
is true, calls the adapter's notifyCancel()
method.
Returns true if the dialog is open, false otherwise.
Given a dialog surface element, an accept button element, and an optional focusTrap factory function, creates a properly configured focus-trap instance such that:
surfaceEl
acceptButtonEl
receives focus when the focus trap is activatedescape
key deactivates focusThis focus trap instance can be used to implement the trapFocusOnSurface
and
untrapFocusOnSurface
adapter methods by calling instance.activate()
and instance.deactivate()
respectively within those methods.
The focusTrapFactory
can be used to override the focus-trap
function used to create the focus
trap. It's API is the same as focus-trap's createFocusTrap (which is what it defaults to). You can pass in a custom function for mocking out the
actual function within tests, or to modify the arguments passed to the function before it's called.
When using mdc-theme--dark
/ mdc-dialog--theme-dark
, the dialog by default sets its background color to #303030
. You can override this by either overridding the
--mdc-dialog-dark-theme-bg-color
, overridding the $mdc-dialog-dark-theme-bg-color
sass variable, or directly in CSS:
.mdc-theme--dark .mdc-dialog__surface,
.mdc-dialog--theme-dark .mdc-dialog__surface {
background-color: /* custom bg color */;
}
FAQs
The Material Components Web dialog component
The npm package @material/dialog receives a total of 714,515 weekly downloads. As such, @material/dialog popularity was classified as popular.
We found that @material/dialog demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 15 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Deno 2.2 enhances Node.js compatibility, improves dependency management, adds OpenTelemetry support, and expands linting and task automation for developers.
Security News
React's CRA deprecation announcement sparked community criticism over framework recommendations, leading to quick updates acknowledging build tools like Vite as valid alternatives.
Security News
Ransomware payment rates hit an all-time low in 2024 as law enforcement crackdowns, stronger defenses, and shifting policies make attacks riskier and less profitable.