JSPM

@material/dialog

0.1.1
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 586805
  • Score
    100M100P100Q181693F
  • License Apache-2.0

The Material Components Web dialog component

Package Exports

  • @material/dialog
  • @material/dialog/constants
  • @material/dialog/constants.js
  • @material/dialog/dist/mdc.dialog
  • @material/dialog/dist/mdc.dialog.css
  • @material/dialog/dist/mdc.dialog.js
  • @material/dialog/dist/mdc.dialog.min
  • @material/dialog/dist/mdc.dialog.min.css
  • @material/dialog/foundation
  • @material/dialog/foundation.js
  • @material/dialog/index
  • @material/dialog/mdc-dialog.scss
  • @material/dialog/util

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@material/dialog) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

MDC Dialog

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.

Installation

npm install --save @material/dialog

Dialog usage

Dialogs inform users about a specific task and may contain critical information or require decisions.

<aside id="my-mdc-dialog"
  class="mdc-dialog"
  role="alertdialog"
  aria-hidden="true"
  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>

NOTE: The .mdc-dialog__footer__button--accept element must be the final focusable element within the dialog in order for this component to function properly.

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"
    class="mdc-dialog"
    role="alertdialog"
    aria-hidden="true"
    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.

Using the Component

MDC Dialog ships with a Component / Foundation combo which allows for frameworks to richly integrate the correct dialog behaviors into idiomatic components.

Including in code

ES2015
import {MDCDialog, MDCDialogFoundation} from 'mdc-dialog';
CommonJS
const mdcDialog = require('mdc-dialog');
const MDCDialog = mdcDialog.MDCDialog;
const MDCDialogFoundation = mdcDialog.MDCDialogFoundation;
AMD
require(['path/to/mdc-dialog'], mdcDialog => {
  const MDCDialog = mdcDrawer.MDCDialog;
  const MDCDialogFoundation = mdcDialog.MDCDialogFoundation;
});
Global
const MDCDialog = mdc.dialog.MDCDialog;
const MDCDialogFoundation = mdc.dialog.MDCDialogFoundation;

Automatic Instantiation

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'));

Manual Instantiation

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'));

Using the dialog component

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();
})

Dialog component API

MDCDialog.open

Boolean. True when the dialog is shown, false otherwise.

MDCDialog.lastFocusedTarget

EventTarget, usually an HTMLElement. Represents the element that was focused on the page before the dialog is shown. If set, the dialog will return focus to this element when closed. This property should be set before calls to show().

MDCDialog.initialize() => void

Attaches ripples to the dialog footer buttons

MDCDialog.destroy() => void

Cleans up ripples when dialog is destroyed

MDCDialog.show() => void

Shows the dialog

MDCDialog.close() => void

Closes the dialog

Dialog Events

MDCDialog:accept

Broadcast when a user actions on the .mdc-dialog__footer__button--accept element.

MDCDialog:cancel

Broadcast when a user actions on the .mdc-dialog__footer__button--cancel element.

Using the Foundation Class

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.

Adapter API

Method Signature Description
hasClass(className: string) => boolean Returns boolean indicating whether the root has a given class.
addClass(className: string) => void Adds a class to the root element.
removeClass(className: string) => void Removes a class from the root element.
setAttr(attr: string, val: string) => void Sets the given attribute to the given value on the root element.
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.
registerFocusTrappingHandler(handler: EventListener) => void Registers a focus event listener with a given handler at the capture phase on the document.
deregisterFocusTrappingHandler(handler: EventListener) => void Deregisters a focus event listener from a given handler at the capture phase on the document.
numFocusableTargets() => number Returns the number of focusable elements in the dialog
setDialogFocusFirstTarget() => void Resets focus to the first focusable element in the dialog
setInitialFocus() => void Sets focus on the mdc-dialog__footer__button--accept element.
getFocusableElements() => Array<Element> Returns the list of focusable elements inside the dialog.
saveElementTabState(el: Element) => void Saves the current tab index for the element in a way which it can be retrieved later on.
restoreElementTabState(el: Element) => void Restores the saved tab index (if any) for an element.
makeElementUntabbable(el: Element) => void Makes an element untabbable, e.g. by setting the tabindex to -1.
setBodyAttr(attr: string, val: string) => void Sets the given attribute to the given value on the body element.
rmBodyAttr(attr: string) => void Removes the given attribute from the body element.
getFocusedTarget() => Element Returns the currently focused element, e.g. document.activeElement.
setFocusedTarget(target: EventTarget) => void Sets focus on the given target, e.g. by calling focus()
notifyAccept() => {} Broadcasts an event denoting that the user has accepted the dialog.
notifyCancel() => {} Broadcasts an event denoting that the user has cancelled the dialog.

The full foundation API

MDCDialogFoundation.open() => void

Opens the dialog, registers appropriate event listners, sets aria attributes, focuses elements.

MDCDialogFoundation.close() => void

Closes the dialog, deregisters appropriate event listners, resets aria attributes, focuses elements.

MDCDialogFoundation.accept(notifyChange = false) => void

Closes the dialog. If notifyChange is true, calls the adapter's notifyAccept() method.

MDCDialogFoundation.cancel(notifyChange = false) => void

Closes the dialog. If notifyChange is true, calls the adapter's notifyCancel() method.

MDCDialogFoundation.isOpen() => Boolean

Returns true if the dialog is open, false otherwise.

Theming - Dark Theme Considerations

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 */;
}