Skip to main content

Modal
Ready

Modals are used to display content that temporarily blocks interactions with the main view of an application. Modals should be used sparingly only when necessary.

Modal component is positioned over everything else in the application preventing scrolling of the main document, making only the modal’s content scrollable. Duet only supports one modal dialog at a time as nested modals are often a sign of bad user experience.

Examples

Open in new window
<duet-modal 
size="small"
heading="Onko matkapuhelimesi tai tablettisi rikkoutunut?"
icon="damage-breakage"
class="duet-text-center"
active>

<duet-paragraph>
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam quis nostrud.
</duet-paragraph>
<duet-paragraph>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt.
</duet-paragraph>
<duet-button variation="primary" onclick="modal.hide()">
Jatka
</duet-button>
</duet-modal>

<duet-button variation="primary" onclick="modal.show()">
Show modal
</duet-button>

<script>
// Save reference to the modal component below
var modal = document.querySelector("duet-modal")

// Listen for open events
modal.addEventListener("duetOpen", function() {
console.log("Modal opened")
})

// Listen for close events
modal.addEventListener("duetClose", function() {
console.log("Modal closed")
})

// Listen for beforeClose events
modal.addEventListener("duetBeforeClose", function(e) {
var event = e.detail.originalEvent
if (!confirm("About to dismiss the modal, are you sure you want to continue?")) {
event.preventDefault()
console.log("Modal not closed as user prevented it")
}

})
</script>
Open in new window
<duet-modal
heading="Oletko varma, että haluat poistua tältä&nbsp;sivulta?"
icon="messaging-alert"
color="warning"
size="small"
variation="dialog"
class="duet-text-center"
active>

<duet-paragraph>
Kaikki täyttämäsi tiedot poistetaan.
</duet-paragraph>
<duet-button variation="primary" onclick="modal.hide()">
Kyllä
</duet-button>
<duet-button onclick="modal.hide()">
Ei
</duet-button>
</duet-modal>

<duet-button variation="primary" onclick="modal.show()">
Show modal
</duet-button>

<script>
var modal = document.querySelector("duet-modal")
</script>
Open in new window
<duet-modal heading="Tarkista tietosi" icon="profile-personal-info" active>
<form novalidate action="#">
<duet-paragraph class="duet-text-center">
Kaikki kentät ovat pakollisia ellei muuten mainita.
</duet-paragraph>
<duet-spacer size="large"></duet-spacer>
<duet-choice-group
value="suomi"
label="Asiointikieli"
direction="horizontal"
name="group"
responsive>

<duet-choice label="Suomi" type="radio" value="suomi" expand></duet-choice>
<duet-choice label="Svenska" type="radio" value="svenska" expand></duet-choice>
<duet-choice label="English" type="radio" value="english" expand></duet-choice>
</duet-choice-group>
<duet-grid responsive>
<duet-input label="Etunimi" name="firstname" placeholder="Matti" expand></duet-input>
<duet-input label="Sukunimi" name="lastname" placeholder="Meikäläinen" expand></duet-input>
</duet-grid>
<duet-input label="Kansalaisuus" name="citizenship" icon="form-location" value="Suomi" expand></duet-input>
<duet-input label="Katuosoite" name="streetaddress" placeholder="Kotikatu 123" expand></duet-input>
<duet-grid responsive>
<duet-input label="Postinumero" name="zip" placeholder="00100"></duet-input>
<duet-input label="Kaupunki" name="city" placeholder="Helsinki" expand></duet-input>
</duet-grid>
<duet-input label="Maa" name="country" icon="form-location" value="Suomi" expand></duet-input>
<duet-input label="Tilinumero" name="bankaccount" placeholder="FI28 12345 67890" expand></duet-input>
<duet-spacer size="large"></duet-spacer>
<duet-button variation="primary" onclick="modal.hide()">Jatka</duet-button>
<duet-button onclick="modal.hide()">Peruuta</duet-button>
</form>
</duet-modal>

<duet-button variation="primary" onclick="modal.show()">
Show modal
</duet-button>

<script>
var modal = document.querySelector("duet-modal")
</script>
Open in new window
<duet-modal heading="Verkkopalvelun käyttöehdot" icon="messaging-success" active>
<duet-spacer size="large"></duet-spacer>
<duet-heading level="h4">Tervetuloa LähiTapiolan verkkopalveluun</duet-heading>
<duet-paragraph>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
exercitation <duet-link url="#">ullamco laboris nisi ut aliquip</duet-link> ex ea
commodo consequat. Duis aute irure dolor in reprehenderit in voluptate.
</duet-paragraph>
<duet-heading level="h4">Käytön edellytykset</duet-heading>
<duet-paragraph>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.
</duet-paragraph>
<duet-heading level="h4">Verkkopalvelun sisältö</duet-heading>
<duet-paragraph>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ex ea commodo consequat. Duis aute irure dolor in reprehenderit
in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
</duet-paragraph>
<duet-heading level="h4">Henkilötietojen käsittely</duet-heading>
<duet-paragraph>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ex ea commodo consequat. Duis aute irure dolor in reprehenderit
in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in culpa.
</duet-paragraph>
<duet-spacer></duet-spacer>
<div class="duet-text-center">
<duet-button variation="primary" onclick="modal.hide()">
Hyväksyn verkkopalvelun käyttöehdot
</duet-button>
</div>
</duet-modal>

<duet-button variation="primary" onclick="modal.show()">
Show modal
</duet-button>

<script>
// Save reference to modal component to use in buttons
var modal = document.querySelector("duet-modal")
</script>

Properties #

Property Attribute Description Type Default
accessibleCloseLabel accessible-close-label Adds accessible label for the close icon that is only shown for screen readers. This property is always required to create an accessibly interface! Swedish translation for this property is “Stäng fönstret”. string "Sulje ikkuna"
active active Use this property when you need to have the modal dialog initially active. boolean false
color color Custom color to be used for the icon, as a design token entered in camelCase or kebab-case. Example: "primary". string ""
heading heading Accessible heading displayed in the modal. The modal marks this as the label of the modal when used. This helps screen reader users which is why this is a required property. string ""
icon icon Icon to display above the heading (from Duet’s icons). Example: "form-location" string ""
size size Size of the modal window. "medium" | "small" "medium"
theme theme Theme of the modal. "" | "default" | "turva" ""

Events #

Event Description Type
duetBeforeClose Emitted when the close button or esc is hit, but before the modal is closed. To prevent the modal from actually closing, use ev.detail.originalEvent.preventDefault(). CustomEvent<{ originalEvent: Event; component: "duet-modal"; }>
duetClose Emitted when the modal is closed. CustomEvent<any>
duetOpen Emitted when the modal is opened. CustomEvent<any>

Methods #

hide() => Promise<void> #

Hides the modal dialog and puts focus back to the original element
that triggered the modal (if we’re still in the same view).

Returns #

Type: Promise<void>

show() => Promise<void> #

Shows the modal dialog. Additionally saves the element that triggered
the modal so that focus can be moved back to this specific element when
the modal dialog is closed.

Returns #

Type: Promise<void>


Usage #

This section includes guidelines for designers and developers about the usage of this component in different contexts.

When to use #

  • When you need to display content that temporarily blocks interactions with the main view of an application.
  • When you need to ask a confirmation from a user before proceeding.
  • When the user is required to take an action.
  • For important warnings, as a way to prevent or correct critical errors.

When not to use #

  • For nonessential information that is not related to the current user flow.
  • In the middle of a purchase flow to interrupt it.
  • When the modal requires additional information for decision making that is unavailable in the modal itself.

Variations #

This section describes the different component variations, their purpose, and when to use each variation.

Name Purpose
small Small modal dialog variation is used for confirmation messages and similar.
medium Medium modal dialog should be always used when there’s more than just one paragraph of content.

Accessibility #

This component has been validated to meet the WCAG 2.1 AA accessibility guidelines. You can find additional information regarding accessibility of this component below.

Additional considerations #


Integration

For integration, event and theming guidelines, please see Using Components. This documentation explains how to implement and use Duet’s components across different technologies like Angular, React or Vanilla JavaScript.



Tutorials

Follow these practical tutorials to learn how to build simple page layouts using Duet’s CSS Framework, Web Components and other features:

Tutorials

Abstract

Tutorials

Building Layouts

Tutorials

Using CLI Tools

Tutorials

Creating Custom Patterns

Tutorials

Server Side Rendering

Tutorials

Sharing Prototypes

Tutorials

Usage With Markdown

Tutorials

VS Code

Tutorials

Zeplin


Troubleshooting

If you experience any issues while using a component, please head over to the Support page for more guidelines and help.