<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>
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 #
<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 closing start", Date.now())
})
// Listen for closing animation completion
modal.addEventListener("duetCloseComplete", function () {
console.log("Modal closing done ", Date.now())
})
// 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>
<duet-modal
size="small"
heading="Onko matkapuhelimesi tai tablettisi rikkoutunut?"
icon="damage-breakage"
class="duet-text-center"
active
heading-visual-level="h3"
heading-level="h1"
>
<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>
<duet-modal
heading="Oletko varma, että haluat poistua tältä 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>
<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>
<duet-modal size="large" 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>
<duet-modal
size="large"
gutter-size="small"
heading="Onko matkapuhelimesi tai tablettisi rikkoutunut?"
heading-level="h1"
class="duet-text-center"
active
>
<img src="https://cdn.duetds.com/api/assets/illustrations/lt-booking.png" slot="top" />
<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>
<duet-modal
size="large"
gutter-size="medium"
heading="Onko matkapuhelimesi tai tablettisi rikkoutunut?"
heading-level="h1"
class="duet-text-center"
active
>
<img src="https://cdn.duetds.com/api/assets/illustrations/lt-booking.png" slot="top" />
<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>
<duet-modal
size="large"
gutter-size="large"
heading="Onko matkapuhelimesi tai tablettisi rikkoutunut?"
heading-level="h1"
class="duet-text-center"
active
>
<img src="https://cdn.duetds.com/api/assets/illustrations/lt-booking.png" slot="top" />
<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>
<duet-modal
active
variation="slide-up"
>
<div slot="sticky-header">
<duet-heading level="h3">Etsi lorem ipsum</duet-heading>
<duet-input type="search" label="Dolor sit amet" expand></duet-input>
</div>
<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. Laborum nostrud nisi ullamco reprehenderit in minim pariatur nostrud
est commodo. Non velit Lorem ex irure cillum reprehenderit ullamco amet et nostrud commodo amet. Laboris cupidatat
velit Lorem velit dolore. Aliqua ullamco eu aliquip nostrud esse incididunt excepteur ipsum elit. Dolore nulla
proident sint dolore qui amet incididunt do proident ad Lorem adipisicing. Eu sunt sit Lorem excepteur pariatur eu
culpa aute.
</duet-paragraph>
<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. Laborum nostrud nisi ullamco reprehenderit in minim pariatur nostrud
est commodo. Non velit Lorem ex irure cillum reprehenderit ullamco amet et nostrud commodo amet. Laboris cupidatat
velit Lorem velit dolore. Aliqua ullamco eu aliquip nostrud esse incididunt excepteur ipsum elit. Dolore nulla
proident sint dolore qui amet incididunt do proident ad Lorem adipisicing. Eu sunt sit Lorem excepteur pariatur eu
culpa aute.
</duet-paragraph>
<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. Laborum nostrud nisi ullamco reprehenderit in minim pariatur nostrud
est commodo. Non velit Lorem ex irure cillum reprehenderit ullamco amet et nostrud commodo amet. Laboris cupidatat
velit Lorem velit dolore. Aliqua ullamco eu aliquip nostrud esse incididunt excepteur ipsum elit. Dolore nulla
proident sint dolore qui amet incididunt do proident ad Lorem adipisicing. Eu sunt sit Lorem excepteur pariatur eu
culpa aute.
</duet-paragraph>
<duet-paragraph>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.
</duet-paragraph>
<duet-button variation="primary" id="hide-modal-button"> Jatka </duet-button>
</duet-modal>
<duet-button variation="primary" id="open-modal-button"> Show modal </duet-button>
<script>
const modal = document.querySelector("duet-modal")
document.getElementById("open-modal-button").addEventListener("click", () => {
modal.show()
})
document.getElementById("hide-modal-button").addEventListener("click", () => {
modal.hide()
})
// Listen for close events
modal.addEventListener("duetClose", () => {
console.log("Modal closing start", Date.now())
})
// Listen for closing animation completion
modal.addEventListener("duetCloseComplete", () => {
console.log("Modal closing done ", Date.now())
})
</script>
<duet-layout>
<div slot="main">
<duet-modal variation="loader">
<duet-heading level="h5" weight="semibold">Compiling an insurance offer for you. This may take a while.</duet-heading>
</duet-modal>
<duet-paragraph>
When some process takes a while it is good to inform the user about what is happening and how it is progressing. One
way to do it is using a separate page, but if page loads are to be avoided, or if we want to keep the context, a loader
modal can be used.
</duet-paragraph>
<duet-paragraph>
In this example we set the first message (telling what it is we are processing) directly in the modal. If the process
takes more than 10s we use modal's addMessage method to add progress messages with javascript. Once the process is
complete, we can add a non-visual message (using the second parameter of addMessage) to let screen reader users know
about the completion.
</duet-paragraph>
<duet-button variation="primary" id="start-button"> Get an offer </duet-button>
</div>
</duet-layout>
<script>
const modal = document.querySelector("duet-modal")
document.getElementById("start-button").addEventListener("click", () => {
// First show the modal, start adding messages only after that
modal.show()
setTimeout(() => {
modal.addMessage("Taking a bit longer than expected, please be patient.")
}, 10000)
setTimeout(() => {
modal.addMessage("Now moving to the second step, please wait.")
}, 15000)
setTimeout(() => {
modal.addMessage("Five more seconds and we are ready.")
}, 20000)
// The success messsage is not displayed, just read out by screen readers
setTimeout(() => {
modal.addMessage("Process complete.", false)
}, 25000)
// Give a moment after the success message so screen readers can read it out
setTimeout(() => {
modal.hide()
}, 25500)
})
</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 | getLocaleString( this.accessibleCloseLabelDefaults, this.language ) |
accessibleDescribedBy | accessible-described-by | Indicates the id or a string of space seperated ids of a component(s) that describes the input. | string | undefined |
accessibleDescription | accessible-description | Aria description the button | string | undefined |
accessibleDetails | accessible-details | Details of the component | string | undefined |
accessibleLabel | accessible-label | By default the heading is used aria-label for the modal. If you wish to use something else then you must set this label. | string | undefined |
accessibleLabelledBy | accessible-labelled-by | Indicates the id or a string of space seperated ids of a component(s) that labels the input. | string | undefined |
accessibleLoaderAnnouncement | accessible-loader-announcement | When modal used as a lodader, as an audible substitute for the spinner, we use this message | string | getLocaleString( this.accessibleLoaderAnnouncementDefaults, this.language ) |
active | active | Use this property when you need to have the modal dialog initially active. | boolean | false |
closeOnBlur | close-on-blur | Use this property when you want the modal to close when clicked outside of modal. | 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 | "" |
gutterSize | gutter-size | Size of the modal window's padding. | "large" | "medium" | "none" | "small" | "medium" |
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 | "" |
headingLevel | heading-level | Accessible heading size | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "h3" |
headingVisualLevel | heading-visual-level | Makes the visual style mimic a specific heading level. This option allows you to make e.g. h1 visually look like h3, but still keep it h1 in the markup. | "h0" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | undefined |
icon | icon | Icon to display above the heading (from Duet’s icons). Example: "form-location" | string | "" |
language | language | [DEPRECATED] this is now handled via the html lang tag, and is no longer used - kept to avoid breaking changes and ease unit testing The currently active language. This setting also changes the logo to match the chosen language. | "en" | "fi" | "sv" | getLanguage() |
size | size | Size of the modal window. | "large" | "medium" | "small" | "medium" |
theme | theme | Theme of the modal. | "" | "default" | "turva" | "" |
variation | variation | Variation of the modal window. Slide-up variation has fixed height so it suits well for situations where the modal content height changes. Loader variation is used when the user initiates an action that takes time to complete - it can be used with addMessage() method to insert accessible message to the modal to inform the user about the progress. | "default" | "loader" | "slide-up" | "default" |
Events #
Event | Description | Type |
---|---|---|
duetBeforeClose | Emitted 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> |
duetCloseComplete | Emitted when the modal closing transition is complete. | CustomEvent<any> |
duetOpen | Emitted when the modal is opened. | CustomEvent<any> |
Methods #
addMessage(message: string, visible?: boolean) => Promise<void>
#
Adds a message to the modal dialog using animation and annoucing it to screen readers.
Primarily for use with the loader variation.
Parameters #
Name | Type | Description |
---|---|---|
message | string | The message to be added to the modal dialog. |
visible | boolean | Set to false if you want to add a non-visual message. |
Returns #
Type: Promise<void>
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>
scrollToTop(smooth?: boolean) => Promise<void>
#
Scolls the top of the modal's content into view
Parameters #
Name | Type | Description |
---|---|---|
smooth | boolean | Set to false for instant scrolling |
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>
Slots #
Slot | Description |
---|---|
"sticky-header" | Content will be fixed to the top of the modal when scrolling, typically used with slide-up variation for e.g. a search input |
"top" | This is a slot that takes any content and will be displayed as the first thing in the hero area (typically an image) |
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 (except as the loader variation when there are lenghty server processes).
- 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.
- Modal uses ARIA
role="dialog"
andaria-modal="true"
to convey to users of assistive technologies that it works like native dialog windows. - Modal contents are also wrapped in ARIA
role="document"
to inform assistive technologies to switch context to a reading mode. - After a modal is closed, the focus is moved back to the button that triggered the modal.
heading
property can be used to display a heading 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.- Modal traps focus while it’s open and users can’t navigate out of the modal before the modal is closed.
- Pressing
esc
closes the modal window. - When opening modal the focus is set to the close button which makes screenreaders announce first the heading and then the close button. There is a difference on Android where there is a bug in this behavior on TalkBack screenreader where the heading is not always announced and on Android devices the focus is set to the modal element to make sure the heading always gets announced.
Additional considerations #
- When you have primary and secondary action buttons in modal, you should display primary on the left and secondary on the right. View an example.
- For
small
modal dialogs the action buttons are always centered. View an example. - For
medium
modal dialogs the action buttons are always left aligned. View an example. - Never have more than two buttons at the bottom of the modal.
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:
Building Layouts
TutorialsUsing CLI Tools
TutorialsCreating Custom Patterns
TutorialsServer Side Rendering
TutorialsSharing Prototypes
TutorialsUsage With Markdown
Troubleshooting
If you experience any issues while using a component, please head over to the Support page for more guidelines and help.