Disruptive, action-blocking overlays used to display important information

import { CdrModal } from '@rei/cedar'
Uses: CdrButton,CdrIcon

Modals are used to direct attention to important, task-relevant information.

When to use

  • Displaying important information requiring a user response
  • Displaying non-essential content related to the underlying page that exceeds 560 characters

When not to use

  • Displaying limited additional page content
  • Providing status feedback or messages
  • Use modals sparingly. Modals are disruptive and their sudden appearance forces users to stop their current task and focus on the modal content
  • Note that the modal centers within the page
  • Headlines should not exceed 68 characters
  • Keep modal titles short and informative
  • If two buttons are needed, place the primary button on the left and the secondary button on the right. Stack buttons at XS
  • Content behind modal does not scroll and cannot be interacted with in any way
  • Gradient is added at bottom to signify further scrollable content
  • Modals open one at a time and are never displayed in groups

Dismiss a modal by:

  • Clicking the close button
  • Interacting with the overlay background
  • Pressing the escape key (ESC)

What Cedar provides

  • Uses the label prop to set the aria-label
  • Assigns role="document" to the modal content
  • All text content within the modal is read by screen readers, including the close button text
  • Only the content in the modal is read by the screen reader. Content outside modal is not read when the modal is in focus
  • Modal can be closed using the keyboard (ESC key), close button, or by clicking outside of modal
  • Uses the aria-hidden and tabindex="-1" on focusable items for all content outside of the modal

Development responsibilities

When using this component, here's what you are responsible for:

  • If your modal is launched by a button, add aria-haspopup="dialog" to the button element:
<cdr-button
  aria-haspopup="dialog"
>Launch modal</cdr-button>
  • Set the aria-describedby prop to point to an element that describes what the modal does:
  <cdr-modal aria-describedby="description" label="modal title">
    <div id="description">
      modal content description
    </div>
  </cdr-modal>

Using multiple modals

When rendering multiple modals on a single page you can reduce your markup size by using a single CdrModal instance to launch all the modals.

<cdr-button
  @click="openTermsModal"
  aria-haspopup="alertdialog"
>Terms and Conditions
</cdr-button>

<cdr-button
  @click="openShippingModal"
  modifier="secondary"
  aria-haspopup="dialog"
>Free Shipping
</cdr-button>

<cdr-modal
  :opened="opened"
  :label="title"
  @closed="opened = false"
  aria-describedby="description"
  :role="role"
>
  <template #title>
    <cdr-text
      tag="h4"
      class="title-header"
    > <span v-if="isAlert"><icon-warning-fill/></span> {{ title }}, {{ role }}
    </cdr-text>
  </template>
  <cdr-text tag="p" id="description"> {{ content }}</cdr-text>
  <div v-if="isAlert">
     <cdr-button @click="opened= false">Accept</cdr-button>
     <cdr-button @click="opened= false" modifier="secondary" >Cancel</cdr-button>
  </div>
  
</cdr-modal>

Using modals as alert dialogs

In the multiple modal example, the cdr-modal role property of the "Terms and Conditions" modal has been changed to alertdialog. This role will notify users of critical information requiring their immediate attention.

  <cdr-modal role="alertdialog" aria-describedby="description" label="modal title">
    <div id="description">
      modal content description
    </div>
  </cdr-modal>

Generally, these modals have at least a confirmation and close button but can have additional interactive controls as needed. Like a traditional modal dialog, alert dialogs move and capture the user’s focus to the blocking overlay window. By default, focus will be placed on the modal window. For alert dialogs you should alter this and place it on the most appropriate interactive control.

Only use the alertdialog role when an alert occurs. Additionally, only use an alert dialog for alert messages which have associated interactive controls. Review the alert documentation for requirements on alerts which only contains static content and have no interactive controls.

If the title slot is left empty, the label prop will render as the title. Hide the title altogether by setting showTitle to false.

When using the label slot, add CdrText to use the appropriate header styles.

<template #title>
  <cdr-text
    tag="h1"
    class="custom-text-class"
  >Add to Cart
  </cdr-text>
</template>

The modal override slot provides a way to work from essentially a blank slate when creating modal content. This is useful for situations where more art-direction or custom functionality is necessary.

  <cdr-modal
    v-if="opened"
    :opened="opened"
    label="Fancy modal"
    @closed="closed"
    aria-describedby="description"
    role="dialog"
  >
    ...
    <template #modal>
      ...fancy modal code
      <cdr-button @click="close">Close modal</cdr-button>
    </template>
  </cdr-modal>

Size

The modal has a default width of 640px which converts to a full screen view at xs screen sizes.

Scroll behavior

The modal content area will scroll vertically if there's enough content. The modal title does not scroll; it stays affixed to the top of the modal.

Keep alive

Don’t use v-if with CdrModal unless the component is wrapped with keep-alive. CdrModal handles showing and hiding itself when toggling, so v-if shouldn’t be needed in most cases.

<keep-alive>
  <cdr-modal
    v-if="opened"
    :opened="opened"
    label="Add to Cart"
    @closed="closed"
    aria-describedby="description"
  >
    ...
  </cdr-modal>
</keep-alive>

CdrModal

Props

NameTypeDefault
opened
Required

Toggles the state of the modal

boolean
label
Required

Sets `aria-label` and modal title text. Can also use title slot to set title.

string
showTitle

Toggles the modal title text, which comes from `label` prop or `title` slot.

booleantrue
ariaDescribedby

Text for aria-describedby attribute. Applied to modal content element

stringnull
role

Sets the `role` attribute on the modal content element Possible values: dialog, alertDialog

string'dialog'
id

Sets unique `id` for modal

stringnull
overlayClass

Adds custom class to the `cdr-modal__overlay` div

string
wrapperClass

Adds custom class to the `cdr-modal__outerWrap` div

string
contentClass

Adds custom class to the `cdr-modal__innerWrap` div

string
animationDuration

Sets duration for modal's close animation

number300

Slots

Name
modal

Use to override the entire CdrModal content container.

title

Use to override the default title

default

Events

NameParameters
closed

-